Kerrosmalli ja vastuunjako

Tämä on neljäs osa sarjasta joka dokumentoi EnergyHub-järjestelmän rakentamisen vanhaan rintamamiestaloon. Edellisessä osassa käytiin läpi Home Assistantin rooli integraatiokerroksena — mitä se tekee ja mitä se jättää tekemättä. Tässä osassa katsotaan miten kaikki kerrokset toimivat yhdessä ja kuka vastaa mistäkin.
Kotitalouden energiajärjestelmä on harhaanjohtavan yksinkertainen paperilla. Aurinko tuottaa, lämpöpumppu lämmittää, auto latautuu. Mutta kun kaikki tapahtuu samanaikaisesti — ja samaan aikaan sähkön hinta on negatiivinen, L1-vaihe lähestyy 25 ampeeria ja lämpöpumpun käyttövesi on viilenemässä — tarvitaan selkeä kuva siitä kenen vuoro on päättää.
EnergyHubissa vastaus on kerrosmalli. Jokainen kerros tietää oman vastuualueensa eikä astu toisen tontille.
Neljä kerrosta, neljä vastuuta
┌─────────────────────────────────────────────┐
│ HAVAINTOKERROS │
│ InfluxDB + Grafana │
│ Tallentaa kaiken — tekee näkymättömän │
│ näkyväksi jälkikäteen │
├─────────────────────────────────────────────┤
│ OPTIMOINTIKERROS │
│ Node-RED │
│ Päättää mitä tehdään — priorisoi, │
│ tasapainottaa, optimoi │
├─────────────────────────────────────────────┤
│ INTEGRAATIOKERROS │
│ Home Assistant │
│ Lukee, normalisoi, välittää — ylläpitää │
│ järjestelmän tilaa │
├─────────────────────────────────────────────┤
│ KENTTÄKERROS │
│ Modbus · Shelly · P1-mittari │
│ Toimii itsenäisesti — fyysiset suojaukset │
│ eivät riipu ylemmistä kerroksista │
└─────────────────────────────────────────────┘
Kerrosten välinen kommunikaatio tapahtuu MQTT:n kautta. Kenttäkerroksen laiteprotokollat — kuten Modbus TCP aurinkoinvertterin ja lämpöpumpun kanssa — jäävät integraatiokerroksen sisälle, eivätkä näy ylöspäin. MQTT-broker, tässä tapauksessa Mosquitto, toimii väylänä jossa jokainen kerros julkaisee omaan suuntaansa ilman suoria kytköksiä toisiin kerroksiin.
Kenttäkerros — toimii aina
Kenttäkerroksen laitteet — Sungrow-aurinkoinvertteri, Thermia-maalämpöpumppu, Shelly-releet, HomeWizard P1 -mittari — toimivat omalla logiikallaan riippumatta siitä mitä ylemmissä kerroksissa tapahtuu. Sama pätee laajemmin: Fronius Symo, SMA Sunny Boy, ABB-invertterit, Huawei SUN2000 ja GoodWe toimivat kaikki itsenäisesti — EnergyHub ohjaa niitä, mutta ei ole niiden toiminnan edellytys. Nibe-, Mitsubishi-, Daikin- ja Vaillant-lämpöpumput ovat samassa asemassa kuin Thermia: ne lämmittävät taloa omalla säätölogiikallaan, EnergyHub vain antaa lisäohjeita.
Kenttäkerroksessa on fyysisesti toimivat turvasuojaukset: aurinkoinvertterin ylijännitesuoja, lämpöpumpun kompressorin suojatermostaatti ja sähkökeskuksen sulakkeet. Nämä toimivat laitehardwaressa — eivät ohjelmiston varassa. EnergyHubin ohjelmallinen kuormanpudotus on lisäsuoja näiden päällä, ei niiden korvike.
Integraatiokerros — lukee ja välittää
Home Assistant lukee kenttäkerroksen laitteiden tilat Modbus TCP:n kautta ja normalisoi ne kanonisiksi mittauksiksi. sensor.m_grid_power_w, sensor.m_pv_power_w, sensor.m_spot_price_eur_kwh — nämä ovat yhtenäisiä arvoja joita kaikki muut kerrokset käyttävät.
HA myös vastaanottaa Node-REDin komennot MQTT:sta ja välittää ne laitteille. Kun Node-RED päättää että lämpöpumppu tarvitsee boostin, se julkaisee energyhub/command/hp/mode: boost — HA kuuntelee, tulkitsee ja ohjaa Shelly Pro 2:n relettä sen mukaisesti.
HA ylläpitää myös järjestelmän tilaa. Operating mode — normal, peak_protection, vacation, emergency — asuu HA:ssa. Node-RED voi pyytää tilamuutosta, mutta HA kirjaa sen ja julkaisee kaikkien saataville. Näin tila on aina yhdessä paikassa.
Optimointikerros — päättää
Node-RED on järjestelmän aivot. Se vastaanottaa kaiken telemetrian MQTT:n kautta, ylläpitää flow-kontekstissa ajantasaisen kuvan tilanteesta ja ajaa päätöslogiikan minuutin välein.
Päätöslogiikka on eksplisiittistä JavaScript-koodia — ei piilotettuna YAML-automaatioiden ketjuun. Kun Node-RED päättää sallia EV-latauksen, se tekee sen koska spot-hinta on alle kynnysarvon tai aurinkoylijäämä ylittää rajan. Syy on koodissa luettavissa, ei arvailtavissa.
Safety Guardian on erillinen flow joka reagoi välittömästi — ei minuutin syklillä vaan 10 sekunnin välein saapuviin vaihevirtatietoihin. Kun L1-vaihe lähestyy 25 ampeerin sulakerajaa, Safety Guardian laukaisee peak_protection-moodin välittömästi odottamatta seuraavaa minuuttipäätöstä. Vaihevirtatiedot tulevat HA:n kautta — jos HA käynnistetään uudelleen, reaaliaikainen valvonta palautuu vasta kun HA alkaa julkaista uutta telemetriaa.
Node-RED kirjaa jokaisen päätöksensä perusteluineen energyhub/observability/decisions-topiciin — ei vain mitä tehtiin, vaan miksi tehtiin. Tämä ei ole ohjausta varten vaan auditointia varten. Jos joku kysyy miksi EV ei latautunut tiistaina klo 14, vastaus löytyy observability-topicista: virta oli liian korkea, moodi oli peak_protection, lataus estettiin tästä syystä.
Havaintokerros — tekee näkymättömän näkyväksi
InfluxDB tallentaa kaiken aikasarjadatana — vaihevirrat, spot-hinnat, aurinkotuotannon, lämpöpumpun kompressorin kierrosluvun, päätökset ja niiden syyt. Grafana visualisoi sen.
Havaintokerros ei ohjaa mitään. Se ei lähetä komentoja eikä muuta tiloja. Mutta se on se kerros joka paljastaa onko järjestelmä oikeasti toiminut kuten piti — ja tekee mahdolliseksi kysyä kysymyksiä datalta jälkikäteen.
Tämä on HEOMF-kypsyysmallissa keskeinen asia: järjestelmä jota ei voi analysoida jälkikäteen, on järjestelmä jota ei voi parantaa.
MQTT — kerrosten yhteinen kieli
MQTT on se liima joka pitää kerrokset yhdessä mutta löyhästi kytkettynä. Kerrosten välinen kommunikaatio tapahtuu MQTT:n kautta — ei suoria funktiokutsuja, ei jaettuja tietorakenteita.
Topicrakenne noudattaa selkeää logiikkaa:
energyhub/telemetry/ → HA julkaisee mittauksia ylöspäin
energyhub/command/ → Node-RED antaa komentoja alaspäin
energyhub/system/ → järjestelmätilan viestit
energyhub/observability/ → päätösloki analyysiin
Tämä tarkoittaa että Node-RED voidaan käynnistää uudelleen — se lukee MQTT:n retain-viesteistä viimeisimmän tunnetun tilan ja jatkaa siitä. HA voidaan käynnistää uudelleen — Node-RED odottaa uusia telemetriaviestejä ja jatkaa heti kun niitä alkaa tulla. Kummankin voi käynnistää uudelleen ilman että koko järjestelmä menee sekaisin, vaikka lyhyt katkos reaaliaikaisessa päätöksenteossa syntyy.
Tämä ei ole onnettomuus — se on suunniteltu ominaisuus.
Vastuunjako käytännössä
Yksi konkreettinen esimerkki selventää vastuunjaon paremmin kuin mikään kaavio.
Klo 14:30 aurinko tuottaa 12 kW, spot-hinta on -0,001 EUR/kWh, L1-vaihe on 16 ampeeria ja EV on kytkettynä.
Kenttäkerros: Sungrow raportoi 12 kW tuotannon Modbus-rekistereistä. P1-mittari raportoi L1=16 A.
Integraatiokerros: HA lukee arvot, normalisoi ne kanonisiksi sensoreiksi ja julkaisee MQTT:hen: grid=-3695 W (vienti), pv=12000 W, spot=-0.001 EUR/kWh, L1=16.2 A.
Optimointikerros: Node-RED lukee tilanteen. Hinta on negatiivinen — PV-rajoituslogiikka laskee sopivan rajoitusprosentin omakäytön perusteella ja julkaisee energyhub/command/pv/curtail_pct: 24. EV-lataus sallitaan koska se käyttää ylijäämää eikä nosta vaihevirta yli rajan.
Integraatiokerros: HA vastaanottaa PV-rajoituskomennon ja kirjoittaa tässä Sungrow-toteutuksessa Modbus-rekisteriin 5007 arvon 240 (24,0 %). Invertterin ohjausrekisterit vaihtelevat valmistajittain — SunSpec-standardia tukevat laitteet kuten monet Fronius- ja SMA-invertterit käyttävät yhtenäistä rekisterikarttaa.
Kenttäkerros: Sungrow siirtää paneelien toimintapisteen pois maksimitehopisteestä. MPPT-jännite nousee 501 V:sta 558 V:iin — invertteri ottaa vähemmän virtaa paneeleilta.
Havaintokerros: InfluxDB tallentaa koko tapahtumaketjun syineen. Grafana näyttää sen kaavioina.
Jokainen kerros teki oman osuutensa. Kukaan ei astunut toisen tontille.
Miksi tämä on tärkeämpää kuin miltä näyttää
Useimmat kotiautomaatiojärjestelmät rakentuvat yksittäisten automaatioiden varaan. ”Jos aurinko tuottaa yli 2 kW ja hinta on alle 5 senttiä, lataa auto.” Tämä toimii kunnes tulee tilanne jota ei osattu ennakoida — ja niitä tulee aina.
Kerrosmalli ei poista yllätyksiä. Mutta se tekee niistä hallittavia. Kun jotain menee väärin, tiedetään missä kerroksessa etsiä. Kun logiikkaa pitää muuttaa, tiedetään mihin koskea. Kun järjestelmä laajenee — akku, V2H, tehomaksu — uusi komponentti liitetään oikeaan kerrokseen ilman että koskaan tarvitsee kirjoittaa kaikkea uudelleen.
Se on EnergyHubin ydinajatus: rakenna infrastruktuuri, ei automaatio.
Seuraavaksi: Osa 5 — Prioriteetit, tilakoneet ja fallback. Miten järjestelmä päättää kuka saa sähköä kun kaikki haluavat sitä yhtä aikaa.
Tekninen toteutus: MQTT-rakenne ja Node-REDin integraatio on kuvattu tarkemmin ohjeessa HA:n valmistelu integraatiokerrokseksi.