This commit is contained in:
Mateusz Gruszczyński
2026-08-27 23:18:03 +02:00
parent 7465de4b55
commit 016aac0f8d
19 changed files with 147 additions and 52 deletions
+18 -2
View File
@@ -1158,7 +1158,7 @@ async fn control_zones(state: &AppState) -> Result<()> {
home_assistant::resolve_entity_id(&settings.home_assistant, Some(configured_outdoor))
};
let ha_outdoor_temperature = if let Some(entity_id) = resolved_outdoor.as_deref() {
match home_assistant::read_temperature(&state.http, &settings.home_assistant, Some(entity_id), Some(300)).await {
match home_assistant::read_temperature(&state.http, &settings.home_assistant, Some(entity_id), Some(settings.home_assistant.sensor_stale_after_seconds)).await {
Ok(value) => {
record_ha_history(
state,
@@ -1204,8 +1204,9 @@ async fn control_zones(state: &AppState) -> Result<()> {
let resolved_entity = home_assistant::resolve_entity_id(&settings.home_assistant, zone.ha_entity_id.as_deref());
let http = &state.http;
let ha_settings = &settings.home_assistant;
let stale_after_seconds = effective_sensor_stale_after_seconds(zone.sensor_stale_after_seconds, ha_settings.sensor_stale_after_seconds);
Some(async move {
let result = home_assistant::read_temperature(http, ha_settings, resolved_entity.as_deref(), Some(zone.sensor_stale_after_seconds)).await
let result = home_assistant::read_temperature(http, ha_settings, resolved_entity.as_deref(), Some(stale_after_seconds)).await
.map_err(|err| err.to_string());
(zone_id, resolved_entity, result)
})
@@ -1773,6 +1774,13 @@ fn external_room_sensor_cooling_assist(mode: &str, control_source: &str) -> f64
if mode == "cool" && matches!(control_source, "external" | "combined") { 0.5 } else { 0.0 }
}
fn effective_sensor_stale_after_seconds(zone_value: u64, global_value: u64) -> u64 {
let global = global_value.clamp(30, 86_400);
// 0 and the historical hidden default (300 s) mean "inherit the HA setting".
// A non-default value supplied through the existing zone API remains a per-zone override.
if zone_value == 0 || zone_value == 300 { global } else { zone_value.clamp(30, 86_400) }
}
fn round_device_setpoint(mode: &str, demand: bool, value: f64) -> f64 {
let value = value.clamp(16.0, 30.0);
match (mode, demand) {
@@ -2407,6 +2415,14 @@ mod tests {
use super::*;
use chrono::TimeZone;
#[test]
fn global_ha_sensor_stale_timeout_is_used_for_default_zone_value() {
assert_eq!(effective_sensor_stale_after_seconds(300, 600), 600);
assert_eq!(effective_sensor_stale_after_seconds(0, 900), 900);
assert_eq!(effective_sensor_stale_after_seconds(120, 600), 120);
assert_eq!(effective_sensor_stale_after_seconds(120_000, 600), 86_400);
}
#[test]
fn overnight_schedule_works() {
let now = Utc.with_ymd_and_hms(2025, 1, 7, 1, 0, 0).unwrap().with_timezone(&Local); // Tuesday