Garo laddbox – dum till smart
För två år sedan installerade jag en laddbox för vår nya bil (en Seat Leon ST e-hybrid), där jag gick på elektrikerns rekommendation – en Garo GLB. 1
Medan det är en stabil och driftsäker laddbox så visade det sig dessvärre att det var en mycket dum sådan, den stödjer inga av de otaliga protokollen som möjliggör smart styrning efter elpris eller liknande (Garo har sedan dess kommit med en "+"-variant som stödjer i.a.f. OCPP). Visade sig också att Seat är ett litet för lite märke för t.ex. Tibber att supporta med smart integration.
Boxen har ett enkelt webbgränssnitt som görs tillgängligt på det lokala nätverket där man kan schemalägga laddning vissa tider eller helt enkelt sätta den till on/off, dock fyller den inte riktigt de lite mer precisa behoven jag har.
Så vad ska man göra om man vill schemalägga laddningen efter elpriset? Hacka boxen såklart!
Uppdatering 2024-06-01: Jag har numera bytt laddbox (till en Zaptec Go) och har därför inte möjlighet att besvara frågor gällande Garo GLB.
Steg 1 – hitta endpoints
Inuti boxen finns en vanlig Raspberry Pi som är själva hjärnan för laddboxen – och då enheten möjliggör en att manuellt ladda in ett firmware så funderade jag först på att ändra i källkoden (i ett par bash-skript som körs i samband med uppdateringen) så att jag kunde SSH:a in i den. Men då jag gärna vill undvika att "bricka" den helt så började jag istället att kika på nätverkstrafiken som går via webbgränssnittet.
Genom att bara kolla i webbläsarens nätverks-"inspector" var det ganska enkelt att hitta intressanta endpoints som används vid olika interaktioner – bl.a. en status-endpoint som kollas av en gång i sekunden:
1# /servlet/rest/chargebox/status23{4 "serialNumber":"xxx",5 "ocppState":null,6 "connectedToInternet":true,7 "freeCharging":false,8 "ocppConnectionState":null,9 "connector":"SEARCH_COMM",10 "mode":"SCHEMA",11 "...":"..."12}
1# /servlet/rest/chargebox/status23{4 "serialNumber":"xxx",5 "ocppState":null,6 "connectedToInternet":true,7 "freeCharging":false,8 "ocppConnectionState":null,9 "connector":"SEARCH_COMM",10 "mode":"SCHEMA",11 "...":"..."12}
Genom att klicka runt hittade jag också /servlet/rest/chargebox/mode/ALWAYS_ON
, /servlet/rest/chargebox/mode/ALWAYS_OFF
och /servlet/rest/chargebox/mode/SCHEMA
som sätter boxen i on/off eller "schema"-läge genom en POST
-request. Användbart värre!
Steg 2 - bygga något för att testa
Då webbgränssnittet endast är tillgänglig när man befinner sig på samma nätverk (antingen genom en router eller direkt uppkoppling emot boxen Wifi-modul) så kan man inte komma åt boxen från vilken server som helst utifrån, utan den behöver vara lokal, och då jag inte har någon server/dator som är på dygnet runt på nätverket så valde jag att använda mig av Apples Shortcuts.
iOS tillåter en att schemalägga automatiserade jobb, och mobilen är alltid kopplad mot nätverket när man är hemma. Så jag byggde ett enkelt flöde där man som användare kan välja om boxen ska vara på, av eller enligt schema.
Detta fungerade finemang, kanske inte särskilt användbart då samma funktionalitet redan finns i webgränssnittet – men visar ändå att metoden fungerar.
Steg 3 – automatisk schemaläggning efter elpris
I webbgränssnittet när man lägger in en "slot" där laddaren ska vara aktiv hittade jag endpointen /servlet/rest/chargebox/schema
dit det postades data i följande format:
1{2 "schemaId": 0,3 "start": "09:00:00",4 "stop": "10:00:00",5 "weekday": "5",6 "chargeLimit": 07}
1{2 "schemaId": 0,3 "start": "09:00:00",4 "stop": "10:00:00",5 "weekday": "5",6 "chargeLimit": 07}
Perfekt, inga konstigheter eller krusiduller. Bara att posta in dag och tider som laddaren ska vara aktiv. Nu behövde jag bara faktiskt få fram de tiderna som laddaren ska vara aktiv; sedan tidigare har jag alla dagens (och morgondagens) elpriser nära till hands via elchock.se så byggde jag ett litet API som spottar ut de fyra billigaste sammanhängande timmarna (då jag bara har en plugin-hybrid brukar jag kunna ladda den på 2-4h) och hämta dem i precis det formatet som Garo-laddboxen behöver:
1[2 {3 "schemaId":0,4 "start":"20:00:00",5 "stop":"21:00:00",6 "weekday":"4",7 "price":0.45419,8 "chargeLimit":09 },10 {11 "schemaId":0,12 "start":"21:00:00",13 "stop":"22:00:00",14 "weekday":"4",15 "price":0.43319,16 "chargeLimit":017 }18 # ...19]
1[2 {3 "schemaId":0,4 "start":"20:00:00",5 "stop":"21:00:00",6 "weekday":"4",7 "price":0.45419,8 "chargeLimit":09 },10 {11 "schemaId":0,12 "start":"21:00:00",13 "stop":"22:00:00",14 "weekday":"4",15 "price":0.43319,16 "chargeLimit":017 }18 # ...19]
Blev sedan till att ånyo bygga en Shortcuts-app som skulle göra allt följande:
- Rensa ut det gamla schemat (via en
DELETE
-request till/servlet/rest/chargebox/schema/{id}
) - Hämta rätt tider efter pris via elchock.se
- Pushar vidare tiderna till laddboxen
Det slutgiltiga flödet blev något sådant här:
Den fula List
-sektionen med 7-1 är då jag inte hittade något annat smart sätt att göra en omvänd for-loop med rätt index för att rensa ut de gamla schemaraderna.
I webbgränssnittet för Garo-laddboxen kan man bekräfta att korrekt schema är inladdat:
Detta jobbet är sedan inlagt att köras varje eftermiddag för att ladda in schemat i laddboxen automatiskt i bakgrunden medan allt jag behöver göra är att se till att bilen är inkopplad.
–
Apples Shortcuts-lösning är långt mer kraftfull än vad man först kan tro där man kan bygga rätt så avancerade automatiseringar. Som programmerare så är det dock något frustrerande emellanåt när man vet precis vad man ska öppna men inte riktigt vet hur – t.ex. så är POST
och DELETE
-requests en inställning i Get URL-funktionen och för att undvika att escape:a JSON så måste man posta en Dictionary-variabel som en fil istället för text.
Om jag hade en lokal server placeras som kunde t.ex. läsa av statusen i någorlunda realtid för att få en uppfattning om laddningsnivå på bilen så skulle man bättre kunna styra schemaalgoritmen – i nuvarande fall om 22:00 är billigare än 20:00 och bilen laddar fullt på en timma så träffar den lite fel. Men rimligtvis är detta bra nog 90% av fallen för mig. 2
Finns så mycket annat att ta hänsyn till också, hittade t.ex. denna avhandlingen från Chalmers som verkar intressant. ↩