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),
#[error(transparent)]
HomeAssistant(#[from] hass_rs::HassError),
#[error("Entity {0} not found")]
NoEntity(String),
HomeAssistant(#[from] Box<hass_rs::HassError>),
}

View File

@@ -17,47 +17,61 @@ async fn handle_command(
match message {
CommandMessage::ToggleLight { entity_id } => {
if let Some(entity) = state.get(&entity_id) {
let payload = json!({
call_service(
client,
"light",
toggle_action(&entity.state, "on"),
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))
}),
)
.await?;
}
}
CommandMessage::ToggleThermostat { entity_id } => {
if let Some(entity) = state.get(&entity_id) {
let payload = json!({
call_service(
client,
"climate",
toggle_action(&entity.state, "heat"),
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))
}),
)
.await?;
}
}
CommandMessage::SetTemperature {
entity_id,
temperature,
} => {
let payload = json!({
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("climate".into(), "set_temperature".into(), Some(payload))
.call_service(domain.into(), service.into(), Some(data))
.await
.map_err(Box::new)
.map_err(Into::into)
}
}
}
pub async fn hass(
s2c_tx: UnboundedSender<EventMessage>,
@@ -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::<String, HassEntity>::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! {

View File

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