# Climate regulator

Przetwarzanie scheduler

Strefowy regulator klimatu - może być używany jako termostat dla ogrzewania lub chłodzenia określonej strefy. Wyjście powinno być podłączone do centralnego regulatora klimatu.

Climate regulator
AT
OT
PRE
DWC
COM
PRO
TT
TD

# Wejścia

IDSkrótNazwaTypDomyślnieOpis
air_tempATTemperatura powietrzaNUMBER0Bieżąca temperatura powietrza
outside_tempOTTemperatura zewnętrznaNUMBER-1000Bieżąca temperatura zewnętrzna
presencePREObecnośćBOOLEANfalseWydłuża okres temperatury komfortowej gdy wysoki. Przełącza z trybu eko na komfort.
dwcDWCKontakt drzwi/oknaBOOLEANfalseJeśli aktywny dłużej niż skonfigurowany czas: wyłącza ogrzewanie/chłodzenie przy otwartych drzwiach lub oknie
comfortCOMTryb komfortowyBOOLEANfalseAktywuje tryb temperatury komfortowej do następnej zmiany okresu harmonogramu
protectionPROTryb ochronnyBOOLEANfalseAktywuje tryb temperatury ochronnej aby chronić budynek przed mrozem lub przegrzaniem

# Wyjścia

IDSkrótNazwaTypDomyślnieOpis
target_tempTTTemperatura docelowaNUMBER0Wyjściowa temperatura docelowa
temp_deviationTDOdchylenie temperaturyNUMBER0Wyjście wyrażające zapotrzebowanie na ogrzewanie lub chłodzenie jako różnicę temperatur. Dodatnie dla ogrzewania. Ujemne dla chłodzenia.

# Konfiguracja

IDNazwaTypDomyślnieJednostkaOpis
thermal_modeTryb termicznyENUM0Określa tryb termiczny: Ogrzewanie i chłodzenie, Tylko ogrzewanie, Tylko chłodzenie

Szczegóły:

Wartości: Heating and cooling, Heating only, Cooling only
operation_modeTryb pracyENUM0Określa tryb pracy: Harmonogram, Ręczny

Szczegóły:

Wartości: Schedule, Manual
scheduleHarmonogramSCHEDULE0Harmonogram do użycia dla trybu pracy opartego na harmonogramie

Szczegóły:

Podtyp: CLIMATE
Widoczne gdyoperation_mode = Schedule
comfort_heating_tempTemperatura ogrzewania komfortowegoNUMBER21°CTemperatura ogrzewania komfortowego

Szczegóły:

Widoczne gdythermal_mode = Heating and cooling, Heating only
comfort_cooling_temp
comfort_cooling_tempTemperatura chłodzenia komfortowegoNUMBER25°CTemperatura chłodzenia komfortowego

Szczegóły:

Widoczne gdythermal_mode = Heating and cooling, Cooling only
comfort_heating_temp
eco_heating_temp_diffRóżnica temp. ogrzewania ekoNUMBER2°CRóżnica temperatury ogrzewania eko poniżej temperatury komfortowej

Szczegóły:

Widoczne gdythermal_mode = Heating and cooling, Heating only
≥ 0
eco_cooling_temp_diffRóżnica temp. chłodzenia ekoNUMBER3°CRóżnica temperatury chłodzenia eko powyżej temperatury komfortowej

Szczegóły:

Widoczne gdythermal_mode = Heating and cooling, Cooling only
≥ 0
frost_protection_tempTemperatura ochrony przed mrozemNUMBER10°CTemperatura ochrony przed mrozem. Poniżej tej wartości aktywowane jest ogrzewanie.

Szczegóły:

Widoczne gdythermal_mode = Heating and cooling, Heating only
≥ 5
< comfort_heating_temp
overheat_protection_tempTemperatura ochrony przed przegrzaniemNUMBER40°CTemperatura ochrony przed przegrzaniem. Powyżej tej wartości aktywowane jest chłodzenie.

Szczegóły:

Widoczne gdythermal_mode = Heating and cooling, Cooling only
comfort_cooling_temp
dwc_delayOpóźnienie kontaktu drzwi/oknaNUMBER30sOpóźnienie kontaktu drzwi/okna w sekundach

Szczegóły:

> 0
presence_extension_durationCzas przedłużenia obecnościNUMBER1800sCzas przedłużenia temperatury komfortowej (w sekundach) przy wykryciu obecności

Szczegóły:

Widoczne gdyoperation_mode = Schedule
≥ 0

# Stan

IDNazwaTypDomyślnieJednostkaOpis
dwc_state_change_tsZnacznik czasu ostatniej zmiany stanu kontaktuNUMBER0
dwc_stateBieżący stan kontaktu drzwi/oknaBOOLEANfalseUżywany aby zapobiec przedłużeniu czasu kontaktu przy ponownym wysłaniu tego samego wejścia
dwc_lockStan blokady kontaktu drzwi/oknaBOOLEANfalseStan blokady kontaktu drzwi/okna
last_activation_tsOstatni znacznik czasu wykonaniaNUMBER0sOstatni znacznik czasu wykonania w sekundach od epoki
next_activation_tsNastępny znacznik czasu wykonaniaNUMBER0sNastępny znacznik czasu wykonania w sekundach od epoki

# Kod źródłowy

Pokaż kod Volang

extern fn std::next_activation_at() {
    operation_mode = config::get("operation_mode") 
    if (operation_mode == 0) { // schedule
        schedule_id = config::get("schedule")
        return schedule::get_next_activation_ts(schedule_id)
    }
    return 0
}

extern fn process() {
    channel = input::channel()
    value = input::value()
    now = time::uptime()

    // inputs
    air_temp = input::get("air_temp")
    floor_temp = input::get("floor_temp")
    outside_temp = input::get("outside_temp")
    presence = input::get("presence")
    dwc = input::get("dwc")
    comfort_forced = input::get("comfort")
    protection_forced = input::get("protection")

    // configs
    thermal_mode = config::get("thermal_mode") // 0=heating and cooling, 1=heating only, 2=cooling only
    operation_mode = config::get("operation_mode") // 0=schedule, 1=manual
    comfort_heating_temp = config::get("comfort_heating_temp")
    comfort_cooling_temp = config::get("comfort_cooling_temp")
    eco_heating_temp_diff = config::get("eco_heating_temp_diff")
    eco_cooling_temp_diff = config::get("eco_cooling_temp_diff")
    frost_protection_temp = config::get("frost_protection_temp")
    overheat_protection_temp = config::get("overheat_protection_temp")
    dwc_delay_sec = config::get("dwc_delay")
    presence_extension_duration = config::get("presence_extension_duration")


    last_dwc_state = state::get("dwc_state")
    if (channel == "dwc") {
        // on DWC switch
        if ((value and !last_dwc_state) or (!value and last_dwc_state)) {
            callback::clear()
            callback::set(dwc_delay_sec * 1000 + 5, "process")
            state::set("dwc_state_change_ts", now)
            state::set("dwc_state", value)
        }
    }
    last_dwc_ts = state::get("dwc_state_change_ts")
    dwc_duration_sec = (now - last_dwc_ts) / 1000.0

    fn round2decimal(temp_deviation) {
        return math::round(100.0 * temp_deviation) / 100.0
    }

    // define:
    // - comfort mode: 0=eco, 1=comfort, 2=protection
    // - target temperatures for heating and cooling
    comfort_mode = 0
    target_heating_temp = 0
    target_cooling_temp = 0

    if (operation_mode == 0) { // schedule
        schedule_id = config::get("schedule")
        comfort_mode = schedule::get_entry_type(schedule_id)
    }

    if (comfort_mode == 1 or comfort_forced) { // comfort
        target_heating_temp = comfort_heating_temp
        target_cooling_temp = comfort_cooling_temp
    } else if (comfort_mode == 2 or protection_forced) { // protection
        target_heating_temp = frost_protection_temp
        target_cooling_temp = overheat_protection_temp
    } else { // no entry - default: eco
        target_heating_temp = comfort_heating_temp - eco_heating_temp_diff
        target_cooling_temp = comfort_cooling_temp + eco_cooling_temp_diff
    }

    // define:
    // - chosen thermal mode: 0=idle, 1=heating, 2=cooling
    // - temperature deviation
    chosen_thermal_mode = 0 // idle
    target_temp = air_temp
    temp_deviation = 0.0
    outside_temp_helps = false
    outside_temp_sensor = outside_temp != -1000
    if (air_temp < target_heating_temp and (thermal_mode == 0 or thermal_mode == 1)) {
        chosen_thermal_mode = 1 // heating
        target_temp = target_heating_temp
        temp_deviation = target_temp - air_temp // positive
        outside_temp_helps = outside_temp_sensor and (outside_temp > target_heating_temp)
    }
    if (air_temp > target_cooling_temp and (thermal_mode == 0 or thermal_mode == 2)) {
        chosen_thermal_mode = 2 // cooling
        target_temp = target_cooling_temp
        temp_deviation = target_temp - air_temp // negative
        outside_temp_helps = outside_temp_sensor and (outside_temp < target_cooling_temp)
    }

    if (!outside_temp_helps and (dwc and dwc_duration_sec > dwc_delay_sec)) {
        state::set("dwc_lock", true)
    }
    if (state::get("dwc_lock") and !dwc and dwc_duration_sec > dwc_delay_sec) {
        state::set("dwc_lock", false)
    }
    dwc_lock_active = state::get("dwc_lock")

    protective_action_required = air_temp < frost_protection_temp or air_temp > overheat_protection_temp
    if (dwc_lock_active and !protective_action_required) {
        output::set("temp_deviation", round2decimal(0.0))
        output::set("target_temp", round2decimal(target_temp))
        return
    }

    output::set("temp_deviation", round2decimal(temp_deviation))
    output::set("target_temp", round2decimal(target_temp))

}

process()

# Harmonogramy klimatyczne

Regulator klimatu wykorzystuje harmonogram typu Klimat do definiowania nastaw temperaturowych w 24-godzinnym cyklu dziennym. Każdy wpis harmonogramu niesie docelową wartość temperatury; regulator porównuje ją z wartościami zmierzonymi, sterując wyjściami ogrzewania lub chłodzenia.

Różne profile temperaturowe dla dni roboczych, weekendów czy sytuacji niestandardowych (nieobecność, impreza itp.) uzyskuje się łącząc harmonogram z Trybami pracy, zamiast na sztywno kodować dni tygodnia.

Szczegóły konfiguracji harmonogramów klimatycznych w edytorze wizualnym znajdziesz w Voldeno Studio – Harmonogramy.

Strefowy regulator klimatu - może być używany jako termostat dla ogrzewania lub chłodzenia określonej strefy. Wyjście powinno być podłączone do centralnego regulatora klimatu.