Remove knobs from the home_assistant handler
I cannot figure out why they're buggy :/
This commit is contained in:
parent
8797f61746
commit
cb119963ce
2 changed files with 10 additions and 155 deletions
|
@ -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> },
|
|
||||||
}
|
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue