From cb119963ce8b98278c4dfaebe833036b01afc1c9 Mon Sep 17 00:00:00 2001 From: Moritz Ruth Date: Thu, 20 Jun 2024 14:31:42 +0200 Subject: [PATCH] Remove knobs from the home_assistant handler I cannot figure out why they're buggy :/ --- handlers/home_assistant/src/config.rs | 18 +-- handlers/home_assistant/src/handler.rs | 147 ++----------------------- 2 files changed, 10 insertions(+), 155 deletions(-) diff --git a/handlers/home_assistant/src/config.rs b/handlers/home_assistant/src/config.rs index 02c5c4c..8ed04b7 100644 --- a/handlers/home_assistant/src/config.rs +++ b/handlers/home_assistant/src/config.rs @@ -1,5 +1,5 @@ use crate::ha_client::EntityId; -use deckster_mode::shared::state::{KeyStyleByStateMap, KnobStyleByStateMap}; +use deckster_mode::shared::state::KeyStyleByStateMap; use serde::Deserialize; use url::Url; @@ -34,19 +34,3 @@ impl KeyMode { } } } - -#[derive(Debug, Clone, Deserialize)] -pub struct KnobConfig { - pub(crate) entity_id: EntityId, - pub disconnected_state: Option>, - #[serde(flatten)] - pub mode: KnobMode, - #[serde(default)] - pub style: KnobStyleByStateMap>, -} - -#[derive(Debug, Clone, Deserialize)] -#[serde(tag = "mode", rename_all = "kebab-case")] -pub enum KnobMode { - Brightness { delta: Option }, -} diff --git a/handlers/home_assistant/src/handler.rs b/handlers/home_assistant/src/handler.rs index 4d89a35..7f37126 100644 --- a/handlers/home_assistant/src/handler.rs +++ b/handlers/home_assistant/src/handler.rs @@ -1,25 +1,22 @@ -use crate::config::{GlobalConfig, KeyConfig, KeyMode, KnobConfig, KnobMode}; -use crate::ha_client::{HaClient, StateUpdate}; -use crate::util::{spawn_debouncer, spawn_throttler}; -use deckster_mode::shared::handler_communication::{ - HandlerCommand, HandlerEvent, HandlerInitializationError, InitialHandlerMessage, KeyEvent, KnobEvent, RotationDirection, -}; -use deckster_mode::shared::path::{KeyPath, KnobPath}; -use deckster_mode::shared::style::KnobStyle; -use deckster_mode::{send_command, DecksterHandler}; -use serde_json::json; use std::thread; -use std::time::Duration; + use tokio::select; use tokio::sync::broadcast; use tokio::task::LocalSet; +use deckster_mode::shared::handler_communication::{HandlerCommand, HandlerEvent, HandlerInitializationError, InitialHandlerMessage, KeyEvent}; +use deckster_mode::shared::path::KeyPath; +use deckster_mode::{send_command, DecksterHandler}; + +use crate::config::{GlobalConfig, KeyConfig, KeyMode}; +use crate::ha_client::{HaClient, StateUpdate}; + pub struct Handler { events_sender: broadcast::Sender, } impl Handler { - pub fn new(data: InitialHandlerMessage) -> Result { + pub fn new(data: InitialHandlerMessage) -> Result { let events_sender = broadcast::Sender::::new(5); let mut subscribed_entity_ids = Vec::new(); @@ -27,10 +24,6 @@ impl Handler { subscribed_entity_ids.push(c.mode.state_entity_id().clone()) } - for c in data.knob_configs.values() { - subscribed_entity_ids.push(c.entity_id.clone()) - } - thread::spawn({ let events_sender = events_sender.clone(); @@ -47,10 +40,6 @@ impl Handler { task_set.spawn_local(manage_key(events_sender.subscribe(), ha_client.clone(), path, config)); } - for (path, config) in data.knob_configs { - task_set.spawn_local(manage_knob(events_sender.subscribe(), ha_client.clone(), path, config)); - } - runtime.block_on(task_set) } }); @@ -119,121 +108,3 @@ async fn manage_key(mut events: broadcast::Receiver, ha_client: Ha } } } - -async fn manage_knob(mut events: broadcast::Receiver, ha_client: HaClient, path: KnobPath, config: KnobConfig) { - if let Some(state) = &config.disconnected_state { - send_command(HandlerCommand::SetKnobStyle { - path: path.clone(), - value: config.style.get(state).cloned(), - }); - } - - let mut state_updates = ha_client.subscribe_to_state_updates(); - - let mut current_client_brightness = 0u8; - let mut current_server_brightness = 0u8; - let (new_brightness_requests_sender, mut new_brightness_requests_receiver) = spawn_throttler::(Duration::from_millis(150)); - let (apply_server_debounce_sender, mut apply_server_debounce_receiver) = spawn_debouncer(Duration::from_secs(3)); - - loop { - select! { - Some(_) = apply_server_debounce_receiver.recv() => { - current_client_brightness = current_server_brightness; - - let percentage = (((current_server_brightness as f32 / 255_f32) * 100.0).round() as u8).to_string().into_boxed_str(); - send_command(HandlerCommand::SetKnobStyle { - path: path.clone(), - value: config.style.get(&percentage).or_else(|| config.style.get("default")).cloned().map(|s| KnobStyle { - // RustRover: false positive - label: s.label.map(|l| l.replace("{value}", &percentage)), - ..s - }) - }); - } - Some(new_brightness) = new_brightness_requests_receiver.recv() => { - ha_client.call_service("light", "turn_on", json!({ - "entity_id": config.entity_id.to_string(), - "brightness": new_brightness - }).to_string()).await - } - Ok(update) = state_updates.recv() => { - match update { - StateUpdate::Disconnected => { - if let Some(state) = &config.disconnected_state { - send_command(HandlerCommand::SetKnobStyle { - path: path.clone(), - value: config.style.get(state).cloned(), - }); - send_command(HandlerCommand::SetKnobValue { - path: path.clone(), - value: None - }); - } - } - StateUpdate::Actual(update) => { - if update.entity_id == config.entity_id { - current_server_brightness = update.attributes - .get("brightness") - .and_then(|b| b.as_number()) - .and_then(|b| b.as_u64()).unwrap_or(0) - .clamp(0, 255) as u8; - - if current_client_brightness == 0 { - current_client_brightness = current_server_brightness; - } - - let percentage = (((current_server_brightness as f32 / 255_f32) * 100.0).round() as u8).to_string().into_boxed_str(); - send_command(HandlerCommand::SetKnobStyle { - path: path.clone(), - value: config.style.get(&percentage).or_else(|| config.style.get("default")).cloned().map(|s| KnobStyle { - // RustRover: false positive - label: s.label.map(|l| l.replace("{value}", &percentage)), - ..s - }) - }); - } - } - } - } - Ok(HandlerEvent::Knob { path: p, event }) = events.recv() => { - if p != path { - continue - } - - match event { - KnobEvent::Press => { - match &config.mode { - KnobMode::Brightness { .. } => { - current_client_brightness = if current_client_brightness == 0 { - 255 - } else { - 0 - }; - - apply_server_debounce_sender.send(()).await.unwrap(); - new_brightness_requests_sender.send(current_client_brightness).await.unwrap(); - } - } - } - KnobEvent::Rotate { direction } => { - match &config.mode { - KnobMode::Brightness { delta } => { - let factor = match direction { - RotationDirection::Counterclockwise => -1_f32, - RotationDirection::Clockwise => 1_f32, - }; - - let delta = (delta.unwrap_or(1) as f32 / 100_f32) * 255_f32; - - current_client_brightness = (current_client_brightness as isize + (factor * delta).round() as isize).clamp(0, 255) as u8; - apply_server_debounce_sender.send(()).await.unwrap(); - new_brightness_requests_sender.send(current_client_brightness).await.unwrap(); - } - } - } - _ => {} - } - } - } - } -}