Crates.io | ble-ledly |
lib.rs | ble-ledly |
version | 0.3.0 |
source | src |
created_at | 2022-07-19 21:45:02.716672 |
updated_at | 2022-07-27 08:47:38.179731 |
description | A customizable and extensible cross-platform high-level Bluetooth Low Energy light controller. |
homepage | https://github.com/espressoshock/ble-ledly |
repository | https://github.com/espressoshock/ble-ledly |
max_upload_size | |
id | 628548 |
size | 1,910,145 |
Customizable and extensible cross-platform high-level Bluetooth Low Energy light controller.
Provides out-of-the-box support for generic RGB led strips and BLE lamps and light bulbs. Designed to be extensible, allows to implement your own devices, communication protocol or both (See the readme file for more). Supports hardware specific animations (transferrable) and software non-transferrable animations.
Each device supports multiple capabilities available as featurs through conditional compilation in the .toml file.
ble-ledly = {version = "0.3", features = ["all"]}
Each capability provides a single point access to a specific device characteristic that can be manipulated through the publicly available set()
method. All the methods are available through the standard API Capability::set(opts)
or through more idiomatic methods as follow.
// standard
Light::set(light, &protocol, &LightOption::On).await?;
// idiomatic syntactic sugar
light.turn_on(&protocol).await?;
Capability | Description | Implemented? |
---|---|---|
Light |
Light state (on/off) | ✅ |
Color |
Light Color (RGB) | ✅ |
Brightness |
Light white levels | ✅ |
HWAnimate |
Hardware specific animations (subjected to protocol) | ✅ |
SWAnimate |
Software animation (require continuous communication, but allows custom effect on any device) | ✅ |
Temperature |
Light temperature (K) |
Transferrable animations are built-in in the target ble device which takes care of driving the led(s); once the command is sent, no extra communication needed between the client and ble light controller. Non-transferrable animations bypass the controller's built-in effects and allow for higher degree of customization while providing support for legacy or cheap light controllers allowing to provide effects otherwise not available to the target device. As a consequence, this requires continuous connection between the controller and client.
Animation | Capability | Color Support | Implemented? |
---|---|---|---|
Pulsating | HWAnimate | Red/Green/Blue | ✅ |
Breathing | SWAnimate | RGB/Any | ✅ |
Rainbow Pulsating | HWAnimate | N/A | |
Pulsating Bicolor | HWAnimate | Red/Green, Red/Blue, Green/Blue | |
Rainbow flashing | HWAnimate | N/A | |
Cross-fade | SWAnimate | RGB/Any | |
Rainbow jumping | HWAnimate | N/A | |
Flashing | HWAnimate | Red, Green, Blue, Yellow, Purple, Cyan |
This library has been designed with extensibility in mind.
Device
trait and use the built-in communication protocol.Protocol
trait and use it to drive one of the built-in devices.device
and communication protocol
.An example using built-in device LedDevice and GenericRGB communication protocol. For more examples, see the examples folder.
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// Create a new Light controller with prefix
// Auto-filter devices that contain the prefix
let mut controller = Controller::<LedDevice>::new_with_prefix("QHM-").await?;
// Connect
controller.connect().await?;
// Choose your communication protocol
let protocol = GenericRGB::default();
// set default write characteristic for all connected
// devices
controller.set_all_char(&CharKind::Write, &UuidKind::Uuid16(0xFFD9))?;
// Setting first found light color to red
let first_light = controller.list().get(0).unwrap();
first_light.color(&protocol, 255, 0, 0).await?;
Ok(())
}
use ble_ledly::capability::color::*;
use ble_ledly::capability::light::*;
use ble_ledly::capability::sw_animate::*;
use ble_ledly::communication_protocol::GenericRGB;
use ble_ledly::Controller;
use ble_ledly::device::LedDevice;
use ble_ledly::device::{CharKind, UuidKind};
use std::error::Error;
use std::time::Duration;
use tokio::time;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// Create a new Light controller
let mut controller = Controller::<LedDevice>::new().await?;
// Discover devices (scan)
let led_devices = controller.device_discovery().await?;
// inspect all found devices
for device in led_devices.iter() {
println!("Found device: {}", device);
}
// filter devices
let lights: Vec<LedDevice> = led_devices
.into_iter()
.filter(|device| device.name.contains("QHM-"))
.collect();
// Connect
controller.connect_with_devices(lights).await?;
// Choose your communication protocol
let protocol = GenericRGB::default();
// set the default write Characteristic
// for all devices. Optionally you can also
// set it per-device. Look the examples folder for more
controller.set_all_char(&CharKind::Write, &UuidKind::Uuid16(0xFFD9))?;
// list all connected devices
let connected_lights = controller.list();
for light in connected_lights.iter_mut() {
println!("Connected to : {}", light.name);
// Control the lights
println!("Turning light on...");
light.turn_on(&protocol).await?;
// Set color
println!("Setting color...");
light.color(&protocol, 255, 0, 0).await?;
time::sleep(Duration::from_millis(800)).await;
light.color(&protocol, 0, 255, 0).await?;
time::sleep(Duration::from_millis(800)).await;
light.color(&protocol, 0, 0, 255).await?;
time::sleep(Duration::from_millis(800)).await;
println!("SW Animation - Breathing effect...");
light
.breathing(
&GenericRGB {},
&ColorOption::RGB(255, 0, 0),
&SWAnimationRepeat::FiniteCount(2),
&SWAnimationSpeed::Fastest,
)
.await?;
light
.breathing(
&GenericRGB {},
&ColorOption::RGB(0, 255, 0),
&SWAnimationRepeat::FiniteCount(2),
&SWAnimationSpeed::Fastest,
)
.await?;
light
.breathing(
&GenericRGB {},
&ColorOption::RGB(0, 0, 255),
&SWAnimationRepeat::FiniteCount(2),
&SWAnimationSpeed::Fastest,
)
.await?;
// Control the lights
println!("Turning light off...");
light.turn_off(&protocol).await?;
}
Ok(())
}
Open a PR or issue
MIT