Case: oma talo — Osa 16

Written by

in

Kun kukaan ei katso: vahtikoira hiljaisille vioille

Tämä on kuudestoista osa sarjasta, joka dokumentoi EnergyHub-kotiautomaatiojärjestelmän rakentamisen vanhaan rintamamiestaloon. Edellinen osa kertoi systemaattisesta vikojen läpikäynnistä ennen käyttöönottoa. Se päättyi lupaukseen kertoa seuraavaksi operoinnista — siitä, miten energianhallintajärjestelmää pidetään pystyssä silloin, kun kukaan ei aktiivisesti katso.

Tämä osa on siitä. Se alkaa viasta, jota en huomannut kahteen viikkoon — ja päättyy samaan vikaan, mutta toisella lopputuloksella.

Varmuuskopio, joka oli hiljaa rikki

Järjestelmästä otetaan automaattinen varmuuskopio joka yö kello kolme. Arkisto pakataan, tarkistussumma lasketaan, tiedosto ladataan pilveen. Olin rakentanut tämän varmuuskopioinnin kuukausia sitten ja lakannut ajattelemasta sitä — juuri niin kuin varmuuskopion kuuluukin toimia.

Sitten eräänä päivänä satuin katsomaan varmuuskopiohakemistoa. Tuorein arkisto oli kahden viikon takaa.

Skripti oli ajautunut joka yö. Ajastin oli tehnyt työnsä. Mutta itse varmuuskopiointi epäonnistui hiljaa: eräs komento vaati oikeuksia, joita ajastettu ajo ei voinut antaa, ja koska skriptistä puuttui rivi joka olisi pysäyttänyt sen ensimmäiseen virheeseen, se jatkoi loppuun asti ja raportoi onnistuneensa. Loki näytti siistiltä. Paluukoodi oli nolla — merkki onnistumisesta. Vain tiedostojen puuttuminen kertoi, ettei mitään ollut oikeasti tallennettu kahteen viikkoon.

Tämä on täsmälleen sama vikaluokka josta edellinen osa kertoi: hiljainen epäonnistuminen. Mikään ei kaadu, mikään ei hälytä, ja virhe elää niin kauan kuin kukaan ei satu katsomaan oikeaa paikkaa oikeaan aikaan. Erona vain se, että nyt vika ei ollut ohjauslogiikassa vaan ylläpidossa — ja se osui juuri siihen mekanismiin, jonka koko tarkoitus on suojata katastrofilta.

Korjasin varmuuskopiointiskriptin. Mutta oikea opetus ei ollut korjaus. Se oli kysymys, jonka vika nosti esiin: mitä muuta on hiljaa rikki, mistä en tiedä?

Se mitä ei mittaa, ei ole olemassa

Kotiautomaatiojärjestelmä koostuu joukosta osasia, jotka kaikki voivat pettää itsenäisesti. Home Assistant integroi laitteet. Node-RED tekee optimointipäätökset. MQTT-viestiväylä välittää tiedot. InfluxDB tallentaa historian, Grafana piirtää sen. Kaikki pyörii pienessä palvelimessa nurkassa, eikä kukaan katso sitä päivittäin — se on koko pointti. Automaation kuuluu olla näkymätön.

Mutta näkymättömyydellä on hinta. Jos järjestelmä ei kerro itsestään mitään, ainoa tapa tietää että se voi hyvin on tarkistaa se käsin. Ja käsin tarkistaminen ei skaalaudu — sitä ei yksinkertaisesti tule tehtyä, ennen kuin jokin menee niin pahasti pieleen että se huomataan muuta kautta. Kylmä suihku, pimeä huone, kahden viikon aukko varmuuskopioissa.

Ratkaisu ei ole katsoa useammin. Ratkaisu on rakentaa monitorointi, joka on osa järjestelmää itseään: järjestelmä joka kertoo omasta voinnistaan — ja erillinen valvoja, joka huomaa jos se lakkaa kertomasta.

Sydämensyke

Ensimmäinen kerros on sydämensyke. Node-RED — järjestelmän aivot, joka tekee energianhallinnan optimointipäätökset — julkaisee säännöllisin väliajoin viestin, joka kertoo yhden asian: minä olen elossa.

Mutta pelkkä ”olen elossa” ei riitä, ja tämä on tärkeä oivallus. Prosessi voi olla pystyssä ja silti kyvytön tekemään työnsä, jos sen syötteet ovat pysähtyneet. Jos sähkön hintatieto on tunteja vanhaa tai lämpöpumpun mittaukset ovat lakanneet päivittymästä, järjestelmä on teknisesti hengissä mutta käytännössä sokea. Se tekisi päätöksiä vanhentuneen tiedon varassa — mikä on usein vaarallisempaa kuin päätösten tekemättä jättäminen.

Siksi sydämensyke kertoo prosessin hengissäolon lisäksi sen, kuinka tuoretta jokainen keskeinen syöte on: milloin sähkömittarilta tuli viimeksi lukema, milloin sähkön pörssihinnat päivittyivät, milloin lämpöpumppu ja aurinkopaneelit raportoivat, ja milloin optimointilogiikka viimeksi ajoi läpi. Syke ei ole ”olen elossa” vaan ”olen elossa ja näen”. Se julkaistaan viestiväylälle muutaman sekunnin välein, ja se on perusta kaikelle mitä seuraa.

Vahtikoira järjestelmän ulkopuolella

Toinen kerros on valvoja — vahtikoira, joka on tarkoituksella järjestelmän ulkopuolella.

Tämä sijoittelu on olennainen, ja se on monitoroinnin tärkein yksittäinen suunnitteluperiaate. Sydämensyke tulee Node-REDistä, mutta juuri Node-REDin kaatuminen on yksi tärkeimmistä asioista jotka pitää havaita. Jos valvoja eläisi saman prosessin sisällä jota se valvoo, se kaatuisi yhdessä sen kanssa eikä kukaan saisi tietää. Siksi vahtikoira ajaa palvelimella itsenäisenä käyttöjärjestelmän ajastamana prosessina, Node-REDin, Home Assistantin ja koko muun konttipohjaisen järjestelmän ulkopuolella. Se herää minuutin välein, tarkistaa terveyden ja kirjaa havaintonsa.

Mitä se tarkistaa? Ovatko kaikki palvelut pystyssä. Onko sydämensyke tuore vai onko se vaiennut. Ovatko syötteet ajan tasalla. Milloin viimeisin varmuuskopio syntyi — se sama tarkistus, jonka puuttuminen aloitti tämän koko tarinan. Ja paljonko levytilaa on jäljellä, koska täyttyvä levy on hidas, hiljainen tapa kaataa koko kotiautomaatiojärjestelmä.

Tärkein sääntö: vahtikoira ei pure — vielä

Vahtikoiran voisi kuvitella toimivan: se havaitsee ongelman ja korjaa sen — käynnistää kaatuneen palvelun uudelleen, palauttaa laitteet turvatilaan. Se on lopullinen tavoite. Mutta se ei ole se, mistä aloitin, ja syy on periaatteellinen.

Valvoja, joka tekee automaattisia korjauksia, on itsessään vaarallinen, jos sen käsitys ”ongelmasta” on väärä. Väärin viritetty vahtikoira, joka käynnistää palveluita uudelleen turhaan tai palauttaa laitteita turvatilaan silloin kun kaikki on kunnossa, aiheuttaa enemmän häiriötä kuin se estää. Ja ennen kuin sille antaa vallan toimia, pitää tietää tarkalleen miltä normaali näyttää — muuten se ei osaa erottaa normaalia poikkeavasta.

Siksi ensimmäinen versio on tarkoituksella hampaaton. Se katsoo, se kirjaa, se raportoi — mutta se ei kajoa mihinkään. Sen ainoa tehtävä on kerätä tietoa siitä, miten järjestelmä käyttäytyy tavallisesti: kuinka tuoreita syötteet ovat normaalisti, kuinka paljon ne vaihtelevat, mikä on tavallista ja mikä poikkeavaa.

Ja tämä maltti osoittautui heti hyödylliseksi. Kun annoin vahtikoiran kerätä dataa vuorokauden yli ja katsoin sitten mitä se oli nähnyt, syötteiden tuoreudesta paljastui selkeä kuvio: normaalitilassa mittaustiedot olivat lähes aina alle minuutin vanhoja, ja jakauman yläraja asettui johdonmukaisesti noin 59 sekuntiin — ei koskaan sen yli. Jos olisin arvannut varoitusrajan etukäteen, olisin todennäköisesti asettanut sen 60 sekuntiin, mikä on juuri normaalin ylärajalla — ja se olisi tuottanut turhia hälytyksiä lähes joka päivä. Datan perusteella nostin varoitusrajan 90 sekuntiin ja varsinaisen vikarajan 180 sekuntiin, kolmeen mittaussykliin. Nyt raja laukeaa vasta aidosta poikkeamasta, ei normaalin vaihtelun huipusta. Tätä ei olisi voinut päätellä pöydän takana — se piti mitata.

Tämä on sama periaate jolla koko järjestelmä otettiin käyttöön: havainnoi ensin, toimi vasta sitten. Vahtikoira aloittaa katsojana, ei tekijänä.

Mitä testi paljasti

Ennen kuin luotin vahtikoiraan, testasin sen: pysäytin Node-REDin tahallani ja katsoin, mitä tapahtuu.

Vahtikoira huomasi katkon välittömästi ja merkitsi tilan vialliseksi. Ja mikä tärkeintä — se ei tehnyt mitään muuta. Node-RED pysyi alhaalla, koska tässä vaiheessa vahtikoiralla ei ole valtaa käynnistää sitä. Se on juuri se käyttäytyminen jonka halusin varmistaa: valvoja havaitsee, mutta ei toimi. Käynnistin Node-REDin itse takaisin, ja sydämensyke palasi.

Tämä testi oli tärkeä paitsi toimivuuden varmistamiseksi, myös siksi että se pakotti minut näkemään vian sellaisena kuin vahtikoira sen näkee. Kun katko oli päällä, palvelu näkyi alhaalla, sydämensykkeen ”viimeksi nähty” -aika alkoi kasvaa, ja optimointilogiikan viimeisin ajo jäi taakse. Kaikki kolme osaa kertoivat saman tarinan eri kulmasta — ja juuri se moniulotteisuus on syy, miksi rakensin sykkeen kertomaan muutakin kuin pelkän hengissäolon. Yksi signaali voi valehdella; kolme rinnakkaista signaalia piirtää totuuden.

Kun yksi mittari nikottelee

Yksi hienovarainen suunnittelukysymys ansaitsee oman huomionsa, koska se on juuri sellainen kohta jossa naiivi toteutus pettää.

Kun vahtikoira valvoo useaa syötettä — sähkömittari, hinnat, lämpöpumppu, aurinkopaneelit — herää kysymys: milloin se hälyttää? Ilmeinen vastaus olisi ”kun ne kaikki ovat vanhentuneet”. Mutta se olisi vaarallinen virhe. Jos vaatisin että kaikki syötteet vanhenevat yhtä aikaa ennen hälytystä, niin tilanne jossa vain yksi integraatio kuolee — vaikkapa lämpöpumpun tiedonsiirto katkeaa mutta kaikki muu jatkaa normaalisti — jäisi täysin huomaamatta. Ja juuri se on todennäköisin vikatapaus: yksittäinen yhteys irtoaa, ei koko väylä kerralla.

Ratkaisu on kaksitasoinen. Jos yksittäinen syöte vanhenee, se on varoituksen arvoinen — jokin integraatio on pulassa, ja vahtikoira kertoo tarkalleen mikä. Jos kaikki syötteet vanhenevat yhtä aikaa, se on vakavampi merkki: koko optimointisykli tai viestiväylä on jumissa. Molemmat havaitaan, mutta eri painoarvolla. Sokea piste, jossa yksittäisen laitteen hiljainen kuolema katoaa muiden terveyden taakse, on suljettu.

Samaan tapaan yksittäinen hetkellinen piikki ei saa laukaista hälytystä. Jos jokin syöte sattuu olemaan hetken tavallista vanhempi yhden tarkistuksen ajan, se on kohinaa, ei vikaa. Vahtikoira vaatii että poikkeava tila jatkuu useamman peräkkäisen tarkistuksen ajan ennen kuin se nostaa hälytyksen — ja vastaavasti se ei julista tilaa terveeksi heti ensimmäisestä normaalista lukemasta, jottei vilkkuva, epävakaasti nikotteleva vika pääse piiloutumaan hälytyksen ja normaalin väliin sahaamalla. Nämä ovat pieniä yksityiskohtia, mutta juuri ne erottavat monitorointijärjestelmän joka on hyödyllinen sellaisesta joka huutaa sudesta niin usein, ettei sitä enää kuunnella.

Nyt kaikki jää talteen

Yksi asia puuttui vielä. Vahtikoira raportoi terveyden minuutin välein, mutta raportti katosi heti — se oli hetken tilannekuva, ei historiaa. Jos halusin tietää miten syötteet käyttäytyivät viime yönä, tietoa ei ollut mistä katsoa.

Niinpä kytkin sekä sydämensykkeen että vahtikoiran raportit samaan aikasarjatietokantaan, johon järjestelmä muutenkin tallentaa historiansa — InfluxDB:hen, jonka päälle Grafana piirtää kuvaajat. Nyt jokainen syke ja jokainen terveystarkistus jää talteen, ja niistä syntyy oma valvontanäkymänsä: järjestelmän terveyden kojelauta, joka näyttää yhdellä silmäyksellä ovatko palvelut pystyssä, kuinka tuoreita syötteet ovat, milloin viimeisin varmuuskopio otettiin ja paljonko levytilaa on jäljellä.

KUVA 1: System Health -kojelauta yleisnäkymänä — palvelut, telemetria-ikien aikasarja, varmuuskopion ikä, levytila

Juuri tätä kertyvää dataa valvojan rajojen asettaminen vaatii — ja kuten edellä kuvattu varoitusrajan tarina osoitti, sitä ei voi arvata etukäteen. Se pitää mitata. Kojelauta teki myös oman hyödyllisen palveluksensa: kun näkee järjestelmän terveyden piirrettynä, huomaa myös monitoroinnin omat aukot. Muutama puute paljastui vasta siinä vaiheessa kun data piirtyi ruudulle — mikä on hyvä muistutus siitä, että näkyvyyden rakentaminen tekee näkyväksi myös sen, mitä ei vielä mitata.

Ja sitten, ennen kuin ehdin edes julkaista tätä artikkelia, vahtikoira teki ensimmäisen aidon löytönsä.

Ensimmäinen aito saalis

Ajattelin, että ensimmäinen todellinen havainto antaisi odottaa itseään viikkoja. Se tuli päivissä — ja tavalla, joka oli melkein liian osuva ollakseen totta.

Osana tätä samaa työtä tein tietoturvasiivouksen: järjestelmän tietokantaan oli aikanaan luotu yksi ylioikeuksinen pääsytunniste, jota useampi palvelu käytti yhteisesti, ja se korvattiin rajatuilla, palvelukohtaisilla tunnisteilla. Oikea ja tarpeellinen parannus. Mutta sillä oli sivuvaikutus, jota en huomannut: yöllinen varmuuskopiointiskripti haki tietokantaosuuttaan varten juuri sitä vanhaa tunnistetta. Kun tunniste mitätöitiin, skripti alkoi saada joka yö kirjautumisvirheen. Ajastin ajoi, virhe kirjautui lokiin, jota kukaan ei lukenut. Täsmälleen sama hiljainen vikaluokka kuin tämän artikkelin alussa — nyt vain oman parannukseni aiheuttamana.

Erona edelliseen kertaan: nyt joku katsoi. Huomasin vian, koska kaksi mittaria oli eri mieltä. Vahtikoiran raportoima varmuuskopion ikä kasvoi kohti 56:ta tuntia, kun kojelaudan toinen paneeli näytti tyytyväisenä vihreää kymmentä tuntia. Ristiriita itsessään oli hälytys. Selitys löytyi kaivamalla: järjestelmässä on kaksi erillistä varmuuskopioprosessia — palvelukohtainen ja koko järjestelmän kattava — ja paneeli seurasi sitä joka toimi, vahtikoira sitä joka oli rikki.

Vahtikoira oli oikeassa, ja syy on periaatteellinen. Se ei kysynyt varmuuskopioprosessilta miten meni, vaan mittasi levyllä olevan varmuuskopiotiedoston todellisen iän. Tämä on sama periaate, joka on kulkenut läpi koko sarjan ohjauspuolella:

Komento ei ole toteuma. Lokirivi on väite. Tiedosto levyllä on tosiasia. Valvo tosiasioita.

Vika eli alle kaksi vuorokautta ennen kuin se jäi kiinni. Edellinen vastaava eli kaksi viikkoa — ja senkin löytyminen oli puhdasta sattumaa. Se on koko tämän monitorointikerroksen arvo yhdessä vertailussa.

KUVA 2:Varmuuskopion ikä kasvoi, vaikka järjestelmä näytti muuten toimivan. Korjauksen jälkeen ikä putosi takaisin lähelle nollaa. Tämä on juuri se hiljainen vikaluokka, jota vahtikoiran pitää havaita.

Korjaus itsessään tarjosi vielä yhden muistutuksen. Sen aikana yksi apuskripti kaatui virheeseen, jonka syntaksitarkistus oli jo ehtinyt hylätä — mutta ajoin skriptin silti. Tarkistus, joka ei pysäytä, ei ole tarkistus. Sama kuri, joka koskee järjestelmän muutoksia, koskee myös sen korjauksia.

Kuka valvoo valvojaa?

Kojelauta paljasti vielä yhden asian, joka ansaitsee rehellisen maininnan: monitoroinnin omat viat.

Yksi kojelaudan paneeleista — sähkömittauksen valvonnan tila — alkoi vilkkua. Välillä se näytti vihreää, välillä oranssia ”ei viestiä”. Data sen takana sahasi tasaisesti kahden arvon väliä, ilman mitään yhteyttä järjestelmän todelliseen tilaan. Juurisyy ei ollut sähkömittarissa vaan valvontatavassa: valvoja katsoi, sattuuko viesti näkymään juuri sen lyhyessä kuunteluikkunassa — puhdas ajoitusarpajainen, jossa noin joka kolmas tarkistus voitti.

Monitorointi on itsekin ohjelmisto, ja sillä on omat buginsa. Valvoja, joka välillä valehtelee, on pahempi kuin valvoja jota ei ole — koska siihen joko lakataan luottamasta, tai pahempaa, sen ilmoituksiin turrutaan. Korjaus noudattaa täsmälleen samaa mallia, joka pelasti varmuuskopiovalvonnan: oikea kysymys ei ole ”näinkö viestin juuri nyt” vaan ”kuinka vanha viimeisin luotettava viesti on”. Ja siihen asti kojelaudan puolella sama vaimennus kuin muuallakin: yksittäinen ohi mennyt näyte ei käännä tilaa — vasta jatkuva hiljaisuus.

Näkyvyyden rakentaminen teki näkyväksi myös valvonnan omat puutteet. Se ei ole häpeä vaan ominaisuus: järjestelmä, joka paljastaa omat vikansa, on tervein mahdollinen.

Kaksi tekoälyä, kuten ennenkin

Kuten edellisessä osassa, käytin myös tässä kahden tekoälyavustajan työnjakoa: toinen auttoi toteutuksessa, toinen katselmoi suunnitelmia ja etsi sokeita pisteitä. Useampi tämän osan tärkeimmistä yksityiskohdista — kaksitasoinen hälytyslogiikka yksittäisen ja yhtäaikaisen vanhenemisen välillä, sekä vaatimus ettei vilkkuva tila jää piiloon — nousi nimenomaan katselmoinnista. Lopulliset päätökset ja testit jäivät ihmiselle, mutta yhden hengen projektissa toinen näkökulma on arvokas — varsinkin silloin, kun rakennetaan turvakerroksia, joiden pitää toimia myös silloin kun muu järjestelmä ei toimi.

Operointi on oma taitonsa

Tämän sarjan alkuosat kertoivat järjestelmän rakentamisesta: miten laitteet liitetään, miten ohjauslogiikka kirjoitetaan, miten optimointi tehdään. Tämä osa kertoi jostain muusta — järjestelmän pitämisestä pystyssä sen jälkeen kun se on rakennettu. Ne ovat eri taitoja, ja jälkimmäinen jää usein huomiotta, kunnes jokin menee hiljaa rikki.

Hiljainen vika on operoinnin keskeisin vihollinen, koska se ei ilmoita itsestään. Kylmä suihku, kahden viikon aukko varmuuskopioissa, pysähtynyt integraatio jota kukaan ei huomaa — ne kaikki jakavat saman piirteen: mikään ei kaadu, mikään ei huuda. Ratkaisu ei ole valppaus, koska ihminen ei jaksa katsoa loputtomiin. Ratkaisu on rakenne: järjestelmä joka kertoo omasta voinnistaan, ja valvoja joka huomaa hiljaisuuden. Ja rakenne ehti todistaa arvonsa ennen kuin tämä artikkeli ehti julkaisuun — sen ensimmäinen aito saalis oli hiljaa rikkoutunut varmuuskopiointi, täsmälleen se vika, jota vastaan se rakennettiin.

Tärkein periaate koko työssä oli silti maltti: valvoja aloittaa katsojana, ei tekijänä, ja saa hampaat vasta kun normaali on mitattu.

Se seuraava askel — hampaiden antaminen valvojalle — on oma tarinansa. Kun järjestelmä osaa luotettavasti havaita että jokin on vialla, seuraava kysymys on: saako se korjata sen itse? Ja jos saa, miten varmistetaan ettei korjaus itse aiheuta vahinkoa — ettei vahtikoira pure väärää jalkaa? Se on fail-safe-arkkitehtuurin aihe, ja se on tulevan osan tarina.


Seuraavaksi: Osa 17 — lämpöpumppu siirtyy final gate -polkuun. Kolme tapaa epäonnistua täysin hiljaa, yksi onnenkantamoinen jossa Thermia validoi koko päätösketjun itse kesken testien — ja miksi mikään ei ole valmista ennen kuin se on todennettu restartin yli.

Piditkö artikkelista?

Seuraa blogia myös Blogit.fi:ssä, niin löydät uudet kirjoitukset helposti.

Seuraa blogia Blogit.fi:ssä