use embassy_strike_driver::{DetectorConfig, DetectorUpdate}; use embassy_sync::channel::{Channel, Receiver, Sender}; use sachy_fmt::info; use striker_proto::{StrikerResponse, Update}; use crate::{ locks::DataTransferLock, state::{DETECTOR_CONFIG, DETECTOR_CONFIG_UPDATES, DEVICE_STATE, DeviceState}, }; pub type NetDataChannel = Channel; pub type NetDataSender = Sender<'static, DataTransferLock, StrikerResponse, 8>; pub type NetDataReceiver = Receiver<'static, DataTransferLock, StrikerResponse, 8>; static NET_CHANNEL: NetDataChannel = Channel::new(); pub struct UpdateConnection; impl UpdateConnection { pub fn disconnect() { DEVICE_STATE.lock(|state| state.set(DeviceState::Disconnected)); } pub fn connect() { DEVICE_STATE.lock(|state| state.set(DeviceState::Connected)); } pub fn is_connected() -> bool { DEVICE_STATE.lock(|state| state.get() == DeviceState::Connected) } pub fn get_receiver() -> NetDataReceiver { NET_CHANNEL.receiver() } pub fn can_update() -> Option { Self::is_connected().then(|| NET_CHANNEL.sender()) } pub fn transmit_update(update: DetectorUpdate<'_>) { let sender = Self::can_update(); match update { DetectorUpdate::Tick { timestamp, level } => { sender.and_then(|sender| { sender .try_send(StrikerResponse::Update(Update::Warning { timestamp, level, })) .ok() }); } DetectorUpdate::Detection { timestamp, average, samples, peaks, } => { info!("STRIKE @ {}: Peaks {}", timestamp, peaks); sender.and_then(|sender| { sender .try_send(StrikerResponse::Update(Update::Strike { timestamp, peaks: peaks.to_vec(), samples: samples .iter() .map(|&sample| (average as i16).saturating_sub_unsigned(sample)) .collect(), average, })) .ok() }); } }; } } pub struct DetectorConfigUpdate { pub blip_threshold: Option, pub blip_size: Option, } pub struct DetectorConfigurationHandle; impl DetectorConfigurationHandle { pub fn set_config(update: DetectorConfigUpdate) { let update = DETECTOR_CONFIG.lock(|config| { if let Some(size) = update.blip_size { config.set_blip_size(size); } if let Some(threshold) = update.blip_threshold { config.set_blip_threshold(threshold); } config.clone() }); DETECTOR_CONFIG_UPDATES.signal(update); } pub fn get_config() -> DetectorConfig { DETECTOR_CONFIG.lock(Clone::clone) } pub async fn get_updated_config() -> DetectorConfig { DETECTOR_CONFIG_UPDATES.wait().await } }