Specifikace aplikace
Energetický Semafor · architektonický přehled · aktualizováno 3. července 2026
Co to je
Energetický Semafor je aplikace, která vám denně odpovídá na jednu otázku: teď, nebo později? Spojuje čtyři signály — denní spotovou cenu OTE-CR, plán HDO vašeho distributora, uhlíkovou stopu sítě (ČEPS) a (volitelně) stav vaší FVE / baterie / elektromobilu — do jednoho semaforu: Levné · Průměr · Drahé. K dispozici jako web aplikace, mobilní aplikace (iOS + Android, brzy v Play Store), a kuchyňský kiosk pro starý tablet.
Jak semafor rozhoduje
Pravidlo pro barvu se řídí typem vašeho produktu, protože „levné teď?" znamená pro fixní a spotový produkt něco jiného:
| Produkt | Pravidlo | Červená (Drahé) |
|---|---|---|
| Fixní (většina domácností) | Cena má dvě pevné hladiny podle tarifního pásma — semafor kopíruje pásmo: nízký tarif (NT) = Levné, vysoký tarif (VT) = Průměr. | Nezobrazuje se — fixní cena se vůči sobě samé nikdy nestane „drahou“. |
| Spotový (a přepínač „Spot OTE“) | Cena se porovnává s průměrem dne: Levné ≤ 0,7 × průměru, Drahé ≥ 1,3 × průměru, mezi tím Průměr. | Ano — ve špičkách, kdy spot vystřelí nad 1,3 × denního průměru. |
Sazba bez nízkého tarifu (např. D02d) na fixním produktu svítí celý den oranžově — vaše cena se během dne opravdu nemění, a semafor to nepředstírá jinak.
Obrazovky webu
Hlavní záložky a jejich účel:
| Cesta | Co dělá | Datový zdroj |
|---|---|---|
/ | Teď — semafor + hero karta, 12-bar náhled na 3 hodiny dopředu, jeden návrh akce. | /api/now |
/historie | Historie — posledních 7 dní v shrnutí (denní průměr, nejlevnější okno, úspora). | synthetic (V1: Supabase ote_quarter_hour) |
/vy | Vy — profil domácnosti, měsíční úspora, nastavení, Pro upsell. | localStorage + /api/now |
/kiosk | Kuchyňský kiosk — landscape, čitelný ze 4 m, auto-rotace Teď / Dnes / Týden. | /api/now + /api/plan |
/epaper | E-paper varianta — monochrom, pro Pi-driven Inky / Inkplate displej. | /api/now |
/admin/readiness | Operátorský dashboard — OTE pulse, latence, poslední chyba. Vyžaduje ADMIN_READINESS_ENABLED=1. | /api/readiness |
/admin/calc-debug | Veřejná auditní stránka (M-V3AA): pro aktuální QH ukáže Server UTC vs Europe/Prague, ČNB kurz (live/fallback), raw OTE EUR/MWh, spot + allIn výpočet krok po kroku, koeficienty tarifu, carbon source. Každé číslo na /monitor a /api/now musí jít odsud odvodit. | live |
/admin/grid-debug | ČEPS Emise (autoritativní) vs IPCC AR6 × mix (derived) — 24h cross-validation graf + tabulka samplů. | /api/v1/grid + Supabase historie |
/zasady-ochrany-osobnich-udaju | Zásady ochrany osobních údajů (GDPR). Vyžadováno Play Store + App Store. | — |
/spec | Tato stránka. | — |
API endpointy
JSON API, které pohánějí jak web tak mobilní aplikaci. Edge runtime, region fra1 (Frankfurt).
| Cesta | Co vrací | Cache |
|---|---|---|
| /api/now?priceMode=allIn|spot | Aktuální stav semaforu — cena teď, cheapestWindow, next-12 strip, recommendation, carbon chip. Time-of-day výpočet je vždy v Europe/Prague (M-V3AA: server běží UTC, ale OTE QH index a všechny hour-of-day výpočty jdou přes Intl.DateTimeFormat se zónou Europe/Prague). Sdílený ČEPS cache (45 s) s /api/v1/grid → carbon hodnota na obou endpointech je vždy ze stejného vzorku. | no-store; OTE cache 60s; ČEPS cache 45s |
| /api/recommendation?priceMode=allIn|spot&sazba=…&distributor=…&hdoKod=… | Deterministická česká věta (M-V3AC). Mirror /api/now parametrů — recommendation se počítá ze STEJNÉHO state, který hero ukazuje. Tělo: 'Levné teď.' / 'Průměr.' / 'Drahé teď.' + konkrétní okno (start–end), volitelně 'uspoříte N %' když je rozdíl ≥ 5 %, volitelně 'Zítra X–Y' když je day-ahead publikován. | 60s public |
| /api/plan?date=today|tomorrow&priceMode=allIn|spot | 96-bar plán celého dne + carbon série. Volitelný priceMode přepíná mezi všezahrnujícím tarifem a spotem. | public, max-age=60 |
| /api/v1/grid | Veřejný endpoint — ČEPS snapshot (load + mix + low-carbon share). Pro Home Assistant. | 60s public |
| /api/v1/today, /api/v1/plan, /api/v1/state | Veřejný API balíček pro integrátory — otevřený, bez klíče (D13). Dokumentace na /api-docs. | 60s public |
| /api/readiness | Operační stav: OTE pulse, latence, schema. Gateováno ADMIN_READINESS_ENABLED. | no-store |
| /api/health | Smoke test pro Vercel deploy gate — ověří Supabase / OTE adapter / klíče. | no-store |
| /api/cron/ote-poll | Vercel Cron každou minutu — warmuje OTE cache. | — |
| /api/cron/daily-digest | Vercel Cron 13:30 Europe/Prague — push o cenách na zítřek (M5). | — |
| /api/cron/plunge-alert | Vercel Cron každých 15 min — detekuje záporné OTE → push (M5). | — |
Zdroje dat
Všechna data v EU. Žádné DPA navíc kromě uvedených zpracovatelů.
| Zdroj | Endpoint / mechanismus | Co odtud bereme | Auth |
|---|---|---|---|
| OTE-CR (SOAP) | https://www.ote-cr.cz/services/PublicDataService | Denní spot — 96 čtvrthodinových cen v EUR/MWh, zveřejněno ~13:00 Europe/Prague na následující den. Cena platí od minut 00 / 15 / 30 / 45 každé hodiny, v rámci čtvrthodiny se nemění. | — |
| ČNB (REST) | https://api.cnb.cz/cnbapi/exrates/daily | Denní fixing EUR → CZK. Aktualizace jednou denně ~14:30 v pracovní den. Slouží k převodu velkoobchodní ceny OTE-CR na korunu. Při výpadku pojistný kurz 25,0 Kč/EUR. | — |
| ČEPS (SOAP) | https://www.ceps.cz/_layouts/CepsData.asmx | Aktuální zatížení sítě (MW) + výroba podle paliva (jadrno / uhlí / plyn / OZE / přečerpávací) + CO₂ intenzita (Emise). Vzorek 1 / minutu. | — |
| IPCC AR6 (offline) | EMISSION_FACTORS_G_PER_KWH | Lifecycle emisní faktory pro CZ palivový mix (uhlí 950, jadrno 12, plyn 490, solární 45, větrná 11, voda 24, biomasa 230, přečerpávací 0). Pinováno v @semafor/core/carbon. Použito jako fallback když ČEPS Emise endpoint nevrátí hodnotu. | — |
| ERÚ tarify 2026 | tariffs2026 | Distribuční + systémové + POZE + daň z elektřiny + DPH koeficienty. Versionováno podle roku v @semafor/core/tariffs. | — |
| Distributor HDO | ČEZ-D / EG.D / PRE-D — uživatelem zadaný HDO kód | Plán NT / VT pro daný OPM. Uživatel zadá HDO kód z faktury při onboardingu. | — |
| Electricity Maps | api.electricitymap.org | Plánováno: 24h dopředu carbon intensity. Aktuálně placené (vyžaduje API klíč) — ČEPS-derived alternativa je výchozí. | API klíč |
| Estimated mix (M-V3AE) | createEstimatedCepsAdapter | Strukturovaný odhad mixu sítě jako fallback když ČEPS SOAP nedostupné. Anchor: Europe/Prague místní hodina + měsíc (sezónní solární škálování). Modeluje 8 paliv: Jádro 3.8 GW baseload, Uhlí 1.2–1.8 GW (rampuje s peak load), Plyn 0.25–0.6 GW (peakery), Solární 0–1.8 GW léto / 0–0.5 GW zima (Gaussian peak 13:00 lokálně), Větrná 0.3 GW, Voda 0.2 GW, Biomasa 0.13 GW, Přečerpávací ±0.3–0.8 GW (nabíjí při low-price, vybíjí 18–21h). Sourcing: ENTSO-E denní profily 2024–2025. Surface jako source="estimated". Weather hook připraven (cloudCoverPct, windSpeedMs) — open-meteo integrace plánovaná pro V1. | — |
| Synthetic fallback (legacy) | buildSyntheticNowState / buildSyntheticDayBars | Deterministická křivka (peakish: ranní + večerní špička). Aktivuje se při OTE_LIVE=0 nebo když /api/now nemá živá data. Pro grid mix vyhrává estimated mix (M-V3AE). | — |
Cenový řetězec (OTE → ČNB → Kč/MWh → Kč/kWh)
Každá cena, kterou v aplikaci uvidíte, vznikla touto cestou — pojmenovaná pro auditní transparentnost (M-V3T fix Daniela 2026-05-16):
- OTE-CR SOAP — element
<Price>obsahuje 15-min spotovou cenu v EUR/MWh (ne CZK). Příklad: 09:30–09:45 dne 2026-05-16 =17.63. Tu samou hodnotu vidíte na ote-cr.cz/cs/. - ČNB denní fixing — kurz EUR → CZK z
api.cnb.cz/cnbapi/exrates/daily. Aktualizace 1×/pracovní den ~14:30. Per-proces cache aby se nevolal pokaždé. Pro ten samý 09:30–09:45 sample při kurzu 24,335 = 17,63 × 24,335 = 429,02 Kč/MWh. - Volitelně přepočet na Kč/kWh — když uživatel zvolí přepínač Kč/kWh, dělíme 1000. 429,02 Kč/MWh = 0,43 Kč/kWh. Spotová velkoobchodní, bez DPH a distribuce.
- Volitelně přidání tarifních složek — když je zvolen mód „Můj tarif" (na záložce Plán + výchozí pro Now-tab), přidávají se distribuce (NT/VT podle HDO) dle cenového výměru ERÚ č. 14/2025, systémové služby, daň z elektřiny a 21 % DPH. Příspěvek na POZE je od roku 2026 pro domácnosti nulový (hradí ho státní rozpočet). Jde o orientační výpočet ceny za kWh — pevné měsíční platby (za příkon dle jističe, za činnost operátora trhu) v ceně nejsou, protože se nemění podle toho, KDY spotřebováváte.
- Fallback pro ČNB výpadek — pokud
api.cnb.cznedostupný (HTTP error, timeout), použijeme pojistný kurz 25,0 Kč/EUR. Volba je hardcoded a vzácně se mýlí o víc než 5 % — lepší než cenu nezobrazit vůbec. /admin/grid-debug ukáže, kdy se fallback aktivoval.
Cena: dva módy zobrazení
Na záložce Plán můžete přepínat mezi dvěma pohledy na cenu:
- Můj tarif (výchozí) — orientační výpočet vaší ceny za kWh. Z OTE spotu se spočítá silová složka, přidá distribuce (NT/VT podle HDO) dle cenového výměru ERÚ č. 14/2025, systémové služby, daň z elektřiny a DPH 21 % (POZE je od roku 2026 nulové). Pevné měsíční platby (jistič, operátor trhu) v ceně za kWh nejsou.
- Spot OTE — pouze velkoobchodní cena OTE-CR, bez tarifních příplatků. Stejná data jako EnerSpot.cz. Hodí se pro nadšence, prosumery a každého, kdo si tarifní přípočty řeší sám. Číslo je vždy nižší než „Můj tarif".
Komponenty
UI primitiva z balíčku @semafor/ui:
- ClockArc — značka aplikace. 64-pixelový prstenec s obloukem značícím nejlevnější okno. Škáluje se od Apple Watch (24 px) po kiosk (160 px). Subtle dýchací animace (4 s loop, opacity 0,78 ↔ 1,0).
- HeroCard — barevný gradient (zelený / oranžový / červený) s názvem stavu, cenou a doporučenou akcí. ClockArc je integrovaný v pravém horním rohu.
- PriceStrip — 12-bar mini-graf cen na další 3 hodiny. Popisky „Teď · +1 h · +2 h · +3 h" plus tečka pro „now" na horní hraně.
- PriceChart — 96-bar denní graf (jeden bar / čtvrthodinu) + tenký uhlíkový pruh nad ním. Hodinové popisky 00 / 04 / 08 / 12 / 16 / 20.
- ApplianceRow — řádek se spotřebičem (pračka / myčka / EV / tepelné čerpadlo) + nejlevnější doporučený čas spuštění.
- TabBar — Teď / Plán / Historie / Vy. Outline ikony, filled výplň pro aktivní záložku.
- TopBar — pozdrav (Dobré ráno / odpoledne / večer) + ozubené kolo pro nastavení.
- CarbonChip — „Síť: čistá / smíšená / špinavá" pill s g CO₂/kWh. Bere data ze /api/now.
- Sparkline — mini-trend pro „Měsíční úspora" na Vy záložce.
- SegmentedControl — Dnes / Zítra / Týden přepínač na Plán záložce. Také používáno pro „Můj tarif / Spot OTE" toggle.
Motivy (theme skins)
Aplikace podporuje čtyři vizuální motivy. Ve výchozím stavu se motiv přizpůsobí preferencím systému (světlý / tmavý); ostatní jsou opt-in.
- Light — výchozí, bílé pozadí, Bohemia blue accent. Kalibrované proti Apple Weather.
- Dark — tmavě navy pozadí, světlý text, jasnější verze barev semaforu.
- E-paper — pouze černá na bílé. Bez gradientů, bez stínů. Pro Inky / Inkplate / Kindle.
- Neon (NEW) — limetkový accent na téměř-černém navy pozadí. Inspirováno EnerSpot.cz. Opt-in skin pro „dashboard look".
Jazyk
Aplikace běží primárně v češtině (vy-formálně). Anglická verze je k dispozici pro mezinárodní integrátory (Home Assistant docs, GitHub README). Slovenština je plánována na V2.
Jak přepnout do angličtiny: nastavte primární jazyk prohlížeče na en. V Edge / Chrome: Nastavení → Jazyky → přesunout English (United States) nahoru. Aplikace čte hlavičku Accept-Language a přepne se automaticky. UI přepínač v aplikaci přijde v M6 spolu s Vy → Vzhled.
Zde používané externí služby a regiony
| Služba | Účel | Region |
|---|---|---|
| Vercel | Hosting web + edge runtime + ISR | Frankfurt (fra1) |
| Supabase | Postgres + Auth + Realtime + Storage | Frankfurt |
| Upstash Redis | OTE / HDO cache (60 s / 1 h TTL) | EU |
| Sentry | Error tracking + performance (PII redakce zapnutá) | EU |
| Axiom | Structured logging via OpenTelemetry | EU |
| PostHog | Anonymní statistika použití (jen po opt-in) | EU |
| Resend | Transactional email (týdenní digest, magic-link auth) | EU |
| Expo / EAS | Mobile build + OTA updates | Globální (zařízení) |
| Google Play Console | Distribuce Android (V0.1) | — |
| App Store Connect | Distribuce iOS (V1) | — |
Pro vývojáře
Repozitář: monorepo (pnpm workspaces + Turborepo).
@semafor/core— doménová logika (cenotvorba, HDO, sazby, semafor, uhlík). Žádné runtime závislosti na Reactu ani I/O. 216 testů, ≥ 95 % coverage.@semafor/data— adaptéry pro OTE, ČEPS, Electricity Maps, distributor HDO, inverter cloud. Veškerý I/O zde. 80 testů.@semafor/ui— cross-platform komponentní knihovna (react-native-web + StyleSheet + typed tokens). Storybook. 81 testů (včetně 14 pro theme variants).apps/web— Next.js 15 App Router. Edge runtime, region fra1. 41 testů (včetně build smoke + visual regression).apps/mobile— Expo SDK 54 managed workflow. iOS + Android. 0.1.0 verzována.
Celkem 418 testů, lint + typecheck clean. CI: GitHub Actions; CD: Vercel (web) + EAS Submit (mobile).
Stop-and-ask: co čeká na rozhodnutí Daniela
- Google Play Developer Account ($25 jednorázově).
- Apple Developer Program (€99 / rok).
- Electricity Maps API — placený plán, jen pro cross-validaci s ČEPS-derived hodnotami. Volitelné.
- Resend EU pro digest e-mail. Potřeba při M5.
- Upstash Redis EU + Supabase
jobstabulka. Potřeba při M5 / před stabilním produkčním cron.