diff --git a/dashboard/src/error.rs b/dashboard/src/error.rs index fb7402d..ecde20b 100644 --- a/dashboard/src/error.rs +++ b/dashboard/src/error.rs @@ -17,8 +17,5 @@ pub enum AppError { SlintPlatform(#[from] slint::PlatformError), #[error(transparent)] - HomeAssistant(#[from] hass_rs::HassError), - - #[error("Entity {0} not found")] - NoEntity(String), + HomeAssistant(#[from] Box), } diff --git a/dashboard/src/home_assistant.rs b/dashboard/src/home_assistant.rs index 4e9b0fa..0fa6270 100644 --- a/dashboard/src/home_assistant.rs +++ b/dashboard/src/home_assistant.rs @@ -17,46 +17,60 @@ async fn handle_command( match message { CommandMessage::ToggleLight { entity_id } => { if let Some(entity) = state.get(&entity_id) { - let payload = json!({ - "entity_id": entity_id - }); - let service = toggle_action(&entity.state, "on"); - client - .call_service("light".into(), service.into(), Some(payload)) - .await - .map_err(Into::into) - } else { - Err(AppError::NoEntity(entity_id)) + call_service( + client, + "light", + toggle_action(&entity.state, "on"), + json!({ + "entity_id": entity_id + }), + ) + .await?; } } CommandMessage::ToggleThermostat { entity_id } => { if let Some(entity) = state.get(&entity_id) { - let payload = json!({ - "entity_id": entity_id - }); - let service = toggle_action(&entity.state, "heat"); - client - .call_service("climate".into(), service.into(), Some(payload)) - .await - .map_err(Into::into) - } else { - Err(AppError::NoEntity(entity_id)) + call_service( + client, + "climate", + toggle_action(&entity.state, "heat"), + json!({ + "entity_id": entity_id + }), + ) + .await?; } } CommandMessage::SetTemperature { entity_id, temperature, } => { - let payload = json!({ - "entity_id": entity_id, - "temperature": temperature - }); - client - .call_service("climate".into(), "set_temperature".into(), Some(payload)) - .await - .map_err(Into::into) + call_service( + client, + "climate", + "set_temperature", + json!({ + "entity_id": entity_id, + "temperature": temperature + }), + ) + .await?; } } + Ok(()) +} + +async fn call_service( + client: &mut HassClient, + domain: &str, + service: &str, + data: serde_json::Value, +) -> Result<(), AppError> { + client + .call_service(domain.into(), service.into(), Some(data)) + .await + .map_err(Box::new) + .map_err(Into::into) } pub async fn hass( @@ -83,11 +97,14 @@ pub async fn hass( let url = format!("{}://{}/api/websocket", scheme, url.authority()); - let mut client = HassClient::new(&url).await?; - client.auth_with_longlivedtoken(&hass_token).await?; + let mut client = HassClient::new(&url).await.map_err(Box::new)?; + client + .auth_with_longlivedtoken(&hass_token) + .await + .map_err(Box::new)?; let mut state = HashMap::::new(); - let states = client.get_states().await?; + let states = client.get_states().await.map_err(Box::new)?; states.iter().for_each(|entity| { state.insert(entity.entity_id.clone(), entity.clone()); @@ -97,7 +114,10 @@ pub async fn hass( initial_state.sort_by(|a, b| a.entity_id.cmp(&b.entity_id)); s2c_tx.send(EventMessage::InitialState(initial_state)).ok(); - let mut event_receiver = client.subscribe_event("state_changed").await?; + let mut event_receiver = client + .subscribe_event("state_changed") + .await + .map_err(Box::new)?; loop { tokio::select! { diff --git a/dashboard/src/main.rs b/dashboard/src/main.rs index dc3973c..566c879 100644 --- a/dashboard/src/main.rs +++ b/dashboard/src/main.rs @@ -13,7 +13,6 @@ use crate::{ messages::{CommandMessage, EventMessage}, }; -#[allow(clippy::result_large_err)] #[tokio::main] async fn main() -> Result<(), AppError> { dotenvy::dotenv().ok();