,

Kommunens tømmekalender inn i Home Assistant

Kommunens tømmekalender inn i Home Assistant

Kommunens tømmekalender skulle vises i Home Assistant, sånn at neste dato per fraksjon (rest, papir, plast, mat) dukket opp på veggpanelet. Det hadde gått knirkefritt lenge, kjørt fra et skyhostet script. Så, en dag, stoppet det. Ingen datoer på panelet, ingen feilmelding i dashbordet. Bare stille.

Symptomet så ut som kodefeil

Scriptet var en Google Apps Script som hentet data fra kommunens renovasjons-API og dyttet det videre til Home Assistant. Loggen viste timeout mot kommunens server. Den første, naturlige antagelsen var at API-et var endret eller nede. Men det stemte ikke: det nøyaktig samme kallet fra et norsk hjemmenett svarte med en gang.

Forskjellen lå altså i hvor kallet kom fra. Kommunens server lyttet på en port som ikke er standard, og de utgående IP-ene til skyleverandøren nådde rett og slett aldri frem. Trafikken ble stoppet et sted mellom skyen og kommunen. Fra et norsk nett gikk den rett igjennom, uten kluss.

Diagnose: nettverk, ikke kode

Nettverksdiagram som viser at skyleverandørens utgående IP blir blokkert mot kommunens server på en ikke-standard port, mens et norsk hjemmenett når fram

En rask test for å skille kode fra nett: kjør nøyaktig samme forespørsel fra to steder, og se hva som skjer.

# Fra hjemmenett: svarer
curl -m 10 -v https://api.kommune.example:8443/renovasjon/neste

# Fra skyhost: henger og timer ut
curl -m 10 -v https://api.kommune.example:8443/renovasjon/neste

Når koden er identisk og det eneste som skiller er hvilket nett kallet kommer fra, da er det ikke koden som er problemet. En del offentlige API-er er geo- eller nettgjerdet. De slipper inn norske aksessnett, men stenger ute utenlandske skyranger, gjerne ekstra hardt på uvanlige porter.

Løsning: flytt henteren hjem

Arkitekturdiagram av en liten lokal container i hjemmenettet som poller kommunens tømmekalender én gang i døgnet med tilfeldig jitter og sender data videre til Home Assistant

Henteren ble flyttet til en liten lokal container på samme nett som Home Assistant. Den poller én gang i døgnet med litt tilfeldig jitter, så kommunens server slipper å få et treff på nøyaktig samme sekund hver eneste dag. Resultatet skrives inn i input_datetime-hjelpere, én per fraksjon.

# Home Assistant hjelpere (configuration.yaml)
input_datetime:
  neste_restavfall:
    name: Neste restavfall
    has_date: true
    has_time: false
  neste_papir:
    name: Neste papir
    has_date: true
    has_time: false

Selve container-scriptet henter dataene og skriver dem via REST-API-et til Home Assistant.

import random, time, requests

time.sleep(random.randint(0, 3600))  # jitter, skånsom mot kommunen

data = requests.get("https://api.kommune.example:8443/renovasjon/neste",
                    timeout=15).json()

for fraksjon, dato in data.items():
    requests.post(
        f"http://192.168.x.x:8123/api/services/input_datetime/set_datetime",
        headers={"Authorization": "Bearer "},
        json={"entity_id": f"input_datetime.neste_{fraksjon}", "date": dato},
        timeout=15)

Det hele kjøres som en cron-jobb inne i containeren, én gang i døgnet.

# crontab: kl 06 hver dag, container legger på jitter selv
0 6 * * * python3 /app/hent_tommekalender.py

Lærdom

Det som ser ut som en kodefeil kan like gjerne være et nettverksproblem. Så før du graver deg ned i koden: kjør samme kall fra et annet nett. Er det bare opprinnelsen som skiller, ligger problemet i nettet og ikke i logikken. Og for offentlige API-er som er geo- eller nettgjerdet er svaret enkelt nok: kjør hentingen fra riktig nett. En liten lokal container koster nesten ingenting og rydder unna hele klassen med skyrelaterte tilgangsfeil på én gang.


Trenger du hjelp med dette?

Ta kontakt for en uforpliktende prat om hvordan jeg kan hjelpe deg.



Navn