1786289002
This commit is contained in:
@@ -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),
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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! {
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user