mod bluetooth; mod patterns; mod runner; mod spectacle; use crate::patterns::{ColorWipe, Fade, Patterns, PixelColor}; use crate::runner::Runner; use bluer::gatt::remote::Characteristic; use patterns::Strip; use std::path::Path; use std::time::Duration; use tokio::sync::mpsc; use tokio::sync::watch; const SERVICE_UUID: bluer::Uuid = bluer::Uuid::from_u128(0xadaf0900c33242a893bd25e905756cb8); const PIXEL_DATA_UUID: bluer::Uuid = bluer::Uuid::from_u128(0xadaf0903c33242a893bd25e905756cb8); const STRIP_SIZE: usize = 25; const BASE_STRIP_DATA: [u8; 3] = [0x00, 0x00, 0x01]; #[tokio::main(flavor = "current_thread")] async fn main() -> bluer::Result<()> { let pixel = PixelColor { red: 231, green: 124, blue: 0, }; let fade = Fade::<25> { current_iteration: 0, nbr_iterations: 0, begin_color: pixel, end_color: Default::default(), }; let context = runner::Context { pattern: Patterns::Fade(fade), period: Duration::from_millis(300), }; let mut runner = runner::Runner::<25>::new(); runner.push(context); let context = runner::Context { pattern: Patterns::ColorWipe(ColorWipe { current_iteration: 0, color: Default::default(), infinite: false, }), period: Default::default(), }; runner.push(context); let yaml = serde_yaml::to_string(&runner).unwrap(); println!("{}", yaml); let file = Path::new("spectacle.yml"); let config: Runner<25> = Runner::load_from_file(file); println!("{:?}", config); let adapter = bluetooth::create_session().await?; let (tx_scan, mut rx_scan) = mpsc::channel(3); tokio::spawn(bluetooth::bluetooth_scan( tx_scan, adapter.clone(), SERVICE_UUID, )); let (tx, rx) = watch::channel(Strip::::default()); tokio::spawn(async move { while let Some(device) = rx_scan.recv().await { bluetooth::connect(&device, 3).await?; let char = bluetooth::get_char(&device, SERVICE_UUID, PIXEL_DATA_UUID).await?; if let Some(char) = char { let mut rx_device = rx.clone(); tokio::spawn(async move { println!("device connected : {}", &device.address()); while rx_device.changed().await.is_ok() { let strip = *rx_device.borrow(); if write_strip(&strip, &char).await.is_err() { break; }; } println!("device {} disconnected", &device.address()); // drop(rx_device); }); } } bluer::Result::Ok(()) }); println!("starting"); config.runner_loop(tx).await; tokio::time::sleep(Duration::from_secs(5)).await; println!("error sending value"); Ok(()) } pub async fn write_strip( data: &Strip, char: &Characteristic, ) -> bluer::Result<()> { let frame = [BASE_STRIP_DATA.to_vec(), data.to_array()].concat(); // print!("{:?}", frame); char.write(&*frame).await?; Ok(()) }