<< Go back to Posts

Publishing to HACS





Introduction

This post is a tutorial to deploy a custom app on your Home-assistant setup, and sharing it with the community on HACS.

I started playing with home-assistant: I was searching for opensource software to control RGB lightbulb before buying some.

My Setup

I installed it with a simple docker compose. Just after the first launch, without any config, it was able to detect all compatible devices on my network, so I added them.

I created a repo for the dockerfile and subneeded folders like the config/ folder.

Dockerfile:

services:
  homeassistant:
    container_name: homeassistant
    image: ghcr.io/home-assistant/home-assistant:stable
    privileged: true
    restart: unless-stopped
    environment:
      - TZ=Europe/Paris
    volumes:
      - /home/japoneris/path/to/config:/config
      - /run/dbus:/run/dbus:ro
    network_mode: host

Searching for Additional Components

There are plenty of core extensions you can add.
I was looking at weather forecasts: an easy case, no dependencies, no device needed.
There are several providers, most requiring an API key (which may require you to enter a credit card in some cases).
I finally found one without this need (France Météo), which worked well.

Outside of that, I have two favorite weather apps:

  • Ventusky: Nice GUI, helps me plan my day when using my bike.
  • La Météo Agricole: French only, accurate forecast for the next hour. Especially useful in emergency scenarios when I need to avoid a rain cloud.

Building a Custom Component

Getting the POC

My goal was to create a component for Ventusky to see the process of building on a low‑risk project.
First, I downloaded the HTML page of Ventusky: all the information for my location was available—temperature, wind, humidity, hourly and daily data. I asked Claude Code to make a script to collect and format this information as JSON.
Everything OK.

Making the Component

Then, I asked claude to build the component and a javascript card for display. Both were done quickly, everything was functional. It created two repos:

custom_components/ventustky/ // for the core python script / logic
www/ventusky/ // For javascript card

The only file that needed a rework was the manifest.json (where claude sonnet wanted to be the codeowner XD).

So, in terms of writing, I cannot help, AI did everything, and did it well. It will split your code into pieces and add the necessary async / await keywords whenever they are needed.

Note on the manifest.json (if you want to distribute the package)

There are a few rules to follow:

  • domain and name keys first AND THEN alphabetical order (yes, modern json for human …)
  • codeowner with an @, like @japoneris
  • documentation: Set it up with https://github.com/<org/user>/<repository>/README.md
  • issue_tracker: Set it up with https://github.com/<org/user>/<repository>/issues
  • version: of your app. Start with 0.0.1.

Check my example that passed the test: Link to manifest.json

Adding the Component

To add the component, it is very easy:

cd config
mkdir custom_components
mkdir www

Then, copy the ventusky folder from myproject/custom_components/ventusky into config/custom_components/. Do the same for the www folder.

Finally, try to add a new device and search for the name you gave in the manifest.

Adding a Logo

I started writing this article the 24th of February, beginning the process of publishing an icon on the official brand repository, saw that there were 200 pull requests waiting before mine.

Fortunately, my PR was rejected with the comment:

Check the new Home assistant version, you would only need to put the image in your repository without PR.

custom_components/
  my_super_app/
    brand/
      icon.png
      logo.png

I stopped my docker, pulled the new release, reloaded, and the icon showed up!

You can find the information about the new release here

Find the docker images here: Docker Hub: homeassistant repository


HACS (Home Assistant Community Store)

HACS is a kind of Play Store for non-official extensions. Their website is buggy (it crashed my firefox at least 3 times …).

To install, follow their steps here. For docker, it is easy. Get a shell on container, execute your script, and you are done.

docker ps # get the container ID
docker exec -it <containerID> bash
wget -O - https://get.hacs.xyz | bash -

Then restart the container by running docker compose restart.

Finally, configure HACS. Read their setup steps.


Publishing your Module to HACS

You want to share your integration with the community?

You need to prepare your repo for that.

What you need to do

In the repository that contains your custom_components/mydomainname/ folder, add the following items at the root:

  • README.md: Main project page, letting user know what it is about
  • hacs.json: Configuration file
  • Workflows: We will talk about later

Official documentation if needed

hacs.json

Basic example: (See requirements)

{
  "name": "ventusky",
  "content_in_root": false
}

Workflow: Github Actions

You need to configure two GitHub Actions in your repository.

  • What are they? Pieces of code that are run by GitHub on push, on demand, or on a schedule.
  • What do they do? Check if your repo complies with the required rules (e.g., proper formatting).

Create the workflow directory:

mkdir .github/workflows
cd .github/workflows

Then create two files (the names are not important) ending with .yml or .yaml.

File 1:

name: HACS Action

on:
  push:
  pull_request:
  schedule:
    - cron: "0 0 * * *"

jobs:
  hacs:
    name: HACS Action
    runs-on: ubuntu-latest
    steps:
      - name: HACS Action
        uses: hacs/action@22.5.0
        with:
          category: integration

File 2

name: Validate with hassfest

on:
  push:
  pull_request:
  schedule:
    - cron:  '0 0 * * *'

jobs:
  validate:
    runs-on: "ubuntu-latest"
    steps:
        - uses: "actions/checkout@v4"
        - uses: "home-assistant/actions/hassfest@master"

Commit these files. After a push, go to the Actions tab on GitHub to see any errors.

The final step is to wait for your pull request to be accepted!



>> You can subscribe to my mailing list here for a monthly update. <<