Wiki

← Zpět na výpis

Příklad Python rules

import asyncio
import time

# --- KONFIGURACE ČASOVÁNÍ ---
# Interval kontroly stačí klidně 15-30 sekund, voda má velkou setrvačnost.
CHECK_INTERVAL = 15.0 

# ----------------------------------------------------------------------
# HLAVNÍ LOOP - NABÍJENÍ BOJLERU
# ----------------------------------------------------------------------

running = True

while running:

    # 1. NAČTENÍ KONFIGURACE A CÍLŮ
    # -----------------------------
    # Povolení ohřevu (ON/OFF)
    POVOLENI_OHREVU = items_cache.get('ohrev_voda', 'OFF')
    
    # Nastavená cílová teplota vody v bojleru
    CILOVA_TEPLOTA = float(items_cache.get('nast_tepl_tuv', 55.0))
    
    # Hystereze pro zapnutí (např. 2.0°C -> zapne při 53°C, vypne při 55°C)
    HYSTEREZE = float(items_cache.get('nast_hystereze_voda', 2.0))
    
    # Minimální rozdíl teplot (Kotel musí být o X stupňů teplejší než bojler)
    MIN_ROZDIL_TEPLOT = float(items_cache.get('nast_min_rozd_voda', 5.0))

    # NOVÉ: Minimální teplota kotle pro povolení ohřevu
    # (Pokud kotel nemá ani tolik, čerpadlo nespustíme)
    MIN_TEPLOTA_KOTLE = float(items_cache.get('nast_minimal_tepl', 60.0))


    # 2. NAČTENÍ SENZORŮ
    # ------------------
    # Teplota v bojleru
    TEPLOTA_BOJLER = float(items_cache.get('bojler', 0.0))
    
    # Teplota zdroje (Kotel výstup - použijeme stejný item jako v topení)
    TEPLOTA_KOTEL = float(items_cache.get('kotel_vystup', 0.0))
    
    # Aktuální stav čerpadla
    CERPADLO_STAV = items_cache.get('ceradlo_tuv', 'OFF')


    # 3. ROZHODOVACÍ LOGIKA
    # ---------------------
    
    # Výchozí akce - Čerpadlo má být vypnuté, pokud se nerozhodne jinak
    nova_akce = 'OFF'
    duvod = ''

    # A) ZÁKLADNÍ PODMÍNKA: Je ohřev povolen?
    if POVOLENI_OHREVU == 'ON':
        
        # B) BEZPEČNOSTNÍ PODMÍNKY (ZDROJ TEPLA):
        # 1. Má kotel dostatečnou teplotu oproti bojleru? (Diference)
        je_kotel_teplejsi = TEPLOTA_KOTEL > (TEPLOTA_BOJLER + MIN_ROZDIL_TEPLOT)
        
        # 2. Má kotel absolutní minimální teplotu? (NOVÉ)
        ma_kotel_min_teplotu = TEPLOTA_KOTEL >= MIN_TEPLOTA_KOTLE
        
        # Obě podmínky musí platit, abychom vůbec uvažovali o zapnutí
        if je_kotel_teplejsi and ma_kotel_min_teplotu:
            
            # C) TERMOSTATICKÁ LOGIKA (Hystereze)
            # -----------------------------------
            
            # Pokud čerpadlo BĚŽÍ -> Vypínáme až při dosažení cílové teploty
            if CERPADLO_STAV == 'ON':
                if TEPLOTA_BOJLER >= CILOVA_TEPLOTA:
                    nova_akce = 'OFF'
                    duvod = f"Nahřáto ({TEPLOTA_BOJLER}°C >= {CILOVA_TEPLOTA}°C)"
                else:
                    nova_akce = 'ON' # Stále topíme
            
            # Pokud čerpadlo STOJÍ -> Zapínáme až po poklesu o hysterezi
            else: # CERPADLO_STAV == 'OFF'
                prah_zapnuti = CILOVA_TEPLOTA - HYSTEREZE
                
                if TEPLOTA_BOJLER < prah_zapnuti:
                    nova_akce = 'ON'
                    duvod = f"Start ohřevu (Bojler {TEPLOTA_BOJLER}°C < {prah_zapnuti}°C)"
                else:
                    nova_akce = 'OFF' # Ještě není dost zima
                    
        else:
            # OCHRANA AKTIVNÍ: Zdroj tepla není připraven
            nova_akce = 'OFF'
            
            # Logujeme důvod jen pokud čerpadlo běželo a my ho musíme vypnout
            if CERPADLO_STAV == 'ON':
                if not ma_kotel_min_teplotu:
                    duvod = f"STOP: Kotel pod minimem ({TEPLOTA_KOTEL}°C < {MIN_TEPLOTA_KOTLE}°C)"
                else:
                    duvod = f"STOP: Malý spád (Kotel {TEPLOTA_KOTEL}°C vs Bojler {TEPLOTA_BOJLER}°C)"
            
    else:
        # Ohřev zakázán uživatelem
        nova_akce = 'OFF'
        if CERPADLO_STAV == 'ON':
            duvod = "STOP: Ohřev zakázán (OFF)"


    # 4. PROVEDENÍ AKCE (ZÁPIS DO DB)
    # -------------------------------
    if nova_akce != CERPADLO_STAV:
        log_msg = f"BOJLER: Změna na {nova_akce} - {duvod}"
        await db.set_item_state('ceradlo_tuv', nova_akce, log_msg)
        await asyncio.sleep(2.0)


    # 5. KONTROLA UKONČENÍ
    # --------------------
    if POVOLENI_OHREVU == 'OFF':
        running = False

    # 6. ČEKÁNÍ NA DALŠÍ CYKLUS
    if running:
        await asyncio.sleep(CHECK_INTERVAL)