lci_gateway/
dimmer.rs

1use super::{common, DeviceType, Thing};
2use thiserror::Error;
3
4/// A connected light that can go between 0 and 100 percent brightness.
5pub struct Dimmer {
6    thing: Thing,
7}
8
9impl Dimmer {
10    /// Create a new Dimmer from a generic "Thing". LCI gateway must publish the type as a Dimmer.
11    pub fn new(thing: Thing) -> Result<Self, DimmerError> {
12        let thing_type = thing.get_type();
13        if thing_type == Some(DeviceType::Dimmer) {
14            Ok(Self { thing })
15        } else {
16            Err(DimmerError::InvalidDeviceType(thing_type))
17        }
18    }
19
20    /// Returns the label of the device such as "Kitchen Lights".
21    pub fn label(&self) -> String {
22        self.thing.label().clone()
23    }
24
25    /// Returns the device's online state.
26    pub async fn online(&self) -> Result<common::OnlineState, common::OnlineStateConversionError> {
27        common::get_online_state(&self.thing).await
28    }
29
30    /// Returns the dimmer's brightness level.
31    pub async fn brightness(&self) -> Result<common::Percentage, DimmerBrightnessError> {
32        let string = common::get_field(&self.thing, "dimmer")
33            .await
34            .map_err(DimmerBrightnessError::GetFailure)?;
35        let val = string
36            .parse::<u8>()
37            .map_err(|e| DimmerBrightnessError::Parse(string, e))?;
38        Ok(common::Percentage::new(val))
39    }
40
41    /// Turns on the dimmer to 100%
42    pub async fn on(&mut self) -> Result<(), common::SetError> {
43        common::set_field(&mut self.thing, "dimmer", "ON".to_string()).await?;
44        Ok(())
45    }
46
47    /// Turns off the dimmer and sets to 0%
48    pub async fn off(&mut self) -> Result<(), common::SetError> {
49        common::set_field(&mut self.thing, "dimmer", "OFF".to_string()).await?;
50        Ok(())
51    }
52
53    /// Turns on the dimmer and sets the brightness between 0 and 100.
54    pub async fn set_brightness(&mut self, brightness: u8) -> Result<(), SetBrightnessError> {
55        if brightness > 100 {
56            return Err(SetBrightnessError::InvalidValue(brightness));
57        }
58        common::set_field(&mut self.thing, "dimmer", brightness.to_string()).await?;
59        Ok(())
60    }
61}
62
63/// Returned when a Dimmer can not be made from the given "thing".
64#[derive(Debug, Error)]
65pub enum DimmerError {
66    /// Returned when the "thing" is not a dimmer.
67    #[error("The device type {0:?} is not a dimmer.")]
68    InvalidDeviceType(Option<DeviceType>),
69}
70
71/// Returned when getting the brightness fails.
72#[derive(Debug, Error)]
73pub enum DimmerBrightnessError {
74    /// The LCI gateway could not be reached.
75    #[error("The LCI gateway could not be reached. {0}")]
76    GetFailure(common::GetFailure),
77    /// The response from the LCI gateway could not be parsed.
78    #[error("The response from the LCI gateway could not be parsed, {1}")]
79    Parse(String, std::num::ParseIntError),
80}
81
82/// The brightness of the dimmer could not be set.
83#[derive(Debug, Error)]
84pub enum SetBrightnessError {
85    /// The given value is not between 0 and 100
86    #[error("Supplied brightness {0} is not between 0 and 100.")]
87    InvalidValue(u8),
88    /// The LCI gateway request failed.
89    #[error("The set command failed to process. {0}")]
90    SetError(common::SetError),
91}
92
93impl From<common::SetError> for SetBrightnessError {
94    fn from(error: common::SetError) -> Self {
95        Self::SetError(error)
96    }
97}