v0.9.4-fix_ux
This commit is contained in:
+19
-7
@@ -71,6 +71,14 @@ pub async fn control_group(state: &AppState, group_id: &str, patch: GroupControl
|
||||
// "blocked by a disabled group". ON clears that scoped OFF and lets group arbitration
|
||||
// take ownership again. The whole-house master remains independent.
|
||||
let manual_group_control = source != "automation.group";
|
||||
// A manual Group OFF is a temporary bulk pause. All members receive the same
|
||||
// 15-minute hand-back deadline, so their thermostat automation resumes together.
|
||||
// Automation-driven group OFF remains persistent until another automation/user action.
|
||||
let group_handback_at = if manual_group_control && patch.power == Some(false) {
|
||||
Some(group.updated_at.clone() + chrono::Duration::minutes(LOCAL_THERMOSTAT_RESUME_DELAY_MINUTES))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let explicit_group_power = patch.power.is_some() && manual_group_control;
|
||||
// Applying a manual mode/profile/custom target to an already-enabled group is itself an
|
||||
// explicit scoped takeover. It must wake members that were left locally OFF by a previous
|
||||
@@ -160,10 +168,10 @@ pub async fn control_group(state: &AppState, group_id: &str, patch: GroupControl
|
||||
};
|
||||
}
|
||||
}
|
||||
// Power OFF is persisted as an ordinary per-zone thermostat OFF, with no automatic
|
||||
// 15-minute hand-back. This keeps the physical unit off while removing group ownership
|
||||
// and, importantly, still lets the user turn that thermostat back on independently.
|
||||
// Power ON clears this scoped OFF and returns the member to group arbitration.
|
||||
// Group power OFF is represented on every member as a local thermostat OFF so the
|
||||
// physical unit is stopped immediately and group ownership is released. A manual Group
|
||||
// OFF gets one synchronized 15-minute hand-back deadline for all members; automation
|
||||
// Group OFF is persistent. Power ON clears the scoped OFF immediately.
|
||||
let mut force_power_off_after_save = false;
|
||||
let mut applied_group_power: Option<bool> = None;
|
||||
let requested_member_power = patch.power.or(manual_group_activation.then_some(true));
|
||||
@@ -184,7 +192,7 @@ pub async fn control_group(state: &AppState, group_id: &str, patch: GroupControl
|
||||
applied_group_power = Some(true);
|
||||
} else {
|
||||
zone.local_thermostat_power = Some(false);
|
||||
zone.local_thermostat_resume_at = None;
|
||||
zone.local_thermostat_resume_at = group_handback_at.clone();
|
||||
zone.local_thermostat_restore_zone_enabled = None;
|
||||
zone.demand = false;
|
||||
zone.demand_since = None;
|
||||
@@ -200,8 +208,12 @@ pub async fn control_group(state: &AppState, group_id: &str, patch: GroupControl
|
||||
zone.control_owner = "local_thermostat".into();
|
||||
zone.control_source = "local_thermostat".into();
|
||||
zone.control_since = Some(Utc::now());
|
||||
zone.control_resume_at = None;
|
||||
zone.control_reason = format!("Group {} powered the thermostat off; group ownership released", group.name);
|
||||
zone.control_resume_at = group_handback_at.clone();
|
||||
zone.control_reason = if group_handback_at.is_some() {
|
||||
format!("Group {} powered the thermostat off; automation resumes after {} minutes", group.name, LOCAL_THERMOSTAT_RESUME_DELAY_MINUTES)
|
||||
} else {
|
||||
format!("Group {} powered the thermostat off; group ownership released", group.name)
|
||||
};
|
||||
} else if group.power_enabled && zone.local_thermostat_power.is_none() {
|
||||
zone.control_owner = "automation".into();
|
||||
zone.control_source = format!("group:{}", group.id);
|
||||
|
||||
Reference in New Issue
Block a user