From 22ef93a2c420e65e63d7cb0ba2b2b499d7a3b2cf Mon Sep 17 00:00:00 2001 From: arendst Date: Tue, 25 Jul 2017 18:05:47 +0200 Subject: [PATCH] v5.4.0 5.4.0 20170725 * Fix command reset regression introduced in 5.2.0 * Increase polling from 0.1 second to 0.05 second * Add multipress to all buttons * Fix button 1 double press behaviour on multi relay devices * Add support for Hua Fan Smart Socket (#479) * Add support for Sonoff 4ch Pro (#565) * Add command SetOption13 1 to allow immediate action on single button press * (disables multipress, hold and unrestricted commands) (#587) --- README.md | 4 +- sonoff/_releasenotes.ino | 12 +- sonoff/settings.h | 2 +- sonoff/settings.ino | 10 +- sonoff/sonoff.ino | 404 +++++++++++++++++++++++---------------- sonoff/sonoff_template.h | 56 +++--- 6 files changed, 292 insertions(+), 196 deletions(-) diff --git a/README.md b/README.md index 5e2af2338ffd..8915464e157f 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.3.0** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. +Current version is **5.4.0** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. ### **** ATTENTION Version 5.x.x specific information **** @@ -34,6 +34,7 @@ The following devices are supported: - [iTead Sonoff Dual](http://sonoff.itead.cc/en/products/sonoff/sonoff-dual) - [iTead Sonoff Pow](http://sonoff.itead.cc/en/products/sonoff/sonoff-pow) - [iTead Sonoff 4CH](http://sonoff.itead.cc/en/products/sonoff/sonoff-4ch) +- [iTead Sonoff 4CH Pro](http://sonoff.itead.cc/en/products/sonoff/sonoff-4ch-pro) - [iTead S20 Smart Socket](http://sonoff.itead.cc/en/products/residential/s20-socket) - [iTead Slampher](http://sonoff.itead.cc/en/products/residential/slampher-rf) - [iTead Sonoff Touch](http://sonoff.itead.cc/en/products/residential/sonoff-touch) @@ -46,7 +47,6 @@ The following devices are supported: - [Electrodragon IoT Relay Board](http://www.electrodragon.com/product/wifi-iot-relay-board-based-esp8266/) Planned support: -- [iTead Sonoff 4CH Pro](http://sonoff.itead.cc/en/products/sonoff/sonoff-4ch-pro) - [iTead Sonoff T1](https://www.itead.cc/smart-home/sonoff-t1.html) - [iTead Sonoff B1](https://www.itead.cc/smart-home/sonoff-b1.html) diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index c77e42fd22b4..331e25afbef9 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,4 +1,14 @@ -/* 5.3.0 20170715 +/* 5.4.0 20170725 + * Fix command reset regression introduced in 5.2.0 + * Increase polling from 0.1 second to 0.05 second + * Add multipress to all buttons + * Fix button 1 double press behaviour on multi relay devices + * Add support for Hua Fan Smart Socket (#479) + * Add support for Sonoff 4ch Pro (#565) + * Add command SetOption13 1 to allow immediate action on single button press + * (disables multipress, hold and unrestricted commands) (#587) + * + * 5.3.0 20170715 * Major Hue rewrite which might introduce Alexa problems. If so, initiate an issue * Add support for Sonoff Led and BN-SZ01 Ceiling Led brightness control to Hue * Fix Sonoff Led Power, Dimmer and Color MQTT response (#176) diff --git a/sonoff/settings.h b/sonoff/settings.h index 47a51f8865af..1826ea637277 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -35,7 +35,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t mqtt_offline : 1; // bit 10 uint32_t button_swap : 1; // bit 11 (v5.1.6) uint32_t stop_flash_rotate : 1; // bit 12 (v5.2.0) - uint32_t spare13 : 1; + uint32_t button_single : 1; // bit 13 (v5.4.0) uint32_t spare14 : 1; uint32_t spare15 : 1; uint32_t spare16 : 1; diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 2af936703d98..adce6a6934bb 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -197,7 +197,7 @@ void CFG_Save(byte rotate) * * rotate 0 = Save in next flash slot * rotate 1 = Save only in eeprom flash slot until SetOption12 0 or restart - * rotate 2 = Save in eeprom flash slot and continue depending on stop_flash_rotate + * rotate 2 = Save in eeprom flash slot, erase next flash slots and continue depending on stop_flash_rotate * stop_flash_rotate 0 = Allow flash slot rotation (SetOption12 0) * stop_flash_rotate 1 = Allow only eeprom flash slot use (SetOption12 1) */ @@ -205,10 +205,10 @@ void CFG_Save(byte rotate) #ifndef BE_MINIMAL if ((getHash() != _cfgHash) || rotate) { - if (1 == rotate) { - stop_flash_rotate = 1; // Disable flash rotate from now on + if (1 == rotate) { // Use eeprom flash slot only and disable flash rotate from now on (upgrade) + stop_flash_rotate = 1; } - if (2 == rotate) { + if (2 == rotate) { // Use eeprom flash slot and erase next flash slots if stop_flash_rotate is off (default) _cfgLocation = CFG_LOCATION +1; } if (stop_flash_rotate) { @@ -390,7 +390,7 @@ void CFG_Default() addLog_P(LOG_LEVEL_NONE, PSTR("Cnfg: Use defaults")); CFG_DefaultSet1(); CFG_DefaultSet2(); - CFG_Save(1); + CFG_Save(2); } void CFG_DefaultSet1() diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 576b0ebde1ae..8704121abc37 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,7 +25,7 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x05030000 // 5.3.0 +#define VERSION 0x05040000 // 5.4.0 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}; @@ -132,7 +132,7 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX}; #define SAFE_POWER_WINDOW 30 // Time in MINUTES to disable allow max unit safe power (Pow) #define MAX_POWER_RETRY 5 // Retry count allowing agreed power limit overflow (Pow) -#define STATES 10 // loops per second +#define STATES 20 // State loops per second #define SYSLOG_TIMER 600 // Seconds to restore syslog_level #define SERIALLOG_TIMER 600 // Seconds to disable SerialLog #define OTA_ATTEMPTS 10 // Number of times to try fetching the new firmware @@ -287,8 +287,8 @@ uint8_t blinkstate = 0; // LED state uint8_t lastbutton[4] = { NOT_PRESSED, NOT_PRESSED, NOT_PRESSED, NOT_PRESSED }; // Last button states uint8_t holdbutton[4] = { 0 }; // Timer for button hold -uint8_t multiwindow = 0; // Max time between button presses to record press count -uint8_t multipress = 0; // Number of button presses within multiwindow +uint8_t multiwindow[4] = { 0 }; // Max time between button presses to record press count +uint8_t multipress[4] = { 0 }; // Number of button presses within multiwindow uint8_t lastwallswitch[4]; // Last wall switch states uint8_t holdwallswitch[4] = { 0 }; // Timer for wallswitch push button hold uint8_t blockgpio0 = 4; // Block GPIO0 for 4 seconds after poweron to workaround Wemos D1 RTS circuit @@ -1061,7 +1061,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 <= 12)) || ((index > 31) && (index <= P_MAX_PARAM8 +31))) { + else if (!strcmp_P(type,PSTR("SETOPTION")) && ((index >= 0) && (index <= 13)) || ((index > 31) && (index <= P_MAX_PARAM8 +31))) { if (index <= 31) { ptype = 0; // SetOption0 .. 31 } else { @@ -1082,6 +1082,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) case 10: // mqtt_offline case 11: // button_swap case 12: // stop_flash_rotate + case 13: // button_single bitWrite(sysCfg.flag.data, index, payload); } if (12 == index) { // stop_flash_rotate @@ -2069,167 +2070,152 @@ void every_second() } } -void stateloop() +/*********************************************************************************************\ + * Button handler with single press only or multi-press and hold on all buttons +\*********************************************************************************************/ + +void button_handler() { uint8_t button = NOT_PRESSED; - uint8_t flag; - uint8_t switchflag; - uint8_t power_now; + uint8_t butt_present = 0; + uint8_t flag = 0; char scmnd[20]; char log[LOGSZ]; - char svalue[80]; // was MESSZ - timerxs = millis() + (1000 / STATES); - state++; - if (STATES == state) { // Every second - state = 0; - every_second(); - } - - if (mqtt_cmnd_publish) { - mqtt_cmnd_publish--; // Clean up - } - - if (latching_relay_pulse) { - latching_relay_pulse--; - if (!latching_relay_pulse) { - setLatchingRelay(0, 0); - } - } - - for (byte i = 0; i < MAX_PULSETIMERS; i++) - if ((pulse_timer[i] > 0) && (pulse_timer[i] < 112)) { - pulse_timer[i]--; - if (!pulse_timer[i]) { - do_cmnd_power(i +1, 0); - } - } - - if (blink_mask) { - blink_timer--; - if (!blink_timer) { - blink_timer = sysCfg.blinktime; - blink_counter--; - if (!blink_counter) { - stop_all_power_blink(); + for (byte i = 0; i < Maxdevice; i++) { + butt_present = 0; + + if (!i && ((SONOFF_DUAL == sysCfg.module) || (CH4 == sysCfg.module))) { + butt_present = 1; + if (ButtonCode) { + snprintf_P(log, sizeof(log), PSTR("APP: Button code %04X"), ButtonCode); + addLog(LOG_LEVEL_DEBUG, log); + button = PRESSED; + if (0xF500 == ButtonCode) { // Button hold + holdbutton[i] = (sysCfg.param[P_HOLD_TIME] * (STATES / 10)) -1; + } + ButtonCode = 0; } else { - blink_power ^= 1; - power_now = (power & (0xFF ^ blink_mask)) | ((blink_power) ? blink_mask : 0); - setRelay(power_now); - } - } - } - - if (sfl_flg) { // Sonoff BN-SZ01 or Sonoff Led - sl_animate(); - } - -#ifdef USE_WS2812 - if (pin[GPIO_WS2812] < 99) { - ws2812_animate(); - } -#endif // USE_WS2812 - - if ((SONOFF_DUAL == sysCfg.module) || (CH4 == sysCfg.module)) { - if (ButtonCode) { - snprintf_P(log, sizeof(log), PSTR("APP: Button code %04X"), ButtonCode); - addLog(LOG_LEVEL_DEBUG, log); - button = PRESSED; - if (0xF500 == ButtonCode) { - holdbutton[0] = (STATES *4) -1; + button = NOT_PRESSED; } - ButtonCode = 0; } else { - button = NOT_PRESSED; - } - } else { - if ((pin[GPIO_KEY1] < 99) && !blockgpio0) { - button = digitalRead(pin[GPIO_KEY1]); - } - } - if ((PRESSED == button) && (NOT_PRESSED == lastbutton[0])) { - multipress = (multiwindow) ? multipress +1 : 1; - snprintf_P(log, sizeof(log), PSTR("APP: Multipress %d"), multipress); - addLog(LOG_LEVEL_DEBUG, log); - blinks = 201; - multiwindow = STATES /2; // 1/2 second multi press window - } - lastbutton[0] = button; - if (NOT_PRESSED == button) { - holdbutton[0] = 0; - } else { - holdbutton[0]++; - if (holdbutton[0] == sysCfg.param[P_HOLD_TIME]) { // 4 seconds button hold - multipress = 0; - if (!sysCfg.flag.button_restrict) { // no restriction (OPTION - snprintf_P(scmnd, sizeof(scmnd), PSTR("reset 1")); - do_cmnd(scmnd); - } else { - send_button_power(0, 1, 3); // Execute command via MQTT + if ((pin[GPIO_KEY1 +i] < 99) && !blockgpio0) { + butt_present = 1; + button = digitalRead(pin[GPIO_KEY1 +i]); } } - } - if (multiwindow) { - multiwindow--; - } else { - if ((!restartflag) && (!holdbutton[0]) && (multipress > 0) && (multipress < MAX_BUTTON_COMMANDS +3)) { - if ((SONOFF_DUAL == sysCfg.module) || (CH4 == sysCfg.module)) { - flag = ((1 == multipress) || (2 == multipress)); - } else { -// flag = (1 == multipress); - flag = (sysCfg.flag.button_swap +1 == multipress); - } - if (flag && send_button_power(0, multipress, 2)) { // Execute command via MQTT using ButtonTopic to sync external clients - // Success + + if (butt_present) { + if (SONOFF_4CHPRO == sysCfg.module) { + if (holdbutton[i]) { + holdbutton[i]--; + } + flag = 0; + if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) { + snprintf_P(log, sizeof(log), PSTR("APP: Button %d level 1-0"), i +1); + addLog(LOG_LEVEL_DEBUG, log); + holdbutton[i] = STATES; + flag = 1; + } + if ((NOT_PRESSED == button) && (PRESSED == lastbutton[i])) { + snprintf_P(log, sizeof(log), PSTR("APP: Button %d level 0-1"), i +1); + addLog(LOG_LEVEL_DEBUG, log); + if (!holdbutton[i]) { // Do not allow within 1 second + flag = 1; + } + } + if (flag) { + if (!send_button_power(0, i +1, 2)) { // Execute Toggle command via MQTT if ButtonTopic is set + do_cmnd_power(i +1, 2); // Execute Toggle command internally + } + } } else { - if ((1 == multipress) || (2 == multipress)) { - if (WIFI_State()) { // WPSconfig, Smartconfig or Wifimanager active - restartflag = 1; + if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) { + if (sysCfg.flag.button_single) { // Allow only single button press for immediate action + snprintf_P(log, sizeof(log), PSTR("APP: Button %d immediate"), i +1); + if (!send_button_power(0, i +1, 2)) { // Execute Toggle command via MQTT if ButtonTopic is set + do_cmnd_power(i +1, 2); // Execute Toggle command internally + } } else { - do_cmnd_power(multipress, 2); // Execute command internally + multipress[i] = (multiwindow[i]) ? multipress[i] +1 : 1; + snprintf_P(log, sizeof(log), PSTR("APP: Button %d multi-press %d"), i +1, multipress[i]); + multiwindow[i] = STATES /2; // 0.5 second multi press window } + addLog(LOG_LEVEL_DEBUG, log); + blinks = 201; + } + + if (NOT_PRESSED == button) { + holdbutton[i] = 0; } else { - if (!sysCfg.flag.button_restrict) { - snprintf_P(scmnd, sizeof(scmnd), commands[multipress -3]); - do_cmnd(scmnd); + holdbutton[i]++; + if (sysCfg.flag.button_single) { // Allow only single button press for immediate action + if (holdbutton[i] == sysCfg.param[P_HOLD_TIME] * (STATES / 10) * 4) { // Button hold for four times longer +// sysCfg.flag.button_single = 0; + snprintf_P(scmnd, sizeof(scmnd), PSTR("setoption13 0")); // Disable single press only + do_cmnd(scmnd); + } + } else { + if (holdbutton[i] == sysCfg.param[P_HOLD_TIME] * (STATES / 10)) { // Button hold + multipress[i] = 0; + if (!sysCfg.flag.button_restrict) { // No button restriction + snprintf_P(scmnd, sizeof(scmnd), PSTR("reset 1")); + do_cmnd(scmnd); + } else { + send_button_power(0, i +1, 3); // Execute Hold command via MQTT if ButtonTopic is set + } + } } } - } - multipress = 0; - } - } - - for (byte i = 1; i < Maxdevice; i++) { - if (pin[GPIO_KEY1 +i] < 99) { - if (holdbutton[i]) { - holdbutton[i]--; - if (0 == holdbutton[i]) { - send_button_power(0, i +1, 3); // Execute command via MQTT - } - } - - button = digitalRead(pin[GPIO_KEY1 +i]); -/* - if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) { - if (!send_button_power(0, i +1, 2)) { // Execute command via MQTT - do_cmnd_power(i +1, 2); // Execute command internally - } - } -*/ - if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) { - holdbutton[i] = sysCfg.param[P_HOLD_TIME]; - } - if ((NOT_PRESSED == button) && (PRESSED == lastbutton[i]) && (holdbutton[i])) { - holdbutton[i] = 0; - if (!send_button_power(0, i +1, 2)) { // Execute command via MQTT - do_cmnd_power(i +1, 2); // Execute command internally + if (!sysCfg.flag.button_single) { // Allow multi-press + if (multiwindow[i]) { + multiwindow[i]--; + } else { + if (!restartflag && !holdbutton[i] && (multipress[i] > 0) && (multipress[i] < MAX_BUTTON_COMMANDS +3)) { + flag = 0; + if (multipress[i] < 3) { // Single or Double press + if ((SONOFF_DUAL == sysCfg.module) || (CH4 == sysCfg.module)) { + flag = 1; + } else { + flag = (sysCfg.flag.button_swap +1 == multipress[i]); + multipress[i] = 1; + } + } + if (flag && send_button_power(0, i + multipress[i], 2)) { // Execute Toggle command via MQTT if ButtonTopic is set + // Success + } else { + if (multipress[i] < 3) { // Single or Double press + if (WIFI_State()) { // WPSconfig, Smartconfig or Wifimanager active + restartflag = 1; + } else { + do_cmnd_power(i + multipress[i], 2); // Execute Toggle command internally + } + } else { // 3 - 7 press + if (!sysCfg.flag.button_restrict) { + snprintf_P(scmnd, sizeof(scmnd), commands[multipress[i] -3]); + do_cmnd(scmnd); + } + } + } + multipress[i] = 0; + } + } } } - lastbutton[i] = button; } } +} + +/*********************************************************************************************\ + * Switch handler +\*********************************************************************************************/ + +void switch_handler() +{ + uint8_t button = NOT_PRESSED; + uint8_t switchflag; for (byte i = 0; i < 4; i++) { if (pin[GPIO_SWT1 +i] < 99) { @@ -2237,7 +2223,7 @@ void stateloop() if (holdwallswitch[i]) { holdwallswitch[i]--; if (0 == holdwallswitch[i]) { - send_button_power(1, i +1, 3); // Execute command via MQTT + send_button_power(1, i +1, 3); // Execute command via MQTT } } @@ -2246,7 +2232,7 @@ void stateloop() switchflag = 3; switch (sysCfg.switchmode[i]) { case TOGGLE: - switchflag = 2; // Toggle + switchflag = 2; // Toggle break; case FOLLOW: switchflag = button & 0x01; // Follow wall switch state @@ -2266,7 +2252,7 @@ void stateloop() break; case PUSHBUTTONHOLD: if ((PRESSED == button) && (NOT_PRESSED == lastwallswitch[i])) { - holdwallswitch[i] = sysCfg.param[P_HOLD_TIME]; + holdwallswitch[i] = sysCfg.param[P_HOLD_TIME] * (STATES / 10); } if ((NOT_PRESSED == button) && (PRESSED == lastwallswitch[i]) && (holdwallswitch[i])) { holdwallswitch[i] = 0; @@ -2275,7 +2261,7 @@ void stateloop() break; case PUSHBUTTONHOLD_INV: if ((NOT_PRESSED == button) && (PRESSED == lastwallswitch[i])) { - holdwallswitch[i] = sysCfg.param[P_HOLD_TIME]; + holdwallswitch[i] = sysCfg.param[P_HOLD_TIME] * (STATES / 10); } if ((PRESSED == button) && (NOT_PRESSED == lastwallswitch[i]) && (holdwallswitch[i])) { holdwallswitch[i] = 0; @@ -2294,6 +2280,110 @@ void stateloop() } } } +} + +/*********************************************************************************************\ + * State loop +\*********************************************************************************************/ + +void stateloop() +{ + uint8_t power_now; + char log[LOGSZ]; + char svalue[80]; // was MESSZ + + timerxs = millis() + (1000 / STATES); + state++; + +/*-------------------------------------------------------------------------------------------*\ + * Every second +\*-------------------------------------------------------------------------------------------*/ + + if (STATES == state) { + state = 0; + every_second(); + } + +/*-------------------------------------------------------------------------------------------*\ + * Every 0.1 second +\*-------------------------------------------------------------------------------------------*/ + +// if (0 == (state & 1)) { + if (!(state % (STATES/10))) { + + if (mqtt_cmnd_publish) { + mqtt_cmnd_publish--; // Clean up + } + + if (latching_relay_pulse) { + latching_relay_pulse--; + if (!latching_relay_pulse) { + setLatchingRelay(0, 0); + } + } + + for (byte i = 0; i < MAX_PULSETIMERS; i++) { + if ((pulse_timer[i] > 0) && (pulse_timer[i] < 112)) { + pulse_timer[i]--; + if (!pulse_timer[i]) { + do_cmnd_power(i +1, 0); + } + } + } + + if (blink_mask) { + blink_timer--; + if (!blink_timer) { + blink_timer = sysCfg.blinktime; + blink_counter--; + if (!blink_counter) { + stop_all_power_blink(); + } else { + blink_power ^= 1; + power_now = (power & (0xFF ^ blink_mask)) | ((blink_power) ? blink_mask : 0); + setRelay(power_now); + } + } + } + + if (sfl_flg) { // Sonoff BN-SZ01 or Sonoff Led + sl_animate(); + } + +#ifdef USE_WS2812 + if (pin[GPIO_WS2812] < 99) { + ws2812_animate(); + } +#endif // USE_WS2812 + + // Backlog + if (blogdelay) { + blogdelay--; + } + if ((blogptr != blogidx) && !blogdelay && !blogmutex) { + blogmutex = 1; + do_cmnd((char*)Backlog[blogptr].c_str()); + blogmutex = 0; + blogptr++; +/* + if (blogptr >= MAX_BACKLOG) { + blogptr = 0; + } +*/ + blogptr &= 0xF; + } + } + +/*-------------------------------------------------------------------------------------------*\ + * Every 0.05 second +\*-------------------------------------------------------------------------------------------*/ + + button_handler(); + switch_handler(); + +/*-------------------------------------------------------------------------------------------*\ + * Every 0.2 second +\*-------------------------------------------------------------------------------------------*/ if (!(state % ((STATES/10)*2))) { if (blinks || restartflag || otaflag) { @@ -2318,21 +2408,9 @@ void stateloop() } } - if (blogdelay) { - blogdelay--; - } - if ((blogptr != blogidx) && !blogdelay && !blogmutex) { - blogmutex = 1; - do_cmnd((char*)Backlog[blogptr].c_str()); - blogmutex = 0; - blogptr++; -/* - if (blogptr >= MAX_BACKLOG) { - blogptr = 0; - } -*/ - blogptr &= 0xF; - } +/*-------------------------------------------------------------------------------------------*\ + * Every second at 0.2 second interval +\*-------------------------------------------------------------------------------------------*/ switch (state) { case (STATES/10)*2: diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 7508b1dffb0c..c2e918c70fdc 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -146,6 +146,8 @@ enum module_t { H801, SONOFF_SC, SONOFF_BN, + SONOFF_4CHPRO, + HUAFAN_SS, MAXMODULE }; /********************************************************************************************/ @@ -157,15 +159,13 @@ typedef struct MYIO { } myio; typedef struct MYTMPLT { - char name[14]; - uint8_t flag; // not used + char name[15]; myio gp; } mytmplt; // Default module settings const mytmplt modules[MAXMODULE] PROGMEM = { { "Sonoff Basic", // Sonoff Basic (ESP8266) - 0, // not used GPIO_KEY1, // GPIO00 Button GPIO_USER, // GPIO01 Serial RXD and Optional sensor 0, // GPIO02 @@ -186,7 +186,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0 // ADC0 Analog input }, { "Sonoff RF", // Sonoff RF (ESP8266) - 0, // not used GPIO_KEY1, // GPIO00 Button GPIO_USER, // GPIO01 Serial RXD and Optional sensor 0, @@ -200,7 +199,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0, 0 }, { "Sonoff SV", // Sonoff SV (ESP8266) - 0, // not used GPIO_KEY1, // GPIO00 Button GPIO_USER, // GPIO01 Serial RXD and Optional sensor 0, @@ -215,7 +213,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { GPIO_ADC0 // ADC0 Analog input }, { "Sonoff TH", // Sonoff TH10/16 (ESP8266) - 0, // not used GPIO_KEY1, // GPIO00 Button GPIO_USER, // GPIO01 Serial RXD and Optional sensor 0, @@ -229,7 +226,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0, 0 }, { "Sonoff Dual", // Sonoff Dual (ESP8266) - 0, // not used 0, GPIO_TXD, // GPIO01 Relay control 0, @@ -242,7 +238,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0, 0, 0 }, { "Sonoff Pow", // Sonoff Pow (ESP8266) - 0, // not used GPIO_KEY1, // GPIO00 Button 0, 0, 0, 0, GPIO_HLW_SEL, // GPIO05 HLW8012 Sel output @@ -254,7 +249,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0 }, { "Sonoff 4CH", // Sonoff 4CH (ESP8285) - 0, // not used GPIO_KEY1, // GPIO00 Button 1 GPIO_USER, // GPIO01 Serial RXD and Optional sensor GPIO_USER, // GPIO02 Optional sensor @@ -272,7 +266,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0 }, { "S20 Socket", // S20 Smart Socket (ESP8266) - 0, // not used GPIO_KEY1, // GPIO00 Button GPIO_USER, // GPIO01 Serial RXD and Optional sensor 0, @@ -284,7 +277,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0, 0, 0 }, { "Slampher", // Slampher (ESP8266) - 0, // not used GPIO_KEY1, // GPIO00 Button GPIO_USER, // GPIO01 Serial RXD and Optional sensor 0, @@ -296,7 +288,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0, 0, 0 }, { "Sonoff Touch", // Sonoff Touch (ESP8285) - 0, // not used GPIO_KEY1, // GPIO00 Button GPIO_USER, // GPIO01 Serial RXD and Optional sensor 0, @@ -310,7 +301,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0, 0, 0 }, { "Sonoff LED", // Sonoff LED (ESP8266) - 0, // not used GPIO_KEY1, // GPIO00 Button 0, 0, 0, GPIO_USER, // GPIO04 Optional sensor (PWM3 Green) @@ -323,7 +313,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0 }, { "1 Channel", // 1 Channel Inching/Latching Relay using (PSA-B01 - ESP8266 and PSF-B01 - ESP8285) - 0, // not used GPIO_KEY1, // GPIO00 Button 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Flash connection @@ -332,7 +321,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0, 0, 0 }, { "4 Channel", // 4 Channel Inching/Latching Relays (ESP8266) - 0, // not used 0, GPIO_TXD, // GPIO01 Relay control 0, @@ -344,7 +332,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0, 0, 0 }, { "Motor C/AC", // Motor Clockwise / Anti clockwise (PSA-B01 - ESP8266) - 0, // not used GPIO_KEY1, // GPIO00 Button 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Flash connection @@ -353,7 +340,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0, 0, 0 }, { "ElectroDragon", // ElectroDragon IoT Relay Board (ESP8266) - 0, // not used GPIO_KEY2, // GPIO00 Button 2 GPIO_USER, // GPIO01 Serial RXD and Optional sensor GPIO_KEY1, // GPIO02 Button 1 @@ -370,7 +356,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { }, { "EXS Relay", // Latching relay https://ex-store.de/ESP8266-WiFi-Relay-V31 (ESP8266) // Module Pin 1 VCC 3V3, Module Pin 6 GND - 0, // not used GPIO_KEY1, // GPIO00 Module Pin 8 - Button (firmware flash) GPIO_USER, // GPIO01 Module Pin 2 = UART0_TXD GPIO_USER, // GPIO02 Module Pin 7 @@ -386,7 +371,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0 }, { "WiOn", // Indoor Tap https://www.amazon.com/gp/product/B00ZYLUBJU/ref=s9_acsd_al_bw_c_x_3_w (ESP8266) - 0, // not used GPIO_USER, // GPIO00 Optional sensor (pm clock) 0, GPIO_LED1, // GPIO02 Green Led (1 = On, 0 = Off) @@ -399,7 +383,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0 }, { "WeMos D1 mini", // WeMos and NodeMCU hardware (ESP8266) - 0, // not used GPIO_USER, // GPIO00 D3 Wemos Button Shield GPIO_USER, // GPIO01 TX Serial RXD GPIO_USER, // GPIO02 D4 Wemos DHT Shield @@ -415,7 +398,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { GPIO_ADC0 // ADC0 A0 Analog input }, { "Sonoff Dev", // Sonoff Dev (ESP8266) - 0, // not used GPIO_KEY1, // GPIO00 E-FW Button GPIO_USER, // GPIO01 TX Serial RXD and Optional sensor 0, // GPIO02 @@ -431,7 +413,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { GPIO_ADC0 // ADC0 A0 Analog input }, { "H801", // Lixada H801 Wifi (ESP8266) - 0, // not used GPIO_KEY1, // GPIO00 E-FW Button GPIO_LED1, // GPIO01 Green LED GPIO_TXD, // GPIO02 RX - Pin next to TX on the PCB @@ -446,7 +427,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0 }, { "Sonoff SC", // Sonoff SC (ESP8266) - 0, // not used GPIO_KEY1, // GPIO00 Button GPIO_TXD, // GPIO01 RXD to ATMEGA328P GPIO_USER, // GPIO02 Optional sensor @@ -458,7 +438,6 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0, 0, 0 }, { "Sonoff BN-SZ", // Sonoff BN-SZ01 Ceiling led (ESP8285) - 0, // not used 0, 0, 0, 0, 0, 0, 0, 0, 0, // Flash connection 0, 0, @@ -467,6 +446,35 @@ const mytmplt modules[MAXMODULE] PROGMEM = { GPIO_LED1_INV, // GPIO13 Red Led (0 = On, 1 = Off) 0, 0, 0, 0 + }, + { "Sonoff 4CH Pro", // Sonoff 4CH Pro (ESP8285) + GPIO_KEY1, // GPIO00 Button 1 + GPIO_USER, // GPIO01 Serial RXD and Optional sensor + GPIO_USER, // GPIO02 Optional sensor + GPIO_USER, // GPIO03 Serial TXD and Optional sensor + GPIO_REL3, // GPIO04 Sonoff 4CH Red Led and Relay 3 (0 = Off, 1 = On) + GPIO_REL2, // GPIO05 Sonoff 4CH Red Led and Relay 2 (0 = Off, 1 = On) + 0, 0, 0, // Flash connection + GPIO_KEY2, // GPIO09 Button 2 + GPIO_KEY3, // GPIO10 Button 3 + 0, // Flash connection + GPIO_REL1, // GPIO12 Red Led and Relay 1 (0 = Off, 1 = On) + GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) + GPIO_KEY4, // GPIO14 Button 4 + GPIO_REL4, // GPIO15 Red Led and Relay 4 (0 = Off, 1 = On) + 0, 0 + }, + { "Huafan SS", // Hua Fan Smart Socket (ESP8266) - like Sonoff Pow + GPIO_LED1_INV, // GPIO0 Blue Led (0 = On, 1 = Off) + 0, 0, + GPIO_LED2_INV, // GPIO3 Red Led (0 = On, 1 = Off) + GPIO_KEY1, // GPIO4 Button + GPIO_REL1_INV, // GPIO5 Relay (0 = On, 1 = Off) + 0, 0, 0, 0, 0, 0, // Flash connection + GPIO_HLW_CF1, // GPIO12 HLW8012 CF1 voltage / current + GPIO_HLW_SEL, // GPIO13 HLW8012 Sel output + GPIO_HLW_CF, // GPIO14 HLW8012 CF power + 0, 0, 0 } };