This commit is contained in:
Mateusz Gruszczyński
2026-08-23 23:32:26 +02:00
parent b23578a0c8
commit f569b7db14
42 changed files with 597 additions and 4104 deletions
+30 -1
View File
@@ -6,7 +6,7 @@ use tokio::time::sleep;
use crate::{
error::AppError,
home_assistant,
models::{Automation, Device, DeviceCommand, Reading, Schedule, Zone},
models::{Automation, Device, DeviceCommand, Reading, Schedule, Zone, ZoneReading},
state::AppState,
};
@@ -341,6 +341,7 @@ async fn control_zones(state: &AppState) -> Result<()> {
Err(err) => state.log("error", "zone.action_error", &err.to_string(), json!({"zone_id": zone.id})),
}
}
record_zone_history(state, &zone, outdoor_temperature, settings.poll_interval_seconds)?;
state.db.save_zone(&zone)?;
state.broadcast("zone.updated", serde_json::to_value(&zone)?);
continue;
@@ -352,6 +353,7 @@ async fn control_zones(state: &AppState) -> Result<()> {
zone.effective_setpoint = Some(target);
let Some(temp) = temperature else {
record_zone_history(state, &zone, outdoor_temperature, settings.poll_interval_seconds)?;
state.db.save_zone(&zone)?;
state.broadcast("zone.updated", serde_json::to_value(&zone)?);
continue;
@@ -422,12 +424,39 @@ async fn control_zones(state: &AppState) -> Result<()> {
}
}
record_zone_history(state, &zone, outdoor_temperature, settings.poll_interval_seconds)?;
state.db.save_zone(&zone)?;
state.broadcast("zone.updated", serde_json::to_value(&zone)?);
}
Ok(())
}
fn record_zone_history(state: &AppState, zone: &Zone, outdoor_temperature: Option<f64>, poll_interval_seconds: u64) -> Result<()> {
let Some(device) = state.db.get_device(&zone.device_id)? else { return Ok(()); };
let reading = ZoneReading {
id: 0,
zone_id: zone.id.clone(),
device_id: zone.device_id.clone(),
timestamp: Utc::now(),
gree_temperature: zone.device_temperature,
external_temperature: zone.external_temperature,
control_temperature: zone.current_temperature,
target_temperature: zone.effective_setpoint,
device_setpoint: zone.device_setpoint.or(Some(device.target_temperature)),
outdoor_temperature,
power: device.power,
mode: if zone.effective_mode.is_empty() { device.mode.clone() } else { zone.effective_mode.clone() },
fan_speed: device.fan_speed,
demand: zone.demand,
control_source: zone.control_temperature_source.clone(),
active_preset: zone.active_preset.clone(),
};
// History is deliberately less frequent than the zone control loop to keep SQLite compact.
let interval = poll_interval_seconds.max(15) as i64;
state.db.add_zone_reading_if_due(&reading, interval)?;
Ok(())
}
fn select_zone_temperature(zone: &Zone, device_temperature: Option<f64>, external_temperature: Option<f64>) -> (Option<f64>, String, bool) {
match zone.sensor_source.as_str() {
"home_assistant" => match (external_temperature, device_temperature) {