v0.14.2
This commit is contained in:
+78
-1
@@ -20,12 +20,81 @@ struct SystemInfoResponse {
|
||||
gree_received_frames_by_device: std::collections::HashMap<String, u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize)]
|
||||
struct DeviceGroupEnergySnapshot {
|
||||
total_kwh: f64,
|
||||
timestamp: Option<chrono::DateTime<Utc>>,
|
||||
source: String,
|
||||
origin: String,
|
||||
}
|
||||
|
||||
fn device_group_energy_snapshot(
|
||||
state: &AppState,
|
||||
group: &DeviceGroup,
|
||||
devices: &[Device],
|
||||
) -> Result<Option<DeviceGroupEnergySnapshot>, AppError> {
|
||||
let selected_source = match group.energy_source {
|
||||
EnergySourcePreference::GreeCloud => Some("gree_cloud"),
|
||||
EnergySourcePreference::HomeAssistant => Some("home_assistant"),
|
||||
EnergySourcePreference::Auto if group.energy_device_id.is_some() => Some("gree_cloud"),
|
||||
EnergySourcePreference::Auto if group.ha_energy_entity_id.is_some() => Some("home_assistant"),
|
||||
EnergySourcePreference::Auto => None,
|
||||
};
|
||||
|
||||
match selected_source {
|
||||
Some("gree_cloud") => {
|
||||
let Some(device_id) = group.energy_device_id.as_deref() else {
|
||||
return Ok(None);
|
||||
};
|
||||
if let Some(device) = devices.iter().find(|device| device.id == device_id) {
|
||||
if let Some(total_kwh) = device
|
||||
.total_energy_kwh
|
||||
.filter(|value| value.is_finite() && *value >= 0.0)
|
||||
{
|
||||
return Ok(Some(DeviceGroupEnergySnapshot {
|
||||
total_kwh,
|
||||
timestamp: device
|
||||
.last_cloud_sync
|
||||
.clone()
|
||||
.or_else(|| device.last_seen.clone()),
|
||||
source: "gree_cloud".into(),
|
||||
origin: "cloud".into(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
Ok(state
|
||||
.db
|
||||
.last_energy_reading(device_id, "gree_cloud")?
|
||||
.map(|reading| DeviceGroupEnergySnapshot {
|
||||
total_kwh: reading.normalized_meter_kwh,
|
||||
timestamp: Some(reading.timestamp),
|
||||
source: "gree_cloud".into(),
|
||||
origin: "database".into(),
|
||||
}))
|
||||
}
|
||||
Some("home_assistant") => {
|
||||
let storage_id = format!("group:{}", group.id);
|
||||
Ok(state
|
||||
.db
|
||||
.last_energy_reading(&storage_id, "home_assistant")?
|
||||
.map(|reading| DeviceGroupEnergySnapshot {
|
||||
total_kwh: reading.normalized_meter_kwh,
|
||||
timestamp: Some(reading.timestamp),
|
||||
source: "home_assistant".into(),
|
||||
origin: "database".into(),
|
||||
}))
|
||||
}
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
struct BootstrapResponse {
|
||||
devices: Vec<Device>,
|
||||
zones: Vec<Zone>,
|
||||
groups: Vec<ClimateGroup>,
|
||||
device_groups: Vec<DeviceGroup>,
|
||||
device_group_energy: std::collections::HashMap<String, DeviceGroupEnergySnapshot>,
|
||||
schedules: Vec<Schedule>,
|
||||
automations: Vec<Automation>,
|
||||
flows: Vec<Flow>,
|
||||
@@ -59,6 +128,13 @@ async fn build_bootstrap(state: &AppState) -> Result<BootstrapResponse, AppError
|
||||
(settings_snapshot(&settings), settings.house_mode.clone())
|
||||
};
|
||||
let devices = state.db.list_devices()?;
|
||||
let device_groups = state.db.list_device_groups()?;
|
||||
let mut device_group_energy = std::collections::HashMap::new();
|
||||
for group in &device_groups {
|
||||
if let Some(snapshot) = device_group_energy_snapshot(state, group, &devices)? {
|
||||
device_group_energy.insert(group.id.clone(), snapshot);
|
||||
}
|
||||
}
|
||||
let system = build_system_info(state, &devices);
|
||||
let control_plan = engine::get_control_plan_snapshot(state).await?;
|
||||
|
||||
@@ -66,7 +142,8 @@ async fn build_bootstrap(state: &AppState) -> Result<BootstrapResponse, AppError
|
||||
devices,
|
||||
zones: state.db.list_zones()?,
|
||||
groups: state.db.list_groups()?,
|
||||
device_groups: state.db.list_device_groups()?,
|
||||
device_groups,
|
||||
device_group_energy,
|
||||
schedules: state.db.list_schedules()?,
|
||||
automations: state.db.list_automations()?,
|
||||
flows: state.db.list_flows()?,
|
||||
|
||||
Reference in New Issue
Block a user