# Climate regulator

Process scheduler
Climate regulator
AT
OT
PRE
DWC
COM
PRO
TT
TD

# 入力

ID略称名前デフォルト説明
air_tempATair_tempNUMBER0
outside_tempOToutside_tempNUMBER-1000
presencePREpresenceBOOLEANfalse
dwcDWCdwcBOOLEANfalse
comfortCOMcomfortBOOLEANfalse
protectionPROprotectionBOOLEANfalse

# 出力

ID略称名前デフォルト説明
target_tempTTtarget_tempNUMBER0
temp_deviationTDtemp_deviationNUMBER0

# 設定

ID名前デフォルト単位説明
thermal_modethermal_modeENUM0

詳細:

値: Heating and cooling, Heating only, Cooling only
operation_modeoperation_modeENUM0

詳細:

値: Schedule, Manual
schedulescheduleSCHEDULE0

詳細:

サブタイプ: CLIMATE
表示条件operation_mode = Schedule
comfort_heating_tempcomfort_heating_tempNUMBER21°C

詳細:

表示条件thermal_mode = Heating and cooling, Heating only
comfort_cooling_temp
comfort_cooling_tempcomfort_cooling_tempNUMBER25°C

詳細:

表示条件thermal_mode = Heating and cooling, Cooling only
comfort_heating_temp
eco_heating_temp_diffeco_heating_temp_diffNUMBER2°C

詳細:

表示条件thermal_mode = Heating and cooling, Heating only
≥ 0
eco_cooling_temp_diffeco_cooling_temp_diffNUMBER3°C

詳細:

表示条件thermal_mode = Heating and cooling, Cooling only
≥ 0
frost_protection_tempfrost_protection_tempNUMBER10°C

詳細:

表示条件thermal_mode = Heating and cooling, Heating only
≥ 5
< comfort_heating_temp
overheat_protection_tempoverheat_protection_tempNUMBER40°C

詳細:

表示条件thermal_mode = Heating and cooling, Cooling only
comfort_cooling_temp
dwc_delaydwc_delayNUMBER30s

詳細:

> 0
presence_extension_durationpresence_extension_durationNUMBER1800s

詳細:

表示条件operation_mode = Schedule
≥ 0

# 状態

ID名前デフォルト単位説明
dwc_state_change_tsdwc_state_change_tsNUMBER0
dwc_statedwc_stateBOOLEANfalse
dwc_lockdwc_lockBOOLEANfalse
last_activation_tslast_activation_tsNUMBER0s
next_activation_tsnext_activation_tsNUMBER0s

# ソースコード

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()

# 空調スケジュール

Climate Regulator は Climate タイプのスケジュールを使用し、24時間の日次サイクルで温度セットポイントを定義します。各スケジュールエントリには目標温度の数値が含まれ、レギュレータは計測値と比較して暖房または冷房出力を駆動します。

平日、週末、外出、パーティーなど、状況ごとに異なる温度プロファイルは、曜日をハードコードするのではなく、スケジュールと Operation Modes を組み合わせることで実現します。

Climate スケジュールをビジュアルエディタで設定する方法の詳細は Voldeno Studio — スケジュール を参照してください。

Voldeno スマートホーム自動化における Climate regulator Logic Block の動作、用途、設定方法を説明します。