Read bitmask value of register in Modbus sensor

Hi. I’m working on the integration of my PV system into HA. My PV battery unit has a modbus interface to read the values from. I managed to get most of the desired values displayed in HA except for one particular register. The register is holding a bitmask UINT16 value and each of the bits (0-6) represent a boolean state of a sensor (on/off). Any idea how I can tell HA to use a specific bit for a sensor entity?

1 Like

A template sensor will be able to extract the information.

You are already extracting the value using a modbus sensor ?
And can you give an example of the sensor data please ?

Hi. Yes, I am already extracting the value of the modbus sensor. A sample value would be “4”, which in this case means that bit 2 is set to true.

Here a overview of the bits and their values:
bit -> value when set
0 -> 1
1 -> 2
2 -> 4
3 -> 8
4 -> 16
5 -> 32
6 -> 64

so when bits 0 and 3 are “true”, the value of the register would be 9. So it’s an ordinary integer based bitmask.

1 Like

so i spent some more time on this and TBH, I don’t see any other way to get this working in a sane way than to adding a bitmask filter to the homeassistant sensor component. It’s a one-liner to do this operation in python but a huge PITA via Jinja or whatever else

ok, just found the bitwise_and filter extension from HomeAssistant and it seems to work using that. Phew - that was a tough one to figure out :slight_smile:

1 Like

Well done ! :+1:

Hello da-anda
could you please so kind and share your template with the bitwise_and() filter.
I have nearly the same to do for the EMS state of my S10 Battery.
I also get the modbus value bit I’m not able to get the bits status extracted.

What I have is the value extracted:

  ems:
    friendly_name: "EMS"
    unit_of_measurement: 'Status'
    value_template: '{{ states.sensor.ems_status.state | int%256  }}'

but how may I use the bitwise filter on it ?

Thank you in advanced.

sure, this is my sensor setup

binary_sensor:
  - platform: template
    sensors:
      e3dc_emergency_power_available:
        friendly_name: "E3DC Emergency Power available"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(4) > 0 }}"
      e3dc_battery_loading_blocked:
        friendly_name: "E3DC Battery loading blocked"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(1) > 0 }}"
      e3dc_battery_unloading_blocked:
        friendly_name: "E3DC Battery unloading blocked"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(2) > 0 }}"
      e3dc_weather_based_loading:
        friendly_name: "E3DC weather based loading limiter"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(8) > 0 }}"
      e3dc_power_limiter:
        friendly_name: "E3DC power limiter"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(16) > 0 }}"
      e3dc_smartcharge_loading_blocked:
        friendly_name: "E3DC SmartCharge loading blocked"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(32) > 0 }}"
      e3dc_smartcharge_unloading_blocked:
        friendly_name: "E3DC SmartCharge unloading blocked"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(64) > 0 }}"
6 Likes

Thank you very much. That is exactly what I was looking for.
You are the best !!!

Hey, thanks for sharing this! I’m pretty new to HA and struggle a lot with my E3DC. If you don’t mind would it be possible the share the implementation of the other values as well?
Thanks a lot!

1 Like

+1 for sharing your archivements

Hey, sorry, must have missed the notification about your reply. You still need help with the other values?

sensor:
  - platform: modbus
    registers:
      - name: E3DC solar power
        unit_of_measurement: W
        register: 40067
      - name: E3DC battery power
        unit_of_measurement: W
        register: 40069
      - name: E3DC battery soc
        unit_of_measurement: '%'
        register: 40082
        data_type: uint
      - name: E3DC power consumption
        unit_of_measurement: W
        register: 40071
      - name: E3DC grid power
        unit_of_measurement: W
        register: 40073
      - name: E3DC emergency power state
        data_type: uint
        register: 40083
      - name: E3DC EMS state
        data_type: uint
        register: 40084
1 Like

I have just started using home assistant, having received my raspberry pi just yesterday I am trying to add all available integrations to the setup.
I have a E3DC S10 Mini inverter in my network and noticed that there is no standard integration available. I stumbled upon this forum entry and am now trying to follow up and integrate the E3DC via Modbus.
I crosschecked the registers with the documentation that is available in the E3DC Webinterface.
I have enabled the Modbus on the E3DC itself.
Now I was trying to add the Modbus, the sensor and binary sensor as described in this thread to the configuration.yaml, however the sensor data is not available in home assistant. Guess I have either made a mistake in the config, or it is not retrieving information from the inverter. IP and Port are correct. Where could I start to investigate the issue?

modbus:
  - name: E3DC
    type: tcp
    host: 192.168.0.195
    port: 502

sensor:
  - platform: modbus
    registers:
      - name: E3DC solar power
        hub: E3DC
        unit_of_measurement: W
        register: 40067
[...]

Edit: I did find a home-assistant.log file indicating that Modbus is not able to setup the connection to the inverter…

2020-10-08 19:48:20 ERROR (SyncWorker_22) [pymodbus.client.sync] Connection to (192.168.0.195, 502) failed: [Errno 111] Connection refused

Still struggling to solve it though. So if anyone has made similar experience, I’d be glad for support

please note that at least for me the registers were off by -1, so you have to use 40066 in HA when the documentation says 40067. And you should enable the E3DC mode for Modbus and not the other one in the S10.
No idea about the connection issue though.

Issue has been solved. Somehow the Modbus was still deactivated on the E3DC, although I thought that I activated it. Everything seems to work as expected. Thanks for the reply and the help for integration.

FYI, I added the autarky and consumption ratio sensors to my setup in order to be able to use this gem for Lovelace: https://github.com/JonahKr/power-distribution-card

My new sensor setup looks like this:

sensors:
  - platform: modbus
    registers:
      - name: E3DC solar power
        unit_of_measurement: W
        register: 40067
        hub: e3dc
        device_class: power
      - name: E3DC battery power
        unit_of_measurement: W
        register: 40069
        hub: e3dc
        device_class: power
      - name: E3DC battery soc
        unit_of_measurement: '%'
        register: 40082
        data_type: uint
        hub: e3dc
        device_class: battery
      - name: E3DC power consumption
        unit_of_measurement: W
        register: 40071
        hub: e3dc
        device_class: power
      - name: E3DC grid power
        unit_of_measurement: W
        register: 40073
        hub: e3dc
        device_class: power
      - name: E3DC emergency power state
        data_type: uint
        register: 40083
        hub: e3dc
      - name: E3DC EMS state
        data_type: uint
        register: 40084
        hub: e3dc
      - name: E3DC autarky and consumption
        data_type: uint
        register: 40081
        hub: e3dc
  - platform: template
    sensors:
      e3dc_autarky:
        friendly_name: 'E3DC Autarky'
        unit_of_measurement: '%'
        value_template: "{{ (states('sensor.e3dc_autarky_and_consumption')|int / 256)|round(0,'floor') }}"
      e3dc_own_consumption:
        friendly_name: 'E3DC Own Consumption ratio'
        unit_of_measurement: '%'
        value_template: "{{ ((states('sensor.e3dc_autarky_and_consumption')|int / 256 - states('sensor.e3dc_autarky')|int) * 256)|round(0,'floor') }}"

binary_sensor:
  - platform: template
    sensors:
      e3dc_emergency_power_available:
        friendly_name: "E3DC Emergency Power available"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(4) > 0 }}"
      e3dc_battery_loading_blocked:
        friendly_name: "E3DC Battery loading blocked"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(1) > 0 }}"
      e3dc_battery_unloading_blocked:
        friendly_name: "E3DC Battery unloading blocked"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(2) > 0 }}"
      e3dc_weather_based_loading:
        friendly_name: "E3DC weather based loading limiter"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(8) > 0 }}"
      e3dc_power_limiter:
        friendly_name: "E3DC power limiter"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(16) > 0 }}"
      e3dc_smartcharge_loading_blocked:
        friendly_name: "E3DC SmartCharge loading blocked"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(32) > 0 }}"
      e3dc_smartcharge_unloading_blocked:
        friendly_name: "E3DC SmartCharge unloading blocked"
        value_template: "{{ states('sensor.e3dc_ems_state')|int|bitwise_and(64) > 0 }}"

Thank you for the update, this looks briliant.

Seems to be solved - sunspec was chosen instead of E3DC. I now have values :smile:
Hi all, I’m a very basic user of HA. I managed some Integrations and now try to integrate my E3DC S10 Pro. I did some basic register entries in the config.yaml.
It seems that I got some steps in the right direction. I get entities but incorrect or no values.
eg. actual solar power is 2659 but I get 0.
There is a message (translated it from german) This entity in not unique…

Would be great if I could get any hints.

modbus:
  name: e3dc
  type: tcp
  host: 192.168.1.45
  port: 502

sensor:
  - platform: modbus
    registers:
      - name: E3DC Solar Hausdach
        unit_of_measurement: W
        register: 40067
        hub: e3dc
        device_class: power
      - name: E3DC Batterie
        unit_of_measurement: W
        register: 40069
        hub: e3dc
        device_class: power
      - name: E3DC Hausbezug
        unit_of_measurement: W
        register: 40071
        hub: e3dc
        device_class: power
      - name: E3DC Netzbezug
        unit_of_measurement: W
        register: 40073
        hub: e3dc
        device_class: power
      - name: E3DC Solar extern Garage
        register: 40075
        hub: e3dc
        device_class: power     

Hi Peter, all,
managed to enable the modbus connection by copying and adopting to my specifics (IP) - fine so far.
Also gave the templated sensors (binary sensors) a try - looks like they are working as well. To be honest, I have no clue of how to adopt additional (binary) sensors for the values deriving from the modbus register reads. What I’m looking for is a simple way to get sensor usable in e.g. lovelace (via power-distribution card or others) for all of the data from the modbus register(s).
In case anybody could help me on that: highly appreciated. Either directly or link or …
Thanks in advance.

I’m not sure what the problem is. Do you have these entities?


I use it now with the newest version of the power-distribution-card.