Jak zkrotit balkonovou FVE – nula přetoků do sítě přes Node-RED
Balkonová elektrárna se prodává jako „zapoj do zásuvky a hotovo“. Do zásuvky ji opravdu zapojíte za deset minut. Problém začíná ve chvíli, kdy vyrobíte víc, než zrovna spotřebujete – přebytek poteče do sítě, distributor ho změří, nezaplatí za něj, a pokud máte smlouvu na rezervovaný výkon 0 kW, formálně dodáváte něco, na co nemáte právo.
Obtížnost: Pokročilý
Co je potřeba: Mikrostřídač s lokálním řízením výkonu (EcoFlow STREAM), třífázový elektroměr Shelly Pro 3EM, chytré relé (Shelly 1 Gen3), Home Assistant + Node-RED, BLE proxy
Řešení bez baterie je jediné: průběžně přiškrcovat výkon střídače tak, aby se výroba nikdy nedostala nad okamžitou spotřebu. Anglicky curtailment, česky „nula přetoků“.
Zní to jako triviální regulační smyčka. Není. Za tři týdny stavby a ladění jsem narazil na tři různé deadlocky, jeden neviditelný scénář, který by mi tekl do sítě 133 Wh za čtvrt hodiny bez jediného varování, a na cizí řídicí kanál, o kterém jsem netušil, že existuje.
Tenhle článek popisuje celou cestu: co je potřeba za hardware, proč se v Česku musí regulovat na jednu fázi, jak vypadá regulační vzorec, jak funguje hardwarová pojistka a hlavně – jaké pasti na vás čekají, až to postavíte.
Reálný výsledek po prvním plném dni ostrého provozu: výroba 1920 Wh, přetok do sítě 0,9 Wh. To je 0,047 % výroby a 0,003 % měsíční tolerance ERÚ.
Proč vůbec nula přetoků
Existují tři důvody, a každý sám o sobě by stačil.
1. Smlouva s distributorem. Nejjednodušší cesta, jak balkonovku legálně připojit, je kategorie „mikrozdroj zjednodušeně připojený do 10 kW bez přetoků„. Rezervovaný výkon 0 kW, poplatek 0 Kč, žádná licence ERÚ. Podmínkou je technické opatření, které dodávce do sítě zamezí.
2. Ekonomika. I kdyby vám přetoky nikdo nezakázal, nikdo vám je taky nezaplatí. Bez smlouvy o výkupu je každá kilowatthodina poslaná do sítě dárek distributorovi. Regulace na nulu má ekonomický smysl nezávisle na legislativě.
3. Ten nejdůležitější a nejméně známý: český elektroměr nesalduje fáze.
O tomhle bodě je zbytek článku.
Klíčové zjištění: elektroměr měří po fázích a NESALDUJE
Tohle je věc, na které padne většina návodů převzatých z Německa.
V Německu (a ve velké části EU) elektroměr sečte všechny tři fáze a zaznamená výsledek. Když na L1 vyrábíte 500 W a na L2 odebíráte 800 W, elektroměr vidí odběr 300 W a je klid.
V Česku ne. Elektroměr (u nás konkrétně ADX12A) měří každou fázi zvlášť a toky mezi fázemi nesčítá. Přebytek na fázi, kam vyrábí střídač, se zapíše do registru 2.8.0 = dodávka bez ohledu na to, kolik zrovna odebíráte na zbylých dvou fázích.
Česko má v této věci výjimku – vyhláška 82/2011 Sb. ve znění 359/2020 Sb. Ověřeno dotazem na ČEZ Distribuci a nezávisle na diskusních fórech i v odborných článcích (hybrid.cz, tzb-info).
Co z toho plyne pro regulaci
Mikrostřídač je jednofázový. Regulujte podle výkonu TÉ JEDNÉ fáze, kam vyrábí. Nikdy ne podle součtu.
Kdybyste regulovali podle součtu tří fází (což udělá naprostá většina hotových řešení, protože je to „logičtější“), vypadalo by to v HA skvěle – celkový odběr je kladný, vše v pořádku – a přitom by vám na fázi střídače tekl do sítě přetok, který uvidíte až na vyúčtování.
To má jeden nepříjemný důsledek, na který je lepší se připravit dopředu.
Strop výroby neurčuje střídač, ale baseload jedné fáze
Změřil jsem si profil tří fází pomocí Shelly Pro 3EM ještě před montáží, dva dny historie, denní hodiny:
| Kanál | Minimum | Medián | Hodnocení |
|---|---|---|---|
| A | ~3 W | ~3 W | mrtvá fáze – 100 % času by regulace držela nulu |
| B | 131 W | 186 W | stabilní dno, 0 % času ve stopce |
| C | 69 W | 186 W | stejný průměr jako B, ale 7,9 % času pod prahem |
Vybral jsem fázi B. Ne kvůli průměru (ten měla stejný jako C), ale kvůli stabilnímu dnu. Regulace se řídí minimem, ne průměrem, takže fáze s hlubokými propady je pro nás horší, i když v průměru vypadá stejně.
A teď to nepříjemné číslo: z 800 W instalovaného výkonu je v mém případě reálně využitelných jen ~168 W průměrně. Strop neurčuje střídač ani panely, ale trvalá spotřeba té jedné fáze.
Praktický závěr: než začnete cokoli montovat, změřte si profil fází. A pak zvažte, jestli nepřehodit trvalé spotřebiče – lednici, mrazák, server, router, oběhové čerpadlo – na fázi, kam bude vyrábět střídač. Je to nejlevnější způsob, jak zvýšit výnos celé investice.
Výhled: Lex OZE III (zákon 87/2025 Sb.) součtové měření vrací, jedno z účinnostních dat je 1. 1. 2027, vázané na rollout chytrých elektroměrů. Architekturu jsem proto postavil tak, že cíl regulace je jedna konfigurační hodnota – přepnutím z
Bnatotalse systém přizpůsobí bez zásahu do hardwaru.
Hardware – co všechno je potřeba
Výrobní část
| Komponenta | Konkrétně | Poznámka |
|---|---|---|
| Mikrostřídač | EcoFlow STREAM Microinverter EF-PS-800 | 800 W AC, 2× MPPT, IP67, EN 50549-1 |
| Panely | 2× Jinko Tiger Neo JKM440N (440 Wp) | N-type TOPCon, sklo-sklo bifaciální |
| Konstrukce | hliníkové profily + klemy | u mě na střechu pergoly, ~1 300 Kč |
Celkem 0,88 kWp DC / 0,80 kW AC / 0 kW rezervovaný výkon.

Řídicí a jisticí část (tohle je to, o čem článek je)
| Komponenta | Role | Cena |
|---|---|---|
| Shelly Pro 3EM | měření všech tří fází, zdroj pravdy pro regulaci | ~3 500 Kč |
| Shelly 1 Gen3 | hardwarový watchdog – fyzicky odpojí střídač | ~370 Kč |
| ESP32-WROOM-32U + ESPHome bluetooth_proxy | BLE dosah ke střídači v pergole | ~400 Kč |
| Napájecí zdroj Mean Well HDR-15-5 (DIN, 230 V → 5 V) | napájení ESP32 | ~300 Kč |
| IP65 box Noark PHS-8T + průchodka + silikagel | venkovní krabice na ESP32 | ~700 Kč |
| RCD 25 A/30 mA typ A + jistič 13 A char. B | podružný rozvaděč | dle instalace |
Home Assistant a Node-RED běží na existujícím serveru – pokud je teprve stavíte, mám na to samostatné návody: instalace Home Assistantu a Node-RED od instalace k prvnímu flow.
Pozor na napájení ESP32: z HDR-15-5 jde 5 V do micro-USB breakoutu, nikdy ne přímo do pinu 3V3. A box dejte do stínu – u mě naměřil Shelly v pergole 56,8 °C při 35 °C ve stínu a nulové zátěži.
Proč EcoFlow STREAM a ne PowerStream
Tohle rozhodnutí je pro celý projekt zásadní a je jediné, které nejde zpětně opravit softwarem.
PowerStream (dřívější hit a stále nejčastěji zmiňovaný v návodech) neumí nastavit výkon lokálně. I když se k němu připojíte přes Bluetooth, samotné nastavení výkonu vyžaduje EcoFlow cloud. To znamená, že vaše antireflow regulace je závislá na tom, jestli výrobci běží servery a jestli za pět let nevypne API.

STREAM jde řídit plně lokálně přes BLE díky komunitní integraci rabits/ha-ef-ble. Žádný cloud, žádné API klíče, žádná internetová konektivita. To je pro dlouhodobě provozovaný systém rozdíl mezi „funguje“ a „funguje, dokud“.
Entity, které integrace vytvoří (ověřeno na EF-BK1163)
| Entita | Role |
|---|---|
number.ef_bk1163_maximum_output_power | nastavitelný limit (0-800, krok 1 W) – tohle je ta páka |
sensor.ef_bk1163_grid_power | aktuální AC výstup střídače |
sensor.ef_bk1163_pv_1_power + _pv_2_power | výkon panelů – dva MPPT vstupy, musíte je sečíst |
sensor.ef_bk1163_grid_voltage / _frequency / _current | síťové veličiny |
Zakázané by default, ale stojí za povolení: grid_connection_status (užitečná diagnostika po zásahu watchdogu).
Změřené časování – počítejte s ním
Než jsem začal ladit, změřil jsem si na živém zařízení, jak rychle střídač vůbec reaguje. Odhady z internetu byly optimistické:
- Mrtvá doba příkaz → skutečná změna výkonu: ~4 s
- Zpoždění senzoru: ~2 s (fyzická změna → hodnota v HA)
- Rampa výstupu při změně: ~250 W/s
To znamená, že Shelly 3EM vidí realitu dřív než samotný střídač přes BLE. Regulace se proto opírá o elektroměr, ne o hlášení střídače.
Architektura: dvě nezávislé vrstvy
Základní princip, na kterém celý systém stojí:
| Vrstva | Co dělá | Kdy zasáhne |
|---|---|---|
| Software (Node-RED) | přepočítává limit střídače podle změřeného výkonu fáze | průběžně, každých 10 s + okamžitě při záporném odečtu |
| Hardware (Shelly 1 Gen3) | fyzicky odpojí střídač od sítě | když software přestane potvrzovat, že je vše v pořádku |
Hardwarová vrstva funguje jako dead-man’s switch. Shelly o Home Assistantu vůbec nic neví. Node-RED mu každých 10 sekund pošle:
http://192.168.1.57/rpc/Switch.Set?id=0&on=true&toggle_after=30
Každý takový heartbeat přepíše odpočet na nových 30 sekund. Jakmile potvrzování ustane – z jakéhokoli důvodu, ať už spadne Node-RED, Home Assistant, WiFi nebo celý server – relé samo rozepne, střídač ztratí AC a anti-islanding ho do 0,2 s odstaví.
Heartbeat NENÍ bezpodmínečný
Tohle je klíčový detail. Kdyby Node-RED posílal heartbeat prostě každých 10 s injectem, chránil by vás jen před vlastním pádem. Nechránil by před stavem, kdy Node-RED vesele běží, ale řídí naslepo – třeba proto, že Shelly 3EM přestal odesílat data.
Heartbeat proto odchází jen tehdy, když projde health check:
- data ze Shelly 3EM nejsou starší než 30 s,
- data ze střídače nejsou starší než 60 s a zároveň hlásí nenulový výkon (proč, to je dál),
- elevace slunce je nad 5°,
- neběží žádný trvalý přetok,
- není aktivní zámek po předchozím zásahu.
Konfigurace Shelly 1 Gen3
Nastavení je důležitější, než se zdá:
initial_state = off ← po výpadku proudu NESMÍ sepnout
in_mode = detached ← fyzický vstup neovládá relé
auto_on = false
auto_off = false ← časovač jde přes toggle_after v každém heartbeatu,
NE přes config auto_off
Otestujte to. Odpojte Shelly od napájení a zapojte zpět – relé musí zůstat rozepnuté, dokud nepřijde první heartbeat. U mě to prošlo, ale je to ten typ testu, který nechcete dělat až v ostrém provozu.
Regulační vzorec
limit = aktuální_výstup_střídače + (min_15s(výkon_cílové_fáze) − buffer)
limit = clamp(0 … 800), zaokrouhleno DOLŮ na 10 W
Vypadá to jednoduše, ale každý člen tam je z konkrétního důvodu.
Proč je tam aktuální_výstup_střídače? Protože odečet fáze už obsahuje to, co střídač právě dodává. Kdybyste počítali jen limit = min − buffer, dostanete regulátor s pevným bodem v (spotřeba − buffer) / 2 – tedy takový, který trvale rozdá jen polovinu dostupné výroby. Simulace: 212 Wh proti 384 Wh se správným vzorcem. Tuhle chybu mi mimochodem navrhla externí AI recenze jako „zjednodušení“.
Proč klouzavé minimum a ne okamžitá hodnota? Protože regulace se nesmí nechat překvapit spotřebičem, který se právě vypnul. Minimum za posledních 15 s je konzervativní odhad toho, co na fázi opravdu trvale běží.
Proč ne průměr? Zase externí návrh, zase vyvrácený simulací: průměr dal 18,2 Wh přetoku a méně výroby (289 vs 384 Wh). Průměr vás nechrání před propadem zátěže a přitom vás nutí k většímu bufferu.
Proč zaokrouhlovat dolů? Zaokrouhlování nahoru by ukrajovalo z bufferu.
Asymetrická reakce
Dolů skočí limit okamžitě v jednom kroku. Nahoru přidává maximálně 5 W za sekundu.
Přetok je drahý, ušlá výroba ne. Tahle asymetrie je nejlevnější bezpečnostní opatření v celém systému.
Důležitý detail: rampa musí být vyjádřená ve W za sekundu a násobit se skutečně uplynulým časem, ne „50 W za průchod smyčkou“. Původně jsem to měl na průchod a znamenalo to, že interval tiku byl skrytým regulátorem strmosti – kdo by ho zkrátil z 10 s na 5 s, tiše by zdvojnásobil rychlost náběhu. Simulace: +54 % přetoku a špička ze 400 na 611 W.
Rychlá cesta
Kromě pravidelného 10s tiku spouští přepočet i samotný odečet ze Shelly 3EM, jakmile na cílovém kanálu spadne pod −100 W. Shelly hlásí zhruba po sekundě, takže se překmit srovná za ~1 s místo až 10 s.
Proč zrovna −100 W a ne třeba −20 W? Protože nižší práh nic nepřináší. Když zmizí 2000W zátěž, odečet spadne z +40 rovnou na −310 W v jednom jediném vzorku. Práh −100 W ho tedy chytí ve stejné sekundě. Samostatné přetoky velikosti −20 až −50 W v praxi prakticky nevznikají.
Délka okna – 15 s je optimum, ne minimum
Původních 30 s jsem zvolil od stolu jako „konzervativní“. Analýza šesti hodin ostrého provozu ukázala, že to stálo 135 Wh ze 406 Wh dosažitelných – tedy pětinu až třetinu výroby.
Simulace na skutečně naměřeném profilu spotřeby:
| Okno | Výroba | Přetok | Max |
|---|---|---|---|
| 30 s | 415 Wh | 3,09 Wh | 589 W |
| 20 s | 465 Wh | 2,85 Wh | 593 W |
| 15 s | 498 Wh | 2,72 Wh | 593 W |
| 10 s | 514 Wh | 3,68 Wh | 592 W |
Zkrácení na 15 s dá +20 % výroby a přetok se nezhorší. Při 10 s už přetok roste bez úměrného zisku.
Kolik má být buffer
Buffer je bezpečnostní polštář – regulace necílí na 0 W odběru, ale na +buffer W.
Intuice říká „když mám přetoky, zvětším buffer“. Je to skoro neúčinné.
| Buffer | Výroba | Přetok | Max |
|---|---|---|---|
| 20 W | 410,2 Wh | 1,98 Wh | 430 W |
| 40 W | 384,4 Wh | 1,86 Wh | 410 W |
| 60 W | 359,7 Wh | 1,74 Wh | 390 W |
| 80 W | 329,7 Wh | 1,64 Wh | 380 W |
| 120 W | 256,6 Wh | 1,45 Wh | 380 W |
Zvýšení ze 40 na 120 W stojí třetinu výroby a přetok sníží jen o pětinu.
Důvod je fyzikální: zbytkový přetok nevzniká překmitem v ustáleném stavu (tam regulace drží přesně), ale výhradně při skokovém odpojení zátěže. A tam je jedno, jestli máte buffer 40 nebo 120 W, protože střídač stejně potřebuje ~3 s na sjetí dolů. Špičkový přetok je u všech bufferů prakticky stejný.
Správné pravidlo pro volbu bufferu
Buffer má krýt největší pravidelně spínající zátěž na dané fázi.
U mě to je kompresor lednice a mrazáku, ~70-85 W. Proto buffer 60 W. Když jsem měl den s prázdným domem a celková zátěž fáze B byla jen 150-230 W, každé sepnutí kompresoru znamenalo, že třetina až polovina veškeré spotřeby zmizí naráz. Buffer 60 W většinu z toho pohltil – ven proteklo 3-15 W po dobu ~5 s.
Node-RED flow – struktura

Logicky to vypadá takhle:
[inject: každých 10 s]──┐
├→ [REGULACE]──┬→ [STREAM: nastav limit] (number.set_value)
[3EM: state_changed]────┤ ├→ [Shelly heartbeat] (HTTP request)
(rychlá cesta < -100W)│ └→ [notifikace při závadě]
│
[STREAM: state_changed]─┘
↓
[cache: uloží do flow kontextu]
[hlídač nevýroby: elevace > 25° AND relé sepnuté AND PV < 20 W po 20 min]
→ notifikace
Ovládání z HA je přes čtyři helpery:
| Helper | Význam |
|---|---|
input_boolean.fve_regulace_povolena | hlavní vypínač. off → limit 0 a zastaví se heartbeat → relé za 30 s rozepne |
input_number.fve_buffer | bezpečnostní polštář ve W (u mě 60) |
input_number.fve_manualni_limit | > 0 vnutí pevný limit. Jen pro oživování |
input_select.fve_cil_regulace | kanál 3EM: A / B / C / total |
Volby jsou schválně písmena kanálů 3EM, ne L1/L2/L3 – jinak si vyrobíte druhé číslování a jednou se v tom spletete.
Jádro výpočtu
const MAX_W = 800; // max AC výkon střídače
const RAMP_UP_W_S = 5; // max přírůstek limitu za SEKUNDU
const STEP = 10; // krok nastavení STREAMu
const WIN_MS = 15000; // okno klouzavého minima
const MAX_AGE_3EM = 30000; // max stáří dat ze Shelly 3EM
const MIN_ELEV = 5; // min elevace slunce (°)
const GROSS_EXPORT = -100; // práh hrubého přetoku (W)
const GROSS_MS = 20000; // jak dlouho smí trvat, než rozepneme relé
const now = Date.now();
const c = flow.get('cache') || {};
// --- okno klouzavého minima ---
let win = flow.get('win') || [];
win = win.filter(s => now - s.t < WIN_MS);
const minFaze = win.length ? Math.min(...win.map(s => s.v)) : null;
// --- health check ---
const blokace = [];
if (now - c.ts3em > MAX_AGE_3EM) blokace.push('data 3EM stara');
if (c.elevace < MIN_ELEV) blokace.push('slunce pod obzorem');
if (minFaze === null) blokace.push('chybi okno mereni');
// POZOR: staroba dat ze střídače blokuje JEN když hlásí nenulový výkon
if (c.out > 0 && now - c.tsStream > 60000) blokace.push('data STREAM stara');
// --- výpočet limitu ---
let limit;
if (blokace.length) {
limit = 0;
} else {
const raw = c.out + (minFaze - buffer);
limit = Math.max(0, Math.min(MAX_W, raw));
limit = Math.floor(limit / STEP) * STEP; // vždy DOLŮ
// rampa nahoru vázaná na ČAS, ne na cyklus
const dt = Math.min((now - (c.tLast || now)) / 1000, 30);
if (limit > c.lastLimit) {
limit = Math.min(limit, c.lastLimit + RAMP_UP_W_S * dt);
limit = Math.floor(limit / STEP) * STEP;
}
}
Kompletní flow má 16 funkčních uzlů (plus 4 komentáře) a je k dispozici ke stažení jako importovatelný JSON.
Flow ke stažení
Celý flow si můžete stáhnout a naimportovat do vlastního Node-RED:
⬇️ fve-antireflow-node-red.json (verze ze 7. 8. 2026)
Import: v Node-RED menu → Import → vybrat soubor → Import. Flow se vloží jako nová záložka FVE regulace.
Co musíte po importu upravit
Flow je vytažený z mého ostrého provozu, takže odkazuje na moje entity. Pět míst, kde je potřeba zasáhnout:
| Kde | Co změnit |
|---|---|
Uzel Shelly: heartbeat a Shelly: OFF | v URL nahradit SHELLY-IP skutečnou IP adresou vašeho Shelly 1 Gen3 |
Uzel notifikace na telefon | službu notify.mobile_app_TVUJ_TELEFON přepsat na vaši mobilní aplikaci |
Uzel 3EM / helpery / osvit / STREAM | regex musí odpovídat názvům vašich entit Shelly 3EM a střídače |
Funkce cache -> flow kontext | konstanty STREAM_OUTPUT, STREAM_PV1, STREAM_PV2, STREAM_LIMIT – u vás bude jiné označení zařízení než ef_bk1163 |
Uzel STREAM: nastav limit | entityId na vaši number.*_maximum_output_power |
Dál je potřeba mít v Home Assistantu založené čtyři helpery z tabulky výše (fve_regulace_povolena, fve_buffer, fve_manualni_limit, fve_cil_regulace) a nastavený server node Home Assistant.
Nespouštějte to naostro hned po importu.
fve_regulace_povolenanechte naoffa projděte oživovací postup na konci článku – hlavně test watchdogu.
Past č. 1: BLE fronta se dá zahltit
Tohle byl nejzávažnější nález ze simulace a v ostrém provozu by mě stál rozepnuté relé.
ha-ef-ble je alpha integrace a zápis přes BLE trvá řádově sekundu. Rychlá cesta ale umí smyčku spustit i jednou za sekundu. Když každý průchod pošle number.set_value, fronta se zahltí a příkazy vůbec nedorazí. Střídač pak drží starý výkon, i když regulace už dávno přikázala nulu.
V simulaci to vypadalo takhle: výstup zůstal na 450 W celých 49 sekund, dokud nezasáhlo relé. To je 11,92 Wh přetoku v jediné epizodě.
Oprava – zápis se posílá jen když:
- limit se liší od toho, co má střídač skutečně nastaveno, o víc než 20 W (nula vždy), a zároveň
- od posledního zápisu uplynuly aspoň 3 s (při snižování – bezpečný směr) nebo 10 s (při zvyšování),
- nebo je poslední zápis starší než 5 minut (obnovovací zápis).
Efekt: v ustáleném provozu ~4 zápisy za 10 minut místo 60. Při běžném provozu ~100 zápisů za hodinu místo 424.
Past č. 2: EcoFlow aplikace je druhý řídicí kanál
První den ostrého provozu jsem si všiml, že limit občas skočí na 800 W. Nejdřív jsem to sváděl na chování střídače po BLE reconnectu. Analýza logu ukázala, že skoky (18:22:30, 18:27:12, 18:42:03) nekorelují s výpadky BLE (17:47, 17:56, 18:19).
Byla to mobilní aplikace EcoFlow, respektive cloud. Prosazuje svoje nastavení i bez otevřené aplikace, v intervalech 5 a 15 minut.
Mělo to ještě jeden zákeřný aspekt. Můj omezovač zápisů se původně porovnával s tím, co flow naposledy odeslalo. Cizí zápis tak prošel bez povšimnutí – vlastní výpočet se nezměnil, takže flow nemělo důvod psát a čekalo až na obnovovací zápis. Naměřená doba nápravy: 56 až 154 sekund. Při plném slunci by to znamenalo ~670 W přetoku po dobu až dvou a půl minut a jisté rozepnutí relé.
Dvě opravy:
- Ve flow: porovnávat se skutečným stavem entity
number.ef_bk1163_maximum_output_power, ne s vlastní historií. Náprava proběhne do 3 s, tedy dřív, než se cizí příkaz vůbec stihne fyzicky projevit (mrtvá doba je 4 s). - V síti: zablokovat střídači WiFi na routeru. Souboj dvou regulátorů o jedno zařízení je zbytečné riziko a odpovídá to i původnímu záměru jet bez cloudu. Po zablokování nepřišel ani jeden cizí zápis.
Past č. 3: tři deadlocky ze stejné příčiny
Tohle je nejcennější část článku a vsadím se, že na to narazíte taky.
Příčina: HA posílá state_changed jen při ZMĚNĚ hodnoty
Znělo to samozřejmě, dokud jsem si nespočítal důsledky. Když se hodnota nemění, událost nepřijde. Vůbec žádná. A veškerá logika postavená na „kdy jsem naposledy dostal data“ se rozpadne.
Deadlock 1 – PV = 0. Health check měl podmínku „PV výkon pod 20 W → blokuj“. Znělo to rozumně (v noci se nereguluje). Jenže: při rozepnutém relé střídač zastaví MPPT a hlásí PV = 0. Elektronika přitom žije z DC a BLE čte dál, takže to nevypadá jako výpadek. Výsledek: nízké PV zablokovalo heartbeat → relé zůstalo rozepnuté → PV zůstalo 0 → systém se sám už nikdy nevrátil.
Deadlock 2 – staroba dat. Po opravě prvního deadlocku se relé pořád nevracelo, tentokrát kvůli „data STREAM stará“. Při rozepnutém relé hlásí střídač neměnné nuly → HA neposílá žádné události → tsStream stárne donekonečna → blokace trvá věčně. Stejná příčina, jiná proměnná.
Deadlock 3 – prázdné okno měření. Objevil se až po zkrácení okna z 30 na 15 s. Při ustálené zátěži přestanou chodit události ze Shelly 3EM (hodnota se nemění!), okno klouzavého minima se vyprázdní, health check hlásí „chybí okno měření“ a limit spadne na 0. V logu jsem viděl 36 propadů limitu na nulu za den, z toho polovinu při zátěži 500-2200 W. Se 30s oknem bylo dvakrát tolik času vzorek chytit, takže se to schovávalo.
Obecné pravidlo, které z toho vzniklo
Podmínka odvozená ze střídače smí blokovat, jen když máme pozitivní důkaz, že střídač žije – tedy že hlásí nenulový výkon. Nula znamená „nevíme“, ne „závada“.
Bezpečnost musí stát na veličinách, které na stavu systému nezávisí: na vypočítané elevaci slunce (
sun.sunse počítá, zaseknout se nemůže) a na měření ze Shelly 3EM, které je před relé.
Konkrétní opravy:
- podmínka „PV > 20 W“ z health checku odstraněna (noc hlídá elevace slunce),
- staroba dat ze střídače blokuje jen když
out > 0, - regulační smyčka si okno měření doplňuje sama z poslední známé hodnoty (max. 1× za 2 s, jen když jsou data 3EM čerstvá).
Stejná past mimochodem hrozí u grid_connection_status – po sepnutí relé hlásí grid_offline po celou reconnect delay. Do health checku jsem ho proto schválně nepřidal.
Past č. 4: špatně určená fáze je neviditelná
Nejzákeřnější scénář ze všech. Kdyby zásuvka byla ve skutečnosti na jiné fázi, než mám nastavenou v fve_cil_regulace, na regulovaném kanálu by nebylo vidět vůbec nic. Regulace by spokojeně reportovala zdravý stav a střídač by exportoval, dokud by si toho někdo nevšiml na vyúčtování.
V simulaci: 133 Wh přetoku za 15 minut, nula zásahů, žádná notifikace.
Oprava: práh hrubého přetoku se nevyhodnocuje jen na regulovaném kanálu, ale na všech třech. Domácnost bez jiného zdroje nesmí exportovat na žádné fázi, takže je to bezpečné pravidlo. Po opravě nález klesl na 3,4 Wh, dvě rozepnutí relé a notifikaci na telefon.
Jak fázi ověřit v praxi
Stáhněte limit ze 100 na 0 W a sledujte kanály 3EM. U mě kanál B skočil ze 140,2 na 221,8 W (+81,6 W), A a C se nehnuly. Při návratu limitu spadl zpět. Fáze potvrzena.
Kdy rozepne relé (a kdy schválně ne)
Hrubý přetok sám o sobě relé nerozepne. Tohle je záměrné rozhodnutí, ne opomenutí.
Vzorec si přetok srovná během jednoho cyklu a rozepnutí by stálo víc než ten přetok: střídač má po ztrátě AC předepsanou reconnect delay 60 s až 20 minut podle síťového profilu. Jedno vypnutí konvice by vás tak stálo klidně 20 minut výroby.
Relé jde dolů, teprve když se stav nesrovná:
| Situace | Reakce |
|---|---|
| Přetok < −100 W, trvá do 20 s | jen se stáhne limit, relé drží |
| Přetok < −100 W déle než 20 s | zastaví se heartbeat + explicitní OFF → relé rozepne + zámek |
| Data z 3EM starší než 30 s | zastaví se heartbeat → relé rozepne do 30 s |
| Data ze střídače starší než 60 s a zároveň nenulový výkon | totéž |
fve_regulace_povolena = off | limit 0, heartbeat stop |
| Noc (elevace < 5°) | limit 0, heartbeat stop |
| Pád Node-RED, HA, WiFi | heartbeat prostě přestane chodit → relé rozepne do 30 s |
| Start / deploy Node-RED | reset kontextu + limit 0, relé se nerozepíná |
Zámek po zásahu watchdogu
Jakmile relé rozepne, střídač je odpojený a přetok zmizí. Bez dalšího opatření by regulace stav vyhodnotila jako zdravý, sepnula zpátky, střídač by po reconnect delay najel, zase začal exportovat – a takhle donekonečna. V simulaci: 4 rozepnutí za 700 sekund.
Proto se po zásahu kvůli přetoku nastaví zámek 5 minut. Při opakovaných zásazích se zdvojnásobuje (5 → 10 → 20 → 40 → 60 min, strop 60). Počítadlo se nuluje po 30 minutách klidu. Každý zásah pošle notifikaci na telefon.
Proč se při deployi relé nerozepíná
Původní návrh při každém startu Node-RED fyzicky odpojil střídač jako „bezpečný start“. Simulace ukázala, že to znamená, že každý deploy stojí celý reconnect delay, tedy až 20 minut výroby. A není to potřeba:
- po resetu kontextu je
lastLimit = 0, takže první příkaz po startu je max. 50 W (rampa), ne starý limit, - když start trvá déle než 30 s, relé rozepne samo (vyprší
toggle_after), - když je po startu cokoli špatně, health check heartbeat nepustí.
Hlídač nevýroby – opačný problém
Watchdog hlídá „vyrábíme moc“. Potřebujete ale i opak: svítí, ale střídač nedodává. Chytá mrtvé BLE, rozepnuté relé, které se nevrátilo, vyhozený jistič nebo odpojený konektor panelu.
elevace > 25° AND relé držíme sepnuté AND PV < 20 W po dobu 20 min
→ notifikace na telefon
Bez něj se dozvíte, že FVE týden nejela, až z vyúčtování.
Podmínka „relé držíme sepnuté“ (heartbeat odešel v posledních 60 s) je důležitá – když je relé rozepnuté kvůli noci nebo zámku, je nulová výroba správný stav, ne závada.
Původní verze měla podmínku „osvit > 300 W/m²“ z meteostanice. Pak se ukázalo, že ten senzor dva dny hlásil zamrzlých 1,9 W/m² – hlídač by tedy nesepnul nikdy. Diagnostika nesmí záviset na zařízení, které samo tiše umře. Meteostanice ve flow proto není vůbec; regulace jede výhradně ze Shelly 3EM, z vlastních dat střídače a z vypočítané elevace slunce.
Simulace: nástroj, který se vyplatil nejvíc
Nejlepší rozhodnutí celého projektu: napsal jsem si simulační harness, který načítá skutečný kód z flow JSON a protahuje ho fyzikálním modelem – elektroměr po fázích (nesalduje), Shelly relé s odpočtem toggle_after, střídač včetně reconnect delay, mrtvé doby 4 s, zpoždění senzoru 2 s, fronta BLE zápisů (zápis, který dorazí během zpracování předchozího, se zahodí), výpadky WiFi/HA/BLE/3EM.
Dnes má 18 scénářů, které jedou po každé změně flow.
| # | Scénář | Přetok | Max | Relé |
|---|---|---|---|---|
| 1 | Silné slunce 800 W, spotřeba jen 150 W | 0,00 Wh | 0 W | 0 |
| 3 | Spotřeba prudce klesne 2150 → 150 W | 0,79 Wh | 650 W | 0 |
| 5 | Výpadek WiFi v pergole (200 s) | 0,00 Wh | 0 W | 1 |
| 8 | Mrtvé BLE, střídač zamrzne na limitu | 0,00 Wh | 0 W | 1 |
| 9 | Reálný provoz 2 h (proměnlivá zátěž + mraky) | 2,86 Wh | 410 W | 0 |
| 15 | Špatně určená fáze (regulace B, střídač na C) | 3,65 Wh | 250 W | 2 |
| 16 | Návrat po rozepnutí (regrese na deadlock PV=0) | 0,00 Wh | 0 W | 0 |
| 17 | Aplikace přepisuje limit na 800 W každé 4 min | 0,00 Wh | 0 W | 0 |
| 18 | Ustálená zátěž, řídké události (regrese na deadlock 3) | 0,00 Wh | 0 W | 0 |
Ale pozor – a tohle je důležité poučení: simulace našla osm vážných chyb, ale oba deadlocky přehlédla, protože měl model slepou skvrnu. Model počítal výkon panelů nezávisle na stavu relé a posílal vzorky každou sekundu bez ohledu na to, jestli se hodnota změnila. Realita dělá obojí jinak.
Simulace vás nezachrání před chybou, kterou máte i v modelu. Zachrání vás ale před tím, aby se stejná chyba vrátila – jakmile jsem model opravil a přidal scénáře 16 a 18 jako regresní testy, jsou ty deadlocky navždy pokryté.
Reálné výsledky

První plný den ostrého provozu:
| Metrika | Hodnota |
|---|---|
| Výroba | 1920 Wh (06:19-19:42, špička 680 W) |
| Přetok do sítě (registr 2.8.0) | 0,9 Wh = 0,047 % výroby |
| Záporných odečtů | 21 z 9466 vzorků (0,22 % času) |
| Nejhorší okamžik | −344,5 W (jediný vzorek) |
| Rozepnutí relé | 0 |
| Výpadky BLE | 3 (6 s, 25 s, 3 s) – žádný nad prahem 60 s |
| Teploty | Shelly 3EM 52,1 °C, Shelly v pergole 54,6 °C |
Pro srovnání: tolerance ERÚ je 30 kWh měsíčně. 0,9 Wh za den je 0,003 % té tolerance.
Den s prázdným domem ukázal, kde zbytkový přetok vlastně vzniká. Celkem 1,79 Wh, z toho:
- jedna velká epizoda (spotřeba spadla z 3453 na 1634 W, −515 W po 4 s) = 0,571 Wh = 69 %
- 25 drobných epizod z cyklující lednice a mrazáku = 0,252 Wh = 31 %
Za den bylo 144 poklesů odečtu o víc než 50 W. Buffer 60 W většinu pohltil.
Zbytkové riziko, které curtailment neumí odstranit
Buďme upřímní: v okamžiku, kdy zmizí zátěž, teče do sítě rozdíl po dobu jednoho měřicího cyklu. Při plném výkonu je to až 800 W po dobu ~1 sekundy. Žádné softwarové ladění to neodstraní, protože fyzika střídače potřebuje ~3-4 s na sjetí dolů.
Právně to spadá pod dvě věci:
- výslovná výjimka v podmínkách PRE Distribuce (stejný PPDS jako ČEZ): technické řešení musí zamezit dodávce „s výjimkou krátkodobých přetoků, které slouží pro reakci omezujícího zařízení“,
- tolerance ERÚ od 8/2025: krátké technické přetoky ≤300 W okamžitě a 30 kWh/měsíc u legálně připojených zdrojů.
Trvale to odstraní až baterie (u STREAMu je to samostatný produkt AC Pro, ~1,92 kWh), která přebytek pohltí místo přiškrcení. Musí být na stejné fázi jako střídač – u nesaldujícího elektroměru je to nutnost, ne doporučení.
Oživování – doporučený postup
Nedělejte to najednou. Tenhle postup mě zachránil několikrát:
- Import flow + deploy,
fve_regulace_povolenanechte off. - Spárovat střídač přes BLE, doplnit entity, deploy.
- Ověřit, že regulační uzel ukazuje rozumné hodnoty (výkon fáze, minimum z okna).
- Test watchdogu – dělejte ho PŘED ostrým během:
- zastavte Node-RED → do 30 s musí relé slyšitelně cvaknout
- odpojte Shelly od napájení a zapojte → musí zůstat rozepnuté, dokud nepřijde heartbeat.
fve_manualni_limit= 100 W,fve_regulace_povolena= on. Sledujte výkon cílové fáze – musí klesnout zhruba o 100 W. Tím ověříte i správnost fáze.fve_manualni_limitzpět na 0 → naběhne automatická regulace.- Po prvním slunečném dni zkontrolovat na elektroměru registr 2.8.0 – musí zůstat na nule.
Bezpečnostní trik pro první test: nastavte manuální limit níž, než je minimální trvalá spotřeba té fáze (u mě 100 W při minimu 131 W). Pak nemůže vzniknout přetok, ani kdyby celá regulace nefungovala.
Shrnutí – checklist, než začnete
Před nákupem:
- Ověřit, že vybraný střídač jde řídit lokálně (BLE/Modbus), ne přes cloud
- Změřit profil tří fází aspoň týden – hledáte fázi se stabilním dnem, ne s nejvyšším průměrem
- Spočítat, kolik z instalovaného výkonu reálně využijete (u mě ~168 W z 800 W)
- Zvážit přesun trvalých spotřebičů na cílovou fázi
Při stavbě:
- Elektroměr Shelly Pro 3EM v hlavním rozvaděči (měří všechny fáze)
- Hardwarové relé před střídačem, s
initial_state = off - BLE proxy s ověřeným dosahem (u mě RSSI −38 dBm, 3 krátké výpadky za den)
- Box do stínu – teploty rostou rychleji, než čekáte
V softwaru:
- Regulovat podle jedné fáze, ale hrubý přetok hlídat na všech třech
- Vzorec musí obsahovat aktuální výstup střídače, jinak rozdáte půlku výroby
- Klouzavé minimum (15 s), ne průměr, ne okamžitá hodnota
- Asymetrická rampa: dolů skokem, nahoru 5 W/s
- Zaokrouhlovat vždy dolů
- Omezit počet zápisů na BLE (deadband + minimální rozestup)
- Porovnávat se skutečným stavem entity, ne s vlastní historií
- Žádná blokující podmínka odvozená ze střídače bez pozitivního důkazu, že střídač žije
- Heartbeat health-gated, ne bezpodmínečný inject
- Zámek po zásahu watchdogu, jinak systém začne cyklovat
- Hlídač nevýroby jako druhá strana mince
Papírování:
- Pořadí je montáž → revize (s naměřenou impedancí) → až potom žádost na distributora
- Impedanční limit pro 0,8 kW jednofázově: ≤0,75 Ω
- Kategorie „mikrozdroj zjednodušeně připojený do 10 kW bez přetoků“, poplatek 0 Kč, licence ERÚ netřeba
- Revizní zprávu, projektovou dokumentaci a protokol o nastavení ochran lze u malé instalace nahradit vyplněným formulářem žádosti (potvrzeno ČEZ Distribucí) – impedanci ale změřte vždy
Co se ukázalo nejcennější
Kdybych měl z celého projektu vypíchnout tři věci:
- Změřte si profil fází dřív, než cokoli koupíte. Určuje to strop výnosu celé investice a nezmění to žádné softwarové ladění.
- Hardwarová pojistka není volitelná, dokud stavíte na alpha integraci. Dead-man’s switch s health-gated heartbeatem stojí 370 Kč a řeší celou třídu problémů, které v softwaru nikdy nedomyslíte.
- Napište si simulaci, která načítá váš skutečný kód. Najde vám chyby, které v provozu uvidíte až na vyúčtování – a hlavně zabrání tomu, aby se jednou opravená chyba vrátila.
A jedno poučení navíc, které platí pro celý Home Assistant a ne jen pro FVE:
state_changedse posílá jen při změně hodnoty. Jakákoli logika typu „kdy jsem naposledy dostal data“ musí počítat s tím, že u ustálené veličiny nedostanete data nikdy. Narazil jsem na to třikrát v jednom projektu, pokaždé z jiné strany.
Flow je ke stažení jako importovatelný JSON. Systém běží v ostrém provozu od srpna 2026 a text budu aktualizovat, jak přibudou data z delšího provozu (hlavně zimní profil fází a chování při dlouhodobých výpadcích BLE).