From 0c59eb5585f5b698653e3b50776a6f0904024d6a Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Sun, 20 Aug 2017 11:40:50 +0200 Subject: [PATCH] Add more precision to Sonoff Pow period and power results using command WattRes 0|1 (#759) --- README.md | 2 +- sonoff/_releasenotes.ino | 5 +- sonoff/settings.h | 2 +- sonoff/sonoff.ino | 8 ++- sonoff/xsns_hlw8012.ino | 122 ++++++++++++++++++++------------------- 5 files changed, 77 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 12e520fc4..6458d091f 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.6.1b** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. +Current version is **5.6.1c** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. ### ATTENTION All versions diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 429e93858..ac763e00e 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,4 +1,7 @@ -/* 5.6.1b +/* 5.6.1c + * Add more precision to Sonoff Pow period and power results using command WattRes 0|1 (#759) + * + * 5.6.1b * Add Supla Espablo support (#755) * * 5.6.1a diff --git a/sonoff/settings.h b/sonoff/settings.h index 5f6d787bf..f51f8c1f8 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -41,7 +41,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t spare16 : 1; uint32_t spare17 : 1; uint32_t spare18 : 1; - uint32_t spare19 : 1; + uint32_t wattage_resolution : 1; uint32_t voltage_resolution : 1; uint32_t emulation : 2; uint32_t energy_resolution : 3; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index aaf9b477e..aeaa583b5 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,7 +25,7 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x05060102 // 5.6.1b +#define VERSION 0x05060103 // 5.6.1c 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}; @@ -1152,6 +1152,12 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } snprintf_P(svalue, sizeof(svalue), PSTR("{\"PressRes\":%d}"), sysCfg.flag.pressure_resolution); } + else if (!strcmp_P(type,PSTR("WATTRES"))) { + if ((payload >= 0) && (payload <= 1)) { + sysCfg.flag.wattage_resolution = payload; + } + snprintf_P(svalue, sizeof(svalue), PSTR("{\"WattRes\":%d}"), sysCfg.flag.wattage_resolution); + } else if (!strcmp_P(type,PSTR("VOLTRES"))) { if ((payload >= 0) && (payload <= 1)) { sysCfg.flag.voltage_resolution = payload; diff --git a/sonoff/xsns_hlw8012.ino b/sonoff/xsns_hlw8012.ino index 471b79d18..009ac8fa4 100644 --- a/sonoff/xsns_hlw8012.ino +++ b/sonoff/xsns_hlw8012.ino @@ -79,7 +79,7 @@ void hlw_cf_interrupt() // Service Power { hlw_cf_plen = micros() - hlw_cf_last; hlw_cf_last = micros(); - if (hlw_cf_plen > 4000000) { + if (hlw_cf_plen > 4000000) { // 4 seconds hlw_cf_plen = 0; // Just powered on } hlw_cf_timer = 15; // Support down to 4W which takes about 3 seconds @@ -139,7 +139,7 @@ void hlw_200mS() if (hlw_cf_timer) { hlw_cf_timer--; if (!hlw_cf_timer) { - hlw_cf_plen = 0; // No load for over three seconds + hlw_cf_plen = 0; // No load for over 3 seconds } } @@ -173,7 +173,7 @@ void hlw_savestate() sysCfg.hlw_kWhtotal = rtcMem.hlw_kWhtotal; } -void hlw_readEnergy(byte option, float &et, float &ed, uint16_t &e, uint16_t &w, float &u, float &i, float &c) +void hlw_readEnergy(byte option, float &et, float &ed, float &e, float &w, float &u, float &i, float &c) { /* option 0 = do not calculate period energy usage * option 1 = calculate period energy usage @@ -210,14 +210,14 @@ void hlw_readEnergy(byte option, float &et, float &ed, uint16_t &e, uint16_t &w, hlw_len = hlw_period * 1000000 / hlw_Ecntr; hlw_Ecntr = 0; hlw_temp = ((HLW_PREF * sysCfg.hlw_pcal) / hlw_len) / hlw_interval; - e = hlw_temp / 10; + e = (float)hlw_temp / 10; } } } w = 0; if (hlw_cf_plen) { hlw_w = (HLW_PREF * sysCfg.hlw_pcal) / hlw_cf_plen; - w = hlw_w / 10; + w = (float)hlw_w / 10; } u = 0; if (hlw_cf1u_plen && (w || (power &1))) { @@ -307,14 +307,15 @@ void hlw_margin_chk() char svalue[200]; // was MESSZ float pet; float ped; + float pe; + float pw; float pu; float pi; float pc; uint16_t uped; + uint16_t pwv; uint16_t puv; uint16_t piv; - uint16_t pe; - uint16_t pw; boolean flag; boolean jsonflg; @@ -325,6 +326,7 @@ void hlw_margin_chk() hlw_readEnergy(0, pet, ped, pe, pw, pu, pi, pc); if (power && (sysCfg.hlw_pmin || sysCfg.hlw_pmax || sysCfg.hlw_umin || sysCfg.hlw_umax || sysCfg.hlw_imin || sysCfg.hlw_imax)) { + pwv = (uint16_t)(pw); puv = (uint16_t)(pu); piv = (uint16_t)(pi * 1000); @@ -333,11 +335,11 @@ void hlw_margin_chk() snprintf_P(svalue, sizeof(svalue), PSTR("{")); jsonflg = 0; - if (hlw_margin(0, sysCfg.hlw_pmin, pw, flag, hlw_pminflg)) { + if (hlw_margin(0, sysCfg.hlw_pmin, pwv, flag, hlw_pminflg)) { snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"PowerLow\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag)); jsonflg = 1; } - if (hlw_margin(1, sysCfg.hlw_pmax, pw, flag, hlw_pmaxflg)) { + if (hlw_margin(1, sysCfg.hlw_pmax, pwv, flag, hlw_pmaxflg)) { snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"PowerHigh\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag)); jsonflg = 1; } @@ -373,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.flag.value_units) ? " W" : ""); + snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerReached\":\"%d%s\"}"), pwv, (sysCfg.flag.value_units) ? " W" : ""); mqtt_publish_topic_P(1, PSTR("WARNING"), svalue); hlw_mqttPresent(0); do_cmnd_power(1, 0); @@ -384,7 +386,7 @@ void hlw_margin_chk() } } } - else if (power && (pw <= sysCfg.hlw_mpl)) { + else if (power && (pwv <= sysCfg.hlw_mpl)) { hlw_mplh_counter = 0; hlw_mplr_counter = 0; hlw_mplw_counter = 0; @@ -492,13 +494,13 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len break; } } - char stemp0[10]; - char stemp1[10]; - char stemp2[10]; - dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, stemp0); - dtostrf((float)rtcMem.hlw_kWhtoday / 100000000, 1, sysCfg.flag.energy_resolution, stemp1); - dtostrf((float)(rtcMem.hlw_kWhtotal + (hlw_kWhtoday / 1000)) / 100000, 1, sysCfg.flag.energy_resolution, stemp2); - snprintf_P(svalue, ssvalue, PSTR("{\"EnergyReset\":{\"Total\":%s, \"Yesterday\":%s, \"Today\":%s}}"), stemp2, stemp0, stemp1); + char sey[10]; + char sen[10]; + char set[10]; + dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, sey); + dtostrf((float)rtcMem.hlw_kWhtoday / 100000000, 1, sysCfg.flag.energy_resolution, sen); + dtostrf((float)(rtcMem.hlw_kWhtotal + (hlw_kWhtoday / 1000)) / 100000, 1, sysCfg.flag.energy_resolution, set); + snprintf_P(svalue, ssvalue, PSTR("{\"EnergyReset\":{\"Total\":%s, \"Yesterday\":%s, \"Today\":%s}}"), set, sey, sen); } else if (!strcmp_P(type,PSTR("HLWPCAL"))) { if ((payload > 0) && (payload < 32001)) { @@ -613,35 +615,39 @@ void hlw_mqttStat(byte option, char* svalue, uint16_t ssvalue) /* option 0 = do not show period energy usage * option 1 = show period energy usage */ - char stemp0[10]; - char stemp1[10]; - char stemp2[10]; - char stemp3[10]; - char stemp4[10]; - char stemp5[10]; - char speriod[20]; float pet; float ped; + float pe; + float pw; float pu; float pi; float pc; - uint16_t pe; - uint16_t pw; + char spet[10]; + char sped[10]; + char spe[10]; + char spw[10]; + char spu[10]; + char spi[10]; + char spc[10]; + char sey[10]; + char speriod[20]; hlw_readEnergy(option, pet, ped, pe, pw, pu, pi, pc); - 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); - dtostrf(pet, 1, sysCfg.flag.energy_resolution, stemp4); - dtostrf(pu, 1, sysCfg.flag.voltage_resolution, stemp5); - snprintf_P(speriod, sizeof(speriod), PSTR(", \"Period\":%d"), pe); - snprintf_P(svalue, ssvalue, PSTR("%s\"Total\":%s, \"Yesterday\":%s, \"Today\":%s%s, \"Power\":%d, \"Factor\":%s, \"Voltage\":%s, \"Current\":%s}"), - svalue, stemp4, stemp0, stemp1, (option) ? speriod : "", pw, stemp2, stemp5, stemp3); + dtostrf(pet, 1, sysCfg.flag.energy_resolution, spet); + dtostrf(ped, 1, sysCfg.flag.energy_resolution, sped); + dtostrf(pe, 1, sysCfg.flag.wattage_resolution, spe); + dtostrf(pw, 1, sysCfg.flag.wattage_resolution, spw); + dtostrf(pu, 1, sysCfg.flag.voltage_resolution, spu); + dtostrf(pi, 1, 3, spi); + dtostrf(pc, 1, 2, spc); + dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, sey); + snprintf_P(speriod, sizeof(speriod), PSTR(", \"Period\":%s"), spe); + snprintf_P(svalue, ssvalue, PSTR("%s\"Total\":%s, \"Yesterday\":%s, \"Today\":%s%s, \"Power\":%s, \"Factor\":%s, \"Voltage\":%s, \"Current\":%s}"), + svalue, spet, sey, sped, (option) ? speriod : "", spw, spc, spu, spi); #ifdef USE_DOMOTICZ if (option) { // Only send if telemetry - dtostrf(pet * 1000, 1, 1, stemp1); - domoticz_sensor4(pw, stemp1); + dtostrf(pet * 1000, 1, 1, spet); + domoticz_sensor4((uint16_t)pw, spet); } #endif // USE_DOMOTICZ } @@ -670,7 +676,7 @@ void hlw_mqttStatus(char* svalue, uint16_t ssvalue) const char HTTP_ENERGY_SNS[] PROGMEM = "Voltage%s V" "Current%s A" - "Power%d W" + "Power%s W" "Power Factor%s" "Energy Today%s kWh" "Energy Yesterday%s kWh" @@ -678,32 +684,32 @@ const char HTTP_ENERGY_SNS[] PROGMEM = String hlw_webPresent() { - String page = ""; - char stemp[10]; - char stemp2[10]; - char stemp3[10]; - char stemp4[10]; - char stemp5[10]; - char stemp6[10]; - char sensor[320]; float pet; float ped; + float pe; + float pw; float pu; float pi; float pc; - uint16_t pe; - uint16_t pw; + char spet[10]; + char sped[10]; + char spw[10]; + char spu[10]; + char spi[10]; + char spc[10]; + char sey[10]; + char sensor[320]; hlw_readEnergy(0, pet, ped, pe, pw, pu, pi, pc); - dtostrf(pu, 1, sysCfg.flag.voltage_resolution, stemp6); - dtostrf(pi, 1, 3, stemp); - dtostrf(pc, 1, 2, stemp2); - dtostrf(ped, 1, sysCfg.flag.energy_resolution, stemp3); - dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, stemp4); - dtostrf(pet, 1, sysCfg.flag.energy_resolution, stemp5); - snprintf_P(sensor, sizeof(sensor), HTTP_ENERGY_SNS, stemp6, stemp, pw, stemp2, stemp3, stemp4, stemp5); - page += sensor; - return page; + dtostrf(pet, 1, sysCfg.flag.energy_resolution, spet); + dtostrf(ped, 1, sysCfg.flag.energy_resolution, sped); + dtostrf(pw, 1, sysCfg.flag.wattage_resolution, spw); + dtostrf(pu, 1, sysCfg.flag.voltage_resolution, spu); + dtostrf(pi, 1, 3, spi); + dtostrf(pc, 1, 2, spc); + dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, sey); + snprintf_P(sensor, sizeof(sensor), HTTP_ENERGY_SNS, spu, spi, spw, spc, sped, sey, spet); + return String(sensor); } #endif // USE_WEBSERVER