
Voimapirtissä on kaksi yksinkertaista painiketta: 80 % aamuksi ja 100 % aamuksi. Painalluksen jälkeen nappi lukittuu aktiiviseksi ja näkymä kertoo, että lataus on tilattu. Ja silti tabletti ei kytke yhtään latausrelettä. Se ei ajasta mitään. Se luo määräaikaan sidotun lataustavoitteen, jota EnergyHub arvioi uudelleen kerta toisensa jälkeen — järjestelmän muun automaation ja turvarajojen rinnalla.
Tämä ero ajastimen ja tavoitteen välillä on koko osan ydin. Ajastin kytkee releen kello 02.00. Tavoite sanoo ”auto riittävän täyteen kello kuudeksi, mahdollisimman halvalla” ja jättää järjestelmän ratkaistavaksi, milloin ja miten se tapahtuu. Ja kun alkaa purkaa sitä, mitä ”riittävän täyteen” oikeasti tarkoittaa, törmää artikkelin toiseen kantavaan väitteeseen:
80 prosenttia on laskettava energiamäärä. 100 prosenttia on auton ilmoittama valmistumisehto.
Ensimmäinen voidaan arvioida melko luotettavasti akun koon, nykyisen varaustason ja lataustehon perusteella. Jälkimmäinen riippuu lisäksi auton omasta akunhallinnasta, lataustehon hidastumisesta loppua kohden, SOC-telemetrian päivitysväleistä ja siitä, milloin auto itse katsoo latauksen päättyneeksi. Nämä eivät ole sama luokka ongelmaa, vaikka käyttöliittymässä ne näyttävät kahdelta vierekkäiseltä napilta.
Mistä tämä jatkaa
Osa 13 käsitteli sähköauton perusoptimointia ja jätti määräaikalatauksen nimenomaan tulevaksi työksi. Jo silloin tunnistettiin lähtökohdat: auto on Nissan Leaf, käytettävä akkukapasiteetti on noin 39 kWh, kotilataus on yksivaiheinen noin 3,6 kW / 16 A, SOC saadaan Nissan-integraatiosta, Shelly Pro 3EM mittaa todellisen lataustehon ja Shelly Pro 1 ohjaa fyysistä latausrelettä. Ja mikä tärkeintä: Nissanin oma charging-tieto ei yksin riitä todistamaan, että lataus todella kuluttaa sähköä. Releen tila, mitattu teho ja auton SOC ovat kolme eri asiaa.
Osa 19 kuvasi käsiohjauksen perusarkkitehtuurin: tabletti ei ohjaa relettä suoraan, vaan lähettää validoidun pyynnön EnergyHubille. Osa 21 yhdistää nämä kaksi lankaa — miten käyttäjän määräaikapyyntö syntyy, miten siitä lasketaan energiantarve ja latausikkuna, miten suunnitelma muutetaan turvalliseksi fyysiseksi ohjaukseksi, miten toteutunut lataus todetaan, ja miksi sadan prosentin tavoite osoittautui erikoistapaukseksi.
Mitä napin painaminen todella tekee
Painike ei lähetä komentoa Shellylle. Se kutsuu EnergyHubin HTTP-taustapalvelua reitillä POST /energyhub/api/ev/charge_by, ja taustapalvelu muodostaa manuaalipyynnön:
{ "schema": "eh.manual.v1", "domain": "ev", "intent": "charge_by", "payload": { "target_soc_pct": 80, "deadline": "seuraava klo 06.00 Europe/Helsinki-ajassa" } }
Pyynnölle luodaan yksilöllinen request_id, eikä selain saa itse määrätä pyynnön elinkaarta tai kirjoittaa suoraan komentotopiceihin. Määräaika lasketaan palvelimella: painike muodostaa määräajaksi seuraavan aamun kello 06.00 Europe/Helsinki-aikavyöhykkeessä. Tabletin kelloon ei tässäkään luoteta.
Ohjausketju on tuttu edellisistä osista, mutta nyt sen läpi kulkee tavoite eikä kytkin:
Voimapirtti → HTTP-taustapalvelu → energyhub/manual/request → B3 manual gate validator → EV Manual Request Manager → retained energyhub/manual/intent/ev → Priority Resolver → EV lease → final_gate → energyhub/command/ev/allowed → Home Assistant → Shelly Pro 1 → rele-, teho- ja SOC-readback
Tärkein arkkitehtoninen kohta on, että manuaalipyyntö tarkoittaa tavoitetta, ei suoraa laitekomentoa. Aktiivinen charge_by saa ohittaa normaalin tilanteen, jossa hinta- tai aurinkologiikka ei muuten juuri sillä hetkellä lataisi autoa. Mutta se ei ohita pääsulake- ja vaihekuormarajoja, vanhentunutta vaihetelemetriaa, järjestelmän safety trip -tilaa, laitteen capability-estoa, final gate -lukkoja, auton poissaoloa eikä fyysisen toteuman tarkistusta. Siksi ”80 % aamuksi” on turvarajojen alainen best-effort-tavoite, ei ehdoton lupaus.
Kahdeksankymmentä prosenttia kilowattitunneiksi
Tässä on artikkelin tärkein konkreettinen laskelma, ja se on lohdullisen suoraviivainen. Puuttuva energia saadaan käytettävästä akkukapasiteetista ja SOC-erosta:
puuttuva energia = 39 kWh × (tavoite-SOC − nykyinen SOC) / 100
Esimerkiksi 70 prosentista 80 prosenttiin se on 39 kWh × (80 − 70) / 100 = 3,9 kWh. Yksi 15 minuutin latausjakso tuottaa nimellisesti 3,6 kW × 0,25 h = 0,9 kWh verkosta, ja 90 prosentin hyötysuhteella siitä päätyy akkuun 0,81 kWh vartilta. 3,9 kWh vaatii siten laskennallisesti noin viisi varttia, ja planneri lisää yhden puskurivartin — yhteensä kuusi varttia eli 90 minuuttia latausaikaa.
Nämä eivät ole paperilaskelmia vaan tuotantokoodista erotetun plannerin testituloksia. Planneri käyttää 15 minuutin jaksoja ja seuraavia oletuksia, jotka on hyvä kirjata näkyviin:
p_ev_battery_usable_kwh = 39 kWh p_ev_charge_power_kw = 3,6 kW p_ev_charge_efficiency = 0,90 p_ev_charge_by_buffer_slots = 1 vartti p_ev_soc_stale_s = 600 s p_ev_full_soc_complete_pct = 98 %
Halvin ikkuna ei ole sama kuin viimeinen turvallinen aloitus
Planneri ei vain poimi irrallisia halpoja vartteja. Se laskee, paljonko latausaikaa tarvitaan, kuinka monta varttia ennen määräaikaa on jäljellä, milloin latauksen on viimeistään alettava, ja löytyykö käytettävissä olevista hinnoista ylipäätään toteuttamiskelpoinen suunnitelma. Kaksi aikaleimaa kannattaa pitää erillään, koska ne tarkoittavat eri asiaa:
Tavoite: 80 % Nykyinen SOC: 70 % Tarvittava lataus: 90 min Suunniteltu alku: 02.00 Suunniteltu loppu: 03.30 Aloitettava viimeistään: 04.30 Määräaika: 06.00
Suunniteltu alku perustuu halvimpaan löydettyyn latausikkunaan. ”Aloitettava viimeistään” — latest start — on turvallinen takaraja, jonka jälkeen hintojen odottaminen alkaisi vaarantaa itse tavoitteen. Niin kauan kuin latest start ei ole lähellä, planneri saa odottaa halvempaa hetkeä. Kun se lähestyy, odottaminen loppuu ja tavoite menee hinnan edelle.
Suunnitelma elää olosuhteiden mukana
Yhden onnistuneen polun näyttäminen antaisi väärän kuvan. Määräaikasuunnitelma on tilakone, ja sen mielenkiintoisimmat tilat ovat ne, joissa asiat eivät mene suoraviivaisesti.
Tavoite jo saavutettu. Jos auto on 80 prosentissa ja tavoite on 80, tarvittava energia on nolla ja tarvittavat vartit nolla. Järjestelmä ei käynnistä latausta pelkästään siksi, että nappia painettiin.
Suunnitelma odottaa halvinta ikkunaa. Auto on kotona, SOC on tuore, hintatiedot riittävät ja aikaa on — mutta halvin ikkuna on vasta myöhemmin, joten rele pysyy toistaiseksi pois päältä. Tämä on normaali ”kaikki hyvin, odotetaan” -tila.
Suunnitelma odottaa hintoja. Määräaika ja energiantarve tunnetaan, mutta huomisen varttihintoja ei vielä ole julkaistu määräaikaan asti. Tässä on tärkeä täsmennys: järjestelmä ei voi valita ”huomisen halvimpia vartteja”, ennen kuin ne hinnat ovat oikeasti saatavilla. Testissä puuttuvat hinnat eivät johtaneet siihen, että auto olisi varmuuden vuoksi käynnistetty heti — planneri jäi odottamaan hintoja niin kauan kuin latest start ei ollut lähellä. Puuttuville hinnoille ei keksitä arvoja.
Auto ei ole kotona. Planneri voi laskea energiantarpeen ja suunnitelman, mutta ei saa käynnistää fyysistä latausta: blocked_by = ev_not_home. Auton palatessa suunnitelma arvioidaan uudelleen.
Opportunistinen lataus. Normaali EnergyHub-automaatio voi haluta ladata jo ennen suunniteltua ikkunaa — hinta on jo edullinen, aurinkoa on tarjolla, tai lataus on jo käynnissä eikä sitä kannata katkaista juuri ennen seuraavaa halpaa varttia. Aktiivinen charge_by ei lukitse autoa odottamaan yhtä ennalta määrättyä alkuhetkeä. Se sallii järkevän normaalin latauksen edetä kohti samaa tavoitetta.
Aikaa ei ole riittävästi. Tämä on turvallisen käyttöliittymän kannalta tärkein tila. Jos SOC on 0 %, tavoite 100 % ja aikaa on jäljellä kaksi varttia, suunnitelma ei ole toteuttamiskelpoinen — 39 kWh vaatisi 750 minuuttia. Silloin järjestelmä ei väitä tavoitteen olevan saavutettavissa. Se aloittaa latauksen heti ja tekee sen minkä ehtii, tilassa best_effort_time_short. Mahdotonta tavoitetta ei muuteta onnistuneeksi suunnitelmaksi vain siksi, että käyttäjä painoi nappia.
Vanhentunut SOC ei ole sama kuin oikea SOC
Nissanin SOC ei päivity jatkuvana reaaliaikamittauksena, joten planneri tarkistaa tiedon iän. Nykyinen raja on 600 sekuntia. Jos viimeisin lukema on sitä vanhempi, järjestelmä ei käytä esimerkiksi vanhaa 70 prosentin lukemaa varmana lähtökohtana, vaan pudottaa suunnittelu-SOC:n konservatiivisesti nollaan:
current_soc_pct = 70 planning_soc_pct = 0 soc_fresh = false soc_estimate = conservative_zero
Tällöin 80 prosentin tavoitteeseen varataan 31,2 kWh, 40 varttia, 600 minuuttia. Se on erittäin varovainen ratkaisu: se vähentää alilatauksen riskiä mutta voi johtaa tarpeettoman pitkään suunnitelmaan. Ja tässä on hyvä esimerkki siitä, miksi käyttöliittymän on näytettävä muutakin kuin prosenttiluku. ”Varaustaso 70 %, päivitetty 4 min sitten” on aivan eri tieto kuin ”Varaustaso 70 %, tiedon ikä 45 min — suunnitelma tehty varovaisella oletuksella”. Sama luku, eri luotettavuus.
Kaksi eri tapaa käyttää varttihintoja
Tässä kohtaa on syytä erottaa kaksi läheistä mutta eri asiaa. Aktiivisen charge_by-pyynnön planneri palvelee käyttäjän nimenomaista tavoitetta: ”haluan auton 80 tai 100 prosenttiin kello kuudeksi”. Se laskee tarvittavat vartit ja valitsee määräajan sisältä edullisen toteutuksen.
Sen rinnalle on rakennettu erillinen aamukuuden hintaennuste, joka voi ilman aktiivista pyyntöä arvioida, mikä SOC olisi aamukuudelta pelkällä normaalilla hintaohjauksella, montako latausvarttia olisi käytössä, ja tarvittaisiinko erillistä 80 tai 100 prosentin tilausta ollenkaan. Sen skeemassa on kentät kuten forecast_at_06_pct, delivered_kwh, cheap_slots_count, price_window_complete ja confidence. Jos hintajakso ei ulotu kokonaan seuraavaan aamukuuteen, ennuste palauttaa rehellisesti available = false, reason = price_window_incomplete — se ei keksi puuttuville hinnoille arvoja. Tässä taustaennusteessa aurinkolataus on tarkoituksella erotettu vahvistetuista hintavarteista: illalla tehtävässä arviossa huomisen aurinko on epävarmempi kuin julkaistu varttihinta.
Ratkaisevaa on, että ennuste on havainnointia, ei fyysisen ohjauksen omistaja. Se kertoo mitä todennäköisesti tapahtuu; se ei yksin käynnistä relettä.
Kaksi korjausta, jotka kuulostavat pieniltä mutta eivät ole
Toteutuksesta poistettiin vanhentunut kiinteä ”halpa hinta” -kynnys (commit 18993d0). Järjestelmään ei haluttu kahta rinnakkaista totuutta: vanhaa kiinteää hintarajaa ja varttisuunnitelmasta johdettua dynaamista logiikkaa. Tämä on sama sarjan läpi kulkeva opetus kuin osan 18 legacy-ohjauspolku — vaarallista ei ole vain algoritmin vaikeus, vaan se, jos vanhaa ja uutta päätöslogiikkaa jää elämään rinnakkain.
Toinen korjaus koski seuraavan halvan vartin ennakointia (commit 4eb9943). Alkuperäinen logiikka saattoi tulkita ”onko seuraava vartti halpa” liian laajasti ja käynnistää latauksen yhden vartin etuajassa. Korjaus rajasi merkityksen: jos lataus on jo käynnissä ja seuraava vartti on halpa, sitä voidaan jatkaa ilman turhaa katkaisua — mutta jos lataus ei ole käynnissä, seuraavan halvan vartin tieto ei yksin käynnistä sitä etuajassa. Ero on hiuksenhieno ihmiselle mutta ratkaiseva releelle: ”älä katkaise juuri ennen halpaa varttia” ja ”käynnistä ennen halpaa varttia” kuulostavat melkein samalta, mutta ovat fyysiselle releelle täysin eri komentoja.
Kahdeksankymppinen valmistui — kahdeksassakymmenessä
80 prosentin määräaikapolku on toteutettu ja se on saavuttanut terminal-tilan puhtaasti:
target_soc_pct = 80 completion_soc_pct = 80 observed_soc_pct = 80 state = completed completed_at = 20.7.2026 klo 18.23.25
Järjestelmä ei vain lakannut pyytämästä latausta. Manual Request Manager kirjoitti retained-intentin valmistuneeksi ja säilytti alkuperäisen request ID:n, tavoitteen, toteutuneen SOC:n, valmistumisajan ja edellisen intentin. Näin käyttöliittymä osaa erottaa toisistaan ”ei aktiivista pyyntöä” ja ”80 % -pyyntö valmistui onnistuneesti” — kaksi tilaa, jotka ilman tätä näyttäisivät samalta tyhjältä.
Sadan prosentin ensimmäinen yön yli -testi
Sitten se mielenkiintoisempi tavoite. Ensimmäisessä dokumentoidussa 100 prosentin testissä 20.7. noin klo 21.04 lähtötilanne oli 84 %, tavoite 100 %, completion-raja 98 %, määräaika seuraavana aamuna kuudelta. Planneri laski yhdeksän varttia, 135 minuuttia, suunnitellun alun klo 03.30, latest start klo 03.45 — suunnitelma oli toteuttamiskelpoinen. (Järjestelmän JSONissa aikaleimat olivat UTC-muodossa, joten 00:30Z tarkoitti heinäkuussa Suomen aikaa klo 03.30.)
Mutta auto ei odottanut kello 03.30 asti. Normaali automaatio löysi jo keskiyöllä edullisen lataustilanteen, ja aktiivinen määräaikapyyntö siirtyi tilaan charge_by_opportunistic_normal_charge. Lataus jatkui noin 3,7 kW teholla. Kello 01.30 paikallista aikaa SOC päivittyi 98 prosenttiin, planneri palautti charge_by_target_met_soc_98_target_100, ja Manual Request Manager merkitsi 100 prosentin pyynnön valmistuneeksi. Heti tämän jälkeen normaali hintalogiikka salli latauksen uudelleen, koska sähkö oli yhä halpaa, ja auto jatkoi oman akunhallintansa ohjaamana täyteen. Aamulla se oli sadassa prosentissa.
Testi todisti, että koko ketju toimii: pyyntö säilyi aktiivisena, hinnat ja määräaika muodostivat toteuttamiskelpoisen suunnitelman, final gate välitti latausluvan, rele ja todellinen teho vastasivat päätöstä, SOC saavutti 98 prosentin valmistumisrajan, ja auto saavutti myöhemmin todellisen 100 prosentin varaustason.
Mutta se paljasti myös semanttisen ongelman, ja tämä on artikkelin tekninen käännekohta: charge_by ilmoitti sadan prosentin tehtävän valmistuneeksi jo 98 prosentissa. Varsinainen sataan asti jatkaminen tapahtui tällä kertaa normaalin halvan hinnan automaation ansiosta. Jos normaali automaatio ei olisi juuri silloin jatkanut latausta, ”100 % aamuksi” -pyyntö olisi voinut päättyä järjestelmän mielestä onnistuneena, vaikka auto olisi jäänyt 98 prosenttiin.
Toinen testi: 48 prosentista aamuksi
Jotta ensimmäinen ei jäisi sattumaksi, toinen yön yli -testi alkoi paljon matalammalta. Nykyinen SOC 48 %, tavoite 100 %, energiantarve noin 20,28 kWh, tarvittavat vartit 27, tarvittava aika 405 minuuttia, suunniteltu alku noin klo 23.15, loppu klo 06.00, price plan -keskihinta noin 0,0192 €/kWh, feasible = true. Planneri odotti ensin suunniteltua ikkunaa ja siirtyi sitten lataukseen.
Retained-intent kirjasi:
state = completed target_soc_pct = 100 completion_soc_pct = 98 observed_soc_pct = 98 completed_at = 22.7.2026 klo 03.47.27
Aamun myöhempi tilanne oli SOC 100 %, relay_actual = true, power_w = 0, status = relay_on_no_power. Auto oli täynnä, mutta rele jäi sallituksi eikä auto enää ottanut tehoa. Tämä ei ollut päätöksen ja fyysisen toteuman ristiriita vaan normaali täyden auton tila. Toinenkin testi siis vahvisti käytännön toiminnan — ja toisti täsmälleen saman kysymyksen: aktiivinen sadan prosentin intentti valmistui 98 prosentissa.
Miksi sata prosenttia on eri asia kuin kahdeksankymmentä
Kahdeksaankymmeneen asti lataus on lähellä lineaarista. Tavallisella AC-latauksella Leaf ottaa suurimman osan matkasta lähes vakiotehon, jolloin SOC-muutoksen voi arvioida melko hyvin kaavalla energia jaettuna tehokkaalla latausteholla. Loppupäässä auton oma akunhallinta ottaa ohjat, ja silloin lineaarinen oletus pettää. Aiemmassa mittauksessa 29.5.2026 tämä näkyi selvästi:
SOC Mitattu teho 85–95 % noin 3,71–3,78 kW 98 % noin 2,87 kW 100 % noin 0,63 kW 100 % jälkeen pieni teho jatkui vielä pitkään
Teho alkoi laskea noin 97–98 prosentin kohdalla, loppuvaihe saattoi kestää 60–75 minuuttia, ja auton SOC saattoi näyttää 100 prosenttia ennen kuin latausvirta loppui kokonaan — akunhallinta viimeisteli latausta vielä lukeman saavuttamisen jälkeen. Tästä seuraa kolme eri ”valmis”-määritelmää, jotka eivät toteudu samalla hetkellä: SOC näyttää 100 %, SOC on vähintään valmistumisrajan (esim. 98 %), tai auto ei enää ota merkittävää tehoa.
Completion-rajaksi valittiin 98 prosenttia juuri siksi, ettei aktiivinen intentti jää roikkumaan viivästyvää Nissan API -päivitystä, hidasta tasapainotusta tai pientä loppuvaiheen tehoa odottamaan. Ratkaisu estää zombie-intentin — mutta samalla se tekee käyttäjälle näkyvästä ”100 %” -lupauksesta epätarkan. Tässä on rehellisyyden paikka: nykyinen tuotantoplanneri ei mallinna koko taper-käyrää. Sen todennettu logiikka nojaa 39 kWh kapasiteettiin, 3,6 kW tehoon, 90 prosentin hyötysuhteeseen, yhteen puskurivarttiin ja sadan prosentin pyynnön 98 prosentin completion-rajaan. Mitattu loppupään hidastuminen selittää, miksi sadalle prosentille tarvitaan oma valmistumispolitiikka — mutta itse valmistuminen ratkaistaan tuolla completion-rajalla, ei tarkalla käyrämallilla.
Milloin auto oikeasti lataa
Järjestelmä ei päättele latausta pelkästä releestä. Rele pois ja teho 0 W on relay_off — lataus ei ole fyysisesti sallittu. Rele päällä ja teho noin 3,6–3,8 kW on charging — auto ottaa oikeasti tehoa. Mutta rele päällä ja teho 0 W on oma tilansa, relay_on_no_power, joka voi tarkoittaa montaa asiaa: auto on jo täynnä, autoa ei ole kytketty, auton oma ajastus estää latauksen, auto ei juuri nyt pyydä virtaa, käynnistymisessä on viive, tai fyysisessä polussa on ongelma. Tätä tilaa ei saa automaattisesti nimetä viaksi. Sen merkitys riippuu SOC:sta, kotonaolosta, telemetrian iästä ja siitä, onko latauksen juuri pitänyt käynnistyä. Sadan prosentin testin aamuna SOC 100 %, rele päällä, teho 0 W oli täysin normaali täyden auton tila.
Planneri päättää, milloin latausta tarvitaan. Final gate päättää, saako päätös muuttua fyysiseksi komennoksi. Priority Resolver ei kirjoita suoraan Shellylle, vaan sen päätös muutetaan lyhytikäiseksi EV leaseksi, jonka final gate tarkistaa — onko lease voimassa, haluaako se latauksen päälle, onko turvalukkoja, onko ohjauspolku fyysinen. Vasta tästä muodostuu energyhub/command/ev/allowed, ja vasta sitten Home Assistant toteuttaa releohjauksen.
Kun pääsulake voittaa täydellisen hintasuunnitelman
Leaf lataa yhdeltä vaiheelta noin 16 ampeerilla, ja talon pääsulakkeet ovat 3 × 25 A. Juuri L1-vaiheen muu kuorma ratkaisee, voidaanko lataus käynnistää. Kun rele on pois päältä, start admission laskee mitatun nykyisen vaihevirran plus Leafin odotetun 16 A kuorman, ja jos ennuste ylittää rajan, käynnistys estetään tai siirtyy. Tämä voi tuottaa tilanteen, jossa hinnan perusteella valittu vartti olisi optimaalinen ja aikaa olisi teoriassa riittävästi, mutta pääsulakevahti estää latauksen — ja plannerin suunnitelma eroaa toteumasta turvallisuussyystä. Silloin käyttäjälle ei riitä ”Lataus suunniteltu 02.00–04.30”, vaan tarvittaessa on kerrottava ”Lataus viivästyy: vaihekuorma estää käynnistyksen, tavoite on edelleen mahdollinen” — tai pahemmassa tapauksessa ”Tavoitetta ei ehkä saavuteta: turvallisuusraja on estänyt latausta 75 min, paras mahdollinen lataus jatkuu”.
Restart-kestävä tavoite ei saa olla ikuinen tavoite
charge_by tallennetaan retained manual intentinä, joten Node-REDin tai palvelimen uudelleenkäynnistys ei unohda, että auto piti ladata aamuksi. Sama retained-tila on kuitenkin riski, jonka tämä sarja on nähnyt aiemminkin: ilman määräaikaa tai terminal-tilaa vanha latauspyyntö voisi nousta restartin jälkeen zombina takaisin eloon. Siksi intentillä on yksilöllinen request ID, deadline, aktiivinen tila, completed-tila, cleared-tila, havaittu valmistumis-SOC, valmistumisaika ja edellinen intentti. Periaate tiivistyy yhteen lauseeseen: restart-kestävä tavoite ei saa olla ikuinen tavoite.
Mitä Voimapirtin pitäisi luvata
Kaikki edellä johtaa yhteen käyttöliittymäkysymykseen: mitä paneeli saa sanoa? Ero on kolmijakoinen — tavoite, ennuste ja vahvistettu toteuma ovat kolme eri asiaa, eikä niitä saa esittää yhtenä.
Aktiivisen latauspyynnön ennusteessa on kentät kuten forecast_at_deadline_pct, estimated_finish_at, planned_start_at, confidence, delivered_kwh ja slots. Mukana on myös kaksi kenttää, joiden ero on olennainen: assumption_connected = true ja connected_verified = false. Järjestelmä voi suunnitella sillä oletuksella, että auto on kytketty, mutta sillä ei ole vielä kaikissa tilanteissa varmaa erillistä tietoa kaapelin kytkennästä. Siksi käyttöliittymä ei saa sanoa ”Auto on varmasti valmis klo 06.00” vain siksi, että laskennallinen suunnitelma näyttää hyvältä. Rehellisempiä muotoiluja ovat ”80 % arvioitu klo 06.00 — auton oletetaan olevan kytketty” tai ”Tavoite saavutetaan nykyisellä suunnitelmalla, mikäli auto pysyy kytkettynä eikä turvaraja keskeytä latausta”.
Demossa sadan prosentin tilauksen teksti on ollut ”Vähintään 100 % määräaikaan mennessä”, ja se ei ole hyvä ilmaisu. Yli sataa prosenttia ei ole, järjestelmän oma completion-raja on 98 prosenttia, ja kyse on tavoitteesta tai ennusteesta, ei absoluuttisesta takuusta. Parempi olisi ”100 % tilattu aamuksi — tavoite klo 06.00, suunnitelma valmis”, tai kun luottamus on heikompi, ”100 % tavoite aamuksi — arvio 98–100 %, loppulatauksen kesto vaihtelee”. Käyttöliittymän eri tilat — odottaa hintoja, best-effort, auto ei kotona, pääsulake estää, loppuvaihe käynnissä, auto täynnä — ansaitsevat kukin oman ihmiskielisen tekstinsä sen sijaan, että ne kaikki näyttäisivät ”lataus tilattu”.
Opit
Määräaikalataus ei ole ajastin, vaan tavoite turvarajojen alla. Nappi ei kytke relettä kello 02.00. Se luo tavoitteen, jonka järjestelmä arvioi uudelleen joka kierroksella muun automaation ja turvarajojen rinnalla — ja jonka turvaraja saa perustellusti estää.
80 % on laskettava, 100 % on neuvoteltava. Kahdeksankymmenen prosentin energiantarpeen saa akun koosta ja SOC-erosta melko luotettavasti. Sadan prosentin kohdalla auton oma akunhallinta, taper-käyrä ja telemetrian viive tekevät ”valmiista” määrittelykysymyksen, ei laskutoimituksen.
Valmistumisraja on kompromissi, ei totuus. 98 prosentin completion-raja estää zombie-intentin mutta tekee sadan prosentin lupauksesta epätarkan. Molemmat testit päätyivät aamulla oikeaan sataan prosenttiin, mutta molemmissa intentti merkittiin valmiiksi jo 98:ssa — ja toisella kertaa se olisi voinut jäädä siihen, ellei normaali halvan hinnan automaatio olisi jatkanut.
Tavoite, ennuste ja toteuma ovat kolme eri asiaa. Sama ”komento ≠ toteuma” -periaate, joka on kulkenut tämän sarjan läpi releistä lähtien, laajenee tässä kolmeksi: mitä käyttäjä pyysi, mitä järjestelmä arvioi tapahtuvan, ja mitä oikeasti mitattiin. Käyttöliittymä saa näyttää kaikki kolme — mutta ei sekoittaa niitä yhdeksi lupaukseksi.
Rele päällä ei tarkoita, että auto lataa. relay_on_no_power on normaali tila täydelle autolle. Todellinen teho on aina tarkistettava, eikä yksikään tila saa muuttua ”viaksi” ilman, että SOC, kotonaolo ja telemetrian ikä on otettu huomioon.
Mitä vielä avoinna
Rehellisyyden nimissä osa isoimmista kysymyksistä on tarkoituksella jätetty auki. Miten sadan prosentin valmistuminen pitäisi lopulta määritellä? Todennäköisesti yhdistelmänä: pyyntö on valmis, kun tuore SOC on 100 %, tai kun SOC on vähintään 98 % ja auto ottaa alle 200 W yhtäjaksoisesti määritellyn ajan ja varattu loppulatauspuskuri on kulunut. Tähän liittyy kysymys, pitäisikö sadan prosentin tavoitteen pysyä aktiivisena 98 prosentin jälkeen omana finishing-tilanaan, jolloin Voimapirtti näyttäisi ”98 % · loppulataus käynnissä” sen sijaan että hyppäisi suoraan valmiiseen.
Lisäksi auki ovat toteutuneen energian perusteella tarkentuva ennuste (Shellyn mittaama latausenergia täydentämässä viivästyvää Nissan-SOC:ta, ei korvaamassa sitä terminal-päätöksessä), kytkentätiedon varsinainen vahvistus, sekä DST-, restart- ja turvalukko-soak-testit. Aamukuusi muodostetaan jo oikein Europe/Helsinki-aikavyöhykkeessä eikä ”nyt plus tuntimäärä” -laskuna — kesä- ja talviaikaan siirtyvässä yössä vuorokaudessa on eri määrä vartteja — ja Voimapirtin fixtureissä on jo 100 vartin DST-päivä, mutta pitkäkestoinen määräaikapolun DST-hyväksyntätesti on vielä ajettava.
Määräaikalatauksen vaikein osa ei lopulta ollut halvimpien varttien järjestäminen. Vaikeinta oli päättää, mitä ”valmis” tarkoittaa järjestelmässä, jossa käyttäjä pyytää 100 prosenttia, auton API ilmoittaa 98, latausteho alkaa laskea — ja akku on silti aamulla oikeasti täynnä.
Seuraavassa osassa siirrytään ohjaamisesta mittaamiseen. Koko tämä sarja on rakentanut järjestelmää, joka tekee päätöksiä — mutta yksikään päätös ei ole parempi kuin data, jonka varaan se rakennetaan. Siitä, miten raakatelemetriasta tehdään luotettavaa aineistoa, miten lämmitys- ja käyttövesijaksot erotetaan toisistaan ja miksi hiljainen data-aukko on vaarallisempi kuin näkyvä virhe, kertoo osa 22.