mirror of https://github.com/arendst/Tasmota.git
v4.0.8
4.0.8 20170321 * Fix entering non-numeric webpassword * Force selection between TLS or Webserver due to memory restraint (#240) * Allow entering empty string using "0" for selected commands (#242) * Fix exception when posting commands to web console containing % (#250)
This commit is contained in:
parent
742a87df8a
commit
99b7474ac4
|
@ -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 **4.0.7** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
|
||||
Current version is **4.0.8** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/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```.
|
||||
|
|
Binary file not shown.
|
@ -1,4 +1,10 @@
|
|||
/* 4.0.7 20170319
|
||||
/* 4.0.8 20170321
|
||||
* Fix entering non-numeric webpassword
|
||||
* Force selection between TLS or Webserver due to memory restraint (#240)
|
||||
* Allow entering empty string using "0" for selected commands (#242)
|
||||
* Fix exception when posting commands to web console containing % (#250)
|
||||
*
|
||||
* 4.0.7 20170319
|
||||
* Increased Sonoff Led PWM frequency from 432 to 1000
|
||||
* Fix possible watch dog reboot after changing module type on web page
|
||||
* Fix reporting of GPIO usage from web page
|
||||
|
|
|
@ -145,11 +145,17 @@ struct SYSCFG {
|
|||
uint16_t hlw_mkwh; // MaxEnergy
|
||||
uint16_t hlw_mkwhs; // MaxEnergyStart
|
||||
|
||||
// 3.0.6
|
||||
uint16_t ex_pulsetime; // Not used since 4.0.4
|
||||
|
||||
// 3.1.1
|
||||
uint8_t poweronstate;
|
||||
|
||||
// 3.1.6
|
||||
uint16_t blinktime;
|
||||
uint16_t blinkcount;
|
||||
|
||||
// 3.2.4
|
||||
uint16_t ws_pixels;
|
||||
uint8_t ws_red;
|
||||
uint8_t ws_green;
|
||||
|
@ -162,18 +168,22 @@ struct SYSCFG {
|
|||
uint8_t ws_width;
|
||||
uint16_t ws_wakeup;
|
||||
|
||||
// 3.2.5
|
||||
char friendlyname[4][33];
|
||||
|
||||
// 3.2.8
|
||||
char switch_topic[33];
|
||||
byte mqtt_switch_retain;
|
||||
uint8_t mqtt_enabled;
|
||||
|
||||
// 3.2.12
|
||||
uint8_t sleep;
|
||||
|
||||
// 3.9.3
|
||||
uint16_t domoticz_switch_idx[4];
|
||||
uint16_t domoticz_sensor_idx[12];
|
||||
|
||||
uint8_t module;
|
||||
mytmplt my_module;
|
||||
|
||||
uint16_t led_pixels;
|
||||
uint8_t led_color[5];
|
||||
uint8_t led_table;
|
||||
|
@ -184,13 +194,20 @@ struct SYSCFG {
|
|||
uint8_t led_width;
|
||||
uint16_t led_wakeup;
|
||||
|
||||
// 3.9.7
|
||||
uint8_t emulation;
|
||||
|
||||
// 3.9.20
|
||||
char web_password[33];
|
||||
|
||||
// 3.9.21
|
||||
uint8_t switchmode[4];
|
||||
|
||||
// 4.0.4
|
||||
char ntp_server[3][33];
|
||||
uint16_t pulsetime[MAX_PULSETIMERS];
|
||||
|
||||
// 4.0.7
|
||||
uint16_t pwmvalue[5];
|
||||
|
||||
} sysCfg;
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
|
||||
//#define ALLOW_MIGRATE_TO_V3
|
||||
#ifdef ALLOW_MIGRATE_TO_V3
|
||||
#define VERSION 0x03091E00 // 3.9.30
|
||||
#define VERSION 0x03091F00 // 3.9.31
|
||||
#else
|
||||
#define VERSION 0x04000700 // 4.0.7
|
||||
#define VERSION 0x04000800 // 4.0.8
|
||||
#endif // ALLOW_MIGRATE_TO_V3
|
||||
|
||||
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
|
||||
|
@ -115,7 +115,7 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
|
|||
#define MAX_PULSETIMERS 4 // Max number of supported pulse timers
|
||||
#define WS2812_MAX_LEDS 256 // Max number of LEDs
|
||||
|
||||
#define PWM_RANGE 1023 // 127..1023 but as Color is addressed by 8 bits it should be 255 for my code
|
||||
#define PWM_RANGE 1023 // 255..1023 needs to be devisible by 256
|
||||
#define PWM_FREQ 1000 // 100..1000 Hz led refresh
|
||||
|
||||
#define MAX_POWER_HOLD 10 // Time in SECONDS to allow max agreed power (Pow)
|
||||
|
@ -132,11 +132,7 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
|
|||
#define INPUT_BUFFER_SIZE 100 // Max number of characters in serial buffer
|
||||
#define TOPSZ 60 // Max number of characters in topic string
|
||||
#define LOGSZ 128 // Max number of characters in log string
|
||||
#ifdef USE_MQTT_TLS
|
||||
#define MAX_LOG_LINES 10 // Max number of lines in weblog
|
||||
#else
|
||||
#define MAX_LOG_LINES 20 // Max number of lines in weblog
|
||||
#endif
|
||||
|
||||
#define APP_BAUDRATE 115200 // Default serial baudrate
|
||||
#define MAX_STATUS 11 // Max number of status lines
|
||||
|
@ -144,8 +140,8 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
|
|||
enum butt_t {PRESSED, NOT_PRESSED};
|
||||
|
||||
#include "support.h" // Global support
|
||||
#include <PubSubClient.h> // MQTT
|
||||
|
||||
#include <PubSubClient.h> // MQTT
|
||||
#define MESSZ 360 // Max number of characters in JSON message string (4 x DS18x20 sensors)
|
||||
#if (MQTT_MAX_PACKET_SIZE -TOPSZ -7) < MESSZ // If the max message size is too small, throw an error at compile time
|
||||
// See pubsubclient.c line 359
|
||||
|
@ -620,7 +616,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
|
|||
#ifdef USE_MQTT_TLS
|
||||
else if (!strcmp(type,"MQTTFINGERPRINT")) {
|
||||
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_fingerprint))) {
|
||||
strlcpy(sysCfg.mqtt_fingerprint, (payload == 1) ? MQTT_FINGERPRINT : dataBuf, sizeof(sysCfg.mqtt_fingerprint));
|
||||
strlcpy(sysCfg.mqtt_fingerprint, (!strcmp(dataBuf,"0")) ? "" : (payload == 1) ? MQTT_FINGERPRINT : dataBuf, sizeof(sysCfg.mqtt_fingerprint));
|
||||
restartflag = 2;
|
||||
}
|
||||
snprintf_P(svalue, ssvalue, PSTR("{\"MqttFingerprint\":\"%s\"}"), sysCfg.mqtt_fingerprint);
|
||||
|
@ -635,14 +631,14 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
|
|||
}
|
||||
else if (!strcmp(type,"MQTTUSER")) {
|
||||
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_user))) {
|
||||
strlcpy(sysCfg.mqtt_user, (payload == 1) ? MQTT_USER : dataBuf, sizeof(sysCfg.mqtt_user));
|
||||
strlcpy(sysCfg.mqtt_user, (!strcmp(dataBuf,"0")) ? "" : (payload == 1) ? MQTT_USER : dataBuf, sizeof(sysCfg.mqtt_user));
|
||||
restartflag = 2;
|
||||
}
|
||||
snprintf_P(svalue, ssvalue, PSTR("[\"MqttUser\":\"%s\"}"), sysCfg.mqtt_user);
|
||||
}
|
||||
else if (!strcmp(type,"MQTTPASSWORD")) {
|
||||
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_pwd))) {
|
||||
strlcpy(sysCfg.mqtt_pwd, (payload == 1) ? MQTT_PASS : dataBuf, sizeof(sysCfg.mqtt_pwd));
|
||||
strlcpy(sysCfg.mqtt_pwd, (!strcmp(dataBuf,"0")) ? "" : (payload == 1) ? MQTT_PASS : dataBuf, sizeof(sysCfg.mqtt_pwd));
|
||||
restartflag = 2;
|
||||
}
|
||||
snprintf_P(svalue, ssvalue, PSTR("{\"MqttPassword\":\"%s\"}"), sysCfg.mqtt_pwd);
|
||||
|
@ -672,7 +668,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
|
|||
for(i = 0; i <= data_len; i++)
|
||||
if ((dataBuf[i] == '/') || (dataBuf[i] == '+') || (dataBuf[i] == '#') || (dataBuf[i] == ' ')) dataBuf[i] = '_';
|
||||
if (!strcmp(dataBuf, MQTTClient)) payload = 1;
|
||||
strlcpy(sysCfg.button_topic, (payload == 1) ? sysCfg.mqtt_topic : dataBuf, sizeof(sysCfg.button_topic));
|
||||
strlcpy(sysCfg.button_topic, (!strcmp(dataBuf,"0")) ? "" : (payload == 1) ? sysCfg.mqtt_topic : dataBuf, sizeof(sysCfg.button_topic));
|
||||
}
|
||||
snprintf_P(svalue, ssvalue, PSTR("{\"ButtonTopic\":\"%s\"}"), sysCfg.button_topic);
|
||||
}
|
||||
|
@ -681,7 +677,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
|
|||
for(i = 0; i <= data_len; i++)
|
||||
if ((dataBuf[i] == '/') || (dataBuf[i] == '+') || (dataBuf[i] == '#') || (dataBuf[i] == ' ')) dataBuf[i] = '_';
|
||||
if (!strcmp(dataBuf, MQTTClient)) payload = 1;
|
||||
strlcpy(sysCfg.switch_topic, (payload == 1) ? sysCfg.mqtt_topic : dataBuf, sizeof(sysCfg.switch_topic));
|
||||
strlcpy(sysCfg.switch_topic, (!strcmp(dataBuf,"0")) ? "" : (payload == 1) ? sysCfg.mqtt_topic : dataBuf, sizeof(sysCfg.switch_topic));
|
||||
}
|
||||
snprintf_P(svalue, ssvalue, PSTR("{\"SwitchTopic\":\"%s\"}"), sysCfg.switch_topic);
|
||||
}
|
||||
|
@ -1038,7 +1034,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
|||
}
|
||||
else if (!strcmp(type,"NTPSERVER") && (index > 0) && (index <= 3)) {
|
||||
if ((data_len > 0) && (data_len < sizeof(sysCfg.ntp_server[0]))) {
|
||||
strlcpy(sysCfg.ntp_server[index -1], (payload == 1) ? (index==1)?NTP_SERVER1:(index==2)?NTP_SERVER2:NTP_SERVER3 : dataBuf, sizeof(sysCfg.ntp_server[0]));
|
||||
strlcpy(sysCfg.ntp_server[index -1], (!strcmp(dataBuf,"0")) ? "" : (payload == 1) ? (index==1)?NTP_SERVER1:(index==2)?NTP_SERVER2:NTP_SERVER3 : dataBuf, sizeof(sysCfg.ntp_server[0]));
|
||||
for (i = 0; i < strlen(sysCfg.ntp_server[index -1]); i++) if (sysCfg.ntp_server[index -1][i] == ',') sysCfg.ntp_server[index -1][i] = '.';
|
||||
restartflag = 2;
|
||||
}
|
||||
|
@ -1128,11 +1124,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
|||
}
|
||||
else if (!strcmp(type,"WEBPASSWORD")) {
|
||||
if ((data_len > 0) && (data_len < sizeof(sysCfg.web_password))) {
|
||||
if (payload == 0) {
|
||||
sysCfg.web_password[0] = 0; // No password
|
||||
} else {
|
||||
strlcpy(sysCfg.web_password, (payload == 1) ? WEB_PASSWORD : dataBuf, sizeof(sysCfg.web_password));
|
||||
}
|
||||
strlcpy(sysCfg.web_password, (!strcmp(dataBuf,"0")) ? "" : (payload == 1) ? WEB_PASSWORD : dataBuf, sizeof(sysCfg.web_password));
|
||||
}
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"WebPassword\":\"%s\"}"), sysCfg.web_password);
|
||||
}
|
||||
|
@ -1757,7 +1749,7 @@ void stateloop()
|
|||
} else {
|
||||
flag = (multipress == 1);
|
||||
}
|
||||
if (flag && sysCfg.mqtt_enabled && mqttClient.connected() && strcmp(sysCfg.button_topic, "0")) {
|
||||
if (flag && sysCfg.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.button_topic) != 0) && strcmp(sysCfg.button_topic, "0")) {
|
||||
send_button_power(0, multipress, 2); // Execute command via MQTT using ButtonTopic to sync external clients
|
||||
} else {
|
||||
if ((multipress == 1) || (multipress == 2)) {
|
||||
|
@ -1780,7 +1772,7 @@ void stateloop()
|
|||
for (byte i = 1; i < Maxdevice; i++) if (pin[GPIO_KEY1 +i] < 99) {
|
||||
button = digitalRead(pin[GPIO_KEY1 +i]);
|
||||
if ((button == PRESSED) && (lastbutton[i] == NOT_PRESSED)) {
|
||||
if (sysCfg.mqtt_enabled && mqttClient.connected() && strcmp(sysCfg.button_topic, "0")) {
|
||||
if (sysCfg.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.button_topic) != 0) && strcmp(sysCfg.button_topic, "0")) {
|
||||
send_button_power(0, i +1, 2); // Execute commend via MQTT
|
||||
} else {
|
||||
do_cmnd_power(i +1, 2); // Execute command internally
|
||||
|
@ -1789,7 +1781,6 @@ void stateloop()
|
|||
lastbutton[i] = button;
|
||||
}
|
||||
|
||||
// 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]) {
|
||||
|
@ -1811,7 +1802,7 @@ void stateloop()
|
|||
if ((button == NOT_PRESSED) && (lastwallswitch[i] == PRESSED)) switchflag = 2; // Toggle with releasing pushbutton from Gnd
|
||||
}
|
||||
if (switchflag < 3) {
|
||||
if (sysCfg.mqtt_enabled && mqttClient.connected() && strcmp(sysCfg.switch_topic,"0")) {
|
||||
if (sysCfg.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.switch_topic) != 0) && strcmp(sysCfg.switch_topic, "0")) {
|
||||
send_button_power(1, i +1, switchflag); // Execute commend via MQTT
|
||||
} else {
|
||||
do_cmnd_power(i +1, switchflag); // Execute command internally (if i < Maxdevice)
|
||||
|
|
|
@ -157,6 +157,10 @@
|
|||
* No user configurable items below
|
||||
\*********************************************************************************************/
|
||||
|
||||
#if defined(USE_MQTT_TLS) && defined(USE_WEBSERVER)
|
||||
#error "Select either USE_MQTT_TLS or USE_WEBSERVER as there is just not enough memory to play with"
|
||||
#endif
|
||||
|
||||
#if (ARDUINO < 10610)
|
||||
#error "This software is supported with Arduino IDE starting from 1.6.10 and ESP8266 Release 2.3.0"
|
||||
#endif
|
||||
|
|
|
@ -103,7 +103,8 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM =
|
|||
"t=document.getElementById('t1');"
|
||||
"if(p==1){"
|
||||
"c=document.getElementById('c1');"
|
||||
"o='&c1='+c.value;"
|
||||
// "o='&c1='+c.value;"
|
||||
"o='&c1='+encodeURI(c.value);"
|
||||
"c.value='';"
|
||||
"t.scrollTop=sn;"
|
||||
"}"
|
||||
|
@ -691,8 +692,8 @@ void handleMqtt()
|
|||
page.replace("{m1}", sysCfg.mqtt_host);
|
||||
page.replace("{m2}", String(sysCfg.mqtt_port));
|
||||
page.replace("{m3}", sysCfg.mqtt_client);
|
||||
page.replace("{m4}", sysCfg.mqtt_user);
|
||||
page.replace("{m5}", sysCfg.mqtt_pwd);
|
||||
page.replace("{m4}", (sysCfg.mqtt_user[0] == '\0')?"0":sysCfg.mqtt_user);
|
||||
page.replace("{m5}", (sysCfg.mqtt_pwd[0] == '\0')?"0":sysCfg.mqtt_pwd);
|
||||
page.replace("{m6}", sysCfg.mqtt_topic);
|
||||
page += FPSTR(HTTP_FORM_END);
|
||||
page += FPSTR(HTTP_BTN_CONF);
|
||||
|
@ -829,8 +830,8 @@ void handleSave()
|
|||
strlcpy(sysCfg.mqtt_host, (!strlen(webServer->arg("mh").c_str())) ? MQTT_HOST : webServer->arg("mh").c_str(), sizeof(sysCfg.mqtt_host));
|
||||
sysCfg.mqtt_port = (!strlen(webServer->arg("ml").c_str())) ? MQTT_PORT : atoi(webServer->arg("ml").c_str());
|
||||
strlcpy(sysCfg.mqtt_client, (!strlen(webServer->arg("mc").c_str())) ? MQTT_CLIENT_ID : webServer->arg("mc").c_str(), sizeof(sysCfg.mqtt_client));
|
||||
strlcpy(sysCfg.mqtt_user, (!strlen(webServer->arg("mu").c_str())) ? MQTT_USER : webServer->arg("mu").c_str(), sizeof(sysCfg.mqtt_user));
|
||||
strlcpy(sysCfg.mqtt_pwd, (!strlen(webServer->arg("mp").c_str())) ? MQTT_PASS : webServer->arg("mp").c_str(), sizeof(sysCfg.mqtt_pwd));
|
||||
strlcpy(sysCfg.mqtt_user, (!strlen(webServer->arg("mu").c_str())) ? MQTT_USER : (!strcmp(webServer->arg("mu").c_str(),"0")) ? "" : webServer->arg("mu").c_str(), sizeof(sysCfg.mqtt_user));
|
||||
strlcpy(sysCfg.mqtt_pwd, (!strlen(webServer->arg("mp").c_str())) ? MQTT_PASS : (!strcmp(webServer->arg("mp").c_str(),"0")) ? "" : webServer->arg("mp").c_str(), sizeof(sysCfg.mqtt_pwd));
|
||||
strlcpy(sysCfg.mqtt_topic, (!strlen(webServer->arg("mt").c_str())) ? MQTT_TOPIC : webServer->arg("mt").c_str(), sizeof(sysCfg.mqtt_topic));
|
||||
snprintf_P(log, sizeof(log), PSTR("HTTP: MQTT Host %s, Port %d, Client %s, User %s, Password %s, Topic %s"),
|
||||
sysCfg.mqtt_host, sysCfg.mqtt_port, sysCfg.mqtt_client, sysCfg.mqtt_user, sysCfg.mqtt_pwd, sysCfg.mqtt_topic);
|
||||
|
@ -855,8 +856,7 @@ void handleSave()
|
|||
break;
|
||||
#endif // USE_DOMOTICZ
|
||||
case 5:
|
||||
strlcpy(sysCfg.web_password, (!strlen(webServer->arg("p1").c_str())) ? WEB_PASSWORD : webServer->arg("p1").c_str(), sizeof(sysCfg.web_password));
|
||||
if (sysCfg.web_password[0] == '0') sysCfg.web_password[0] = '\0';
|
||||
strlcpy(sysCfg.web_password, (!strlen(webServer->arg("p1").c_str())) ? WEB_PASSWORD : (!strcmp(webServer->arg("p1").c_str(),"0")) ? "" : webServer->arg("p1").c_str(), sizeof(sysCfg.web_password));
|
||||
sysCfg.mqtt_enabled = webServer->hasArg("b1");
|
||||
#ifdef USE_EMULATION
|
||||
sysCfg.emulation = (!strlen(webServer->arg("b2").c_str())) ? 0 : atoi(webServer->arg("b2").c_str());
|
||||
|
@ -1152,7 +1152,8 @@ void handleCmnd()
|
|||
if (valid) {
|
||||
byte curridx = logidx;
|
||||
if (strlen(webServer->arg("cmnd").c_str())) {
|
||||
snprintf_P(svalue, sizeof(svalue), webServer->arg("cmnd").c_str());
|
||||
// snprintf_P(svalue, sizeof(svalue), webServer->arg("cmnd").c_str());
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%s"), webServer->arg("cmnd").c_str());
|
||||
byte syslog_now = syslog_level;
|
||||
syslog_level = 0; // Disable UDP syslog to not trigger hardware WDT
|
||||
do_cmnd(svalue);
|
||||
|
@ -1211,7 +1212,7 @@ void handleAjax()
|
|||
byte cflg = 1, counter = 99;
|
||||
|
||||
if (strlen(webServer->arg("c1").c_str())) {
|
||||
snprintf_P(svalue, sizeof(svalue), webServer->arg("c1").c_str());
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%s"), webServer->arg("c1").c_str());
|
||||
snprintf_P(log, sizeof(log), PSTR("CMND: %s"), svalue);
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
byte syslog_now = syslog_level;
|
||||
|
|
Loading…
Reference in New Issue