Právě se nacházíte: Home / vyvoj /
ESP32-Grid-Load-Vypocet22.ino
podrobněji:String getEncryptionTypeString(wifi_auth_mode_t encryptionType)
wifi_auth_mode_t
, což je standardní datový typ z ESP-IDF frameworku pro ESP32) a vrací jeho textový popis. Například pro WIFI_AUTH_WPA2_PSK
vrátí řetězec "WPA2". Slouží k zobrazení srozumitelného typu šifrování uživateli, například při skenování dostupných Wi-Fi sítí.String read_file(fs::FS &fs, const char * path)
fs::FS &fs
: Reference na objekt systému souborů (v tomto případě SPIFFS).const char * path
: Cesta k souboru, který se má číst (např. "/config.txt").String
.void write_file(fs::FS &fs, const char * path, const char * message)
fs::FS &fs
: Reference na objekt systému souborů (SPIFFS).const char * path
: Cesta k souboru, do kterého se má zapisovat.const char * message
: Textový řetězec, který se má do souboru zapsat.message
do souboru. Během operace vypisuje informace o zapisovaném obsahu a názvu souboru na sériovou linku pro ladění. Nastavuje globální příznak UkladamWeb = 1
, aby se pozastavila hlavní smyčka loop()
během zápisu.void write_file2(fs::FS &fs, const char * path, const char * message)
write_file
, ale s minimálním výpisem na sériovou linku (pouze název souboru, pokud je WebSerialAno == 2
)./EaTest.ea
signalizujícího restart.String processor(const String& var)
ESPAsyncWebServer
. Funguje jako "template processor".const String& var
: Název zástupného symbolu (placeholderu) z HTML šablony (např. "EasunData", "temp1").%NAZEV_PROMENNE%
, zavolá tuto funkci s NAZEV_PROMENNE
jako argumentem var
. Funkce processor
pak na základě hodnoty var
načte odpovídající data ze souboru v SPIFFS (např. pro "temp1" čte /temp1.ea
) a vrátí je jako řetězec. Tento řetězec nahradí placeholder v odesílané HTML stránce.void notFound(AsyncWebServerRequest *request)
ESPAsyncWebServer
.AsyncWebServerRequest *request
: Ukazatel na objekt reprezentující HTTP požadavek.void buildTeplotaPageAndSettings()
/teplota
, kde může uživatel tato nastavení měnit./NazevTeplotaX.ea
)./VstupniTeplotaXa.ea
, /VstupniTeplotaX.ea
)./DistrX.ea
)./VstupniTeplota4.ea
)./VstupniTeplota5.ea
)./VstupniTeplota6.ea
)./distrmin.ea
, /distrmax.ea
)./solarWMin1.ea
, /solarWMax1.ea
, /solarWMin2.ea
)./oled.ea
, /htmlcolor.ea
)./baterie1.ea
- Min SOC, /baterie2.ea
- Max Watt)./teplota
(ukládá do globální proměnné gettemp
). Tento HTML kód obsahuje formulářové prvky (textová pole, posuvníky, select boxy) předvyplněné aktuálně načtenými hodnotami, což uživateli umožňuje vidět a měnit nastavení.void HlaskaRestart()
NeRestartuj
:
NeRestartuj == 0
: Zobrazí hlášku o aktualizaci dat a restartu. Vypne všechna SSR relé, zapíše testovací soubor a provede plný restart ESP32 (ESP.restart()
).NeRestartuj == 1
: Typicky po změně nastavení, která nevyžadují plný restart (např. úroveň sériového logování). Znovu načte hodnotu WebSerialAno
z SPIFFS. Resetuje příznak UkladamWeb
.NeRestartuj == 2
: Typicky po změně nastavení teplot, baterie nebo OLED. Zavolá buildTeplotaPageAndSettings()
pro aktualizaci HTML a souvisejících globálních proměnných. Znovu načte nastavení baterie (batterySOCMin
, batteryMaxWatt
) a barvu webu (barvicka
) z SPIFFS. Resetuje příznak UkladamWeb
.void action(AsyncWebServerRequest *request)
/reset
.AsyncWebServerRequest *request
: Ukazatel na objekt HTTP požadavku.KWh
s hodnotou "kWh", resetuje čítač spotřebované energie na modulu PZEM004T (pzem.resetEnergy()
).resetovat
s hodnotou "Resetovat nastavení", naformátuje celý systém souborů SPIFFS (smaže všechna uložená nastavení), zobrazí zprávu na OLED a provede plný restart zařízení voláním HlaskaRestart()
s NeRestartuj = 0
.void setupSoftAPForFallback()
getwifi_fallback_html
), která obsahuje prvek (dropdown menu) naplněný nalezenými SSID sítěmi, jejich RSSI (síla signálu) a typem šifrování. Dále obsahuje pole pro zadání hesla k vybrané síti a pole pro jméno, příjmení a email uživatele.
Nastaví handlery pro webový server v tomto AP režimu:
Pro / zobrazí tuto konfigurační stránku.
Pro /getwifi zpracuje odeslaná data (vybrané SSID, heslo, uživatelské údaje), uloží je do SPIFFS a restartuje ESP32, aby se pokusilo připojit k nově nakonfigurované síti.
Spustí webový server.
int initWiFi()
Popis: Inicializuje a spravuje připojení ESP32 k Wi-Fi síti.
Funkčnost:
Nastaví ESP32 do režimu Wi-Fi klienta (STA).
Pokusí se připojit k síti pomocí SSID a hesla načtených z globálních proměnných ssid a password (ty jsou naplněny z SPIFFS v setup()).
Během pokusů o připojení zobrazuje tečky na LCD a OLED.
Implementuje vícestupňový mechanismus opakovaných pokusů:
Po WIFI_RETRY_ATTEMPTS_STAGE1_MSG neúspěšných pokusech zobrazí zprávu "zkoušíme znovu".
Po WIFI_RETRY_ATTEMPTS_AP_MODE_FALLBACK pokusech zavolá setupSoftAPForFallback() pro spuštění nouzového AP režimu.
Po WIFI_RETRY_ATTEMPTS_RESTART_ESP pokusech restartuje ESP32.
Pokud je připojení úspěšné:
Zobrazí na LCD a OLED informace o síti (IP adresa, maska podsítě, brána, DNS, MAC adresa).
Uloží MAC adresu a IP adresu do globálních proměnných WiFiMac a IpAdresa.
Zapíše MAC adresu do souboru /keymac.ea v SPIFFS.
Vrátí 1 jako indikaci úspěchu.
Návratová hodnota: 1 při úspěšném připojení, jinak se buď přepne do AP módu, nebo restartuje.
String generujTeplotniKartu(...)
Popis: Pomocná funkce pro vytvoření HTML bloku (karty) zobrazujícího informace o jednom teplotním senzoru.
Parametry:
nazevDefault: Výchozí název senzoru (např. "TEPLOTA1").
nazevCustom: Uživatelsky definovaný název senzoru (pokud existuje).
teplotaAktualni: Aktuálně naměřená teplota.
tempMin, tempMax: Nastavené minimální a maximální teploty pro senzor.
ssrStatus: Stav přidruženého SSR relé (1 = ON, 0 = OFF).
distributorStatus: Stav povolení odběru od distributora (0 = Ne, 1 = Ano, 2 = Ano-Min-Max).
solarW: Aktuální solární výroba.
solarWMin: Minimální solární výroba pro aktivaci.
teplotaPrumerZaObdobi, krokuProPrumer: Hodnoty pro výpočet průměrné teploty (používá se, pokud aktuální čtení selže).
cardClass: CSS třída pro stylování karty (výchozí "card").
Funkčnost: Sestaví HTML řetězec obsahující:
Indikátor "S" (žlutý), pokud je dostatek solární energie (solarW >= solarWMin).
Indikátor "G" (červený), pokud je pro senzor povolen odběr od distributora.
Název senzoru (uživatelský, pokud je zadán, jinak výchozí).
Stav SSR relé ("ON" zeleně, "OFF" červeně).
Aktuální teplotu (nebo průměrnou, pokud je aktuální neplatná, s indikátorem '?').
Nastavené Min a Max teploty.
void SkladamHtml()
Popis: Sestavuje kompletní HTML kód pro hlavní webovou stránku (index, /).
Funkčnost:
Začíná základní HTML strukturou (hlavička, CSS, navigační odkazy).
Přidává dynamický obsah:
Informace o DHT senzoru (teplota, vlhkost).
Pro každý aktivní Dallas teplotní senzor volá generujTeplotniKartu() pro vytvoření informační karty. Pokud nejsou nalezena žádná Dallas čidla, zobrazí zprávu o kontrole zapojení.
Zobrazuje kartu "HEATING / PWM" s aktuálním odběrem topných těles (odberWatt), napětím (voltage), proudem (current), vypočteným PWM procentem (VypocetProcenta) a celkovou spotřebovanou energií (energy v kWh). Zobrazuje i externě doporučené PWM (VypocetProcentaOld1), pokud je k dispozici.
Zobrazuje kartu "SOLAR" s aktuální solární výrobou (solarW, solarA, solarV).
Zobrazuje kartu "LOAD / GRID" s celkovou spotřebou domu (loadW) a odběrem/dodávkou ze sítě (cezW, cezV).
Pokud je aktivní baterie (batteryV > 10), zobrazuje kartu "BATTERY" s napětím, výkonem, SOC a nastavenými limity (batteryMaxWatt, batterySOCMin).
Pokud je aktivní externí (primární) SSR zařízení (TssrXX > 0), zobrazí o tom informaci.
Přidává patičku s počítadlem (counter), verzí firmware, IP adresou a MAC adresou.
Výsledný HTML kód je uložen do globální proměnné output3.
int EasunEnergyPwm()
Popis: Funkce pro získání doporučené hodnoty PWM z externího serveru na základě aktuální solární výroby a nastavení distributora.
Funkčnost:
Pokud jsou nastaveny potřebné parametry (serverName2, apiKeyValue, WiFiMac), sestaví URL a odešle HTTP GET požadavek na serverName2.
URL obsahuje api_key, DBMac (což je WiFiMac), aktuální solarW, a nastavené cezWMin a cezWMax.
Očekává od serveru odpověď ve formě celého čísla, které reprezentuje doporučenou hodnotu PWM.
Tuto hodnotu uloží do globální proměnné VypocetProcentaOld1 a vrátí ji.
Pokud nejsou parametry nastaveny nebo dojde k chybě, pravděpodobně vrátí předchozí hodnotu VypocetProcentaOld1 nebo implicitně 0.
void EasunEnergy()
Popis: Funkce pro odesílání komplexních provozních dat na externí server pro účely archivace nebo dalšího zpracování.
Funkčnost:
Spustí se, pokud je čas odeslat data (JakCastoPosilatData == JakCastoPosilatDataFakt).
Pokud jsou nastaveny parametry (serverName2, apiKeyValue, WiFiMac) a aktuální odběr topných těles (odberWatt) a PWM (VypocetProcenta) jsou kladné:
Sestaví HTTP POST požadavek na serverName2.
Požadavek obsahuje api_key, WiFiMac, solarW, solarA, solarV, loadW, cezW, cezV, aktuální VypocetProcenta (PWM) a odberWatt (spotřeba topných těles).
Odešle požadavek a loguje HTTP stavový kód odpovědi.
void StavLCD3Radek()
Popis: Aktualizuje specificky třetí řádek LCD displeje a odpovídající část OLED displeje (pokud oled1 == 0).
Funkčnost:
Vymaže obsah na daných pozicích.
Zobrazí indikátor "OK:" nebo "NE:" podle toho, zda je energie využívána efektivně (např. solarW > 0 && odberWatt < solarW && odberWatt - cezW > 0).
Zobrazí rozdíl solarW - loadW (přebytek/nedostatek).
Zobrazí aktuální vypočtenou hodnotu PWM (VypocetProcenta).
Zobrazí aktuální odběr topných těles (odberWatt).
void StavLCD()
Popis: Hlavní funkce pro řízení zobrazení stavových informací na LCD (zejména 3. řádku).
Funkčnost:
Loguje základní informace o solární výrobě a odběru, pokud je WebSerialAno nastaveno.
Volá StavLCD3Radek() pro zobrazení dynamických dat o přebytcích, PWM a odběru.
float LogikaSolarPrebytekFunkce(float currentPwm)
Popis: Pomocná funkce pro VypocetSolarSpotrebaRefactored, která upravuje PWM, když je dostatek solární energie (přebytek).
Parametry: currentPwm (aktuální PWM před úpravou).
Funkčnost:
Pokud je odběr z baterie (batteryW) vyšší než povolené maximum (batteryMaxWatt), může se pokusit získat doporučené PWM z externího serveru (EasunEnergyPwm()).
Pokud je currentPwm nulové a není externí doporučení, nastaví základní PWM (např. 20-50%) v závislosti na velikosti přebytku (solarW - loadW).
Pokud je více SSR relé aktivních současně (v režimu "společně"), může PWM rozdělit mezi ně.
Pokud je odběr ze sítě (cezW) pod minimem (cezWMin), může se pokusit zvýšit PWM na základě poměru solarW / loadW nebo externího doporučení, aby se využily přebytky nebo dosáhlo minimálního odběru.
Používá krokovací proměnné (SolarKrokPlus, SolarKrokPlusMax, SolarKrokPlusMax2) k postupné úpravě PWM, aby se zabránilo rychlým změnám.
Návratová hodnota: Upravená hodnota PWM.
float LogikaGridNeboSolarNedostatekFunkce(float currentPwm)
Popis: Pomocná funkce pro VypocetSolarSpotrebaRefactored, která upravuje PWM, když solární energie nestačí nebo se využívá energie ze sítě.
Parametry: currentPwm (aktuální PWM před úpravou).
Funkčnost:
Pokud odběr ze sítě (cezW) překročí maximum (cezWMax), sníží currentPwm na základě poměru loadW / solarW (nebo fixní hodnotou, pokud solarW je 0).
Pokud odběr ze sítě (cezW) je pod minimem (cezWMin) a zároveň odběr z baterie (batteryW) je vyšší než povolené maximum (batteryMaxWatt), pokusí se zvýšit currentPwm (pokud je solární energie), aby se snížil odběr z baterie nebo zvýšil odběr ze sítě na minimum.
Používá krokovací proměnné (SolarKrokMinus, SolarKrokMinusMax, SolarKrokPlusU, SolarKrokPlusMaxU) pro postupné úpravy.
Návratová hodnota: Upravená hodnota PWM.
float RegulacePwmPodleBaterieFunkce(float currentPwm)
Popis: Pomocná funkce pro VypocetSolarSpotrebaRefactored, upravující PWM na základě stavu baterie.
Parametry: currentPwm (aktuální PWM).
Funkčnost: Pokud je odběr z baterie (batteryW) menší než nastavené maximum (batteryMaxWatt) a batteryMaxWatt není nula (tj. limit je aktivní), sníží currentPwm o 1.5.
Poznámka k logice: Toto chování se zdá být opačné, než by se očekávalo. Obvykle by se PWM snižovalo, pokud odběr z baterie překročí maximum. Je možné, že batteryW je interpretováno jinak (např. záporné hodnoty pro vybíjení) nebo je zde specifický záměr.
Návratová hodnota: Upravená hodnota PWM.
float RegulacePwmPodleDistributoraFunkce(float currentPwm)
Popis: Pomocná funkce pro VypocetSolarSpotrebaRefactored, upravující PWM, když je povoleno využití energie od distributora pro topná tělesa.
Parametry: currentPwm (aktuální PWM).
Funkčnost:
Pokud je globální nastavení temp5 (maximální PWM od distributora) větší než 0:
Postupně upravuje temp55 (aktuální cílové PWM od distributora) směrem k temp5.
Pokud je některé SSR relé zapnuté a má nastaveno distributorX == 1 (Distr.Ano), nastaví currentPwm na temp55.
Pokud je některé SSR relé zapnuté a má nastaveno distributorX == 2 (Distr.Ano-Min-Max):
Snaží se udržet odběr ze sítě (cezW) mezi cezWMin a cezWMax a zároveň zohledňuje odběr z baterie (batteryW vs batteryMaxWatt).
Pokud je odběr ze sítě příliš vysoký nebo odběr z baterie příliš vysoký, sníží currentPwm.
Pokud je odběr ze sítě nízký a je prostor v baterii, zvýší currentPwm (až do limitu temp5).
Návratová hodnota: Upravená hodnota PWM.
float FinalniUpravyARegulacePwmFunkce(float currentPwm)
Popis: Pomocná funkce pro VypocetSolarSpotrebaRefactored, provádí závěrečné kontroly a ohraničení hodnoty PWM.
Parametry: currentPwm (aktuální PWM).
Funkčnost:
Pokud je solární výroba (solarW) nad minimem (solarWMin) a je nastaveno minimální PWM pro solár (solarPMin > 0), zajistí, že currentPwm není nižší než solarPMin.
Pokud má externí (primární) zařízení (TssrXX) prioritu, nastaví currentPwm na 0.
Pokud jsou všechna SSR relé (ssrON1, ssrON2, ssrON3) vypnutá, nastaví currentPwm na 0.
Pokud je solární výroba pod minimem (solarW < solarWMin) a zároveň není povoleno topení od distributora (temp5 == 0), nastaví currentPwm na 0.
Pokud je solární výroba nad minimem a je nastaveno maximální PWM pro solár (solarPMax > 0 a solarPMax < currentPwm), omezí currentPwm na solarPMax.
Pokud je SOC baterie (batterySOC) pod minimem (batterySOCMin) a tento limit je aktivní (batterySOCMin > 0), nastaví currentPwm na 0.
Nakonec omezí currentPwm do rozsahu 0 až 100.
Návratová hodnota: Finální hodnota PWM.
float VypocetSolarSpotrebaRefactored()
Popis: Hlavní funkce pro výpočet optimální hodnoty PWM pro řízení SSR relé. Nahrazuje starší funkci VypocetSolarSpotreba().
Funkčnost:
Převezme aktuální globální hodnotu VypocetProcenta jako výchozí bod.
Inkrementuje různé krokovací čítače (SolarKrokPlus, SolarKrokPlusU, SolarKrokMinus, VypocetProcentaOld2, VypocetProcentaOld3), které slouží k časování nebo postupnému provádění změn v pomocných funkcích.
Na základě aktuálních podmínek (solární přebytek vs. nedostatek, stav distributora) volá buď LogikaSolarPrebytekFunkce nebo LogikaGridNeboSolarNedostatekFunkce.
Následně volá RegulacePwmPodleBaterieFunkce a RegulacePwmPodleDistributoraFunkce pro další úpravy.
Nakonec volá FinalniUpravyARegulacePwmFunkce pro finální ohraničení a kontroly.
Pokud není aktivní LCD menu, aktualizuje stav na LCD pomocí StavLCD().
Pokud jsou splněny podmínky, volá EasunEnergy() pro odeslání dat.
Resetuje krokovací čítače.
Aktualizuje globální proměnnou VypocetProcenta výslednou hodnotou a tuto hodnotu také vrátí.
Návratová hodnota: Vypočtená hodnota PWM (0-100).
void OvladaniPwmSSR()
Popis: Aplikuje vypočtenou hodnotu PWM na fyzický výstupní pin ESP32.
Funkčnost:
Zavolá VypocetSolarSpotrebaRefactored() pro získání aktuální optimální hodnoty PWM (0-100).
Převede tuto procentuální hodnotu na 8bitovou hodnotu (0-255) vhodnou pro funkci analogWrite(). Výpočet: (int)(PWMNastav * 2.55).
Nastaví PWM signál na PWMpin pomocí analogWrite(PWMpin, PWMvalue).
void MqttLCDdata()
Popis: Zobrazuje data přijatá prostřednictvím MQTT na LCD a OLED displejích (pokud oled1 == 0, tj. OLED sdílí zobrazení s LCD).
Funkčnost:
OLED: Zobrazuje:
Solární výrobu (solarW, solarV, solarA).
Spotřebu (loadW), odběr ze sítě (cezW, cezV).
Stav baterie (batteryW, batteryV, batterySOC).
Na 3. řádku (index 6,7) OLEDu zobrazuje přebytky/nedostatky, PWM a odběr topných těles (podobně jako StavLCD3Radek).
LCD:
Řádek 0: Solární výrobu (solarW). Pokud solarW <= 0, zobrazí "GRID:" a aktuální PWM (VypocetProcenta). Pokud je nějaké SSR aktivní a solarW <= 0, zobrazí detaily tohoto SSR (Min teplota, aktuální teplota, Max teplota).
Řádek 1: Spotřebu (loadW), odběr ze sítě (cezW), napětí sítě (cezV).
Řádek 2: Informace o baterii (batteryW, batteryV, batterySOC). Pokud je batterySOCMin > 0, střídavě zobrazuje aktuální SOC vs. batterySOCMin a standardní údaje o baterii. Pokud baterie není funkční (batteryV <= 10), zobrazuje celkovou spotřebu (energy v kWh) nebo stav aktivního SSR.
void onMqttMessage(int messageSize)
Popis: Callback funkce, která se automaticky zavolá, když MQTT klient přijme novou zprávu.
Parametry: messageSize (velikost přijaté zprávy, zde se přímo nepoužívá, ale je součástí signatury callbacku).
Funkčnost:
Získá téma (topic) a obsah (payload) přijaté MQTT zprávy.
Porovná téma zprávy s předdefinovanými tématy uloženými v proměnných topic0 až topic2b (např. topic0 pro solární výrobu ve Wattech).
Pokud se téma shoduje, převede obsah zprávy (payload) na odpovídající datový typ (např. toInt(), toFloat()) a uloží ho do příslušné globální proměnné (např. solarW, batterySOC).
Resetuje watchdog čítač, což signalizuje, že MQTT komunikace je aktivní.
void TeplotaNaLCD()
Popis: Zobrazuje aktuální teploty z Dallas senzorů a související informace na LCD a OLED displejích.
Funkčnost:
LCD (řádek 0, pravá část): Střídavě zobrazuje teplotu z T1, T2, T3 (pokud jsou aktivní a watchdog2 dosáhne určité hodnoty).
OLED (pokud oled1 == 1, tj. OLED má samostatné zobrazení teplot):
Pokud není aktivní externí SSR (TssrXX == 0):
Pro každý aktivní Dallas senzor (T1, T2, T3) zobrazí:
Název ("T1", "T2", "T3").
Aktuální teplotu (nebo průměrnou, pokud je aktuální čtení chybné).
Nastavené Min a Max teploty.
Stav SSR ("ON" / "OF").
Informaci o povolení distributora ("Distr: Ano" / prázdné).
Pokud je aktivní externí SSR (TssrXX > 0):
Zobrazí informaci o kontrole externího relé, adresu serveru a které externí SSR je zapnuto.
LCD (řádek 0, část): Střídavě zobrazuje solární napětí (solarV) nebo proud (solarA) v závislosti na hodnotě watchdog2.
void SSRRele()
Popis: Hlavní logika pro rozhodování o zapnutí/vypnutí jednotlivých SSR relé (SSR1, SSR2, SSR3) na základě teplot, nastavení a dostupnosti energie.
Funkčnost: Pro každé ze tří teplotních čidel/SSR relé (pokud je nakonfigurováno, tj. tempX > 0 a tempXa >= 0, a pokud nemá prioritu externí zařízení TssrXX == 0):
Použije aktuální teplotu (teplotaX) nebo její klouzavý průměr (tXprumer / tXkrok), pokud je aktuální čtení neplatné.
Podmínky pro zapnutí ssrONX = 1:
Pokud teplota klesne pod nastavenou minimální hodnotu (tempXa - 0.5).
NEBO pokud je již relé zapnuto (tempXb == 1) a teplota je stále pod nastavenou maximální hodnotou (tempX + 0.5).
A ZÁROVEŇ je k dispozici energie: buď solární výroba je nad minimem (solarW > solarWMin) NEBO je pro dané SSR povoleno použití distributora (distributorX == 1 nebo distributorX == 2).
Podmínky pro vypnutí ssrONX = 0:
Pokud teplota překročí maximální hodnotu (tempX).
Nebo pokud nejsou splněny podmínky pro zapnutí.
Aktualizuje pomocný příznak tempXb (latch pro hysterezi), pokud je temp6 == 0 (zapínání pod Max teplotou a solární energie je dostupná).
Pokud je tempX <= 0 (SSR není nakonfigurováno), ssrONX se nastaví na 0.
Režim "samostatně" (temp4 == 0): Pokud se zapne SSR1, ZapniSsrIhned1 se nastaví na 1, což zabrání zapnutí SSR2 a SSR3. Podobně pro SSR2, pokud je aktivní, zabrání SSR3.
Režim "společně" (temp4 == 1): ZapniSsrIhnedX se nenastavuje, takže více SSR může být aktivních současně.
Fyzicky zapne/vypne relé pomocí digitalWrite(SSRX_PIN, HIGH/LOW).
void ZapninamRelePodleTeploty()
Popis: Funkce, která rozhoduje, zda se má vůbec přistoupit k logice spínání SSR relé (SSRRele()) na základě stavu baterie a dostupnosti jiných zdrojů energie.
Funkčnost:
Pokud baterie funguje (batteryV > 10):
Pokud je povoleno topení od distributora (temp5 > 0) NEBO je dostatek solární energie (solarW >= solarWMin) NEBO je kontrola SOC baterie vypnutá (batterySOCMin == 0), A ZÁROVEŇ aktuální SOC baterie je vyšší než nastavené minimum (batterySOC > batterySOCMin), pak zavolá SSRRele().
Jinak (např. SOC je příliš nízké a není jiný povolený zdroj), vypne všechna SSR relé (ssrONX = 0, digitalWrite(LOW)).
Pokud baterie nefunguje (batteryV <= 10):
Pokud je povoleno topení od distributora (temp5 > 0) NEBO je dostatek solární energie (solarW >= solarWMin), pak zavolá SSRRele().
Jinak vypne všechna SSR relé.
String generateResetPageContent()
Popis: Dynamicky generuje HTML obsah pro stránku /reset.
Funkčnost:
Sestaví HTML stránku s navigačními odkazy.
Přidá formulář s tlačítkem "Resetovat nastavení", které po potvrzení odešle POST požadavek na /action pro formátování SPIFFS.
Vypíše seznam všech souborů nalezených v kořenovém adresáři SPIFFS.
U každého souboru zobrazí jeho název, velikost a odkaz "Smazat". Kliknutí na "Smazat" (po potvrzení) odešle GET požadavek na /deletefile?filename=NAZEV_SOUBORU.
void initializeTemperatureSensors()
Popis: Inicializuje knihovnu DallasTemperature pro komunikaci s 1-Wire teplotními senzory.
Funkčnost:
Volá sensors.begin(), což detekuje připojené senzory na 1-Wire sběrnici.
Získá počet nalezených senzorů pomocí sensors.getDeviceCount() a uloží ho do globální proměnné deviceCount.
Pokud se počet detekovaných senzorů změnil od posledního volání, vypíše informaci na sériovou linku.
Nastaví watchdog2Max (používá se pro cyklování zobrazení na LCD) na dvojnásobek počtu senzorů.
void aktualizujMereniTeplotDallas()
Popis: Pravidelně čte hodnoty z Dallas teplotních senzorů a spravuje jejich stav.
Funkčnost:
Zkontroluje aktuální počet senzorů na sběrnici (sensors.getDeviceCount()). Pokud se liší od uloženého deviceCount, zavolá initializeTemperatureSensors() pro re-inicializaci a resetuje průměrovací proměnné.
Pokud je deviceCount > 0:
Vyžádá nové hodnoty teplot ze všech senzorů (sensors.requestTemperatures()).
Pro každý potenciální senzor (index 0, 1, 2):
Načte teplotu pomocí sensors.getTempCByIndex(index).
Uloží načtenou hodnotu do příslušné globální proměnné teplota1, teplota2 nebo teplota3.
Pokud je hodnota platná (není NaN, 85.0°C ani -127.0°C – což jsou chybové hodnoty Dallas senzorů):
Přidá hodnotu k součtu pro klouzavý průměr (tXprumer) a inkrementuje počet kroků (tXkrok).
Nastaví příznak, že alespoň jedno čtení v tomto cyklu bylo úspěšné.
Pokud senzor není přítomen (např. deviceCount < 2 pro teplota2), nastaví teplotaX na DEVICE_DISCONNECTED_C.
Pokud byla všechna čtení v tomto cyklu chybná (a deviceCount > 0), inkrementuje consecutive_temp_sensor_read_errors.
Pokud consecutive_temp_sensor_read_errors dosáhne MAX_CONSECUTIVE_TEMP_ERRORS, provede re-inicializaci senzorů a resetuje průměry.
Pokud bylo alespoň jedno čtení v cyklu úspěšné, resetuje consecutive_temp_sensor_read_errors.
Pokud deviceCount == 0, nastaví všechny teplotaX na DEVICE_DISCONNECTED_C a resetuje průměry a chybový čítač.
void setup()
Popis: Standardní funkce Arduino, která se spouští jednou při startu nebo restartu ESP32. Provádí veškerou potřebnou inicializaci.
Funkčnost:
Inicializuje sériovou komunikaci (Serial.begin()).
Inicializuje Task Watchdog Timer pro sledování zablokování hlavní smyčky.
Nastavuje GPIO piny jako výstupy pro SSR relé a jako vstupy s pull-up rezistory pro tlačítka menu. Vypíná všechna SSR relé.
Inicializuje systém souborů SPIFFS (SPIFFS.begin()).
Načítá testovací příznak restartu (/EaTest.ea).
Inicializuje Dallas teplotní senzory (initializeTemperatureSensors()) a DHT senzor (dht1.begin()).
Inicializuje I2C komunikaci (Wire.begin()) a displeje LCD (lcd.init(), lcd.backlight()) a OLED (oled.begin()). Zobrazuje úvodní obrazovky.
Načítá všechna uložená nastavení z SPIFFS do globálních proměnných (Wi-Fi, MQTT, uživatelské údaje, API klíče, adresy serverů, parametry teplotní regulace, limity baterie, nastavení displeje, úroveň logování). Pro nastavení teplot volá buildTeplotaPageAndSettings().
Konfigurace sítě:
Pokud nejsou uloženy přihlašovací údaje k Wi-Fi, aktivuje AP mód: naskenuje okolní sítě, zobrazí je na konfigurační webové stránce, kde uživatel může vybrat síť, zadat heslo a své údaje. Po uložení se ESP32 restartuje.
Pokud jsou údaje k Wi-Fi uloženy, volá initWiFi() pro připojení.
MQTT: Pokud je Wi-Fi připojena, MQTT broker je nakonfigurován (broker != "null") a povoleno (BrokerAno == 0):
Pokusí se připojit k MQTT brokeru. V případě neúspěchu zobrazí chybu a může restartovat.
Nastaví onMqttMessage jako callback pro příchozí zprávy.
Přihlásí se k odběru témat (topics) definovaných v načtených nastaveních (např. pro solární výrobu, spotřebu, baterii).
Web Server: Nastaví všechny handlery (obslužné funkce) pro jednotlivé URL cesty webového serveru (/, /wifi, /mqtt, /teplota, /batt, /serial, /web, /key, /reset, /deletefile, /action, /tssr, /data, /data2, /restart). Spustí web server (server.begin()).
Autorizace zařízení: Pokud je Wi-Fi připojena a API klíč (ApiEspXX) je načten, odešle GET požadavek na AdresaAutorizace obsahující API klíč, MAC adresu a uživatelské údaje. Podle odpovědi serveru nastaví globální příznak ApiChybaOvereni, který ovlivňuje funkčnost programu (plná funkčnost, omezená, nebo chyba).
Resetuje testovací příznak restartu (write_file2(SPIFFS, "/EaTest.ea", "0")).
bool readButtonDebounced(int pin, int buttonIndex)
Popis: Čte stav tlačítka připojeného na zadaný pin a provádí softwarové ošetření proti zákmitům (debouncing).
Parametry:
pin: GPIO pin, na kterém je tlačítko připojeno.
buttonIndex: Index tlačítka (0, 1, 2) pro ukládání jeho stavu do polí btnLastState, btnLastDebounceTime, btnCurrentState.
Funkčnost:
Přečte aktuální stav pinu.
Pokud se stav liší od posledního známého stavu (btnLastState[buttonIndex]), zaznamená čas změny (btnLastDebounceTime[buttonIndex]).
Pokud od poslední změny uplynula dostatečná doba (btnDebounceDelay), považuje aktuální stav za stabilní.
Pokud se tento stabilní stav liší od potvrzeného stavu (btnCurrentState[buttonIndex]) a je to stisk (LOW, protože se používá INPUT_PULLUP), aktualizuje btnCurrentState a vrátí true.
V ostatních případech vrátí false.
Návratová hodnota: true, pokud byl detekován potvrzený stisk tlačítka, jinak false.
void loadSettingsForMenuEdit()
Popis: Načítá aktuální hodnoty nastavení baterie z SPIFFS do dočasných proměnných pro účely editace v LCD menu.
Funkčnost:
Přečte hodnotu minimálního SOC baterie ze souboru /baterie1.ea a uloží ji do temp_batterySOCMin.
Přečte hodnotu maximálního výkonu odebíraného z baterie ze souboru /baterie2.ea a uloží ji do temp_batteryMaxWatt.
Tyto dočasné proměnné pak slouží jako pracovní kopie během editace v menu, aby se změny neprojevily okamžitě v hlavním programu.
void saveAndApplyMenuSettings()
Popis: Ukládá změněné hodnoty nastavení baterie z LCD menu zpět do SPIFFS a aplikuje je.
Funkčnost:
Zobrazí na LCD zprávu o ukládání.
Zapíše hodnotu z temp_batterySOCMin do souboru /baterie1.ea.
Zapíše hodnotu z temp_batteryMaxWatt do souboru /baterie2.ea.
Nastaví NeRestartuj = 2 a zavolá HlaskaRestart(). Tím dojde k znovunačtení konfigurace (včetně právě uložených hodnot baterie a sestavení HTML pro /teplota) bez nutnosti plného restartu ESP32.
Po krátké prodlevě přepne stav menu zpět na hlavní zobrazení (STATE_MAIN_DISPLAY) a vymaže LCD.
void displayLcdMenu()
Popis: Zobrazuje aktuální stav a obsah LCD menu na displeji.
Funkčnost:
Vymaže LCD displej.
Podle aktuálního stavu menu (currentMenuState):
STATE_MENU_ROOT: Zobrazí hlavní položky menu ("1.Baterie", "2.Ulozit & Pouzit", "3.Zpet na Hl.Obr."). Před aktuálně vybranou položkou (menuSelectedItem) zobrazí znak '>'.
STATE_EDIT_BATT_SOC: Zobrazí text "Min SOC Baterie:", aktuální hodnotu menuEditValue v procentech a nápovědu k ovládání.
STATE_EDIT_BATT_WATT: Zobrazí text "Max Watt Baterie:", aktuální hodnotu menuEditValue ve Wattech a nápovědu k ovládání.
Výchozí stav (pro neimplementované části): Zobrazí "Menu ve vyvoji".
void handleLcdMenuInput()
Popis: Zpracovává stisky tlačítek pro navigaci a úpravy v LCD menu.
Funkčnost:
Timeout nečinnosti: Pokud je menu aktivní a od poslední interakce uplynul čas MENU_INACTIVITY_TIMEOUT_MS, automaticky se vrátí na hlavní zobrazení (STATE_MAIN_DISPLAY).
Přečte stavy tlačítek UP, DOWN, CONFIRM pomocí readButtonDebounced().
Pokud je aktivní menu a bylo stisknuto tlačítko, aktualizuje čas poslední aktivity.
Logika podle stavu menu:
STATE_MAIN_DISPLAY: Pokud je stisknuto CONFIRM, přejde do STATE_MENU_ROOT, načte nastavení pro editaci (loadSettingsForMenuEdit()) a zobrazí menu.
STATE_MENU_ROOT:
UP/DOWN: Mění vybranou položku menuSelectedItem (cyklicky).
CONFIRM:
Na "1.Baterie": Přejde do STATE_EDIT_BATT_SOC, menuEditValue se nastaví na temp_batterySOCMin.
Na "2.Ulozit & Pouzit": Zavolá saveAndApplyMenuSettings().
Na "3.Zpet na Hl.Obr.": Přejde do STATE_MAIN_DISPLAY.
STATE_EDIT_BATT_SOC / STATE_EDIT_BATT_WATT:
UP/DOWN: Mění menuEditValue (s limity 0-100% pro SOC, -2000-2000W pro Watt). Implementuje auto-repeat: krátký stisk změní hodnotu o 1, držený stisk po počáteční prodlevě (AUTO_REPEAT_INITIAL_DELAY_MS) začne měnit hodnotu opakovaně v intervalech (AUTO_REPEAT_INTERVAL_MS), u Wattů o 5.
CONFIRM:
Z STATE_EDIT_BATT_SOC: Uloží menuEditValue do temp_batterySOCMin, přejde do STATE_EDIT_BATT_WATT, menuEditValue se nastaví na temp_batteryMaxWatt.
Z STATE_EDIT_BATT_WATT: Uloží menuEditValue do temp_batteryMaxWatt, vrátí se do STATE_MENU_ROOT.
Po každé akci, která mění zobrazení menu, volá displayLcdMenu().
void loop()
Popis: Hlavní, neustále se opakující smyčka programu.
Funkčnost:
"Nakrmí" Task Watchdog Timer (esp_task_wdt_reset()) na začátku každé iterace, aby se předešlo restartu z důvodu zablokování.
Pokud není aktivní ukládání z webu (UkladamWeb == 0) a zařízení je autorizováno (ApiChybaOvereni == 1), zavolá handleLcdMenuInput() pro zpracování interakcí s LCD menu.
Pokud není aktivní ukládání z webu, zařízení je autorizováno a uplynul interval MAIN_PROCESSING_INTERVAL od posledního hlavního zpracování:
Aktualizuje čas posledního zpracování.
Komunikace a sběr dat:
Polluje MQTT klienta (wmqttClient.poll()) pro příjem a odeslání zpráv (pokud je MQTT povoleno).
Pokud je nakonfigurován serverName3 (adresa primárního zařízení), provede HTTP GET požadavek na /tssr tohoto zařízení, aby zjistil stav jeho SSR relé a uložil ho do TssrXX.
Přečte data z měřiče energie PZEM004T (napětí, proud, výkon, spotřebovaná energie, frekvence).
Aktualizuje měření z Dallas teplotních senzorů (aktualizujMereniTeplotDallas()) a z DHT senzoru (dht1.read...).
Zobrazení (pokud není aktivní LCD menu):
Zobrazí data z MQTT na LCD/OLED (MqttLCDdata()).
Zobrazí teploty z Dallas senzorů na LCD/OLED (TeplotaNaLCD()).
Regulace a řízení:
Vypočítá optimální hodnotu PWM (VypocetSolarSpotrebaRefactored()).
Nastaví vypočtené PWM na výstupní pin (OvladaniPwmSSR()).
Rozhodne o zapnutí/vypnutí SSR relé na základě teplot a dostupnosti energie (ZapninamRelePodleTeploty()).
Externí logování:
Odešle data na externí servery (EasunEnergy() a další POST na serverName).
Watchdog a údržba:
Kontroluje stav MQTT připojení (watchdog čítač). Pokud watchdog překročí watchdogX, pokusí se znovu připojit. Pokud i to selže, restartuje ESP32.
Připraví datové řetězce SkladamData a SkladamData2 pro případné požadavky na /data a /data2.
Sestaví HTML kód hlavní stránky (SkladamHtml()), pokud je Wi-Fi připojena a je čas na aktualizaci.
Inkrementuje různé čítače (watchdog, watchdog2 pro cyklování LCD, counter, JakCastoPosilatData).
Pokud je aktivní LCD menu, použije krátkou prodlevu delay(50). Jinak použije delší prodlevu delay(MAIN_PROCESSING_INTERVAL) pro řízení frekvence hlavní smyčky.