A RPi Pico powered Lightning Detector
at main 109 lines 3.3 kB view raw
1use embassy_strike_driver::{DetectorConfig, DetectorUpdate}; 2use embassy_sync::channel::{Channel, Receiver, Sender}; 3use sachy_fmt::info; 4use striker_proto::{StrikerResponse, Update}; 5 6use crate::{ 7 locks::DataTransferLock, 8 state::{DETECTOR_CONFIG, DETECTOR_CONFIG_UPDATES, DEVICE_STATE, DeviceState}, 9}; 10 11pub type NetDataChannel = Channel<DataTransferLock, StrikerResponse, 8>; 12pub type NetDataSender = Sender<'static, DataTransferLock, StrikerResponse, 8>; 13pub type NetDataReceiver = Receiver<'static, DataTransferLock, StrikerResponse, 8>; 14 15static NET_CHANNEL: NetDataChannel = Channel::new(); 16 17pub struct UpdateConnection; 18 19impl UpdateConnection { 20 pub fn disconnect() { 21 DEVICE_STATE.lock(|state| state.set(DeviceState::Disconnected)); 22 } 23 24 pub fn connect() { 25 DEVICE_STATE.lock(|state| state.set(DeviceState::Connected)); 26 } 27 28 pub fn is_connected() -> bool { 29 DEVICE_STATE.lock(|state| state.get() == DeviceState::Connected) 30 } 31 32 pub fn get_receiver() -> NetDataReceiver { 33 NET_CHANNEL.receiver() 34 } 35 36 pub fn can_update() -> Option<NetDataSender> { 37 Self::is_connected().then(|| NET_CHANNEL.sender()) 38 } 39 40 pub fn transmit_update(update: DetectorUpdate<'_>) { 41 let sender = Self::can_update(); 42 43 match update { 44 DetectorUpdate::Tick { timestamp, level } => { 45 sender.and_then(|sender| { 46 sender 47 .try_send(StrikerResponse::Update(Update::Warning { 48 timestamp, 49 level, 50 })) 51 .ok() 52 }); 53 } 54 DetectorUpdate::Detection { 55 timestamp, 56 average, 57 samples, 58 peaks, 59 } => { 60 info!("STRIKE @ {}: Peaks {}", timestamp, peaks); 61 sender.and_then(|sender| { 62 sender 63 .try_send(StrikerResponse::Update(Update::Strike { 64 timestamp, 65 peaks: peaks.to_vec(), 66 samples: samples 67 .iter() 68 .map(|&sample| (average as i16).saturating_sub_unsigned(sample)) 69 .collect(), 70 average, 71 })) 72 .ok() 73 }); 74 } 75 }; 76 } 77} 78 79pub struct DetectorConfigUpdate { 80 pub blip_threshold: Option<u16>, 81 pub blip_size: Option<usize>, 82} 83 84pub struct DetectorConfigurationHandle; 85 86impl DetectorConfigurationHandle { 87 pub fn set_config(update: DetectorConfigUpdate) { 88 let update = DETECTOR_CONFIG.lock(|config| { 89 if let Some(size) = update.blip_size { 90 config.set_blip_size(size); 91 } 92 93 if let Some(threshold) = update.blip_threshold { 94 config.set_blip_threshold(threshold); 95 } 96 97 config.clone() 98 }); 99 DETECTOR_CONFIG_UPDATES.signal(update); 100 } 101 102 pub fn get_config() -> DetectorConfig { 103 DETECTOR_CONFIG.lock(Clone::clone) 104 } 105 106 pub async fn get_updated_config() -> DetectorConfig { 107 DETECTOR_CONFIG_UPDATES.wait().await 108 } 109}