Commit Graph

261 Commits

Author SHA1 Message Date
Dusan Vojacek
f70111f44b feat(pool): řízení bazénu Phase 1 — nejlevnější okno + dump-load (bez solveru)
fn_pool_schedule_slot: nejlevnější souvislé okno denního runtime budgetu
(fn_pool_daily_runtime_min) z vw_site_effective_price + dump-load při sell<=0.
fn_pool_control_tick: každých 15 min spočte stav a zařadí POOL_PUMP_ON (jen když
existuje signal_route → bezpečné před aktivací). lifespan job pool_control.
Shelly přes signal_service, žádné Modbus. Bazál odečet (R__003) se tím stává
správným (řízená+plánovaná zátěž). Aktivace provozně: daily_runtime_min=480,
schedulable, signal_route.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 22:00:49 +02:00
Dusan Vojacek
8ffe5460f1 fix(planner): živé EV SoC z integrálu power_w — konec phantom 11 kW oken
needed_wh i headroom z live_soc (soc_at_connect + integrál power_w), ne ze
zamrzlého soc_at_connect. energy_delivered_wh se během session nikdy nezapisoval
(→ needed konstantní, plánovač slepý k pokroku), counter energy_kwh (Telto reg 39)
je rozbitý (17.4 kWh nabito → counter 0.18). Nový fn_ev_session_delivered_wh
integruje power_w (dt cap 120 s), clamp 99 %, fallback drží staré chování bez
telemetrie. Ověřeno živě: needed_wh 18750→1329, live_soc 97.9 %.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 20:33:08 +02:00
Dusan Vojacek
f726188ec9 docs: arbitráž — sell strana marginální cena vs strop exportu (proč baterie nedrží na špičku)
All checks were successful
CI and deploy / migration-check (push) Successful in 31s
CI and deploy / deploy (push) Has been skipped
Zrcadlo sekce 3 (buy: min(buy) != cena zásoby) na prodejní straně: baterie se
nevyprodá do jednoho slotu (strop 13.5 kW = 3.4 kWh/15min), rozloží se přes
více slotů s klesající cenou. Rozhodnutí drzet vs vybit = proti MARGINÁLNÍ
ceně (nejnizsi pouzity slot), ne spicce. Konkrétní příklad večer 2026-06-14
+ caveat terminal value za horizontem (jeden skalár, ne marginální).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 11:46:42 +02:00
Dusan Vojacek
87a4f47666 docs: changelog hotfix hardcoded wallbox kody (oslepnuti planovace po rename)
All checks were successful
CI and deploy / migration-check (push) Successful in 32s
CI and deploy / deploy (push) Has been skipped
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 11:31:52 +02:00
Dusan Vojacek
74e156514a docs: nocni read-only backlog (workflow 16 agentu) — co chybi/dotahnout/zlepsit
Some checks failed
CI and deploy / migration-check (push) Failing after 16m35s
CI and deploy / deploy (push) Has been cancelled
Prioritizovany backlog (TL;DR, Tier 1-3, rozdelane, rizika, dozraje casem).
Nejzavaznejsi nalez: golden gate NEbeztzi v CI (deploy.yml = jen migrace+validate+
deploy) -> ochrana solveru je v nasazeni iluzorni. K review uzivatelem.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 10:08:31 +02:00
Dusan Vojacek
5bfea4457b docs+re-trigger: CI gotcha prazdny commit/duplicitni SHA netriggeruje deploy; re-trigger Faze 0 (V106)
All checks were successful
CI and deploy / migration-check (push) Successful in 37s
CI and deploy / deploy (push) Has been skipped
Faze 0 (battery guard + EV reg15/session, V106) zustala na serveru nenasazena
(V105) — prazdny re-trigger commit se neprojevil. Tento neprazdny commit na main
(unikatni SHA, ref=main) spusti realny deploy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 23:20:35 +02:00
Dusan Vojacek
8452b34b25 Merge branch 'fix/ev-teltocharge-reg15-and-session-visibility' into dev
Some checks failed
CI and deploy / migration-check (push) Failing after 7m26s
CI and deploy / deploy (push) Has been skipped
# Conflicts:
#	docs/planning-changelog.md
2026-06-13 22:41:14 +02:00
Dusan Vojacek
521a3653d3 Faze 0A: battery guard carve-out — neblokovat import na nabiti pri zaporne cene
_apply_export_plan_guard / _build_setpoints: kdyz slot CHARGE / importuje na
nabiti baterie (grid_sp>0 & bat>0), guard vrati sp beze zmeny a export_ban se
nenastavi. Opravuje, ze se baterie nedobila v zapornych cenach (CHARGE+17kW
prekloplen na PASSIVE -> Deye nenabijel ze site). Diagnoza: agent a599eecc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 22:40:18 +02:00
Dusan Vojacek
d81a150014 fix(planner): EV session viditelna i bez deadline / nad targetem (BUG2)
Zivy incident home-01: aktivni plan mel ev_sessions:0, ac session bezela
(target 70 %). Planovac neviděl ~6 kW zatez auta a spatne rozvrhl baterii
(zbytecny vecerni import).

Root cause (dve pasti):
- fn_planning_site_context vracela session jako null, kdyz needed_wh=0
  (auto nad targetem) i kdyz target_deadline is null.
- _ev_session_from_json (Python) zahazovala session bez deadline.

Fix:
- R__038 fn_ev_session_planning_json: session se vyradi (null) JEN bez tvrdych
  dat (kapacita vozidla / soc_at_connect). target_deadline smi byt NULL --
  solver hard deadline constraint aplikuje jen pri needed>0; oportunisticka
  vrstva bezi i bez deadline. Auto nad targetem zustava v planu jako znama
  zatez i s headroomem k levnemu doplneni. R__039 vola helper (deduplikace
  dvou inline poddotazu, SQL-first).
- _ev_session_from_json si NULL deadline ponecha (energy_needed_wh default 0).
- testy test_ev_session_parse.py; docs ev-charging + planning-changelog;
  CLAUDE.md funkce.

Navrh agresivnejsiho oportunistickeho algoritmu (P50 levnych oken z
market_price_stats misto konstanty 1 Kc/kWh) -- NEnasazeno, k rozhodnuti,
sepsano v docs/04-modules/planning.md (EV oportunismus); riziko regrese
golden ekonomiky, nutny EV fixture + eval.

Overeni: pytest -q 362 passed; golden replay gate 7 passed; solver_v2_eval
beze zmeny (fixtures bez EV session).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 22:03:27 +02:00
Dusan Vojacek
54288ee2fd fix(modbus): reg 15 re-asert kazdy tick + per-charger failsafe (BUG1)
Zivy incident home-01 (TeltoCharge .16): od ~22:45 UTC 12.6. nevznikl zadny
telto journal radek (ani failed), auto jelo failsafe 8 A misto planovanych 0 A.

Root cause: reg 15 (amps) byl write-on-change proti journalu
(fn_modbus_device_state_map). Jakmile mel reg 15 radek "0 verified" a plan
dal chtel 0, NIKDY nevznikl novy prikaz -- a TeltoCharge si po vypadku
komunikace sam prepsal reg 15 na failsafe (reg 20) BEZ journal radku. Verify
cte zpet jen 'written' radky, takze tichy drift 0 -> 8 A nikdo nevidel ani
neopravil.

- reg 15 (amps to use) se zapisuje VZDY (re-asert) -- volatilni ridici
  registr, ne EEPROM; drzi verify jobu cerstvy written radek -> drift se
  zachyti a hned opravi. _split_amps_and_watchdog odděluje 15 od 19/20.
- reg 19/20 (watchdog config, EEPROM) zustavaji write-on-change.
- per-charger failsafe/timeout: asset_ev_charger.watchdog_failsafe_a /
  watchdog_comm_timeout_s (V106; default 8 A / 300 s). "Zakaz nabijeni" =
  reg 15 = 0 (protokol rev 0.5 nema samostatny enable registr).
- testy test_ev_write_on_change.py; docs teltocharge + journal + data-model.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 22:03:11 +02:00
Dusan Vojacek
6e89b044f5 open questions: Tesla target bug vyřešen (03b7396)
All checks were successful
CI and deploy / migration-check (push) Successful in 1m24s
CI and deploy / deploy (push) Has been skipped
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 08:29:53 +02:00
Dusan Vojacek
c635f8f5dc open question: Tesla charge_limit přepisuje session target (noční nález)
All checks were successful
CI and deploy / migration-check (push) Successful in 22s
CI and deploy / deploy (push) Has been skipped
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 00:57:04 +02:00
Dusan Vojacek
7e9cd933b6 V105: WB2 mimo EMS (endpoint disabled + schedulable=false), reaktivace dokumentovaná
All checks were successful
CI and deploy / migration-check (push) Successful in 13s
CI and deploy / deploy (push) Successful in 55s
Dle dotačních podmínek WB2 řídí elektroměr; EMS na něj přestane sahat
(poll i zápisy) — uvolní RS485 bránu. Zpětné zapnutí = 2 UPDATE
(komentář migrace + teltocharge doc).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 00:47:38 +02:00
Dusan Vojacek
f81c2e4b71 docs TUV: hydraulika nádrže — krátké DHW běhy, bulk přes topný okruh do spodku, T_mid nutné, charakterizační test
All checks were successful
CI and deploy / migration-check (push) Successful in 18s
CI and deploy / deploy (push) Has been skipped
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 00:39:40 +02:00
Dusan Vojacek
b168618332 V104 úklid stale pending + TUV design: stavový automat, spirála dump-load, legionella
Some checks failed
CI and deploy / migration-check (push) Successful in 15s
CI and deploy / deploy (push) Failing after 24s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 00:31:24 +02:00
Dusan Vojacek
b08782525e fix(modbus): zadne vecne pending v journalu + flock timeout + EV poll backoff
Zivy incident home-01 (TeltoCharge .16): zapis 15/19-20 koncil failed
s prazdnym error_msg, nebo zustal trvale pending a zablokoval exportni ticky.

- _gateway_exclusive: neblokujici flock s deadline (EMS_MODBUS_FLOCK_TIMEOUT_S,
  default 20 s) -> GatewayLockTimeout misto starvation bez limitu
- execute_modbus_commands: invariant written/failed + neprazdny error_msg
  (str(e) or repr(e)); safety net pres BaseException (CancelledError, chyba DB);
  journal update mimo retry cyklus zarizeni; force_disconnect bez zamku brany
- telemetry poll_ev_chargers: po 3 selhanich backoff 5 min per (host,port,unit)
  - mrtvy unit_id drzi branu 4x8=32 s z kazde minuty
- testy backend/tests/test_modbus_execute_failsafe.py; docs
  modbus-command-journal.md (sekce Robustnost zapisu + konfigurace)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 00:17:04 +02:00
Dusan Vojacek
042581681b docs: design řízení TUV (EHS set-point posun + spirály) s NZÚ TČ+FV compliance mappingem
All checks were successful
CI and deploy / migration-check (push) Successful in 21s
CI and deploy / deploy (push) Has been skipped
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 23:44:19 +02:00
Dusan Vojacek
a742c295b7 V103: degradační cena dle cen packů — KV1/BA81 0.50→0.25, HU1 →0.15
All checks were successful
CI and deploy / migration-check (push) Successful in 24s
CI and deploy / deploy (push) Successful in 55s
Calendar-bound filozofie (majitel): parametr = šumový floor, ne plná cena
cyklu. Odemyká mělčí arbitráže na malých packech. Detail v changelogu.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 22:27:57 +02:00
Dusan Vojacek
f531214dac Merge branch 'worktree-agent-a85e5077c297a63df' into dev
All checks were successful
CI and deploy / migration-check (push) Successful in 18s
CI and deploy / deploy (push) Successful in 1m14s
2026-06-12 22:23:46 +02:00
Dusan Vojacek
7decfebdbd TeltoCharge write-on-change: zápis jen při změně hodnoty (EEPROM wear)
Wallbox dostával zápisy 15/19/20 každý export tick (~8x/hod: control_export
:14,:29,:44,:59 + rolling replan */15 s exportem), protože drop-unchanged
stál na fn_modbus_last_verified_map — dokud verify čtení nedoběhlo/selhalo,
mapa byla prázdná a celá trojice se psala pořád dokola. write_ev_arrival_hold
navíc psal trojici nepodmíněně při každém píchnutí kabelu (docstring lhal).

- nová ems.fn_modbus_device_state_map (R__100): nejnovější řádek journalu
  per registr, hodnota jen pro written/verified; failed/mismatch => registr
  chybí => po výpadku se konfigurace obnoví jedním zápisem
- write_ev_setpoints + write_ev_arrival_hold filtrují přes tuto mapu:
  reg 15 jen při změně plánu, watchdog 19/20 jednou po startu/po výpadku
- verify job EV chargery ověřuje už dnes (fn_modbus_written_command_ids bez
  filtru asset_type); registry 15/19/20 jsou dle oficiálního protokolu R/W
- watchdog Telto sytí jakákoli validní komunikace vč. FC3 čtení telemetrie
  (60 s << 300 s) — periodické zápisy k udržení spojení nejsou potřeba,
  failsafe 8 A nastane jen při skutečném výpadku EMS
- testy: tests/test_ev_write_on_change.py (drop, setpoints, arrival hold)
- docs: modbus-registers-teltocharge.md (sekce Zápis už není "NEimplementováno",
  R/W tabulka, watchdog sémantika), modbus-command-journal.md (sekce EV
  wallbox), CLAUDE.md (fn_modbus_device_state_map)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 22:21:59 +02:00
Dusan Vojacek
55deae984e HU1 studie: --pure-bess a --rt-eff flagy + výsledky čistého BESS
All checks were successful
CI and deploy / migration-check (push) Successful in 19s
CI and deploy / deploy (push) Successful in 1m5s
Zadání majitele: čistý BESS bez odběru, export povolen, varianta bez ztrát.
Výsledky (365 dní vč. zimy 25/26): arbitráž na spotu +129.4 tis. Kč/rok
(η=1.0) / +110.0 tis. (η=0.9); konzervativně (spready −30 % + deg 0.5)
+63.4 tis. Na fixní smlouvě jen ~24–35 tis. → spot je podmínka smysluplnosti
BESS. Léto ~378 Kč/den, zima ~308.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 22:11:41 +02:00
Dusan Vojacek
a889950eba Merge commit '826c776'
All checks were successful
CI and deploy / migration-check (push) Successful in 27s
CI and deploy / deploy (push) Has been skipped
2026-06-12 22:00:45 +02:00
Dusan Vojacek
826c776c34 HU1: realistická studie přechodu na spot (den-po-dni solver_v2, 2 roky OTE)
scripts/harness/hu1_realistic_eval.py — realistická simulace BESS 128 kWh/36 kW
na spotu místo perfect hindsight: D−1 plán přes solve_dispatch_v2 (informační
množina = ceny zítřka z OTE D−1 13:30), SoC řetězené mezi dny, parametry
baterie/grid z DB site 5 (fn_planning_site_context). Scénáře fix/spot ×
bez/s baterií, Kč/den po měsících a sezónách, roční projekce, citlivosti
(degradace 0.15/0.5/1.0, spread compression −30 %), GAP vs 7denní hindsight.
Varianty běží paralelně (ProcessPoolExecutor). HU1 nemá telemetrii →
parametrizovaný průmyslový odběr (konstanty v hlavičce, přepsat čísly
od majitele); fixní cena = proxy BA81 (--fix-buy).

Výsledky (788 dní 2024-04-14…2026-06-12, 2 zimy): D−B (přechod na spot
s baterií) −163,6 tis. Kč/rok base, konzervativně −110,1 tis.; léto −629,
zima −254 Kč/den, nejhorší měsíc (12/2024) −41 Kč/den — stále úspora.
GAP realistic vs hindsight ≈ 0 (ceny jsou D−1 známé) → dřívější horní mez
byla nadhodnocená sezónností, ne neznalostí budoucnosti.

Doc: docs/studies/hu1-spot-realistic.md (generuje skript, opakovatelné);
README harness doplněn.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 21:56:03 +02:00
Dusan Vojacek
e2688bb899 TČ ŽIVÉ: MIM adresa 5 (V101), fix dekódování defrost (0xFF = off)
Some checks failed
CI and deploy / migration-check (push) Successful in 18s
CI and deploy / deploy (push) Has been cancelled
Rozchozeno po třech vrstvách: protokol převodníku Modbus TCP to RTU
(byl None), parita EVEN, adresa MIM 5 (seed měl 1). První živé čtení:
EHS typ 115, comm ready, mode heat, prostor 20 °C, voda 54.4 °C, TUV
zásobník 46.6 °C, bez chyb. Defrost reg: 0 i 0xFF znamená OFF (manuál),
bool() by 255 četl jako zapnuto.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 21:40:15 +02:00
Dusan Vojacek
287353b082 docs: home-01 CT doinstalováno majitelem (reg 619 vs 625), changelog — dopatch k d8f6de7
All checks were successful
CI and deploy / migration-check (push) Successful in 19s
CI and deploy / deploy (push) Successful in 1m7s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 20:27:15 +02:00
Dusan Vojacek
80623573ea Merge branch 'worktree-agent-a53f3277d55fecfcb' into dev
All checks were successful
CI and deploy / migration-check (push) Successful in 19s
CI and deploy / deploy (push) Successful in 1m14s
2026-06-12 19:40:50 +02:00
Dusan Vojacek
3b5f07b66e feat(planner): EV účtování v2 — headroom fix, deadline boundary, min. výkon WB, via-bat reporting
Hloubková diagnóza EV potvrdila: oportunitní ekonomika via-baterie je v LP
správně, ale okraje lhaly nebo byly nevykonatelné:

- V099 + R__039: ems.ev_session.opportunistic_value_czk_kwh (NULL = zdědit
  z asset_vehicle, 0 = vypnout pro session); headroom_wh z max(target_soc,
  soc_at_connect) — „nenabíjet" (nízký target) už paradoxně NEzvětšuje
  oportunistickou vrstvu; vehicles JSON nese min_power_w wallboxu.
- R__015: patch klíč opportunistic_value_czk_kwh (validace >= 0).
- solver_v2: (a) deadline suma range(t_dl) — slot začínající v deadline už
  nepatří „do deadline"; (b) Σ ev_direct <= gi + PV (fyzikální split);
  (c) binárka ev_on → setpoint ∈ {0} ∪ [min_power_w, max] (konec 400–900 W
  nevykonatelných setpointů); (d) bez session EV == 0 (stop-session i golden
  fixtures — žádné pumpování při buy<0); dekompozice total == needed − unmet
  + opp i pro needed = 0; (e) battery_arbitrage_czk = via_bat kWh × oportunitní
  cena (min sell exportního slotu téhož pražského dne, jinak terminal value)
  místo konstantní 0. Oportunismus PO deadline zůstává POVOLENÝ (rozhodnutí:
  auto často doma, odjezd řeší rolling replan).
- R__033: fn_plan_current_bundle.intervals + ev1/ev2_via_bat_w (UI nemá cenit
  EV kWh z baterie slotovým buy).

Golden gate beze změny snapshotů (v1 nedotčen, fixtures bez EV sessions);
solver_v2_eval před/po identický (CELKEM −1283.5 Kč, Δ −221.9 vs v1);
tests/test_solver_v2.py +7 testů; plná sada 310 passed / 4 xfailed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 19:31:56 +02:00
Dusan Vojacek
283443d6bd Merge branch 'worktree-agent-a288972b643cdefcc' into dev
All checks were successful
CI and deploy / migration-check (push) Successful in 22s
CI and deploy / deploy (push) Has been skipped
2026-06-12 19:17:01 +02:00
Dusan Vojacek
48f5a6b00b Discord EV: dva výběry (odjezd × cíl) místo řady tlačítek
Arrival zpráva má dva persistent Selecty (custom_id ev:<site>:<charger>:dep
a :tgt, obsluha on_interaction + regex → přežijí restart):
„Kdy odjíždíš?" za 2 h | za 4 h | dnes večer 18:00 | zítra ráno 7:00 |
zítra poledne 12:00 | pondělí ráno 7:00; „Kolik potřebuješ?" 30/50/70/100 %
| Nenabíjet. Každý výběr okamžitě PATCHne session přes
fn_ev_session_apply_patch jen ve své dimenzi (absolutní deadline
Europe/Prague, nejbližší budoucí výskyt; pevná volba smí přes 48 h),
druhý rozměr zůstává z fn_ev_session_defaults. Pak replan + export a edit
zprávy přepočteným plánem (build_ev_plan_summary) + potvrzením. Whitelist
DISCORD_ALLOWED_USER_IDS i bot-first/webhook fallback beze změny; legacy
tlačítka h2/h4/morning/full/stop starších zpráv dál obsloužená.

Testy: mapování výběr→patch, absolutní deadline z voleb (půlnoc, pondělí
z pátku >48 h, pondělí ráno v pondělí), parse, legacy akce — bez DB/sítě.
Docs: discord-ev-interaction.md (nové UI, no-click = pohotovostní režim
30 % + oportunismus).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 19:14:56 +02:00
Dusan Vojacek
60eda46dd7 V098: týdenní požadavky EV (ev_weekly_requirement) + fn_ev_session_defaults
Tabulka ems.ev_weekly_requirement (dow 0=pondělí..6, target_soc_pct,
deadline_hour Europe/Prague, enabled; unique per vozidlo+den) se seedem
tesla-my pondělí 07:00 → 90 %. Nová ems.fn_ev_session_defaults(vehicle,
arrival) → jsonb {target_soc_pct, deadline, source}: kaskáda týdenní
požadavek (výskyt do 48 h) → forecast z ev_usage_stats
(target_soc_forecast_enabled, chování V089 beze změny) → defaulty vozidla
(deadline = příští výskyt default_deadline_hour). fn_ev_session_transition
ji volá při založení session (SQL-first, Python beze změny); comment
funkce sjednocen na styl bez parametrů.

Docs: ev-charging.md sekce Týdenní požadavky + kaskáda, CLAUDE.md seznam fn.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 19:14:40 +02:00
Dusan Vojacek
f0e81def5d open question: TUV delta jednotky °C/min vs užití v solveru (~60× podhodnocené chladnutí)
All checks were successful
CI and deploy / migration-check (push) Successful in 15s
CI and deploy / deploy (push) Has been skipped
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 19:09:33 +02:00
Dusan Vojacek
815a233049 feat(telemetry): idle-skip zápisů — neukládat 1min řádky idle zařízení
Some checks failed
CI and deploy / migration-check (push) Successful in 28s
CI and deploy / deploy (push) Failing after 17m56s
Slabý server: dict (tabulka, asset_id) → (signature, last_stored_at);
_idle_skip ukládá vždy při změně signature, aktivitě, po startu procesu
a heartbeat po > 840 s (každý 15min bucket má ≥ 1 řádek).

- telemetry_ev_charger: aktivní = status != 'available' nebo power > 50 W;
  signature (status, výkon na 100 W)
- telemetry_pool_pump: aktivní = is_on nebo power > 5 W (ON řádky 1/min
  kvůli on_minutes); signature (is_on, výkon na 10 W)
- telemetry_loxone_sensor: jen změna hodnoty ≥ 0.1 / heartbeat
- telemetry_heat_pump: aktivní = mode != 'off' nebo defrost; signature
  (mode, teploty na 0.2 °C)
- telemetry_inverter: beze změny — NIKDY se nepřeskakuje (audit Wh split,
  baseline, SoC plánovače)

Detekce příjezdu/odjezdu EV: previous_status přesunut z posledního řádku DB
do in-memory _EV_LAST_STATUS (po startu seed z vw_latest_ev_charger —
přechod během výpadku se pozná, prázdná DB nevystřelí falešný příjezd);
fn_ev_session_transition se volá jen při změně statusu.

PoolCard: staleness práh 5 → 16 min (> heartbeat 840 s).
Docs: telemetry.md sekce „Idle-skip zápisů" (pravidla pro nové čtecí dotazy:
sumy/gapfill, ne avg přes řádky), planning-changelog (TUV °C/min).
Testy: tests/test_telemetry_idle_skip.py — _idle_skip jednotkově + EV
arrival/departure přežije skip i restart procesu (303 passed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 19:06:41 +02:00
Dusan Vojacek
e41840cb7d V097: wallboxy TeltoCharge na reálný RS485 převodník 172.16.1.16 (unit 1/2, 9600 8N1)
All checks were successful
CI and deploy / migration-check (push) Successful in 19s
CI and deploy / deploy (push) Successful in 1m4s
Nahrazuje placeholder IP 192.168.1.101/.102 ze seedu; sdílená sběrnice
s plánovaným Chint elektroměrem (unit 3). Teltonika strana čeká na povolení
Modbusu v aplikaci.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 18:31:49 +02:00
Dusan Vojacek
8289e32a03 docs: heat-pump.md odkaz na MIM-B19N registry (dopatch k d63a85a)
Some checks failed
CI and deploy / deploy (push) Has been cancelled
CI and deploy / migration-check (push) Has been cancelled
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 18:24:36 +02:00
Dusan Vojacek
d63a85a2ea TČ Samsung přes MIM-B19N: endpoint 172.16.1.17, plný poll, registry doc
Some checks failed
CI and deploy / migration-check (push) Failing after 7m29s
CI and deploy / deploy (push) Has been skipped
- V096: endpoint home-01 TČ z placeholderu 192.168.1.103 na reálný Waveshare
  RS485 TO POE ETH (B) 172.16.1.17:502; telemetry_heat_pump.room_temp_c.
- R__048: fn_telemetry_heat_pump_sample rozšířena (water_inlet, room_temp,
  defrost, alarm_code) — drop/comment bez parametrů dle konvence.
- poll_heat_pump: místo TODO stubu (zapisoval dummy 45/55 °C!) skutečné čtení
  MIM bloku 50-75 + defrost reg 2; gate na comm_status ready (jinak skip);
  operating_mode off/heat/cool/auto/dhw/error; power_w NULL (MIM příkon nemá).
- docs/04-modules/modbus-registers-mim-b19n.md (mapa, 9600 8E1, DIP adresa,
  troubleshooting E6xx) + heat-pump.md odkaz.

Živý stav: TCP :502 OK, Modbus bez odpovědi (čeká na protokol převodníku /
paritu EVEN / polaritu A-B — checklist v docu).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 18:24:10 +02:00
Dusan Vojacek
c7f595c587 HOTFIX BA81: export plan guard neodstavuje pole B při kladné vykupní ceně
Some checks failed
CI and deploy / deploy (push) Has been cancelled
CI and deploy / migration-check (push) Has been cancelled
_apply_export_plan_guard při export_mode=NONE (plán nabíjí baterii, neexportuje)
vynucoval _passive_no_export_guard s export_ban=True + deye_gen_cutoff_enabled=True
bez ohledu na cenu -> reg 178 bity 0-1=3 (MI cutoff) + reg 145=0 a mikroinvertory
(pole B) fyzicky stály i při sell +1.36 Kč (BA81 dnes: gen port ~0 W od 12:16Z,
SoC 64 %, stringy 4.2 kW do baterie). Tvrdý ban nově JEN při záporné vykupní;
při kladné guard dál drží PASSIVE/143=0/baterie nevybíjí do sítě, ale MI jedou
(absorbce do baterie, přetok se prodá). Plánový z_gen_cutoff se respektuje.

Pre-existing fail test_neg_buy_and_sell_with_pv_b_forces_pv_a_off padá i na main
(pv_a_allowed_w None != 0) — nesouvisí, řešit zvlášť.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 15:07:17 +02:00
Dusan Vojacek
2122fa2035 Tesla presence watcher: geofence, ev_presence_obs, 'píchni auto' pobídka
All checks were successful
CI and deploy / migration-check (push) Successful in 47s
CI and deploy / deploy (push) Has been skipped
- V095 ems.ev_presence_obs (state/at_home/distance/charging/shift per ~5 min)
- tesla_client: get_vehicle_api_state (jen /vehicles — nebudí), haversine_m
- collector poll_tesla_presence: online → poloha → geofence 150 m vs GPS site;
  přechod pryč→doma + Disconnected → Discord pobídka s aktuálním přebytkem
  (cooldown 2 h); vše logováno pro budoucí dostupnostní statistiku
- 6 testů (haversine, přechody); docs: zákopy reauth procesu (6 bodů)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 14:14:48 +02:00
Dusan Vojacek
5a10da57e9 Tesla OAuth: redirect URI je /t-auth (oprava všude + Caddy rewrite)
All checks were successful
CI and deploy / migration-check (push) Successful in 26s
CI and deploy / deploy (push) Has been skipped
V dev portálu je registrováno https://ems.vojacek.eu/t-auth — docs i setup
skript diktovaly /tesla/callback (mismatch = invalid_auth_code / chybné
návody). Caddy blok nově servíruje callback stránku na /t-auth (rewrite).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 12:45:57 +02:00
Dusan Vojacek
85dff7f13e v2: měkký EV cíl — oportunistické nabíjení nad target (+ strop energie)
All checks were successful
CI and deploy / migration-check (push) Successful in 44s
CI and deploy / deploy (push) Has been skipped
Uživatel: 'potřebuju do X % (tvrdý), ale klidně dobij na 100 % když je to
skoro zadarmo; při záporných cenách radši do auta než nechat na střeše'.

- V094 asset_vehicle.opportunistic_value_czk_kwh (default 1.0; = hodnota
  ušetřeného BUDOUCÍHO nabíjení — auto neumí zpět, žádný noční prodej)
- R__039 ev_sessions: + headroom_wh ((100−target) % kapacity) + opp value;
  session se nenuluje po dosažení targetu, dokud má headroom
- solver_v2: dekompozice Σ(EV) == needed − unmet + opp, opp ∈ [0, headroom],
  odměna opp×value; zároveň FIX latentního bugu — při buy<0 chyběl strop
  celkové energie do auta (model mohl pumpovat bez limitu)
- 3 testy (neg ceny sají nad target po strop; běžné ceny ne; cap při opp=0);
  eval fixtures beze změny (sessions null)

Víkend (pátek nízký tvrdý cíl + víkendová negativa → samo doplní do 100 %)
vyplývá z mechanismu, žádná speciální logika.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 12:17:59 +02:00
Dusan Vojacek
15d47e8a80 Bazén: sezóna (schedulable), filtrace dle teploty vody, Loxone čidla
All checks were successful
CI and deploy / migration-check (push) Successful in 42s
CI and deploy / deploy (push) Has been skipped
- V092: ems.loxone_sensor + telemetry_loxone_sensor (hypertable) — generické
  čtení Loxone hodnot (poslouží i ohřevu/akumulačce); pool sloupce teplotní
  funkce (ref/base/per_c/min/max) + water_temp_sensor_id
- R__098 fn_pool_daily_runtime_min: clamp(base+per_c×(t−ref)) z poslední
  teploty <24 h, fallback daily_runtime_min; JSON detail pro UI/solver
- collector poll_loxone_sensors: /jdev/sps/io/<name>/state, LL.value parse,
  no-op bez čidel
- sezóna = schedulable přepínač (dokumentováno vč. SQL); hranice filtrace ×
  ohřev TČ (oddělené logiky, sdílí jen čidlo)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 11:47:03 +02:00
Dusan Vojacek
0e7f7b69ae Discord bot fáze B: tlačítka na EV zprávě → patch session + okamžitý replan
All checks were successful
CI and deploy / migration-check (push) Successful in 21s
CI and deploy / deploy (push) Has been skipped
services/discord_bot.py: gateway klient jako lifespan task (spojení ven,
žádný veřejný endpoint; bez DISCORD_BOT_TOKEN tiše spí). Tlačítka
[za 2h][za 4h][ráno][do plna][nenabíjet] s custom_id ev:<site>:<charger>:<akce>
(přežijí restart); whitelist DISCORD_ALLOWED_USER_IDS; akce = fn_ev_session_
apply_patch → run_rolling_replan → export_setpoints → edit zprávy novým plánem.

services/ev_notify.py: sdílený builder souhrnu (vyčleněno z collectoru),
send bot-first s webhook fallbackem. requirements: discord.py>=2.4.
7 testů helperů (parse, deadline akce vč. morning přes Prague TZ).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 11:41:05 +02:00
Dusan Vojacek
29d854f23d Bazén vizualizace + EV Discord notifikace po příjezdu (fáze A)
Some checks failed
CI and deploy / deploy (push) Has been cancelled
CI and deploy / migration-check (push) Has been cancelled
- R__097: vw_latest_pool_pump + vw_pool_pump_day_energy (denní kWh z delty
  čítače, minuty běhu) + ems_anon granty
- PoolCard na Dashboardu: stav/W/dnešní kWh+hodiny/7denní mini sloupce
- _notify_ev_arrival_plan: po příjezdu EV Discord souhrn (SoC auta → cíl,
  deadline, nabíjecí okna shlukovaná ze slotů aktivního plánu, ø cena)
- docs/discord-ev-interaction.md: fáze B (bot s tlačítky přes gateway —
  žádný veřejný endpoint; čeká na DISCORD_BOT_TOKEN od uživatele)
- docs: pool-shelly + ev-charging aktualizovány (pravidlo docs 1:1)

První commit na dev větvi (nová kadence: deploy až s milníkovým merge).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 10:59:09 +02:00
Dusan Vojacek
ab17e86900 Dokumentace: noc 11.→12. 6. — v2 aktivní, robustnostní trojice, EV forecast, CI opravy
Some checks failed
CI and deploy / migration-check (push) Successful in 16s
CI and deploy / deploy (push) Has been cancelled
- planning-changelog.md: záznam 2026-06-12 (přepnutí na v2, noční polštář /
  PV front-load / denní rampa s tabulkou, EV usage forecast, zimní posouzení)
- planning.md: default PLANNING_ENGINE_VERSION=v2 + sekce robustnosti
- refactor-clean-planner.md: Fáze 3 = v2 AKTIVNÍ
- ev-charging.md: EV spotřební forecast (sběr/statistiky/aktivace)
- consumption.md: bazál odečítá bazén
- deployment-self-hosted.md: tři CI vady + self-install deploy.sh + stop před flyway

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 10:37:20 +02:00
Dusan Vojacek
02c35f8add Merge: bazénové čerpadlo přes Shelly (telemetrie + signal ovládání)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 00:12:43 +02:00
Dusan Vojacek
60176fc7b2 Tesla Fleet API: čtení SoC po příjezdu k wallboxu
All checks were successful
CI and deploy / deploy (push) Successful in 58s
CI and deploy / migration-check (push) Successful in 16s
- services/tesla_client.py: access token s cache + ROTACE refresh tokenu do
  ems.tesla_token (env jen seed — Tesla refresh token je jednorázový),
  vehicles → vehicle_data?endpoints=charge_state, 408 (spící auto) = tiché
  přeskočení, výběr vozidla dle VIN / jediného na účtu (VIN se auto-naučí)
- hook _patch_session_from_tesla v _on_ev_arrival: PŘED replanem doplní
  soc_at_connect_pct (+ target z charge_limit_soc) do otevřené session přes
  fn_ev_session_apply_patch (rozšířena o soc_at_connect_pct) — energii si
  odvodí fn_planning_site_context (SQL-first); selhání neblokuje replan
- V086: asset_vehicle.vin, api_type='tesla' pro tesla-my (Model Y, home-01),
  singleton ems.tesla_token; R__095: fn_tesla_token_get/upsert,
  fn_tesla_arrival_context, fn_vehicle_set_vin
- config: TESLA_CLIENT_ID/SECRET/REFRESH_TOKEN (prázdné = vypnuto)
- testy parserů; plná sada beze změny

Aktivace: env do /opt/ems-deploy/.env + recreate backendu (docs/tesla-fleet-api.md §Stav).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 23:29:24 +02:00
Dusan Vojacek
620cea8b9b Tesla Fleet API: příprava domény ems.vojacek.eu (cert + public key + callback)
All checks were successful
CI and deploy / migration-check (push) Successful in 33s
CI and deploy / deploy (push) Successful in 1m30s
Doména slouží jen jako veřejná vizitka pro Tesla: Caddy blok vystavuje POUZE
.well-known public key a statickou OAuth callback stránku (zobrazí ?code=,
nic neodesílá), vše ostatní 404 — EMS zůstává na VPN. Certifikát Let's Encrypt
řeší hostovský Caddy automaticky.

deploy/tesla/setup_tesla_domain.sh (spustit NA SERVERU): EC keypair prime256v1
(privátní do /opt/ems-deploy/secrets 0600), public do .well-known, callback,
vypíše Caddy blok. docs/tesla-fleet-api.md: developer portál, partner
registrace, OAuth flow, plán EMS integrace (tesla_client + hook v _on_ev_arrival).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 22:58:28 +02:00
Dusan Vojacek
cf663ae417 Docs: pool-shelly — architektura, šablony seedů, návrh solver integrace
- šablona insertů endpoint/asset/signal_route (placeholdery IP, výkon, runtime)
- tok ovládání přes fn_signal_enqueue_bool a signal_service
- návrh pool[t] binárky analogicky hp[t] s denním runtime constraintem
- checklist oživení, otevřené otázky (sezónnost, bazál, UI)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:37:57 +02:00
Dusan Vojacek
5239463699 EV telemetrie: skutečné čtení Teltonika TeltoCharge (konec stub-u)
Some checks failed
CI and deploy / migration-check (push) Failing after 23s
CI and deploy / deploy (push) Has been skipped
poll_ev_chargers četl placeholder ('available'/0 W) — EV spotřeba se nikdy
neodečítala z bazálu a session detekce nefungovala. Nyní: blok registrů 0-40
jedním FC 3 (oficiální protokol rev 0.5), parse_teltocharge_frame (status z
reg 6 → available/preparing/charging/..., výkon reg 38, energie session reg 39,
proud max L1-L3 reg 3-5). Při selhání čtení se vzorek NEzapisuje (fabrikovaný
available by falešně ukončoval session).

fn_telemetry_ev_charger_sample: + p_current_a (drop staré 7-arg signatury).
6 nových testů parseru; plná sada beze změny. Docs: modbus-registers-teltocharge.md.

Po deployi: home-01 ev-charger-1/2 začnou posílat reálná data; bazál se začne
čistit od EV (EMA 00:30); rebuild stats má smysl až po ~2 týdnech čisté historie.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 22:10:46 +02:00
Dusan Vojacek
53e9afb513 Investiční studie v2: POTENCIÁLNÍ výroba místo telemetrie (škrcení 81 %!)
Klíčová oprava (postřeh uživatele): při sell<0 lokality škrtí výrobu
(reg 340 / GEN cutoff) — telemetrie ukázala 357 kWh, predikce 1879 kWh
(96 % minut v derating). Studie nyní používají max(skutečnost, kanonický
forecast per pole) v sell<0 slotech.

Nové výsledky (horní meze): BA81 32 kWh +35/+46 Kč/den (výkon 6.25/12 kW);
KV1 25 kWh +20/+22 Kč/den (stará smlouva); HU1 fixní: 75 Kč/den bez sdílení,
149 Kč/den s EDC sdílením @1.5 Kč distribuce (sdílitelných ~49 kWh/den!);
HU1 spot: 372 Kč/den, sdílení +0. + docs/onboarding-wallbox-tc-2026-06.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 17:24:49 +02:00
Dusan Vojacek
ad4b52c9ce Dokumentace refaktoru a delta-triage skill
- docs/refactor-clean-planner.md: plán Fází 0-4, stav, závazná pravidla
  (golden gate), návod nasazení v2 (shadow → vyhodnocení → přepnutí)
- docs/planning-changelog.md: záznam 2026-06-11 (Fáze 0-3 kompletní)
- docs/04-modules/planning.md: sekce Verze enginu v1/v2 + env flagy
- docs/audits/*: stav implementace FE fixů
- .claude/skills/ems-delta-triage: postup triáže neekonomického chování
  (realita vs plán vs shadow peer vs oracle, verdikt s Kč)
- CLAUDE.md: ukazatele na refaktor, solver_v2 a delta-triage v 'Kde hledat co'

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 14:45:16 +02:00