mirror of https://github.com/arendst/Tasmota.git
Add command ModuleAddress 1/2/3
Add command ModuleAddress 1/2/3 to set Pzem module address when a single module is connected (#2315)
This commit is contained in:
parent
d193b8cb1a
commit
7b70c042bd
|
@ -12,6 +12,7 @@
|
||||||
* 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-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)
|
* Add initial support for up to three PZEM-003/-017 on serial modbus connection with addresses 1 (default), 2 and 3 (#2315)
|
||||||
* Add driver USE_SDM630_2 as future replacement for USE_SDM630 - Pls test and report
|
* Add driver USE_SDM630_2 as future replacement for USE_SDM630 - Pls test and report
|
||||||
|
* Add command ModuleAddress 1/2/3 to set Pzem module address when a single module is connected (#2315)
|
||||||
*
|
*
|
||||||
* 6.6.0.11 20190907
|
* 6.6.0.11 20190907
|
||||||
* Change Settings crc calculation allowing short term backward compatibility
|
* Change Settings crc calculation allowing short term backward compatibility
|
||||||
|
|
|
@ -279,6 +279,8 @@ enum XsnsFunctions {FUNC_SETTINGS_OVERRIDE, FUNC_PIN_STATE, FUNC_MODULE_INIT, FU
|
||||||
FUNC_RULES_PROCESS, FUNC_SERIAL, FUNC_FREE_MEM, FUNC_BUTTON_PRESSED,
|
FUNC_RULES_PROCESS, FUNC_SERIAL, FUNC_FREE_MEM, FUNC_BUTTON_PRESSED,
|
||||||
FUNC_WEB_ADD_BUTTON, FUNC_WEB_ADD_MAIN_BUTTON, FUNC_WEB_ADD_HANDLER, FUNC_SET_CHANNELS};
|
FUNC_WEB_ADD_BUTTON, FUNC_WEB_ADD_MAIN_BUTTON, FUNC_WEB_ADD_HANDLER, FUNC_SET_CHANNELS};
|
||||||
|
|
||||||
|
enum AddressConfigSteps { ADDR_IDLE, ADDR_RECEIVE, ADDR_SEND };
|
||||||
|
|
||||||
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
|
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
|
||||||
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_MAX };
|
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_MAX };
|
||||||
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote";
|
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote";
|
||||||
|
|
|
@ -37,14 +37,15 @@
|
||||||
#define D_CMND_VOLTAGECAL "VoltageCal"
|
#define D_CMND_VOLTAGECAL "VoltageCal"
|
||||||
#define D_CMND_CURRENTCAL "CurrentCal"
|
#define D_CMND_CURRENTCAL "CurrentCal"
|
||||||
#define D_CMND_TARIFF "Tariff"
|
#define D_CMND_TARIFF "Tariff"
|
||||||
|
#define D_CMND_MODULEADDRESS "ModuleAddress"
|
||||||
|
|
||||||
enum EnergyCommands {
|
enum EnergyCommands {
|
||||||
CMND_POWERCAL, CMND_VOLTAGECAL, CMND_CURRENTCAL,
|
CMND_POWERCAL, CMND_VOLTAGECAL, CMND_CURRENTCAL,
|
||||||
CMND_POWERSET, CMND_VOLTAGESET, CMND_CURRENTSET, CMND_FREQUENCYSET };
|
CMND_POWERSET, CMND_VOLTAGESET, CMND_CURRENTSET, CMND_FREQUENCYSET, CMND_MODULEADDRESS };
|
||||||
|
|
||||||
const char kEnergyCommands[] PROGMEM = "|" // No prefix
|
const char kEnergyCommands[] PROGMEM = "|" // No prefix
|
||||||
D_CMND_POWERCAL "|" D_CMND_VOLTAGECAL "|" D_CMND_CURRENTCAL "|"
|
D_CMND_POWERCAL "|" D_CMND_VOLTAGECAL "|" D_CMND_CURRENTCAL "|"
|
||||||
D_CMND_POWERSET "|" D_CMND_VOLTAGESET "|" D_CMND_CURRENTSET "|" D_CMND_FREQUENCYSET "|"
|
D_CMND_POWERSET "|" D_CMND_VOLTAGESET "|" D_CMND_CURRENTSET "|" D_CMND_FREQUENCYSET "|" D_CMND_MODULEADDRESS "|"
|
||||||
#ifdef USE_ENERGY_MARGIN_DETECTION
|
#ifdef USE_ENERGY_MARGIN_DETECTION
|
||||||
D_CMND_POWERDELTA "|" D_CMND_POWERLOW "|" D_CMND_POWERHIGH "|" D_CMND_VOLTAGELOW "|" D_CMND_VOLTAGEHIGH "|" D_CMND_CURRENTLOW "|" D_CMND_CURRENTHIGH "|"
|
D_CMND_POWERDELTA "|" D_CMND_POWERLOW "|" D_CMND_POWERHIGH "|" D_CMND_VOLTAGELOW "|" D_CMND_VOLTAGEHIGH "|" D_CMND_CURRENTLOW "|" D_CMND_CURRENTHIGH "|"
|
||||||
#ifdef USE_ENERGY_POWER_LIMIT
|
#ifdef USE_ENERGY_POWER_LIMIT
|
||||||
|
@ -57,7 +58,7 @@ const char kEnergyCommands[] PROGMEM = "|" // No prefix
|
||||||
|
|
||||||
void (* const EnergyCommand[])(void) PROGMEM = {
|
void (* const EnergyCommand[])(void) PROGMEM = {
|
||||||
&CmndPowerCal, &CmndVoltageCal, &CmndCurrentCal,
|
&CmndPowerCal, &CmndVoltageCal, &CmndCurrentCal,
|
||||||
&CmndPowerSet, &CmndVoltageSet, &CmndCurrentSet, &CmndFrequencySet,
|
&CmndPowerSet, &CmndVoltageSet, &CmndCurrentSet, &CmndFrequencySet, &CmndModuleAddress,
|
||||||
#ifdef USE_ENERGY_MARGIN_DETECTION
|
#ifdef USE_ENERGY_MARGIN_DETECTION
|
||||||
&CmndPowerDelta, &CmndPowerLow, &CmndPowerHigh, &CmndVoltageLow, &CmndVoltageHigh, &CmndCurrentLow, &CmndCurrentHigh,
|
&CmndPowerDelta, &CmndPowerLow, &CmndPowerHigh, &CmndVoltageLow, &CmndVoltageHigh, &CmndCurrentLow, &CmndCurrentHigh,
|
||||||
#ifdef USE_ENERGY_POWER_LIMIT
|
#ifdef USE_ENERGY_POWER_LIMIT
|
||||||
|
@ -614,6 +615,16 @@ void CmndFrequencySet(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CmndModuleAddress(void)
|
||||||
|
{
|
||||||
|
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 4) && (1 == Energy.phase_count)) {
|
||||||
|
Energy.command_code = CMND_MODULEADDRESS;
|
||||||
|
if (XnrgCall(FUNC_COMMAND)) { // Module address
|
||||||
|
ResponseCmndDone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_ENERGY_MARGIN_DETECTION
|
#ifdef USE_ENERGY_MARGIN_DETECTION
|
||||||
void CmndPowerDelta(void)
|
void CmndPowerDelta(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,8 +59,9 @@ TasmotaSerial *PzemSerial = nullptr;
|
||||||
struct PZEM {
|
struct PZEM {
|
||||||
float energy = 0;
|
float energy = 0;
|
||||||
uint8_t send_retry = 0;
|
uint8_t send_retry = 0;
|
||||||
uint8_t read_state = 0;
|
uint8_t read_state = 0; // Set address
|
||||||
uint8_t phase = 0;
|
uint8_t phase = 0;
|
||||||
|
uint8_t address = 0;
|
||||||
} Pzem;
|
} Pzem;
|
||||||
|
|
||||||
struct PZEMCommand {
|
struct PZEMCommand {
|
||||||
|
@ -70,8 +71,6 @@ struct PZEMCommand {
|
||||||
uint8_t crc;
|
uint8_t crc;
|
||||||
};
|
};
|
||||||
|
|
||||||
IPAddress pzem_ip(192, 168, 1, 1);
|
|
||||||
|
|
||||||
uint8_t PzemCrc(uint8_t *data)
|
uint8_t PzemCrc(uint8_t *data)
|
||||||
{
|
{
|
||||||
uint16_t crc = 0;
|
uint16_t crc = 0;
|
||||||
|
@ -86,10 +85,10 @@ void PzemSend(uint8_t cmd)
|
||||||
PZEMCommand pzem;
|
PZEMCommand pzem;
|
||||||
|
|
||||||
pzem.command = cmd;
|
pzem.command = cmd;
|
||||||
for (uint32_t i = 0; i < sizeof(pzem.addr) -1; i++) {
|
pzem.addr[0] = 0; // Address 0.0.0.1
|
||||||
pzem.addr[i] = pzem_ip[i];
|
pzem.addr[1] = 0;
|
||||||
}
|
pzem.addr[2] = 0;
|
||||||
pzem.addr[3] = pzem_ip[3] + Pzem.phase;
|
pzem.addr[3] = ((PZEM_SET_ADDRESS == cmd) && Pzem.address) ? Pzem.address : 1 + Pzem.phase;
|
||||||
pzem.data = 0;
|
pzem.data = 0;
|
||||||
|
|
||||||
uint8_t *bytes = (uint8_t*)&pzem;
|
uint8_t *bytes = (uint8_t*)&pzem;
|
||||||
|
@ -97,6 +96,8 @@ void PzemSend(uint8_t cmd)
|
||||||
|
|
||||||
PzemSerial->flush();
|
PzemSerial->flush();
|
||||||
PzemSerial->write(bytes, sizeof(pzem));
|
PzemSerial->write(bytes, sizeof(pzem));
|
||||||
|
|
||||||
|
Pzem.address = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PzemReceiveReady(void)
|
bool PzemReceiveReady(void)
|
||||||
|
@ -209,6 +210,9 @@ void PzemEvery200ms(void)
|
||||||
if (Pzem.phase >= Energy.phase_count) {
|
if (Pzem.phase >= Energy.phase_count) {
|
||||||
Pzem.phase = 0;
|
Pzem.phase = 0;
|
||||||
}
|
}
|
||||||
|
if (Pzem.address) {
|
||||||
|
Pzem.read_state = 0; // Set address
|
||||||
|
}
|
||||||
Pzem.send_retry = 5;
|
Pzem.send_retry = 5;
|
||||||
PzemSend(pzem_commands[Pzem.read_state]);
|
PzemSend(pzem_commands[Pzem.read_state]);
|
||||||
}
|
}
|
||||||
|
@ -230,6 +234,7 @@ void PzemSnsInit(void)
|
||||||
}
|
}
|
||||||
Energy.phase_count = 3; // Start off with three phases
|
Energy.phase_count = 3; // Start off with three phases
|
||||||
Pzem.phase = 2;
|
Pzem.phase = 2;
|
||||||
|
Pzem.read_state = 1;
|
||||||
} else {
|
} else {
|
||||||
energy_flg = ENERGY_NONE;
|
energy_flg = ENERGY_NONE;
|
||||||
}
|
}
|
||||||
|
@ -242,6 +247,18 @@ void PzemDrvInit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PzemCommand(void)
|
||||||
|
{
|
||||||
|
bool serviced = true;
|
||||||
|
|
||||||
|
if (CMND_MODULEADDRESS == Energy.command_code) {
|
||||||
|
Pzem.address = XdrvMailbox.payload; // Valid addresses are 1, 2 and 3
|
||||||
|
}
|
||||||
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
|
return serviced;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Interface
|
* Interface
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -254,6 +271,9 @@ bool Xnrg03(uint8_t function)
|
||||||
case FUNC_EVERY_200_MSECOND:
|
case FUNC_EVERY_200_MSECOND:
|
||||||
if (PzemSerial) { PzemEvery200ms(); }
|
if (PzemSerial) { PzemEvery200ms(); }
|
||||||
break;
|
break;
|
||||||
|
case FUNC_COMMAND:
|
||||||
|
result = PzemCommand();
|
||||||
|
break;
|
||||||
case FUNC_INIT:
|
case FUNC_INIT:
|
||||||
PzemSnsInit();
|
PzemSnsInit();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -40,6 +40,8 @@ struct PZEMAC {
|
||||||
float energy = 0;
|
float energy = 0;
|
||||||
uint8_t send_retry = 0;
|
uint8_t send_retry = 0;
|
||||||
uint8_t phase = 0;
|
uint8_t phase = 0;
|
||||||
|
uint8_t address = 0;
|
||||||
|
uint8_t address_step = ADDR_IDLE;
|
||||||
} PzemAc;
|
} PzemAc;
|
||||||
|
|
||||||
void PzemAcEverySecond(void)
|
void PzemAcEverySecond(void)
|
||||||
|
@ -49,27 +51,34 @@ void PzemAcEverySecond(void)
|
||||||
if (data_ready) {
|
if (data_ready) {
|
||||||
uint8_t buffer[30]; // At least 5 + (2 * 10) = 25
|
uint8_t buffer[30]; // At least 5 + (2 * 10) = 25
|
||||||
|
|
||||||
uint8_t error = PzemAcModbus->ReceiveBuffer(buffer, 10);
|
uint8_t registers = 10;
|
||||||
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, (buffer[2]) ? buffer[2] +5 : sizeof(buffer));
|
if (ADDR_RECEIVE == PzemAc.address_step) {
|
||||||
|
registers = 2; // Need 1 byte extra as response is F8 06 00 02 00 01 FD A3
|
||||||
|
PzemAc.address_step--;
|
||||||
|
}
|
||||||
|
uint8_t error = PzemAcModbus->ReceiveBuffer(buffer, registers);
|
||||||
|
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, PzemAcModbus->ReceiveCount());
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PAC: PzemAc %d 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 {
|
} else {
|
||||||
Energy.data_valid = 0;
|
Energy.data_valid = 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 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
|
// 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--
|
// 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
|
Energy.voltage[PzemAc.phase] = (float)((buffer[3] << 8) + buffer[4]) / 10.0; // 6553.0 V
|
||||||
Energy.current[PzemAc.phase] = (float)((buffer[7] << 24) + (buffer[8] << 16) + (buffer[5] << 8) + buffer[6]) / 1000.0; // 4294967.000 A
|
Energy.current[PzemAc.phase] = (float)((buffer[7] << 24) + (buffer[8] << 16) + (buffer[5] << 8) + buffer[6]) / 1000.0; // 4294967.000 A
|
||||||
Energy.active_power[PzemAc.phase] = (float)((buffer[11] << 24) + (buffer[12] << 16) + (buffer[9] << 8) + buffer[10]) / 10.0; // 429496729.0 W
|
Energy.active_power[PzemAc.phase] = (float)((buffer[11] << 24) + (buffer[12] << 16) + (buffer[9] << 8) + buffer[10]) / 10.0; // 429496729.0 W
|
||||||
Energy.frequency[PzemAc.phase] = (float)((buffer[17] << 8) + buffer[18]) / 10.0; // 50.0 Hz
|
Energy.frequency[PzemAc.phase] = (float)((buffer[17] << 8) + buffer[18]) / 10.0; // 50.0 Hz
|
||||||
Energy.power_factor[PzemAc.phase] = (float)((buffer[19] << 8) + buffer[20]) / 100.0; // 1.00
|
Energy.power_factor[PzemAc.phase] = (float)((buffer[19] << 8) + buffer[20]) / 100.0; // 1.00
|
||||||
|
|
||||||
PzemAc.energy += (float)((buffer[15] << 24) + (buffer[16] << 16) + (buffer[13] << 8) + buffer[14]); // 4294967295 Wh
|
PzemAc.energy += (float)((buffer[15] << 24) + (buffer[16] << 16) + (buffer[13] << 8) + buffer[14]); // 4294967295 Wh
|
||||||
if (PzemAc.phase == Energy.phase_count -1) {
|
if (PzemAc.phase == Energy.phase_count -1) {
|
||||||
EnergyUpdateTotal(PzemAc.energy, false);
|
EnergyUpdateTotal(PzemAc.energy, false);
|
||||||
PzemAc.energy = 0;
|
PzemAc.energy = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +89,12 @@ void PzemAcEverySecond(void)
|
||||||
PzemAc.phase = 0;
|
PzemAc.phase = 0;
|
||||||
}
|
}
|
||||||
PzemAc.send_retry = ENERGY_WATCHDOG;
|
PzemAc.send_retry = ENERGY_WATCHDOG;
|
||||||
PzemAcModbus->Send(PZEM_AC_DEVICE_ADDRESS + PzemAc.phase, 0x04, 0, 10);
|
if (ADDR_SEND == PzemAc.address_step) {
|
||||||
|
PzemAcModbus->Send(0xF8, 0x06, 0x0002, (uint16_t)PzemAc.address);
|
||||||
|
PzemAc.address_step--;
|
||||||
|
} else {
|
||||||
|
PzemAcModbus->Send(PZEM_AC_DEVICE_ADDRESS + PzemAc.phase, 0x04, 0, 10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PzemAc.send_retry--;
|
PzemAc.send_retry--;
|
||||||
|
@ -110,6 +124,19 @@ void PzemAcDrvInit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PzemAcCommand(void)
|
||||||
|
{
|
||||||
|
bool serviced = true;
|
||||||
|
|
||||||
|
if (CMND_MODULEADDRESS == Energy.command_code) {
|
||||||
|
PzemAc.address = XdrvMailbox.payload; // Valid addresses are 1, 2 and 3
|
||||||
|
PzemAc.address_step = ADDR_SEND;
|
||||||
|
}
|
||||||
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
|
return serviced;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Interface
|
* Interface
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -122,6 +149,9 @@ bool Xnrg05(uint8_t function)
|
||||||
case FUNC_ENERGY_EVERY_SECOND:
|
case FUNC_ENERGY_EVERY_SECOND:
|
||||||
if (uptime > 4) { PzemAcEverySecond(); } // Fix start up issue #5875
|
if (uptime > 4) { PzemAcEverySecond(); } // Fix start up issue #5875
|
||||||
break;
|
break;
|
||||||
|
case FUNC_COMMAND:
|
||||||
|
result = PzemAcCommand();
|
||||||
|
break;
|
||||||
case FUNC_INIT:
|
case FUNC_INIT:
|
||||||
PzemAcSnsInit();
|
PzemAcSnsInit();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -40,6 +40,8 @@ struct PZEMDC {
|
||||||
float energy = 0;
|
float energy = 0;
|
||||||
uint8_t send_retry = 0;
|
uint8_t send_retry = 0;
|
||||||
uint8_t channel = 0;
|
uint8_t channel = 0;
|
||||||
|
uint8_t address = 0;
|
||||||
|
uint8_t address_step = ADDR_IDLE;
|
||||||
} PzemDc;
|
} PzemDc;
|
||||||
|
|
||||||
void PzemDcEverySecond(void)
|
void PzemDcEverySecond(void)
|
||||||
|
@ -49,25 +51,32 @@ void PzemDcEverySecond(void)
|
||||||
if (data_ready) {
|
if (data_ready) {
|
||||||
uint8_t buffer[26]; // At least 5 + (2 * 8) = 21
|
uint8_t buffer[26]; // At least 5 + (2 * 8) = 21
|
||||||
|
|
||||||
uint8_t error = PzemDcModbus->ReceiveBuffer(buffer, 8);
|
uint8_t registers = 8;
|
||||||
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, sizeof(buffer));
|
if (ADDR_RECEIVE == PzemDc.address_step) {
|
||||||
|
registers = 2; // Need 1 byte extra as response is F8 06 00 02 00 01 FD A3
|
||||||
|
PzemDc.address_step--;
|
||||||
|
}
|
||||||
|
uint8_t error = PzemDcModbus->ReceiveBuffer(buffer, registers);
|
||||||
|
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, PzemDcModbus->ReceiveCount());
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PDC: PzemDc %d error %d"), PZEM_DC_DEVICE_ADDRESS + PzemDc.channel, error);
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("PDC: PzemDc %d error %d"), PZEM_DC_DEVICE_ADDRESS + PzemDc.channel, error);
|
||||||
} else {
|
} else {
|
||||||
Energy.data_valid = 0;
|
Energy.data_valid = 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 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
|
// 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--
|
// 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
|
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.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
|
Energy.active_power[PzemDc.channel] = (float)((buffer[9] << 24) + (buffer[10] << 16) + (buffer[7] << 8) + buffer[8]) / 10.0; // 429496729.0 W
|
||||||
|
|
||||||
PzemDc.energy += (float)((buffer[13] << 24) + (buffer[14] << 16) + (buffer[11] << 8) + buffer[12]); // 4294967295 Wh
|
PzemDc.energy += (float)((buffer[13] << 24) + (buffer[14] << 16) + (buffer[11] << 8) + buffer[12]); // 4294967295 Wh
|
||||||
if (PzemDc.channel == Energy.phase_count -1) {
|
if (PzemDc.channel == Energy.phase_count -1) {
|
||||||
EnergyUpdateTotal(PzemDc.energy, false);
|
EnergyUpdateTotal(PzemDc.energy, false);
|
||||||
PzemDc.energy = 0;
|
PzemDc.energy = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +87,12 @@ void PzemDcEverySecond(void)
|
||||||
PzemDc.channel = 0;
|
PzemDc.channel = 0;
|
||||||
}
|
}
|
||||||
PzemDc.send_retry = ENERGY_WATCHDOG;
|
PzemDc.send_retry = ENERGY_WATCHDOG;
|
||||||
PzemDcModbus->Send(PZEM_DC_DEVICE_ADDRESS + PzemDc.channel, 0x04, 0, 8);
|
if (ADDR_SEND == PzemDc.address_step) {
|
||||||
|
PzemDcModbus->Send(0xF8, 0x06, 0x0002, (uint16_t)PzemDc.address);
|
||||||
|
PzemDc.address_step--;
|
||||||
|
} else {
|
||||||
|
PzemDcModbus->Send(PZEM_DC_DEVICE_ADDRESS + PzemDc.channel, 0x04, 0, 8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PzemDc.send_retry--;
|
PzemDc.send_retry--;
|
||||||
|
@ -109,6 +123,19 @@ void PzemDcDrvInit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PzemDcCommand(void)
|
||||||
|
{
|
||||||
|
bool serviced = true;
|
||||||
|
|
||||||
|
if (CMND_MODULEADDRESS == Energy.command_code) {
|
||||||
|
PzemDc.address = XdrvMailbox.payload; // Valid addresses are 1, 2 and 3
|
||||||
|
PzemDc.address_step = ADDR_SEND;
|
||||||
|
}
|
||||||
|
else serviced = false; // Unknown command
|
||||||
|
|
||||||
|
return serviced;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Interface
|
* Interface
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -121,6 +148,9 @@ bool Xnrg06(uint8_t function)
|
||||||
case FUNC_ENERGY_EVERY_SECOND:
|
case FUNC_ENERGY_EVERY_SECOND:
|
||||||
if (uptime > 4) { PzemDcEverySecond(); } // Fix start up issue #5875
|
if (uptime > 4) { PzemDcEverySecond(); } // Fix start up issue #5875
|
||||||
break;
|
break;
|
||||||
|
case FUNC_COMMAND:
|
||||||
|
result = PzemDcCommand();
|
||||||
|
break;
|
||||||
case FUNC_INIT:
|
case FUNC_INIT:
|
||||||
PzemDcSnsInit();
|
PzemDcSnsInit();
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue