diff --git a/sonoff/xnrg_03_pzem004t.ino b/sonoff/xnrg_03_pzem004t.ino index d41910f9310b..39b690bceff9 100644 --- a/sonoff/xnrg_03_pzem004t.ino +++ b/sonoff/xnrg_03_pzem004t.ino @@ -58,6 +58,7 @@ TasmotaSerial *PzemSerial = nullptr; struct PZEM { float energy = 0; + float last_energy = 0; uint8_t send_retry = 0; uint8_t read_state = 0; // Set address uint8_t phase = 0; @@ -190,7 +191,10 @@ void PzemEvery250ms(void) case 4: // Total energy as 99999Wh Pzem.energy += value; if (Pzem.phase == Energy.phase_count -1) { - EnergyUpdateTotal(Pzem.energy, false); + if (Pzem.energy > Pzem.last_energy) { // Handle missed phase + EnergyUpdateTotal(Pzem.energy, false); + Pzem.last_energy = Pzem.energy; + } Pzem.energy = 0; } break; diff --git a/sonoff/xnrg_05_pzem_ac.ino b/sonoff/xnrg_05_pzem_ac.ino index 4209b32af6da..af36d7466755 100644 --- a/sonoff/xnrg_05_pzem_ac.ino +++ b/sonoff/xnrg_05_pzem_ac.ino @@ -38,6 +38,7 @@ TasmotaModbus *PzemAcModbus; struct PZEMAC { float energy = 0; + float last_energy = 0; uint8_t send_retry = 0; uint8_t phase = 0; uint8_t address = 0; @@ -65,7 +66,8 @@ void PzemAcEverySecond(void) Energy.data_valid[PzemAc.phase] = 0; if (10 == registers) { - // 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 + // 0 1 2 3 4 5 6 7 8 9 = ModBus register + // 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 = Buffer index // 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-- Energy.voltage[PzemAc.phase] = (float)((buffer[3] << 8) + buffer[4]) / 10.0; // 6553.0 V @@ -76,9 +78,13 @@ void PzemAcEverySecond(void) PzemAc.energy += (float)((buffer[15] << 24) + (buffer[16] << 16) + (buffer[13] << 8) + buffer[14]); // 4294967295 Wh if (PzemAc.phase == Energy.phase_count -1) { - EnergyUpdateTotal(PzemAc.energy, false); + if (PzemAc.energy > PzemAc.last_energy) { // Handle missed phase + EnergyUpdateTotal(PzemAc.energy, false); + PzemAc.last_energy = PzemAc.energy; + } PzemAc.energy = 0; } + } } } diff --git a/sonoff/xnrg_06_pzem_dc.ino b/sonoff/xnrg_06_pzem_dc.ino index d7d4f2818d4f..5aaf3f29e776 100644 --- a/sonoff/xnrg_06_pzem_dc.ino +++ b/sonoff/xnrg_06_pzem_dc.ino @@ -38,6 +38,7 @@ TasmotaModbus *PzemDcModbus; struct PZEMDC { float energy = 0; + float last_energy = 0; uint8_t send_retry = 0; uint8_t channel = 0; uint8_t address = 0; @@ -65,7 +66,8 @@ void PzemDcEverySecond(void) Energy.data_valid[PzemDc.channel] = 0; if (8 == registers) { - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + // 0 1 2 3 4 5 6 7 = ModBus register + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 = Buffer index // 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-- Energy.voltage[PzemDc.channel] = (float)((buffer[3] << 8) + buffer[4]) / 100.0; // 655.00 V @@ -74,7 +76,10 @@ void PzemDcEverySecond(void) PzemDc.energy += (float)((buffer[13] << 24) + (buffer[14] << 16) + (buffer[11] << 8) + buffer[12]); // 4294967295 Wh if (PzemDc.channel == Energy.phase_count -1) { - EnergyUpdateTotal(PzemDc.energy, false); + if (PzemDc.energy > PzemDc.last_energy) { // Handle missed channel + EnergyUpdateTotal(PzemDc.energy, false); + PzemDc.last_energy = PzemDc.energy; + } PzemDc.energy = 0; } }