This commit is contained in:
Mateusz Gruszczyński
2026-09-15 18:47:20 +02:00
parent 7ffaba6c7a
commit 3d69e74319
37 changed files with 426 additions and 318 deletions
+64 -6
View File
@@ -86,6 +86,58 @@ async fn resolve_cycle_outdoor_temperature(
temperature
}
async fn read_cycle_zone_outdoor_sensors(
state: &AppState,
settings: &RuntimeSettings,
zones: &[Zone],
) -> HashMap<String, Option<f64>> {
futures_util::future::join_all(zones.iter().filter_map(|zone| {
let configured = zone
.ha_outdoor_entity_id
.as_deref()
.map(str::trim)
.filter(|value| !value.is_empty())?;
let zone_id = zone.id.clone();
let resolved_entity =
home_assistant::resolve_entity_id(&settings.home_assistant, Some(configured));
let http = &state.http;
let ha_settings = &settings.home_assistant;
let poll_interval_seconds = settings.poll_interval_seconds;
Some(async move {
let Some(entity_id) = resolved_entity else {
return (zone_id, None);
};
match home_assistant::read_temperature(
http,
ha_settings,
Some(&entity_id),
Some(ha_settings.sensor_stale_after_seconds),
)
.await
{
Ok(value) => {
record_ha_history(
state,
&entity_id,
Some(&zone_id),
"outdoor",
value,
poll_interval_seconds,
);
(zone_id, Some(value))
}
Err(err) => {
tracing::debug!(zone_id=%zone_id, resolved_entity=%entity_id, error=?err, "zone outdoor Home Assistant sensor unavailable; using global outdoor fallback");
(zone_id, None)
}
}
})
}))
.await
.into_iter()
.collect()
}
async fn read_cycle_room_sensors(
state: &AppState,
settings: &RuntimeSettings,
@@ -479,13 +531,10 @@ async fn control_zones(state: &AppState) -> Result<()> {
.await?;
let device_snapshot = state.db.list_devices()?;
let outdoor_temperature =
let global_outdoor_temperature =
resolve_cycle_outdoor_temperature(state, &settings, &device_snapshot).await;
let outdoor_assist_temperature = if settings.outdoor_assist_enabled {
outdoor_temperature
} else {
None
};
let mut zone_outdoor_sensor_results =
read_cycle_zone_outdoor_sensors(state, &settings, &zone_snapshot).await;
let night_active = night_mode_active(&settings.night_mode, Local::now().time());
let mut room_sensor_results = read_cycle_room_sensors(state, &settings, &zone_snapshot).await;
@@ -498,6 +547,15 @@ async fn control_zones(state: &AppState) -> Result<()> {
continue;
};
let cycle_started_at = zone.updated_at.clone();
let outdoor_temperature = zone_outdoor_sensor_results
.remove(&zone.id)
.flatten()
.or(global_outdoor_temperature);
let outdoor_assist_temperature = if settings.outdoor_assist_enabled {
outdoor_temperature
} else {
None
};
if zone
.manual_override_until
.map(|until| until <= Utc::now())