This commit is contained in:
Mateusz Gruszczyński
2026-08-27 17:17:05 +02:00
parent 65eaf50fb6
commit 62514258d3
16 changed files with 205 additions and 43 deletions
+15 -9
View File
@@ -529,7 +529,7 @@ impl ZoneInput {
sensor_source: self.sensor_source, ha_entity_id: self.ha_entity_id.filter(|v| !v.trim().is_empty()),
external_sensor_weight: self.external_sensor_weight, max_sensor_difference: self.max_sensor_difference,
device_temperature: None, external_temperature: None, current_temperature: None, control_temperature_source: "device".into(),
active_preset: "comfort".into(), manual_preset: None, manual_setpoint: None, manual_override_until: None, local_thermostat_power: None,
active_preset: "comfort".into(), manual_preset: None, manual_setpoint: None, manual_override_until: None, local_thermostat_power: None, local_thermostat_resume_at: None,
device_manual_override: false, device_manual_override_since: None, device_manual_override_until: None, device_manual_override_fields: Vec::new(), device_manual_override_baseline: None,
effective_mode: String::new(), effective_setpoint: None, device_setpoint: None,
demand: false, demand_since: None, target_alerted_at: None, last_action_at: None,
@@ -577,6 +577,7 @@ async fn update_zone(State(state): State<AppState>, Path(id): Path<String>, Json
zone.manual_setpoint = existing.manual_setpoint;
zone.manual_override_until = existing.manual_override_until;
zone.local_thermostat_power = existing.local_thermostat_power;
zone.local_thermostat_resume_at = existing.local_thermostat_resume_at;
zone.device_manual_override = existing.device_manual_override;
zone.device_manual_override_since = existing.device_manual_override_since;
zone.device_manual_override_until = existing.device_manual_override_until;
@@ -618,16 +619,19 @@ async fn apply_zone_control_patch(state: &AppState, id: &str, patch: ZoneControl
|| patch.preset.is_some() || patch.enabled.is_some();
if resume_local_thermostat {
zone.local_thermostat_power = None;
zone.manual_preset = None;
zone.manual_setpoint = None;
zone.manual_override_until = None;
engine::reset_local_thermostat_override(&mut zone);
}
if let Some(power) = patch.power {
zone.local_thermostat_power = Some(power);
zone.local_thermostat_resume_at = if power {
None
} else {
Some(Utc::now() + chrono::Duration::minutes(engine::LOCAL_THERMOSTAT_RESUME_DELAY_MINUTES))
};
if power { zone.enabled = true; }
// A manually started local thermostat keeps an already selected target/profile until
// the user chooses Auto or resumes global automation.
// it is switched off and the delayed hand-back completes, Auto is selected, or the
// user explicitly resumes automation.
if power && (zone.manual_preset.is_some() || zone.manual_setpoint.is_some()) {
zone.manual_override_until = None;
}
@@ -680,7 +684,7 @@ async fn apply_zone_control_patch(state: &AppState, id: &str, patch: ZoneControl
}
if let Some(value) = patch.enabled {
zone.enabled = value;
if !value { zone.local_thermostat_power = None; }
if !value { engine::reset_local_thermostat_override(&mut zone); }
}
let device_override_cleared = if resume_device_automation { engine::reset_device_manual_override(&mut zone) } else { false };
let house_mode = state.settings.read().await.house_mode.clone();
@@ -709,6 +713,7 @@ async fn apply_zone_control_patch(state: &AppState, id: &str, patch: ZoneControl
"inherit_house_mode": zone.inherit_house_mode, "preset": zone.manual_preset,
"override_until": zone.manual_override_until, "enabled": zone.enabled,
"local_thermostat_power": zone.local_thermostat_power,
"local_thermostat_resume_at": zone.local_thermostat_resume_at,
"device_manual_override_cleared": device_override_cleared
}));
Ok(zone)
@@ -955,6 +960,7 @@ async fn list_home_assistant_groups(State(state): State<AppState>) -> Result<Jso
"control_source": zone.control_source,
"current_schedule": zone.current_schedule_name,
"local_thermostat_power": zone.local_thermostat_power,
"local_thermostat_resume_at": zone.local_thermostat_resume_at,
"device_manual_override": zone.device_manual_override,
"device_manual_override_until": zone.device_manual_override_until,
})).collect::<Vec<_>>();
@@ -1009,8 +1015,8 @@ fn set_all_groups_power(state: &AppState, power: bool) -> Result<(), AppError> {
fn clear_all_local_thermostat_overrides(state: &AppState) -> Result<usize, AppError> {
let mut cleared = 0;
for mut zone in state.db.list_zones()? {
if zone.local_thermostat_power.is_none() { continue; }
zone.local_thermostat_power = None;
if zone.local_thermostat_power.is_none() && zone.local_thermostat_resume_at.is_none() { continue; }
engine::reset_local_thermostat_override(&mut zone);
zone.updated_at = Utc::now();
state.db.save_zone(&zone)?;
state.broadcast("zone.updated", serde_json::to_value(&zone)?);