Devember Project: Writing my first Home Assistant integration:

I have never written a Home Assistant Integration. However, the Home Assistant Team have made it as easy as possible . I own an EMU M-Bus center which polls several M-Bus Power meters in my main breaker panel and offers the polled data over a REST API.

I want to consume this REST API into a Home Assistant Integration. I know there are REST sensors in HA that you can configure in YAML, but I want to get the experience of writing am Integration. Also, I’m supposed to learn Python and need a good Project to keep me motivated. The end goal is to have the Integration be able to read an arbitrairy amount of EMU Allrounder Power meters (because that’s all I have available for testing). I want to publish the Integration on the Home Assistant Community Store.

EDIT: Repo link: GitHub - redlukas/emu_mbus_center

1 Like

All right. This is the first day I am spending time with the project. I’m glad the dec31st deadline has been extended, otherwise it would probably not be possible.

Home assistant have created a nice Dev environment and guides on how to write integrations, so I’m setting up the environment and reading the documentation.

very interested, as i am in the same boat, wouls like to integrate battery storage and inverter output into home assistant

wouls like to integrate battery storage and inverter output into home assistant

do you want to do it with an integration or just via the config?

1 Like

Lesson 1: doing an integration for HACS is not the same as doing one for HA. the latter would mean a PR into the core repo. HACS have their own style guide published here and their own (optional) dev contianer here

anyway, there is now a repo.

honestly i have no idea, my homeassistant experience totals 3 hours

Okay. I strongly suggest you go the config route. in the directory where HA is installed, there is a fille called configuration.yaml. there you can define your own sensors. Depending on the interface available on your battery and inverter you’d integrate them there (if there is not already an integration for those devices).

1 Like

Next hurdle: The dev container i am using is a bit older. you must run git config --global url. git:// before you can run the task Run Home Assistant on port 9123 for the first time.

Also you should update the version pf pip that comes with it.

and lastly you need to add a “version” field to the manifest.json so your custom integration loads properly.

then the HA instance of your dev environment is available on http://localhost:9123/

I found some more resources and made some more progress. Home assistant maintains a repo with example configurations for custom components. On the one hand this is great, because it’s info straight from the horse’s mouth, on the other hand it shows just how outdated the cookiecutter template and its dev container are.

On the issue of the devcontainer: while I did get it to run yesterday, it seems that the changes made in VScode are not automatically reflected in the custom component in the HA instance of the dev container. this is an issue. So today I have set up a HA instance on a RasPi4, SCPd my custom component to it and was immediately greeted with an error. Yay, my changes get reflected, but it also meand I borked it.

Tomorrow I wont be working on this, but friday I intend to dive deeper in the framework and API provided by home assistant with the goal of getting the Installation wizard to run trough.

1 Like

I have decided to not get the config flow working first.

Instead, I want to get the integration working via a configuration.yaml entry and then add the bells and whistles.

for this simple integration, i have created a new repo.

I am following this guide among others.

The integration already gets picked up by HA, but there is an exception thrown during the loading process. I will dive into that tomorrow.

success! I have now been able to write the mini-integration so it gets picked up by HA and actually read out!

Also, it actually gets polled:

(yes I know that the readings are in Wh but they get reported to HA as being in kWh, easy fix.)

I now need to:

  1. Add the other info the REST call gives me as attributes
  2. Add all kinds of error handling and validation for the REST calls

I have now added the additional info as attributes and am now doing a fair bit of error handling for the GET requests as well as some good validation of the response. The integration now works on a basic level.

Up next:

  1. see if I can do multiple sensors with only one config entry
  2. getting the setup workflow to work

Some ways down the road:

  1. Publishing the Integration on HACS
  2. Stretch goal: Automatic discovery of new sensors

It is now possible to create multiple sensors with one config entry. This will clean up the config in a big way and also pave the way for a smooth setup workflow.

I have pivoted slightly and have released an MVP that is HACS-Compatible.

I have issued a PR to HACS so my integration gets included in their store. It seems some automated checks are still failing, i will review them next.

I have fixed the issues and uploaded some logos. The PR for the logos has already been accepted into the Home Assistant logos Repo. This means that all checks for the PR into the HACS repo now pass.

While I wait for this PR to be accepted, I will do further work on the config flow. However, the documentation I find (mostly this and this page) does not provide the level of handholding I seem to need. I am therefore looking at existing integrations to figure out what does what and which methods get called in which event.

I made some good progress on the config flow today. I had gotten stuck because I did not understand the sequence in which the methods get called.

At the root of my problem was a different one: when you switch to a config flow (as opposed to configuration via YAML), Home Assistant highly encourages you to also implement some other modernities, namely non-blocking functions and the use of a coordinator (say an API call returns a JSON with multiple values. Each of those values gets mapped to its own entity in Home Assistant. The old way would have been to either call the API for every entity you want to update or to choose one main value, create one entity for that value and put all the other values into attibutes for that one entity (which is the route I had chosen in my MVP). The Coordinator lets you make one API call and then distribute the return value to multiple individual HA entities).

I have now started doing all that. the coordinator is already working, but i have some unsolved problems with the async python, which I have zero experience with.

And for future reference, the thing I got stuck on was this: When the config_flow.async_step_user() method has run trough, the next thing that gets called is __init__.async_setup_entry() and not, as I had thought, sensor.async_setup_entry().

In have slain the beast that is async python. or at least: it works in my very narrow use case, in this very protected environment. The Sensors all get their update, from one single API call, that is even non-blocking.

and it gets picked up correctly by the recorder

My PR has beed merged, my repo is now in the default HACS list, which means it can now (or as soon as HACS has done their refresh of the reop list) be installed trough the HA UI without any weird trickery.

Meanwhile, I am still working on the config flow. I’ve gotten it to work in a way that you have to input the IP of the center and all the sensors you want to add, formatted as a python dict. that is not very user-friendly. So I have added a scanning feature that checks the center for connected sensors. I am working on incorporating that into my workflow.

EDIT: The Repo now shows up in the HACS list:

I know the logo looks atrocious. It was really done with light mode in mind:

I have already issued a PR to add dark theme logos, it is currently waiting for approval.

1 Like

I am making some progress in the Config flow. For the first time today I achieved that my prompts actually have my labels. It was not working due to two things. first: apparently, home assistant is looking for the labels in ./translations/en.json and not, as the template has suggested in ./strings.json. Second: As is documented, the frontend caches heavily. This apparently also applies to the labels (but not the entry fields themselves) of the config flow. so any time you have changed something on the labels of the config flow, you must do a full cache refresh of your browser after the restart of the home assistant instance. This is cumbersome, but now that I know it, I know what I have to do.

Lastly: As I have talked about i have incorporated a scanning feature to discover all the sensors. Now I need to figure out how I can add the Sensor ID as a label to those dynamically generated fields. My fear is rising that the correct way to do things is not to discover all the sensors during the config flow, but to implement the autodiscover flow. I really dont want to have to do this for the initial release.

I have finished the config flow, written the documentation and made a new release. All my work is now available in HACS. I have therefore reached the goal I set.

for anyone reading this in the future: I have certainly made the right decision to only publish this integration in the HACS repo and not targeting an induction into core HA. first i only had one kind of sensor to test with and to release an integration to Core that only covers a small portion of the Center’s abilities would have been ill-advised. second and more importantly for my sistuation: there are development guides that would have been hard for me to achieve. first and foremost, they dont want the integration to make calls to the center’s API directly. Instead, one must write an API wrapper, publish that to PyPi and then use that wrapper in your integration, which would have been another hurdle for me to overcome, as this is another thing I have never done.