Modbus read value appears with wrong value in sensor

I have an issiue, where a Modbus slave is returning wrong values. If I test with a modbus program. I get a 5 digit value 5xxxx. This is expected.

My sensor in Homeassistant. Is showing a negative value of -7xxx.

I have 2 identical devices, and one of them shows correctly, one of them does not. I’ve tried deleting the sensor, renaming, also renaming the modbus device. Tried reading a different holding register, that holds the same value but with no luck. It keeps showing this wrong value.

The weird thing is, when the value in the modbus device increases, so does the read value in home assistant. So it seems like, it reads the correct value, but shows the wrong value. Tried deleting the sensor, tried resetting statistics. All efforts has failed.

Can anyone give me a hint, what to try next.

Tried changing the datatype. from default, to all other options, the result in HA is the same. Enabled debugging, but the log shows no errors.

Skærmbillede 2023-08-23 kl. 07.30.09

Is everything identical?

  • Device settings
  • Interfaces (eg any serial to tcp converters)
  • Any scaling, offset, byte swap

Can you read any correct values at all from the “bad” device?
Can you try and swap anything in between the device and HA?

Both Are the Same ND Meter Cube 400. They are connected in the same switch. The Registers, firmware ect. Are Identical. It has been working earlier.

The only thing that I think might have something to do with it, was that I needed to Restore the HA Appliance. And it was then offline for 14 days.

Nothing has ever changed. It’s running Modbus TCP. Below is the Snippet of the config on both meters, be aware, that all the datatype and all differences, are added by me trying to debug it.

  - name: 40007_515_Total_kWh
    unique_id: 40007_515_Total_kWh
    slave: 1
    address: 515
    input_type: holding
    unit_of_measurement: kWh
    device_class: energy
    state_class: total_increasing
    scan_interval: 5
  - name: 40007_515_Total_kWh
    unique_id: 40007_515_Total_kWh
    slave: 1
    address: 515
    input_type: holding
    unit_of_measurement: kWh
    device_class: energy
    state_class: total_increasing
    scan_interval: 5

Let’s say the device value is 51234 and HA value then shows -73456

  • If device value change to 51235, what will HA show?
  • Have you find any common pattern between the device value and Home Assistant value? Eg offset or byte swap.
  • Have you tried to set offset=0, scale=1, swap=none just in case, although that is the default?
  • If you change offset/scale/swap, does it behave as expected based on the received value?

If the device change to 35, the negative value will be 73455, so it will “rise” with 1.

It seems like the modbus readout is correct as the value rises with the actual modbus value. Just like it starts from a Negative number instead of 0.

I’ll try the rest now.

Just set scale swap ect. No change. But I noticed a weird thing. The Test sensor that reads another register, that shows the same value, is also negative, but another digit.

I needs to be mentioned, that the other registers I read from the same device works fine. Here’s all the yaml behind the device.

- name: "40008_new"
  type: tcp
  host: 172.16.100.8
  port: 502
  sensors:
  - name: 40008_Power_All_Total
    slave: 1
    address: 2816
    input_type: holding
    unit_of_measurement: kW
    device_class: power
    state_class: measurement
    count: 1
    scale: 0.1
    offset: 0
    scan_interval: 5
  - name: 40008_Power_P1_Total
    slave: 1
    address: 2823
    input_type: holding
    unit_of_measurement: kW
    device_class: power
    state_class: measurement
    count: 1
    scale: 0.1
    offset: 0
    scan_interval: 5
  - name: 40008_Power_P2_Total
    slave: 1
    address: 2826
    input_type: holding
    unit_of_measurement: kW
    device_class: power
    state_class: measurement
    count: 1
    scale: 0.1
    offset: 0
    scan_interval: 5
  - name: 40008_515_Total_kWh_Final
    unique_id: 40008_515_final
    slave: 1
    address: 515
    input_type: holding
    unit_of_measurement: kWh
    device_class: energy
    state_class: total_increasing
    scan_interval: 5
    count: 1
    data_type: string
    scale: 1
    offset: 0
    swap: none
  - name: 40008_test_2
    unique_id: 40008_test_2
    slave: 1
    address: 7681
    #input_type: holding
    #unit_of_measurement: kWh
    #device_class: energy
    state_class: measurement
    scan_interval: 5
  - name: 40008_514_Total_kWh
    slave: 1
    address: 514
    input_type: holding
    #unit_of_measurement: kWh
    #device_class: energy
    state_class: total_increasing
    scan_interval: 5
  - name: 40008_Export_Total_kWh
    slave: 1
    address: 525
    input_type: holding
    unit_of_measurement: kWh
    device_class: energy
    state_class: total_increasing
    scan_interval: 5

Just set scale swap ect. No change. But I noticed a weird thing. The Test sensor that reads another register, that shows the same value, is also negative, but another digit.

int16 vs uint16

I’ve just beat you by 1 minute. Uint16 was the solution. but why it’s not necessary on the other Device I just don’t get.

Is the value from that device small enough to not set the msb that will flip it negative?

I Don’t really know, But I’ll keep an eye on this.

I’m having a kind of similar problem:
I’m reading the power of a Solar Inverter via Modbus.
During night the Inverter goes off and the sensor value jumps to high negative value.
That causes problems with displaying and further calulations…

Any idea how to prevent this?

2 Likes

Same here. How to ignore these values? Filter seems not able to filter out these out of range values.

1 Like

Her is our code that has been reading from the cube 400 for a very long time.
Hope it helps.

- name: CubeMeter
  type: tcp
  host: 10.10.1.149
  port: 502
  sensors:
    - name: "Office Main incomer"
      slave: 2
      address: 514
      input_type: holding
      data_type: int32
      scale: 0.1
      precision: 1
      unit_of_measurement: "kWh"
      device_class: energy
      state_class: total_increasing