diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 7327cb8b6..444375040 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,6 +1,7 @@ /* 6.5.0.13 20190527 * Add command SetOption38 6..255 to set IRReceive protocol detection sensitivity mimizing UNKNOWN protocols (#5853) * Fix missing white channel for WS2812 (#5869) + * Add reset of Energy values when connection to sensor is lost for over 4 seconds (#5874, #5881) * * 6.5.0.12 20190521 * Add AriLux RF control GPIO option "ALux IrSel" (159) replacing "Led4i" (59) for full LED control (#5709) diff --git a/sonoff/xdrv_03_energy.ino b/sonoff/xdrv_03_energy.ino index 1d47bc034..52585a632 100644 --- a/sonoff/xdrv_03_energy.ino +++ b/sonoff/xdrv_03_energy.ino @@ -28,6 +28,7 @@ #define ENERGY_NONE 0 #define ENERGY_OVERTEMP 73.0 // Industry standard lowest overtemp in Celsius +#define ENERGY_WATCHDOG 4 // Allow up to 4 seconds before deciding no valid data present #define FEATURE_POWER_LIMIT true @@ -71,6 +72,7 @@ unsigned long energy_period = 0; // 12312312 Wh * 10^-2 (deca milli Watt hour float energy_power_last[3] = { 0 }; uint8_t energy_power_delta = 0; +uint8_t energy_data_valid = 0; bool energy_voltage_available = true; // Enable if voltage is measured bool energy_current_available = true; // Enable if current is measured @@ -327,6 +329,18 @@ void EnergyOverTempCheck() SetAllPower(POWER_ALL_OFF, SRC_OVERTEMP); } } + if (energy_data_valid <= ENERGY_WATCHDOG) { + energy_data_valid++; + if (energy_data_valid > ENERGY_WATCHDOG) { + // Reset energy registers + energy_voltage = 0; + energy_current = 0; + energy_active_power = 0; + if (!isnan(energy_frequency)) { energy_frequency = 0; } + if (!isnan(energy_power_factor)) { energy_power_factor = 0; } + energy_start = 0; + } + } } /*********************************************************************************************\ diff --git a/sonoff/xnrg_01_hlw8012.ino b/sonoff/xnrg_01_hlw8012.ino index c098870e4..e26f195fb 100644 --- a/sonoff/xnrg_01_hlw8012.ino +++ b/sonoff/xnrg_01_hlw8012.ino @@ -86,6 +86,7 @@ void HlwCfInterrupt(void) // Service Power hlw_cf_pulse_last_time = us; hlw_energy_period_counter++; } + energy_data_valid = 0; } void HlwCf1Interrupt(void) // Service Voltage and Current @@ -104,6 +105,7 @@ void HlwCf1Interrupt(void) // Service Voltage and Current hlw_cf1_timer = 8; // We need up to HLW_SAMPLE_COUNT samples within 1 second (low current could take up to 0.3 second) } } + energy_data_valid = 0; } /********************************************************************************************/ @@ -189,14 +191,20 @@ void HlwEvery200ms(void) void HlwEverySecond(void) { - unsigned long hlw_len; + if (energy_data_valid > ENERGY_WATCHDOG) { + hlw_cf1_voltage_pulse_length = 0; + hlw_cf1_current_pulse_length = 0; + hlw_cf_power_pulse_length = 0; + } else { + unsigned long hlw_len; - if (hlw_energy_period_counter) { - hlw_len = 10000 / hlw_energy_period_counter; - hlw_energy_period_counter = 0; - if (hlw_len) { - energy_kWhtoday_delta += ((hlw_power_ratio * Settings.energy_power_calibration) / hlw_len) / 36; - EnergyUpdateToday(); + if (hlw_energy_period_counter) { + hlw_len = 10000 / hlw_energy_period_counter; + hlw_energy_period_counter = 0; + if (hlw_len) { + energy_kWhtoday_delta += ((hlw_power_ratio * Settings.energy_power_calibration) / hlw_len) / 36; + EnergyUpdateToday(); + } } } } diff --git a/sonoff/xnrg_02_cse7766.ino b/sonoff/xnrg_02_cse7766.ino index 55d87a163..b2b2cecca 100644 --- a/sonoff/xnrg_02_cse7766.ino +++ b/sonoff/xnrg_02_cse7766.ino @@ -139,6 +139,7 @@ bool CseSerialInput(void) uint8_t checksum = 0; for (uint8_t i = 2; i < 23; i++) { checksum += serial_in_buffer[i]; } if (checksum == serial_in_buffer[23]) { + energy_data_valid = 0; CseReceived(); cse_receive_flag = 0; return 1; @@ -170,28 +171,34 @@ bool CseSerialInput(void) void CseEverySecond(void) { - long cf_frequency = 0; - - if (CSE_PULSES_NOT_INITIALIZED == cf_pulses_last_time) { - cf_pulses_last_time = cf_pulses; // Init after restart + if (energy_data_valid > ENERGY_WATCHDOG) { + voltage_cycle = 0; + current_cycle = 0; + power_cycle = 0; } else { - if (cf_pulses < cf_pulses_last_time) { // Rolled over after 65535 pulses - cf_frequency = (65536 - cf_pulses_last_time) + cf_pulses; + long cf_frequency = 0; + + if (CSE_PULSES_NOT_INITIALIZED == cf_pulses_last_time) { + cf_pulses_last_time = cf_pulses; // Init after restart } else { - cf_frequency = cf_pulses - cf_pulses_last_time; - } - if (cf_frequency && energy_active_power) { - unsigned long delta = (cf_frequency * Settings.energy_power_calibration) / 36; - // prevent invalid load delta steps even checksum is valid (issue #5789): - if (delta <= (3680*100/36) * 10 ) { // max load for S31/Pow R2: 3.68kW - cf_pulses_last_time = cf_pulses; - energy_kWhtoday_delta += delta; + if (cf_pulses < cf_pulses_last_time) { // Rolled over after 65535 pulses + cf_frequency = (65536 - cf_pulses_last_time) + cf_pulses; + } else { + cf_frequency = cf_pulses - cf_pulses_last_time; } - else { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("CSE: Load overflow")); - cf_pulses_last_time = CSE_PULSES_NOT_INITIALIZED; + if (cf_frequency && energy_active_power) { + unsigned long delta = (cf_frequency * Settings.energy_power_calibration) / 36; + // prevent invalid load delta steps even checksum is valid (issue #5789): + if (delta <= (3680*100/36) * 10 ) { // max load for S31/Pow R2: 3.68kW + cf_pulses_last_time = cf_pulses; + energy_kWhtoday_delta += delta; + } + else { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("CSE: Load overflow")); + cf_pulses_last_time = CSE_PULSES_NOT_INITIALIZED; + } + EnergyUpdateToday(); } - EnergyUpdateToday(); } } } diff --git a/sonoff/xnrg_03_pzem004t.ino b/sonoff/xnrg_03_pzem004t.ino index b2c72bfa8..8340b09dc 100644 --- a/sonoff/xnrg_03_pzem004t.ino +++ b/sonoff/xnrg_03_pzem004t.ino @@ -169,6 +169,7 @@ void PzemEvery200ms(void) if (data_ready) { float value = 0; if (PzemRecieve(pzem_responses[pzem_read_state], &value)) { + energy_data_valid = 0; switch (pzem_read_state) { case 1: // Voltage as 230.2V energy_voltage = value; diff --git a/sonoff/xnrg_04_mcp39f501.ino b/sonoff/xnrg_04_mcp39f501.ino index af6e8657c..cbffbf10b 100644 --- a/sonoff/xnrg_04_mcp39f501.ino +++ b/sonoff/xnrg_04_mcp39f501.ino @@ -469,6 +469,7 @@ void McpParseData(void) energy_active_power = 0; energy_current = 0; } + energy_data_valid = 0; } /********************************************************************************************/ @@ -526,6 +527,13 @@ void McpSerialInput(void) void McpEverySecond(void) { + if (energy_data_valid > ENERGY_WATCHDOG) { + mcp_voltage_rms = 0; + mcp_current_rms = 0; + mcp_active_power = 0; + mcp_line_frequency = 0; + } + if (mcp_active_power) { energy_kWhtoday_delta += ((mcp_active_power * 10) / 36); EnergyUpdateToday(); diff --git a/sonoff/xnrg_05_pzem_ac.ino b/sonoff/xnrg_05_pzem_ac.ino index bb8c129d5..653b4ef63 100644 --- a/sonoff/xnrg_05_pzem_ac.ino +++ b/sonoff/xnrg_05_pzem_ac.ino @@ -51,6 +51,8 @@ void PzemAcEverySecond(void) if (error) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "PzemAc response error %d"), error); } else { + energy_data_valid = 0; + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 // 01 04 14 08 D1 00 6C 00 00 00 F4 00 00 00 26 00 00 01 F4 00 64 00 00 51 34 // Id Cc Sz Volt- Current---- Power------ Energy----- Frequ PFact Alarm Crc-- diff --git a/sonoff/xnrg_06_pzem_dc.ino b/sonoff/xnrg_06_pzem_dc.ino index 00e75a5ca..f9817577a 100644 --- a/sonoff/xnrg_06_pzem_dc.ino +++ b/sonoff/xnrg_06_pzem_dc.ino @@ -51,6 +51,8 @@ void PzemDcEverySecond(void) if (error) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "PzemDc response error %d"), error); } else { + energy_data_valid = 0; + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // 01 04 10 05 40 00 0A 00 0D 00 00 00 02 00 00 00 00 00 00 D6 29 // Id Cc Sz Volt- Curre Power------ Energy----- HiAlm LoAlm Crc--