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)
This commit is contained in:
arendst 2017-07-25 18:05:47 +02:00
parent 7e6b3a2bb1
commit 22ef93a2c4
6 changed files with 293 additions and 197 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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()

View File

@ -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();
}
for (byte i = 0; i < Maxdevice; i++) {
butt_present = 0;
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();
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);
button = NOT_PRESSED;
}
}
}
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;
}
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
}
}
}
}
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;
}
}
}
}
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
}
}
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:

View File

@ -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
}
};