4.0.2 20170308
* Restore correct seriallog level after Serial logging was disabled
* Add simple dimmer slider to Sonoff Led web page
* Reduced root webpage size by 31%
* Expand Status 2 with Build date/time and core version
* Fix webserver redirection when not in WifiManager mode (#156)
* Add command ButtonRestrict On/Off to restrict access to button hold
and button multi press options above 2 (#161)
* Fix DS18S20 negative temperature readings (#165)
* Fix crlf compilation error due to bad syntax (#144, #167)
This commit is contained in:
arendst 2017-03-08 16:20:45 +01:00
parent 4797696b39
commit ac84010015
14 changed files with 333 additions and 232 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 **4.0.1** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
Current version is **4.0.2** - 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.

Binary file not shown.

View File

@ -1,4 +1,14 @@
/* 4.0.1 20170305
/* 4.0.2 20170308
* Restore correct seriallog level after Serial logging was disabled
* Add simple dimmer slider to Sonoff Led web page
* Reduced root webpage size by 31%
* Expand Status 2 with Build date/time and core version
* Fix webserver redirection when not in WifiManager mode (#156)
* Add command ButtonRestrict On/Off to restrict access to button hold and button multi press options above 2 (#161)
* Fix DS18S20 negative temperature readings (#165)
* Fix crlf compilation error due to bad syntax (#144, #167)
*
* 4.0.1 20170305
* Fix char default sizes and set MESSZ to 360 (#143)
* Fix SerialLog setting status
* Disable syslog when emulation is active

View File

@ -77,10 +77,10 @@ struct SYSCFG {
unsigned long saveFlag;
unsigned long version;
unsigned long bootcount;
byte migflg; // Not used since 3.9.1
byte migflg; // Not used since 3.9.1
int16_t savedata;
byte savestate;
byte model; // Not used since 3.9.1
byte model; // Not used since 3.9.1
int8_t timezone;
char otaUrl[101];
char ex_friendlyname[33]; // Not used since 3.2.5 - see below
@ -111,12 +111,12 @@ struct SYSCFG {
byte mqtt_button_retain;
byte mqtt_power_retain;
byte value_units;
byte message_format; // Not used since 3.2.6a
byte button_restrict; // Was message_format until 3.2.6a
uint16_t tele_period;
uint8_t power;
uint8_t ledstate;
uint8_t ex_switchmode; // Not used since 3.9.21
uint8_t ex_switchmode; // Not used since 3.9.21
char domoticz_in_topic[33];
char domoticz_out_topic[33];
@ -188,7 +188,6 @@ struct SYSCFG {
char web_password[33];
uint8_t switchmode[4];
} sysCfg;
struct RTCMEM {

View File

@ -414,7 +414,6 @@ void CFG_DefaultSet1()
void CFG_DefaultSet2()
{
sysCfg.migflg = 0xA5;
sysCfg.savedata = SAVE_DATA;
sysCfg.savestate = SAVE_STATE;
sysCfg.module = MODULE;
@ -449,8 +448,9 @@ void CFG_DefaultSet2()
strlcpy(sysCfg.mqtt_subtopic, MQTT_SUBTOPIC, sizeof(sysCfg.mqtt_subtopic));
sysCfg.mqtt_button_retain = MQTT_BUTTON_RETAIN;
sysCfg.mqtt_power_retain = MQTT_POWER_RETAIN;
sysCfg.value_units = VALUE_UNITS;
sysCfg.message_format = 0;
sysCfg.value_units = 0;
sysCfg.button_restrict = 0;
// sysCfg.message_format = 0;
sysCfg.tele_period = TELE_PERIOD;
sysCfg.power = APP_POWER;
@ -614,7 +614,7 @@ void CFG_Migrate_Part2()
sysCfg.hlw_imax = sysCfg2.hlw_imax;
}
if (sysCfg2.version >= 0x02000700) { // 2.0.7
sysCfg.message_format = 0;
// sysCfg.message_format = 0;
strlcpy(sysCfg.domoticz_in_topic, sysCfg2.domoticz_in_topic, sizeof(sysCfg.domoticz_in_topic));
strlcpy(sysCfg.domoticz_out_topic, sysCfg2.domoticz_out_topic, sizeof(sysCfg.domoticz_out_topic));
sysCfg.domoticz_update_timer = sysCfg2.domoticz_update_timer;
@ -670,7 +670,7 @@ void CFG_Delta()
sysCfg.blinkcount = APP_BLINKCOUNT;
}
if (sysCfg.version < 0x03011000) { // 3.1.16 - Add parameter
getClient(sysCfg.ex_friendlyname, sysCfg.mqtt_client, sizeof(sysCfg.ex_friendlyname));
getClient(sysCfg.friendlyname[0], sysCfg.mqtt_client, sizeof(sysCfg.friendlyname[0]));
}
if (sysCfg.version < 0x03020400) { // 3.2.4 - Add parameter
sysCfg.ws_pixels = WS2812_LEDS;
@ -686,7 +686,7 @@ void CFG_Delta()
sysCfg.ws_wakeup = 0;
}
if (sysCfg.version < 0x03020500) { // 3.2.5 - Add parameter
strlcpy(sysCfg.friendlyname[0], sysCfg.ex_friendlyname, sizeof(sysCfg.friendlyname[0]));
getClient(sysCfg.friendlyname[0], sysCfg.mqtt_client, sizeof(sysCfg.friendlyname[0]));
strlcpy(sysCfg.friendlyname[1], FRIENDLY_NAME"2", sizeof(sysCfg.friendlyname[1]));
strlcpy(sysCfg.friendlyname[2], FRIENDLY_NAME"3", sizeof(sysCfg.friendlyname[2]));
strlcpy(sysCfg.friendlyname[3], FRIENDLY_NAME"4", sizeof(sysCfg.friendlyname[3]));
@ -725,8 +725,12 @@ void CFG_Delta()
if (sysCfg.version < 0x03091500) {
for (byte i = 0; i < 4; i++) sysCfg.switchmode[i] = sysCfg.ex_switchmode;
}
if (sysCfg.version < 0x04000200) {
sysCfg.button_restrict = 0;
}
sysCfg.version = VERSION;
}
}

View File

@ -12,9 +12,9 @@
//#define ALLOW_MIGRATE_TO_V3
#ifdef ALLOW_MIGRATE_TO_V3
#define VERSION 0x03091800 // 3.9.24
#define VERSION 0x03091900 // 3.9.25
#else
#define VERSION 0x04000100 // 4.0.1
#define VERSION 0x04000200 // 4.0.2
#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};
@ -108,7 +108,6 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
#define HLW_UREF_PULSE 1950 // was 1666us = 600Hz = 220V
#define HLW_IREF_PULSE 3500 // was 1666us = 600Hz = 4.545A
#define VALUE_UNITS 0 // Default do not show value units (Hr, Sec, V, A, W etc.)
#define MQTT_SUBTOPIC "POWER" // Default MQTT subtopic (POWER or LIGHT)
#define MQTT_RETRY_SECS 10 // Seconds to retry MQTT connection
#define APP_POWER 0 // Default saved power state Off
@ -591,6 +590,147 @@ void mqtt_reconnect()
/********************************************************************************************/
boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue)
{
boolean serviced = true;
char stemp1[TOPSZ], stemp2[10];
uint16_t i;
if (!strcmp(type,"MQTTHOST")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_host))) {
strlcpy(sysCfg.mqtt_host, (payload == 1) ? MQTT_HOST : dataBuf, sizeof(sysCfg.mqtt_host));
restartflag = 2;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MqttHost\",\"%s\"}"), sysCfg.mqtt_host);
}
else if (!strcmp(type,"MQTTPORT")) {
if ((data_len > 0) && (payload > 0) && (payload < 32766)) {
sysCfg.mqtt_port = (payload == 1) ? MQTT_PORT : payload;
restartflag = 2;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MqttPort\":%d}"), sysCfg.mqtt_port);
}
#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));
restartflag = 2;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MqttFingerprint\":\"%s\"}"), sysCfg.mqtt_fingerprint);
}
#endif
else if (!grpflg && !strcmp(type,"MQTTCLIENT")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_client))) {
strlcpy(sysCfg.mqtt_client, (payload == 1) ? MQTT_CLIENT_ID : dataBuf, sizeof(sysCfg.mqtt_client));
restartflag = 2;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MqttClient\":\"%s\"}"), sysCfg.mqtt_client);
}
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));
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));
restartflag = 2;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MqttPassword\":\"%s\"}"), sysCfg.mqtt_pwd);
}
else if (!strcmp(type,"GROUPTOPIC")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_grptopic))) {
for(i = 0; i <= data_len; i++)
if ((dataBuf[i] == '/') || (dataBuf[i] == '+') || (dataBuf[i] == '#')) dataBuf[i] = '_';
if (!strcmp(dataBuf, MQTTClient)) payload = 1;
strlcpy(sysCfg.mqtt_grptopic, (payload == 1) ? MQTT_GRPTOPIC : dataBuf, sizeof(sysCfg.mqtt_grptopic));
restartflag = 2;
}
snprintf_P(svalue, ssvalue, PSTR("{\"GroupTopic\":\"%s\"}"), sysCfg.mqtt_grptopic);
}
else if (!grpflg && !strcmp(type,"TOPIC")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_topic))) {
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.mqtt_topic, (payload == 1) ? MQTT_TOPIC : dataBuf, sizeof(sysCfg.mqtt_topic));
restartflag = 2;
}
snprintf_P(svalue, ssvalue, PSTR("{\"Topic\":\"%s\"}"), sysCfg.mqtt_topic);
}
else if (!grpflg && !strcmp(type,"BUTTONTOPIC")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.button_topic))) {
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));
}
snprintf_P(svalue, ssvalue, PSTR("{\"ButtonTopic\":\"%s\"}"), sysCfg.button_topic);
}
else if (!grpflg && !strcmp(type,"SWITCHTOPIC")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.switch_topic))) {
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));
}
snprintf_P(svalue, ssvalue, PSTR("{\"SwitchTopic\":\"%s\"}"), sysCfg.switch_topic);
}
else if (!strcmp(type,"BUTTONRETAIN")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
strlcpy(sysCfg.button_topic, sysCfg.mqtt_topic, sizeof(sysCfg.button_topic));
if (!payload) {
for(i = 1; i <= Maxdevice; i++) {
send_button_power(0, i, 3); // Clear MQTT retain in broker
}
}
sysCfg.mqtt_button_retain = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"ButtonRetain\":\"%s\"}"), (sysCfg.mqtt_button_retain) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (!strcmp(type,"SWITCHRETAIN")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
strlcpy(sysCfg.button_topic, sysCfg.mqtt_topic, sizeof(sysCfg.button_topic));
if (!payload) {
for(i = 1; i <= 4; i++) {
send_button_power(1, i, 3); // Clear MQTT retain in broker
}
}
sysCfg.mqtt_switch_retain = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"SwitchRetain\":\"%s\"}"), (sysCfg.mqtt_switch_retain) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (!strcmp(type,"POWERRETAIN") || !strcmp(type,"LIGHTRETAIN")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
if (!payload) {
for(i = 1; i <= Maxdevice; i++) { // Clear MQTT retain in broker
snprintf_P(stemp2, sizeof(stemp2), PSTR("%d"), i);
snprintf_P(stemp1, sizeof(stemp1), PSTR("%s/%s/POWER%s"), PUB_PREFIX, sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp2 : "");
mqtt_publish(stemp1, "", sysCfg.mqtt_power_retain);
snprintf_P(stemp1, sizeof(stemp1), PSTR("%s/%s/LIGHT%s"), PUB_PREFIX, sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp2 : "");
mqtt_publish(stemp1, "", sysCfg.mqtt_power_retain);
}
}
sysCfg.mqtt_power_retain = payload;
}
snprintf_P(stemp1, sizeof(stemp1), PSTR("%s"), (!strcmp(sysCfg.mqtt_subtopic,"POWER")) ? "Power" : "Light");
snprintf_P(svalue, ssvalue, PSTR("{\"%sRetain\":\"%s\"}"), stemp1, (sysCfg.mqtt_power_retain) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
#ifdef USE_DOMOTICZ
else if (domoticz_command(type, index, dataBuf, data_len, payload, svalue, ssvalue)) {
// Serviced
}
#endif // USE_DOMOTICZ
else {
serviced = false;
}
return serviced;
}
/********************************************************************************************/
void mqttDataCb(char* topic, byte* data, unsigned int data_len)
{
char *str;
@ -603,9 +743,8 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
}
char topicBuf[TOPSZ], dataBuf[data_len+1], dataBufUc[128], svalue[MESSZ];
char topicBuf[TOPSZ], dataBuf[data_len+1], dataBufUc[128], svalue[MESSZ], stemp1[TOPSZ];
char *p, *mtopic = NULL, *type = NULL;
char stemp1[TOPSZ], stemp2[10];
uint16_t i = 0, grpflg = 0, index;
strncpy(topicBuf, topic, sizeof(topicBuf));
@ -721,6 +860,25 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"SaveState\":\"%s\"}"), (sysCfg.savestate) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (!strcmp(type,"BUTTONRESTRICT")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
sysCfg.button_restrict = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"ButtonRestrict\":\"%s\"}"), (sysCfg.button_restrict) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (!strcmp(type,"UNITS")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
sysCfg.value_units = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Units\":\"%s\"}"), (sysCfg.value_units) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (!strcmp(type,"MQTT")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
sysCfg.mqtt_enabled = payload;
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Mqtt\":\"%s\"}"), (sysCfg.mqtt_enabled) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (!strcmp(type,"MODULE")) {
if ((data_len > 0) && (payload > 0) && (payload <= MAXMODULE)) {
sysCfg.module = payload -1;
@ -951,19 +1109,6 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
#endif // USE_EMULATION
#endif // USE_WEBSERVER
else if (!strcmp(type,"UNITS")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
sysCfg.value_units = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Units\":\"%s\"}"), (sysCfg.value_units) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (!strcmp(type,"MQTT")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
sysCfg.mqtt_enabled = payload;
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Mqtt\":\"%s\"}"), (sysCfg.mqtt_enabled) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (!strcmp(type,"TELEPERIOD")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.tele_period = (payload == 1) ? TELE_PERIOD : payload;
@ -1034,144 +1179,17 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
CFG_Dump();
snprintf_P(svalue, sizeof(svalue), PSTR("{\"CfgDump\":\"Done\"}"));
}
else if (sysCfg.mqtt_enabled && mqtt_command(grpflg, type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) {
// Serviced
}
else if (hlw_flg && hlw_command(type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) {
// Serviced
}
#ifdef USE_I2C
else if (i2c_flg && !strcmp(type,"I2CSCAN")) {
i2c_scan(svalue, sizeof(svalue));
}
#endif // USE_I2C
/*** MQTT Commands ***************************************************************************/
else if (sysCfg.mqtt_enabled && !strcmp(type,"MQTTHOST")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_host))) {
strlcpy(sysCfg.mqtt_host, (payload == 1) ? MQTT_HOST : dataBuf, sizeof(sysCfg.mqtt_host));
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MqttHost\",\"%s\"}"), sysCfg.mqtt_host);
}
else if (sysCfg.mqtt_enabled && !strcmp(type,"MQTTPORT")) {
if ((data_len > 0) && (payload > 0) && (payload < 32766)) {
sysCfg.mqtt_port = (payload == 1) ? MQTT_PORT : payload;
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MqttPort\":%d}"), sysCfg.mqtt_port);
}
#ifdef USE_MQTT_TLS
else if (sysCfg.mqtt_enabled && !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));
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MqttFingerprint\":\"%s\"}"), sysCfg.mqtt_fingerprint);
}
#endif
else if (sysCfg.mqtt_enabled && !grpflg && !strcmp(type,"MQTTCLIENT")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_client))) {
strlcpy(sysCfg.mqtt_client, (payload == 1) ? MQTT_CLIENT_ID : dataBuf, sizeof(sysCfg.mqtt_client));
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MqttClient\":\"%s\"}"), sysCfg.mqtt_client);
}
else if (sysCfg.mqtt_enabled && !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));
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("[\"MqttUser\":\"%s\"}"), sysCfg.mqtt_user);
}
else if (sysCfg.mqtt_enabled && !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));
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MqttPassword\":\"%s\"}"), sysCfg.mqtt_pwd);
}
else if (sysCfg.mqtt_enabled && !strcmp(type,"GROUPTOPIC")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_grptopic))) {
for(i = 0; i <= data_len; i++)
if ((dataBuf[i] == '/') || (dataBuf[i] == '+') || (dataBuf[i] == '#')) dataBuf[i] = '_';
if (!strcmp(dataBuf, MQTTClient)) payload = 1;
strlcpy(sysCfg.mqtt_grptopic, (payload == 1) ? MQTT_GRPTOPIC : dataBuf, sizeof(sysCfg.mqtt_grptopic));
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"GroupTopic\":\"%s\"}"), sysCfg.mqtt_grptopic);
}
else if (sysCfg.mqtt_enabled && !grpflg && !strcmp(type,"TOPIC")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_topic))) {
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.mqtt_topic, (payload == 1) ? MQTT_TOPIC : dataBuf, sizeof(sysCfg.mqtt_topic));
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Topic\":\"%s\"}"), sysCfg.mqtt_topic);
}
else if (sysCfg.mqtt_enabled && !grpflg && !strcmp(type,"BUTTONTOPIC")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.button_topic))) {
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));
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"ButtonTopic\":\"%s\"}"), sysCfg.button_topic);
}
else if (sysCfg.mqtt_enabled && !grpflg && !strcmp(type,"SWITCHTOPIC")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.switch_topic))) {
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));
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"SwitchTopic\":\"%s\"}"), sysCfg.switch_topic);
}
else if (sysCfg.mqtt_enabled && !strcmp(type,"BUTTONRETAIN")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
strlcpy(sysCfg.button_topic, sysCfg.mqtt_topic, sizeof(sysCfg.button_topic));
if (!payload) {
for(i = 1; i <= Maxdevice; i++) {
send_button_power(0, i, 3); // Clear MQTT retain in broker
}
}
sysCfg.mqtt_button_retain = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"ButtonRetain\":\"%s\"}"), (sysCfg.mqtt_button_retain) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (sysCfg.mqtt_enabled && !strcmp(type,"SWITCHRETAIN")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
// strlcpy(sysCfg.button_topic, sysCfg.mqtt_topic, sizeof(sysCfg.button_topic));
if (!payload) {
for(i = 1; i <= 4; i++) {
send_button_power(1, i, 3); // Clear MQTT retain in broker
}
}
sysCfg.mqtt_switch_retain = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"SwitchRetain\":\"%s\"}"), (sysCfg.mqtt_switch_retain) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (sysCfg.mqtt_enabled && (!strcmp(type,"POWERRETAIN") || !strcmp(type,"LIGHTRETAIN"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
if (!payload) {
for(i = 1; i <= Maxdevice; i++) { // Clear MQTT retain in broker
snprintf_P(stemp2, sizeof(stemp2), PSTR("%d"), i);
snprintf_P(stemp1, sizeof(stemp1), PSTR("%s/%s/POWER%s"), PUB_PREFIX, sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp2 : "");
mqtt_publish(stemp1, "", sysCfg.mqtt_power_retain);
snprintf_P(stemp1, sizeof(stemp1), PSTR("%s/%s/LIGHT%s"), PUB_PREFIX, sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp2 : "");
mqtt_publish(stemp1, "", sysCfg.mqtt_power_retain);
}
}
sysCfg.mqtt_power_retain = payload;
}
snprintf_P(stemp1, sizeof(stemp1), PSTR("%s"), (!strcmp(sysCfg.mqtt_subtopic,"POWER")) ? "Power" : "Light");
snprintf_P(svalue, sizeof(svalue), PSTR("{\"%sRetain\":\"%s\"}"), stemp1, (sysCfg.mqtt_power_retain) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
#ifdef USE_DOMOTICZ
else if (sysCfg.mqtt_enabled && domoticz_command(type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) {
// Serviced
}
#endif // USE_DOMOTICZ
else if (hlw_flg && hlw_command(type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) {
// Serviced
}
#ifdef USE_WS2812
else if ((pin[GPIO_WS2812] < 99) && ws2812_command(type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) {
// Serviced
@ -1204,7 +1222,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
mqtt_publish_topic_P(0, PSTR("COMMANDS2"), svalue);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Commands3\":\"%s%s, PulseTime, BlinkTime, BlinkCount"), (Maxdevice == 1) ? "Power, Light" : "Power1, Power2, Light1 Light2", (sysCfg.module != MOTOR) ? ", PowerOnState" : "");
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Commands3\":\"%s%s, PulseTime, BlinkTime, BlinkCount, ButtonRestrict"), (Maxdevice == 1) ? "Power, Light" : "Power1, Power2, Light1 Light2", (sysCfg.module != MOTOR) ? ", PowerOnState" : "");
#ifdef USE_WEBSERVER
snprintf_P(svalue, sizeof(svalue), PSTR("%s, Weblog, Webserver, WebPassword, Emulation"), svalue);
#endif
@ -1377,8 +1395,10 @@ void publish_status(uint8_t payload)
}
if ((payload == 0) || (payload == 2)) {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusFWR\":{\"Program\":\"%s\", \"Boot\":%d, \"SDK\":\"%s\"}}"),
Version, ESP.getBootVersion(), ESP.getSdkVersion());
// snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusFWR\":{\"Program\":\"%s\", \"BuildDateTime\":\"%s/%s\", \"Boot\":%d, \"Core\":\"%s\", \"SDK\":\"%s\"}}"),
// Version, __DATE__, __TIME__, ESP.getBootVersion(), ESP.getCoreVersion().c_str(), ESP.getSdkVersion());
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusFWR\":{\"Program\":\"%s\", \"BuildDateTime\":\"%s\", \"Boot\":%d, \"Core\":\"%s\", \"SDK\":\"%s\"}}"),
Version, getBuildDateTime().c_str(), ESP.getBootVersion(), ESP.getCoreVersion().c_str(), ESP.getSdkVersion());
mqtt_publish_topic_P(option, PSTR("STATUS2"), svalue);
}
@ -1438,11 +1458,8 @@ void publish_status(uint8_t payload)
void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
{
char stime[21];
snprintf_P(svalue, ssvalue, PSTR("%s{\"Time\":\"%s\""), svalue, getDateTime().c_str());
snprintf_P(stime, sizeof(stime), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"),
rtcTime.Year, rtcTime.Month, rtcTime.Day, rtcTime.Hour, rtcTime.Minute, rtcTime.Second);
snprintf_P(svalue, ssvalue, PSTR("%s{\"Time\":\"%s\""), svalue, stime);
if (pin[GPIO_DSB] < 99) {
#ifdef USE_DS18B20
dsb_mqttPresent(svalue, ssvalue, djson);
@ -1481,10 +1498,7 @@ void every_second_cb()
void every_second()
{
char svalue[MESSZ], stime[21];
snprintf_P(stime, sizeof(stime), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"),
rtcTime.Year, rtcTime.Month, rtcTime.Day, rtcTime.Hour, rtcTime.Minute, rtcTime.Second);
char svalue[MESSZ];
if (pulse_timer > 111) pulse_timer--;
@ -1551,7 +1565,7 @@ void every_second()
if (tele_period >= sysCfg.tele_period) {
tele_period = 0;
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%s\", \"Uptime\":%d"), stime, uptime);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%s\", \"Uptime\":%d"), getDateTime().c_str(), uptime);
for (byte i = 0; i < Maxdevice; i++) {
if (Maxdevice == 1) { // Legacy
snprintf_P(svalue, sizeof(svalue), PSTR("%s, \"%s\":"), svalue, sysCfg.mqtt_subtopic);
@ -1577,7 +1591,7 @@ void every_second()
if ((rtcTime.Minute == 2) && (rtcTime.Second == 30)) {
uptime++;
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%s\", \"Uptime\":%d}"), stime, uptime);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%s\", \"Uptime\":%d}"), getDateTime().c_str(), uptime);
mqtt_publish_topic_P(1, PSTR("UPTIME"), svalue);
}
}
@ -1652,7 +1666,7 @@ void stateloop()
holdcount = 0;
} else {
holdcount++;
if (holdcount == (STATES *4)) { // 4 seconds button hold
if (!sysCfg.button_restrict && (holdcount == (STATES *4))) { // 4 seconds button hold
snprintf_P(scmnd, sizeof(scmnd), PSTR("reset 1"));
multipress = 0;
do_cmnd(scmnd);
@ -1669,8 +1683,7 @@ void stateloop()
}
if (flag && sysCfg.mqtt_enabled && mqttClient.connected() && strcmp(sysCfg.button_topic, "0")) {
send_button_power(0, multipress, 2); // Execute command via MQTT using ButtonTopic to sync external clients
} else
{
} else {
if ((multipress == 1) || (multipress == 2)) {
if (WIFI_State()) { // WPSconfig, Smartconfig or Wifimanager active
restartflag = 1;
@ -1678,8 +1691,10 @@ void stateloop()
do_cmnd_power(multipress, 2); // Execute command internally
}
} else {
snprintf_P(scmnd, sizeof(scmnd), commands[multipress -3]);
do_cmnd(scmnd);
if (!sysCfg.button_restrict) {
snprintf_P(scmnd, sizeof(scmnd), commands[multipress -3]);
do_cmnd(scmnd);
}
}
}
multipress = 0;
@ -1878,7 +1893,7 @@ void serial()
}
if (SerialInByte == '\n') {
serialInBuf[SerialInByteCounter] = 0; // serial data completed
if (seriallog_level < LOG_LEVEL_INFO) seriallog_level = LOG_LEVEL_INFO;
seriallog_level = (sysCfg.seriallog_level < LOG_LEVEL_INFO) ? LOG_LEVEL_INFO : sysCfg.seriallog_level;
snprintf_P(log, sizeof(log), PSTR("CMND: %s"), serialInBuf);
addLog(LOG_LEVEL_INFO, log);
do_cmnd(serialInBuf);

View File

@ -587,12 +587,49 @@ extern "C" {
Ticker tickerRTC;
static const uint8_t monthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // API starts months from 1, this array starts from 0
static const char monthNames[37] = { "JanFebMrtAprMayJunJulAugSepOctNovDec" };
static const char monthNames[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
uint32_t utctime = 0, loctime = 0, dsttime = 0, stdtime = 0, ntptime = 0, midnight = 1451602800;
rtcCallback rtcCb = NULL;
String getBuildDateTime()
{
// "2017-03-07T11:08:02"
char bdt[21];
char *str, *p, *smonth;
char mdate[] = __DATE__; // "Mar 7 2017"
int month, day, year;
// sscanf(mdate, "%s %d %d", bdt, &day, &year); // Not implemented in 2.3.0 and probably too many code
byte i = 0;
for (str = strtok_r(mdate, " ", &p); str && i < 3; str = strtok_r(NULL, " ", &p)) {
switch (i++) {
case 0: // Month
smonth = str;
break;
case 1: // Day
day = atoi(str);
break;
case 2: // Year
year = atoi(str);
}
}
month = (strstr(monthNames, smonth) -monthNames) /3 +1;
snprintf_P(bdt, sizeof(bdt), PSTR("%d-%02d-%02dT%s"), year, month, day, __TIME__);
return String(bdt);
}
String getDateTime()
{
// "2017-03-07T11:08:02"
char dt[21];
snprintf_P(dt, sizeof(dt), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"),
rtcTime.Year, rtcTime.Month, rtcTime.Day, rtcTime.Hour, rtcTime.Minute, rtcTime.Second);
return String(dt);
}
void breakTime(uint32_t timeInput, TIME_T &tm)
{
// break the given timeInput into time components

View File

@ -141,7 +141,7 @@
// When USE_WS2812_DMA is enabled expect Exceptions on Pow
/*********************************************************************************************\
* Compile a minimal version if upgrade memory gets tight.
* Compile a minimal version if upgrade memory gets tight ONLY TO BE USED FOR UPGRADE STEP 1!
* To be used as step 1 during upgrade.
* Step 2 is re-compile with option BE_MINIMAL commented out.
* !!! Needed for next release of Arduino/ESP8266 (+22k code, +2k mem) !!!

View File

@ -40,8 +40,11 @@ const char HTTP_HEAD[] PROGMEM =
"<meta charset='utf-8'>"
"<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,user-scalable=no\"/>"
"<title>{v}</title>"
"<script>"
"var cn=120;"
"var cn,x,lt;"
"cn=120;"
"x=null;" // Allow for abortion
"function u(){"
"if(cn>=0){"
"document.getElementById('t').innerHTML='Restart in '+cn+' seconds';"
@ -53,12 +56,10 @@ const char HTTP_HEAD[] PROGMEM =
"document.getElementById('s1').value=l.innerText||l.textContent;"
"document.getElementById('p1').focus();"
"}"
"var x=null;" // Allow for abortion
"var lt;" // Enable clearTimeout
"function la(p){"
"var a='';"
"if(la.arguments.length==1){"
"a='?o='+p;"
"a=p;"
"clearTimeout(lt);"
"}"
"if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1)
@ -72,6 +73,27 @@ const char HTTP_HEAD[] PROGMEM =
"x.send();"
"lt=setTimeout(la,2345);"
"}"
"function lb(p){"
"la('?d='+p);"
"}"
"</script>"
"<style>"
"div,fieldset,input,select{padding:5px;font-size:1em;}"
"input{width:95%;}"
"select{width:100%;}"
"textarea{resize:none;width:98%;height:318px;padding:5px;overflow:auto;}"
"body{text-align:center;font-family:verdana;}"
"td{padding:0px;}"
"button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;-webkit-transition-duration:0.4s;transition-duration:0.4s;}"
"button:hover{background-color:#006cba;}"
"</style>"
"</head>"
"<body>"
"<div style='text-align:left;display:inline-block;min-width:320px;'>"
"<div style='text-align:center;'><h3>{ha} Module</h3><h2>{h}</h2></div>";
const char HTTP_SCRIPT_CONSOL[] PROGMEM =
"var sn=0;" // Scroll position
"var id=99;" // Get most of weblog initially
"function l(p){" // Console log and command service
@ -106,25 +128,13 @@ const char HTTP_HEAD[] PROGMEM =
"lt=setTimeout(l,2345);"
"return false;"
"}"
"</script>"
"<style>"
"div,fieldset,input,select{padding:5px;font-size:1em;}"
"input{width:95%;}"
"select{width:100%;}"
"textarea{resize:none;width:98%;height:318px;padding:5px;overflow:auto;}"
"body{text-align:center;font-family:verdana;}"
"td{padding:0px;}"
"button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;-webkit-transition-duration:0.4s;transition-duration:0.4s;}"
"button:hover{background-color:#006cba;}"
"</script>";
const char HTTP_LNK_STYLE[] PROGMEM =
".q{float:right;width:64px;text-align:right;}"
".l{background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAALVBMVEX///8EBwfBwsLw8PAzNjaCg4NTVVUjJiZDRUUUFxdiZGSho6O"
"Sk5Pg4eFydHTCjaf3AAAAZElEQVQ4je2NSw7AIAhEBamKn97/uMXEGBvozkWb9C2Zx4xzWykBhFAeYp9gkLyZE0zIMno9n4g19hmdY39scwqVkOXaxph0ZCXQcqxSpgQpONa59wkRDOL93eA"
"XvimwlbPbwwVAegLS1HGfZAAAAABJRU5ErkJggg==') no-repeat left center;background-size:1em;}"
"</style>"
"</head>"
"<body>"
"<div style='text-align:left;display:inline-block;min-width:320px;'>"
"<div style='text-align:center;'><h3>{ha} Module</h3><h2>{h}</h2></div>";
"</style>";
const char HTTP_MSG_RSTRT[] PROGMEM =
"<br/><div style='text-align:center;'>Device will restart in a few seconds</div><br/>";
const char HTTP_BTN_MENU1[] PROGMEM =
@ -396,10 +406,15 @@ void handleRoot()
page += F("<div id='l1' name='l1'></div>");
if (Maxdevice) {
if (sysCfg.module == SONOFF_LED) {
snprintf_P(line, sizeof(line), PSTR("<input type='range' min='1' max='100' value='%d' onchange='lb(value)'>"),
sysCfg.led_dimmer[0]);
page += line;
}
page += F("<table style='width:100%'><tr>");
for (byte idx = 1; idx <= Maxdevice; idx++) {
snprintf_P(stemp, sizeof(stemp), PSTR(" %d"), idx);
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><button onclick='la(%d);'>Toggle%s</button></td>"),
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><button onclick='la(\"?o=%d\");'>Toggle%s</button></td>"),
100 / Maxdevice, idx, (Maxdevice > 1) ? stemp : "");
page += line;
}
@ -416,7 +431,14 @@ void handleRoot()
void handleAjax2()
{
char svalue[16];
if (strlen(webServer->arg("o").c_str())) do_cmnd_power(atoi(webServer->arg("o").c_str()), 2);
if (strlen(webServer->arg("d").c_str())) {
snprintf_P(svalue, sizeof(svalue), PSTR("dimmer %s"), webServer->arg("d").c_str());
do_cmnd(svalue);
}
String tpage = "";
if (hlw_flg) tpage += hlw_webPresent();
#ifdef USE_DS18B20
@ -445,18 +467,20 @@ void handleAjax2()
if (Maxdevice) {
page += F("<table style='width:100%'><tr>");
for (byte idx = 1; idx <= Maxdevice; idx++) {
/*
page += F("<td style='width:{1%'><div style='text-align:center;font-weight:bold;font-size:{2px'>{3</div></td>");
page.replace("{1", String(100 / Maxdevice));
page.replace("{2", String(70 - (Maxdevice * 8)));
page.replace("{3", (power & (0x01 << (idx -1))) ? "ON" : "OFF");
*/
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><div style='text-align:center;font-weight:bold;font-size:%dpx'>%s</div></td>"),
100 / Maxdevice, 70 - (Maxdevice * 8), (power & (0x01 << (idx -1))) ? "ON" : "OFF");
page += line;
}
page += F("</tr></table>");
}
/*
* Will interrupt user action when selected
if (sysCfg.module == SONOFF_LED) {
snprintf_P(line, sizeof(line), PSTR("<input type='range' min='1' max='100' value='%d' onchange='lb(value)'>"),
sysCfg.led_dimmer[0]);
page += line;
}
*/
webServer->sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
webServer->sendHeader("Pragma", "no-cache");
webServer->sendHeader("Expires", "-1");
@ -478,7 +502,7 @@ void handleConfig()
String page = FPSTR(HTTP_HEAD);
page.replace("{v}", "Configuration");
page += FPSTR(HTTP_BTN_MENU2);
if (sysCfg.mqtt_enabled) page += FPSTR(HTTP_BTN_MENU3);
if (sysCfg.mqtt_enabled) page += FPSTR(HTTP_BTN_MENU3);
page += FPSTR(HTTP_BTN_MENU4);
page += FPSTR(HTTP_BTN_MAIN);
showPage(page);
@ -546,6 +570,7 @@ void handleWifi(boolean scan)
String page = FPSTR(HTTP_HEAD);
page.replace("{v}", "Configure Wifi");
page.replace("</style>", FPSTR(HTTP_LNK_STYLE));
if (scan) {
#ifdef USE_EMULATION
@ -1153,6 +1178,7 @@ void handleConsole()
String page = FPSTR(HTTP_HEAD);
page.replace("{v}", "Console");
page.replace("</script>", FPSTR(HTTP_SCRIPT_CONSOL));
page.replace("<body>", "<body onload='l()'>");
page += FPSTR(HTTP_FORM_CMND);
page += FPSTR(HTTP_BTN_MAIN);
@ -1221,8 +1247,7 @@ void handleInfo()
page += F("<style>td{padding:0px 5px;}</style>");
page += F("<table style'width:100%;'>");
page += F("<tr><th>Program version</th><td>"); page += Version; page += F("</td></tr>");
page += F("<tr><th>Build Date/Time</th><td>"); page += __DATE__;
page += F("/"); page += __TIME__ ; page += F("</td></tr>");
page += F("<tr><th>Build Date & Time</th><td>"); page += getBuildDateTime(); page += F("</td></tr>");
page += F("<tr><th>Core/SDK version</th><td>"); page += ESP.getCoreVersion(); page += F("/"); page += String(ESP.getSdkVersion()); page += F("</td></tr>");
// page += F("<tr><th>Boot version</th><td>"); page += String(ESP.getBootVersion()); page += F("</td></tr>");
page += F("<tr><th>Uptime</th><td>"); page += String(uptime); page += F(" Hours</td></tr>");
@ -1252,7 +1277,7 @@ void handleInfo()
if (sysCfg.mqtt_enabled) {
page += F("<tr><th>MQTT Host</th><td>"); page += sysCfg.mqtt_host; page += F("</td></tr>");
page += F("<tr><th>MQTT Port</th><td>"); page += String(sysCfg.mqtt_port); page += F("</td></tr>");
page += F("<tr><th>MQTT Client and<br/>&nbsp;Fallback Topic</th><td>"); page += MQTTClient; page += F("</td></tr>");
page += F("<tr><th>MQTT Client &<br/>&nbsp;Fallback Topic</th><td>"); page += MQTTClient; page += F("</td></tr>");
page += F("<tr><th>MQTT User</th><td>"); page += sysCfg.mqtt_user; page += F("</td></tr>");
// page += F("<tr><th>MQTT Password</th><td>"); page += sysCfg.mqtt_pwd; page += F("</td></tr>");
page += F("<tr><th>MQTT Topic</th><td>"); page += sysCfg.mqtt_topic; page += F("</td></tr>");
@ -1275,9 +1300,9 @@ void handleInfo()
#ifdef USE_DISCOVERY
page += F("Enabled");
page += F("</td></tr>");
page += F("<tr><th>mDNS Webserver Advertise</th><td>");
page += F("<tr><th>mDNS Advertise</th><td>");
#ifdef WEBSERVER_ADVERTISE
page += F("Enabled");
page += F("Webserver");
#else
page += F("Disabled");
#endif // WEBSERVER_ADVERTISE
@ -1355,7 +1380,7 @@ void handleNotFound()
/* Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */
boolean captivePortal()
{
if (!isIp(webServer->hostHeader())) {
if ((_httpflag == HTTP_MANAGER) && !isIp(webServer->hostHeader())) {
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Request redirected to captive portal"));
webServer->sendHeader("Location", String("http://") + webServer->client().localIP().toString(), true);

View File

@ -99,12 +99,11 @@ void sl_init(void)
}
void sl_blank(byte state)
/*
* Called by interrupt disabling routines like OTA or web upload
* state = 0: No blank
* 1: Blank led to solve flicker
*/
{
// Called by interrupt disabling routines like OTA or web upload
// state = 0: No blank
// 1: Blank led to solve flicker
if (sysCfg.module == SONOFF_LED) {
sl_blankv = state;
sl_wakeupActive = 0;

View File

@ -394,16 +394,12 @@ void hue_todo(String *path)
void hue_config_response(String *response)
{
char buffer[21];
*response += FPSTR(HUE_CONFIG_RESPONSE_JSON);
response->replace("{mac}", WiFi.macAddress());
response->replace("{ip}", WiFi.localIP().toString());
response->replace("{mask}", WiFi.subnetMask().toString());
response->replace("{gw}", WiFi.gatewayIP().toString());
snprintf_P(buffer, sizeof(buffer), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"),
rtcTime.Year, rtcTime.Month, rtcTime.Day, rtcTime.Hour, rtcTime.Minute, rtcTime.Second);
response->replace("{dt}", buffer);
response->replace("{dt}", getDateTime());
}
void hue_global_cfg(String *path)

View File

@ -107,7 +107,7 @@ float ds18x20_convertCtoF(float c)
boolean ds18x20_read(uint8_t sensor, bool S, float &t)
{
byte data[12];
uint8_t sign = 1;
int8_t sign = 1;
uint8_t i = 0;
float temp9 = 0.0;
uint8_t present = 0;
@ -122,7 +122,24 @@ boolean ds18x20_read(uint8_t sensor, bool S, float &t)
if (OneWire::crc8(data, 8) == data[8]) {
switch(ds18x20_addr[ds18x20_idx[sensor]][0]) {
case 0x10: // DS18S20
if (data[1] > 0x80) sign = -1; // App-Note fix possible sign error
/*
// App_note AN162.pdf page 9
int temp_lsb, temp_msb;
temp_msb = data[1]; // Sign byte + lsbit
temp_lsb = data[0]; // Temp data plus lsb
if (temp_msb <= 0x80) temp_lsb = (temp_lsb/2); // Shift to get whole degree
temp_msb = temp_msb & 0x80; // Mask all but the sign bit
if (temp_msb >= 0x80) { // Negative temperature
temp_lsb = (~temp_lsb)+1; // Twos complement
temp_lsb = (temp_lsb/2); // Shift to get whole degree
temp_lsb = ((-1)*temp_lsb); // Add sign bit
}
t = (int)temp_lsb; // Temperature in whole degree
*/
if (data[1] > 0x80) {
data[0] = (~data[0]) +1;
sign = -1; // App-Note fix possible sign error
}
if (data[0] & 1) {
temp9 = ((data[0] >> 1) + 0.5) * sign;
} else {

View File

@ -546,8 +546,7 @@ void hlw_mqttPresent()
// {"Time":"2017-03-04T13:37:24", "Yesterday":0.013, "Today":0.000, "Period":0, "Power":0, "Factor":0.00, "Voltage":0, "Current":0.000}
char svalue[200]; // was MESSZ
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%04d-%02d-%02dT%02d:%02d:%02d\", "),
rtcTime.Year, rtcTime.Month, rtcTime.Day, rtcTime.Hour, rtcTime.Minute, rtcTime.Second);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%s\", "), getDateTime().c_str());
hlw_mqttStat(1, svalue, sizeof(svalue));
// snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/ENERGY"), PUB_PREFIX2, sysCfg.mqtt_topic);