Skip to content

v1.3.0 — support consumption-only (non-OZE) accounts - #1

Open
lchojnowski wants to merge 8 commits into
Fistacho:mainfrom
lchojnowski:feat/non-oze-accounts
Open

lchojnowski wants to merge 8 commits into
Fistacho:mainfrom
lchojnowski:feat/non-oze-accounts

Conversation

@lchojnowski

Copy link
Copy Markdown

Problem

Addon zakłada konto prosumenckie (OZE) dla każdego użytkownika:

  • billing idzie przez /api/oze/GetBillingData, dane godzinowe przez
    OzeReport/GenerateOzeReport z OZE-owym ItemId,
  • dla zwykłego (konsumenckiego) konta portal odpowiada na endpointy /oze/*
    HTTP 200 {"Faulted": true} (a GetOzeDetails → 404, GenerateOzeReport
    → 302), więc addon "działa", ale wszystkie sensory są puste,
  • discovery publikuje 7 sensorów (w tym eksport/bilans), które dla konta bez
    OZE nigdy nie będą miały danych.

Co ustaliłem na koncie bez OZE (recon na żywym koncie, 2026-07)

  • GetPHListHasOze: false (flaga globalna; nie ma flagi per-KU/PPE).
  • Historia zużycia nie ma żadnych danych godzinowych ani eksportu CSV.
    Zamiast tego SPA używa dwóch endpointów nieobecnych w addonie:
    • GET /mojeon/api/CompareYearEnergyConsumptionChartData?kuId= — roczne
      sumy zużycia per okres rozliczeniowy (ostatni wpis = bieżący okres,
      narastająco),
    • GET /mojeon/api/GetDetailsEnergyConsumptionChartData?kuId=&meterId=
      przyrosty zużycia per odczyt licznika (LegendId = typ odczytu). Serwer
      ignoruje parametry dat (stałe okno ~2 lata); meterId jest wymagany
      i jest dostępny wyłącznie w server-side renderowanym <select> na
      stronie Historia-zuzycia (addon i tak ją odwiedza przy keepalive).
  • GetMeterReadingsForKU działa i zwraca narastające stany licznika.

Zmiany

  • api.py — guard na Faulted: true w _get() (błąd zamiast cichych
    null-i); metody get_compare_year_data / get_details_chart_data /
    get_history_page; parsery: parse_chart_rows, parse_history_meters,
    parse_meter_readings (z FormatedDate, bo epoka /Date(ms)/ w UTC
    cofa datę o dzień).
  • coordinator.py — dispatch po HasOze: ścieżka OZE bez zmian
    (billing + agregaty + hourly jak dotąd); ścieżka bez OZE pobiera wykresy
    per-KU + stany licznika, buduje wiersze statystyk z zamkniętych okresów
    (najnowszy, jeszcze rosnący okres jest wstrzymywany do następnego odczytu).
    Przy wielu PPE pod jednym KU dane per-KU idą tylko do pierwszego PPE
    (bez duplikacji statystyk).
  • mqtt_publisher.py — zestawy sensorów per typ konta: bez OZE tylko
    consumption_current_period + nowy meter_reading; discovery czyści
    retained topici drugiego zestawu (pusty payload), więc martwe encje
    znikają idempotentnie.
  • stats_importer.py — parametr oze_keys; dla kont bez OZE
    importowany jest tylko eon_pl:imported_<PPE> (eksport byłby samymi
    zerami). oze_keys=None zachowuje dotychczasowe zachowanie.
  • web_server.py — tabela ingress pokazuje dla kont bez OZE
    zużycie okresu + stan licznika zamiast pustych kresek.
  • test_fetch.py (nowy) — harness całego pipeline'u na wklejonym
    cookie (bez Playwright/MQTT/HA), maskuje KU/PPE w outputcie.
  • test_parsers.py (nowy) — testy offline: blokują pozycyjne mapowanie
    CSV OZE (kolumny 2/4/6) i pokrywają nowe parsery.

Kompatybilność z OZE

Przy has_oze=True każdy call, payload, topic i statistic_id są identyczne
jak w v1.2.1 — dispatch to wyłącznie domyślne parametry / gałęzie if.
Jedyna różnica: odpowiedź Faulted: true loguje warning zamiast cicho
publikować null-e. Test test_parsers.py::test_oze_csv_positional_mapping
przybija dotychczasowy format CSV. Nie mam konta OZE — proszę o jeden
smoke-test fetcha przed merge.

Przetestowane na żywo (konto bez OZE)

HAOS x86_64, HA core 2026.7.2, tryb manual_cookie_only:

  • fetch → HasOze=False, 1 kontrakt, 8 wierszy statystyk,
  • MQTT discovery → dokładnie 2 sensory (zużycie okresu 3507.38 kWh, stan
    licznika 14529.52 kWh z datą i typem odczytu w atrybutach), zero encji
    OZE,
  • recorder → eon_pl:imported_<PPE>: 8 miesięcznych przyrostów zgodnych
    1:1 z portalem (suma 10297.28 kWh), eon_pl:exported_<PPE> nieobecny,
  • idempotencja → podwójny refetch i restart addona: sumy bez zmian, cookie
    wznowione z /data,
  • keepalive stabilny, śmieciowe cookie odrzucane bez utraty ważnej sesji.

🤖 Generated with Claude Code

lchojnowski and others added 8 commits July 20, 2026 07:49
…OZE accounts

The portal answers HTTP 200 {"Faulted": true} on /oze/* endpoints for
consumption-only accounts — treat that as an API error instead of silently
producing null sensors. Add the two chart endpoints such accounts actually
use (CompareYear / GetDetailsEnergyConsumptionChartData), a parser for the
shared chart JSON shape, a Historia-zuzycia meter-select parser (the only
source of meterId), and a GetMeterReadingsForKU parser.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…unts

OZE accounts keep the exact previous flow (billing, OZE aggregates, hourly
CSV). Non-OZE accounts skip those endpoints entirely and fetch per-KU
CompareYear + Details charts and meter readings instead; the newest Details
category is held back from statistics until a newer one closes it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Non-OZE contracts publish consumption_current_period + meter_reading only;
discovery topics of the other account type get an empty retained payload so
stale entities disappear idempotently.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
test_fetch.py runs the real coordinator against the live portal with a
pasted .AspNet.Cookies (no Playwright/MQTT/HA needed) and masks KU/PPE in
output. test_parsers.py locks the positional OZE CSV mapping and the new
non-OZE parsers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…y in UTC

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant