tradfri_rs/
device.rs

1use std::sync::Arc;
2
3use anyhow::Result;
4use serde::{de, Deserialize, Serialize};
5use serde_json::json;
6use serde_repr::{Deserialize_repr, Serialize_repr};
7
8use crate::gateway::Gateway;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub enum BulbTemperature {
12    #[serde(rename = "f5faf6")]
13    White,
14    #[serde(rename = "f1e0b5")]
15    Warm,
16    #[serde(rename = "efd275")]
17    Glow,
18}
19
20#[derive(Clone, Debug, Serialize_repr, Deserialize_repr)]
21#[repr(u8)]
22pub enum DeviceState {
23    On = 1,
24    Off = 0,
25}
26
27#[derive(Clone, Debug, Serialize, Deserialize)]
28pub struct BulbData {
29    #[serde(rename = "5850")]
30    pub status: DeviceState,
31    #[serde(rename = "5706")]
32    pub temperature: BulbTemperature,
33}
34
35#[derive(Debug, Serialize, Deserialize)]
36pub struct Device<'a> {
37    #[serde(rename = "9003")]
38    pub id: u64,
39    #[serde(rename = "9001")]
40    pub name: String,
41    #[serde(deserialize_with = "flatten_bulb_data")]
42    #[serde(rename = "3311")]
43    pub data: BulbData,
44    #[serde(skip)]
45    gateway: Option<Arc<&'a Gateway>>,
46}
47
48impl<'a> Device<'a> {
49    pub(crate) fn set_gateway(&mut self, gateway: Arc<&'a Gateway>) {
50        self.gateway = Some(Arc::clone(&gateway))
51    }
52
53    pub fn turn_on(&self) -> Result<()> {
54        self.modify(BulbData {
55            status: DeviceState::On,
56            ..self.data.clone()
57        })
58    }
59
60    pub fn turn_off(&self) -> Result<()> {
61        self.modify(BulbData {
62            status: DeviceState::Off,
63            ..self.data.clone()
64        })
65    }
66
67    fn modify(&self, data: BulbData) -> Result<()> {
68        let gateway = self.gateway.clone().unwrap();
69        let gateway = gateway.as_ref();
70
71        let res = gateway.set_device_state(self.id, json!({ "3311": [data] }));
72
73        res
74    }
75}
76
77fn flatten_bulb_data<'de, D>(deserializer: D) -> Result<BulbData, D::Error>
78where
79    D: de::Deserializer<'de>,
80{
81    let vec: Vec<serde_json::Value> = de::Deserialize::deserialize(deserializer)?;
82    let value = vec.into_iter().nth(0).unwrap();
83    serde_json::from_value(value).map_err(de::Error::custom)
84}