v0.16.3
This commit is contained in:
1 parent
f376f0a7b6
commit
8059e16d12
36 files changed
+1140
-193
No files matched your search
@@ -33,7 +33,12 @@ fn flow_zone_action_already_satisfied(
|
||||
action: &DeviceCommand,
|
||||
heat_anticipation_c: Option<f64>,
|
||||
standby_offset_c: Option<f64>,
|
||||
simple_heat: Option<&SimpleHeatSettings>,
|
||||
) -> bool {
|
||||
if let Some(profile) = simple_heat {
|
||||
return zone.simple_heat.as_ref() == Some(profile)
|
||||
&& zone.control_source == "automation.flow";
|
||||
}
|
||||
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)
|
||||
{
|
||||
@@ -202,6 +207,7 @@ async fn run_automations(state: &AppState) -> Result<()> {
|
||||
&effective_action,
|
||||
item.action_zone_heat_anticipation_c,
|
||||
item.action_zone_standby_offset_c,
|
||||
item.action_zone_simple_heat.as_ref(),
|
||||
) {
|
||||
let before_runtime = item.flow_runtime.clone();
|
||||
flow_acknowledge_change_gates(&mut item);
|
||||
@@ -289,6 +295,7 @@ async fn run_automations(state: &AppState) -> Result<()> {
|
||||
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,
|
||||
item.action_zone_simple_heat.as_ref(),
|
||||
).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() });
|
||||
@@ -1120,6 +1127,7 @@ fn flow_condition_kind_runtime(kind: &str) -> bool {
|
||||
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>,
|
||||
simple_heat: Option<&SimpleHeatSettings>,
|
||||
) -> Result<bool, AppError> {
|
||||
let _schedule_guard = state.lock_schedule_operation().await;
|
||||
// Match the canonical thermostat ordering used by Web/HA zone control. This prevents
|
||||
@@ -1131,13 +1139,29 @@ async fn apply_flow_zone_action(
|
||||
// A disabled Zone is an administrative gate for every Flow thermostat action.
|
||||
// Flow power commands control only the assigned unit runtime; they never change zone.enabled.
|
||||
if !zone.enabled { return Ok(false); }
|
||||
// Explicit manual target wins until Auto is selected again. A previous Flow v4
|
||||
// may have left a custom preset behind: that is *automation*, not manual,
|
||||
// and must be replaceable by the simplified Flow without user intervention.
|
||||
if simple_heat.is_some() && zone.control_source != "automation.flow"
|
||||
&& (zone.manual_preset.is_some() || zone.manual_setpoint.is_some()) {
|
||||
return Ok(false);
|
||||
}
|
||||
let device_id = zone.device_id.clone();
|
||||
if let Some(profile) = simple_heat {
|
||||
if zone.simple_heat.as_ref() != Some(profile) {
|
||||
zone.simple_heat_runtime = SimpleHeatRuntime::default();
|
||||
}
|
||||
zone.simple_heat = Some(profile.clone());
|
||||
} else {
|
||||
zone.simple_heat = None;
|
||||
zone.simple_heat_runtime = SimpleHeatRuntime::default();
|
||||
}
|
||||
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())) }
|
||||
}
|
||||
match preset.unwrap_or("auto") {
|
||||
match if simple_heat.is_some() { "auto" } else { preset.unwrap_or("auto") } {
|
||||
"auto" => { zone.manual_preset = None; zone.manual_setpoint = None; zone.manual_override_until = None; }
|
||||
"custom" => {
|
||||
let target = action.target_temperature.ok_or_else(|| AppError::BadRequest("Flow custom thermostat action has no target".into()))?;
|
||||
@@ -1163,7 +1187,17 @@ async fn apply_flow_zone_action(
|
||||
zone.control_source = "automation.flow".into();
|
||||
zone.control_reason = "Visual Flow automation".into();
|
||||
let schedules = state.db.list_schedules()?;
|
||||
let house_mode = state.settings.read().await.house_mode.clone();
|
||||
let runtime_settings = state.settings.read().await;
|
||||
let house_mode = runtime_settings.house_mode.clone();
|
||||
if simple_heat.is_some() {
|
||||
// Show the correct bedroom/child-room night target immediately after
|
||||
// Flow activation, not the old Comfort preset until the next zone tick.
|
||||
zone.simple_heat_runtime.night = Some(night_mode_active(
|
||||
&runtime_settings.night_mode,
|
||||
Local::now().time(),
|
||||
));
|
||||
}
|
||||
drop(runtime_settings);
|
||||
refresh_control_ownership(&mut zone);
|
||||
if zone.control_owner == "automation" {
|
||||
zone.control_source = "automation.flow".into();
|
||||
|
||||
Reference in new issue
Block a user