thedeemling / hass-energa-my-meter

Home Assistant custom integration to gather data from the Energa My Meter (https://mojlicznik.energa-operator.pl/) website.
https://gitlab.com/home-assistant-custom-components/hass-energa-my-meter
Other
2 stars 0 forks source link

ładowanie statystyk historycznych z liczników dwukierunkowych (instalacja PV) #8

Open paki111 opened 1 week ago

paki111 commented 1 week ago

Wiem, że ładowanie danych historycznych jest ustawione paczkami po 60 dni (1440 rekordy statystyk godzinowych). Załadowałem tak wczoraj dla kilku liczników po 730 dni, czyli max co daje nam platforma mójlicznik. Dla standardowych liczników konsumenckich gdzie jest tylko energia pobrana z sieci, wszystko działa prawidłowo.

Niestety zauważyłem, że dla liczników prosumenckich (dwukierunkowych) gdzie są dwie encje statystyczne czyli energia pobrana z sieci i oddana do sieci, nie ładują się wszystkie dane dla maksymalnego okresu 730 dni. Ponawiałem przez inicjalizację ręczną oraz przez ustawianie różnych czasów aktualizacji automatycznej.

Na początku wszystko wyglądało prawidłowo. Załadowały się dwie pierwsze paczki po 60 dni czyli dostałem 2880 rekordów dla każdej encji. Później się okazało, że kolejne paczki już się nie ładują. Podejrzewam, że w pierwszej fazie integracja pobiera dane, bo zauważyłem jak po inicjalizacji procesor pracuje, ale dużo dłużej niż dla licznika z jedną encją i w pewnym momencie przestaje a dane nie lądują w bazie. Z pamięcią RAM jest ok, tzn. nie przepełnia się a sam HA nie natrafia na żaden błąd krytyczny. Poniżej zrzut z bazy jak wygląda podsumowanie ilościowe statystyk ze wszystkich liczników gdzie mam pełną historię 730 dni.

statystyki_hist_my_meter

To jest wycinek logów, który wydaje się najlepszy:

ERROR (MainThread) [custom_components.energa_my_meter.hass_integration.energa_coordinator] Unexpected error fetching Energa My Meter data
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 382, in _async_refresh
    self.data = await self._async_update_data()
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/energa_my_meter/hass_integration/energa_coordinator.py", line 42, in _async_update_data
    return await get_instance(self.hass).async_add_executor_job(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/energa_my_meter/hass_integration/energa_coordinator.py", line 75, in refresh_data
    statistics[mode] = updater.gather_stats(EnergaStatsModes[mode])
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/energa_my_meter/hass_integration/data_updater.py", line 89, in gather_stats
    point.date_to.strftime(DEBUGGING_DATE_FORMAT)
    ^^^^^^^^^^^^^

Załączam jeszcze dodatkowe logi. W pierwszym widać encję energy_consumed, ale nie widać energy_produced. W drugim logu po dodaniu licznika na nowo, czyli ładowaniu danych od początku, widać Updating the statistics data for mode ENERGY_PRODUCED, no ale to ładowanie powtarza się tylko 2 razy i trafiamy na opisywany przeze mnie problem z kolejnymi paczkami. my_meter.log mymeter.log

Po restarcie HA jak ładują się wszystkie liczniki, inicjalizacja jest ponawiana do skutku i finalnie wszystko się prezentuje prawidłowo. Na licznikach dociągają się bieżące rekordy statystyk (np. po kilka sztuk od poprzedniego ładowania). No ale z wyjątkiem liczników dwukierunkowych, bo niby są zainicjowane, ale brakujące paczki danych się nie ładują. Nie generują się też statystyki dla danych aktualnych. Czy świeże dane będą pobierane dopiero po ściągnięciu całej historii?

image

Próby dla okresy krótsze niż 730 dni

Dalej aby przyspieszyć ładowanie danych na nowo, robiłem testy tylko dla jednego z tych dwóch liczników dwukierunkowych.

Podsumowanie

Te wszystkie próby i analiza dla różnych przypadków doprowadziły mnie do wniosku, że trzeba zrobić fixa na obsługę błędu w danych, może jakiś null, może to: AttributeError: 'EnergaHistoricalPoint' object has no attribute 'date_to'. Przypadek dotyczy prawdopodobnie tylko energii oddawanej do sieci.

thedeemling commented 1 week ago

Brzmi jak mój błąd w obsłudze dat w przypadku, kiedy energa zwróciła estymowany punkt historyczny: https://github.com/thedeemling/hass-energa-my-meter/blob/main/custom_components/energa_my_meter/hass_integration/data_updater.py#L85

Z jakiegoś powodu w tym przypadku Energa nie zwraca daty (a ja używam jej tylko do wypisania informacji do debugu... więc zupełnie bez sensu w tym przypadku spowodowałem błąd ;)) https://github.com/thedeemling/hass-energa-my-meter/blob/main/custom_components/energa_my_meter/hass_integration/data_updater.py#L89

Punkty estymowane i tak są porzucane, bo nie mogę ich zaktualizować potem faktycznymi danymi.

Zastanawia mnie tylko, czemu masz estymaty w danych historycznych...? Myślałem, że Energa je zwraca tylko dla aktualnych danych.

Dziś wieczorem poprawię ten błąd w kodzie z próbą wypisania do kodu pustej daty (żeby nie wyrzucał takimi brzydalami), ale żeby się upewnić, że algorytm działa... Czy mógłbyś:

  1. Włączyć sobie logi w trybie debug
  2. Zobaczyć, z jakimi parametrami odpytujemy API Energi o dane historyczne
  3. Zobaczyć, czy faktycznie idą tam estymaty/podesłać plik (po depersonalizacji, oczywiście), żebym mógł przeanalizować?

Dodam, że ja mam tylko licznik jednokierunkowy, więc ciężko mi to sprawdzić samodzielnie :(

thedeemling commented 1 week ago

Pechowo strona Energi pokazuje teraz błąd :) image

więc przetestuję i wrzucę poprawkę później.

jj641 commented 1 week ago

Warto sprawdzić na stronie Energii mojlicznik.energa-operator.pl w zakładce Wytwórca od jakiego miesiąca i roku są przechowywane rzeczywiste dane Energii wprowadzonej do sieci w kWh (a nie wyprodukowanej w instalacji fotowoltaicznej - semantyka - uwagi [paki111] - Identyfikatory encji)

thedeemling commented 1 week ago

Wypuściłem poprawkę dotyczącą logowania daty dla punktu estymaty: https://github.com/thedeemling/hass-energa-my-meter/releases/tag/2.2.1

Prawdopodobnie nie rozwiąże Twojego problemu, bo - jak mówiłem - nie zakładałem, że mogą być estymowane wartości w starych danych (myślałem, że to tylko tam, gdzie Energa "przewiduje" wartości - np. "teraz" albo "za godzinę"). Daj znać.

@jj641, niestety - ja u siebie takiej zakładki nie mam, więc nie wiem, co jest w środku. Mam natomiast funkcję w stylu "znajdź pierwszą statystykę i od niej zacznij" dla normalnych liczników - jest to jakieś rozwiązanie dla danych produkcyjnych - jak nie ma żadnych statystyk w Home Assistant'cie, to najpierw wyszukaj pierwszą :)

Mam do Was dwa kolejne pytania:

  1. Czy mogła się zdarzyć taka sytuacja, że dane produkcji energii zostały zbierane później niż konsumpcji? Np. mamy licznik, dopiero po roku zrobiliśmy z niego dwukierunkowy - czy w takiej sytuacji Energa nadaje nowy numer i część danych po prostu jest zbierana później? Założyłem w algorytmie, że one są równolegle produkowane.

  2. Czy w przypadku zerowej produkcji, Energa zwraca 0 w odpowiedziach, czy puste wartości (null?)

paki111 commented 1 week ago

Warto sprawdzić na stronie Energii mojlicznik.energa-operator.pl w zakładce Wytwórca od jakiego miesiąca i roku są przechowywane rzeczywiste dane Energii wprowadzonej do sieci w kWh (a nie wyprodukowanej w instalacji fotowoltaicznej - uwagi [paki111] - Identyfikatory encji)

W zakładce "Wytwórca" też są dane trzymane 2 lata. Szkoda, bo to tylko suma miesięczna, to mogliby trzymać dłużej. Ja na szczęście już 4 lata temu sobie te miesięczne podsumowania skopiowałem.

Wypuściłem poprawkę dotyczącą logowania daty dla punktu estymaty: https://github.com/thedeemling/hass-energa-my-meter/releases/tag/2.2.1

Zweryfikuję, może jeszcze dziś w nocy.

Mam do Was dwa kolejne pytania:

  1. Czy mogła się zdarzyć taka sytuacja, że dane produkcji energii zostały zbierane później niż konsumpcji? Np. mamy licznik, dopiero po roku zrobiliśmy z niego dwukierunkowy - czy w takiej sytuacji Energa nadaje nowy numer i część danych po prostu jest zbierana później? Założyłem w algorytmie, że one są równolegle produkowane.
  2. Czy w przypadku zerowej produkcji, Energa zwraca 0 w odpowiedziach, czy puste wartości (null?)
  1. Tak jak pisałem wcześniej o identyfikatorze meterPoint, po wymianie licznika mamy inny numer licznika, ale ciągłość danych na meterPoint. Jak najbardziej może tak się zdarzyć, że jakiś czas można mieć sam import z sieci a później aktualizację umowy i zacząć eksport do sieci. Sama wymiana licznika musi być "przezroczysta" dla ciągłości pomiarów. Teraz pytanie @thedeemling jak to zrobić w Twojej integracji, bo przecież nie da się ponownie zainicjować tego samego wpisu aby dodać tryb dla energii oddawanej do sieci. Rozumiem, że po usunięciu wpisu, dane w bazie zostają i będziemy mogli ponownie dodać PPE i zaznaczyć tryb, tylko czy będzie kontynuacja odkładania statystyk?
  2. API wysyła 0 w godzinach bez eksportu energii. Moim zdaniem mógłbyś zera pomijać aby ograniczyć ilość dodawanych rekordów. Np. teraz w listopadzie słońce jest krótko i mam eksport tylko przez 3 godziny a czasem nawet żadnego przez całą dobę.
        "mainChart": [
            {
                "tm": "1728882000000",
                "tarAvg": 0.000964045174967252,
                "zones": [
                    0,
                    null,
                    null
                ],
                "est": false,
                "cplt": true
            },
            {
                "tm": "1728885600000",
                "tarAvg": 0.00258550262673869,
                "zones": [
                    0.103,
                    null,
                    null
                ],
                "est": false,
                "cplt": true
            },
            {
                "tm": "1728889200000",
                "tarAvg": 0.02336503507225458,
                "zones": [
                    0.412,
                    null,
                    null
                ],
                "est": false,
                "cplt": true
            },
            {
                "tm": "1728892800000",
                "tarAvg": 0.0593971380466239,
                "zones": [
                    0.748,
                    null,
                    null
                ],
                "est": false,
                "cplt": true
            },
            {
                "tm": "1728896400000",
                "tarAvg": 0.0991637096253774,
                "zones": [
                    1.135,
                    null,
                    null
                ],
                "est": false,
                "cplt": true
            },
            {
                "tm": "1728900000000",
                "tarAvg": 0.1311963451238101,
                "zones": [
                    1.234,
                    null,
                    null
                ],
                "est": false,
                "cplt": true
            },
            {
                "tm": "1728903600000",
                "tarAvg": 0.1354936629215757,
                "zones": [
                    1.722,
                    null,
                    null
                ],
                "est": false,
                "cplt": true
            },
            {
                "tm": "1728907200000",
                "tarAvg": 0.1229327624546833,
                "zones": [
                    2.204,
                    null,
                    null
                ],
                "est": false,
                "cplt": true
            },
            {
                "tm": "1728910800000",
                "tarAvg": 0.1141839451935508,
                "zones": [
                    1.882,
                    null,
                    null
                ],
                "est": false,
                "cplt": true
            },
            {
                "tm": "1728914400000",
                "tarAvg": 0.0654212875319777,
                "zones": [
                    1.18,
                    null,
                    null
                ],
                "est": false,
                "cplt": true
            },
            {
                "tm": "1728918000000",
                "tarAvg": 0.0272670586050331,
                "zones": [
                    0,
                    null,
                    null
                ],
                "est": false,
                "cplt": true
            },
            {
                "tm": "1728921600000",
                "tarAvg": 0.002594960681063212,
                "zones": [
                    0,
                    null,
                    null
                ],
                "est": false,
                "cplt": true
            }]
paki111 commented 6 days ago

Wypuściłem poprawkę dotyczącą logowania daty dla punktu estymaty: https://github.com/thedeemling/hass-energa-my-meter/releases/tag/2.2.1

Prawdopodobnie nie rozwiąże Twojego problemu, bo - jak mówiłem - nie zakładałem, że mogą być estymowane wartości w starych danych (myślałem, że to tylko tam, gdzie Energa "przewiduje" wartości - np. "teraz" albo "za godzinę"). Daj znać.

Owszem, nie rozwiązało to mojego problemu. Czy jest szansa na fixa?

Gdy nie mam załadowanej kompletnej historii to nie liczy mi się prawidłowo statystyka? Przyrosty bieżące widzę na jednej encji a historię na drugiej encji. Czy tak powinno być? To widok z tabeli statystyk gdzie widać tę nieciągłość w danych:

image

Aktualnie mam z tym problem, bo nie wyświetlę tego jako jedna seria na wykresie statystyk. Dopiero po dodaniu dwóch encji, widzę historię i aktualne przyrosty, ale przecież nie tak działają inne statystyki.

image

Jeżeli to jest konsekwencja Twojego "obejścia" na brak możliwości dodawania danych w HA z datą wsteczną, to OK, da się z tym żyć. Mam tylko pytanie, czy jak już uda się ściągnąć całą historię (fix:), to będzie inaczej wyglądać czy i tak będzie trzeba dodać na wykresie dwie encje aby widzieć komplet pomiarów z jednego liczydła (czyli z jednego trybu, w tym przypadku energia oddana do sieci).

thedeemling commented 5 days ago

Hej, w IT wszystko jest możliwe - ogarniemy i będzie działać najlepiej, jak się da, dopóki Energa nie poprawi API, a Hass ładowania statystyk :)

Przede wszystkim: czy moja poprawka wpłynęła na występowanie tego błędu podczas ładowania danych? Chciałem się skupić na usunięciu buga z kodu.

Ta encja _energy_produced to tzw. "live sensor" (https://github.com/thedeemling/hass-energa-my-meter/blob/main/custom_components/energa_my_meter/hass_integration/live_sensors.py#L29), który pobiera dane prezentowane przez Energę "na żywo" - w sensie, jak Energa zaktualizuje licznik, to go pobierze. image

Te dane pochodzą z prostego "daj mi wartość" i nie są historyzowane inaczej niż przez samego Home Assistanta (poprzez wykrywanie zmiany stanu). Ponieważ Energa rzadko aktualizuje te dane (jak widzisz, u mnie o północy, a jest prawie 9), to będziesz widział rzadkie słupki w historii. Traktuj te encje "live" raczej jako podsumowanie, "źródło prawdy" całości zużycia/produkcji.

Encje _produced_strefa_X to są encje statystyczne, ładowane z API historii w Moim Liczniku. One z kolei mają tylko przyrosty, bo Energa w tym api nie podaje sumarycznej wartości godzinowej :( Wyliczanie własnoręczne wartości sumarycznej dla statystyk byłoby problematyczne i pewnie powodowałoby trochę bugów (musiałbym zacząć od "teraz" - najnowszego odczytu i się cofać w historii do poprzednich dni, używając tego odczytu jako bazy. To by się łatwo rozjechało, jeżeli Energa zaokrągla wartosci (a robi to chyba do drugiego miejsca poprzecinku?). Stąd też algorytm wygląda następująco: zacznij z wartością 0 i datą podaną przez użytkownika, a następnie traktuj "słupki" z Energi jako przyrosty do sumy.

Czy te słupki z energią oddaną od sieci nie pokrywają się z tym, co zwraca API Energi?

Muszę tylko ostrzec: niestety, w najbliższych dniach będę miał mniej czasu na projekt, muszę nadgonić trochę spraw osobistych - wrócę do tematu w przyszłym tygodniu.

paki111 commented 5 days ago

Twoja poprawka nie wpłynęła negatywnie na ogólne ładowanie danych na innych licznikach (jeżeli o to pytałeś?).

Dziś dodałem licznik na nowo aby upewnić się, czy fix 2.2.1 rozwiązał też problem ładowania historii gdy wystąpi błąd Unexpected error fetching Energa My Meter data spowodowany prawdopodobnie przez AttributeError: 'EnergaHistoricalPoint' object has no attribute 'date_to'.

Ustawiłem tryb debug dla logów i oto wynik: home-assistant_2024-11-21T09-04-14.022Z.log Niestety nie pomogło. Przy którejś paczce dane historyczne przestają się pobierać.

... Tam gdzie dane historyczne się zaczytały to słupki się pokrywają, czyli są poprawne wartości. Zaokrąglenia zużycia na portalu są do trzeciej cyfry po przecinku. Będę czekał na na późniejszy update z Twojej strony.