From 06d0c62dfa8fd0566b0584e18c0383476379699e Mon Sep 17 00:00:00 2001 From: arendst Date: Fri, 18 Aug 2017 12:55:08 +0200 Subject: [PATCH] Add global interlock Use command SetOption14 1 to enable interlock mode --- README.md | 2 +- sonoff/_releasenotes.ino | 3 ++- sonoff/settings.h | 2 +- sonoff/sonoff.ino | 36 ++++++++++++++++++++++++++++++++++-- 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 50b5e1e03..36513d374 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## Sonoff-Tasmota Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE. -Current version is **5.5.2j** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. +Current version is **5.5.2k** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. ### ATTENTION All versions diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 72fb41be3..046deffe6 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,4 +1,4 @@ -/* 5.5.2j +/* 5.5.2k * Fix Sonoff Pow intermittent exception 0 * Change Sonoff Pow sending Domoticz telemetry data only * Add Sonoff B1 RGBCW led support with command Color RRGGBBCCWW (#676) @@ -11,6 +11,7 @@ * Fix Mitsubishi HVAC IR power controll (#740) * Add Sonoff T1 support (#582) * Change Sonoff T1 command Ledstate functionality by turning led on if power is off + * Add command SetOption14 0|1 to enable interlock mode (#719, #721) * * 5.5.2 20170808 * Extent max number of WS2812 pixels from 256 to 512 (#667) diff --git a/sonoff/settings.h b/sonoff/settings.h index 2ee62d957..c08889332 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -36,7 +36,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t button_swap : 1; // bit 11 (v5.1.6) uint32_t stop_flash_rotate : 1; // bit 12 (v5.2.0) uint32_t button_single : 1; // bit 13 (v5.4.0) - uint32_t spare14 : 1; + uint32_t interlock : 1; // bit 14 (v5.5.2k) uint32_t spare15 : 1; uint32_t spare16 : 1; uint32_t spare17 : 1; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 939eb9bfe..48df04fb2 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,7 +25,7 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x0505020A // 5.5.2j +#define VERSION 0x0505020B // 5.5.2k enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL}; enum week_t {Last, First, Second, Third, Fourth}; @@ -266,6 +266,7 @@ uint8_t blogidx = 0; // Command backlog index uint8_t blogptr = 0; // Command backlog pointer uint8_t blogmutex = 0; // Command backlog pending uint16_t blogdelay = 0; // Command backlog delay +uint8_t interlockmutex = 0; // Interlock power command pending #ifdef USE_MQTT_TLS WiFiClientSecure espClient; // Wifi Secure Client @@ -403,6 +404,20 @@ void setRelay(uint8_t rpower) power = (1 << Maxdevice) -1; rpower = power; } + if (sysCfg.flag.interlock) { // Allow only one or no relay set + uint8_t mask = 0x01; + uint8_t count = 0; + for (byte i = 0; i < Maxdevice; i++) { + if (rpower & mask) { + count++; + } + mask <<= 1; + } + if (count > 1) { + power = 0; + rpower = 0; + } + } if ((SONOFF_DUAL == sysCfg.module) || (CH4 == sysCfg.module)) { Serial.write(0xA0); Serial.write(0x04); @@ -1010,6 +1025,12 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) return; } else if ((sysCfg.module != MOTOR) && !strcmp_P(type,PSTR("POWERONSTATE"))) { + /* 0 = Keep relays off after power on + * 1 = Turn relays on after power on + * 2 = Toggle relays after power on + * 3 = Set relays to last saved state after power on + * 4 = Turn relays on and disable any relay control (used for Sonoff Pow to always measure power) + */ if ((payload >= 0) && (payload <= 4)) { sysCfg.poweronstate = payload; if (4 == sysCfg.poweronstate) { @@ -1062,7 +1083,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } snprintf_P(svalue, sizeof(svalue), PSTR("{\"SaveData\":\"%s\"}"), (sysCfg.savedata > 1) ? stemp1 : getStateText(sysCfg.savedata)); } - else if (!strcmp_P(type,PSTR("SETOPTION")) && ((index >= 0) && (index <= 13)) || ((index > 31) && (index <= P_MAX_PARAM8 +31))) { + else if (!strcmp_P(type,PSTR("SETOPTION")) && ((index >= 0) && (index <= 14)) || ((index > 31) && (index <= P_MAX_PARAM8 +31))) { if (index <= 31) { ptype = 0; // SetOption0 .. 31 } else { @@ -1084,6 +1105,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) case 11: // button_swap case 12: // stop_flash_rotate case 13: // button_single + case 14: // interlock bitWrite(sysCfg.flag.data, index, payload); } if (12 == index) { // stop_flash_rotate @@ -1650,6 +1672,16 @@ void do_cmnd_power(byte device, byte state) blink_mask &= (0xFF ^ mask); // Clear device mask mqtt_publishPowerBlinkState(device); } + if (sysCfg.flag.interlock && !interlockmutex) { // Clear all but masked relay + interlockmutex = 1; + for (byte i = 0; i < Maxdevice; i++) { + byte imask = 0x01 << i; + if ((power & imask) && (mask != imask)) { + do_cmnd_power(i +1, 0); + } + } + interlockmutex = 0; + } switch (state) { case 0: { // Off power &= (0xFF ^ mask);