[OH3] [Modbus] SDM120 strange values, permission problems

Hi, I finally got my modbus binding too work. I’m reading SDM120M energymeters. Got 12 of them, but only connected 6 of them on a USB-RS485 dongle.

I got a few problems:

  1. The values I’m getting are wrong, voltage should be around 230v, is giving me 1 or with other settings something very small.
  2. Can not use the symlink ttyRS485, only ttyUSB0 works, ttyRS485 gives permissions problems.
  3. Sometimes modbus hangs and I need a restart of openhab to get is to work. Are there still problems with nrjavaserial? Can I upgrade something?

Trying to get this working for a few days now … I need some help. Sorry for the long post.

Hardeware stuff:

Running Openhab 3.2 on a HP t630 thin client running Debian.

Software stuff:

###@scouthab:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 11 (bullseye)
Release:        11
Codename:       bullseye
###@scouthab:~$ java -version
openjdk version "11.0.13" 2021-10-19 LTS
OpenJDK Runtime Environment Zulu11.52+13-CA (build 11.0.13+8-LTS)
OpenJDK Server VM Zulu11.52+13-CA (build 11.0.13+8-LTS, mixed mode)
openhab> bundle:list|grep Modbus
255 │ Active │  80 │ 3.2.0                 │ openHAB Add-ons :: Bundles :: Modbus Binding
256 │ Active │  80 │ 3.2.0                 │ openHAB Add-ons :: Bundles :: E3DC Modbus Binding
258 │ Active │  80 │ 3.2.0                 │ openHAB Add-ons :: Bundles :: Modbus SBC Binding
275 │ Active │  80 │ 3.2.0                 │ openHAB Core :: Bundles :: Modbus Transport
openhab> log:set INFO org.openhab.binding.modbus
openhab> list -s | grep nrjavaserial
249 │ Active │  80 │ 5.2.1                 │ nrjavaserial
openhab> openhab:serial identifiers
[name: /dev/ttyUSB1, current owner: null]
[name: /dev/ttyUSB0, current owner: null]
[name: /dev/ttyS0, current owner: null]

1. Wrong values

After fixing some wiring problems, I’m able to get readings from them directly using Python.

***@scouthab:~$ python3 sdm_modbus/example-rtu.py --stopbits 1 --parity N --baud 9600 --unit 1 /dev/ttyRS485
SDM120(/dev/ttyRS485, connectionType.RTU: stopbits=1, parity=N, baud=9600, timeout=1, retries=3, unit=0x1):

Input Registers:
        Voltage: 233.80V
        Current: 0.03A
        Power (Active): 0.00W
        Power (Apparent): 0.00VA
        Power (Reactive): 0.00VAr
        Power Factor: 1.00
        Phase Angle: 0.00°
        Frequency: 50.00Hz
        Imported Energy (Active): 108.94kWh
        Exported Energy (Active): 0.00kWh
        Imported Energy (Reactive): 9.43kVArh
        Exported Energy (Reactive): 16.95kVArh
        Total Demand Power (Active): 0.00W
        Maximum Total Demand Power (Active): 1475.33W
        Import Demand Power (Active): 0.00W
        Maximum Import Demand Power (Active): 1475.33W
        Export Demand Power (Active): 0.00W
        Maximum Export Demand Power (Active): 0.00W
        Total Demand Current: 0.00A
        Maximum Total Demand Current: 6.43A
        Total Energy (Active): 108.94kWh
        Total Energy (Reactive): 26.39kVArh

Holding Registers:
        Demand Time: 57s
        Demand Period: 60s
        Relay Pulse Width: 60ms
        Network Parity Stop: N-1
        Meter ID: 1
        Baud Rate: 9600
        P1 Output Mode: Export Energy (Active)
        Display Scroll Timing: 0s
        P1 Divisor: 0.001kWh/imp
        Measurement Mode: 0
        Pulse/LED Indicator Mode: Import + Export Energy (Active)

Got a modbus connection thing:

UID: modbus:serial:SDM120_1
label: SDM120_1
thingTypeUID: modbus:serial
configuration:
  baud: 9600
  connectMaxTries: 1
  timeBetweenTransactionsMillis: 100
  stopBits: "1.0"
  parity: none
  receiveTimeoutMillis: 1500
  dataBits: 8
  echo: false
  encoding: rtu
  flowControlIn: none
  flowControlOut: none
  port: /dev/ttyUSB0
  connectTimeoutMillis: 10000
  id: 1
  enableDiscovery: false

A values read thing:

UID: modbus:poller:SDM120_1:SDM120_1_power
label: SDM120-1 Values
thingTypeUID: modbus:poller
configuration:
  length: 14
  start: 0
  refresh: 10000
  maxTries: 3
  cacheMillis: 50
  type: holding
bridgeUID: modbus:serial:SDM120_1

A voltage read thing:

UID: modbus:data:SDM120_1_power:SDM120-1_voltage
label: SDM120-1 Voltage
thingTypeUID: modbus:data
configuration:
  readValueType: float32
  readTransform: default
  writeTransform: default
  readStart: "0"
  updateUnchangedValuesEveryMillis: 1000
  writeMultipleEvenWithSingleRegisterOrCoil: false
  writeMaxTries: 3
bridgeUID: modbus:poller:SDM120_1:SDM120_1_power

A current read thing:

UID: modbus:data:SDM120_1_power:SDM120-1_current
label: SDM120-1 Current
thingTypeUID: modbus:data
configuration:
  readValueType: float32
  readTransform: default
  writeTransform: default
  readStart: "6"
  updateUnchangedValuesEveryMillis: 1000
  writeMultipleEvenWithSingleRegisterOrCoil: false
  writeMaxTries: 3
bridgeUID: modbus:poller:SDM120_1:SDM120_1_power

And a power read thing:

UID: modbus:data:SDM120_1_power:SDM120-1_power
label: SDM120-1 Power
thingTypeUID: modbus:data
configuration:
  readValueType: float32
  readTransform: default
  writeTransform: default
  readStart: "12"
  updateUnchangedValuesEveryMillis: 1000
  writeMultipleEvenWithSingleRegisterOrCoil: false
  writeMaxTries: 3
bridgeUID: modbus:poller:SDM120_1:SDM120_1_power

This results in the following log output:

2022-01-08 20:27:24.324 [DEBUG] [t.wimpi.modbus.io.ModbusRTUTransport] - Sent: 01 03 00 00 00 0e c4 0e 
2022-01-08 20:27:24.406 [DEBUG] [t.wimpi.modbus.io.ModbusRTUTransport] - Response (CRC OK): 01 03 1c 3f 80 00 00 42 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 42 70 00 00 37 22 
2022-01-08 20:27:24.407 [DEBUG] [bus.handler.ModbusPollerThingHandler] - Thing modbus:poller:SDM120_1:SDM120_1_power received response PollResult(result=AsyncModbusReadResult(request = ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=0, length=14, maxTries=3], registers = ModbusRegisterArray(3F800000427000000000000000000000000000000000000042700000)))
2022-01-08 20:27:24.410 [DEBUG] [ernal.handler.ModbusDataThingHandler] - Thing modbus:data:SDM120_1_power:SDM120-1_voltage channels updated: {modbus:data:SDM120_1_power:SDM120-1_voltage:number=1.0}. readValueType=float32, readIndex=Optional[0], readSubIndex(or 0)=0, extractIndex=0 -> numeric value 1.0 and boolValue=true. Registers ModbusRegisterArray(3F800000427000000000000000000000000000000000000042700000) for request ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=0, length=14, maxTries=3]
2022-01-08 20:27:24.412 [DEBUG] [ernal.handler.ModbusDataThingHandler] - Thing modbus:data:SDM120_1_power:SDM120-1_power channels updated: null. readValueType=float32, readIndex=Optional[12], readSubIndex(or 0)=0, extractIndex=12 -> numeric value 60.0 and boolValue=true. Registers ModbusRegisterArray(3F800000427000000000000000000000000000000000000042700000) for request ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=0, length=14, maxTries=3]
2022-01-08 20:27:24.413 [DEBUG] [ernal.handler.ModbusDataThingHandler] - Thing modbus:data:SDM120_1_power:SDM120-1_current channels updated: null. readValueType=float32, readIndex=Optional[6], readSubIndex(or 0)=0, extractIndex=6 -> numeric value 0.0 and boolValue=false. Registers ModbusRegisterArray(3F800000427000000000000000000000000000000000000042700000) for request ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=0, length=14, maxTries=3]

In short:

Sent: 01 03 00 00 00 0e c4 0e 
Response (CRC OK): 01 03 1c 3f 80 00 00 42 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 42 70 00 00 37 22 
extractIndex=0 -> numeric value 1.0
extractIndex=12 -> numeric value 60.0 
extractIndex=6 -> numeric value 0.0

Using float32_swap instead of float32 … also gives strange results.

2022-01-08 20:34:58.454 [DEBUG] [ernal.handler.ModbusDataThingHandler] - Thing modbus:data:SDM120_1_power:SDM120-1_voltage channels updated: {modbus:data:SDM120_1_power:SDM120-1_voltage:number=0.000000000000000000000000000000000000000022779507836064226}. readValueType=float32_swap, readIndex=Optional[0], readSubIndex(or 0)=0, extractIndex=0 -> numeric value 0.000000000000000000000000000000000000000022779507836064226 and boolValue=true. Registers ModbusRegisterArray(3F800000427000000000000000000000000000000000000042700000) for request ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=0, length=14, maxTries=3]
2022-01-08 20:34:58.455 [DEBUG] [ernal.handler.ModbusDataThingHandler] - Thing modbus:data:SDM120_1_power:SDM120-1_power channels updated: null. readValueType=float32_swap, readIndex=Optional[12], readSubIndex(or 0)=0, extractIndex=12 -> numeric value 0.00000000000000000000000000000000000000002383328428123649 and boolValue=true. Registers ModbusRegisterArray(3F800000427000000000000000000000000000000000000042700000) for request ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=0, length=14, maxTries=3]
2022-01-08 20:34:58.456 [DEBUG] [ernal.handler.ModbusDataThingHandler] - Thing modbus:data:SDM120_1_power:SDM120-1_current channels updated: null. readValueType=float32_swap, readIndex=Optional[6], readSubIndex(or 0)=0, extractIndex=6 -> numeric value 0.0 and boolValue=false. Registers ModbusRegisterArray(3F800000427000000000000000000000000000000000000042700000) for request ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=0, length=14, maxTries=3]

In short:

same respons
extractIndex=0 -> numeric value 0.000000000000000000000000000000000000000022779507836064226
extractIndex=12 -> numeric value 0.00000000000000000000000000000000000000002383328428123649 
extractIndex=6 -> numeric value 0.0

Is there a setting I have wrong?

2. Not able to use ttyRS485

I’ve seen https://www.openhab.org/docs/administration/serial.html and added all stuff there.
Modified /etc/default/openhab with the

EXTRA_JAVA_OPTS="-Dgnu.io.rxtx.SerialPorts=/dev/ttyUSBP1:/dev/ttyRS485:/dev/ttyUSB0:/dev/ttyUSB1"

User is in the needed group(s)

***@scouthab:~$ groups openhab
openhab : openhab tty dialout sudo audio bluetooth

Using Udev rules to link RS485 USB stick to /dev/ttyRS485, it’s there and it’s working with other programs.

***@scouthab:~$ ls -lhS /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0  6 jan 12:36 /dev/ttyUSB0
***@scouthab:~$ ls -lhS /dev/ttyRS485
lrwxrwxrwx 1 root root 7  6 jan 01:38 /dev/ttyRS485 -> ttyUSB0
openhab> openhab:serial identifiers
[name: /dev/ttyUSB1, current owner: null]
[name: /dev/ttyUSB0, current owner: null]
[name: /dev/ttyS0, current owner: null]

Using ttyRS485: results in the following errors:

2022-01-06 13:45:35.921 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - re-connect reached max tries 1, throwing last error: Could not get port identifier, maybe insufficient permissions. null. Connection SerialConnection [m_SerialPort=null, m_Parameters.getPortName()=/dev/ttyRS485]. Endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyRS485]
2022-01-06 13:45:35.921 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - Error connecting connection SerialConnection [m_SerialPort=null, m_Parameters.getPortName()=/dev/ttyRS485] for endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyRS485]: Could not get port identifier, maybe insufficient permissions. null
2022-01-06 13:45:35.922 [WARN ] [rt.modbus.internal.ModbusManagerImpl] - Could not connect to endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyRS485] -- aborting request ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=30013, length=2, maxTries=3] [operation ID 19ad4f20-e7dc-40da-a994-c9d08b70b0f8]
2022-01-06 13:45:40.924 [WARN ] [ing.ModbusSlaveConnectionFactoryImpl] - connect try 1/1 error: Could not get port identifier, maybe insufficient permissions. null. Connection SerialConnection [m_SerialPort=null, m_Parameters.getPortName()=/dev/ttyRS485]. Endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyRS485]

Some posts mention to set something via openhabian-config:

  • system related (option 30)
  • serial port (option 35)

However when I try to select option 35 … I’m not able to see that menu and switch back to the previous menu … maybe because I do not use a Raspberry Pi?

3. Still something with nrjavaserial?

Read that the problem was fixed in 3.1.0 and up … or was I wrong? Do I still need to update something?

openhab> bundle:list|grep Modbus
255 │ Active │  80 │ 3.2.0                 │ openHAB Add-ons :: Bundles :: Modbus Binding
256 │ Active │  80 │ 3.2.0                 │ openHAB Add-ons :: Bundles :: E3DC Modbus Binding
258 │ Active │  80 │ 3.2.0                 │ openHAB Add-ons :: Bundles :: Modbus SBC Binding
275 │ Active │  80 │ 3.2.0                 │ openHAB Core :: Bundles :: Modbus Transport
openhab> list -s | grep nrjavaserial
249 │ Active │  80 │ 5.2.1                 │ nrjavaserial

Your Things settings look reasonable.
See another user’s working setting here -

Start with one at a time, simplify your problems.

Better, but not “fixed” I think.
The underlying issue is that it isn’t very good at recovering from errors.
So first try to reduce those serial errors - pay attention to cabling and termination.

I am no expert at all, just can tell what I did and which sources I’ve used.
Did used a usb-RS485 adapter first as well, but later moved to a USR-TCP232-410S. Not sure what was the exact reason, but I think it had something to do when moving from 1 SDM120 to 3 pcs.
At the end, I don’t think the problem was with the USB device, but me being incompetent :sweat_smile:

I used the instructions in this post.

About the strange values, it worked for me fine with the .thing file where rossko57 linked to. You can compare them with your settings, but I don’t see really any differences.