This commit is contained in:
Mateusz Gruszczyński
2026-08-23 23:20:00 +02:00
parent 8bb12a1782
commit b23578a0c8
34 changed files with 2300 additions and 447 deletions
+76
View File
@@ -14,6 +14,18 @@ fn default_max_sensor_difference() -> f64 { 3.0 }
fn default_control_temperature_source() -> String { "device".into() }
fn default_min_cycle() -> u64 { 180 }
fn default_cooldown() -> u64 { 300 }
fn default_house_mode() -> String { "cool".into() }
fn default_control_strategy() -> String { "setpoint".into() }
fn default_standby_offset() -> f64 { 2.0 }
fn default_min_adjust() -> u64 { 120 }
fn default_schedule_preset() -> String { "custom".into() }
fn default_active_preset() -> String { "comfort".into() }
fn default_cool_comfort() -> f64 { 23.0 }
fn default_cool_sleep() -> f64 { 24.5 }
fn default_cool_away() -> f64 { 27.0 }
fn default_heat_comfort() -> f64 { 21.0 }
fn default_heat_sleep() -> f64 { 19.0 }
fn default_heat_away() -> f64 { 17.0 }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Device {
@@ -155,14 +167,42 @@ pub struct Zone {
pub enabled: bool,
#[serde(default = "default_mode")]
pub mode: String,
/// When true, the zone follows the global house heating/cooling mode.
#[serde(default = "default_true")]
pub inherit_house_mode: bool,
/// Manual/custom target retained for quick thermostat overrides.
#[serde(default = "default_target")]
pub setpoint: f64,
/// 0 means a zone created before smart profiles; its legacy setpoint remains the comfort target until edited.
#[serde(default)]
pub profile_version: u8,
#[serde(default = "default_cool_comfort")]
pub cool_comfort_setpoint: f64,
#[serde(default = "default_cool_sleep")]
pub cool_sleep_setpoint: f64,
#[serde(default = "default_cool_away")]
pub cool_away_setpoint: f64,
#[serde(default = "default_heat_comfort")]
pub heat_comfort_setpoint: f64,
#[serde(default = "default_heat_sleep")]
pub heat_sleep_setpoint: f64,
#[serde(default = "default_heat_away")]
pub heat_away_setpoint: f64,
#[serde(default = "default_hysteresis")]
pub hysteresis: f64,
#[serde(default = "default_min_cycle")]
pub min_on_seconds: u64,
#[serde(default = "default_min_cycle")]
pub min_off_seconds: u64,
/// Minimum interval between automatic setpoint/fan adjustments.
#[serde(default = "default_min_adjust")]
pub min_adjust_seconds: u64,
/// Difference applied to the AC setpoint while the room is satisfied.
#[serde(default = "default_standby_offset")]
pub standby_offset_c: f64,
/// Let the controller adjust fan speed based on demand and outdoor conditions.
#[serde(default = "default_true")]
pub smart_fan: bool,
#[serde(default = "default_sensor_source")]
pub sensor_source: String,
#[serde(default)]
@@ -185,6 +225,20 @@ pub struct Zone {
/// `device`, `external`, `combined`, `device_fallback`, or `device_discrepancy_fallback`.
#[serde(default = "default_control_temperature_source")]
pub control_temperature_source: String,
/// Effective profile currently used by the zone: comfort/sleep/away/custom.
#[serde(default = "default_active_preset")]
pub active_preset: String,
/// Optional user override. Cleared automatically at the next schedule boundary.
#[serde(default)]
pub manual_preset: Option<String>,
#[serde(default)]
pub manual_override_until: Option<DateTime<Utc>>,
#[serde(default)]
pub effective_mode: String,
#[serde(default)]
pub effective_setpoint: Option<f64>,
#[serde(default)]
pub device_setpoint: Option<f64>,
#[serde(default)]
pub demand: bool,
#[serde(default)]
@@ -204,6 +258,11 @@ pub struct ZoneControlPatch {
pub mode: Option<String>,
#[serde(default)]
pub enabled: Option<bool>,
/// `auto` clears the override; comfort/sleep/away/custom create a temporary override.
#[serde(default)]
pub preset: Option<String>,
#[serde(default)]
pub clear_override: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -219,6 +278,9 @@ pub struct Schedule {
pub start_time: String,
/// Local time HH:MM. Ranges crossing midnight are supported.
pub end_time: String,
/// comfort/sleep/away/custom. Non-custom profiles resolve their target from the zone.
#[serde(default = "default_schedule_preset")]
pub preset: String,
pub setpoint: f64,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
@@ -279,6 +341,12 @@ pub struct HomeAssistantSettings {
pub token: String,
#[serde(default)]
pub default_entity_id: String,
/// Optional outdoor temperature sensor used only as an assist signal.
#[serde(default)]
pub outdoor_entity_id: String,
/// Accept self-signed/expired certificates for local Home Assistant HTTPS.
#[serde(default)]
pub allow_invalid_tls: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -289,6 +357,14 @@ pub struct RuntimeSettings {
pub zone_interval_seconds: u64,
pub discovery_timeout_ms: u64,
pub discovery_broadcast: String,
/// Global seasonal mode. Zones follow this by default. Values: cool/heat/off.
#[serde(default = "default_house_mode")]
pub house_mode: String,
/// `setpoint` keeps units powered and modulates compressor demand by changing target temperature.
#[serde(default = "default_control_strategy")]
pub control_strategy: String,
#[serde(default = "default_true")]
pub outdoor_assist_enabled: bool,
pub home_assistant: HomeAssistantSettings,
}