diff --git a/code/espurna/config/hardware.h b/code/espurna/config/hardware.h index 0e391e81..12b2b48e 100644 --- a/code/espurna/config/hardware.h +++ b/code/espurna/config/hardware.h @@ -477,6 +477,32 @@ #define BUTTON4_RELAY 0 #endif +#ifndef RELAY1_DELAY_ON +#define RELAY1_DELAY_ON 0 +#endif +#ifndef RELAY2_DELAY_ON +#define RELAY2_DELAY_ON 0 +#endif +#ifndef RELAY3_DELAY_ON +#define RELAY3_DELAY_ON 0 +#endif +#ifndef RELAY4_DELAY_ON +#define RELAY4_DELAY_ON 0 +#endif + +#ifndef RELAY1_DELAY_OFF +#define RELAY1_DELAY_OFF 0 +#endif +#ifndef RELAY2_DELAY_OFF +#define RELAY2_DELAY_OFF 0 +#endif +#ifndef RELAY3_DELAY_OFF +#define RELAY3_DELAY_OFF 0 +#endif +#ifndef RELAY4_DELAY_OFF +#define RELAY4_DELAY_OFF 0 +#endif + #ifndef RELAY1_LED #define RELAY1_LED 0 #endif diff --git a/code/espurna/relay.ino b/code/espurna/relay.ino index ae50ca20..0a264f2c 100644 --- a/code/espurna/relay.ino +++ b/code/espurna/relay.ino @@ -16,6 +16,8 @@ typedef struct { unsigned char pin; bool reverse; unsigned char led; + unsigned long delay_on; + unsigned long delay_off; unsigned int floodWindowStart; unsigned char floodWindowChanges; unsigned int scheduledStatusTime; @@ -81,22 +83,6 @@ bool relayProviderStatus(unsigned char id) { // RELAY // ----------------------------------------------------------------------------- -String relayString() { - DynamicJsonBuffer jsonBuffer; - JsonObject& root = jsonBuffer.createObject(); - JsonArray& relay = root.createNestedArray("relayStatus"); - for (unsigned char i=0; i= floodWindowEnd || currentTime < _relays[id].floodWindowStart) { + // If currentTime is off-limits the floodWindow... + if (currentTime < _relays[id].floodWindowStart || floodWindowEnd <= currentTime) { + + // We reset the floodWindow _relays[id].floodWindowStart = currentTime; _relays[id].floodWindowChanges = 1; + + // If currentTime is in the floodWindow and there have been too many requests... } else if (_relays[id].floodWindowChanges >= RELAY_FLOOD_CHANGES) { - _relays[id].scheduledStatusTime = floodWindowEnd; + + // We schedule the changes to the end of the floodWindow + // unless it's already delayed beyond that point + if (floodWindowEnd - delay > currentTime) { + _relays[id].scheduledStatusTime = floodWindowEnd; + } + } _relays[id].scheduledStatus = status; - _relays[id].scheduledReport = (report ? true : _relays[id].scheduledReport); + if (report) _relays[id].scheduledReport = true; - DEBUG_MSG_P(PSTR("[RELAY] Scheduled %d => %s in %u ms\n"), + DEBUG_MSG_P(PSTR("[RELAY] #%d scheduled %s in %u ms\n"), id, status ? "ON" : "OFF", (_relays[id].scheduledStatusTime - currentTime)); @@ -189,6 +187,10 @@ bool relayStatus(unsigned char id, bool status) { return relayStatus(id, status, true); } +bool relayStatus(unsigned char id) { + return relayProviderStatus(id); +} + void relaySync(unsigned char id) { if (_relays.size() > 1) { @@ -302,7 +304,14 @@ void relaySetupAPI() { //------------------------------------------------------------------------------ void relayWS() { - String output = relayString(); + DynamicJsonBuffer jsonBuffer; + JsonObject& root = jsonBuffer.createObject(); + JsonArray& relay = root.createNestedArray("relayStatus"); + for (unsigned char i=0; i= _relays.size()) return; - char buffer[10]; - sprintf(buffer, "%s,id=%d", MQTT_TOPIC_RELAY, id); - influxDBSend(buffer, relayStatus(id) ? "1" : "0"); -} -#endif - void relayMQTT() { for (unsigned int i=0; i < _relays.size(); i++) { relayMQTT(i); @@ -381,6 +381,19 @@ void relaySetupMQTT() { mqttRegister(relayMQTTCallback); } +//------------------------------------------------------------------------------ +// InfluxDB +//------------------------------------------------------------------------------ + +#if ENABLE_INFLUXDB +void relayInfluxDB(unsigned char id) { + if (id >= _relays.size()) return; + char buffer[10]; + sprintf(buffer, "%s,id=%d", MQTT_TOPIC_RELAY, id); + influxDBSend(buffer, relayStatus(id) ? "1" : "0"); +} +#endif + //------------------------------------------------------------------------------ // Setup //------------------------------------------------------------------------------ @@ -390,27 +403,27 @@ void relaySetup() { #if defined(SONOFF_DUAL) // Two dummy relays for the dual - _relays.push_back((relay_t) {0, 0}); - _relays.push_back((relay_t) {0, 0}); + _relays.push_back((relay_t) {0, 0, 0, RELAY1_DELAY_ON, RELAY1_DELAY_OFF}); + _relays.push_back((relay_t) {0, 0, 0, RELAY2_DELAY_ON, RELAY2_DELAY_OFF}); #elif defined(AI_LIGHT) | defined(LED_CONTROLLER) | defined(H801_LED_CONTROLLER) // One dummy relay for the AI Thinker Light & Magic Home and H801 led controllers - _relays.push_back((relay_t) {0, 0}); + _relays.push_back((relay_t) {0, 0, 0, RELAY1_DELAY_ON, RELAY1_DELAY_OFF}); #else #ifdef RELAY1_PIN - _relays.push_back((relay_t) { RELAY1_PIN, RELAY1_PIN_INVERSE, RELAY1_LED }); + _relays.push_back((relay_t) { RELAY1_PIN, RELAY1_PIN_INVERSE, RELAY1_LED, RELAY1_DELAY_ON, RELAY1_DELAY_OFF }); #endif #ifdef RELAY2_PIN - _relays.push_back((relay_t) { RELAY2_PIN, RELAY2_PIN_INVERSE, RELAY2_LED }); + _relays.push_back((relay_t) { RELAY2_PIN, RELAY2_PIN_INVERSE, RELAY2_LED, RELAY2_DELAY_ON, RELAY2_DELAY_OFF }); #endif #ifdef RELAY3_PIN - _relays.push_back((relay_t) { RELAY3_PIN, RELAY3_PIN_INVERSE, RELAY3_LED }); + _relays.push_back((relay_t) { RELAY3_PIN, RELAY3_PIN_INVERSE, RELAY3_LED, RELAY3_DELAY_ON, RELAY3_DELAY_OFF }); #endif #ifdef RELAY4_PIN - _relays.push_back((relay_t) { RELAY4_PIN, RELAY4_PIN_INVERSE, RELAY4_LED }); + _relays.push_back((relay_t) { RELAY4_PIN, RELAY4_PIN_INVERSE, RELAY4_LED, RELAY4_DELAY_ON, RELAY4_DELAY_OFF }); #endif #endif @@ -443,17 +456,21 @@ void relayLoop(void) { if (relayStatus(id) != status && currentTime >= _relays[id].scheduledStatusTime) { - DEBUG_MSG_P(PSTR("[RELAY] %d => %s\n"), id, status ? "ON" : "OFF"); + DEBUG_MSG_P(PSTR("[RELAY] #%d set to %s\n"), id, status ? "ON" : "OFF"); + // Call the provider to perform the action relayProviderStatus(id, status); + // Change the binded LED if any if (_relays[id].led > 0) { ledStatus(_relays[id].led - 1, status); } + // Send MQTT report if requested if (_relays[id].scheduledReport) { relayMQTT(id); } + if (!recursive) { relayPulse(id); relaySync(id);