Základní popis programu EaSun 2025-06-01

Právě se nacházíte: Home / vyvoj / 

Funkce programu ESP32-Grid-Load-Vypocet22.ino podrobněji:

  • String getEncryptionTypeString(wifi_auth_mode_t encryptionType)

    • Popis: Tato funkce přijímá jako vstup typ šifrování Wi-Fi sítě (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)

    • Popis: Funkce pro čtení obsahu souboru z flash paměti ESP32 pomocí systému souborů SPIFFS.
    • Parametry:
      • 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").
    • Funkčnost: Otevře soubor v režimu čtení ("r"). Pokud soubor neexistuje, je adresářem, nebo je prázdný, vrátí textový řetězec "null". Jinak přečte celý obsah souboru a vrátí jej jako String.
  • void write_file(fs::FS &fs, const char * path, const char * message)

    • Popis: Funkce pro zápis textového obsahu do souboru v systému souborů SPIFFS.
    • Parametry:
      • 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.
    • Funkčnost: Otevře (nebo vytvoří) soubor v režimu zápisu ("w"). Pokud se otevření nepodaří, vypíše chybovou hlášku. Zapíše 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)

    • Popis: Podobná funkci write_file, ale s minimálním výpisem na sériovou linku (pouze název souboru, pokud je WebSerialAno == 2).
    • Funkčnost: Primárně slouží k vytvoření prázdného souboru nebo k zápisu bez detailního logování obsahu. Používá se například pro vytvoření souboru /EaTest.ea signalizujícího restart.
  • String processor(const String& var)

    • Popis: Klíčová funkce pro dynamické generování webových stránek pomocí ESPAsyncWebServer. Funguje jako "template processor".
    • Parametry:
      • const String& var: Název zástupného symbolu (placeholderu) z HTML šablony (např. "EasunData", "temp1").
    • Funkčnost: Když webový server zpracovává HTML stránku a narazí na placeholder ve formátu %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)

    • Popis: Standardní obslužná funkce (handler) pro ESPAsyncWebServer.
    • Parametry:
      • AsyncWebServerRequest *request: Ukazatel na objekt reprezentující HTTP požadavek.
    • Funkčnost: Zavolá se, pokud klient požaduje URL, pro kterou není definován žádný jiný handler. Odešle klientovi odpověď s HTTP stavovým kódem 404 (Not Found) a jednoduchou textovou zprávou "Not found".
  • void buildTeplotaPageAndSettings()

    • Popis: Komplexní funkce, která načítá všechna nastavení týkající se teplotních čidel a regulace z paměti SPIFFS a zároveň sestavuje HTML kód pro webovou stránku /teplota, kde může uživatel tato nastavení měnit.
    • Funkčnost:
      • Načte hodnoty z mnoha souborů v SPIFFS, např.:
        • Názvy teplotních čidel (/NazevTeplotaX.ea).
        • Minimální a maximální teploty pro každé čidlo (/VstupniTeplotaXa.ea/VstupniTeplotaX.ea).
        • Nastavení použití distributora pro každé čidlo (/DistrX.ea).
        • Režim spolupráce teplotních čidel (společně/samostatně - /VstupniTeplota4.ea).
        • Maximální PWM při odběru od distributora (/VstupniTeplota5.ea).
        • Logiku zapínání SSR při solární výrobě (pod Min/Max - /VstupniTeplota6.ea).
        • Minimální a maximální odběr od distributora pro regulaci (/distrmin.ea/distrmax.ea).
        • Minimální/maximální procento PWM a minimální výkon soláru pro aktivaci (/solarWMin1.ea/solarWMax1.ea/solarWMin2.ea).
        • Nastavení OLED displeje a barvy webového rozhraní (/oled.ea/htmlcolor.ea).
        • Limity pro baterii (/baterie1.ea - Min SOC, /baterie2.ea - Max Watt).
      • Aktualizuje odpovídající globální proměnné v programu těmito načtenými hodnotami.
      • Dynamicky generuje HTML kód pro stránku /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()

    • Popis: Zobrazuje informační hlášky na LCD a OLED displejích a řídí restart nebo znovunačtení konfigurace.
    • Funkčnost: Chování závisí na globální proměnné 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 (batterySOCMinbatteryMaxWatt) a barvu webu (barvicka) z SPIFFS. Resetuje příznak UkladamWeb.
  • void action(AsyncWebServerRequest *request)

    • Popis: Obslužná funkce pro HTTP POST požadavky, typicky odeslané z formulářů na stránce /reset.
    • Parametry:
      • AsyncWebServerRequest *request: Ukazatel na objekt HTTP požadavku.
    • Funkčnost: Zpracovává parametry odeslané metodou POST:
      • Pokud je přítomen parametr KWh s hodnotou "kWh", resetuje čítač spotřebované energie na modulu PZEM004T (pzem.resetEnergy()).
      • Pokud je přítomen parametr 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.
      • Po provedení akce odešle klientovi HTML stránku s potvrzením.
  • void setupSoftAPForFallback()

    • Popis: Funkce pro nouzový režim, pokud se ESP32 nemůže připojit k nakonfigurované Wi-Fi síti.
    • Funkčnost:
      • Odpojí ESP32 od jakékoli předchozí Wi-Fi sítě a vymaže konfiguraci klienta (STA).
      • Přepne ESP32 do režimu Access Point (AP) s pevně daným SSID "EASUN" a bez hesla.
      • Získá a zobrazí IP adresu AP.
      • Provede skenování okolních Wi-Fi sítí.
      • Dynamicky sestaví HTML stránku (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.