94 lines
2.8 KiB
Rust
94 lines
2.8 KiB
Rust
use btleplug::Result;
|
|
use btleplug::api::{Central, Manager as _, Peripheral as _, ScanFilter, WriteType};
|
|
use btleplug::platform::{Adapter, Manager, Peripheral};
|
|
use std::error::Error;
|
|
use uuid::{Uuid, uuid};
|
|
|
|
const FIRMWARE_VERSION_UUID: Uuid = uuid!("00002a26-0000-1000-8000-00805f9b34fb");
|
|
const BATTERY_LEVEL_UUID: Uuid = uuid!("00002a19-0000-1000-8000-00805f9b34fb");
|
|
const HEART_RATE_UUID: Uuid = uuid!("00002a37-0000-1000-8000-00805f9b34fb");
|
|
const NOTIFICATION_UUID: Uuid = uuid!("00002a37-0000-1000-8000-00805f9b34fb");
|
|
|
|
pub enum NotificationCategory {
|
|
SimpleAlert,
|
|
Email,
|
|
News,
|
|
CallNotification,
|
|
MissedCall,
|
|
SMS,
|
|
Voicemail,
|
|
Schedule,
|
|
HighPrioritizedAlert,
|
|
InstantMessage,
|
|
}
|
|
pub struct Notification {
|
|
category: NotificationCategory,
|
|
title: String,
|
|
body: String,
|
|
}
|
|
impl Notification {
|
|
fn new(category: NotificationCategory, title: String, body: String) -> Notification {
|
|
return Self {
|
|
category: category,
|
|
title: title,
|
|
body: body,
|
|
};
|
|
}
|
|
}
|
|
|
|
pub async fn find_infinitime(adapter: &Adapter) -> Option<Peripheral> {
|
|
for p in adapter.peripherals().await.unwrap() {
|
|
if p.properties()
|
|
.await
|
|
.unwrap()
|
|
.unwrap()
|
|
.local_name
|
|
.iter()
|
|
.any(|name| name.to_lowercase().contains("infinitime"))
|
|
{
|
|
return Some(p);
|
|
}
|
|
}
|
|
return None;
|
|
}
|
|
|
|
async fn get_property_value(infinitime: &Peripheral, property: Uuid) -> Vec<u8> {
|
|
let chars = infinitime.characteristics();
|
|
let cmd_char = chars.iter().find(|c| c.uuid == property).unwrap();
|
|
let result = infinitime.read(cmd_char).await.unwrap();
|
|
|
|
return result;
|
|
}
|
|
|
|
pub async fn get_firmware_version(infinitime: &Peripheral) -> String {
|
|
let data = get_property_value(infinitime, FIRMWARE_VERSION_UUID).await;
|
|
return String::from_utf8(data).expect("Found invalid UTF-8");
|
|
}
|
|
pub async fn get_battery_level(infinitime: &Peripheral) -> String {
|
|
let data = get_property_value(infinitime, BATTERY_LEVEL_UUID).await;
|
|
let percent = data[0];
|
|
return percent.to_string();
|
|
}
|
|
pub async fn get_heart_rate(infinitime: &Peripheral) -> String {
|
|
let data = get_property_value(infinitime, HEART_RATE_UUID).await;
|
|
let rate = data[1];
|
|
return rate.to_string();
|
|
}
|
|
pub async fn send_notification(infinitime: &Peripheral, notification: Notification) {
|
|
let chars = infinitime.characteristics();
|
|
let cmd_char = chars.iter().find(|c| c.uuid == NOTIFICATION_UUID).unwrap();
|
|
infinitime
|
|
.write(
|
|
cmd_char,
|
|
&[
|
|
&[0, 1],
|
|
notification.title.as_bytes(),
|
|
notification.body.as_bytes(),
|
|
]
|
|
.join(&0),
|
|
WriteType::WithoutResponse,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
}
|