1786289002

This commit is contained in:
2026-08-09 17:23:22 +02:00
parent 7cfaa680f0
commit 827dede10b
3 changed files with 53 additions and 37 deletions

View File

@@ -17,8 +17,5 @@ pub enum AppError {
SlintPlatform(#[from] slint::PlatformError), SlintPlatform(#[from] slint::PlatformError),
#[error(transparent)] #[error(transparent)]
HomeAssistant(#[from] hass_rs::HassError), HomeAssistant(#[from] Box<hass_rs::HassError>),
#[error("Entity {0} not found")]
NoEntity(String),
} }

View File

@@ -17,46 +17,60 @@ async fn handle_command(
match message { match message {
CommandMessage::ToggleLight { entity_id } => { CommandMessage::ToggleLight { entity_id } => {
if let Some(entity) = state.get(&entity_id) { if let Some(entity) = state.get(&entity_id) {
let payload = json!({ call_service(
"entity_id": entity_id client,
}); "light",
let service = toggle_action(&entity.state, "on"); toggle_action(&entity.state, "on"),
client json!({
.call_service("light".into(), service.into(), Some(payload)) "entity_id": entity_id
.await }),
.map_err(Into::into) )
} else { .await?;
Err(AppError::NoEntity(entity_id))
} }
} }
CommandMessage::ToggleThermostat { entity_id } => { CommandMessage::ToggleThermostat { entity_id } => {
if let Some(entity) = state.get(&entity_id) { if let Some(entity) = state.get(&entity_id) {
let payload = json!({ call_service(
"entity_id": entity_id client,
}); "climate",
let service = toggle_action(&entity.state, "heat"); toggle_action(&entity.state, "heat"),
client json!({
.call_service("climate".into(), service.into(), Some(payload)) "entity_id": entity_id
.await }),
.map_err(Into::into) )
} else { .await?;
Err(AppError::NoEntity(entity_id))
} }
} }
CommandMessage::SetTemperature { CommandMessage::SetTemperature {
entity_id, entity_id,
temperature, temperature,
} => { } => {
let payload = json!({ call_service(
"entity_id": entity_id, client,
"temperature": temperature "climate",
}); "set_temperature",
client json!({
.call_service("climate".into(), "set_temperature".into(), Some(payload)) "entity_id": entity_id,
.await "temperature": temperature
.map_err(Into::into) }),
)
.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( pub async fn hass(
@@ -83,11 +97,14 @@ pub async fn hass(
let url = format!("{}://{}/api/websocket", scheme, url.authority()); let url = format!("{}://{}/api/websocket", scheme, url.authority());
let mut client = HassClient::new(&url).await?; let mut client = HassClient::new(&url).await.map_err(Box::new)?;
client.auth_with_longlivedtoken(&hass_token).await?; client
.auth_with_longlivedtoken(&hass_token)
.await
.map_err(Box::new)?;
let mut state = HashMap::<String, HassEntity>::new(); let mut state = HashMap::<String, HassEntity>::new();
let states = client.get_states().await?; let states = client.get_states().await.map_err(Box::new)?;
states.iter().for_each(|entity| { states.iter().for_each(|entity| {
state.insert(entity.entity_id.clone(), entity.clone()); 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)); initial_state.sort_by(|a, b| a.entity_id.cmp(&b.entity_id));
s2c_tx.send(EventMessage::InitialState(initial_state)).ok(); 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 { loop {
tokio::select! { tokio::select! {

View File

@@ -13,7 +13,6 @@ use crate::{
messages::{CommandMessage, EventMessage}, messages::{CommandMessage, EventMessage},
}; };
#[allow(clippy::result_large_err)]
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), AppError> { async fn main() -> Result<(), AppError> {
dotenvy::dotenv().ok(); dotenvy::dotenv().ok();