Read bitmask value of register in Modbus sensor

Hi Peter,
thanks for your fast reply. The listet entities is exactly what I’m missing.
For the sake of clarification here my snip from configuration.yaml:

modbus:

  • name: E3DC
    type: tcp
    host: 192.168.99.70
    port: 502

sensors:

  • platform: modbus
    scan_interval: 10
    registers:
    • name: E3DC_solar_power
      slave: 1
      unit_of_measurement: W
      register: 40068
      hub: e3dc
      device_class: power
    • name: E3DC_battery_power
      slave: 1
      unit_of_measurement: W
      register: 40070
      hub: e3dc
      device_class: power
    • name: E3DC_battery_soc
      slave: 1
      unit_of_measurement: ‘%’
      register: 40083
      data_type: uint
      hub: e3dc
      device_class: battery
    • name: E3DC_power_consumption
      slave: 1
      unit_of_measurement: W
      register: 40072
      hub: e3dc
      device_class: power
    • name: E3DC_grid_power
      slave: 1
      unit_of_measurement: W
      register: 40074
      hub: e3dc
      device_class: power
    • name: E3DC_emergency_power_state
      slave: 1
      data_type: uint
      register: 40084
      hub: e3dc
    • name: E3DC_EMS_state
      slave: 1
      data_type: uint
      register: 40085
      hub: e3dc
    • name: E3DC_autarky_and_consumption
      slave: 1
      data_type: uint
      register: 40082
      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 }}”

So, pretty much like listet here in the forum. Have tried both the original register addresses as listed above and the ones with -1 offset.
Absolutely no idea, why the register-based entities (sensors) do not show up. Have a likewise config for some of the values in node red (implemented by my more capable son) and there the registers show their values.
What I’d expect/like to see as entities are the usual suspects arising form the sensor definitions in the second section. What would be a bonus add-on are the wallbox values - but that is nice to have. The core stuff is my personal must have as I not only want to visualize and store the values but also want to be able to kick off my washer, dryer etc based on E3/DC states/values.
I am like a small brown coated animal running through the forrest not seing nothing …
Thanks.

a) have you enabled the modbus interface on your E3DC?
b) have you set the modbus spec to use also to E3DC (on your E3DC device)? If you have set it to “sunspec” it won’t work, since this spec doesn’t expose all the desired registers.

Hi da-anda (is there btw da-oa as well?),
yessir, ModBus is enabled, set to E3DC and IP port is 502.
In addition, checked the HA log for any error messages as such were also mentioned here.
As from the last restart the log states:
Traceback (most recent call last):
File “/usr/src/homeassistant/homeassistant/helpers/entity_platform.py”, line 199, in _async_setup_platform
await asyncio.shield(task)
File “/usr/local/lib/python3.8/concurrent/futures/thread.py”, line 57, in run
result = self.fn(*self.args, **self.kwargs)
File “/usr/src/homeassistant/homeassistant/components/modbus/sensor.py”, line 134, in setup_platform
hub = hass.data[MODBUS_DOMAIN][hub_name]
KeyError: ‘e3dc’
Was wollen uns - no idea what this tends to tell me …

Peter, da-anda, all,
clear case of “stupid me” - it was a quite simple missmatch in spelling: modbus platform E3DC vs. hub spelling e3dc. Corrected and what shall I say: works. Rest to follow.
Thanks for your contribution - at the least brought back my motivation and directed me to the right look-up. Cheers. Cool.

Hi da-anda (is there btw da-oa as well?),

seems you got the reference :+1: :laughing:

Hi all final found the bits for the status, thanks for that.

Sorry for hijacking this thread, but just if anyone is interested, because modbus to E3DC is limited and existing implementations are for specific use-cases, I wrote a lib to use the “Raw” RSCP protocol and included a command line utility to make use of it with the command_line sensor.
It requires a bit of knowledge about the Tag’s and datatypes structure, but you are not limited in what you request and how much.


It is already working fine in my home assistant setup. The utility combined with jq let you even do almost anything.
Feedback and contributions are always welcome :wink:
1 Like

@grandslam there already is a python based RSCP lib for E3DC around on github which we could use for a “native” HA component, but I lack the python knowledge to write such an integration. https://github.com/fsantini/python-e3dc/

Yes I know that one already, also contributed to it to include some Quattroporte specific stuff and specific case of my setup.
Also there are some others C-based with specific use cases.
But none of them allow the raw communication as command line utility for easy integration without python knowledge.
I have now complete control just by using the HA command_line platform and can use it also outside from HA.

Side note: also needed a reason to learn go :wink:

Maybe a little bit offtopic, but I have successfully integrated the mod bus read outs from my E3DC, creating multiple sensors for the current power (solar, battery, grid and home) in Watts.
Is it possible to track the energy consuption [Wh] using this information? I came across the utility meter integration, which would track Wh per day, week, year, but as an input already requires a sensor providing information in Wh.

My first step would be to understand how the home consumption can be tracked via an utility meter. Secondly the engery bought from grid over time would be interesting to track. Here the sensor could have positive and negative values (depending on if energy is sold, or bought).

well, shouldn’t you be able to convert W into Wh by creating a template sensor that multiplies the sensor value in W with the update interval of the sensor value (about the timerange this power has been consumed)? Like if the sensor is updated every 2 seconds (not sure wthat the actual interval is), it would be 400 (W) / 3600 (seconds per hour) * 2 (duration in seconds, aka the update interval) = 0,22 Wh or something like that.

It won’t be super accurate since your accuracy is limited to the update interval of the sensor values, but at least should give you compareable results for personal information. The value likely will differ from what you actually have to pay for.

Hello all,

i am preparing home assistant (i am new with HA) to check if everything what i have so far in iobroker can be done also on HA. i found this thread about my e3dc s10 system but i dont get it working. to be honest, i dont know why. i put in the example from lanciafulvia but HA says something about sensor is wrong. maybe formating of text wrong? i played with the formating and got different errors or not. in case of not HA stucks on the proof process.

On logs i found this probem and thats where i stuck:
Logger: aiohttp.server
Source: helpers/config_validation.py:737
First occurred: 13:39:13 (1 occurrences)
Last logged: 13:39:13

Error handling request
Traceback (most recent call last):
File “/usr/local/lib/python3.8/site-packages/aiohttp/web_protocol.py”, line 422, in _handle_request
resp = await self._request_handler(request)
File “/usr/local/lib/python3.8/site-packages/aiohttp/web_app.py”, line 499, in _handle
resp = await handler(request)
File “/usr/local/lib/python3.8/site-packages/aiohttp/web_middlewares.py”, line 119, in impl
return await handler(request)
File “/usr/src/homeassistant/homeassistant/components/http/security_filter.py”, line 56, in security_filter_middleware
return await handler(request)
File “/usr/src/homeassistant/homeassistant/components/http/request_context.py”, line 18, in request_context_middleware
return await handler(request)
File “/usr/src/homeassistant/homeassistant/components/http/ban.py”, line 74, in ban_middleware
return await handler(request)
File “/usr/src/homeassistant/homeassistant/components/http/auth.py”, line 135, in auth_middleware
return await handler(request)
File “/usr/src/homeassistant/homeassistant/components/http/view.py”, line 131, in handle
result = await result
File “/usr/src/homeassistant/homeassistant/components/config/core.py”, line 29, in post
errors = await async_check_ha_config_file(request.app[“hass”])
File “/usr/src/homeassistant/homeassistant/config.py”, line 904, in async_check_ha_config_file
res = await check_config.async_check_ha_config_file(hass)
File “/usr/src/homeassistant/homeassistant/helpers/check_config.py”, line 225, in async_check_ha_config_file
p_validated = platform_schema(p_validated)
File “/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py”, line 272, in call
return self._compiled([], data)
File “/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py”, line 594, in validate_dict
return base_validate(path, iteritems(data), out)
File “/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py”, line 386, in validate_mapping
cval = cvalue(key_path, value)
File “/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py”, line 817, in validate_callable
return schema(data)
File “/usr/src/homeassistant/homeassistant/helpers/config_validation.py”, line 486, in verify
return cast(dict, schema(value))
File “/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py”, line 272, in call
return self._compiled([], data)
File “/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py”, line 594, in validate_dict
return base_validate(path, iteritems(data), out)
File “/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py”, line 386, in validate_mapping
cval = cvalue(key_path, value)
File “/usr/local/lib/python3.8/site-packages/voluptuous/validators.py”, line 215, in _run
return self._exec(self._compiled, value, path)
File “/usr/local/lib/python3.8/site-packages/voluptuous/validators.py”, line 339, in _exec
v = func(path, v)
File “/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py”, line 817, in validate_callable
return schema(data)
File “/usr/src/homeassistant/homeassistant/helpers/config_validation.py”, line 737, in validator
if key in config:
TypeError: argument of type ‘NoneType’ is not iterable

looks like your configuration is not formatted correctly. YAML needs correct indention (2 spaces per indention level, no tabs).

Btw, the modbus integration now requires a new config structure, all sensors etc within the modbus domain and not each respective sensor domains. So it now is following the new, required HA component structure. My current config looks like this:

Main modbus config

modbus:
  - name: e3dc
    type: tcp
    host: 192.168.0.XXX
    port: 502
    sensors:
      - name: E3DC solar power
        unit_of_measurement: W
        address: 40067
        device_class: power
      - name: E3DC battery power
        unit_of_measurement: W
        address: 40069
        device_class: power
      - name: E3DC battery soc
        unit_of_measurement: '%'
        address: 40082
        data_type: uint
        device_class: battery
      - name: E3DC power consumption
        unit_of_measurement: W
        address: 40071
        device_class: power
      - name: E3DC grid power
        unit_of_measurement: W
        address: 40073
        device_class: power
      - name: E3DC emergency power state
        data_type: uint
        address: 40083
      - name: E3DC EMS state
        data_type: uint
        address: 40084
      - name: E3DC autarky and consumption
        data_type: uint
        address: 40081
      - name: E3DC string 1 power
        data_type: uint
        address: 40101
        device_class: power
        unit_of_measurement: W
      - name: E3DC string 2 power
        data_type: uint
        address: 40102
        device_class: power
        unit_of_measurement: W
      - name: E3DC powermeter 1 L1
        data_type: int
        address: 40105
        device_class: power
        unit_of_measurement: W
      - name: E3DC powermeter 1 L2
        data_type: int
        address: 40106
        device_class: power
        unit_of_measurement: W
      - name: E3DC powermeter 1 L3
        data_type: int
        address: 40107
        device_class: power
        unit_of_measurement: W

Some binary sensors to prettify some of the modbus values

binary_sensor:
  - platform: template
    sensors:
      e3dc_emergency_power_possible:
        friendly_name: "E3DC Emergency Power possible"
        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 }}"
      e3dc_emergency_power_active:
        friendly_name: "E3DC Emergency Power Mode Active"
        value_template: "{{ is_state('sensor.e3dc_emergency_power_state', '1') }}"
      e3dc_emergency_power_available:
        friendly_name: "E3DC Emergency Power Available"
        value_template: "{{ is_state('sensor.e3dc_emergency_power_state', '1') or is_state('sensor.e3dc_emergency_power_state', '2') }}"
        device_class: "power"

And finally some sensors which I use in conjunction with the power-distribution card

sensor:
  - 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') }}"
2 Likes

thx very much da-anda, indeed, it was the formatting. i did a quick test and everything looks fine so far.
Danke! :slight_smile:

Wohoo!

Nice!
Config valid, i get the e3dc states et all, but no data:

2021-05-18 17:51:27 ERROR (SyncWorker_9) [homeassistant.components.modbus.modbus] Pymodbus: Modbus Error: [Connection] ModbusTcpClient(10.2.1.10:502): Connection unexpectedly closed 0.000040 seconds into read of 8 bytes without response from unit before it closed connection

Port is open, tho:

nmap 10.2.1.10 -p 502
Starting Nmap 7.80 ( https://nmap.org ) at 2021-05-18 17:52 CEST
Nmap scan report for 10.2.1.10
Host is up (0.00037s latency).

PORT STATE SERVICE
502/tcp open mbap

Any advice, please? :slight_smile:

do you get no data at all or just some? Please make sure that the Modbus mode in your E3DC is NOT(!) set to “sunspec mode”, as that one will only provide a fraction of the data. No idea otherwise though.

Good push in the right direction:

Turns out the querying server must be in the same subnet as the e3dc, else RST is sent.
NAT’ed the query; bam works :slight_smile:

Hey,

is it somehow possible to enable the new Energy Grid thing with this?

Sure, you need to create some specific sensors and integration sensors, but it does work. See this topic for some hints. At the time of this topic there was no support yet for the batteries. These require further sensors to be created.

But do not expect a perfect accuracy compared to the E3DC Webinterface. For it to be accurate, we’d need direct access to the energy values (kWh) instead of the power read outs. I opened a ticket with E3DC and requested an update to the Modbus interface. Maybe if enough people request this feature, they will be willing to adapt.

WOW, just WOW
exactly what i was looking for. Thank you da-anda!

What is important to know is that E3DC Modbus ONLY accepts traffice from the same subnet.

  • Set up NAT/masquerade
  • Move to the same subnet

Now it is working fine.
thank you for your efforts!
much appreciated.

Legi,
would you mind to share the YAML Code for your lovely chart of the Fotovoltank?

Locks like the one i can see from e3dc.
Would love to have this as well.
thanks
armin