Cześć.
Dawno mnie nie było, ale jak już jestem to wracam z czymś co każdy lubi - a mianowicie moją historią z EVSE i kupowaniem “nieznanego” sprzętu
WSTĘP
Jako, że przesiadłem się na elektryka to przydało by się powiesić jakiś wallbox co by nie ciągać się z ładowarką mobilną, po przejrzeniu parudziesięciu for i wątków w rozsądnej moim zdaniem cenie miałem albo chińczyka albo zwiększyć budżet do kilku tysięcy - obie te opcje średnio mi odpowiadały. Po przejrzeniu kilku stron wpadło mi w oko coś takiego: AEG Wallbox ECO Line Supreme 22kW. Skuszony znaczkiem CE i ceną (w promce był poniżej 180Eur, teraz jest 199Eur choć na niektórych stronach nadal wisi w cenie ~ 900Eur) skusiłem się na zakup.
Po chwili organizacji dostarczenia go poza DE (mogę polecić z czystym sumieniem bodycar) trafił w moje ręce.
Po otwarciu widać trochę elektroniki, licznik dwukierunkowy z modbus, kilka złącz do RS, Eth, Modbus i ESP32 - no w sumie nie jest źle. Oczywiście bez żadnych testów powiesiłem go na ścianie i zaczęły się pierwsze …
PROBLEMY
Aplikacja AEG PowerUP nie istnieje xD Tak więc dokumentacja ma nie wiele wspólnego z realiami. No OK ale w środku wszędzie jest brand LRT eMobility a aplikacja LRT PowerUP istnieje i w sumie wallbox LRT wygląda 1:1 jak ten AEG więc pewnie jest to tylko rebrand. Aplikacja nie jest dostępna poza DE do instalacji ze sklepu, no ale pliki xapk jak zwykle po internecie latają więc pobrałem ją z innego źródła, zainstalowałem i przystąpiłem do wstępnej konfiguracji przez bluetooth. Konfiguracja strasznie oporna i skończyło się kilkukrotnym czyszczeniem danych aplikacji i ponownym logowaniem.
Wifi skonfigurowane, w sieci widzę nowy IP urządzenia - super, teraz będzie już tylko z górki… Niestety nie, aplikacja o ile po bluetooth działa, o tyle poprzez LAN nie wykrywa sprzętu. No dobra, ale przecież jest tam jakaś chmura od LRT - spróbujmy podpiąć wallboxa - zarządzanie przez chmurę też jest spoko opcją. Po rejestracji i chwili kombinacji - udało się, wallbox działa online przez chmurę, przyjmuje polecenia i w sumie jest dobrze… do czasu.
Oczywiście nie był bym sobą, gdybym nie przećwiczył co się stanie przy zaniku zasilania itp. Kilka minut zabawy i wallbox nie łączy się z chmurą a poza tym ta chmura jakoś do mnie średnio przemawia bo znów chodzi to jak krew z nosa z aplikacją LRT PowerUP.
Idziemy dalej…
No OK rm-rf, kupiłeś sobie kawałek elektroniki, który średnio działa - jak zwykle z resztą z twoimi pomysłami, no ale przecież jest ta nieszczęsna aplikacja mobilna, która działa ale tak nie do końca. Może da radę to jakoś ogarnąć?
Szybki skan IP przez nmap no i mamy port 80
(tyle to mogłem z ręki sprawdzić -_-‘’), no ale sam w sobie nie wiele zwraca - brak panelu. OK czas na skan dirb. Jest odpowiedź na endpoincie /api
- OK to coś już mamy, tylko jak się z tym endpointem dogadać? W ruch poszła analiza pliku XAPK. Aplikacja napisana w DART
, po 10 minutach walki miałem cały kod aplikacji w assemblerze. Widać definicje obiektów, widać cały REST - no OK, nie jest źle! Przecież mogę sobie to bezpośrednio po API podpiąć do Home Assistant i w sumie i tak miałem zamiar to osiągnąć więc tą aplikację możemy całkowicie olać i zrobić to poprawnie
Komunikacja
No dobra, widzę, że wszystkie zapytania lecą w POST
, mam JSONy do tego i wstępnie rozgryzłem jak działa autoryzacja przy pomocy hasła, kilka prób odczytu danych zakończone fiaskiem. Powtórka z analizy kodu… o! przecież oni tutaj zaimplementowali cbor w celu kompresji zapytań. Dorzucamy do testowej aplikacji cbor na payload zapytań i mamy odpowiedź (również skompresowaną cbor), rozpakowujemy i naszym oczą ukazuje się
{'key': 'response/auth/password', 'body': {'authenticated': True}}
No dobra to czas poczytać wszystkie dane z wallbox, co tam mamy i co możemy ustawić. Część kluczy działa przy użyciu loginu i hasła a część zwraca
{'key': 'response/transaction/get', 'error': {'kind': 'Permission', 'message': 'publickey auth required'}}
Wygląda na to, że jest druga autoryzacja - przy pomocy klucza publicznego zapisanego per-user. Sprawdźmy co mamy dla zalogowanego usera:
{'key': 'response/user/current', 'body': {'id': 1, 'name': 'rm-rf', 'admin': True, 'color': {'red': 0, 'blue': 0, 'green': 0}, 'publicKey': [2, 107, 121, 1, 73, 195, 8, 50, 10, 174, 139, 196, 187, 56, 182, 181, 180, 229, 51, 53, 206, 74, 43, 239, 59, 4, 85, 90, 207, 154, 238, 124, 131]}}
Kurcze, klucz publiczny ma 33 bajty - po przeszukaniu kodu ponownie wpadłem na sposób generowania kluczy - SECP256R1 i faktycznie klucz ma 33 bajty w tym kodowaniu.
No ale wiedząc jak działają klucze publiczny + prywatny wiem, że nie mogę wygenerować klucza prywatnego znając tylko publiczny. Czyszczenie danych aplikacji mobilnej, logowanie, ponowna analiza co zwraca user/current
- no i klucz się zaktualizował. OK przy logowaniu aplikacja aktualizuje klucz publiczny do nowego klucza prywatnego. Ponownie analiza endpointów i zapytań i “mamy to” nowy klucz wygenerowany na komputerze jest “wstrzyknięty” w profil użytkownika!
Z górki
Po implementacji klasy do obsługi wszystkich zapytań mamy dostępne takie dane, które przy okazji można ustawiać w wallbox przez zapytania:
Info o current user:
{'key': 'response/user/current', 'body': {'id': 1, 'name': 'rm-rf', 'admin': True, 'color': {'red': 0, 'blue': 0, 'green': 0}, 'publicKey': [2, 107, 121, 1, 73, 195, 8, 50, 10, 174, 139, 196, 187, 56, 182, 181, 180, 229, 51, 53, 206, 74, 43, 239, 59, 4, 85, 90, 207, 154, 238, 124, 131]}}
Info o transakcji:
{'key': 'response/transaction/get', 'body': {'ocppCpState': 'Available', 'connectionState': 'A', 'currentChargeRate': 0, 'authorizationState': 'NotAuthorized', 'secondsSinceChargeStart': 0, 'currentTransactionEnergy': 0}}
Lista wszystkich użytkowników:
{'key': 'response/user/get', 'body': [{'id': 1, 'name': 'rm-rf', 'admin': True, 'color': {'red': 0, 'blue': 0, 'green': 0}, 'publicKey': [2, 107, 121, 1, 73, 195, 8, 50, 10, 174, 139, 196, 187, 56, 182, 181, 180, 229, 51, 53, 206, 74, 43, 239, 59, 4, 85, 90, 207, 154, 238, 124, 131]}]}
Lista kluczy RFID:
{'key': 'response/rfid/get', 'body': [{'name': 'rm-rf', 'tagId': [0, 0, 0, 0, 0, 0, X, X, X, X], 'userId': 1}]}
Status SETUP:
{'key': 'response/setup/get', 'body': {'network': True, 'ambientLight': True, 'maxChargingPower': True}}
Ustawienie maksymalnego Load na ten moment w amperach:
{'key': 'response/config/load/get', 'body': {'maxCurrent': 16}}
Konfiguracja OCCP - można używać swojego serwera zgodnego z 1.6 co polubią posiadacze PV:
{'key': 'response/config/ocpp/get', 'body': {}}
Konfiguracja sieci:
{'key': 'response/config/network/get', 'body': {'wifi': {'mode': 'DHCP', 'ssid': 'NazwaWIFI', 'password': 'Haslo'}, 'ethernet': {'mode': 'Off'}}}
Status sieci:
{'key': 'response/config/network/status', 'body': {'wlan': 'Connected', 'ethernet': 'NotConnected'}}
Informacja o firmware:
{'key': 'response/info/firmwares/get', 'body': {'esp': {'major': 1, 'minor': 6, 'patch': 2}, 'atmel': {'major': 1, 'minor': 3, 'revision': 2, 'buildNumber': 0}}}
Informacja o numerze seryjnym urządzenia:
{'key': 'response/info/serial/get', 'body': {'serialNumber': 'XXXXXXXX'}}
Oczywiście 95% tych parametrów można ustawić samemu co daje dość fajną integrację
Zakończenie
Sądzę, że w przeciągu tygodnia na pypi opublikuję paczkę do pythona do pełnego zarządzania tym WALLBOX przy pomocy REST i zacznę pisać integrację do HACS.
Moje odczucia odnośnie tego wallbox
- Wykonanie jest poprawne
- Klasa IP również
- Cenowo chyba taniej się nie da - dodatkowo znaczyć CE i TUV czego w chińczykach brakuje
- Oficjalna aplikacja to coś czego nigdy używał nie będę - wolę osobny panel w HA.
- Czy kupił bym raz jeszcze? Zdecydowanie tak choć fajnie by było wiedzieć to, że oficjalna aplikacja nie nadaje się do niczego.
Jeśli jest ktoś zainteresowany tym tematem to chętnie przyjmę jakąkolwiek pomoc - testowanie, dump esp, firmware jeśli ktoś może ma itp.
Na ten moment projekt jest skończony w 90% więc na pewno go wypuszczę.
[EDIT]
Klasa do zarządzania dostępna pod: Client Challenge
[EDIT2]
Jak powiedział, tak zrobił Poniżej galeria zdostępnymi opcjami dla tego wallbox i zrobioną integracją. Wyszły małe poprawki w klasie do zarządzania + integracja jest napisana w dużej mierze “na kolanie” - potrzebuje kilku poprawek, między innymi z przechowywaniem kilku stanów.
[EDIT3]
GitHub - Upgreydd/lrt_wallbox_hacs: LRT eMobility (and AEG rebrand) Wallbox HACS Integration - repo dla HACS