Reading modbus data from Eltako 3-phase meter

I recently bought a Level 3 heatpump monitoring kit (order #33521) and have connected it up to a existing Kamstrup 403 heat meter and an Eltako DSZ15DZMOD 3-phase meter, which my electrician installed. At first glance the Modbus protocol looks very similar to that of the SDM630, but the values are all 4-byte integers, mostly unsigned. Here is the extract from my emonhub.conf:


    [[modbus]]
        Type = EmonHubMinimalModbusInterfacer
        [[[init_settings]]]
            #device = /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_B001AG05-if00-port0
            device = /dev/ttyACM0
            baud = 9600
            #datatype = integer
        [[[runtimesettings]]]
            pubchannels = ToEmonCMS,
            read_interval = 10
            nodename = heatpump
            [[[[meters]]]]
                [[[[[electric]]]]]
                    address = 1
                    registers =  52, 72
                    names =  P_total, EI_total
                    datacodes = l, L
		    scales = 1, 0.01
		    units = kW, kWh

Unfortunately, “datacodes” and “units” are ignored and the values are read in as floats. Here a log extract after restart:

2024-08-17 16:46:19,945 INFO     MainThread Creating EmonHubMinimalModbusInterfacer 'modbus'
2024-08-17 16:46:19,946 INFO     MainThread Connecting to Modbus device=/dev/ttyACM0 baud=9600 parity=none datatype=float
2024-08-17 16:46:19,947 INFO     MainThread Setting modbus read_interval: 10
2024-08-17 16:46:19,948 INFO     MainThread Setting modbus nodename: heatpump
2024-08-17 16:46:19,948 INFO     MainThread Setting modbus prefix: 
2024-08-17 16:46:19,949 INFO     MainThread Setting modbus meters electric address 1
2024-08-17 16:46:19,949 INFO     MainThread Setting modbus meters electric registers [52, 72]
2024-08-17 16:46:19,950 INFO     MainThread Setting modbus meters electric names ["P_total", "EI_total"]
2024-08-17 16:46:19,950 INFO     MainThread Setting modbus meters electric scales [1.0, 0.01]
2024-08-17 16:46:19,951 DEBUG    MainThread Setting modbus pubchannels: ['ToEmonCMS']
2024-08-17 16:46:19,952 INFO     MainThread Setting MBUS read_interval: 10
2024-08-17 16:46:19,952 INFO     MainThread Setting MBUS validate_checksum: False
2024-08-17 16:46:19,953 INFO     MainThread Setting MBUS meters: {"heatmeter": {"address": "1", "type": "kamstrup403"}}
2024-08-17 16:46:20,419 DEBUG    modbus     [2.6624670822171524e-44, 1.807675018979014e-45]
2024-08-17 16:46:20,420 DEBUG    modbus     833 NEW FRAME : 
2024-08-17 16:46:20,421 DEBUG    modbus     833 Timestamp : 1723909580.052268
2024-08-17 16:46:20,421 DEBUG    modbus     833 From Node : heatpump
2024-08-17 16:46:20,422 DEBUG    modbus     833    Values : [2.6624670822171524e-44, 1.807675018979014e-45]
2024-08-17 16:46:20,423 DEBUG    modbus     833 Sent to channel(start)' : ToEmonCMS
2024-08-17 16:46:20,423 DEBUG    modbus     833 Sent to channel(end)' : ToEmonCMS

Entering “datatype=int” in the init_settings creates a different error - the register addresses no longer fit (2-byte data?). Is there another magic word I can enter here - “long” is ignored?

How can I get emonhub to read the datacodes? I would welcome any suggestions.

1 Like

UPDATE:
If all else fails, read the documentation!
From the Minimal Modbus API documentation it is clear that read_long is needed. However, the interfacer EmonHubMinimalModbusInterfacer.py only implements read_register (datatype = int) and read_float. So I added an extra elif for read_long that I can access with datatype = long.

elif self.datatype == 'long':
    time.sleep(0.1)	
    value = self._rs485.read_long(int(self._settings['meters'][meter]['registers'][i]), functioncode=4, signed=True, number_of_registers=2)

This works for me, but note that all registers are read as longs, you can’t have mixed longs and floats.
I hope this helps anyone else who bought the “wrong” electricity meter.

1 Like

Thanks for sharing @Lawrie_Witham