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("AP MAC address"); page += WiFi.softAPmacAddress(); page += F(""); } page += F(" "); - if (sysCfg.mqtt_enabled) { + if (sysCfg.flag.mqtt_enabled) { page += F("MQTT Host"); page += sysCfg.mqtt_host; page += F(""); page += F("MQTT Port"); page += String(sysCfg.mqtt_port); page += F(""); page += F("MQTT Client &
 Fallback Topic"); page += MQTTClient; page += F(""); @@ -1483,10 +1483,10 @@ void handleInfo() page += F("Emulation"); #ifdef USE_EMULATION - if (EMUL_WEMO == sysCfg.emulation) { + if (EMUL_WEMO == sysCfg.flag.emulation) { page += F("Belkin WeMo"); } - else if (EMUL_HUE == sysCfg.emulation) { + else if (EMUL_HUE == sysCfg.flag.emulation) { page += F("Hue Bridge"); } else { @@ -1556,7 +1556,7 @@ void handleNotFound() #ifdef USE_EMULATION String path = webServer->uri(); - if ((EMUL_HUE == sysCfg.emulation) && (path.startsWith("/api"))) { + if ((EMUL_HUE == sysCfg.flag.emulation) && (path.startsWith("/api"))) { handle_hue_api(&path); } else #endif // USE_EMULATION diff --git a/sonoff/xdrv_snfsc.ino b/sonoff/xdrv_snfsc.ino index 88d22264b..892eb31eb 100644 --- a/sonoff/xdrv_snfsc.ino +++ b/sonoff/xdrv_snfsc.ino @@ -111,13 +111,10 @@ void sc_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) char stemp1[10]; char stemp2[10]; - float t = sc_value[1]; - if (TEMP_CONVERSION) { - t = sc_convertCtoF(t); - } - dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1); + float t = convertTemp(sc_value[1]); + dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1); float h = sc_value[0]; - dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2); + dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp2); // snprintf_P(svalue, ssvalue, PSTR("%s, \"SC\":{\"Temperature\":%s, \"Humidity\":%s, \"Light\":%d, \"Noise\":%d, \"AirQuality\":%d}"), snprintf_P(svalue, ssvalue, PSTR("%s, \"Temperature\":%s, \"Humidity\":%s, \"Light\":%d, \"Noise\":%d, \"AirQuality\":%d"), svalue, stemp1, stemp2, sc_value[2], sc_value[3], sc_value[4]); @@ -139,15 +136,12 @@ String sc_webPresent() char sensor[80]; char scstype[] = ""; - float t = sc_value[1]; - if (TEMP_CONVERSION) { - t = sc_convertCtoF(t); - } - dtostrf(t, 1, TEMP_RESOLUTION &3, stemp); - snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, scstype, stemp, (TEMP_CONVERSION) ? 'F' : 'C'); + float t = convertTemp(sc_value[1]); + dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp); + snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, scstype, stemp, tempUnit()); page += sensor; float h = sc_value[0]; - dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp); + dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp); snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, scstype, stemp); page += sensor; snprintf_P(sensor, sizeof(sensor), HTTP_SNS_LIGHT, scstype, sc_value[2]); diff --git a/sonoff/xdrv_wemohue.ino b/sonoff/xdrv_wemohue.ino index 5092ea6d0..b7e1b9e2c 100644 --- a/sonoff/xdrv_wemohue.ino +++ b/sonoff/xdrv_wemohue.ino @@ -214,10 +214,10 @@ void pollUDP() String request = packetBuffer; // addLog_P(LOG_LEVEL_DEBUG_MORE, packetBuffer); if (request.indexOf("M-SEARCH") >= 0) { - if ((EMUL_WEMO == sysCfg.emulation) &&(request.indexOf("urn:Belkin:device:**") > 0)) { + if ((EMUL_WEMO == sysCfg.flag.emulation) &&(request.indexOf("urn:Belkin:device:**") > 0)) { wemo_respondToMSearch(); } - else if ((EMUL_HUE == sysCfg.emulation) && ((request.indexOf("ST: urn:schemas-upnp-org:device:basic:1") > 0) || (request.indexOf("ST: upnp:rootdevice") > 0) || (request.indexOf("ST: ssdp:all") > 0))) { + else if ((EMUL_HUE == sysCfg.flag.emulation) && ((request.indexOf("ST: urn:schemas-upnp-org:device:basic:1") > 0) || (request.indexOf("ST: upnp:rootdevice") > 0) || (request.indexOf("ST: ssdp:all") > 0))) { hue_respondToMSearch(); } } diff --git a/sonoff/xsns_bmp.ino b/sonoff/xsns_bmp.ino index 391cba0a2..adf9a47c6 100644 --- a/sonoff/xsns_bmp.ino +++ b/sonoff/xsns_bmp.ino @@ -351,12 +351,7 @@ double bme280_readHumidity(void) * BMP \*********************************************************************************************/ -double bmp_convertCtoF(double c) -{ - return c * 1.8 + 32; -} - -double bmp_readTemperature(bool S) +double bmp_readTemperature(void) { double t = NAN; @@ -369,9 +364,7 @@ double bmp_readTemperature(bool S) t = bmp280_readTemperature(); } if (!isnan(t)) { - if (S) { - t = bmp_convertCtoF(t); - } + t = convertTemp(t); return t; } return 0; @@ -453,12 +446,12 @@ void bmp_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) char stemp2[10]; char stemp3[10]; - double t = bmp_readTemperature(TEMP_CONVERSION); + double t = bmp_readTemperature(); double p = bmp_readPressure(); double h = bmp_readHumidity(); - dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1); - dtostrf(p, 1, PRESSURE_RESOLUTION &3, stemp2); - dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp3); + dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1); + dtostrf(p, 1, sysCfg.flag.pressure_resolution, stemp2); + dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp3); if (!strcmp(bmpstype,"BME280")) { snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s, \"Pressure\":%s}"), svalue, bmpstype, stemp1, stemp3, stemp2); @@ -480,18 +473,18 @@ String bmp_webPresent() char stemp[10]; char sensor[80]; - double t_bmp = bmp_readTemperature(TEMP_CONVERSION); + double t_bmp = bmp_readTemperature(); double p_bmp = bmp_readPressure(); double h_bmp = bmp_readHumidity(); - dtostrf(t_bmp, 1, TEMP_RESOLUTION &3, stemp); - snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, bmpstype, stemp, (TEMP_CONVERSION) ? 'F' : 'C'); + dtostrf(t_bmp, 1, sysCfg.flag.temperature_resolution, stemp); + snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, bmpstype, stemp, tempUnit()); page += sensor; if (!strcmp(bmpstype,"BME280")) { - dtostrf(h_bmp, 1, HUMIDITY_RESOLUTION &3, stemp); + dtostrf(h_bmp, 1, sysCfg.flag.humidity_resolution, stemp); snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, bmpstype, stemp); page += sensor; } - dtostrf(p_bmp, 1, PRESSURE_RESOLUTION &3, stemp); + dtostrf(p_bmp, 1, sysCfg.flag.pressure_resolution, stemp); snprintf_P(sensor, sizeof(sensor), HTTP_SNS_PRESSURE, bmpstype, stemp); page += sensor; } diff --git a/sonoff/xsns_dht.ino b/sonoff/xsns_dht.ino index d391bad1b..3b130b91a 100644 --- a/sonoff/xsns_dht.ino +++ b/sonoff/xsns_dht.ino @@ -32,71 +32,80 @@ POSSIBILITY OF SUCH DAMAGE. * Source: Adafruit Industries https://github.com/adafruit/DHT-sensor-library \*********************************************************************************************/ -#define MIN_INTERVAL 2000 +#define DHT_MAX_SENSORS 3 +#define MIN_INTERVAL 2000 -uint8_t data[5]; -char dhtstype[7]; -uint32_t _lastreadtime; -uint32_t _maxcycles; -bool _lastresult; -float mt; -float mh = 0; +uint32_t dht_maxcycles; +uint8_t dht_data[5]; +byte dht_sensors = 0; + +struct DHTSTRUCT { + byte pin; + byte type; + char stype[10]; + uint32_t lastreadtime; + bool lastresult; + float t; + float h = 0; +} dht[DHT_MAX_SENSORS]; void dht_readPrep() { - digitalWrite(pin[GPIO_DHT11], HIGH); + for (byte i = 0; i < dht_sensors; i++) { + digitalWrite(dht[i].pin, HIGH); + } } -uint32_t dht_expectPulse(bool level) +uint32_t dht_expectPulse(byte sensor, bool level) { uint32_t count = 0; - while (digitalRead(pin[GPIO_DHT11]) == level) { - if (count++ >= _maxcycles) { + while (digitalRead(dht[sensor].pin) == level) { + if (count++ >= dht_maxcycles) { return 0; } } return count; } -boolean dht_read() +boolean dht_read(byte sensor) { char log[LOGSZ]; uint32_t cycles[80]; uint32_t currenttime = millis(); - if ((currenttime - _lastreadtime) < 2000) { - return _lastresult; + if ((currenttime - dht[sensor].lastreadtime) < 2000) { + return dht[sensor].lastresult; } - _lastreadtime = currenttime; + dht[sensor].lastreadtime = currenttime; - data[0] = data[1] = data[2] = data[3] = data[4] = 0; + dht_data[0] = dht_data[1] = dht_data[2] = dht_data[3] = dht_data[4] = 0; -// digitalWrite(pin[GPIO_DHT11], HIGH); +// digitalWrite(dht[sensor].pin, HIGH); // delay(250); - pinMode(pin[GPIO_DHT11], OUTPUT); - digitalWrite(pin[GPIO_DHT11], LOW); + pinMode(dht[sensor].pin, OUTPUT); + digitalWrite(dht[sensor].pin, LOW); delay(20); noInterrupts(); - digitalWrite(pin[GPIO_DHT11], HIGH); + digitalWrite(dht[sensor].pin, HIGH); delayMicroseconds(40); - pinMode(pin[GPIO_DHT11], INPUT_PULLUP); + pinMode(dht[sensor].pin, INPUT_PULLUP); delayMicroseconds(10); - if (0 == dht_expectPulse(LOW)) { + if (0 == dht_expectPulse(sensor, LOW)) { addLog_P(LOG_LEVEL_DEBUG, PSTR("DHT: Timeout waiting for start signal low pulse")); - _lastresult = false; - return _lastresult; + dht[sensor].lastresult = false; + return dht[sensor].lastresult; } - if (0 == dht_expectPulse(HIGH)) { + if (0 == dht_expectPulse(sensor, HIGH)) { addLog_P(LOG_LEVEL_DEBUG, PSTR("DHT: Timeout waiting for start signal high pulse")); - _lastresult = false; - return _lastresult; + dht[sensor].lastresult = false; + return dht[sensor].lastresult; } for (int i = 0; i < 80; i += 2) { - cycles[i] = dht_expectPulse(LOW); - cycles[i+1] = dht_expectPulse(HIGH); + cycles[i] = dht_expectPulse(sensor, LOW); + cycles[i+1] = dht_expectPulse(sensor, HIGH); } interrupts(); @@ -105,101 +114,105 @@ boolean dht_read() uint32_t highCycles = cycles[2*i+1]; if ((0 == lowCycles) || (0 == highCycles)) { addLog_P(LOG_LEVEL_DEBUG, PSTR("DHT: Timeout waiting for pulse")); - _lastresult = false; - return _lastresult; + dht[sensor].lastresult = false; + return dht[sensor].lastresult; } - data[i/8] <<= 1; + dht_data[i/8] <<= 1; if (highCycles > lowCycles) { - data[i/8] |= 1; + dht_data[i/8] |= 1; } } snprintf_P(log, sizeof(log), PSTR("DHT: Received %02X, %02X, %02X, %02X, %02X =? %02X"), - data[0], data[1], data[2], data[3], data[4], (data[0] + data[1] + data[2] + data[3]) & 0xFF); + dht_data[0], dht_data[1], dht_data[2], dht_data[3], dht_data[4], (dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF); addLog(LOG_LEVEL_DEBUG, log); - if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) { - _lastresult = true; - return _lastresult; + if (dht_data[4] == ((dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF)) { + dht[sensor].lastresult = true; } else { addLog_P(LOG_LEVEL_DEBUG, PSTR("DHT: Checksum failure")); - _lastresult = false; - return _lastresult; + dht[sensor].lastresult = false; } + return dht[sensor].lastresult; } -float dht_convertCtoF(float c) +boolean dht_readTempHum(byte sensor, float &t, float &h) { - return c * 1.8 + 32; -} - -boolean dht_readTempHum(bool S, float &t, float &h) -{ - if (!mh) { + if (!dht[sensor].h) { t = NAN; h = NAN; } else { - t = mt; - h = mh; + t = dht[sensor].t; + h = dht[sensor].h; } - if (dht_read()) { - switch (dht_type) { + if (dht_read(sensor)) { + switch (dht[sensor].type) { case GPIO_DHT11: - h = data[0]; - t = data[2]; - if (S) { - t = dht_convertCtoF(t); - } + h = dht_data[0]; + t = convertTemp(dht_data[2]); break; case GPIO_DHT22: case GPIO_DHT21: - h = data[0]; + h = dht_data[0]; h *= 256; - h += data[1]; + h += dht_data[1]; h *= 0.1; - t = data[2] & 0x7F; + t = dht_data[2] & 0x7F; t *= 256; - t += data[3]; + t += dht_data[3]; t *= 0.1; - if (data[2] & 0x80) { + if (dht_data[2] & 0x80) { t *= -1; } - if (S) { - t = dht_convertCtoF(t); - } + t = convertTemp(t); break; } if (!isnan(t)) { - mt = t; + dht[sensor].t = t; } if (!isnan(h)) { - mh = h; + dht[sensor].h = h; } } return (!isnan(t) && !isnan(h)); } +boolean dht_setup(byte pin, byte type) +{ + boolean success = false; + + if (dht_sensors < DHT_MAX_SENSORS) { + dht[dht_sensors].pin = pin; + dht[dht_sensors].type = type; + dht_sensors++; + success = true; + } + return success; +} + void dht_init() { char log[LOGSZ]; - _maxcycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for - // reading pulses from DHT sensor. - pinMode(pin[GPIO_DHT11], INPUT_PULLUP); - _lastreadtime = -MIN_INTERVAL; - switch (dht_type) { - case GPIO_DHT11: - strcpy(dhtstype, "DHT11"); - break; - case GPIO_DHT21: - strcpy(dhtstype, "AM2301"); - break; - case GPIO_DHT22: - strcpy(dhtstype, "DHT22"); + dht_maxcycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for reading pulses from DHT sensor. + + for (byte i = 0; i < dht_sensors; i++) { + pinMode(dht[i].pin, INPUT_PULLUP); + dht[i].lastreadtime = -MIN_INTERVAL; + switch (dht[i].type) { + case GPIO_DHT11: + snprintf_P(dht[i].stype, sizeof(dht[i].stype), PSTR("DHT11-%02d"), dht[i].pin); + break; + case GPIO_DHT21: + snprintf_P(dht[i].stype, sizeof(dht[i].stype), PSTR("AM2301-%02d"), dht[i].pin); + break; + case GPIO_DHT22: + snprintf_P(dht[i].stype, sizeof(dht[i].stype), PSTR("DHT22-%02d"), dht[i].pin); + } } - - snprintf_P(log, sizeof(log), PSTR("DHT: Max clock cycles %d"), _maxcycles); + + snprintf_P(log, sizeof(log), PSTR("DHT: Max clock cycles %d"), dht_maxcycles); addLog(LOG_LEVEL_DEBUG, log); } @@ -214,16 +227,22 @@ void dht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) float t; float h; - if (dht_readTempHum(TEMP_CONVERSION, t, h)) { // Read temperature - dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1); - dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2); -// snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}"), -// svalue, dhtstype, stemp1, stemp2); - snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, dhtstype, stemp1, stemp2); - *djson = 1; + byte dsxflg = 0; + for (byte i = 0; i < dht_sensors; i++) { + if (dht_readTempHum(i, t, h)) { // Read temperature + dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1); + dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp2); +// snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}"), +// svalue, dhtstype, stemp1, stemp2); + snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, dht[i].stype, stemp1, stemp2); + *djson = 1; #ifdef USE_DOMOTICZ - domoticz_sensor2(stemp1, stemp2); + if (!dsxflg) { + domoticz_sensor2(stemp1, stemp2); + dsxflg++; + } #endif // USE_DOMOTICZ + } } } @@ -231,20 +250,20 @@ void dht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) String dht_webPresent() { String page = ""; + char stemp[10]; + char sensor[80]; float t; float h; - if (dht_readTempHum(TEMP_CONVERSION, t, h)) { // Read temperature as Celsius (the default) - char stemp[10]; - char sensor[80]; - - dtostrf(t, 1, TEMP_RESOLUTION &3, stemp); - snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, dhtstype, stemp, (TEMP_CONVERSION) ? 'F' : 'C'); - page += sensor; - dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp); - snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, dhtstype, stemp); - page += sensor; - + for (byte i = 0; i < dht_sensors; i++) { + if (dht_readTempHum(i, t, h)) { + dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp); + snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, dht[i].stype, stemp, tempUnit()); + page += sensor; + dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp); + snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, dht[i].stype, stemp); + page += sensor; + } } return page; } diff --git a/sonoff/xsns_ds18b20.ino b/sonoff/xsns_ds18b20.ino index b84ff0857..0c24e962e 100644 --- a/sonoff/xsns_ds18b20.ino +++ b/sonoff/xsns_ds18b20.ino @@ -129,12 +129,7 @@ void dsb_readTempPrep() dsb_write(0x44); // Start conversion } -float dsb_convertCtoF(float c) -{ - return c * 1.8 + 32; -} - -boolean dsb_readTemp(bool S, float &t) +boolean dsb_readTemp(float &t) { int16_t DSTemp; byte msb, lsb, crc, sign = 1; @@ -178,10 +173,7 @@ boolean dsb_readTemp(bool S, float &t) DSTemp = (~DSTemp) +1; sign = -1; } - t = (float)sign * DSTemp * 0.0625; - if(S) { - t = dsb_convertCtoF(t); - } + t = convertTemp((float)sign * DSTemp * 0.0625); } if (!isnan(t)) dsb_mt = t; return !isnan(t); @@ -196,8 +188,8 @@ void dsb_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) char stemp1[10]; float t; - if (dsb_readTemp(TEMP_CONVERSION, t)) { // Check if read failed - dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1); + if (dsb_readTemp(t)) { // Check if read failed + dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1); snprintf_P(svalue, ssvalue, PSTR("%s, \"DS18B20\":{\"Temperature\":%s}"), svalue, stemp1); *djson = 1; #ifdef USE_DOMOTICZ @@ -213,12 +205,12 @@ String dsb_webPresent() String page = ""; float st; - if (dsb_readTemp(TEMP_CONVERSION, st)) { // Check if read failed + if (dsb_readTemp(st)) { // Check if read failed char stemp[10]; char sensor[80]; - dtostrf(st, 1, TEMP_RESOLUTION &3, stemp); - snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "DS18B20", stemp, (TEMP_CONVERSION) ? 'F' : 'C'); + dtostrf(st, 1, sysCfg.flag.temperature_resolution, stemp); + snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "DS18B20", stemp, tempUnit()); page += sensor; } dsb_readTempPrep(); diff --git a/sonoff/xsns_ds18x20.ino b/sonoff/xsns_ds18x20.ino index 8afc60863..4eef3f685 100644 --- a/sonoff/xsns_ds18x20.ino +++ b/sonoff/xsns_ds18x20.ino @@ -107,12 +107,7 @@ void ds18x20_convert() // delay(750); // 750ms should be enough for 12bit conv } -float ds18x20_convertCtoF(float c) -{ - return c * 1.8 + 32; -} - -boolean ds18x20_read(uint8_t sensor, bool S, float &t) +boolean ds18x20_read(uint8_t sensor, float &t) { byte data[12]; int8_t sign = 1; @@ -155,10 +150,7 @@ boolean ds18x20_read(uint8_t sensor, bool S, float &t) } else { temp9 = (data[0] >> 1) * sign; } - t = (temp9 - 0.25) + ((16.0 - data[6]) / 16.0); - if(S) { - t = ds18x20_convertCtoF(t); - } + t = convertTemp((temp9 - 0.25) + ((16.0 - data[6]) / 16.0)); break; case DS18B20_CHIPID: // DS18B20 case MAX31850_CHIPID: // MAX31850 @@ -167,10 +159,7 @@ boolean ds18x20_read(uint8_t sensor, bool S, float &t) temp12 = (~temp12) +1; sign = -1; } - t = sign * temp12 * 0.0625; - if(S) { - t = ds18x20_convertCtoF(t); - } + t = convertTemp(sign * temp12 * 0.0625); break; } } @@ -205,9 +194,9 @@ void ds18x20_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) byte dsxflg = 0; for (byte i = 0; i < ds18x20_sensors(); i++) { - if (ds18x20_read(i, TEMP_CONVERSION, t)) { // Check if read failed + if (ds18x20_read(i, t)) { // Check if read failed ds18x20_type(i); - dtostrf(t, 1, TEMP_RESOLUTION &3, stemp2); + dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp2); if (!dsxflg) { snprintf_P(svalue, ssvalue, PSTR("%s, \"DS18x20\":{"), svalue); *djson = 1; @@ -237,11 +226,11 @@ String ds18x20_webPresent() float t; for (byte i = 0; i < ds18x20_sensors(); i++) { - if (ds18x20_read(i, TEMP_CONVERSION, t)) { // Check if read failed + if (ds18x20_read(i, t)) { // Check if read failed ds18x20_type(i); - dtostrf(t, 1, TEMP_RESOLUTION &3, stemp); + dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp); snprintf_P(stemp2, sizeof(stemp2), PSTR("%s-%d"), dsbstype, i +1); - snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, stemp2, stemp, (TEMP_CONVERSION) ? 'F' : 'C'); + snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, stemp2, stemp, tempUnit()); page += sensor; } } diff --git a/sonoff/xsns_hlw8012.ino b/sonoff/xsns_hlw8012.ino index 340c6cb71..4f18f0fb0 100644 --- a/sonoff/xsns_hlw8012.ino +++ b/sonoff/xsns_hlw8012.ino @@ -375,7 +375,7 @@ void hlw_margin_chk() } else { hlw_mplh_counter--; if (!hlw_mplh_counter) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerReached\":\"%d%s\"}"), pw, (sysCfg.value_units) ? " W" : ""); + snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerReached\":\"%d%s\"}"), pw, (sysCfg.flag.value_units) ? " W" : ""); mqtt_publish_topic_P(0, PSTR("WARNING"), svalue); do_cmnd_power(1, 0); if (!hlw_mplr_counter) { @@ -421,7 +421,7 @@ void hlw_margin_chk() else if ((1 == hlw_mkwh_state) && (uped >= sysCfg.hlw_mkwh)) { hlw_mkwh_state = 2; dtostrf(ped, 1, 3, svalue); - snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxEnergyReached\":\"%s%s\"}"), svalue, (sysCfg.value_units) ? " kWh" : ""); + snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxEnergyReached\":\"%s%s\"}"), svalue, (sysCfg.flag.value_units) ? " kWh" : ""); mqtt_publish_topic_P(0, PSTR("WARNING"), svalue); do_cmnd_power(1, 0); } @@ -441,105 +441,105 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { sysCfg.hlw_pmin = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"PowerLow\":\"%d%s\"}"), sysCfg.hlw_pmin, (sysCfg.value_units) ? " W" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"PowerLow\":\"%d%s\"}"), sysCfg.hlw_pmin, (sysCfg.flag.value_units) ? " W" : ""); } else if (!strcmp_P(type,PSTR("POWERHIGH"))) { if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { sysCfg.hlw_pmax = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"PowerHigh\":\"%d%s\"}"), sysCfg.hlw_pmax, (sysCfg.value_units) ? " W" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"PowerHigh\":\"%d%s\"}"), sysCfg.hlw_pmax, (sysCfg.flag.value_units) ? " W" : ""); } else if (!strcmp_P(type,PSTR("VOLTAGELOW"))) { if ((data_len > 0) && (payload >= 0) && (payload < 501)) { sysCfg.hlw_umin = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"VoltageLow\":\"%d%s\"}"), sysCfg.hlw_umin, (sysCfg.value_units) ? " V" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"VoltageLow\":\"%d%s\"}"), sysCfg.hlw_umin, (sysCfg.flag.value_units) ? " V" : ""); } else if (!strcmp_P(type,PSTR("VOLTAGEHIGH"))) { if ((data_len > 0) && (payload >= 0) && (payload < 501)) { sysCfg.hlw_umax = payload; } - snprintf_P(svalue, ssvalue, PSTR("[\"VoltageHigh\":\"%d%s\"}"), sysCfg.hlw_umax, (sysCfg.value_units) ? " V" : ""); + snprintf_P(svalue, ssvalue, PSTR("[\"VoltageHigh\":\"%d%s\"}"), sysCfg.hlw_umax, (sysCfg.flag.value_units) ? " V" : ""); } else if (!strcmp_P(type,PSTR("CURRENTLOW"))) { if ((data_len > 0) && (payload >= 0) && (payload < 16001)) { sysCfg.hlw_imin = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"CurrentLow\":\"%d%s\"}"), sysCfg.hlw_imin, (sysCfg.value_units) ? " mA" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"CurrentLow\":\"%d%s\"}"), sysCfg.hlw_imin, (sysCfg.flag.value_units) ? " mA" : ""); } else if (!strcmp_P(type,PSTR("CURRENTHIGH"))) { if ((data_len > 0) && (payload >= 0) && (payload < 16001)) { sysCfg.hlw_imax = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"CurrentHigh\":\"%d%s\"}"), sysCfg.hlw_imax, (sysCfg.value_units) ? " mA" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"CurrentHigh\":\"%d%s\"}"), sysCfg.hlw_imax, (sysCfg.flag.value_units) ? " mA" : ""); } else if (!strcmp_P(type,PSTR("HLWPCAL"))) { if ((data_len > 0) && (payload > 0) && (payload < 32001)) { sysCfg.hlw_pcal = (payload > 9999) ? payload : HLW_PREF_PULSE; // 12530 } - snprintf_P(svalue, ssvalue, PSTR("(\"HlwPcal\":\"%d%s\"}"), sysCfg.hlw_pcal, (sysCfg.value_units) ? " uS" : ""); + snprintf_P(svalue, ssvalue, PSTR("(\"HlwPcal\":\"%d%s\"}"), sysCfg.hlw_pcal, (sysCfg.flag.value_units) ? " uS" : ""); } else if (!strcmp_P(type,PSTR("HLWUCAL"))) { if ((data_len > 0) && (payload > 0) && (payload < 32001)) { sysCfg.hlw_ucal = (payload > 999) ? payload : HLW_UREF_PULSE; // 1950 } - snprintf_P(svalue, ssvalue, PSTR("{\"HlwUcal\":\"%d%s\"}"), sysCfg.hlw_ucal, (sysCfg.value_units) ? " uS" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"HlwUcal\":\"%d%s\"}"), sysCfg.hlw_ucal, (sysCfg.flag.value_units) ? " uS" : ""); } else if (!strcmp_P(type,PSTR("HLWICAL"))) { if ((data_len > 0) && (payload > 0) && (payload < 32001)) { sysCfg.hlw_ical = (payload > 2499) ? payload : HLW_IREF_PULSE; // 3500 } - snprintf_P(svalue, ssvalue, PSTR("{\"HlwIcal\":\"%d%s\"}"), sysCfg.hlw_ical, (sysCfg.value_units) ? " uS" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"HlwIcal\":\"%d%s\"}"), sysCfg.hlw_ical, (sysCfg.flag.value_units) ? " uS" : ""); } #if FEATURE_POWER_LIMIT else if (!strcmp_P(type,PSTR("MAXPOWER"))) { if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { sysCfg.hlw_mpl = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"MaxPower\":\"%d%s\"}"), sysCfg.hlw_mpl, (sysCfg.value_units) ? " W" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"MaxPower\":\"%d%s\"}"), sysCfg.hlw_mpl, (sysCfg.flag.value_units) ? " W" : ""); } else if (!strcmp_P(type,PSTR("MAXPOWERHOLD"))) { if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { sysCfg.hlw_mplh = (1 == payload) ? MAX_POWER_HOLD : payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerHold\":\"%d%s\"}"), sysCfg.hlw_mplh, (sysCfg.value_units) ? " Sec" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerHold\":\"%d%s\"}"), sysCfg.hlw_mplh, (sysCfg.flag.value_units) ? " Sec" : ""); } else if (!strcmp_P(type,PSTR("MAXPOWERWINDOW"))) { if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { sysCfg.hlw_mplw = (1 == payload) ? MAX_POWER_WINDOW : payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerWindow\":\"%d%s\"}"), sysCfg.hlw_mplw, (sysCfg.value_units) ? " Sec" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerWindow\":\"%d%s\"}"), sysCfg.hlw_mplw, (sysCfg.flag.value_units) ? " Sec" : ""); } else if (!strcmp_P(type,PSTR("SAFEPOWER"))) { if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { sysCfg.hlw_mspl = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"SafePower\":\"%d%s\"}"), sysCfg.hlw_mspl, (sysCfg.value_units) ? " W" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"SafePower\":\"%d%s\"}"), sysCfg.hlw_mspl, (sysCfg.flag.value_units) ? " W" : ""); } else if (!strcmp_P(type,PSTR("SAFEPOWERHOLD"))) { if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { sysCfg.hlw_msplh = (1 == payload) ? SAFE_POWER_HOLD : payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerHold\":\"%d%s\"}"), sysCfg.hlw_msplh, (sysCfg.value_units) ? " Sec" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerHold\":\"%d%s\"}"), sysCfg.hlw_msplh, (sysCfg.flag.value_units) ? " Sec" : ""); } else if (!strcmp_P(type,PSTR("SAFEPOWERWINDOW"))) { if ((data_len > 0) && (payload >= 0) && (payload < 1440)) { sysCfg.hlw_msplw = (1 == payload) ? SAFE_POWER_WINDOW : payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerWindow\":\"%d%s\"}"), sysCfg.hlw_msplw, (sysCfg.value_units) ? " Min" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerWindow\":\"%d%s\"}"), sysCfg.hlw_msplw, (sysCfg.flag.value_units) ? " Min" : ""); } else if (!strcmp_P(type,PSTR("MAXENERGY"))) { if ((data_len > 0) && (payload >= 0) && (payload < 3601)) { sysCfg.hlw_mkwh = payload; hlw_mkwh_state = 3; } - snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergy\":\"%d%s\"}"), sysCfg.hlw_mkwh, (sysCfg.value_units) ? " Wh" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergy\":\"%d%s\"}"), sysCfg.hlw_mkwh, (sysCfg.flag.value_units) ? " Wh" : ""); } else if (!strcmp_P(type,PSTR("MAXENERGYSTART"))) { if ((data_len > 0) && (payload >= 0) && (payload < 24)) { sysCfg.hlw_mkwhs = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergyStart\":\"%d%s\"}"), sysCfg.hlw_mkwhs, (sysCfg.value_units) ? " Hr" : ""); + snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergyStart\":\"%d%s\"}"), sysCfg.hlw_mkwhs, (sysCfg.flag.value_units) ? " Hr" : ""); } #endif // FEATURE_POWER_LIMIT else { @@ -567,8 +567,8 @@ void hlw_mqttStat(byte option, char* svalue, uint16_t ssvalue) uint16_t pu; hlw_readEnergy(option, ped, pe, pw, pu, pi, pc); - dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, ENERGY_RESOLUTION &7, stemp0); - dtostrf(ped, 1, ENERGY_RESOLUTION &7, stemp1); + dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, stemp0); + dtostrf(ped, 1, sysCfg.flag.energy_resolution, stemp1); dtostrf(pc, 1, 2, stemp2); dtostrf(pi, 1, 3, stemp3); snprintf_P(speriod, sizeof(speriod), PSTR(", \"Period\":%d"), pe); @@ -625,8 +625,8 @@ String hlw_webPresent() dtostrf(pi, 1, 3, stemp); dtostrf(pc, 1, 2, stemp2); - dtostrf(ped, 1, ENERGY_RESOLUTION &7, stemp3); - dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, ENERGY_RESOLUTION &7, stemp4); + dtostrf(ped, 1, sysCfg.flag.energy_resolution, stemp3); + dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, stemp4); snprintf_P(sensor, sizeof(sensor), HTTP_ENERGY_SNS, pu, stemp, pw, stemp2, stemp3, stemp4); page += sensor; return page; diff --git a/sonoff/xsns_htu21.ino b/sonoff/xsns_htu21.ino index fb943a710..03cf4976e 100644 --- a/sonoff/xsns_htu21.ino +++ b/sonoff/xsns_htu21.ino @@ -138,11 +138,6 @@ boolean htu21_init() return true; } -float htu21_convertCtoF(float c) -{ - return c * 1.8 + 32; -} - float htu21_readHumidity(void) { uint8_t checksum = 0; @@ -179,7 +174,7 @@ float htu21_readHumidity(void) return humidity; } -float htu21_readTemperature(bool S) +float htu21_readTemperature() { uint8_t checksum=0; uint16_t sensorval=0; @@ -202,10 +197,7 @@ float htu21_readTemperature(bool S) return 0.0; // Checksum mismatch } - t = (0.002681 * (float)sensorval - 46.85); - if(S) { - t = htu21_convertCtoF(t); - } + t = convertTemp(0.002681 * (float)sensorval - 46.85); return t; } @@ -279,11 +271,11 @@ void htu_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) char stemp1[10]; char stemp2[10]; - float t = htu21_readTemperature(TEMP_CONVERSION); + float t = htu21_readTemperature(); float h = htu21_readHumidity(); h = htu21_compensatedHumidity(h, t); - dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1); - dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2); + dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1); + dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp2); snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, htustype, stemp1, stemp2); *djson = 1; #ifdef USE_DOMOTICZ @@ -299,13 +291,13 @@ String htu_webPresent() char stemp[10]; char sensor[80]; - float t_htu21 = htu21_readTemperature(TEMP_CONVERSION); + float t_htu21 = htu21_readTemperature(); float h_htu21 = htu21_readHumidity(); h_htu21 = htu21_compensatedHumidity(h_htu21, t_htu21); - dtostrf(t_htu21, 1, TEMP_RESOLUTION &3, stemp); - snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, htustype, stemp, (TEMP_CONVERSION) ? 'F' : 'C'); + dtostrf(t_htu21, 1, sysCfg.flag.temperature_resolution, stemp); + snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, htustype, stemp, tempUnit()); page += sensor; - dtostrf(h_htu21, 1, HUMIDITY_RESOLUTION &3, stemp); + dtostrf(h_htu21, 1, sysCfg.flag.humidity_resolution, stemp); snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, htustype, stemp); page += sensor; } diff --git a/sonoff/xsns_sht1x.ino b/sonoff/xsns_sht1x.ino index 7365c2fb9..4937d067f 100644 --- a/sonoff/xsns_sht1x.ino +++ b/sonoff/xsns_sht1x.ino @@ -161,9 +161,7 @@ boolean sht_readTempHum(float &t, float &h) const float t2 = 0.00008; rhLinear = c1 + c2 * humRaw + c3 * humRaw * humRaw; h = (t - 25) * (t1 + t2 * humRaw) + rhLinear; - if (!isnan(t) && TEMP_CONVERSION) { - t = t * 1.8 + 32; - } + t = convertTemp(t); return (!isnan(t) && !isnan(h)); } @@ -173,8 +171,8 @@ boolean sht_readCharTempHum(char* temp, char* hum) float h; boolean success = sht_readTempHum(t, h); - dtostrf(t, 1, TEMP_RESOLUTION &3, temp); - dtostrf(h, 1, HUMIDITY_RESOLUTION &3, hum); + dtostrf(t, 1, sysCfg.flag.temperature_resolution, temp); + dtostrf(h, 1, sysCfg.flag.humidity_resolution, hum); return success; } @@ -231,7 +229,7 @@ String sht_webPresent() if (sht_readCharTempHum(stemp, shum)) { char sensor[80]; - snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "SHT1X", stemp, (TEMP_CONVERSION) ? 'F' : 'C'); + snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "SHT1X", stemp, tempUnit()); page += sensor; snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, "SHT1X", shum); page += sensor;