I made a silly Home Assistant automation for the The Turing Way November 2024 book dash. For a while I’d had the idea of some reaction happening in response to activity on The Turing Way repository. Maybe lights flashing or a sound playing in response to a PR being merged.

Here is how I made it.

I wrote script to make the lights change to different colours, with a short pause in between the transitions. I put that in a loop to make it a bit more exciting.

alias: Fun lights
sequence:
  - if:
      - condition: state
        entity_id: light.office
        state: "on"
    then:
      - repeat:
          count: 5
          sequence:
            - service: light.turn_on
              metadata: {}
              data:
                rgb_color:
                  - 255
                  - 64
                  - 255
              target:
                entity_id:
                  - light.desk_lights
                  - light.office
            - delay:
                hours: 0
                minutes: 0
                seconds: 0
                milliseconds: 200
            - service: light.turn_on
              metadata: {}
              data:
                rgb_color:
                  - 255
                  - 146
                  - 0
              target:
                entity_id:
                  - light.office
                  - light.desk_lights
            - delay:
                hours: 0
                minutes: 0
                seconds: 0
                milliseconds: 200
            - service: light.turn_on
              metadata: {}
              data:
                rgb_color:
                  - 0
                  - 252
                  - 255
              target:
                entity_id:
                  - light.office
                  - light.desk_lights
            - delay:
                hours: 0
                minutes: 0
                seconds: 0
                milliseconds: 200
      - service: adaptive_lighting.apply
        metadata: {}
        data:
          adapt_brightness: true
          adapt_color: true
          turn_on_lights: true
          lights:
            - light.office
            - light.desk_lights
mode: single
icon: mdi:alarm-light

An automation calls that script in response to a webhook event.

alias: TTW star lights
description: ""
trigger:
  - platform: webhook
    allowed_methods:
      - GET
      - POST
    local_only: false
    webhook_id: 
condition: []
action:
  - service: script.fun_lights
    metadata: {}
    data: {}
mode: single

I found local_only was required to be false for the automation to be triggered by GitHub. I would guess that is because the request request contains an X-Forwarded-For header, so Home Assistant knows it originates from outside my network even though it is routed through a reverse proxy. GitHub webhooks are always POST requests, so it was also necessary to accept that kind of request.

The server which handles incoming requests to my IP is not the one that hosts Home Assistant. I use Traefik proxy to route traffic, so I set that up to forward webhook requests to my Home Assistant service.

...
    [http.middlewares]
      [http.middlewares.homeassistant-webhook-prefix.AddPrefix]
        prefix = "/api/webhook"
      [http.middlewares.ratelimit.rateLimit]
        average = 1
        burst = 5
    [http.routers]
      [http.routers.homeassistant-webhook]
        entrypoints = ["web"]
        middlewares = ["homeassistant-webhook-prefix", "ratelimit"]
        rule = "Host(`webhook.jmadge.com`) && PathPrefix(`/`)"
        service = "homeassistant-webhook"
    [http.services]
      [http.services.homeassistant-webhook.loadBalancer]
        [[http.services.homeassistant-webhook.loadBalancer.servers]]
          url = "http://<home_assistant_host>:8123"
...

In Traefik language, the service defines where the home assistant service is (hostname and port). The router instructs Traefik to forward requests to webhook.jmadge.com to Home Assistant, after applying the middleware. The prefix middleware is needed to make sure the requests reach Home Assistant’s webhook route. It also means I don’t need to expose the entirety of my Home Assistant service to the internet. That could be quite risky; if a malicious actor got access they would have access to a lot of data and be able to control devices in my house!

When I (finally) got the reverse proxy configuration working, I got a 405 error. Thankfully, the Home Assistant community forums told me I needed to update the trusted proxies in Home Assistant configuration.

...
http:
  use_x_forwarded_for: true
  trusted_proxies:
   - 127.0.0.1
   - 172.0.0.0/8
   - 192.168.1.10
   - 192.168.178.205  # Traefik proxy server
...

Then I created a webhook on The Turing Way’s book repository triggered when the number of stars changes. And it was finished!

Other book dash attendees had fun turning my office into a disco.

Future

I would like to create a maker version of this, using a cheap microcontroller (or SBCs) and components. With some instructions, book dash participants could build their own alert machine and have a little celebration as their contributions are made.

That need some thinking to figure out how to made it accessible, without a large cost or need to specialist skills or tools.