Hi all,
I am trying to configure a smart meter in openhab using the modbus binding. My modbus .things file has the following in it.
Bridge modbus:tcp:localhost "Smart_Meter_One" [host = "<IP_ADDRESS_OF_METER>", port=502, id=2] {
Bridge poller inputRegisters [start = 4370, length=2, refresh=1000, type="input"]{
Thing data Voltage [readStart = "4370", readValueType="float32"]
}
}
The address I am trying to read is a 32 bit float address. The value is stored in two 16 bit register with a hexadecimal index of 0x1112-0x1113. I originally tried using the hexadecimal address for accessing the registers but I was getting an error code 2 from the slave which was an illegal address register. This did tell me however that there was communication to the slave so a connection is there.
I changed to the addresing described in the docs. Looking at the poller I am assuming:
- The parameter
type="input
means I am in the input address range of 30001 to 39999. - The parameter
start=4370
means that the first register I want to read is indexed at 34371. - The parameter
length=2
means I want to read two registers.
Then looking at my data Thing
:
- The parameter
readStart = 4370
means the first register to be read is at address 4370. - The parameter
readValueType="float32"
expects a 32 bit number composed of two 16 bit registers in this format.
My modbus.items file then contains the following
Number Voltage1221Float32 "Input registers 1112-1113 as float32 [%.1f]" { channel="modbus:data:localhostTCP:inputRegisters:Voltage:number"}
There is no errors in the log and both the poller
and the data
Thing
have a status of online. The Voltage1221Float32
Item however has a constant state of Null.
Is there any errors in my configuration of the modbus connection?
I know that the modbus device is communicating properly as I tried reading the address from a python script and it worked fine in reading the address.
from pymodbus.client.sync import ModbusTcpClient
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
client = ModbusTcpClient('<IP_ADDRESS_OF_METER>')
def read32bitfloat(address):
response = client.read_input_registers(address, 2)
return response
def read_voltage():
response = read32bitfloat(0x1112)
decoder = BinaryPayloadDecoder.fromRegisters(response.registers, Endian.Big, wordorder=Endian.Little)
return decoder.decode_32bit_float()
if __name__ == '__main__':
print(smart_meters.read_voltage())