Skip to content

Commit 8c3b22c

Browse files
authored
[modbus][sunspec] Fix acc32 and uint32 (openhab#18370)
In 2020 the ACC32 fields were changed from unsigned int to signed, ref. openhab#7826. This is incorrect. The acc32 is an unsigned integer. On top of that, the sunspec meter handlers had values assigned with acc32 that are uint32 according to the sunspec specification. https://sunspec.org/wp-content/uploads/2025/01/SunSpec-Device-Information-Model-Specificiation-V1-2-1-1.pdf This is the latest specification from 2024. Here it is stated that: acc32 = Unsigned 32-bit accumulator (deprecated in favor of uint32) Basically both acc32 and uint32 can have values from 0 to 4294967294 acc32 even until 4294967295, which is due to uint32 0xFFFFFFFF is specified as "not implemented". See also https://community.openhab.org/t/modbus-sunspec-showing-negative-total-exported-energy/161611/13 for the bug. Please cherrypick to 4.3.x branch as well. Signed-off-by: Cor Hoogendoorn <[email protected]>
1 parent 824a8f5 commit 8c3b22c

File tree

1 file changed

+3
-3
lines changed
  • bundles/org.openhab.binding.modbus.sunspec/src/main/java/org/openhab/binding/modbus/sunspec/internal/parser

1 file changed

+3
-3
lines changed

bundles/org.openhab.binding.modbus.sunspec/src/main/java/org/openhab/binding/modbus/sunspec/internal/parser/AbstractBaseParser.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,19 @@ protected Integer extractUInt16(ModbusRegisterArray raw, int index, int def) {
7979
}
8080

8181
/**
82-
* Extract an optional acc32 value
82+
* Extract an optional acc32/uint32 value
8383
*
8484
* @param raw the register array to extract from
8585
* @param index the address of the field
8686
* @return the parsed value or empty if the field is not implemented
8787
*/
8888
protected Optional<Long> extractOptionalAcc32(ModbusRegisterArray raw, int index) {
89-
return ModbusBitUtilities.extractStateFromRegisters(raw, index, ValueType.INT32).map(DecimalType::longValue)
89+
return ModbusBitUtilities.extractStateFromRegisters(raw, index, ValueType.UINT32).map(DecimalType::longValue)
9090
.filter(value -> value != 0);
9191
}
9292

9393
/**
94-
* Extract a mandatory acc32 value
94+
* Extract a mandatory acc32/uint32 value
9595
*
9696
* @param raw the register array to extract from
9797
* @param index the address of the field

0 commit comments

Comments
 (0)