Files
ems/docs/discord-ev-interaction.md
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

75 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Discord EV interakce — návrh (fáze A nasazena, fáze B čeká na bot token)
## Fáze A — notifikace po příjezdu (HOTOVO, `dev`)
Píchneš auto → detekce (~60 s) → Tesla SoC → replan → **Discord zpráva**
(webhook `discord_webhook_daily_url`):
```
🔌 Tesla Model Y připojeno
Baterie auta: 55 % → cíl 100 % (~34 kWh)
Deadline: po 15.06. 06:30
Plán nabíjení: 11:3013:45; 02:1504:30 — 34.2 kWh, ø 1.85 Kč/kWh
```
Implementace: `_notify_ev_arrival_plan` v `telemetry_collector.py` (sloty
`ev*_setpoint_w > 0` z aktivního plánu shlukované do oken).
## Fáze B — zpětná vazba dvěma výběry — ✅ IMPLEMENTOVÁNO (2026-06-12)
**Architektura: Discord BOT přes gateway** — spojení jde Z backendu VEN
(websocket), žádný veřejný endpoint do EMS (na rozdíl od interactions
webhooku). Knihovna `discord.py`, token v `/opt/ems-deploy/.env`.
Zpráva z fáze A dostane **dva selecty** (místo dřívější řady tlačítek):
```
🔌 Tesla Model Y připojeno
Baterie auta: 55 % → cíl 90 % (~26 kWh)
Deadline: po 15.06. 07:00
Plán nabíjení: 11:3013:45; 02:1504:30 — 26.2 kWh, ø 1.85 Kč/kWh
[ 🕑 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
```
**Sémantika:**
- Každý výběr **okamžitě** PATCHne otevřenou session přes
`fn_ev_session_apply_patch` — ale jen ve SVÉ dimenzi: výběr 1 nastaví
`target_deadline` (absolutní čas Europe/Prague; pevné volby = nejbližší
budoucí výskyt, „pondělí ráno" z pátku je validní i přes 48 h),
výběr 2 nastaví `target_soc_pct`. Druhý rozměr zůstává beze změny
(default z `fn_ev_session_defaults`, případně dřívější výběr).
- „Nenabíjet" = stop akce (target = SoC při připojení → solver nic neplánuje).
- **No-click = pohotovostní režim:** bez kliknutí jede session na defaultech
z `ems.fn_ev_session_defaults` (týdenní požadavek `ev_weekly_requirement`
→ forecast z rytmu → defaulty vozidla; viz `docs/04-modules/ev-charging.md`).
S `min_target_soc_pct` 30 % to znamená: drž aspoň ~30 % pro pohotovost
a zbytek doplňuj oportunisticky v levných/záporných slotech
(`opportunistic_value_czk_kwh` — měkký cíl).
Po každém výběru: patch session → okamžitý `run_rolling_replan` +
`export_setpoints` (vzor ev_arrival) → bot **edituje původní zprávu**
přepočteným plánem (`build_ev_plan_summary`) + potvrzením
`_(nastaveno: odjezd dnes večer 18:00)_` (žádný spam).
Bezpečnost: bot reaguje jen na whitelisted user ID (majitel), akce omezené
na patch session + replan (žádné režimy/registry). Selecty expirují
s koncem session (uzavřená session → ephemeral „Session už není otevřená").
**Implementace:** `services/discord_bot.py` (lifespan task; discord.py
gateway), `services/ev_notify.py` (sdílený souhrn plánu; bot-first, webhook
fallback). custom_id `ev:<site>:<charger>:dep` / `:tgt` — obsluha přes
`on_interaction` + regex (persistent vzor), selecty přežijí restart backendu.
Legacy tlačítka `h2|h4|morning|full|stop` ze starších zpráv zůstávají
obsloužená (`action_to_patch`). Env: `DISCORD_BOT_TOKEN`,
`DISCORD_EV_CHANNEL_ID`, `DISCORD_ALLOWED_USER_IDS` (čárkami; prázdné =
bot vypnut, jede fáze A webhook).
Testy: tests/test_discord_bot.py (parse, výběr→patch, absolutní deadline
z voleb vč. půlnoci a pondělí z pátku, legacy akce).
## Výhled (fáze C)
Stejný bot = kanál pro ranní triáž s dotazy („proč jsi v 19:00 nabíjel?" →
delta-triage skill) a rychlé akce (bazén, režimy) — viz noční roadmapa.