mirror of
https://codeberg.org/icewind/mitemp-rs.git
synced 2026-06-03 17:24:08 +02:00
adjust to new btleplug
This commit is contained in:
parent
16cf74d09f
commit
b2e39d8893
2 changed files with 32 additions and 19 deletions
|
|
@ -7,9 +7,9 @@ description = "Read Xiaomi MI Temperature and Humidity Sensor over BLE"
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
btleplug = { version = "0.5.0", git = "https://github.com/icewind1991/btleplug", branch = "store-service-data" }
|
btleplug = { version = "0.7", git = "https://github.com/icewind1991/btleplug", branch = "unify-platform-api" }
|
||||||
num_enum = "0.4.2"
|
num_enum = "0.4"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
main_error = "0.1.0"
|
main_error = "0.1"
|
||||||
env_logger = "0.7.1"
|
env_logger = "0.7"
|
||||||
43
src/lib.rs
43
src/lib.rs
|
|
@ -1,11 +1,11 @@
|
||||||
pub use btleplug::api::BDAddr;
|
pub use btleplug::api::BDAddr;
|
||||||
use btleplug::api::{Central, CentralEvent, Peripheral};
|
use btleplug::api::{Central, CentralEvent, Peripheral};
|
||||||
use btleplug::bluez::adapter::ConnectedAdapter;
|
use btleplug::platform::{Adapter, Manager};
|
||||||
use btleplug::bluez::manager::Manager;
|
|
||||||
use num_enum::TryFromPrimitive;
|
use num_enum::TryFromPrimitive;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
/// Detected mitemp sensor and the data read from it
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Sensor {
|
pub struct Sensor {
|
||||||
pub mac: BDAddr,
|
pub mac: BDAddr,
|
||||||
|
|
@ -33,7 +33,10 @@ impl SensorRawData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn listen<P: Peripheral, A: Central<P> + 'static>(
|
/// Listen for sensor data
|
||||||
|
///
|
||||||
|
/// Returns an iterator that will block waiting for new sensor data
|
||||||
|
pub fn listen<A: Central + 'static>(
|
||||||
adapter: A,
|
adapter: A,
|
||||||
) -> Result<impl Iterator<Item = Sensor>, btleplug::Error> {
|
) -> Result<impl Iterator<Item = Sensor>, btleplug::Error> {
|
||||||
let mut sensors: HashMap<BDAddr, SensorRawData> = HashMap::new();
|
let mut sensors: HashMap<BDAddr, SensorRawData> = HashMap::new();
|
||||||
|
|
@ -51,13 +54,13 @@ pub fn listen<P: Peripheral, A: Central<P> + 'static>(
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.flat_map(move |bd_addr| {
|
.filter_map(move |bd_addr| adapter.peripheral(bd_addr))
|
||||||
let peripheral = adapter.peripheral(bd_addr).unwrap();
|
.flat_map(|peripheral| {
|
||||||
peripheral
|
peripheral
|
||||||
.properties()
|
.properties()
|
||||||
.service_data
|
.service_data
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(move |(_, data)| (bd_addr, data))
|
.map(move |(_, data)| (peripheral.address(), data))
|
||||||
})
|
})
|
||||||
.filter_map(|(bd_addr, data)| Some((bd_addr, parse_advertising_data(&data).ok()?)))
|
.filter_map(|(bd_addr, data)| Some((bd_addr, parse_advertising_data(&data).ok()?)))
|
||||||
.map(move |(bd_addr, update)| {
|
.map(move |(bd_addr, update)| {
|
||||||
|
|
@ -70,10 +73,17 @@ pub fn listen<P: Peripheral, A: Central<P> + 'static>(
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Collected data from a sensor
|
||||||
|
///
|
||||||
|
/// Because not all data is emitted at the same time, some fields might not be populated yet
|
||||||
|
/// in which case they are set to 0
|
||||||
#[derive(Default, Clone, Debug)]
|
#[derive(Default, Clone, Debug)]
|
||||||
pub struct SensorData {
|
pub struct SensorData {
|
||||||
|
/// Battery percentage
|
||||||
pub battery: u8,
|
pub battery: u8,
|
||||||
|
/// Temperature in °C
|
||||||
pub temperature: f32,
|
pub temperature: f32,
|
||||||
|
/// Humidity in %H
|
||||||
pub humidity: f32,
|
pub humidity: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,16 +97,19 @@ impl From<SensorRawData> for SensorData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn adapter_by_mac(addr: BDAddr) -> Result<ConnectedAdapter, btleplug::Error> {
|
pub fn adapter_by_mac(addr: BDAddr) -> Result<Adapter, btleplug::Error> {
|
||||||
let manager = Manager::new()?;
|
let manager = Manager::new()?;
|
||||||
let adapters = manager.adapters()?;
|
manager
|
||||||
|
.adapters()?
|
||||||
let adapter = adapters
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|adapter| adapter.addr == addr)
|
.find(|adapter| {
|
||||||
.ok_or(btleplug::Error::DeviceNotFound)?;
|
adapter
|
||||||
|
.address()
|
||||||
adapter.connect()
|
.ok()
|
||||||
|
.filter(|adapter_addr| *adapter_addr == addr)
|
||||||
|
.is_some()
|
||||||
|
})
|
||||||
|
.ok_or(btleplug::Error::DeviceNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, TryFromPrimitive, Clone, Copy)]
|
#[derive(Debug, Eq, PartialEq, TryFromPrimitive, Clone, Copy)]
|
||||||
|
|
@ -120,7 +133,7 @@ struct InvalidServiceData;
|
||||||
|
|
||||||
fn parse_advertising_data(service_data: &[u8]) -> Result<SensorUpdate, InvalidServiceData> {
|
fn parse_advertising_data(service_data: &[u8]) -> Result<SensorUpdate, InvalidServiceData> {
|
||||||
let sensor_type = &service_data[1..4];
|
let sensor_type = &service_data[1..4];
|
||||||
if sensor_type != &[0x20, 0xaa, 0x01] {
|
if sensor_type != [0x20, 0xaa, 0x01] {
|
||||||
return Err(InvalidServiceData);
|
return Err(InvalidServiceData);
|
||||||
}
|
}
|
||||||
let sensor_type = SensorType::try_from(service_data[11]).map_err(|_| InvalidServiceData)?;
|
let sensor_type = SensorType::try_from(service_data[11]).map_err(|_| InvalidServiceData)?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue