Add more precision to Sonoff Pow period and power results using command WattRes 0|1 (#759)

This commit is contained in:
Theo Arends 2017-08-20 11:40:50 +02:00
parent 3f365b6228
commit 0c59eb5585
5 changed files with 77 additions and 62 deletions

View File

@ -1,7 +1,7 @@
## Sonoff-Tasmota ## 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. 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 ### ATTENTION All versions

View File

@ -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) * Add Supla Espablo support (#755)
* *
* 5.6.1a * 5.6.1a

View File

@ -41,7 +41,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t spare16 : 1; uint32_t spare16 : 1;
uint32_t spare17 : 1; uint32_t spare17 : 1;
uint32_t spare18 : 1; uint32_t spare18 : 1;
uint32_t spare19 : 1; uint32_t wattage_resolution : 1;
uint32_t voltage_resolution : 1; uint32_t voltage_resolution : 1;
uint32_t emulation : 2; uint32_t emulation : 2;
uint32_t energy_resolution : 3; uint32_t energy_resolution : 3;

View File

@ -25,7 +25,7 @@
- Select IDE Tools - Flash Size: "1M (no SPIFFS)" - 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 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}; 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); 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"))) { else if (!strcmp_P(type,PSTR("VOLTRES"))) {
if ((payload >= 0) && (payload <= 1)) { if ((payload >= 0) && (payload <= 1)) {
sysCfg.flag.voltage_resolution = payload; sysCfg.flag.voltage_resolution = payload;

View File

@ -79,7 +79,7 @@ void hlw_cf_interrupt() // Service Power
{ {
hlw_cf_plen = micros() - hlw_cf_last; hlw_cf_plen = micros() - hlw_cf_last;
hlw_cf_last = micros(); 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_plen = 0; // Just powered on
} }
hlw_cf_timer = 15; // Support down to 4W which takes about 3 seconds hlw_cf_timer = 15; // Support down to 4W which takes about 3 seconds
@ -139,7 +139,7 @@ void hlw_200mS()
if (hlw_cf_timer) { if (hlw_cf_timer) {
hlw_cf_timer--; hlw_cf_timer--;
if (!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; 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 0 = do not calculate period energy usage
* option 1 = 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_len = hlw_period * 1000000 / hlw_Ecntr;
hlw_Ecntr = 0; hlw_Ecntr = 0;
hlw_temp = ((HLW_PREF * sysCfg.hlw_pcal) / hlw_len) / hlw_interval; hlw_temp = ((HLW_PREF * sysCfg.hlw_pcal) / hlw_len) / hlw_interval;
e = hlw_temp / 10; e = (float)hlw_temp / 10;
} }
} }
} }
w = 0; w = 0;
if (hlw_cf_plen) { if (hlw_cf_plen) {
hlw_w = (HLW_PREF * sysCfg.hlw_pcal) / hlw_cf_plen; hlw_w = (HLW_PREF * sysCfg.hlw_pcal) / hlw_cf_plen;
w = hlw_w / 10; w = (float)hlw_w / 10;
} }
u = 0; u = 0;
if (hlw_cf1u_plen && (w || (power &1))) { if (hlw_cf1u_plen && (w || (power &1))) {
@ -307,14 +307,15 @@ void hlw_margin_chk()
char svalue[200]; // was MESSZ char svalue[200]; // was MESSZ
float pet; float pet;
float ped; float ped;
float pe;
float pw;
float pu; float pu;
float pi; float pi;
float pc; float pc;
uint16_t uped; uint16_t uped;
uint16_t pwv;
uint16_t puv; uint16_t puv;
uint16_t piv; uint16_t piv;
uint16_t pe;
uint16_t pw;
boolean flag; boolean flag;
boolean jsonflg; boolean jsonflg;
@ -325,6 +326,7 @@ void hlw_margin_chk()
hlw_readEnergy(0, pet, ped, pe, pw, pu, pi, pc); 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)) { 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); puv = (uint16_t)(pu);
piv = (uint16_t)(pi * 1000); piv = (uint16_t)(pi * 1000);
@ -333,11 +335,11 @@ void hlw_margin_chk()
snprintf_P(svalue, sizeof(svalue), PSTR("{")); snprintf_P(svalue, sizeof(svalue), PSTR("{"));
jsonflg = 0; 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)); snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"PowerLow\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
jsonflg = 1; 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)); snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"PowerHigh\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
jsonflg = 1; jsonflg = 1;
} }
@ -373,7 +375,7 @@ void hlw_margin_chk()
} else { } else {
hlw_mplh_counter--; hlw_mplh_counter--;
if (!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); mqtt_publish_topic_P(1, PSTR("WARNING"), svalue);
hlw_mqttPresent(0); hlw_mqttPresent(0);
do_cmnd_power(1, 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_mplh_counter = 0;
hlw_mplr_counter = 0; hlw_mplr_counter = 0;
hlw_mplw_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; break;
} }
} }
char stemp0[10]; char sey[10];
char stemp1[10]; char sen[10];
char stemp2[10]; char set[10];
dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, stemp0); dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, sey);
dtostrf((float)rtcMem.hlw_kWhtoday / 100000000, 1, sysCfg.flag.energy_resolution, stemp1); 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, stemp2); 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}}"), stemp2, stemp0, stemp1); snprintf_P(svalue, ssvalue, PSTR("{\"EnergyReset\":{\"Total\":%s, \"Yesterday\":%s, \"Today\":%s}}"), set, sey, sen);
} }
else if (!strcmp_P(type,PSTR("HLWPCAL"))) { else if (!strcmp_P(type,PSTR("HLWPCAL"))) {
if ((payload > 0) && (payload < 32001)) { 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 0 = do not show period energy usage
* option 1 = 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 pet;
float ped; float ped;
float pe;
float pw;
float pu; float pu;
float pi; float pi;
float pc; float pc;
uint16_t pe; char spet[10];
uint16_t pw; 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); hlw_readEnergy(option, pet, ped, pe, pw, pu, pi, pc);
dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, stemp0); dtostrf(pet, 1, sysCfg.flag.energy_resolution, spet);
dtostrf(ped, 1, sysCfg.flag.energy_resolution, stemp1); dtostrf(ped, 1, sysCfg.flag.energy_resolution, sped);
dtostrf(pc, 1, 2, stemp2); dtostrf(pe, 1, sysCfg.flag.wattage_resolution, spe);
dtostrf(pi, 1, 3, stemp3); dtostrf(pw, 1, sysCfg.flag.wattage_resolution, spw);
dtostrf(pet, 1, sysCfg.flag.energy_resolution, stemp4); dtostrf(pu, 1, sysCfg.flag.voltage_resolution, spu);
dtostrf(pu, 1, sysCfg.flag.voltage_resolution, stemp5); dtostrf(pi, 1, 3, spi);
snprintf_P(speriod, sizeof(speriod), PSTR(", \"Period\":%d"), pe); dtostrf(pc, 1, 2, spc);
snprintf_P(svalue, ssvalue, PSTR("%s\"Total\":%s, \"Yesterday\":%s, \"Today\":%s%s, \"Power\":%d, \"Factor\":%s, \"Voltage\":%s, \"Current\":%s}"), dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, sey);
svalue, stemp4, stemp0, stemp1, (option) ? speriod : "", pw, stemp2, stemp5, stemp3); 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 #ifdef USE_DOMOTICZ
if (option) { // Only send if telemetry if (option) { // Only send if telemetry
dtostrf(pet * 1000, 1, 1, stemp1); dtostrf(pet * 1000, 1, 1, spet);
domoticz_sensor4(pw, stemp1); domoticz_sensor4((uint16_t)pw, spet);
} }
#endif // USE_DOMOTICZ #endif // USE_DOMOTICZ
} }
@ -670,7 +676,7 @@ void hlw_mqttStatus(char* svalue, uint16_t ssvalue)
const char HTTP_ENERGY_SNS[] PROGMEM = const char HTTP_ENERGY_SNS[] PROGMEM =
"<tr><th>Voltage</th><td>%s V</td></tr>" "<tr><th>Voltage</th><td>%s V</td></tr>"
"<tr><th>Current</th><td>%s A</td></tr>" "<tr><th>Current</th><td>%s A</td></tr>"
"<tr><th>Power</th><td>%d W</td></tr>" "<tr><th>Power</th><td>%s W</td></tr>"
"<tr><th>Power Factor</th><td>%s</td></tr>" "<tr><th>Power Factor</th><td>%s</td></tr>"
"<tr><th>Energy Today</th><td>%s kWh</td></tr>" "<tr><th>Energy Today</th><td>%s kWh</td></tr>"
"<tr><th>Energy Yesterday</th><td>%s kWh</td></tr>" "<tr><th>Energy Yesterday</th><td>%s kWh</td></tr>"
@ -678,32 +684,32 @@ const char HTTP_ENERGY_SNS[] PROGMEM =
String hlw_webPresent() 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 pet;
float ped; float ped;
float pe;
float pw;
float pu; float pu;
float pi; float pi;
float pc; float pc;
uint16_t pe; char spet[10];
uint16_t pw; 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); hlw_readEnergy(0, pet, ped, pe, pw, pu, pi, pc);
dtostrf(pu, 1, sysCfg.flag.voltage_resolution, stemp6); dtostrf(pet, 1, sysCfg.flag.energy_resolution, spet);
dtostrf(pi, 1, 3, stemp); dtostrf(ped, 1, sysCfg.flag.energy_resolution, sped);
dtostrf(pc, 1, 2, stemp2); dtostrf(pw, 1, sysCfg.flag.wattage_resolution, spw);
dtostrf(ped, 1, sysCfg.flag.energy_resolution, stemp3); dtostrf(pu, 1, sysCfg.flag.voltage_resolution, spu);
dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, stemp4); dtostrf(pi, 1, 3, spi);
dtostrf(pet, 1, sysCfg.flag.energy_resolution, stemp5); dtostrf(pc, 1, 2, spc);
snprintf_P(sensor, sizeof(sensor), HTTP_ENERGY_SNS, stemp6, stemp, pw, stemp2, stemp3, stemp4, stemp5); dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, sey);
page += sensor; snprintf_P(sensor, sizeof(sensor), HTTP_ENERGY_SNS, spu, spi, spw, spc, sped, sey, spet);
return page; return String(sensor);
} }
#endif // USE_WEBSERVER #endif // USE_WEBSERVER