v0.8.19
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
async fn run_automations(state: &AppState) -> Result<()> {
|
||||
if !state.settings.read().await.house_power_enabled { return Ok(()); }
|
||||
let devices = state.db.list_devices()?;
|
||||
let zones = state.db.list_zones()?;
|
||||
let groups = state.db.list_groups()?;
|
||||
let mut automations = state.db.list_automations()?;
|
||||
// Stable arbitration for same-cycle conflicts: the oldest configured rule wins, then ID.
|
||||
// This avoids database row order deciding the physical outcome (M2).
|
||||
@@ -20,6 +18,20 @@ async fn run_automations(state: &AppState) -> Result<()> {
|
||||
_ => false,
|
||||
};
|
||||
if !should_fire { continue; }
|
||||
|
||||
// API edits/deletes and execution share one short ownership window. If the rule
|
||||
// changed since this cycle snapshot was taken, skip it now and evaluate the new
|
||||
// definition on the next cycle instead of firing stale configuration.
|
||||
let _automation_guard = state.lock_automation_operation().await;
|
||||
let Some(latest_item) = state.db.get_automation(&item.id)? else { continue; };
|
||||
if latest_item.updated_at != item.updated_at { continue; }
|
||||
item = latest_item;
|
||||
// Group membership and zone ownership may have changed after the cycle snapshot but
|
||||
// before we acquired the automation lock. Reload them inside this serialized window so
|
||||
// same-cycle conflict arbitration claims the actual current target set.
|
||||
let zones = state.db.list_zones()?;
|
||||
let groups = state.db.list_groups()?;
|
||||
|
||||
if item.action_group_id.is_none()
|
||||
&& device_blocked_by_disabled_zone(&item.action_device_id, &zones)
|
||||
&& item.action.power != Some(true)
|
||||
@@ -75,7 +87,8 @@ async fn run_automations(state: &AppState) -> Result<()> {
|
||||
power: item.action.power,
|
||||
mode: group_mode,
|
||||
preset: item.action_preset.clone(),
|
||||
}, "automation.group").await.map(|_| true)
|
||||
setpoint: None,
|
||||
}, "automation.group").await.map(|value| !value.get("suppressed").and_then(Value::as_bool).unwrap_or(false))
|
||||
} else {
|
||||
match apply_automatic_device_action(state, &item.action_device_id, item.action.clone()).await {
|
||||
Ok(Some(_)) => Ok(true),
|
||||
|
||||
Reference in New Issue
Block a user