Browse Source

Add support for delayed ON/OFF switches

fastled
Xose Pérez 7 years ago
parent
commit
2d2a8a69a8
2 changed files with 83 additions and 40 deletions
  1. +26
    -0
      code/espurna/config/hardware.h
  2. +57
    -40
      code/espurna/relay.ino

+ 26
- 0
code/espurna/config/hardware.h View File

@ -477,6 +477,32 @@
#define BUTTON4_RELAY 0 #define BUTTON4_RELAY 0
#endif #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 #ifndef RELAY1_LED
#define RELAY1_LED 0 #define RELAY1_LED 0
#endif #endif


+ 57
- 40
code/espurna/relay.ino View File

@ -16,6 +16,8 @@ typedef struct {
unsigned char pin; unsigned char pin;
bool reverse; bool reverse;
unsigned char led; unsigned char led;
unsigned long delay_on;
unsigned long delay_off;
unsigned int floodWindowStart; unsigned int floodWindowStart;
unsigned char floodWindowChanges; unsigned char floodWindowChanges;
unsigned int scheduledStatusTime; unsigned int scheduledStatusTime;
@ -81,22 +83,6 @@ bool relayProviderStatus(unsigned char id) {
// RELAY // RELAY
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
String relayString() {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
JsonArray& relay = root.createNestedArray("relayStatus");
for (unsigned char i=0; i<relayCount(); i++) {
relay.add(relayStatus(i));
}
String output;
root.printTo(output);
return output;
}
bool relayStatus(unsigned char id) {
return relayProviderStatus(id);
}
void relayPulse(unsigned char id) { void relayPulse(unsigned char id) {
byte relayPulseMode = getSetting("relayPulseMode", RELAY_PULSE_MODE).toInt(); byte relayPulseMode = getSetting("relayPulseMode", RELAY_PULSE_MODE).toInt();
@ -158,23 +144,35 @@ bool relayStatus(unsigned char id, bool status, bool report) {
if (relayStatus(id) != status) { if (relayStatus(id) != status) {
unsigned int floodWindowEnd = _relays[id].floodWindowStart + 1000 * RELAY_FLOOD_WINDOW;
unsigned int currentTime = millis(); unsigned int currentTime = millis();
unsigned int floodWindowEnd = _relays[id].floodWindowStart + 1000 * RELAY_FLOOD_WINDOW;
unsigned long delay = status ? _relays[id].delay_on : _relays[id].delay_off;
_relays[id].floodWindowChanges++; _relays[id].floodWindowChanges++;
_relays[id].scheduledStatusTime = currentTime;
_relays[id].scheduledStatusTime = currentTime + delay;
if (currentTime >= 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].floodWindowStart = currentTime;
_relays[id].floodWindowChanges = 1; _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) { } 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].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", id, status ? "ON" : "OFF",
(_relays[id].scheduledStatusTime - currentTime)); (_relays[id].scheduledStatusTime - currentTime));
@ -189,6 +187,10 @@ bool relayStatus(unsigned char id, bool status) {
return relayStatus(id, status, true); return relayStatus(id, status, true);
} }
bool relayStatus(unsigned char id) {
return relayProviderStatus(id);
}
void relaySync(unsigned char id) { void relaySync(unsigned char id) {
if (_relays.size() > 1) { if (_relays.size() > 1) {
@ -302,7 +304,14 @@ void relaySetupAPI() {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void relayWS() { void relayWS() {
String output = relayString();
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
JsonArray& relay = root.createNestedArray("relayStatus");
for (unsigned char i=0; i<relayCount(); i++) {
relay.add(relayStatus(i));
}
String output;
root.printTo(output);
wsSend(output.c_str()); wsSend(output.c_str());
} }
@ -315,15 +324,6 @@ void relayMQTT(unsigned char id) {
mqttSend(MQTT_TOPIC_RELAY, id, relayStatus(id) ? "1" : "0"); mqttSend(MQTT_TOPIC_RELAY, id, relayStatus(id) ? "1" : "0");
} }
#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
void relayMQTT() { void relayMQTT() {
for (unsigned int i=0; i < _relays.size(); i++) { for (unsigned int i=0; i < _relays.size(); i++) {
relayMQTT(i); relayMQTT(i);
@ -381,6 +381,19 @@ void relaySetupMQTT() {
mqttRegister(relayMQTTCallback); 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 // Setup
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -390,27 +403,27 @@ void relaySetup() {
#if defined(SONOFF_DUAL) #if defined(SONOFF_DUAL)
// Two dummy relays for the 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) #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 // 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 #else
#ifdef RELAY1_PIN #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 #endif
#ifdef RELAY2_PIN #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 #endif
#ifdef RELAY3_PIN #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 #endif
#ifdef RELAY4_PIN #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
#endif #endif
@ -443,17 +456,21 @@ void relayLoop(void) {
if (relayStatus(id) != status && currentTime >= _relays[id].scheduledStatusTime) { 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); relayProviderStatus(id, status);
// Change the binded LED if any
if (_relays[id].led > 0) { if (_relays[id].led > 0) {
ledStatus(_relays[id].led - 1, status); ledStatus(_relays[id].led - 1, status);
} }
// Send MQTT report if requested
if (_relays[id].scheduledReport) { if (_relays[id].scheduledReport) {
relayMQTT(id); relayMQTT(id);
} }
if (!recursive) { if (!recursive) {
relayPulse(id); relayPulse(id);
relaySync(id); relaySync(id);


Loading…
Cancel
Save