Remove knobs from the home_assistant handler

I cannot figure out why they're buggy :/
This commit is contained in:
Moritz Ruth 2024-06-20 14:31:42 +02:00
parent 8797f61746
commit cb119963ce
Signed by: moritzruth
GPG key ID: C9BBAB79405EE56D
2 changed files with 10 additions and 155 deletions

View file

@ -1,5 +1,5 @@
use crate::ha_client::EntityId; use crate::ha_client::EntityId;
use deckster_mode::shared::state::{KeyStyleByStateMap, KnobStyleByStateMap}; use deckster_mode::shared::state::KeyStyleByStateMap;
use serde::Deserialize; use serde::Deserialize;
use url::Url; 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<Box<str>>,
#[serde(flatten)]
pub mode: KnobMode,
#[serde(default)]
pub style: KnobStyleByStateMap<Box<str>>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "mode", rename_all = "kebab-case")]
pub enum KnobMode {
Brightness { delta: Option<u8> },
}

View file

@ -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::thread;
use std::time::Duration;
use tokio::select; use tokio::select;
use tokio::sync::broadcast; use tokio::sync::broadcast;
use tokio::task::LocalSet; 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 { pub struct Handler {
events_sender: broadcast::Sender<HandlerEvent>, events_sender: broadcast::Sender<HandlerEvent>,
} }
impl Handler { impl Handler {
pub fn new(data: InitialHandlerMessage<GlobalConfig, KeyConfig, KnobConfig>) -> Result<Self, HandlerInitializationError> { pub fn new(data: InitialHandlerMessage<GlobalConfig, KeyConfig, ()>) -> Result<Self, HandlerInitializationError> {
let events_sender = broadcast::Sender::<HandlerEvent>::new(5); let events_sender = broadcast::Sender::<HandlerEvent>::new(5);
let mut subscribed_entity_ids = Vec::new(); let mut subscribed_entity_ids = Vec::new();
@ -27,10 +24,6 @@ impl Handler {
subscribed_entity_ids.push(c.mode.state_entity_id().clone()) 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({ thread::spawn({
let events_sender = events_sender.clone(); 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)); 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) runtime.block_on(task_set)
} }
}); });
@ -119,121 +108,3 @@ async fn manage_key(mut events: broadcast::Receiver<HandlerEvent>, ha_client: Ha
} }
} }
} }
async fn manage_knob(mut events: broadcast::Receiver<HandlerEvent>, 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::<u8>(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();
}
}
}
_ => {}
}
}
}
}
}