This commit is contained in:
Mateusz Gruszczyński
2026-09-04 11:30:48 +02:00
parent 236540e0f0
commit 9b4fafdfa6
14 changed files with 262 additions and 62 deletions
+20 -1
View File
@@ -1,3 +1,15 @@
fn device_runtime_change_affects_control_plan(before: &Device, after: &Device) -> bool {
// build_control_plan() consumes only these runtime device fields. Poll heartbeat data such
// as last_seen/response_time_ms remains available through device.updated but no longer
// forces an expensive control-plan rebuild.
before.name != after.name
|| before.power != after.power
|| before.mode != after.mode
|| before.target_temperature != after.target_temperature
|| before.online != after.online
|| before.communication_failures != after.communication_failures
}
async fn lock_poll_zone_operations(state: &AppState, device_id: &str) -> Result<Vec<tokio::sync::OwnedMutexGuard<()>>, AppError> {
let mut zone_ids: Vec<String> = state.db.list_zones()?.into_iter()
.filter(|zone| zone.device_id == device_id)
@@ -35,7 +47,11 @@ async fn poll_one_locked(state: &AppState, device_id: &str) -> Result<Device, Ap
}
state.db.save_device(&device)?;
record_reading(state, &device)?;
state.broadcast("device.updated", serde_json::to_value(&device).unwrap_or_default());
state.broadcast_with_control_plan_invalidation(
"device.updated",
serde_json::to_value(&device).unwrap_or_default(),
device_runtime_change_affects_control_plan(&before, &device),
);
Ok(device)
}
@@ -182,6 +198,9 @@ fn record_poll_failure(device: &mut Device, error: &str) {
fn register_device_failure(state: &AppState, device: &mut Device, error: &str) -> Result<(), AppError> {
record_poll_failure(device, error);
state.db.save_device(device)?;
// Command failures can change online/communication health without a device.updated frame.
// Keep the materialized plan current explicitly instead of relying on log-event prefixes.
state.invalidate_control_plan();
state.log("warn", "device.communication_error", &format!("{}: {error}", device.name), json!({
"device_id": device.id,
"consecutive_failures": device.communication_failures,