Prioriteetit, tilakoneet ja fallback

Tämä on viides osa sarjasta joka dokumentoi EnergyHub-järjestelmän rakentamisen vanhaan rintamamiestaloon. Edellisessä osassa käytiin läpi kerrosmalli ja vastuunjako — miten neljä kerrosta kommunikoivat keskenään MQTT:n kautta. Tässä osassa päästään siihen kysymykseen joka nousee aina kun järjestelmä kasvaa riittävän monimutkaiseksi: kuka saa sähköä kun kaikki haluavat sitä yhtä aikaa?
Tiistai-iltapäivä. Aurinko paistaa, invertterin teho on 12 kW. Sähköauto on kytkettynä ja haluaa ladata. Lämpöpumppu harkitsee käyttöveden lämmittämistä. Kiuas on ajastettu käynnistymään tunnin kuluttua. L1-vaihe on 23 ampeeria.
Neljä tavoitetta, yksi liittymä, 25 ampeerin sulake.
Järjestelmä tarvitsee selkeän vastauksen siihen kenen pyyntö menee edelle. Ei kompromissia — prioriteetti.
Tilakone — yksi moodi kerrallaan
EnergyHubissa koko järjestelmä on aina yhdessä tilassa. Operating mode ei ole pelkkä informaatioarvo — se on prioriteettikerros joka määrittää miten kaikki päätökset tehdään.
Tilat järjestyksessä prioriteetin mukaan:
emergency ← korkein prioriteetti — turvatila
peak_protection ← sulake uhkaa — pudota kuormat
manual_override ← ihminen päättää — ei automaatiota
vacation ← talo tyhjillään — minimikäyttö
guest ← mukavuus prioriteetiksi
cheap_energy ← halpa sähkö — lataa kaikki
solar_maximize ← aurinko ylituottaa — käytä itse
normal ← oletustila — hinta + aurinko + sulakkeet
Fallback ei ole varsinainen operating mode — se on järjestelmän terveystila. Se aktivoituu automaattisesti kun data on vanhentunutta tai yhteys on katkennut. Siinä ei kilpailla muiden moodien kanssa: jos järjestelmä ei tiedä missä tilassa se on, se siirtyy konservatiivisiin oletuksiin riippumatta siitä mitä operating mode sanoo.
Tärkeää on ymmärtää mitä prioriteettijärjestys tarkoittaa käytännössä: kun moodi on peak_protection, Node-RED ei enää kysy onko hinta halpa tai tuottaako aurinko. Se pudottaa kuormat prioriteettijärjestyksessä riippumatta muista olosuhteista. Moodi ohittaa optimoinnin.
Miten moodi muuttuu — ja kuka saa muuttaa
Tilamuutos voi tulla kolmesta suunnasta — mutta ei kaikista suunnista kaikkiin tiloihin.
Safety Guardian muuttaa moodin välittömästi kun vaihevirta ylittää 90 % sulakerajasta. Tämä tapahtuu 10 sekunnin syklillä — ei odoteta seuraavaa minuuttipäätöstä. Guardian voi asettaa peak_protection-moodin, mutta se ei voi itse poistaa sitä — paluu normal-moodiin tapahtuu kun vaihevirta laskee alle 75 % rajan. Hystereesi estää sen että moodi flippaa edestakaisin pienten vaihteluiden mukana.
emergency-moodista poistuminen vaatii manuaalisen toimenpiteen — käyttäjän tai huolto-operaation. Se ei nollaudu automaattisesti.
Node-RED Decision Engine toimii optimointi- ja päätöksentekokerroksena. Se voi pyytää moodinvaihtoa kun se havaitsee tilanteen muuttuvan — cheap_energy kun hinta putoaa alle kynnyksen, solar_maximize kun aurinkoylijäämä kasvaa riittäväksi. Se ei voi kuitenkaan ohittaa emergency– tai manual_override-moodia.
Käyttäjä voi vaihtaa moodin suoraan HA:n käyttöliittymästä. manual_override tarkoittaa että järjestelmä ei tee omia päätöksiä — ihminen on ottanut ohjat. Tämä on ainoa tila johon vain käyttäjä pääsee.
Kaikki tilamuutokset kirjataan. InfluxDB:stä näkee jälkikäteen milloin moodi muuttui, mihin suuntaan ja mikä sen aiheutti.
Priority Resolver — päätöslogiikka järjestyksessä
Node-RED:n Priority Resolver käy tilanteet läpi kiinteässä järjestyksessä. Ensimmäinen osuma ratkaisee — loput haarasta jätetään käymättä läpi.
1. Emergency ja safety trip
Jos sys_safety_trip on true tai moodi on emergency, kaikki ohjattavat kuormat sammutetaan välittömästi. EV-lataus estetään, lämpöpumppu blokataan EVU-signaalilla, lisävastus sammutetaan, kiuas estetään. PV-rajoitusta ei aseteta — aurinko saa tuottaa vapaasti koska se pienentää verkkokuormaa. Tässä tilanteessa ei optimoida. Turvallisuus menee edelle.
2. Peak protection
Vaihevirta on liian korkea tai Safety Guardian on laukaissut moodin. Kuormat pudotetaan prioriteettijärjestyksessä:
- EV-lataus estetään ensimmäisenä — suurin yksittäinen kuorma, 3,6 kW
- Kiuas estetään — toinen suuri kuorma
- Lisävastus estetään
- Lämpöpumppu: jos kompressori pyörii yli 60 % teholla, blokataan EVU-signaalilla. Jos alle, annetaan jatkaa normaalisti.
PV:tä ei rajoiteta — aurinkoinvertteri saa tuottaa vapaasti koska se pienentää verkon kuormaa.
3. Manual override
Moodi on manual_override — järjestelmä ei tee mitään. Se ei muuta mitään tilaa, ei lähetä komentoja. Ihminen päättää.
4. Vacation
Talo on tyhjillään. EV-lataus estetään. Kiuas estetään. Lämpöpumppu: jos käyttövesi on laskenut alle minimilämpötilan tai huonelämpötila on laskenut alle asetetun tavoitelämpötilan, annetaan lämmittää normaalisti. Muuten blokataan.
5. Normaali optimointi
Kaikki muut moodit — normal, solar_maximize, cheap_energy, guest — päätyvät tähän haaraan. Tässä otetaan huomioon hinta, aurinkotuotanto ja sulakerajat yhdessä.
Normaali optimointi — kolme muuttujaa
Normaalissa optimoinnissa kolme tekijää vaikuttaa jokaiseen päätökseen:
Hinta — spot-hinta verrattuna kahteen kynnysarvoon. Negatiivinen hinta tarkoittaa että sähköstä maksetaan verkkoon myymisestä — tällöin kannattaa rajoittaa vientiä ja käyttää kaikki itse. Halpa hinta tarkoittaa että lataaminen ja lämmittäminen kannattaa. Kallis hinta tarkoittaa päinvastoin.
Aurinkotuotanto — ylijäämäaurinko on ensisijainen energianlähde omaan käyttöön. Jos aurinko tuottaa enemmän kuin talo kuluttaa, ylijäämä ohjataan ensin EV-lataukseen, sitten lämpöpumpun boostiin. Verkkoon myynti on viimeinen vaihtoehto — ja negatiivisilla hinnoilla jopa haitallinen.
Sulakkeet — vaihevirrat rajoittavat kaiken muun. Optimointilogiikka ei koskaan tee päätöstä joka johtaisi sulakeylitykseen. Tämä ei ole pelkästään Safety Guardianin vastuulla — se on myös optimointilogiikan sisäänrakennettu rajoite.
Capability — lupa ennen päätöstä
Ennen kuin Priority Resolver tekee yhtään päätöstä, se tarkistaa capability-flagit. c_ev_charge_allowed: false tarkoittaa että EV-latausta ei sallita riippumatta hinnasta tai aurinkotilanteesta.
Capability on käyttöoikeus — vastaus kysymykseen ”saako tämä laite toimia”. Se ei kerro tekeekö järjestelmä niin. Komento on se päätös joka lähetetään laitteelle.
Tämä erottelu on tärkeä: käyttäjä voi asettaa capability-flagin pois päältä — ”en halua ladata tänä yönä” — ilman että logiikkaan tarvitsee koskea. Järjestelmä kunnioittaa rajoitteen.
Shadow/live-mekanismi on eri abstraktiotaso. Se ei vastaa kysymykseen ”saako laite toimia” vaan ”saako EnergyHub ohjata laitetta”. Capability on käyttöoikeus laitteelle, shadow/live on execution control — kuka omistaa ohjauksen. Nämä kaksi toimivat yhdessä mutta eri tasoilla.
Fallback — mitä tapahtuu kun yhteys katkeaa
Fallback-logiikka on se osa järjestelmästä josta harvoin puhutaan mutta joka on yhtä tärkeä kuin optimointilogiikka.
Kun järjestelmä ei tiedä mikä on tosi — data on vanhentunutta, yhteys on poikki, mittaukset eivät päivity — se ei arvaa. Se siirtyy konservatiivisiin oletuksiin: EV-lataus estetään, lämpöpumppu jatkaa normaalisti ilman boostia, ei aggressiivista optimointia. Parempi jättää käyttämättä optimointimahdollisuus kuin tehdä väärä päätös epävarman datan perusteella — erityisesti kun EV-lataus on suurin yksittäinen kuorma ja sulakeylilyönti on mahdollinen.
EnergyHubissa fallback toimii kerroksittain.
Jos Node-RED kaatuu, HA jatkaa mittaamista. Laitteet jäävät viimeiseen tunnettuun tilaan — Shelly-releet eivät liiku, invertteri jatkaa viimeisellä rajoitusasetuksella. Ei optimaalista, mutta turvallista.
Jos HA kaatuu, Node-RED lukee MQTT:n retain-viesteistä viimeisimmän tunnetun tilan. Se ei saa uutta dataa, joten se siirtyy konservatiivisiin oletuksiin.
Jos MQTT-broker kaatuu, kaikki kommunikaatio lakkaa. Laitteet jäävät tilaan johon ne viimeksi ohjattiin.
Jokaisessa tapauksessa fyysiset suojaukset — sulakkeet, invertterin suojat, lämpöpumpun termostaatit — toimivat edelleen. Ne eivät riipu ohjelmistosta.
Viimeiseen tunnettuun tilaan jääminen on turvallinen ratkaisu lyhyellä aikavälillä. Pitkällä aikavälillä olosuhteet muuttuvat — aurinkotuotanto laskee, ulkolämpötila vaihtelee, sähkön hinta nousee. Järjestelmä joka on pysähtynyt ei pysty reagoimaan näihin muutoksiin. EV-rele voi jäädä kiinni kun aurinko on laskenut ja sähkö on kallista — tai auki kun aurinko olisi riittänyt lataukseen. Tila joka oli järkevä kaatumishetkellä ei välttämättä ole järkevä kaksi tuntia myöhemmin.
Tästä syystä pitkä kaatuminen ei ole neutraali tila — se on tila jossa optimointi on poissa käytöstä ja laitteet toimivat viimeisen komennon mukaan riippumatta siitä onko se enää perusteltua.
Käytännön ratkaisu on watchdog-logiikka: jos järjestelmä havaitsee että se ei ole saanut uutta dataa tietyn ajan kuluessa, se asettaa laitteet eksplisiittisesti konservatiiviseen tilaan — EV-rele auki, invertteri täydelle teholle, lämpöpumppu normaalille ilman boostia. Tämä on parempi kuin se että laitteet jäävät tuntemattomaan tilaan ilman valvontaa. Watchdog on yksi niistä asioista jotka rakennetaan kun järjestelmä on muuten toimiva — mutta sen puuttuminen huomataan vasta kun kaatuminen kestää odotettua kauemmin.
Käytännön esimerkki: peak protection laukeaa
25.5.2026 klo 14:00. Aurinkoa riittää, sähkön hinta on 2,3 senttiä per kilowattitunti. EV-lataus on sallittu ja lämpöpumppu toimii normaalisti.
Klo 14:05. L1-vaihe nousee 23,8 ampeerin. Safety Guardian havaitsee ylityksen 10 sekunnin syklillä — 90 % 25 ampeerin rajasta on 22,5 ampeeria, raja ylittyy selvästi. Guardian julkaisee energyhub/command/mode: peak_protection. HA kirjaa tilamuutoksen.
Node-RED lukee seuraavalla minuuttisyklillä tilanteen: moodi on peak_protection. Priority Resolver menee suoraan peak-haaraan riippumatta hinnasta tai aurinkotuotannosta. Päätös: EV off, kiuas off, HP normal — kompressori alle 60 %.
Klo 14:20. Suuri kulutus loppuu. L1-vaihe laskee 16,2 ampeerin. Safety Guardian havaitsee että ollaan alle 75 % rajan — 18,75 ampeeria. Guardian julkaisee energyhub/command/mode: normal. Järjestelmä palaa optimointimoodiin.
Koko tapahtuma kestää 15 minuuttia. Päätökset on kirjattu observability-topiciin syineen. InfluxDB näyttää vaihevirran kehityksen kaavioina.
Miksi tilakone eikä ehtojen lista
Vaihtoehto tilakoneelle olisi rakentaa optimointilogiikka pitkänä ehtolistana: ”jos hinta < X ja virta < Y ja aurinko > Z, tee A, muuten jos…”
Tämä toimii pienessä järjestelmässä. Mutta kun ehtoja on kymmeniä ja ne alkavat olla ristiriidassa keskenään, kukaan ei enää tiedä mitä järjestelmä tekee missäkin tilanteessa. Vika löytyy vasta kun se on jo tapahtunut — väärässä tilanteessa, väärällä hetkellä.
Tilakone pakottaa ajattelemaan etukäteen. Jokainen moodi on eksplisiittinen. Tilasiirtymät ovat määriteltyjä — ja tärkeää on myös se kuka saa tehdä minkäkin siirtymän. Mikä tahansa tilanne voidaan kysyä: ”missä moodissa järjestelmä on ja mitä se tässä moodissa tekee?” — ja saada selkeä vastaus.
Se on kotiautomaatiossa harvinainen luksus.
Seuraavaksi: Osa 6 — HA:n rooli ja entiteettimalli. Miten mittaukset, parametrit ja ohjaussignaalit järjestetään niin että ne pysyvät hallittavina kun järjestelmä kasvaa.
Tekninen toteutus: Priority Resolver -koodi ja operating mode -rakenne on kuvattu ohjeessa HA:n valmistelu integraatiokerrokseksi.