govee_api/api/api.rs
1use reqwest::Error as ReqwestError;
2use reqwest::{Client, Url};
3use serde_json::json;
4
5use crate::{
6 structs::govee::{
7 ApiResponseGoveeAppliances, ApiResponseGoveeDeviceState, ApiResponseGoveeDevices,
8 PayloadBody,
9 },
10 GoveeClient, GOVEE_ROOT_URL,
11};
12
13// ------------------------
14// Methods for the Govee API
15// ------------------------
16//
17
18/// Control a Govee device using the provided payload.
19///
20/// This method sends a PUT request to the Govee API's control endpoint in order to control a Govee device.
21///
22/// # Arguments
23///
24/// * `payload` - The payload containing control instructions for the device.
25///
26/// # Returns
27///
28/// Returns `Ok(())` if the request is successful. Otherwise, returns a `ReqwestError` indicating the failure
29impl GoveeClient {
30 pub async fn control_device(&self, payload: PayloadBody) -> Result<(), ReqwestError> {
31 let client = Client::new();
32 let payload_json = json!(payload);
33 let endpoint = format!("{}/v1/devices/control", &self.govee_root_url);
34 let result = client
35 .put(endpoint)
36 .header("Govee-API-Key", &self.govee_api_key.to_string())
37 .json(&payload_json)
38 .send()
39 .await;
40 match result {
41 Ok(res) => res,
42 Err(err) => return Err(err),
43 };
44 Ok(())
45 }
46}
47
48/// Asynchronously controls multiple devices by sending payloads to the Govee API.
49///
50/// This method takes a vector of `PayloadBody` objects and sends control requests to the Govee API
51/// for each payload asynchronously. It uses the provided `self.govee_api_key` and `self.govee_root_url`
52/// to construct the API endpoint for each request.
53///
54/// # Arguments
55///
56/// - `payloads`: A vector of `PayloadBody` objects representing the control payloads for the devices.
57///
58/// # Returns
59///
60/// Returns a `Result` indicating success or an error that occurred during the requests.
61///
62/// # Examples
63///
64/// let govee_client = GoveeClient::new("your_api_key", "https://api.govee.com");
65/// let payloads = vec![payload1, payload2];
66/// let result = govee_client.bulk_control_devices(payloads).await;
67/// match result {
68/// Ok(_) => println!("Devices controlled successfully"),
69/// Err(err) => eprintln!("Error controlling devices: {:?}", err),
70/// }
71///
72impl GoveeClient {
73 pub async fn bulk_control_devices(
74 &self,
75 payloads: Vec<PayloadBody>,
76 ) -> Result<(), ReqwestError> {
77 let client = Client::new();
78 let endpoint = format!("{}/v1/devices/control", &self.govee_root_url);
79 let requests = payloads
80 .iter()
81 .map(|payload| {
82 let payload_json = json!(payload);
83 let endpoint = endpoint.clone();
84 let govee_api_key = self.govee_api_key.to_string();
85 let client = client.clone();
86 async move {
87 client
88 .put(&endpoint)
89 .header("Govee-API-Key", &govee_api_key)
90 .json(&payload_json)
91 .send()
92 .await
93 }
94 })
95 .collect::<Vec<_>>();
96 let results = futures::future::join_all(requests).await;
97 for result in results {
98 match result {
99 Ok(_) => (),
100 Err(err) => return Err(err),
101 }
102 }
103 Ok(())
104 }
105}
106
107/// Controls a Govee appliance using the provided payload.
108///
109/// This method sends a PUT request to the Govee API to control an appliance
110/// with the specified payload. The payload should be in the form of a PayloadBody struct.
111///
112/// # Arguments
113///
114/// * `payload` - The payload containing the control instructions for the appliance.
115///
116/// # Returns
117///
118/// Returns `Ok(())` if the request is successful. Otherwise, returns a `ReqwestError` indicating the failure
119impl GoveeClient {
120 pub async fn control_appliance(&self, payload: PayloadBody) -> Result<(), ReqwestError> {
121 let client = Client::new();
122 let payload_json = json!(payload);
123 let endpoint = format!("{}/v1/appliance/devices/control", GOVEE_ROOT_URL);
124 let result = client
125 .put(endpoint)
126 .header("Govee-API-Key", &self.govee_api_key)
127 .json(&payload_json)
128 .send()
129 .await;
130 match result {
131 Ok(res) => res,
132 Err(err) => return Err(err),
133 };
134 Ok(())
135 }
136}
137
138/// Retrieves a list of Govee devices.
139///
140/// This method sends a GET request to the Govee API to retrieve a list of devices
141/// associated with the Govee account.
142///
143/// # Returns
144///
145/// An `ApiResponseGoveeDevices` containing information about the devices.
146///
147/// # Returns
148///
149/// Returns `Ok(())` if the request is successful. Otherwise, returns a `ReqwestError` indicating the failure
150impl GoveeClient {
151 pub async fn get_devices(&self) -> Result<ApiResponseGoveeDevices, ReqwestError> {
152 let client = Client::new();
153 let endpoint = format!("{}/v1/devices", GOVEE_ROOT_URL);
154 let response = client
155 .get(endpoint)
156 .header("Govee-API-Key", &self.govee_api_key)
157 .send()
158 .await?;
159 let response_json = response.json::<ApiResponseGoveeDevices>().await?;
160 Ok(response_json)
161 }
162}
163
164/// Retrieves a list of Govee appliances.
165///
166/// This method sends a GET request to the Govee API to retrieve a list of appliances
167/// associated with the Govee account.
168///
169/// # Returns
170///
171/// An `ApiResponseGoveeAppliances` containing information about the appliances.
172///
173/// # Returns
174///
175/// Returns `Ok(())` if the request is successful. Otherwise, returns a `ReqwestError` indicating the failure
176impl GoveeClient {
177 pub async fn get_appliances(&self) -> Result<ApiResponseGoveeAppliances, ReqwestError> {
178 let client = Client::new();
179 let endpoint = format!("{}/v1/appliance/devices", GOVEE_ROOT_URL);
180 let response = client
181 .get(endpoint)
182 .header("Govee-API-Key", &self.govee_api_key)
183 .send()
184 .await?;
185 let response_json = response.json::<ApiResponseGoveeAppliances>().await?;
186 Ok(response_json)
187 }
188}
189
190/// Retrieves the state of a Govee device.
191///
192/// This method sends a GET request to the Govee API to retrieve the state of a specific device.
193///
194/// # Arguments
195///
196/// * `device` - The device ID or name.
197/// * `model` - The model of the device.
198///
199/// # Returns
200///
201/// An `ApiResponseGoveeDeviceState` containing the current state of the device.
202///
203/// # Returns
204///
205/// Returns `Ok(())` if the request is successful. Otherwise, returns a `ReqwestError` indicating the failure
206impl GoveeClient {
207 pub async fn get_device_state(
208 &self,
209 device: &str,
210 model: &str,
211 ) -> Result<ApiResponseGoveeDeviceState, ReqwestError> {
212 let client = Client::new();
213 let params = [("device", device), ("model", model)];
214 let endpoint = format!("{}/v1/devices/state", GOVEE_ROOT_URL);
215 let url = Url::parse_with_params(&endpoint, ¶ms).unwrap();
216 let response = client
217 .get(url)
218 .header("Govee-API-Key", &self.govee_api_key)
219 .send()
220 .await?;
221 let response_json = response
222 .json::<ApiResponseGoveeDeviceState>()
223 .await
224 .unwrap();
225 Ok(response_json)
226 }
227}