hive_client/client/api/
devices.rs

1use std::collections::HashMap;
2
3use crate::client::api::error::ApiError;
4use crate::client::api::HiveApi;
5use crate::client::authentication::Tokens;
6use crate::helper::url::{get_base_url, Url};
7use chrono::{serde::ts_milliseconds, DateTime, Utc};
8use serde::Deserialize;
9use serde_json::Value;
10
11#[derive(Deserialize, Debug)]
12#[serde(rename_all = "lowercase")]
13#[allow(missing_docs)]
14pub enum PowerType {
15    /// The device is powered by an internal battery.
16    Battery,
17
18    /// The device is connected directly to the mains power supply.
19    Mains,
20}
21
22#[derive(Deserialize, Debug)]
23#[non_exhaustive]
24#[allow(missing_docs)]
25pub struct Properties {
26    #[serde(rename = "online")]
27    /// Whether the device is currently online or not.
28    pub is_online: bool,
29
30    /// The type of power source used by the device (if applicable).
31    pub power: Option<PowerType>,
32
33    #[serde(rename = "battery")]
34    /// The battery percentage of the device (if applicable).
35    pub battery_percentage: Option<i32>,
36
37    #[serde(rename = "zone")]
38    /// The ID of the zone the device is located in (if applicable).
39    pub zone_id: Option<String>,
40
41    #[serde(flatten)]
42    #[allow(missing_docs)]
43    pub extra: HashMap<String, Value>,
44}
45
46#[derive(Deserialize, Debug)]
47#[serde(rename_all = "camelCase")]
48#[non_exhaustive]
49#[allow(missing_docs)]
50pub struct State {
51    /// The name of the device.
52    pub name: String,
53
54    /// The name of the zone the device is located in (if applicable).
55    pub zone_name: Option<String>,
56}
57
58#[derive(Deserialize, Debug)]
59#[serde(rename_all = "camelCase")]
60#[non_exhaustive]
61/// A [Hive Thermostat](https://www.hivehome.com/shop/smart-heating/hive-thermostat).
62pub struct Thermostat {
63    /// The unique ID of the Thermostat.
64    pub id: String,
65
66    #[serde(with = "ts_milliseconds")]
67    /// The date and time the Thermostat last communicated with the Hub.
68    pub last_seen: DateTime<Utc>,
69
70    #[serde(with = "ts_milliseconds")]
71    #[serde(rename = "created")]
72    /// The date and time when the Thermostat was first created.
73    pub created_at: DateTime<Utc>,
74
75    #[serde(rename = "props")]
76    /// The properties of the Thermostat.
77    pub properties: Properties,
78
79    /// The current state of the Thermostat.
80    pub state: State,
81
82    #[serde(flatten)]
83    #[allow(missing_docs)]
84    pub extra: HashMap<String, Value>,
85}
86
87#[derive(Deserialize, Debug)]
88#[serde(rename_all = "camelCase")]
89#[non_exhaustive]
90/// A [Hive Hub](https://www.hivehome.com/shop/smart-home/hive-hub).
91pub struct Hub {
92    /// The unique ID of the Hub.
93    pub id: String,
94
95    #[serde(with = "ts_milliseconds")]
96    /// The date and time the Hub last communicated with the Hive servers.
97    pub last_seen: DateTime<Utc>,
98
99    #[serde(with = "ts_milliseconds")]
100    #[serde(rename = "created")]
101    /// The date and time when the Hub was first created.
102    pub created_at: DateTime<Utc>,
103
104    #[serde(rename = "props")]
105    /// The properties of the Hub.
106    pub properties: Properties,
107
108    /// The current state of the Hub.
109    pub state: State,
110
111    #[serde(flatten)]
112    #[allow(missing_docs)]
113    pub extra: HashMap<String, Value>,
114}
115
116#[derive(Deserialize, Debug)]
117#[serde(rename_all = "camelCase")]
118#[non_exhaustive]
119/// A Hive Boiler Module.
120pub struct BoilerModule {
121    /// The unique ID of the Boiler Module.
122    pub id: String,
123
124    #[serde(with = "ts_milliseconds")]
125    /// The date and time the Boiler Module last communicated with the Hub.
126    pub last_seen: DateTime<Utc>,
127
128    #[serde(with = "ts_milliseconds")]
129    #[serde(rename = "created")]
130    /// The date and time when the Boiler Module was first created.
131    pub created_at: DateTime<Utc>,
132
133    #[serde(rename = "props")]
134    /// The properties of the Boiler Module.
135    pub properties: Properties,
136
137    /// The current state of the Boiler Module.
138    pub state: State,
139
140    #[serde(flatten)]
141    #[allow(missing_docs)]
142    pub extra: HashMap<String, Value>,
143}
144
145#[derive(Deserialize, Debug)]
146#[serde(rename_all = "lowercase")]
147#[serde(tag = "type")]
148#[non_exhaustive]
149#[allow(missing_docs)]
150pub enum DeviceData {
151    #[serde(rename = "thermostatui")]
152    /// A [Hive Thermostat](https://www.hivehome.com/shop/smart-heating/hive-thermostat).
153    Thermostat(Thermostat),
154
155    /// A [Hive Hub](https://www.hivehome.com/shop/smart-home/hive-hub).
156    Hub(Hub),
157
158    /// A Hive Boiler Module.
159    BoilerModule(BoilerModule),
160
161    #[serde(other)]
162    /// A device which is yet to be mapped by the crate.
163    Unknown,
164}
165
166/// A Device setup in a Hive account.
167///
168/// For example, a [`DeviceData::Thermostat`], a [`DeviceData::Hub`], etc.
169#[derive(Debug)]
170pub struct Device {
171    #[allow(missing_docs)]
172    pub data: DeviceData,
173}
174
175impl Device {
176    pub(crate) const fn new(data: DeviceData) -> Self {
177        Self { data }
178    }
179}
180
181impl HiveApi {
182    pub(crate) async fn get_devices(&self, tokens: &Tokens) -> Result<Vec<DeviceData>, ApiError> {
183        let response = self
184            .client
185            .get(get_base_url(&Url::Device))
186            .header("Authorization", &tokens.id_token)
187            .send()
188            .await;
189
190        let body = response?.text().await?;
191
192        Ok(serde_json::from_str(&body)?)
193    }
194}