mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +00:00
Add fieldpair "F" replacing "M"
This commit is contained in:
parent
768820061b
commit
0dc3b8d7e1
@ -36,7 +36,7 @@
|
||||
* Voltage - Voltage register entered as decimal or hexadecimal for one phase (0x0000) or up to three phases ([0x0000,0x0002,0x0004]) or
|
||||
* Additional defined parameters
|
||||
* Value pair description:
|
||||
* {"R":0,"T":0,"M":1}
|
||||
* {"R":0,"T":0,"F":0}
|
||||
* R - Modbus register entered as decimal or hexadecimal for one phase (0x0160) or up to three phases ([0x0160,0x0162,0x0164])
|
||||
* T - Datatype - optional. default is 0 - float:
|
||||
* 0 - float
|
||||
@ -48,7 +48,17 @@
|
||||
* 6 = 4-byte signed with swapped words
|
||||
* 7 = not used
|
||||
* 8 = 4-byte unsigned with swapped words
|
||||
* M - Multiply, if negative, or divide, if positive, the read register by 1 to 10000 - optional. default = 1
|
||||
* F - Register factor positive for multiplication or negative for division - optional. default is 0 - no action
|
||||
* -4 - divide by 10000
|
||||
* -3 - divide by 1000
|
||||
* -2 - divide by 100
|
||||
* -1 - divide by 10
|
||||
* 0 - no action
|
||||
* 1 - multiply by 10
|
||||
* 2 - multiply by 100
|
||||
* 3 - multiply by 1000
|
||||
* 4 - multiply by 10000
|
||||
* M - [LEGACY - replaced by "F"] Divide register by 1 to 10000 - optional. default = 0 (no action)
|
||||
* Current - Current register entered as decimal or hexadecimal for one phase (0x0006) or up to three phases ([0x0006,0x0008,0x000A]) or
|
||||
* See additional defines like voltage.
|
||||
* Power - Active power register entered as decimal or hexadecimal for one phase (0x000C) or up to three phases ([0x000C,0x000E,0x0010]) or
|
||||
@ -68,7 +78,7 @@
|
||||
* Optional user defined registers:
|
||||
* User - Additional user defined registers
|
||||
* Value pair description:
|
||||
* "User":{"R":0x0024,"T":0,"M":1,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}
|
||||
* "User":{"R":0x0024,"T":0,"F":0,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}
|
||||
* R - Modbus register entered as decimal or hexadecimal for one phase (0x0160) or up to three phases ([0x0160,0x0162,0x0164])
|
||||
* T - Datatype - optional. default is 0 - float:
|
||||
* 0 - float
|
||||
@ -80,7 +90,17 @@
|
||||
* 6 = 4-byte signed with swapped words
|
||||
* 7 = not used
|
||||
* 8 = 4-byte unsigned with swapped words
|
||||
* M - Multiply, if negative, or divide, if positive, the read register by 1 to 10000 - optional. default = 1
|
||||
* F - Register factor positive for multiplication or negative for division - optional. default is 0 - no action
|
||||
* -4 - divide by 10000
|
||||
* -3 - divide by 1000
|
||||
* -2 - divide by 100
|
||||
* -1 - divide by 10
|
||||
* 0 - no action
|
||||
* 1 - multiply by 10
|
||||
* 2 - multiply by 100
|
||||
* 3 - multiply by 1000
|
||||
* 4 - multiply by 10000
|
||||
* M - [LEGACY - replaced by "F"] Divide register by 1 to 10000 - optional. default = 0 (no action)
|
||||
* J - JSON register name (preferrably without spaces like "PhaseAngle")
|
||||
* G - GUI register name
|
||||
* U - GUI unit name
|
||||
@ -105,7 +125,7 @@
|
||||
* rule3 on file#modbus do {"Name":"SDM120","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":0x0048,"J":"ImportActive","G":"Import Active","U":"kWh","D":24},{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":24},{"R":0x004C,"J":"ImportReactive","G":"Import Reactive","U":"kVArh","D":24},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon
|
||||
* rule3 on file#modbus do {"Name":"SDM230 with two user registers","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon
|
||||
* rule3 on file#modbus do {"Name":"SDM630","Baud":9600,"Config":8N1","Address":1,"Function":4,"Voltage":[0,2,4],"Current":[6,8,10],"Power":[12,14,16],"ApparentPower":[18,20,22],"ReactivePower":[24,26,28],"Factor":[30,32,34],"Frequency":70,"Total":342,"ExportActive":[352,354,356],"User":{"R":[346,348,350],"J":"ImportActive","G":"Import Active","U":"kWh","D":24}} endon
|
||||
* rule3 on file#modbus do {"Name":"X3MIC","Baud":9600,"Config":8N1","Address":1,"Function":4,"Voltage":{"R":0x0404,"T":3,"M":10},"Power":{"R":0x040e,"T":3,"M":1},"Total":{"R":0x0423,"T":8,"M":1000}} endon
|
||||
* rule3 on file#modbus do {"Name":"X3MIC","Baud":9600,"Config":8N1","Address":1,"Function":4,"Voltage":{"R":0x0404,"T":3,"F":-1},"Power":{"R":0x040e,"T":3,"F":0},"Total":{"R":0x0423,"T":8,"F":-3}} endon
|
||||
*
|
||||
* Note:
|
||||
* - To enter long rules using the serial console and solve error "Serial buffer overrun" you might need to enlarge the serial input buffer with command serialbuffer 800
|
||||
@ -128,7 +148,7 @@
|
||||
* rule3 on file#modbus do {"Name":"SDM120 test1","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":0,"Current":6,"Power":12,"ApparentPower":18,"ReactivePower":24,"Factor":30,"Frequency":70,"Total":342,"ExportActive":0x004A,"User":[{"R":0x0048,"J":"ImportActive","G":"Import Active","U":"kWh","D":24},{"R":0x004E,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":24},{"R":0x004C,"J":"ImportReactive","G":"Import Reactive","U":"kVArh","D":24},{"R":0x0024,"J":"PhaseAngle","G":"Phase Angle","U":"Deg","D":2}]} endon
|
||||
*
|
||||
* rule3 on file#modbus do {"Name":"SDM230 test6","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":{"R":0,"T":0,"M":1},"Current":{"R":6,"T":0,"M":1},"Power":{"R":12,"T":0,"M":1},"Frequency":70,"Total":342} endon
|
||||
* rule3 on file#modbus do {"Name":"SDM230 test6","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":{"R":0,"T":0,"M":1},"Current":{"R":6,"T":0,"M":1},"Power":{"R":12,"T":0,"M":1},"Frequency":70,"Total":342,"User":{"R":0x0048,"T":0,"M":10,"J":"ImportActive","G":"Import Active","U":"kWh","D":24}} endon
|
||||
* rule3 on file#modbus do {"Name":"SDM230 test6","Baud":2400,"Config":8N1","Address":1,"Function":4,"Voltage":{"R":0,"T":0,"F":0},"Current":{"R":6,"T":0,"F":0},"Power":{"R":12,"T":0,"F":0},"Frequency":70,"Total":342,"User":{"R":0x0048,"T":0,"F":-1,"J":"ImportActive","G":"Import Active","U":"kWh","D":24}} endon
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XNRG_29 29
|
||||
@ -139,8 +159,6 @@
|
||||
#define ENERGY_MODBUS_FUNC 0x04 // Default Modbus function code
|
||||
|
||||
#define ENERGY_MODBUS_DATATYPE 0 // Default Modbus datatype is 4-byte float
|
||||
#define ENERGY_MODBUS_DIVIDER 1 // Default Modbus data divider
|
||||
|
||||
#define ENERGY_MODBUS_DECIMALS 0 // Default user decimal resolution
|
||||
|
||||
#define ENERGY_MODBUS_TICKER // Enable for ESP8266 when using softwareserial solving most modbus serial retries
|
||||
@ -216,7 +234,7 @@ struct NRGMBSPARAM {
|
||||
|
||||
typedef struct NRGMBSREGISTER {
|
||||
uint16_t address[ENERGY_MAX_PHASES];
|
||||
int16_t divider;
|
||||
int16_t factor;
|
||||
uint32_t datatype;
|
||||
} NrgMbsRegister_t;
|
||||
NrgMbsRegister_t *NrgMbsReg = nullptr;
|
||||
@ -342,10 +360,17 @@ void EnergyModbusLoop(void) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NrgMbsReg[NrgMbsParam.state].divider < 1) {
|
||||
value *= (NrgMbsReg[NrgMbsParam.state].divider * -1);
|
||||
uint32_t factor = 1;
|
||||
// 1 = 10, 2 = 100, 3 = 1000, 4 = 10000
|
||||
uint32_t scaler = abs(NrgMbsReg[NrgMbsParam.state].factor);
|
||||
while (scaler) {
|
||||
factor *= 10;
|
||||
scaler--;
|
||||
}
|
||||
if (NrgMbsReg[NrgMbsParam.state].factor < 0) {
|
||||
value /= factor;
|
||||
} else {
|
||||
value /= NrgMbsReg[NrgMbsParam.state].divider;
|
||||
value *= factor;
|
||||
}
|
||||
|
||||
switch (NrgMbsParam.state) {
|
||||
@ -417,7 +442,7 @@ void EnergyModbusLoop(void) {
|
||||
|
||||
#ifdef USE_RULES
|
||||
bool EnergyModbusReadUserRegisters(JsonParserObject user_add_value, uint32_t add_index) {
|
||||
// {"R":0x004E,"T":0,"M":1,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3}
|
||||
// {"R":0x004E,"T":0,"F":0,"J":"ExportReactive","G":"Export Reactive","U":"kVArh","D":3}
|
||||
uint32_t reg_index = NRG_MBS_MAX_REGS + add_index;
|
||||
JsonParserToken val;
|
||||
val = user_add_value[PSTR("R")]; // Register address
|
||||
@ -443,10 +468,21 @@ bool EnergyModbusReadUserRegisters(JsonParserObject user_add_value, uint32_t add
|
||||
// "T":0
|
||||
NrgMbsReg[reg_index].datatype = val.getUInt();
|
||||
}
|
||||
val = user_add_value[PSTR("M")]; // Register divider
|
||||
val = user_add_value[PSTR("F")]; // Register factor
|
||||
if (val) {
|
||||
// "M":1 or "M":-10
|
||||
NrgMbsReg[reg_index].divider = val.getInt();
|
||||
// "F":1 or "F":-2
|
||||
NrgMbsReg[reg_index].factor = val.getInt();
|
||||
}
|
||||
val = user_add_value[PSTR("M")]; // [LEGACY] Register divider
|
||||
if (val) {
|
||||
// "M":1
|
||||
int32_t divider = val.getUInt();
|
||||
int factor = 0;
|
||||
while (divider > 1) {
|
||||
divider /= 10;
|
||||
factor--;
|
||||
}
|
||||
NrgMbsReg[reg_index].factor = factor;
|
||||
}
|
||||
val = user_add_value[PSTR("J")]; // JSON value name
|
||||
if (val) {
|
||||
@ -472,13 +508,13 @@ bool EnergyModbusReadUserRegisters(JsonParserObject user_add_value, uint32_t add
|
||||
}
|
||||
|
||||
#ifdef ENERGY_MODBUS_DEBUG
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Idx %d, R [%04X,%04X,%04X], T %d, M %d, J '%s', G '%s', U '%s', D %d"),
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Idx %d, R [%04X,%04X,%04X], T %d, F %d, J '%s', G '%s', U '%s', D %d"),
|
||||
add_index,
|
||||
NrgMbsReg[reg_index].address[0],
|
||||
NrgMbsReg[reg_index].address[1],
|
||||
NrgMbsReg[reg_index].address[2],
|
||||
NrgMbsReg[reg_index].datatype,
|
||||
NrgMbsReg[reg_index].divider,
|
||||
NrgMbsReg[reg_index].factor,
|
||||
NrgMbsUser[add_index].json_name,
|
||||
NrgMbsUser[add_index].gui_name,
|
||||
NrgMbsUser[add_index].gui_unit,
|
||||
@ -529,7 +565,6 @@ bool EnergyModbusReadRegisters(void) {
|
||||
// Init defaults
|
||||
for (uint32_t i = 0; i < NrgMbsParam.total_regs; i++) {
|
||||
NrgMbsReg[i].datatype = ENERGY_MODBUS_DATATYPE;
|
||||
NrgMbsReg[i].divider = ENERGY_MODBUS_DIVIDER;
|
||||
for (uint32_t j = 0; j < ENERGY_MAX_PHASES; j++) {
|
||||
NrgMbsReg[i].address[j] = nrg_mbs_reg_not_used;
|
||||
}
|
||||
@ -576,12 +611,12 @@ bool EnergyModbusReadRegisters(void) {
|
||||
if (val) {
|
||||
// "Voltage":0
|
||||
// "Voltage":[0,0,0]
|
||||
// "Voltage":{"R":0,"T":0,"M":1}
|
||||
// "Voltage":{"R":[0,0,0],"T":0,"M":1}
|
||||
// "Voltage":{"R":0,"T":0,"F":0}
|
||||
// "Voltage":{"R":[0,0,0],"T":0,"F":0}
|
||||
uint32_t phase = 0;
|
||||
if (val.isObject()) {
|
||||
// "Voltage":{"R":0,"T":0,"M":1}
|
||||
// "Voltage":{"R":[0,0,0],"T":0,"M":1}
|
||||
// "Voltage":{"R":0,"T":0,"F":0}
|
||||
// "Voltage":{"R":[0,0,0],"T":0,"F":0}
|
||||
JsonParserObject register_add_values = val.getObject();
|
||||
val = register_add_values[PSTR("R")]; // Register address
|
||||
if (val.isArray()) {
|
||||
@ -602,10 +637,21 @@ bool EnergyModbusReadRegisters(void) {
|
||||
// "T":0
|
||||
NrgMbsReg[names].datatype = val.getUInt();
|
||||
}
|
||||
val = register_add_values[PSTR("M")]; // Register divider
|
||||
val = register_add_values[PSTR("F")]; // Register factor
|
||||
if (val) {
|
||||
// "M":1 or "M":-10
|
||||
NrgMbsReg[names].divider = val.getInt();
|
||||
// "F":1 or "F":-2
|
||||
NrgMbsReg[names].factor = val.getInt();
|
||||
}
|
||||
val = register_add_values[PSTR("M")]; // [LEGACY] Register divider
|
||||
if (val) {
|
||||
// "M":1
|
||||
int32_t divider = val.getUInt();
|
||||
int factor = 0;
|
||||
while (divider > 1) {
|
||||
divider /= 10;
|
||||
factor--;
|
||||
}
|
||||
NrgMbsReg[names].factor = factor;
|
||||
}
|
||||
} else if (val.isArray()) {
|
||||
// "Voltage":[0,0,0]
|
||||
@ -644,13 +690,13 @@ bool EnergyModbusReadRegisters(void) {
|
||||
}
|
||||
|
||||
#ifdef ENERGY_MODBUS_DEBUG
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Idx %d, R [%04X,%04X,%04X], T %d, M %d"),
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Idx %d, R [%04X,%04X,%04X], T %d, F %d"),
|
||||
names,
|
||||
NrgMbsReg[names].address[0],
|
||||
NrgMbsReg[names].address[1],
|
||||
NrgMbsReg[names].address[2],
|
||||
NrgMbsReg[names].datatype,
|
||||
NrgMbsReg[names].divider);
|
||||
NrgMbsReg[names].factor);
|
||||
#endif
|
||||
|
||||
}
|
||||
@ -687,9 +733,6 @@ bool EnergyModbusReadRegisters(void) {
|
||||
if (NrgMbsReg[i].datatype >= NRG_DT_MAX) {
|
||||
NrgMbsReg[i].datatype = ENERGY_MODBUS_DATATYPE;
|
||||
}
|
||||
if (0 == NrgMbsReg[i].divider) {
|
||||
NrgMbsReg[i].divider = ENERGY_MODBUS_DIVIDER;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENERGY_MODBUS_DEBUG
|
||||
|
Loading…
x
Reference in New Issue
Block a user