diff --git a/README.md b/README.md index 40e575646..5ddba7cce 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## Sonoff-Tasmota Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE. -Current version is **5.0.1** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. +Current version is **5.0.2** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. ### **** ATTENTION Version 5.0.x specific information **** @@ -11,7 +11,7 @@ Best practice to implement is: - Open the webpage to your device - Perform option ``Backup Configuration`` - Upgrade new firmware using ``Firmware upgrade`` -- If configuration conversion failed keep the webpage open and perform ``Restore Configuration`` +- If configuration conversion fails keep the webpage open and perform ``Restore Configuration`` You should now have a device with 32k more code memory to play with. diff --git a/api/arduino/sonoff.ino.bin b/api/arduino/sonoff.ino.bin index 0621a0c0d..32ec27bc1 100644 Binary files a/api/arduino/sonoff.ino.bin and b/api/arduino/sonoff.ino.bin differ diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 03361b437..cb0037510 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,4 +1,15 @@ -/* 5.0.1 20170429 +/* 5.0.2 20170503 + * Reset SaveData, SaveState and MqttResponse to default values due to rearranging settings + * Moved some settings flag area + * Add command TempUnit Celsius|Fahrenheit for selecting Celsius or Fahrenheit (#347) + * Add command TempRes 0..3 for selecting Temperature Resolution (#347) + * Add command HumRes 0..3 for selecting Humidity Resolution (#347) + * Add command PressRes 0..3 for selecting Pressure Resolution (#347) + * Add command EnergyRes 0..5 for selecting Energy Resolution (#347) + * Add "TemperatureUnit":"C|F" to sensor JSON output (#347) + * Add support for up to three DHT type sensors each using a different GPIO (#339, #404) + * + * 5.0.1 20170429 * Adjust Sonoff SC messages to prepare for display feature * Move static data from RAM to Flash * Fix PowerOnState for some devices not reporting "Power on" state (#284, #380, #383) diff --git a/sonoff/settings.h b/sonoff/settings.h index 1f8d02985..d590b1ec7 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -2,21 +2,49 @@ * Config settings \*********************************************************************************************/ +typedef struct { + uint32_t savestate : 1; + uint32_t button_restrict : 1; + uint32_t value_units : 1; + uint32_t mqtt_enabled : 1; + uint32_t mqtt_response : 1; + uint32_t mqtt_power_retain : 1; + uint32_t mqtt_button_retain : 1; + uint32_t mqtt_switch_retain : 1; + uint32_t temperature_conversion : 1; + uint32_t spare23 : 1; + uint32_t spare22 : 1; + uint32_t spare21 : 1; + uint32_t spare20 : 1; + uint32_t spare19 : 1; + uint32_t spare18 : 1; + uint32_t spare17 : 1; + uint32_t spare16 : 1; + uint32_t spare15 : 1; + uint32_t spare14 : 1; + uint32_t spare13 : 1; + uint32_t spare12 : 1; + uint32_t emulation : 2; + uint32_t energy_resolution : 3; + uint32_t pressure_resolution : 2; + uint32_t humidity_resolution : 2; + uint32_t temperature_resolution : 2; +} sysBitfield; + struct SYSCFG { unsigned long cfg_holder; unsigned long saveFlag; unsigned long version; unsigned long bootcount; - byte migflg; // Not used since 3.9.1 + sysBitfield flag; // Add flag since 5.0.2 int16_t savedata; - byte savestate; - byte mqtt_response; // was model until 3.9.1 + int8_t timezone; char otaUrl[101]; - char mqtt_prefix[3][11]; // was ex_friendlyname[33] until 3.2.5 + char mqtt_prefix[3][11]; // was ex_friendlyname[33] until 3.2.5 - byte serial_enable; + byte serial_enable; // Not used (ever) byte seriallog_level; uint8_t sta_config; byte sta_active; @@ -39,10 +67,10 @@ struct SYSCFG { char button_topic[33]; char mqtt_grptopic[33]; char state_text[3][11]; // was ex_mqtt_subtopic[33] until 4.1.1 - byte mqtt_button_retain; - byte mqtt_power_retain; - byte value_units; - byte button_restrict; // Was message_format until 3.2.6a + byte ex_mqtt_button_retain; // Not used since 5.0.2 + byte ex_mqtt_power_retain; // Not used since 5.0.2 + byte ex_value_units; // Not used since 5.0.2 + byte ex_button_restrict; // Not used since 5.0.2 uint16_t tele_period; uint8_t power; @@ -77,7 +105,7 @@ struct SYSCFG { uint16_t hlw_mkwhs; // MaxEnergyStart // 3.0.6 - uint16_t ex_pulsetime; // Not used since 4.0.4 + uint16_t ex_pulsetime; // Not used since 4.0.4 // 3.1.1 uint8_t poweronstate; @@ -104,8 +132,8 @@ struct SYSCFG { // 3.2.8 char switch_topic[33]; - byte mqtt_switch_retain; - uint8_t mqtt_enabled; + byte ex_mqtt_switch_retain; // Not used since 5.0.2 + uint8_t ex_mqtt_enabled; // Not used since 5.0.2 // 3.2.12 uint8_t sleep; @@ -126,7 +154,7 @@ struct SYSCFG { uint16_t led_wakeup; // 3.9.7 - uint8_t emulation; + uint8_t ex_emulation; // Not used since 5.0.2 // 3.9.20 char web_password[33]; diff --git a/sonoff/settings.ino b/sonoff/settings.ino index ca8cbd49d..d655586ef 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -277,7 +277,7 @@ void CFG_Erase() } } -void CFG_Dump() +void CFG_Dump(uint16_t srow, uint16_t mrow) { #define CFG_COLS 16 @@ -288,9 +288,19 @@ void CFG_Dump() uint16_t col; uint8_t *buffer = (uint8_t *) &sysCfg; + row = 0; maxrow = ((sizeof(SYSCFG)+CFG_COLS)/CFG_COLS); + if ((srow > 0) && (srow < maxrow)) { + row = srow; + } + if (0 == mrow) { // Default only four lines + mrow = 4; + } + if ((mrow > 0) && (mrow < (maxrow - row))) { + maxrow = row + mrow; + } - for (row = 0; row < maxrow; row++) { + for (row = srow; row < maxrow; row++) { idx = row * CFG_COLS; snprintf_P(log, sizeof(log), PSTR("%04X:"), idx); for (col = 0; col < CFG_COLS; col++) { @@ -313,25 +323,35 @@ void CFG_Dump() /********************************************************************************************/ +void CFG_Default() +{ + addLog_P(LOG_LEVEL_NONE, PSTR("Config: Use default configuration")); + CFG_DefaultSet1(); + CFG_DefaultSet2(); + CFG_Save(); +} + void CFG_DefaultSet1() { memset(&sysCfg, 0x00, sizeof(SYSCFG)); sysCfg.cfg_holder = CFG_HOLDER; - sysCfg.saveFlag = 0; +// sysCfg.saveFlag = 0; sysCfg.version = VERSION; - sysCfg.bootcount = 0; +// sysCfg.bootcount = 0; } void CFG_DefaultSet2() { + memset((char*)&sysCfg +16, 0x00, sizeof(SYSCFG) -16); + + sysCfg.flag.savestate = SAVE_STATE; sysCfg.savedata = SAVE_DATA; - sysCfg.savestate = SAVE_STATE; sysCfg.timezone = APP_TIMEZONE; strlcpy(sysCfg.otaUrl, OTA_URL, sizeof(sysCfg.otaUrl)); sysCfg.seriallog_level = SERIAL_LOG_LEVEL; - sysCfg.sta_active = 0; +// sysCfg.sta_active = 0; strlcpy(sysCfg.sta_ssid[0], STA_SSID1, sizeof(sysCfg.sta_ssid[0])); strlcpy(sysCfg.sta_pwd[0], STA_PASS1, sizeof(sysCfg.sta_pwd[0])); strlcpy(sysCfg.sta_ssid[1], STA_SSID2, sizeof(sysCfg.sta_ssid[1])); @@ -353,10 +373,10 @@ void CFG_DefaultSet2() strlcpy(sysCfg.mqtt_topic, MQTT_TOPIC, sizeof(sysCfg.mqtt_topic)); strlcpy(sysCfg.button_topic, "0", sizeof(sysCfg.button_topic)); strlcpy(sysCfg.mqtt_grptopic, MQTT_GRPTOPIC, sizeof(sysCfg.mqtt_grptopic)); - sysCfg.mqtt_button_retain = MQTT_BUTTON_RETAIN; - sysCfg.mqtt_power_retain = MQTT_POWER_RETAIN; - sysCfg.value_units = 0; - sysCfg.button_restrict = 0; + sysCfg.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN; + sysCfg.flag.mqtt_power_retain = MQTT_POWER_RETAIN; +// sysCfg.flag.value_units = 0; +// sysCfg.flag.button_restrict = 0; sysCfg.tele_period = TELE_PERIOD; sysCfg.power = APP_POWER; @@ -371,31 +391,31 @@ void CFG_DefaultSet2() sysCfg.domoticz_update_timer = DOMOTICZ_UPDATE_TIMER; for (byte i = 0; i < 4; i++) { sysCfg.switchmode[i] = SWITCH_MODE; - sysCfg.domoticz_relay_idx[i] = 0; - sysCfg.domoticz_key_idx[i] = 0; - sysCfg.domoticz_switch_idx[i] = 0; +// sysCfg.domoticz_relay_idx[i] = 0; +// sysCfg.domoticz_key_idx[i] = 0; +// sysCfg.domoticz_switch_idx[i] = 0; } sysCfg.hlw_pcal = HLW_PREF_PULSE; sysCfg.hlw_ucal = HLW_UREF_PULSE; sysCfg.hlw_ical = HLW_IREF_PULSE; - sysCfg.hlw_kWhtoday = 0; - sysCfg.hlw_kWhyesterday = 0; - sysCfg.hlw_kWhdoy = 0; - sysCfg.hlw_pmin = 0; - sysCfg.hlw_pmax = 0; - sysCfg.hlw_umin = 0; - sysCfg.hlw_umax = 0; - sysCfg.hlw_imin = 0; - sysCfg.hlw_imax = 0; - sysCfg.hlw_mpl = 0; // MaxPowerLimit +// sysCfg.hlw_kWhtoday = 0; +// sysCfg.hlw_kWhyesterday = 0; +// sysCfg.hlw_kWhdoy = 0; +// sysCfg.hlw_pmin = 0; +// sysCfg.hlw_pmax = 0; +// sysCfg.hlw_umin = 0; +// sysCfg.hlw_umax = 0; +// sysCfg.hlw_imin = 0; +// sysCfg.hlw_imax = 0; +// sysCfg.hlw_mpl = 0; // MaxPowerLimit sysCfg.hlw_mplh = MAX_POWER_HOLD; sysCfg.hlw_mplw = MAX_POWER_WINDOW; - sysCfg.hlw_mspl = 0; // MaxSafePowerLimit +// sysCfg.hlw_mspl = 0; // MaxSafePowerLimit sysCfg.hlw_msplh = SAFE_POWER_HOLD; sysCfg.hlw_msplw = SAFE_POWER_WINDOW; - sysCfg.hlw_mkwh = 0; // MaxEnergy - sysCfg.hlw_mkwhs = 0; // MaxEnergyStart +// sysCfg.hlw_mkwh = 0; // MaxEnergy +// sysCfg.hlw_mkwhs = 0; // MaxEnergyStart CFG_DefaultSet_3_2_4(); @@ -407,10 +427,10 @@ void CFG_DefaultSet2() CFG_DefaultSet_3_9_3(); strlcpy(sysCfg.switch_topic, "0", sizeof(sysCfg.switch_topic)); - sysCfg.mqtt_switch_retain = MQTT_SWITCH_RETAIN; - sysCfg.mqtt_enabled = MQTT_USE; + sysCfg.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN; + sysCfg.flag.mqtt_enabled = MQTT_USE; - sysCfg.emulation = EMULATION; + sysCfg.flag.emulation = EMULATION; strlcpy(sysCfg.web_password, WEB_PASSWORD, sizeof(sysCfg.web_password)); @@ -418,7 +438,7 @@ void CFG_DefaultSet2() sysCfg.pulsetime[0] = APP_PULSETIME; // 4.0.7 - for (byte i = 0; i < 5; i++) sysCfg.pwmvalue[i] = 0; +// for (byte i = 0; i < 5; i++) sysCfg.pwmvalue[i] = 0; // 4.0.9 CFG_DefaultSet_4_0_9(); @@ -426,8 +446,12 @@ void CFG_DefaultSet2() // 4.1.1 CFG_DefaultSet_4_1_1(); + // 5.0.2 + CFG_DefaultSet_5_0_2(); } +/********************************************************************************************/ + void CFG_DefaultSet_3_2_4() { sysCfg.ws_pixels = WS2812_LEDS; @@ -503,18 +527,18 @@ void CFG_DefaultSet_4_0_9() void CFG_DefaultSet_4_1_1() { - sysCfg.mqtt_response = 0; strlcpy(sysCfg.state_text[0], MQTT_STATUS_OFF, sizeof(sysCfg.state_text[0])); strlcpy(sysCfg.state_text[1], MQTT_STATUS_ON, sizeof(sysCfg.state_text[1])); strlcpy(sysCfg.state_text[2], MQTT_CMND_TOGGLE, sizeof(sysCfg.state_text[2])); } -void CFG_Default() +void CFG_DefaultSet_5_0_2() { - addLog_P(LOG_LEVEL_NONE, PSTR("Config: Use default configuration")); - CFG_DefaultSet1(); - CFG_DefaultSet2(); - CFG_Save(); + sysCfg.flag.temperature_conversion = TEMP_CONVERSION; + sysCfg.flag.temperature_resolution = TEMP_RESOLUTION; + sysCfg.flag.humidity_resolution = HUMIDITY_RESOLUTION; + sysCfg.flag.pressure_resolution = PRESSURE_RESOLUTION; + sysCfg.flag.energy_resolution = ENERGY_RESOLUTION; } /********************************************************************************************/ @@ -543,8 +567,8 @@ void CFG_Delta() } if (sysCfg.version < 0x03020800) { // 3.2.8 - Add parameter strlcpy(sysCfg.switch_topic, sysCfg.button_topic, sizeof(sysCfg.switch_topic)); - sysCfg.mqtt_switch_retain = MQTT_SWITCH_RETAIN; - sysCfg.mqtt_enabled = MQTT_USE; + sysCfg.ex_mqtt_switch_retain = MQTT_SWITCH_RETAIN; + sysCfg.ex_mqtt_enabled = MQTT_USE; } if (sysCfg.version < 0x03020C00) { // 3.2.12 - Add parameter sysCfg.sleep = APP_SLEEP; @@ -553,7 +577,7 @@ void CFG_Delta() CFG_DefaultSet_3_9_3(); } if (sysCfg.version < 0x03090700) { // 3.9.7 - Add parameter - sysCfg.emulation = EMULATION; + sysCfg.ex_emulation = EMULATION; } if (sysCfg.version < 0x03091400) { strlcpy(sysCfg.web_password, WEB_PASSWORD, sizeof(sysCfg.web_password)); @@ -562,7 +586,7 @@ void CFG_Delta() for (byte i = 0; i < 4; i++) sysCfg.switchmode[i] = sysCfg.ex_switchmode; } if (sysCfg.version < 0x04000200) { - sysCfg.button_restrict = 0; + sysCfg.ex_button_restrict = 0; } if (sysCfg.version < 0x04000400) { CFG_DefaultSet_4_0_4(); @@ -582,6 +606,23 @@ void CFG_Delta() if (sysCfg.version < 0x04010100) { CFG_DefaultSet_4_1_1(); } + if (sysCfg.version < 0x05000105) { + sysCfg.flag = { 0 }; + sysCfg.flag.savestate = SAVE_STATE; + sysCfg.flag.button_restrict = sysCfg.ex_button_restrict; + sysCfg.flag.value_units = sysCfg.ex_value_units; + sysCfg.flag.mqtt_enabled = sysCfg.ex_mqtt_enabled; +// sysCfg.flag.mqtt_response = 0; + sysCfg.flag.mqtt_power_retain = sysCfg.ex_mqtt_power_retain; + sysCfg.flag.mqtt_button_retain = sysCfg.ex_mqtt_button_retain; + sysCfg.flag.mqtt_switch_retain = sysCfg.ex_mqtt_switch_retain; + sysCfg.flag.emulation = sysCfg.ex_emulation; + + CFG_DefaultSet_5_0_2(); + + sysCfg.savedata = SAVE_DATA; + } + sysCfg.version = VERSION; } } diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 54e45df58..78e498ea6 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -10,7 +10,7 @@ * ==================================================== */ -#define VERSION 0x05000100 // 5.0.1 +#define VERSION 0x05000200 // 5.0.2 enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL}; enum week_t {Last, First, Second, Third, Fourth}; @@ -264,7 +264,7 @@ uint8_t pin[GPIO_MAX]; // Possible pin configurations uint8_t rel_inverted[4] = { 0 }; // Relay inverted flag (1 = (0 = On, 1 = Off)) uint8_t led_inverted[4] = { 0 }; // LED inverted flag (1 = (0 = On, 1 = Off)) uint8_t swt_flg = 0; // Any external switch configured -uint8_t dht_type = 0; // DHT type (DHT11, DHT21 or DHT22) +uint8_t dht_flg = 0; // DHT configured uint8_t hlw_flg = 0; // Power monitor configured uint8_t i2c_flg = 0; // I2C configured uint8_t spi_flg = 0; // SPI configured @@ -425,7 +425,7 @@ void mqtt_publish_sec(const char* topic, const char* data, boolean retained) { char log[TOPSZ + MESSZ]; - if (sysCfg.mqtt_enabled) { + if (sysCfg.flag.mqtt_enabled) { if (mqttClient.publish(topic, data, retained)) { snprintf_P(log, sizeof(log), PSTR("MQTT: %s = %s%s"), topic, data, (retained) ? " (retained)" : ""); // mqttClient.loop(); // Do not use here! Will block previous publishes @@ -465,7 +465,7 @@ void mqtt_publish_topic_P(uint8_t prefix, const char* subtopic, const char* data char romram[16]; char stopic[TOPSZ]; - snprintf_P(romram, sizeof(romram), ((prefix > 3) && !sysCfg.mqtt_response) ? PSTR("RESULT") : subtopic); + snprintf_P(romram, sizeof(romram), ((prefix > 3) && !sysCfg.flag.mqtt_response) ? PSTR("RESULT") : subtopic); prefix &= 1; snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s"), sysCfg.mqtt_prefix[prefix +1], sysCfg.mqtt_topic, romram); mqtt_publish(stopic, data); @@ -482,12 +482,12 @@ void mqtt_publishPowerState(byte device) } snprintf_P(sdevice, sizeof(sdevice), PSTR("%d"), device); snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s"), - sysCfg.mqtt_prefix[1], sysCfg.mqtt_topic, (sysCfg.mqtt_response)?"POWER":"RESULT"); + sysCfg.mqtt_prefix[1], sysCfg.mqtt_topic, (sysCfg.flag.mqtt_response)?"POWER":"RESULT"); snprintf_P(svalue, sizeof(svalue), PSTR("{\"POWER%s\":\"%s\"}"), (Maxdevice > 1) ? sdevice : "", getStateText(bitRead(power, device -1))); mqtt_publish(stopic, svalue); json2legacy(stopic, svalue); - mqtt_publish(stopic, svalue, sysCfg.mqtt_power_retain); + mqtt_publish(stopic, svalue, sysCfg.flag.mqtt_power_retain); } void mqtt_publishPowerBlinkState(byte device) @@ -509,7 +509,7 @@ void mqtt_connected() char stopic[TOPSZ]; char svalue[128]; // was MESSZ - if (sysCfg.mqtt_enabled) { + if (sysCfg.flag.mqtt_enabled) { // Satisfy iobroker (#299) snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/POWER"), sysCfg.mqtt_prefix[0], sysCfg.mqtt_topic); @@ -563,7 +563,7 @@ void mqtt_reconnect() mqttcounter = MQTT_RETRY_SECS; - if (!sysCfg.mqtt_enabled) { + if (!sysCfg.flag.mqtt_enabled) { mqtt_connected(); return; } @@ -640,9 +640,9 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, } else if (!strcmp_P(type,PSTR("MQTTRESPONSE"))) { if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { - sysCfg.mqtt_response = payload; + sysCfg.flag.mqtt_response = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"MqttResponse\":\"%s\"}"), getStateText(sysCfg.mqtt_response)); + snprintf_P(svalue, ssvalue, PSTR("{\"MqttResponse\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_response)); } else if (!strcmp_P(type,PSTR("STATETEXT")) && (index > 0) && (index <= 3)) { if ((data_len > 0) && (data_len < sizeof(sysCfg.state_text[0]))) { @@ -764,9 +764,9 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, send_button_power(0, i, 3); // Clear MQTT retain in broker } } - sysCfg.mqtt_button_retain = payload; + sysCfg.flag.mqtt_button_retain = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"ButtonRetain\":\"%s\"}"), getStateText(sysCfg.mqtt_button_retain)); + snprintf_P(svalue, ssvalue, PSTR("{\"ButtonRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_button_retain)); } else if (!strcmp_P(type,PSTR("SWITCHRETAIN"))) { if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { @@ -776,9 +776,9 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, send_button_power(1, i, 3); // Clear MQTT retain in broker } } - sysCfg.mqtt_switch_retain = payload; + sysCfg.flag.mqtt_switch_retain = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"SwitchRetain\":\"%s\"}"), getStateText(sysCfg.mqtt_switch_retain)); + snprintf_P(svalue, ssvalue, PSTR("{\"SwitchRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_switch_retain)); } else if (!strcmp_P(type,PSTR("POWERRETAIN"))) { if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { @@ -786,12 +786,12 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, 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"), sysCfg.mqtt_prefix[1], sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp2 : ""); - mqtt_publish(stemp1, "", sysCfg.mqtt_power_retain); + mqtt_publish(stemp1, "", sysCfg.flag.mqtt_power_retain); } } - sysCfg.mqtt_power_retain = payload; + sysCfg.flag.mqtt_power_retain = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"PowerRetain\":\"%s\"}"), getStateText(sysCfg.mqtt_power_retain)); + snprintf_P(svalue, ssvalue, PSTR("{\"PowerRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_power_retain)); } #ifdef USE_DOMOTICZ else if (domoticz_command(type, index, dataBuf, data_len, payload, svalue, ssvalue)) { @@ -844,7 +844,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) // if (LOG_LEVEL_DEBUG_MORE <= seriallog_level) Serial.println(dataBuf); #ifdef USE_DOMOTICZ - if (sysCfg.mqtt_enabled) { + if (sysCfg.flag.mqtt_enabled) { if (domoticz_mqttData(topicBuf, sizeof(topicBuf), dataBuf, sizeof(dataBuf))) { return; } @@ -901,10 +901,10 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } int16_t payload = atoi(dataBuf); // -32766 - 32767 uint16_t payload16 = atoi(dataBuf); // 0 - 65535 - if (!strcmp_P(dataBufUc,PSTR("OFF")) || !strcmp_P(dataBufUc,PSTR("FALSE")) || !strcmp_P(dataBufUc,PSTR("STOP"))) { + if (!strcmp_P(dataBufUc,PSTR("OFF")) || !strcmp_P(dataBufUc,PSTR("FALSE")) || !strcmp_P(dataBufUc,PSTR("STOP")) || !strcmp_P(dataBufUc,PSTR("CELSIUS"))) { payload = 0; } - if (!strcmp_P(dataBufUc,PSTR("ON")) || !strcmp_P(dataBufUc,PSTR("TRUE")) || !strcmp_P(dataBufUc,PSTR("START")) || !strcmp_P(dataBufUc,PSTR("USER"))) { + if (!strcmp_P(dataBufUc,PSTR("ON")) || !strcmp_P(dataBufUc,PSTR("TRUE")) || !strcmp_P(dataBufUc,PSTR("START")) || !strcmp_P(dataBufUc,PSTR("FAHRENHEIT")) || !strcmp_P(dataBufUc,PSTR("USER"))) { payload = 1; } if (!strcmp_P(dataBufUc,PSTR("TOGGLE")) || !strcmp_P(dataBufUc,PSTR("ADMIN"))) { @@ -970,7 +970,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) sysCfg.savedata = payload; savedatacounter = sysCfg.savedata; } - if (sysCfg.savestate) { + if (sysCfg.flag.savestate) { sysCfg.power = power; } CFG_Save(); @@ -981,28 +981,58 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } else if (!strcmp_P(type,PSTR("SAVESTATE"))) { if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { - sysCfg.savestate = payload; + sysCfg.flag.savestate = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"SaveState\":\"%s\"}"), getStateText(sysCfg.savestate)); + snprintf_P(svalue, sizeof(svalue), PSTR("{\"SaveState\":\"%s\"}"), getStateText(sysCfg.flag.savestate)); } else if (!strcmp_P(type,PSTR("BUTTONRESTRICT"))) { if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { - sysCfg.button_restrict = payload; + sysCfg.flag.button_restrict = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"ButtonRestrict\":\"%s\"}"), getStateText(sysCfg.button_restrict)); + snprintf_P(svalue, sizeof(svalue), PSTR("{\"ButtonRestrict\":\"%s\"}"), getStateText(sysCfg.flag.button_restrict)); } else if (!strcmp_P(type,PSTR("UNITS"))) { if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { - sysCfg.value_units = payload; + sysCfg.flag.value_units = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"Units\":\"%s\"}"), getStateText(sysCfg.value_units)); + snprintf_P(svalue, sizeof(svalue), PSTR("{\"Units\":\"%s\"}"), getStateText(sysCfg.flag.value_units)); } else if (!strcmp_P(type,PSTR("MQTT"))) { if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { - sysCfg.mqtt_enabled = payload; + sysCfg.flag.mqtt_enabled = payload; restartflag = 2; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"Mqtt\":\"%s\"}"), getStateText(sysCfg.mqtt_enabled)); + snprintf_P(svalue, sizeof(svalue), PSTR("{\"Mqtt\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_enabled)); + } + else if (!strcmp_P(type,PSTR("TEMPUNIT"))) { + if ((data_len > 0) && (payload >= 0) && (payload <= 1)) { + sysCfg.flag.temperature_conversion = payload; + } + snprintf_P(svalue, sizeof(svalue), PSTR("{\"TempUnit\":\"%s\"}"), (sysCfg.flag.temperature_conversion) ? "Fahrenheit" : "Celsius"); + } + else if (!strcmp_P(type,PSTR("TEMPRES"))) { + if ((data_len > 0) && (payload >= 0) && (payload <= 3)) { + sysCfg.flag.temperature_resolution = payload; + } + snprintf_P(svalue, sizeof(svalue), PSTR("{\"TempRes\":%d}"), sysCfg.flag.temperature_resolution); + } + else if (!strcmp_P(type,PSTR("HUMRES"))) { + if ((data_len > 0) && (payload >= 0) && (payload <= 3)) { + sysCfg.flag.humidity_resolution = payload; + } + snprintf_P(svalue, sizeof(svalue), PSTR("{\"HumRes\":%d}"), sysCfg.flag.humidity_resolution); + } + else if (!strcmp_P(type,PSTR("PRESSRES"))) { + if ((data_len > 0) && (payload >= 0) && (payload <= 3)) { + sysCfg.flag.pressure_resolution = payload; + } + snprintf_P(svalue, sizeof(svalue), PSTR("{\"PressRes\":%d}"), sysCfg.flag.pressure_resolution); + } + else if (!strcmp_P(type,PSTR("ENERGYRES"))) { + if ((data_len > 0) && (payload >= 0) && (payload <= 5)) { + sysCfg.flag.energy_resolution = payload; + } + snprintf_P(svalue, sizeof(svalue), PSTR("{\"EnergyRes\":%d}"), sysCfg.flag.energy_resolution); } else if (!strcmp_P(type,PSTR("MODULE"))) { if ((data_len > 0) && (payload > 0) && (payload <= MAXMODULE)) { @@ -1123,7 +1153,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) sysCfg.sleep = payload; sleep = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"Sleep\":\"%d%s (%d%s)\"}"), sleep, (sysCfg.value_units) ? " mS" : "", sysCfg.sleep, (sysCfg.value_units) ? " mS" : ""); + snprintf_P(svalue, sizeof(svalue), PSTR("{\"Sleep\":\"%d%s (%d%s)\"}"), sleep, (sysCfg.flag.value_units) ? " mS" : "", sysCfg.sleep, (sysCfg.flag.value_units) ? " mS" : ""); } else if (!strcmp_P(type,PSTR("FLASHMODE"))) { // 0 = QIO, 1 = QOUT, 2 = DIO, 3 = DOUT if ((data_len > 0) && (payload >= 0) && (payload <= 3)) { @@ -1157,7 +1187,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) else if (!strcmp_P(type,PSTR("SYSLOG"))) { if ((data_len > 0) && (payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { sysCfg.syslog_level = payload; - syslog_level = (sysCfg.emulation) ? 0 : payload; + syslog_level = (sysCfg.flag.emulation) ? 0 : payload; syslog_timer = 0; } snprintf_P(svalue, sizeof(svalue), PSTR("{\"SysLog\":\"%d (Active %d)\"}"), sysCfg.syslog_level, syslog_level); @@ -1293,10 +1323,10 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) #ifdef USE_EMULATION else if (!strcmp_P(type,PSTR("EMULATION"))) { if ((data_len > 0) && (payload >= 0) && (payload <= 2)) { - sysCfg.emulation = payload; + sysCfg.flag.emulation = payload; restartflag = 2; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"Emulation\":%d}"), sysCfg.emulation); + snprintf_P(svalue, sizeof(svalue), PSTR("{\"Emulation\":%d}"), sysCfg.flag.emulation); } #endif // USE_EMULATION #endif // USE_WEBSERVER @@ -1308,7 +1338,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } tele_period = sysCfg.tele_period; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"TelePeriod\":\"%d%s\"}"), sysCfg.tele_period, (sysCfg.value_units) ? " Sec" : ""); + snprintf_P(svalue, sizeof(svalue), PSTR("{\"TelePeriod\":\"%d%s\"}"), sysCfg.tele_period, (sysCfg.flag.value_units) ? " Sec" : ""); } else if (!strcmp_P(type,PSTR("RESTART"))) { switch (payload) { @@ -1371,10 +1401,26 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) snprintf_P(svalue, sizeof(svalue), PSTR("{\"LedState\":%d}"), sysCfg.ledstate); } else if (!strcmp_P(type,PSTR("CFGDUMP"))) { - CFG_Dump(); + uint16_t srow = 0; + uint16_t mrow = 0; + if (data_len > 0) { + srow = payload16; + byte i = 0; + while (isdigit(dataBuf[i])) { + i++; + } + if (i < strlen(dataBuf)) { + mrow = atoi(dataBuf +i); + } + if (0 == mrow) { + mrow = payload16; + srow = 0; + } + } + CFG_Dump(srow, mrow); 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))) { + else if (sysCfg.flag.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))) { @@ -1444,10 +1490,10 @@ void send_button_power(byte key, byte device, byte state) } #ifdef USE_DOMOTICZ if (!(domoticz_button(key, device, state, strlen(svalue)))) { - mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.mqtt_switch_retain : sysCfg.mqtt_button_retain); + mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.flag.mqtt_switch_retain : sysCfg.flag.mqtt_button_retain); } #else - mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.mqtt_switch_retain : sysCfg.mqtt_button_retain); + mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.flag.mqtt_switch_retain : sysCfg.flag.mqtt_button_retain); #endif // USE_DOMOTICZ } @@ -1552,7 +1598,7 @@ void publish_status(uint8_t payload) // Workaround MQTT - TCP/IP stack queueing when SUB_PREFIX = PUB_PREFIX option = (!strcmp(sysCfg.mqtt_prefix[0],sysCfg.mqtt_prefix[1]) && (!payload)); - if ((!sysCfg.mqtt_enabled) && (6 == payload)) { + if ((!sysCfg.flag.mqtt_enabled) && (6 == payload)) { payload = 99; } if ((!hlw_flg) && ((8 == payload) || (9 == payload))) { @@ -1561,7 +1607,7 @@ void publish_status(uint8_t payload) if ((0 == payload) || (99 == payload)) { snprintf_P(svalue, sizeof(svalue), PSTR("{\"Status\":{\"Module\":%d, \"FriendlyName\":\"%s\", \"Topic\":\"%s\", \"ButtonTopic\":\"%s\", \"Power\":%d, \"PowerOnState\":%d, \"LedState\":%d, \"SaveData\":%d, \"SaveState\":%d, \"ButtonRetain\":%d, \"PowerRetain\":%d}}"), - sysCfg.module +1, sysCfg.friendlyname[0], sysCfg.mqtt_topic, sysCfg.button_topic, power, sysCfg.poweronstate, sysCfg.ledstate, sysCfg.savedata, sysCfg.savestate, sysCfg.mqtt_button_retain, sysCfg.mqtt_power_retain); + sysCfg.module +1, sysCfg.friendlyname[0], sysCfg.mqtt_topic, sysCfg.button_topic, power, sysCfg.poweronstate, sysCfg.ledstate, sysCfg.savedata, sysCfg.flag.savestate, sysCfg.flag.mqtt_button_retain, sysCfg.flag.mqtt_power_retain); mqtt_publish_topic_P(option, PSTR("STATUS"), svalue); } @@ -1596,7 +1642,7 @@ void publish_status(uint8_t payload) mqtt_publish_topic_P(option, PSTR("STATUS5"), svalue); } - if (((0 == payload) || (6 == payload)) && sysCfg.mqtt_enabled) { + if (((0 == payload) || (6 == payload)) && sysCfg.flag.mqtt_enabled) { snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusMQT\":{\"Host\":\"%s\", \"Port\":%d, \"ClientMask\":\"%s\", \"Client\":\"%s\", \"User\":\"%s\", \"MAX_PACKET_SIZE\":%d, \"KEEPALIVE\":%d}}"), sysCfg.mqtt_host, sysCfg.mqtt_port, sysCfg.mqtt_client, MQTTClient, sysCfg.mqtt_user, MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE); mqtt_publish_topic_P(option, PSTR("STATUS6"), svalue); @@ -1687,7 +1733,7 @@ void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) #endif // USE_DS18x20 } #ifdef USE_DHT - if (dht_type) { + if (dht_flg) { dht_mqttPresent(svalue, ssvalue, djson); } #endif // USE_DHT @@ -1706,7 +1752,10 @@ void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) bh1750_mqttPresent(svalue, ssvalue, djson); #endif // USE_BH1750 } -#endif // USE_I2C +#endif // USE_I2C + if (strstr_P(svalue, PSTR("Temperature"))) { + snprintf_P(svalue, ssvalue, PSTR("%s, \"TempUnit\":\"%c\""), svalue, tempUnit()); + } snprintf_P(svalue, ssvalue, PSTR("%s}"), svalue); } @@ -1735,7 +1784,7 @@ void every_second() if (syslog_timer) { // Restore syslog level syslog_timer--; if (!syslog_timer) { - syslog_level = (sysCfg.emulation) ? 0 : sysCfg.syslog_level; + syslog_level = (sysCfg.flag.emulation) ? 0 : sysCfg.syslog_level; if (sysCfg.syslog_level) { addLog_P(LOG_LEVEL_INFO, PSTR("SYSL: Syslog logging re-enabled")); // Might trigger disable again (on purpose) } @@ -1768,7 +1817,7 @@ void every_second() #endif // USE_DS18x20 } #ifdef USE_DHT - if (dht_type) { + if (dht_flg) { dht_readPrep(); } #endif // USE_DHT @@ -1914,7 +1963,7 @@ void stateloop() holdcount = 0; } else { holdcount++; - if (!sysCfg.button_restrict && ((STATES *4) == holdcount)) { // 4 seconds button hold + if (!sysCfg.flag.button_restrict && ((STATES *4) == holdcount)) { // 4 seconds button hold snprintf_P(scmnd, sizeof(scmnd), PSTR("reset 1")); multipress = 0; do_cmnd(scmnd); @@ -1929,7 +1978,7 @@ void stateloop() } else { flag = (1 == multipress); } - if (flag && sysCfg.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.button_topic) != 0) && strcmp(sysCfg.button_topic, "0")) { + if (flag && sysCfg.flag.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 ((1 == multipress) || (2 == multipress)) { @@ -1939,7 +1988,7 @@ void stateloop() do_cmnd_power(multipress, 2); // Execute command internally } } else { - if (!sysCfg.button_restrict) { + if (!sysCfg.flag.button_restrict) { snprintf_P(scmnd, sizeof(scmnd), commands[multipress -3]); do_cmnd(scmnd); } @@ -1953,7 +2002,7 @@ void stateloop() if (pin[GPIO_KEY1 +i] < 99) { button = digitalRead(pin[GPIO_KEY1 +i]); if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) { - if (sysCfg.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.button_topic) != 0) && strcmp(sysCfg.button_topic, "0")) { + if (sysCfg.flag.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 @@ -1989,7 +2038,7 @@ void stateloop() } } if (switchflag < 3) { - if (sysCfg.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.switch_topic) != 0) && strcmp(sysCfg.switch_topic, "0")) { + if (sysCfg.flag.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) @@ -2066,7 +2115,7 @@ void stateloop() if (savedatacounter) { savedatacounter--; if (savedatacounter <= 0) { - if (sysCfg.savestate) { + if (sysCfg.flag.savestate) { byte mask = 0xFF; for (byte i = 0; i < MAX_PULSETIMERS; i++) { if ((sysCfg.pulsetime[i] > 0) && (sysCfg.pulsetime[i] < 30)) { @@ -2091,7 +2140,7 @@ void stateloop() CFG_Default(); restartflag = 2; } - if (sysCfg.savestate) { + if (sysCfg.flag.savestate) { sysCfg.power = power; } if (hlw_flg) { @@ -2111,7 +2160,7 @@ void stateloop() break; case (STATES/10)*8: if (WL_CONNECTED == WiFi.status()) { - if (sysCfg.mqtt_enabled) { + if (sysCfg.flag.mqtt_enabled) { if (!mqttClient.connected()) { if (!mqttcounter) { mqtt_reconnect(); @@ -2231,17 +2280,16 @@ void GPIO_init() led_inverted[mpin - GPIO_LED1_INV] = 1; mpin -= 4; } - else if (GPIO_DHT11 == mpin) { - dht_type = mpin; - } - else if (GPIO_DHT21 == mpin) { - dht_type = mpin; - mpin--; - } - else if (GPIO_DHT22 == mpin) { - dht_type = mpin; - mpin -= 2; + else if ((mpin >= GPIO_DHT11) && (mpin <= GPIO_DHT22)) { + if (dht_setup(i, mpin)) { + dht_flg = 1; + mpin = GPIO_DHT11; + } else { + mpin = 0; + } } + } + if (mpin) { pin[mpin] = i; } } @@ -2326,7 +2374,7 @@ void GPIO_init() } #ifdef USE_DHT - if (dht_type) { + if (dht_flg) { dht_init(); } #endif // USE_DHT @@ -2389,9 +2437,9 @@ void setup() seriallog_timer = SERIALLOG_TIMER; seriallog_level = sysCfg.seriallog_level; #ifndef USE_EMULATION - sysCfg.emulation = 0; + sysCfg.flag.emulation = 0; #endif // USE_EMULATION - syslog_level = (sysCfg.emulation) ? 0 : sysCfg.syslog_level; + syslog_level = (sysCfg.flag.emulation) ? 0 : sysCfg.syslog_level; sleep = sysCfg.sleep; GPIO_init(); @@ -2432,19 +2480,19 @@ void setup() } else if (2 == sysCfg.poweronstate) { // All saved state toggle power = sysCfg.power & ((1 << Maxdevice) -1) ^ 0xFF; - if (sysCfg.savestate) { + if (sysCfg.flag.savestate) { setRelay(power); } } else if (3 == sysCfg.poweronstate) { // All saved state power = sysCfg.power & ((1 << Maxdevice) -1); - if (sysCfg.savestate) { + if (sysCfg.flag.savestate) { setRelay(power); } } } else { power = sysCfg.power & ((1 << Maxdevice) -1); - if (sysCfg.savestate) { + if (sysCfg.flag.savestate) { setRelay(power); } } @@ -2470,7 +2518,7 @@ void loop() #endif // USE_WEBSERVER #ifdef USE_EMULATION - if (sysCfg.emulation) { + if (sysCfg.flag.emulation) { pollUDP(); } #endif // USE_EMULATION @@ -2478,7 +2526,7 @@ void loop() if (millis() >= timerxs) { stateloop(); } - if (sysCfg.mqtt_enabled) { + if (sysCfg.flag.mqtt_enabled) { mqttClient.loop(); } if (Serial.available()){ diff --git a/sonoff/support.ino b/sonoff/support.ino index 37f7a0730..7f3b86dbf 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -475,7 +475,7 @@ void WIFI_Check(uint8_t param) stopWebserver(); } #ifdef USE_EMULATION - if (sysCfg.emulation) { + if (sysCfg.flag.emulation) { UDP_Connect(); } #endif // USE_EMULATION @@ -942,6 +942,25 @@ void rtc_init() tickerRTC.attach(1, rtc_second); } +/*********************************************************************************************\ + * Miscellaneous +\*********************************************************************************************/ + +float convertTemp(float c) +{ + float result = c; + + if (!isnan(c) && sysCfg.flag.temperature_conversion) { + result = c * 1.8 + 32; // Fahrenheit + } + return result; +} + +char tempUnit() +{ + return (sysCfg.flag.temperature_conversion) ? 'F' : 'C'; +} + /*********************************************************************************************\ * Syslog \*********************************************************************************************/ diff --git a/sonoff/user_config.h b/sonoff/user_config.h index e73361d53..251917b8c 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -120,11 +120,11 @@ #define SWITCH_MODE TOGGLE // [SwitchMode] TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON or PUSHBUTTON_INV (the wall switch state) #define WS2812_LEDS 30 // [Pixels] Number of WS2812 LEDs to start with -#define TEMP_CONVERSION 0 // Convert temperature to (0 = Celsius or 1 = Fahrenheit) -#define TEMP_RESOLUTION 1 // Maximum number of decimals (0 - 3) showing sensor Temperature -#define HUMIDITY_RESOLUTION 1 // Maximum number of decimals (0 - 3) showing sensor Humidity -#define PRESSURE_RESOLUTION 1 // Maximum number of decimals (0 - 3) showing sensor Pressure -#define ENERGY_RESOLUTION 3 // Maximum number of decimals (0 - 5) showing energy usage in kWh +#define TEMP_CONVERSION 0 // [TempUnit] Return temperature in (0 = Celsius or 1 = Fahrenheit) +#define TEMP_RESOLUTION 1 // [TempRes] Maximum number of decimals (0 - 3) showing sensor Temperature +#define HUMIDITY_RESOLUTION 1 // [HumRes] Maximum number of decimals (0 - 3) showing sensor Humidity +#define PRESSURE_RESOLUTION 1 // [PressRes] Maximum number of decimals (0 - 3) showing sensor Pressure +#define ENERGY_RESOLUTION 3 // [EnergyRes] Maximum number of decimals (0 - 5) showing energy usage in kWh // -- Sensor code selection ----------------------- #define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino index f1011fa2d..4a213d62a 100644 --- a/sonoff/webserver.ino +++ b/sonoff/webserver.ino @@ -303,7 +303,7 @@ void startWebserver(int type, IPAddress ipweb) webServer->on("/md", handleModule); webServer->on("/w1", handleWifi1); webServer->on("/w0", handleWifi0); - if (sysCfg.mqtt_enabled) { + if (sysCfg.flag.mqtt_enabled) { webServer->on("/mq", handleMqtt); #ifdef USE_DOMOTICZ webServer->on("/dm", handleDomoticz); @@ -326,12 +326,12 @@ void startWebserver(int type, IPAddress ipweb) webServer->on("/rb", handleRestart); webServer->on("/fwlink", handleRoot); // Microsoft captive portal. Maybe not needed. Might be handled by notFound handler. #ifdef USE_EMULATION - if (EMUL_WEMO == sysCfg.emulation) { + if (EMUL_WEMO == sysCfg.flag.emulation) { webServer->on("/upnp/control/basicevent1", HTTP_POST, handleUPnPevent); webServer->on("/eventservice.xml", handleUPnPservice); webServer->on("/setup.xml", handleUPnPsetupWemo); } - if (EMUL_HUE == sysCfg.emulation) { + if (EMUL_HUE == sysCfg.flag.emulation) { webServer->on("/description.xml", handleUPnPsetupHue); } #endif // USE_EMULATION @@ -483,7 +483,7 @@ void handleAjax2() } #endif // USE_DS18x20 #ifdef USE_DHT - if (dht_type) { + if (dht_flg) { tpage += dht_webPresent(); } #endif // USE_DHT @@ -554,7 +554,7 @@ void handleConfig() String page = FPSTR(HTTP_HEAD); page.replace("{v}", "Configuration"); page += FPSTR(HTTP_BTN_MENU2); - if (sysCfg.mqtt_enabled) { + if (sysCfg.flag.mqtt_enabled) { page += FPSTR(HTTP_BTN_MENU3); } page += FPSTR(HTTP_BTN_MENU4); @@ -857,16 +857,16 @@ void handleOther() page.replace("{v}", "Configure Other"); page += FPSTR(HTTP_FORM_OTHER); page.replace("{p1}", sysCfg.web_password); - page.replace("{r1}", (sysCfg.mqtt_enabled) ? " checked" : ""); + page.replace("{r1}", (sysCfg.flag.mqtt_enabled) ? " checked" : ""); page += FPSTR(HTTP_FORM_OTHER2); page.replace("{1", "1"); page.replace("{2", FRIENDLY_NAME); page.replace("{3", sysCfg.friendlyname[0]); #ifdef USE_EMULATION page += FPSTR(HTTP_FORM_OTHER3); - page.replace("{r2}", (EMUL_NONE == sysCfg.emulation) ? " checked" : ""); - page.replace("{r3}", (EMUL_WEMO == sysCfg.emulation) ? " checked" : ""); - page.replace("{r4}", (EMUL_HUE == sysCfg.emulation) ? " checked" : ""); + page.replace("{r2}", (EMUL_NONE == sysCfg.flag.emulation) ? " checked" : ""); + page.replace("{r3}", (EMUL_WEMO == sysCfg.flag.emulation) ? " checked" : ""); + page.replace("{r4}", (EMUL_HUE == sysCfg.flag.emulation) ? " checked" : ""); for (int i = 1; i < Maxdevice; i++) { page += FPSTR(HTTP_FORM_OTHER2); page.replace("{1", String(i +1)); @@ -972,16 +972,16 @@ void handleSave() #endif // USE_DOMOTICZ case 5: 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"); + sysCfg.flag.mqtt_enabled = webServer->hasArg("b1"); #ifdef USE_EMULATION - sysCfg.emulation = (!strlen(webServer->arg("b2").c_str())) ? 0 : atoi(webServer->arg("b2").c_str()); + sysCfg.flag.emulation = (!strlen(webServer->arg("b2").c_str())) ? 0 : atoi(webServer->arg("b2").c_str()); #endif // USE_EMULATION strlcpy(sysCfg.friendlyname[0], (!strlen(webServer->arg("a1").c_str())) ? FRIENDLY_NAME : webServer->arg("a1").c_str(), sizeof(sysCfg.friendlyname[0])); strlcpy(sysCfg.friendlyname[1], (!strlen(webServer->arg("a2").c_str())) ? FRIENDLY_NAME"2" : webServer->arg("a2").c_str(), sizeof(sysCfg.friendlyname[1])); strlcpy(sysCfg.friendlyname[2], (!strlen(webServer->arg("a3").c_str())) ? FRIENDLY_NAME"3" : webServer->arg("a3").c_str(), sizeof(sysCfg.friendlyname[2])); strlcpy(sysCfg.friendlyname[3], (!strlen(webServer->arg("a4").c_str())) ? FRIENDLY_NAME"4" : webServer->arg("a4").c_str(), sizeof(sysCfg.friendlyname[3])); snprintf_P(log, sizeof(log), PSTR("HTTP: Other MQTT Enable %s, Emulation %d, Friendly Names %s, %s, %s and %s"), - getStateText(sysCfg.mqtt_enabled), sysCfg.emulation, sysCfg.friendlyname[0], sysCfg.friendlyname[1], sysCfg.friendlyname[2], sysCfg.friendlyname[3]); + getStateText(sysCfg.flag.mqtt_enabled), sysCfg.flag.emulation, sysCfg.friendlyname[0], sysCfg.friendlyname[1], sysCfg.friendlyname[2], sysCfg.friendlyname[3]); addLog(LOG_LEVEL_INFO, log); break; case 6: @@ -1190,7 +1190,7 @@ void handleUploadLoop() #ifdef USE_EMULATION UDP_Disconnect(); #endif // USE_EMULATION - if (sysCfg.mqtt_enabled) { + if (sysCfg.flag.mqtt_enabled) { mqttClient.disconnect(); } uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; @@ -1320,7 +1320,7 @@ void handleCmnd() if (message.length()) { message += F("\n"); } - if (sysCfg.mqtt_enabled) { + if (sysCfg.flag.mqtt_enabled) { // [14:49:36 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [RESULT = {"POWER":"OFF"}] // message += Log[counter].substring(17 + strlen(PUB_PREFIX) + strlen(sysCfg.mqtt_topic)); message += Log[counter].substring(Log[counter].lastIndexOf("/",Log[counter].indexOf("="))+1); @@ -1469,7 +1469,7 @@ void handleInfo() page += F("