Ha_openems: FEMS and OpenEMS integration

Hello everybody,

I started with the implementation of a Fenecon FEMS & OpenEMS integration for Home Assistant.
The current status can be considered a first alpha version which:

  • Can be set up via the Home Assistant UI
  • Retrieves all devices (implementation is ready to handle multi-edge and single-edge configuration. Currently, only single-edge setup is tested)
  • Retrieves every channel from the connected system and creates according entities
  • Update FEMS configuration options. Currently limited to support only boolean properties
  • Currently, there is a hard-coded list of ~50 channels whose entities are enabled by default. All other entities are created, but disabled by default. Every entity can be enabled and disabled via the Home Assistant UI
  • Enabled entities are updated in Home Assistant as soon as OpenEMS pushes updates via the WebSocket connection. Currently, there is no throttling, but it could be easily added if necessary for performance reasons in Home Assistant.
  • There is currently no limitation how many channels can be enabled in parallel. The by default enabled 50 entities represent exactly as what also the WebUI subscribes to after the login. However, be careful with expanding to very large numbers. I don’t know what amount OpenEMS can handle (or if these subscription have a performance relevance at all)

To install, you need to add the following Repo in HACS: GitHub - Lamarqe/ha_openems: Home Assistant Integration for FEMS and OpenEMS
But be warned, this is currently only an alpha version status.

Currently missing / next steps:

  • Proper documentation
  • As I want to control my Wallbox settings via Home Assistant, I am working on the possibility to update component configs (in a generic way). For a generic implementation, it requires an extension to be merged, but I might simply hard-code the missing generic information for the Wallbox use-case.
  • Once this is done, I will most likely re-structure the code to improve the quality and maintainability. The current implementation is mostly a quick hack of 2-3 nights in order to evaluate feasibility and gather some feedback.

I also got started in including the OpenEMS and FEMS logos in Home Assistant. As this is still in progress, the Integration currently shows up without a logo.

3 Likes

As there is the question about the WebSockets API which I use in the project:

Well if it really is a public API, then there should be some kind of documentation. There once was a website about the Websocket API in the Documentation, but it always said “todo” and was later removed.

As OpenEMS is open source and the code is not too complex, I simply use a combination of:

  • Trace the websocket communication in the browser console → its very easy and clear.
  • The corresponding OpenEMS implementation to look up some details: OpenEMS requests

I don’t think it needs more…

1 Like

:man_facepalming: You are of course right. Even though it’s not possible to set parameters like reserve SoC via REST-API, I should have just checked the web socket traffic - my bad!

Even though this API is public accessible and can be fixed up when reading in the right place I won’t consider it a API for the public. It’s a system they use but they could also change or remove it - which they obviously won’t unless they re-write the GUI entirely, so nothing to worry about.

Very nice find, I will definitely follow your progress. I like the tight integration into home assistant and the ability to enable various channels by just enabling entities. Being able to also control the system from within home assistant would remove the need to switch between apps when changing some basic settings (like your mentioned Reserve SoC or, more often for me, the Wallbox setting to manually charge!).

One thing that I wonder: Is there a potential migration path from fenecon2mqqt? I am running fine with it for a long time and would hate losing my sensor data, so if your unique names match the ones I already have, all data should be preserved?

I have a Fenecon Home 10 with a Keba Wallbox integration and some Fenecon Apps running.

Just installed the integration, looks fine:

He found all the wallbox entities too:

Installed the app, worked just fine. Tried to enable a new entity which also seemed to work. Noticed all sensors went into unknown state for a short time then came back. No idea what that means but something I noticed.

With how this is setup I understand that keeping old sensor data is probably not possible. Gaining the ability to control my system from Home Assistant on the other hand might make the switch worthwhile. Keep at it, I will follow up!

I would second TheSerapher for a migration feature to keep the existing sensor data. That would be fantastic.

1 Like

All my statistic dashboards are based on historical data, it would really suck losing all that :smiley: Seeing the integration adds a lot of new devices with the FEMS ID as prefix, maybe a configuration option could be added that allows for a migration path - not necessarily migrating all data to new names but maybe just storing sensors under the unique names that already exist?

EDIT: I am guessing but with a config option and some fiddling this could be modified to match existing unique_ids and make a migration possible? That would be awesome and make a move over a lot less painful: ha_openems/custom_components/openems/sensor.py at 9592dd532d274129bf0261263d7e817571cc4315 · Lamarqe/ha_openems · GitHub

I’d not count on that being merged anytime soon. Probably “best” to hard-code for now and replace later if and when they add your extension to the base code.

Man, your 2-3 nights of coding have accomplished more than I ever did in my months of owning the system! I will test if you need some help, Fenecon Home 20 with Keba Charger.

Last but not least one more Wishlist item: Maybe the sensor names can be somehow automatically switched from CamelCase to a more appropriate “Camel Case” with whitespaces. I find it much easier on the eye and how the sensors are displayed in various places (e.g. legends on graphs).

Could be useful, but the great thing about this integration compared to fenecon2mqtt is that you can finally change the entity id and name of the entites without it getting wiped after every restart…

That alle the entities go unknown for a moment is normal when you enabled a new (other) entity in the integration btw.

Fair point! But if this could be automated it would mean I don’t have to rename every single entity :smiley:

Another advantage that might come into play, when restarting the add-on it happens that diffs (Edit: Group By in ApexCharts on my charts) between energy readings suddenly spike to the current reading of the sensor. Probably something of the past as well.

Thanks for the clarification, I thought it was something like that.

Hi Everyone,

First of all, thank to everybody for your positive feedback. That’s super motivating. Happy to see that I am not only doing myself a favor here.

Regarding retaining the entity data: @TheSerapher is right. Its about the unique IDs. I see 2 options:

  1. Align my integrations unique IDs with those of Fenecon2Mqtt. I don’t know the naming scheme of Fenecon2Mqtt (I never installed it myself). Can somebody share? I will consider it as a viable option if I can (technically) do the same and want (does it make sense?) to.
  2. Users need to manually migrate the data using some update statements in the database. Its doable and no super complex: Migrate energy statistics from one entity to another - #7 by BrentV (but of course its more than just some random clicks in a ready UI).

Regarding my PR for OpenEMS, I am confident it will get merged.

Regarding the current naming pattern: I use 1:1 the channels names as they come from the backend. And due to HomeAssistant rules, default names are aligned with sensor IDs. See the statement about property has_entity_name here. For design reasons, I want to keep the sensor IDs aligned with the channel IDs. Users will have to manually change the names (as correctly explained by @benniju)

I intend to maintain a ranked ToDo list in the repo Readme so everybody knows what to expect sooner and what later (or possibly even never :frowning: ). Please note that I am working on this topic only during late evenings for limited time (father of 3 and full-time professional in a relevant position).

1 Like

Here a sample Entity ID (and probably it’s Unique ID): sensor.battery_inverter_fems_sum_essdischargepower

They call come with a battery_inverter prefix, followed with fems and then the channel address split by _. I can see that this might not be what you want for your integration since it does include device names so maybe database migrations are what it takes. I’ve had bad experience with trying to tinker with the statistics database so I’d rather avoid doing that myself :smiley: But what’s a backup for if you don’t give it a shot! Maybe it’s possible to supply users with proper queries for all sensors (they all follow the pattern above)?

I agree on the naming itself but as far as I can tell it just means you shouldn’t include the device name (e.g. FEMS Production Active Power) but it doesn’t mention the entity name has to match the unique ID exactly? So moving from a CamelCase name to the same thing with Whitespaces should be OK since it would just describe what the sensor actually does. I might be wrong here and just trying to avoid manual work for users.

You certainly aren’t just doing it for yourself - after all there was no native integration around for a while and you might just fill that spot :slight_smile:

Its about sensor IDs (visible to Users, used for searching entities), not Unique Ids (internal IDs, not visible in the UI). When I change the default name, I implicitly change the sensor ID. And this I dont want to do, as I want to keep the sensor ID aligned with the channel ID, as I want to make sure that users find the correct entity, when they copy the channel ID from somewhere.

Regarding the Fenecon2mqtt naming scheme: Sorry folks, I wont do it. It leaves out the edge ID. That will lead to conflicts which cannot be resolved for users who are using an OpenEMS system with multiple edges. (If you don’t know what it means, please check the OpenEMS docs).

All valid points, I went ahead and enabled all sensors that were hidden but which I am using already in various places. Found a few that are not being added because it’s some internal thing from Fenecon but I found the useful. Format is from fenecon2mqqt but you get the idea :slight_smile:

## Displayed in the frontend, wanted to access this in Home Assistant as well
- channel: _meta/IsEssChargeFromGridAllowed
  name: Battery Charge From Grid Allowed

## When FEMS fails to send data back upstream, this state changes, used for monitoring, causes the overall state to also go in Warning, made finding the reason easier.
- channel: ctrlBackend0/State
  value_template: >
    {% set text = {
      0: 'Ok',
      1: 'Info',
      2: 'Warning',
      3: 'Fault'} %}
    {% set state = value | int %} {{ text[state] if state in text.keys() else
    'Unknown' }}
  name: Backend Connection State

## External limitation set by the power grid operator. Not something that can be done already on my system but shown in the frontend so I wanted access to it in HA.
- channel: ctrlEssLimiter14a0/RestrictionMode
  value_template: >
    {% set text = {
      0: 'No external limitation',
      1: 'Externally limited' } %}
    {% set state = value | int %} {{ text[state] if state in text.keys() else
    'Unknown' }}

## Same for this, just so I can access via HA
- channel: ctrlGridOptimizedCharge0/State
  value_template: >
    {% set text = {
      0: 'Ok',
      1: 'Info',
      2: 'Warning',
      3: 'Fault'} %}
    {% set state = value | int %} {{ text[state] if state in text.keys() else
    'Unknown' }}
  name: Grid Optimized Charge State
- channel: ctrlGridOptimizedCharge0/_PropertyEnabled
  name: Grid Optimized Charge Enabled

## Not sure if this is still used, found in config nevertheless
- channel: ctrlEvcs0/_PropertyEnabledCharging
  name: EV Charging Station Charging Enabled

I also monitor ALL my battery towers individual cells, voltages and temps (for statistic tracking) without any issues. But now I have to go through them all and enable each individual sensor :smiley: Scratch that, forgot I can multi-select …

- channel: battery0/Tower0Module0Cell000Voltage
  name: Tower 0 Module 0 Cell 000 Voltage
  device_unit: mV
- channel: battery0/Tower0Module0TemperatureSensor1
  name: Tower 0 Module 0 Temperature Sensor 1
  device_unit: °C
## Temp is reported as dC or something weird, just made it so HA recognises it properly as a unit.
  value_template: "{{value | int / 10}}"

In any case, I will leave this running and start collecting data! Luckily my last reset is just a month ago so it won’t hurt me as much, just sad to see data go away :smiley:

I don’t generate entities (not even disabled ones) of channels which are part of a device that does not specify an “Alias”. (see here) Thats a pretty random decision, admittedly. However, it reduced the number of entities which I generate in Home Assistant for my FEMS system by 50%. I simply tried to find a pattern which allowed me to not generate so many entities.

So I assume that the missing entities are exactly part of such devices.

  1. All channel names starting with _Property should be created in the future as these represent device properties which can be updated (thats the still missing implementation to update a device property). So its not an intended behavior. Its simply a missing feature.
  2. I can also add a debug property which allows to generate entities for channels of devices without an alias. But not a priority for now.

Sounds fine - I can easily wait for the implementation and use the add-on to read those specific values for now (but removing all the others I won’t need anymore).

I can see how this could be useful but I like my “live data” a lot and having this data up-to-date at all time helps me in a few places (custom energy meters for example). If this needs to be added maybe it could be a configuration option that defaults to its current behaviour but can be set by those who want data to be throttled.

Added some filtered sensors myself to achieve the same result and use those were I don’t need up-to-date information (e.g. battery charge durations, no need to change it every second :smiley:)

As people started to use the current version, I have tagged the current status with release v0.1.0
Everybody who installed the integration earlier today should receive an update notification. But there is no change in this release compared to the commit ID based installation earlier today.

1 Like

Found an issue in the logs:

Entity sensor.fems72404_meter0_frequency (<class 'custom_components.openems.sensor.OpenEMSSensorEntity'>) is using native unit of measurement 'mHz' which is not a valid unit for the device class ('frequency') it is using; expected one of ['GHz', 'Hz', 'MHz', 'kHz']; Please update your configuration if your entity is manually configured, otherwise report it to the author of the 'openems' custom integration