Wallbox do EV - Krótka historia i dlaczego jest to opcja?

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 :wink:

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ą :confused: 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 :smiley:

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! :smiley:

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

  1. Wykonanie jest poprawne
  2. Klasa IP również
  3. Cenowo chyba taniej się nie da - dodatkowo znaczyć CE i TUV czego w chińczykach brakuje
  4. Oficjalna aplikacja to coś czego nigdy używał nie będę - wolę osobny panel w HA.
  5. 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ł :wink: 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

2 polubienia

Zmiana prądu następuje dynamicznie, czy stop ładowania, zmiana max prądu, start ładowania? Tak działają najczęściej te z tuya co nie jest dobrym rozwiązaniem.

Dodatek sam w sobie nie ma logiki zarządzania prądem - to jest po Twojej stronie by sobie ją wdrożyć w node-red czy innej automatyzacji.
Mniej więcej działa to tak:

  1. Przy definiowaniu urządzenia ustawiasz sobie maks dla swojej instalacji - np. 16A albo 20A czy 32A - HA sam w sobie nie pozwoli na ustawienie powyżej tego bo integracja zablokuje (pomijając już, że to samo fizycznie ustawiasz w tym wallbox przez potencjometr).
  2. start “transakcji” (ładowania) wywoływany jest z pierwszym kluczem RFID dla danego użytkownika - znaczenia to nie ma większego, którego klucza użyjesz bo nie są one identyfikowalne - tylko identyfikują specyficznego użytkownika
  3. Włączenie i wyłączenie transakcji to przycisk switch.
  4. Zmiana aktualnego limitu w przedziale 6 - zdeklarowana wartość odbywa się przez ustawienie “max_load” i nie wymaga wyłączania transakcji - podczas trwającego ładowania możesz sobie ustawić dowolny max_load.

PS. Pewnie wallbox potrafi to sam ogarniać też bo ma licznik 2-kierunkowy i modbus ale ja nie mam PV więc nie sprawdzę i się nie wypowiem.

PS2. Jeszcze mi kilka poprawek zostało z jednostkami itp. ale w przeciągu tygodnia max powinienem to ogarnąć (o ile nie dziś wieczorem). Czy działa? Tak działa wystarczająco dobrze by móc tego używać. Nie wali błędami przez parę hacków dotyczących jak to ma być zarządzane, kolejkowania i priorytetów.

PS3. Taka “automatyzacja” o której mówisz potrzebowała by dostarczania dodatkowi jakichkolwiek paramterów dot. produkcji/użycia w domu więc nie ma możliwości by dodatek sam to z siebie robił bez jakiejś zaawansowanej logiki i pewnie koniec końców i tak nie był byś zadowolony do końca. Zrobienie tego w node-red to 10 minut i zmiana max_load nie wymaga zatrzymania transakcji, więc to jest to o co pytasz.

OK, Wersja finalna 0.1.0 wypuszczona. Działa stabilnie, poprawione pare rzeczy, dodane translacje na kilka języków i popoprawiane jednostki. Na najprostszym panelu prezentuje się to tak:


Wszystko jest w wybranych unitach w HA więc bez problemu można sobie to pokonwertować.

Może jeszcze chwilę powalczę z translacjami bo średnio mi się podobają.