diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 43b0a4bfa..ce32138d4 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -10,6 +10,7 @@ * Add support for Shelly 2.5 dual energy (#6160) * Add initial support for up to three PZEM-014/-016 on serial modbus connection with addresses 1 (default), 2 and 3 (#2315) * Add initial support for up to three PZEM-004T on serial connection with addresses x.x.x.1 (default), 2 and 3 (#2315) + * Add initial support for up to three PZEM-003/-017 on serial modbus connection with addresses 1 (default), 2 and 3 (#2315) * * 6.6.0.11 20190907 * Change Settings crc calculation allowing short term backward compatibility diff --git a/sonoff/xnrg_03_pzem004t.ino b/sonoff/xnrg_03_pzem004t.ino index 31d34ffb4..5e1d3ceb6 100644 --- a/sonoff/xnrg_03_pzem004t.ino +++ b/sonoff/xnrg_03_pzem004t.ino @@ -214,8 +214,8 @@ void PzemEvery200ms(void) } else { Pzem.send_retry--; - if ((Energy.phase_count > 1) && (0 == Pzem.send_retry)) { - Energy.phase_count--; // Decrement phases if no response after retry + if ((Energy.phase_count > 1) && (0 == Pzem.send_retry) && (uptime < 30)) { + Energy.phase_count--; // Decrement phases if no response after retry within 30 seconds after restart } } } diff --git a/sonoff/xnrg_05_pzem_ac.ino b/sonoff/xnrg_05_pzem_ac.ino index 897ef7e36..54fe8a079 100644 --- a/sonoff/xnrg_05_pzem_ac.ino +++ b/sonoff/xnrg_05_pzem_ac.ino @@ -53,7 +53,7 @@ void PzemAcEverySecond(void) AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, (buffer[2]) ? buffer[2] +5 : sizeof(buffer)); if (error) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PAC: PzemAc %d response error %d"), PZEM_AC_DEVICE_ADDRESS + PzemAc.phase, error); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PAC: PzemAc %d error %d"), PZEM_AC_DEVICE_ADDRESS + PzemAc.phase, error); } else { Energy.data_valid = 0; @@ -84,8 +84,8 @@ void PzemAcEverySecond(void) } else { PzemAc.send_retry--; - if ((Energy.phase_count > 1) && (0 == PzemAc.send_retry)) { - Energy.phase_count--; // Decrement phases if no response after retry + if ((Energy.phase_count > 1) && (0 == PzemAc.send_retry) && (uptime < 30)) { + Energy.phase_count--; // Decrement phases if no response after retry within 30 seconds after restart } } } @@ -96,10 +96,8 @@ void PzemAcSnsInit(void) uint8_t result = PzemAcModbus->Begin(9600); if (result) { if (2 == result) { ClaimSerial(); } - Energy.phase_count = 3; // Start off with three phases PzemAc.phase = 2; - } else { energy_flg = ENERGY_NONE; } diff --git a/sonoff/xnrg_06_pzem_dc.ino b/sonoff/xnrg_06_pzem_dc.ino index 9b9dd06a1..5188c051e 100644 --- a/sonoff/xnrg_06_pzem_dc.ino +++ b/sonoff/xnrg_06_pzem_dc.ino @@ -36,10 +36,14 @@ #include TasmotaModbus *PzemDcModbus; +struct PZEMDC { + float energy = 0; + uint8_t send_retry = 0; + uint8_t channel = 0; +} PzemDc; + void PzemDcEverySecond(void) { - static uint8_t send_retry = 0; - bool data_ready = PzemDcModbus->ReceiveReady(); if (data_ready) { @@ -49,28 +53,38 @@ void PzemDcEverySecond(void) AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, sizeof(buffer)); if (error) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "PzemDc response error %d"), error); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PDC: PzemDc %d error %d"), PZEM_DC_DEVICE_ADDRESS + PzemDc.channel, 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-- - Energy.voltage[0] = (float)((buffer[3] << 8) + buffer[4]) / 100.0; // 655.00 V - Energy.current[0] = (float)((buffer[5] << 8) + buffer[6]) / 100.0; // 655.00 A - Energy.active_power[0] = (float)((buffer[9] << 24) + (buffer[10] << 16) + (buffer[7] << 8) + buffer[8]) / 10.0; // 429496729.0 W - float energy = (float)((buffer[13] << 24) + (buffer[14] << 16) + (buffer[11] << 8) + buffer[12]); // 4294967295 Wh + Energy.voltage[PzemDc.channel] = (float)((buffer[3] << 8) + buffer[4]) / 100.0; // 655.00 V + Energy.current[PzemDc.channel] = (float)((buffer[5] << 8) + buffer[6]) / 100.0; // 655.00 A + Energy.active_power[PzemDc.channel] = (float)((buffer[9] << 24) + (buffer[10] << 16) + (buffer[7] << 8) + buffer[8]) / 10.0; // 429496729.0 W - EnergyUpdateTotal(energy, false); + 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); + PzemDc.energy = 0; + } } } - if (0 == send_retry || data_ready) { - send_retry = 5; - PzemDcModbus->Send(PZEM_DC_DEVICE_ADDRESS, 0x04, 0, 8); + if (0 == PzemDc.send_retry || data_ready) { + PzemDc.channel++; + if (PzemDc.channel >= Energy.phase_count) { + PzemDc.channel = 0; + } + PzemDc.send_retry = ENERGY_WATCHDOG; + PzemDcModbus->Send(PZEM_DC_DEVICE_ADDRESS + PzemDc.channel, 0x04, 0, 8); } else { - send_retry--; + PzemDc.send_retry--; + if ((Energy.phase_count > 1) && (0 == PzemDc.send_retry) && (uptime < 30)) { + Energy.phase_count--; // Decrement channels if no response after retry within 30 seconds after restart + } } } @@ -81,6 +95,8 @@ void PzemDcSnsInit(void) if (result) { if (2 == result) { ClaimSerial(); } Energy.type_dc = true; + Energy.phase_count = 3; // Start off with three channels + PzemDc.channel = 2; } else { energy_flg = ENERGY_NONE; }