mirror of https://github.com/arendst/Tasmota.git
v4.0.2
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:
parent
4797696b39
commit
ac84010015
|
@ -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.
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) !!!
|
||||
|
|
|
@ -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/> Fallback Topic</th><td>"); page += MQTTClient; page += F("</td></tr>");
|
||||
page += F("<tr><th>MQTT Client &<br/> 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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue