remove warning and await futures
This commit is contained in:
parent
d7f7dede49
commit
17866b6670
|
@ -1,9 +1,8 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::sync::mpsc::{channel, Sender};
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use bluer::{Adapter, AdapterEvent, Address, Device, Result, Uuid};
|
use bluer::{Adapter, AdapterEvent, Address, Device, Result, Uuid};
|
||||||
|
use bluer::gatt::remote::Characteristic;
|
||||||
use futures::{pin_mut, StreamExt};
|
use futures::{pin_mut, StreamExt};
|
||||||
use tokio::task::spawn_blocking;
|
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
// const CONNECT_RETRIES: u8 = 3;
|
// const CONNECT_RETRIES: u8 = 3;
|
||||||
|
@ -47,7 +46,7 @@ async fn bluetooth_scan(tx: mpsc::Sender<Device>, adapter: Adapter, uuid: Uuid)
|
||||||
match has_service(&device, &uuid).await {
|
match has_service(&device, &uuid).await {
|
||||||
Ok(service_found) => {
|
Ok(service_found) => {
|
||||||
if service_found {
|
if service_found {
|
||||||
tx.send(device).await;
|
tx.send(device).await.unwrap();
|
||||||
println!("found service in device {}", addr);
|
println!("found service in device {}", addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,8 +65,8 @@ async fn bluetooth_scan(tx: mpsc::Sender<Device>, adapter: Adapter, uuid: Uuid)
|
||||||
pub(crate) async fn scan_devices(adapter: Adapter, uuid: Uuid) -> Vec<Device> {
|
pub(crate) async fn scan_devices(adapter: Adapter, uuid: Uuid) -> Vec<Device> {
|
||||||
println!("start scanning devices");
|
println!("start scanning devices");
|
||||||
let (tx, mut rx) = mpsc::channel(4);
|
let (tx, mut rx) = mpsc::channel(4);
|
||||||
;
|
|
||||||
let timeout = tokio::time::timeout(Duration::from_secs(30), bluetooth_scan(tx, adapter, uuid)).await;
|
let timeout = tokio::time::timeout(Duration::from_secs(30), bluetooth_scan(tx, adapter, uuid));
|
||||||
let scan = tokio::spawn(timeout);
|
let scan = tokio::spawn(timeout);
|
||||||
println!("good");
|
println!("good");
|
||||||
let mut devices: Vec<Device> = Vec::new();
|
let mut devices: Vec<Device> = Vec::new();
|
||||||
|
@ -84,3 +83,39 @@ pub(crate) async fn scan_devices(adapter: Adapter, uuid: Uuid) -> Vec<Device> {
|
||||||
|
|
||||||
devices
|
devices
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn connect(device: &Device, retries: u8) -> bluer::Result<()> {
|
||||||
|
if device.is_connected().await? {
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
for i in 0..retries {
|
||||||
|
match device.connect().await {
|
||||||
|
Ok(()) => return Ok(()),
|
||||||
|
Err(_) => {
|
||||||
|
println!("connection error ({}), retry…", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(bluer::Error {
|
||||||
|
kind: bluer::ErrorKind::ConnectionAttemptFailed,
|
||||||
|
message: "all attempts fail".parse().unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_char(device: &Device, service_uuid: Uuid, char_uuid: Uuid) -> Result<Option<Characteristic>> {
|
||||||
|
for service in device.services().await? {
|
||||||
|
if service_uuid == service.uuid().await? {
|
||||||
|
for char in service.characteristics().await? {
|
||||||
|
println!("uuid : {}", &char.uuid().await?);
|
||||||
|
if char_uuid == char.uuid().await? {
|
||||||
|
|
||||||
|
return Ok(Some(char));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(None)
|
||||||
|
}
|
55
src/main.rs
55
src/main.rs
|
@ -1,12 +1,9 @@
|
||||||
mod patterns;
|
mod patterns;
|
||||||
mod bluetooth;
|
mod bluetooth;
|
||||||
|
|
||||||
use patterns::{PixelColor, Strip};
|
use patterns::Strip;
|
||||||
use bluer::Device;
|
|
||||||
use bluer::gatt::remote::Characteristic;
|
use bluer::gatt::remote::Characteristic;
|
||||||
use std::time::Duration;
|
use tokio::sync::watch;
|
||||||
use tokio::time::sleep;
|
|
||||||
use crate::patterns::RainbowPattern;
|
|
||||||
|
|
||||||
const SERVICE_UUID: bluer::Uuid = bluer::Uuid::from_u128(0xadaf0900c33242a893bd25e905756cb8);
|
const SERVICE_UUID: bluer::Uuid = bluer::Uuid::from_u128(0xadaf0900c33242a893bd25e905756cb8);
|
||||||
const PIXEL_DATA_UUID: bluer::Uuid = bluer::Uuid::from_u128(0xadaf0903c33242a893bd25e905756cb8);
|
const PIXEL_DATA_UUID: bluer::Uuid = bluer::Uuid::from_u128(0xadaf0903c33242a893bd25e905756cb8);
|
||||||
|
@ -21,7 +18,21 @@ async fn main() -> bluer::Result<()> {
|
||||||
|
|
||||||
let devices = bluetooth::scan_devices(adapter, SERVICE_UUID).await;
|
let devices = bluetooth::scan_devices(adapter, SERVICE_UUID).await;
|
||||||
|
|
||||||
|
let (tx, rx) = watch::channel(Strip::<STRIP_SIZE>::default());
|
||||||
|
|
||||||
for device in devices {
|
for device in devices {
|
||||||
|
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 = rx.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
while rx.changed().await.is_ok() {
|
||||||
|
let strip = *rx.borrow();
|
||||||
|
write_strip(&strip, &char).await;
|
||||||
|
}
|
||||||
|
}).await;
|
||||||
|
}
|
||||||
|
|
||||||
println!("{:?}", device);
|
println!("{:?}", device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +41,8 @@ async fn main() -> bluer::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// async fn send_seq(char: &Characteristic) -> bluer::Result<()> {
|
// async fn send_seq(char: &Characteristic) -> bluer::Result<()> {
|
||||||
// println!(" Characteristic flags : {:?}, ", char.flags().await?);
|
// println!(" Characteristic flags : {:?}, ", char.flags().await?);
|
||||||
//
|
//
|
||||||
|
@ -50,32 +63,14 @@ async fn main() -> bluer::Result<()> {
|
||||||
// Ok(())
|
// Ok(())
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub async fn write_strip<const N: usize>(data: Strip<N>, char: &Characteristic) -> bluer::Result<()> {
|
pub async fn write_strip<const N: usize>(data: &Strip<N>, char: &Characteristic) -> bluer::Result<()> {
|
||||||
// let frame = [BASE_STRIP_DATA.to_vec(), data.to_array()].concat();
|
let frame = [BASE_STRIP_DATA.to_vec(), data.to_array()].concat();
|
||||||
// print!("{:?}",frame);
|
print!("{:?}",frame);
|
||||||
// char.write(&*frame).await?;
|
char.write(&*frame).await?;
|
||||||
// Ok(())
|
Ok(())
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
|
||||||
// async fn connect(device: &Device, retries: u8) -> bluer::Result<()> {
|
|
||||||
// if device.is_connected().await? {
|
|
||||||
// return Ok(())
|
|
||||||
// }
|
|
||||||
// for i in 0..retries {
|
|
||||||
// match device.connect().await {
|
|
||||||
// Ok(()) => return Ok(()),
|
|
||||||
// Err(_) => {
|
|
||||||
// println!("connection error ({}), retry…", i);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Err(bluer::Error {
|
|
||||||
// kind: bluer::ErrorKind::ConnectionAttemptFailed,
|
|
||||||
// message: "all attempts fail".parse().unwrap(),
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async fn find_neopixel_service(device: &Device) -> bluer::Result<Option<Characteristic>> {
|
// async fn find_neopixel_service(device: &Device) -> bluer::Result<Option<Characteristic>> {
|
||||||
// let addr = device.address();
|
// let addr = device.address();
|
||||||
|
|
|
@ -1,16 +1,33 @@
|
||||||
use bluer::gatt::remote::Characteristic;
|
use std::fmt;
|
||||||
|
|
||||||
const BASE_STRIP_DATA : [u8; 5] = [0x0, 0x0, 0x0, 0x0, 0x1];
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct PixelColor {
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub(crate) struct PixelColor {
|
|
||||||
pub(crate) red: u8,
|
pub(crate) red: u8,
|
||||||
pub(crate) green: u8,
|
pub(crate) green: u8,
|
||||||
pub(crate) blue: u8,
|
pub(crate) blue: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PixelColor {
|
||||||
|
fn new() -> Self {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct Strip<const N: usize> {
|
impl fmt::Display for PixelColor {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "[{},{},{}]", self.red, self.green, self.blue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PixelColor {
|
||||||
|
fn default() -> Self {
|
||||||
|
PixelColor { red: 0, green: 0, blue: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Strip<const N: usize> {
|
||||||
pub strip: [PixelColor; N],
|
pub strip: [PixelColor; N],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,9 +42,56 @@ impl<const N: usize> Strip<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn write_strip<const N: usize>(data: Strip<N>, char: Characteristic) -> bluer::Result<()> {
|
impl<const N: usize> Default for Strip<N> {
|
||||||
let mut frame= BASE_STRIP_DATA.to_vec();
|
fn default() -> Self {
|
||||||
frame.append(&mut data.to_array());
|
Strip { strip: [PixelColor::new(); N] }
|
||||||
char.write(&*frame).await?;
|
}
|
||||||
Ok(())
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub struct RainbowPattern<const N: usize> {
|
||||||
|
pub(crate) current_iteration: usize,
|
||||||
|
pub(crate) max_iteration: Option<usize>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<const N: usize> Iterator for RainbowPattern<N> {
|
||||||
|
type Item = Strip<N>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if let Some(nbr_iteration) = self.max_iteration {
|
||||||
|
if nbr_iteration == self.current_iteration {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut strip = Strip::default();
|
||||||
|
let step = 255 / N;
|
||||||
|
for i in 0..N {
|
||||||
|
let pos = (i*step + self.current_iteration) as u8;
|
||||||
|
strip.strip[i] = wheel(pos)
|
||||||
|
}
|
||||||
|
self.current_iteration = self.current_iteration +1 ;
|
||||||
|
Some(strip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wheel(index: u8) -> PixelColor {
|
||||||
|
let pos = 255 - index;
|
||||||
|
match pos {
|
||||||
|
0..=85 => PixelColor{
|
||||||
|
red: 255 - (pos * 3),
|
||||||
|
green :0,
|
||||||
|
blue : pos * 3},
|
||||||
|
86..=170 => {
|
||||||
|
let pos = pos - 85;
|
||||||
|
PixelColor{
|
||||||
|
red: 0,
|
||||||
|
green :pos*3,
|
||||||
|
blue : 255 - (pos * 3)}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let pos = pos - 170;
|
||||||
|
return PixelColor{red : pos*3, green : 255 - (pos*3), blue : 0};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user