This commit is contained in:
Mateusz Gruszczyński committed 2026-10-17 20:00:28 +02:00
1 parent ccf85a2fb8
commit f376f0a7b6
32 files changed
+312 -114

No files matched your search

+19 -2
View File
@@ -31,7 +31,14 @@ fn flow_zone_action_already_satisfied(
device_swing_horizontal: u8,
preset: Option<&str>,
action: &DeviceCommand,
heat_anticipation_c: Option<f64>,
standby_offset_c: Option<f64>,
) -> bool {
if heat_anticipation_c.is_some_and(|value| (zone.heat_anticipation_c - value).abs() > 0.001)
|| standby_offset_c.is_some_and(|value| (zone.standby_offset_c - value).abs() > 0.001)
{
return false;
}
let mode_satisfied = match action.mode.as_deref() {
Some("auto") => zone.inherit_house_mode,
Some(mode) if matches!(mode, "heat" | "cool") => {
@@ -193,6 +200,8 @@ async fn run_automations(state: &AppState) -> Result<()> {
device.swing_horizontal,
item.action_zone_preset.as_deref(),
&effective_action,
item.action_zone_heat_anticipation_c,
item.action_zone_standby_offset_c,
) {
let before_runtime = item.flow_runtime.clone();
flow_acknowledge_change_gates(&mut item);
@@ -277,7 +286,10 @@ async fn run_automations(state: &AppState) -> Result<()> {
Err(err) => Err(AppError::BadRequest(format!("Home Assistant service action failed: {err}"))),
}
} else if let Some(zone_id) = item.action_zone_id.as_deref() {
apply_flow_zone_action(state, zone_id, item.action_zone_preset.as_deref(), &effective_action).await
apply_flow_zone_action(
state, zone_id, item.action_zone_preset.as_deref(), &effective_action,
item.action_zone_heat_anticipation_c, item.action_zone_standby_offset_c,
).await
} else if let Some(group_id) = item.action_group_id.as_deref() {
let group_mode = effective_action.mode.as_deref().map(|mode| if mode == "auto" { "house".to_string() } else { mode.to_string() });
control_group(state, group_id, GroupControlPatch {
@@ -1105,7 +1117,10 @@ fn flow_condition_kind_runtime(kind: &str) -> bool {
)
}
async fn apply_flow_zone_action(state: &AppState, zone_id: &str, preset: Option<&str>, action: &DeviceCommand) -> Result<bool, AppError> {
async fn apply_flow_zone_action(
state: &AppState, zone_id: &str, preset: Option<&str>, action: &DeviceCommand,
heat_anticipation_c: Option<f64>, standby_offset_c: Option<f64>,
) -> Result<bool, AppError> {
let _schedule_guard = state.lock_schedule_operation().await;
// Match the canonical thermostat ordering used by Web/HA zone control. This prevents
// a Flow action from racing a thermostat arbitration cycle that already holds a stale snapshot.
@@ -1117,6 +1132,8 @@ async fn apply_flow_zone_action(state: &AppState, zone_id: &str, preset: Option<
// Flow power commands control only the assigned unit runtime; they never change zone.enabled.
if !zone.enabled { return Ok(false); }
let device_id = zone.device_id.clone();
if let Some(value) = heat_anticipation_c { zone.heat_anticipation_c = value; }
if let Some(value) = standby_offset_c { zone.standby_offset_c = value; }
if let Some(mode) = action.mode.as_deref() {
match mode { "auto" => zone.inherit_house_mode = true, "heat" | "cool" => { zone.mode = mode.to_string(); zone.inherit_house_mode = false; }, _ => return Err(AppError::BadRequest("unsupported Flow thermostat mode".into())) }
}