| Crates.io | ohea-lock |
| lib.rs | ohea-lock |
| version | 0.1.0 |
| created_at | 2026-01-08 02:50:58.828882+00 |
| updated_at | 2026-01-08 02:50:58.828882+00 |
| description | Rust library for controlling Ohea Lock BLE smart locks |
| homepage | https://github.com/v-vx/ohea-lock |
| repository | https://github.com/v-vx/ohea-lock |
| max_upload_size | |
| id | 2029437 |
| size | 138,083 |
A Rust library for controlling Ohea Lock BLE smart locks.
btleplug support for desktop platforms[dependencies]
ohea-lock = { version = "0.1", features = ["btleplug-support"] }
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
Complete example: discover → connect → pair → control lock
use ohea_lock::{BtleplugTransport, OheaLock, Result};
use btleplug::api::{Central, Manager as _, Peripheral as _, ScanFilter};
use btleplug::platform::Manager;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<()> {
// 1. Get Bluetooth adapter
let manager = Manager::new().await?;
let adapter = manager
.adapters()
.await?
.into_iter()
.next()
.expect("No Bluetooth adapter found");
// 2. Scan for devices
println!("Scanning for Ohea Lock...");
adapter.start_scan(ScanFilter::default()).await?;
tokio::time::sleep(Duration::from_secs(5)).await;
adapter.stop_scan().await?;
// 3. Find Ohea Lock device
let peripheral = adapter
.peripherals()
.await?
.into_iter()
.filter(|p| {
futures::executor::block_on(async {
p.properties()
.await
.ok()
.flatten()
.and_then(|props| props.local_name)
.is_some_and(|name| name == "Ohea Lock")
})
})
.next()
.expect("Ohea Lock not found");
// 4. Connect and discover services (triggers pairing on first connection)
println!("Connecting...");
let transport = BtleplugTransport::connect_and_discover(peripheral).await?;
let mut lock = OheaLock::new(transport);
// 5. Initialize session
lock.initialize().await?;
// 6. Get device information
let info = lock.get_device_info().await?;
println!("Device: {}", info.name);
println!("Firmware: {}", info.firmware_version);
println!("Battery: {}%", info.battery_level);
// 7. Read lock state
let state = lock.get_lock_state().await?;
println!("Lock state: {:?}", state);
// 8. Control the lock
println!("Unlocking...");
lock.unlock().await?;
tokio::time::sleep(Duration::from_secs(2)).await;
println!("Locking...");
lock.lock().await?;
println!("Done!");
Ok(())
}
// Create lock instance
let lock = OheaLock::new(transport);
// Initialize (required after first connection)
lock.initialize().await?;
// Lock control
lock.lock().await?;
lock.unlock().await?;
let state = lock.get_lock_state().await?; // LockState::Locked | LockState::Unlocked
// Device info
let info = lock.get_device_info().await?; // DeviceInfo { name, firmware_version, battery_level }
let battery = lock.get_battery_level().await?; // u8 (0-100)
let firmware = lock.get_firmware_version().await?; // String
// Notifications
lock.subscribe_lock_state().await?;
lock.subscribe_battery_level().await?;
lock.unsubscribe_all().await?;
# Unit tests
cargo test --features btleplug-support
For hardware debugging and interactive testing:
cargo run --example debug --features btleplug-support
GPL-3.0