-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: one put call per connection, simplify types
Sending multiple PUT requests to the same coap connection does not work with the gateway where multiple GET requests works. Also reduces the type complexity in the library.
- Loading branch information
Showing
7 changed files
with
419 additions
and
364 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,46 @@ | ||
use tradfri_gateway::{Device, TradfriGatewayConnector}; | ||
use tradfri_gateway::{Device, TradfriGateway}; | ||
|
||
fn main() { | ||
fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
// Connect with gateway code | ||
let gateway_code = "enter gateway code from the underside of your TRÅDFRI gateway"; | ||
let mut gateway = TradfriGatewayConnector::from_gateway_code(gateway_code) | ||
.unwrap() | ||
.connect() | ||
.unwrap(); | ||
let mut gateway = TradfriGateway::from_gateway_code(gateway_code)?; | ||
println!("{:#?}", gateway); | ||
|
||
// Connect with identifier and session key | ||
// Connect with identifier and session key once created | ||
// let session_key = "enter pre shared key generated from gateway code"; | ||
// let identifier = "enter identifier generated along with the pre shared key"; | ||
// let mut gateway = | ||
// TradfriGatewayConnector::from_identifier_and_session_key(identifier, session_key) | ||
// .unwrap() | ||
// .connect() | ||
// .unwrap(); | ||
// TradfriGateway::from_identifier_and_session_key(identifier, session_key)?; | ||
// println!("{:#?}", gateway); | ||
|
||
// Get all device ids | ||
let ids = gateway.device_ids().unwrap(); | ||
println!("ids {:#?}", ids); | ||
|
||
// Turn on all your lights | ||
for id in ids { | ||
let device = gateway.device(id).unwrap(); | ||
println!("device {:#?}", device); | ||
// Toggle all your lights | ||
for i in 0..10 { | ||
for device in gateway.devices()? { | ||
match device { | ||
Ok(Device::RemoteControl) => (), | ||
Ok(Device::Light(mut light)) => { | ||
if i % 2 == 0 { | ||
light.on()?; | ||
} else { | ||
light.off()?; | ||
} | ||
println!("light {:#?}", light); | ||
} | ||
Err(error) => panic!("{}", error), | ||
} | ||
} | ||
} | ||
|
||
match device { | ||
Device::RemoteControl => (), | ||
Device::Light(mut light) => { | ||
light.on().unwrap(); | ||
println!("light {:#?}", light); | ||
// Turn on one specific light, if id exists | ||
for i in 0..10 { | ||
if let Ok(Device::Light(mut light)) = gateway.device(65568) { | ||
if i % 2 == 0 { | ||
light.on()?; | ||
} else { | ||
light.off()?; | ||
} | ||
} | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
use chrono::{DateTime, NaiveDateTime, TimeZone, Utc}; | ||
|
||
use crate::{ | ||
tradfri_coap::TradfriConnection, BulbColdWarmHexUpdate, BulbParsed, BulbRgbXYUpdate, | ||
BulbUpdate, Device, DeviceError, DeviceInfoParsed, DriverUpdate, LightDeviceParsed, | ||
TradfriGateway, Update, | ||
}; | ||
|
||
#[derive(Debug)] | ||
pub struct Light { | ||
gateway: TradfriGateway, | ||
info: DeviceInfoParsed, | ||
id: u32, | ||
name: String, | ||
creation_date: DateTime<Utc>, | ||
last_seen: DateTime<Utc>, | ||
reachable: bool, | ||
bulbs: Vec<BulbParsed>, | ||
} | ||
|
||
impl Light { | ||
pub fn new(gateway: TradfriGateway, bytes: &[u8]) -> Result<Self, DeviceError> { | ||
let parsed: LightDeviceParsed = match serde_json::from_slice(bytes) { | ||
Ok(p) => p, | ||
Err(error) => { | ||
return Err(DeviceError::SerdeError( | ||
error.to_string(), | ||
String::from_utf8_lossy(bytes).to_string(), | ||
)) | ||
} | ||
}; | ||
|
||
Ok(Self { | ||
gateway, | ||
info: parsed.info, | ||
id: parsed.id, | ||
name: parsed.name, | ||
creation_date: Utc.from_utc_datetime( | ||
&NaiveDateTime::from_timestamp_opt(parsed.creation_date.into(), 0).unwrap(), | ||
), | ||
last_seen: Utc.from_utc_datetime( | ||
&NaiveDateTime::from_timestamp_opt(parsed.last_seen.into(), 0).unwrap(), | ||
), | ||
reachable: parsed.reachable, | ||
bulbs: parsed.bulbs, | ||
}) | ||
} | ||
|
||
pub fn on(&mut self) -> Result<(), DeviceError> { | ||
let update = Update::BulbUpdate { | ||
bulbs: self | ||
.bulbs | ||
.iter() | ||
.map(|bulb| match bulb { | ||
BulbParsed::LedDriver(_) => BulbUpdate::DriverUpdate(DriverUpdate { | ||
on: Some(true), | ||
..Default::default() | ||
}), | ||
BulbParsed::BulbColdWarmHex(_) => { | ||
BulbUpdate::BulbColdWarmHexUpdate(BulbColdWarmHexUpdate { | ||
on: Some(true), | ||
..Default::default() | ||
}) | ||
} | ||
BulbParsed::BulbRgbXY(_) => BulbUpdate::BulbRgbXYUpdate(BulbRgbXYUpdate { | ||
on: Some(true), | ||
..Default::default() | ||
}), | ||
}) | ||
.collect(), | ||
}; | ||
|
||
let mut connection = self.gateway.create_connection()?; | ||
self.gateway | ||
.update_device(self.id, &update, Some(&mut connection))?; | ||
self.update_with_connection(&mut connection)?; | ||
|
||
Ok(()) | ||
} | ||
|
||
pub fn off(&mut self) -> Result<(), DeviceError> { | ||
let update = Update::BulbUpdate { | ||
bulbs: self | ||
.bulbs | ||
.iter() | ||
.map(|bulb| match bulb { | ||
BulbParsed::LedDriver(_) => BulbUpdate::DriverUpdate(DriverUpdate { | ||
on: Some(false), | ||
..Default::default() | ||
}), | ||
BulbParsed::BulbColdWarmHex(_) => { | ||
BulbUpdate::BulbColdWarmHexUpdate(BulbColdWarmHexUpdate { | ||
on: Some(false), | ||
..Default::default() | ||
}) | ||
} | ||
BulbParsed::BulbRgbXY(_) => BulbUpdate::BulbRgbXYUpdate(BulbRgbXYUpdate { | ||
on: Some(false), | ||
..Default::default() | ||
}), | ||
}) | ||
.collect(), | ||
}; | ||
|
||
let mut connection = self.gateway.create_connection()?; | ||
self.gateway | ||
.update_device(self.id, &update, Some(&mut connection))?; | ||
self.update_with_connection(&mut connection)?; | ||
|
||
Ok(()) | ||
} | ||
|
||
pub fn is_on(&self) -> bool { | ||
self.bulbs | ||
.iter() | ||
.fold(0, |acc, b| acc + if b.is_on() { 1 } else { 0 }) | ||
> 0 | ||
} | ||
|
||
pub fn update(&mut self) -> Result<(), DeviceError> { | ||
let mut connection = self.gateway.create_connection()?; | ||
self.update_with_connection(&mut connection) | ||
} | ||
|
||
fn update_with_connection( | ||
&mut self, | ||
connection: &mut TradfriConnection, | ||
) -> Result<(), DeviceError> { | ||
let device = self.gateway.device_with_connection(self.id, connection)?; | ||
|
||
if let Device::Light(light) = device { | ||
self.info = light.info; | ||
self.id = light.id; | ||
self.name = light.name; | ||
self.creation_date = light.creation_date; | ||
self.last_seen = light.last_seen; | ||
self.reachable = light.reachable; | ||
self.bulbs = light.bulbs; | ||
} else { | ||
return Err(DeviceError::ExpectedDeviceType("Light".to_string())); | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
Oops, something went wrong.