Skip to content

Commit

Permalink
v3.9.21
Browse files Browse the repository at this point in the history
3.9.21 20170224
* Add ajax to web root page and web console (#79)
* Add commands SwitchMode1..4 and enable user switches 2, 3 and 4 (#84,
#88)
* Fix MQTT upgrade when webserver is active
  • Loading branch information
arendst committed Feb 24, 2017
1 parent 3f73e48 commit 3fefb9b
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 125 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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 **3.9.20** - See ```sonoff/_releasenotes.ino``` for change information.
Current version is **3.9.21** - See ```sonoff/_releasenotes.ino``` for change information.

- This version provides all (Sonoff) modules in one file and starts up with Sonoff Basic.
- Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```.
Expand Down
Binary file modified api/arduino/sonoff.ino.bin
Binary file not shown.
7 changes: 6 additions & 1 deletion sonoff/_releasenotes.ino
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
/* 3.9.20 20170221
/* 3.9.21 20170224
* Add ajax to web root page and web console (#79)
* Add commands SwitchMode1..4 and enable user switches 2, 3 and 4 (#84, #88)
* Fix MQTT upgrade when webserver is active
*
* 3.9.20 20170221
* Add minimal basic authentication to Web Admin mode (#87)
* Fix Hue and add HSB support (#89)
*
Expand Down
4 changes: 3 additions & 1 deletion sonoff/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ struct SYSCFG {

uint8_t power;
uint8_t ledstate;
uint8_t switchmode;
uint8_t ex_switchmode; // Not used since 3.9.21

char domoticz_in_topic[33];
char domoticz_out_topic[33];
Expand Down Expand Up @@ -185,5 +185,7 @@ struct SYSCFG {
uint8_t emulation;

char web_password[33];
uint8_t switchmode[4];

} sysCfg;

8 changes: 6 additions & 2 deletions sonoff/settings.ino
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ void CFG_DefaultSet2()
sysCfg.poweronstate = APP_POWERON_STATE;
sysCfg.pulsetime = APP_PULSETIME;
sysCfg.ledstate = APP_LEDSTATE;
sysCfg.switchmode = SWITCH_MODE;
// sysCfg.switchmode = SWITCH_MODE;
sysCfg.blinktime = APP_BLINKTIME;
sysCfg.blinkcount = APP_BLINKCOUNT;
sysCfg.sleep = APP_SLEEP;
Expand All @@ -376,6 +376,7 @@ void CFG_DefaultSet2()
strlcpy(sysCfg.domoticz_out_topic, DOMOTICZ_OUT_TOPIC, sizeof(sysCfg.domoticz_out_topic));
sysCfg.domoticz_update_timer = DOMOTICZ_UPDATE_TIMER;
for (byte i = 0; i < 4; i++) {
sysCfg.switchmode[i] = SWITCH_MODE;
sysCfg.domoticz_relay_idx[i] = 0;
sysCfg.domoticz_key_idx[i] = 0;
sysCfg.domoticz_switch_idx[i] = 0;
Expand Down Expand Up @@ -545,7 +546,7 @@ void CFG_Migrate_Part2()
sysCfg.hlw_kWhdoy = sysCfg2.hlw_kWhdoy;
}
if (sysCfg2.version >= 0x02001200) { // 2.0.18
sysCfg.switchmode = sysCfg2.switchmode;
sysCfg.switchmode[0] = sysCfg2.switchmode;
}
if (sysCfg2.version >= 0x02010000) { // 2.1.0
strlcpy(sysCfg.mqtt_fingerprint, sysCfg2.mqtt_fingerprint, sizeof(sysCfg.mqtt_fingerprint));
Expand Down Expand Up @@ -629,6 +630,9 @@ void CFG_Delta()
if (sysCfg.version < 0x03091301) {
strlcpy(sysCfg.web_password, WEB_PASSWORD, sizeof(sysCfg.web_password));
}
if (sysCfg.version < 0x03091500) {
for (byte i = 0; i < 4; i++) sysCfg.switchmode[i] = sysCfg.ex_switchmode;
}

sysCfg.version = VERSION;
}
Expand Down
55 changes: 31 additions & 24 deletions sonoff/sonoff.ino
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* ====================================================
*/

#define VERSION 0x03091400 // 3.9.20
#define VERSION 0x03091500 // 3.9.21

//#define BE_MINIMAL // Compile a minimal version if upgrade memory gets tight (still 404k)
// To be used as step 1. Next step is compile and use desired version
Expand Down Expand Up @@ -118,7 +118,7 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
#define STATES 10 // loops per second
#define SYSLOG_TIMER 600 // Seconds to restore syslog_level
#define SERIALLOG_TIMER 600 // Seconds to disable SerialLog
#define OTA_ATTEMPTS 5 // Number of times to try fetching the new firmware
#define OTA_ATTEMPTS 10 // Number of times to try fetching the new firmware

#define INPUT_BUFFER_SIZE 100 // Max number of characters in serial buffer
#define TOPSZ 60 // Max number of characters in topic string
Expand Down Expand Up @@ -213,12 +213,14 @@ int state = 0; // State per second flag
int mqttflag = 2; // MQTT connection messages flag
int otaflag = 0; // OTA state flag
int otaok = 0; // OTA result
byte otaretry = OTA_ATTEMPTS; // OTA retry counter
int restartflag = 0; // Sonoff restart flag
int wificheckflag = WIFI_RESTART; // Wifi state flag
int uptime = 0; // Current uptime in hours
int tele_period = 0; // Tele period timer
String Log[MAX_LOG_LINES]; // Web log buffer
byte logidx = 0; // Index in Web log buffer
byte logajaxflg = 0; // Reset web console log
byte Maxdevice = MAX_DEVICE; // Max number of devices supported
int status_update_timer = 0; // Refresh initial status
uint16_t pulse_timer = 0; // Power off timer
Expand Down Expand Up @@ -891,11 +893,11 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"FriendlyName%d\":\"%s\"}"), index, sysCfg.friendlyname[index -1]);
}
else if (swt_flg && !strcmp(type,"SWITCHMODE")) {
else if (swt_flg && !strcmp(type,"SWITCHMODE") && (index > 0) && (index <= 4)) {
if ((data_len > 0) && (payload >= 0) && (payload < MAX_SWITCH_OPTION)) {
sysCfg.switchmode = payload;
sysCfg.switchmode[index -1] = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"SwitchMode\":%d}"), sysCfg.switchmode);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"SwitchMode%d\":%d}"), index, sysCfg.switchmode[index-1]);
}
#ifdef USE_WEBSERVER
else if (!strcmp(type,"WEBSERVER")) {
Expand Down Expand Up @@ -1184,7 +1186,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)

snprintf_P(svalue, sizeof(svalue), PSTR("{\"Commands3\":\"%s%s, PulseTime, BlinkTime, BlinkCount"), (Maxdevice == 1) ? "Power, Light" : "Power1, Power2, Light1 Light2", (sysCfg.module != MOTOR) ? ", PowerOnState" : "");
#ifdef USE_WEBSERVER
snprintf_P(svalue, sizeof(svalue), PSTR("%s, Weblog, Webserver, Emulation"), svalue);
snprintf_P(svalue, sizeof(svalue), PSTR("%s, Weblog, Webserver, WebPassword, Emulation"), svalue);
#endif
if (swt_flg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, SwitchMode"), svalue);
#ifdef USE_I2C
Expand Down Expand Up @@ -1223,10 +1225,10 @@ void send_button_power(byte key, byte device, byte state)

char stopic[TOPSZ], svalue[TOPSZ], stemp1[10];

if (device > Maxdevice) device = 1;
if (!key && (device > Maxdevice)) device = 1;
snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), device);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s%s"),
SUB_PREFIX, (key) ? sysCfg.switch_topic : sysCfg.button_topic, sysCfg.mqtt_subtopic, (Maxdevice > 1) ? stemp1 : "");
SUB_PREFIX, (key) ? sysCfg.switch_topic : sysCfg.button_topic, sysCfg.mqtt_subtopic, (key || (Maxdevice > 1)) ? stemp1 : "");

if (state == 3) {
svalue[0] = '\0';
Expand Down Expand Up @@ -1676,11 +1678,12 @@ void stateloop()
lastbutton[i] = button;
}

for (byte i = 0; i < Maxdevice; i++) if (pin[GPIO_SWT1 +i] < 99) {
// for (byte i = 0; i < Maxdevice; i++) if (pin[GPIO_SWT1 +i] < 99) {
for (byte i = 0; i < 4; i++) if (pin[GPIO_SWT1 +i] < 99) {
button = digitalRead(pin[GPIO_SWT1 +i]);
if (button != lastwallswitch[i]) {
switchflag = 3;
switch (sysCfg.switchmode) {
switch (sysCfg.switchmode[i]) {
case TOGGLE:
switchflag = 2; // Toggle
break;
Expand All @@ -1698,9 +1701,9 @@ void stateloop()
}
if (switchflag < 3) {
if (sysCfg.mqtt_enabled && mqttClient.connected() && strcmp(sysCfg.switch_topic,"0")) {
send_button_power(1, i +1, switchflag); // Execute commend via MQTT
send_button_power(1, i +1, switchflag); // Execute commend via MQTT
} else {
do_cmnd_power(i +1, switchflag); // Execute command internally
do_cmnd_power(i +1, switchflag); // Execute command internally (if i < Maxdevice)
}
}
lastwallswitch[i] = button;
Expand Down Expand Up @@ -1730,30 +1733,34 @@ void stateloop()
case (STATES/10)*2:
if (otaflag) {
otaflag--;
if (otaflag <= 0) {
otaflag = 12;
if (otaflag == 2){
otaretry = OTA_ATTEMPTS;
ESPhttpUpdate.rebootOnUpdate(false);
sl_blank(1);
// Try multiple times to get the update, in case we have a transient issue.
// e.g. Someone issued "cmnd/sonoffs/update 1" and all the devices
// are hammering the OTAURL.
for (byte i = 0; i < OTA_ATTEMPTS && !otaok; i++) {
// Delay an increasing pseudo-random time for each interation.
// Starting at 0 (no delay) up to a maximum of OTA_ATTEMPTS-1 seconds.
delay((ESP.getChipId() % 1000) * i);
}
if (otaflag <= 0) {
#ifdef USE_WEBSERVER
if (sysCfg.webserver) stopWebserver();
#endif // USE_WEBSERVER
otaflag = 92;
otaok = 0;
otaretry--;
if (otaretry) {
// snprintf_P(log, sizeof(log), PSTR("OTA: Attempt %d"), OTA_ATTEMPTS - otaretry);
// addLog(LOG_LEVEL_INFO, log);
otaok = (ESPhttpUpdate.update(sysCfg.otaUrl) == HTTP_UPDATE_OK);
if (!otaok) otaflag = 2;
}
}
if (otaflag == 10) { // Allow MQTT to reconnect
if (otaflag == 90) { // Allow MQTT to reconnect
otaflag = 0;
if (otaok) {
if ((sysCfg.module == SONOFF_TOUCH) || (sysCfg.module == SONOFF_4CH)) setFlashChipMode(1, 3); // DOUT - ESP8285
snprintf_P(svalue, sizeof(svalue), PSTR("Successful. Restarting"));
restartflag = 2;
} else {
sl_blank(0);
snprintf_P(svalue, sizeof(svalue), PSTR("Failed %s"), ESPhttpUpdate.getLastErrorString().c_str());
}
restartflag = 2; // Restart anyway to keep memory clean webserver
mqtt_publish_topic_P(0, PSTR("UPGRADE"), svalue);
}
}
Expand Down
29 changes: 20 additions & 9 deletions sonoff/sonoff_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ enum upins_t {
GPIO_WS2812, // WS2812 Led string
GPIO_IRSEND, // IR remote
GPIO_SWT1, // User connected external switches
GPIO_SWT2,
GPIO_SWT3,
GPIO_SWT4,
GPIO_SENSOR_END };

// Text in webpage Module Parameters and commands GPIOS and GPIO
Expand All @@ -27,14 +30,14 @@ const char sensors[GPIO_SENSOR_END][9] PROGMEM = {
"I2C SDA",
"WS2812",
"IRremote",
"Switch" };

"Switch1",
"Switch2",
"Switch3",
"Switch4" };

// Programmer selectable GPIO functionality offset by user selectable GPIOs
enum fpins_t {
GPIO_SWT2 = GPIO_SENSOR_END,
GPIO_SWT3,
GPIO_SWT4,
GPIO_KEY1, // Button usually connected to GPIO0
GPIO_KEY1 = GPIO_SENSOR_END, // Button usually connected to GPIO0
GPIO_KEY2,
GPIO_KEY3,
GPIO_KEY4,
Expand Down Expand Up @@ -107,14 +110,22 @@ typedef struct MYTMPLT {
const mytmplt modules[MAXMODULE] PROGMEM = {
{ "Sonoff Basic", // Sonoff Basic
GPIO_KEY1, // GPIO00 Button
0, 0,
0, // GPIO01 Serial RXD
0, // GPIO02
GPIO_USER, // GPIO03 Serial TXD and Optional sensor
GPIO_USER, // GPIO04 Optional sensor
0, 0, 0, 0, 0, 0, 0,
0, // GPIO05
0, // GPIO06 (SD_CLK Flash)
0, // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
0, // GPIO08 (SD_DATA1 Flash QIO/DIO)
0, // GPIO09 (SD_DATA2 Flash QIO)
0, // GPIO10 (SD_DATA3 Flash QIO)
0, // GPIO11 (SD_CMD Flash)
GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
GPIO_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off)
GPIO_USER, // GPIO14 Optional sensor
0, 0
0, // GPIO15
0 // GPIO16
},
{ "Sonoff RF", // Sonoff RF
GPIO_KEY1, // GPIO00 Button
Expand Down
Loading

0 comments on commit 3fefb9b

Please sign in to comment.