Creating Your First Home Assistant Add-On
One of the things I like so much about the amazing Home Assistant project is its endless potential for extensibility. The core project has always supported custom components, which can easily expand the things that Home Assistant knows how to do through a bit of Python.
But sometimes, writing Python code just isn't the right way to extend the functionality. What if, for example, you want to monitor your UPS (that's Uninterruptible Power Supply in this context, not United Parcel Service - although both are extensions in the Home Assistant ecosystem!)
Yes, it's certainly possible to reverse-engineer and write the monitoring code for your unit in Python as a component inside Home Assistant. But another, and frankly better, option would be to use tried-and-tested software such as NUT (Network UPS Tools) which has been around and maintained for more than twenty years.
But NUT is written in C. How do you bundle NUT to interface with the Python code?
Short answer: You don't. Well, not directly anyway...
Enter Home Assistant Add-ons.
For the past few years, Home Assistant's distribution of choice was with an OS which runs a single piece of software: a custom-built container orchestrator, called the Supervisor (which was initially called hass.io) that runs Home Assistant as a Docker container. The Supervisor also defines a format for packaging other arbitrary containers in parallel in a way that's completely managable through the Home Assistant UI.
Because, at their core, they are Docker containers, this means that one can package virtually anything to run inside Home Assistant - and in any language, too! C, Java, Node.JS or just a bunch of shell scripts. If it runs on Linux, then it can be packaged as an add-on.
One might be daunted by the potential complexity of creating one's own add-on. I certainly was, when I first got started! How to build it? How to package it? How to expose it to Home Assistant? How to test and debug the add-on without destroying the rest of one's running smart home setup (a.k.a. don't develop on your production instance)?
Thankfully, while the process isn't completely point-and-click, it's nearly the next best thing. In this article, we're going to keep to the very basics. In the spirit of one of the most sacred and ancient customs in the world of software development education, we're going to create an add-on that writes "Hello, world!" to the add-on log and exits.
The "meat" of this add-on, will be a one-liner shell script that, predictably, looks like this:
echo Hello, world!
That's the easy part!
Now let's get on to getting that "Hello, world!" to appear inside of a running Home Assistant add-on.
While it's possible to develop the add-on completely inside an existing setup of Home Assistant (and, indeed, in the early days, that's how it was done!), there's a much simpler way to go about it using Visual Studio Code and Docker, meaning you can do it on Linux, Mac or Windows desktop environments. (Don't worry if you're not overly familiar with Docker at this point; while it's a central part of how add-ons work, and knowledge will help you craft better optimized add-ons - such as if you want to publish your add-on - you won't need any direct interaction with Docker for this project, or for simple add-ons that you make for your own use.)
Follow the instructions in the links above to download and install VS Code and Docker, and then download and install the Remote - Containers add-on for VS Code from the preceding link, and you're set to go.
The sample code for this add-on is available on GitHub at https://github.com/issacg/hassio-addon-devcontainer Let's take it for a spin, and then we'll go over the various bits and pieces.
To start, clone the above repository, and open the folder inside VS Code (???????? > ???????? ????????????). You'll be prompted shortly to re-open the project inside the container. If you don't get that prompt, then from the command palette (???????? > ?????????????? ??????????????), select ????????????-????????????????????: ?????????????? ?????? ???????????? ???? ??????????????????
VS Code will restart and create your development environment. This will take several minutes - depending on your Internet connection - the first time, but the environment will be cached and subsequent opens will be much faster. You'll know it's done when you can see the files in the left-side panel.
The next step is to start the embedded Home Assistant inside the development environment. To do so, go to ???????????????? > ?????? ??????????, and select ?????????? ????????.????
This will download and run Home Assistant using the same supervisor I mentioned above. This will setup the same runtime environment as Home Assistant running on a Raspberry Pi, a NUC, or wherever else you might be running your Home Assistant. This step will also need some time the first time you run it - same as when you'd normally run Home Assistant for the first time - to download everything.
When it's done you'll see a brand new Home Assistant instance at https://localhost:8123/
Finish the onboarding process, and go to ???????????????????? > ??????-???? ??????????. You'll see that our add-on appears at the top of the screen, under the section ?????????? ??????-??????
Click on the Add-on to go to the "Demo Addon" page, from which we can install the Add-on.
Clicking ?????????????? will setup our add-on inside Home Assistant. If all goes well, the ?????????????? button will change shortly to ??????????. Additionally, you'll see the normal ?????????????????? button, and a new button labelled ??????????????. You'll use that latter button to rebuild the add-on after making any changes to the add-on source files. For now, just click ??????????. If all goes well, in the Log panel, you'll see the desired output. (Don't worry if the ?????????? button doesn't change to the familiar ???????? and ???????????? buttons - it's intentional for this simple add-on.) Great job!!!
So how does this all work behind the scenes?
If you take a look at the source files for this add-on, you'll see that there aren't so many. While this essentially represents the bare minimum needed for creating an add-on, many add-ons truly don't need any more than these files to get the job done. Let's take them one by one and explain their individual roles.
Let's start with the ????????????.???????? file
{ "name": "Demo Addon", "version": "0.1", "slug": "myaddon", "description": "Add-on that prints 'Hello, world' to the log and exits", "url": "https://github.com/issacg/hassio-addon-devcontainer", "startup": "once", "boot": "manual", "options": {}, "schema": {}, "arch": ["amd64", "armv7", "armhf", "i386" , "aarch64"]
}
This JSON file is required by all add-ons and is used to describe to Home Assistant how to display, install, configure and run your add-on.
Let's start with aesthetics. The ????????, and ?????????????????????? fields contain the name and description to be used in the UI. The ?????????????? is used both to display a version, and, for published add-ons, to signify when an updated version of the add-on is available. The ?????? is typically the home-page or, lacking one, a link to the source code, of the add-on. The ???????? is a short string used to represent the add-on internally inside Home Assistant - one example of its use is to determine the URL of the add-on, but there are some others uses, too, behind the scenes.
The ?????????????? and ???????? fields are read by the supervisor and used to determine when and how to run the add-on. In our case, we are saying that this is a manually started script, and not a long-running daemon, and that Home Assistant shouldn't start it automatically. (For a long running daemon which runs in the background, the typical values would be "??????????????": "??????????????????????" and "????????": "????????".)
The ?????????????? and ???????????? fields are used to setup the ?????????????????????????? pane for the add-on. In our case, we have none, but as these are required fields for all add-ons, we have an empty reference for each to represent that there is no configuration.
Finally the ???????? field is used to tell Home Assistant which hardware chips our add-on is compatible with. The value we use tells the supervisor that we can run on all of the same chips that Home Assistant itself can run on, such as Intel CPUs for desktops, and ARM CPUs for systems such as the Raspberry Pi.
One other field that's typically needed by add-ons, but is intentionally omitted in ours is the ?????????? field. This is required for published add-ons and tells Home Assistant where to download the binary version of the add-on. However, when building your own add-on (or developing locally), this needs to be omitted, otherwise Home Assistant would use the pre-built add-on rather than building it locally and providing the ?????????????? button that we saw earlier.
For a complete list of the supported fields and their intended use, see the Home Assistant documentation.
echo "Hello, world!"
Next, we have the ??????????.???? file. This file is what we're actually going to run inside the add-on. In our case, it's just to echo, or print, "Hello, world!" and then it will exit. For the beginners out there, it's important to note that unlike most of the other files here, the naming of ??????????.???? is just convenience; an add-on doesn't require this filename per se. More on that in a bit...
Moving along, next we have the ????????????????????
ARG BUILD_FROM=homeassistant/amd64-base:latest FROM $BUILD_FROM ENV LANG C.UTF-8 WORKDIR / COPY start.sh /app/start.sh ENTRYPOINT ["/app/start.sh"] LABEL io.hass.version="VERSION" io.hass.type="addon" io.hass.arch="armhf|aarch64|i386|amd64"
Remember how I said above that Docker is an integral part of how add-ons work, but you don't need to sweat if you're not overly familiar with Docker? Well, this file explains to Docker how to package, or build, your add-on. This ???????????????????? essentially says to take the file start.sh that we saw above, copy it into the add-on, and execute it as the entry point of the add-on.
[For more advanced Docker users, it's also worth noting a few things. The $??????????_???????? variable is initialized inside the ???????????????????? to a specific base image, but when being built inside Home Assistant (or through the add-on builder, which is a bit advanced for this post, and so I won't cover) these will be set to appropriate base images based on Alpine which, among other things, enable qemu for cross-platform building. Also worth noting are the labels which are used internally by Supervisor to provide and validate metadata of installed add-ons.]
The ????????????.???? file, similar to its use on GitHub, is used to provide inline documentation on what the add-on is and how to configure and use it. This is written in a special format called Markdown and will be displayed on the add-on page in the UI. It's worth mentioning that in this particular case, since this sample add-on is more oriented to add-on developers as a boilerplate, rather than to add-on users, the ????????????.???? file is similarly focused on how to properly utilize the boilerplate, so you might want to look at the documentation of other add-ons for inspiration for your own ????????????.???? rather than this file ??
The ??????????????.???? file contains the end-user license for your add-on. This file name is more of a convention for GitHub repositories and isn't actually used by Home Assistant itself (yet). If you're writing an open-source add-on, then it's really important to have one of these, but if you're writing your own add-on with no intention of publishing, then this isn't needed at all.
The remaining .?????????????????????????? file as well as the .???????????? and .???????????????????????? folders are more internal plumbing to enable the development environment that we utilized and ensure that it works on Mac, Windows and Linux desktops, and we don't need to dive into the details of them.
Up until now, we've seen how to set up a development environment and build a simple add-on on our desktop computer, but how do we set things up to run on your running Home Assistant?
To do so, we need to copy these files (actually, only the ????????????.????????, ???????????????????? and the ??????????.???? are strictly necessary) to our Home Assistant machine, in a new subfolder in the /addons directory. Any name will do for the subfolder, but convention is to use the same name as defined above in the slug field of the ????????????.???????? file - so in this case, you'd create /addons/myaddon and copy the files there. [How to copy files to and from Home Assistant is a topic by itself and I won't cover it in detail, but as a starting point you might want to look at the "Samba share" or "File editor" add-ons available in the Add-on Store tab.]
Once you've copied the files, you'll need to tell Home Assistant to look for them.
To do so, go to the Add-on store tab, and on the upper right corner, click on the 3 dots, and the click on the ???????????? link. (You'll need to do the same when making changes to the ????????????.???????? file during local development, too.) The new Add-on will be displayed in Local add-ons, the same as we saw in our local build environment.
And that's all there is to it!
In this article we covered what a Home Assistant add-on is, we made a sample "Hello, World!" add-on using the VS Code IDE, and we learned how to copy the add-on to a running instance of Home Assistant running on any hardware platform. This is just scratching the surface of the world of Add-ons, though. We didn't talk about how to host an embedded web interface; how to interact with Home Assistant; how to interact with other Add-ons, or many other features that would make the add-on useful.
Know someone else that this can help? Don't forget to Like and Share the article! Did this help you? Have any questions? Leave questions or comment below, or join the #??????_???????????? channel on Home Assistant Discord.
Employee Retired telecom
1 å¹´??
congrats