1use super::IntegrationResult;
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct DeviceState {
18 pub device_id: String,
19 pub name: String,
20 pub device_type: DeviceType,
21 pub state: String,
22 pub attributes: HashMap<String, serde_json::Value>,
23 pub last_changed: String,
24 pub is_online: bool,
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
29#[serde(rename_all = "snake_case")]
30pub enum DeviceType {
31 Light,
32 Switch,
33 Outlet,
34 Thermostat,
35 Lock,
36 Sensor,
37 Camera,
38 Speaker,
39 Fan,
40 Blind,
41 Garage,
42 Vacuum,
43 AirPurifier,
44 Humidifier,
45 MediaPlayer,
46 Climate,
47 Other,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct Scene {
53 pub id: String,
54 pub name: String,
55 pub description: Option<String>,
56 pub actions: Vec<DeviceAction>,
57 pub icon: Option<String>,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct DeviceAction {
63 pub device_id: String,
64 pub action: String,
65 pub parameters: Option<HashMap<String, serde_json::Value>>,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct HomeAssistantConfig {
74 pub url: String,
75 pub access_token: String,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct HAEntity {
81 pub entity_id: String,
82 pub state: String,
83 pub attributes: HashMap<String, serde_json::Value>,
84 pub last_changed: String,
85 pub last_updated: String,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct HAService {
91 pub domain: String,
92 pub service: String,
93 pub description: Option<String>,
94 pub fields: HashMap<String, HAServiceField>,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct HAServiceField {
99 pub description: String,
100 pub required: bool,
101 pub example: Option<serde_json::Value>,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct HAAutomation {
107 pub id: String,
108 pub alias: String,
109 pub description: Option<String>,
110 pub trigger: Vec<serde_json::Value>,
111 pub condition: Vec<serde_json::Value>,
112 pub action: Vec<serde_json::Value>,
113 pub mode: String,
114}
115
116#[async_trait::async_trait]
118pub trait HomeAssistantProvider: Send + Sync {
119 async fn list_entities(&self, domain: Option<&str>) -> IntegrationResult;
121 async fn get_state(&self, entity_id: &str) -> IntegrationResult;
122 async fn get_history(&self, entity_id: &str, start: &str, end: &str) -> IntegrationResult;
123
124 async fn list_services(&self) -> IntegrationResult;
126 async fn call_service(
127 &self,
128 domain: &str,
129 service: &str,
130 data: Option<serde_json::Value>,
131 ) -> IntegrationResult;
132
133 async fn list_automations(&self) -> IntegrationResult;
135 async fn trigger_automation(&self, automation_id: &str) -> IntegrationResult;
136 async fn toggle_automation(&self, automation_id: &str, enabled: bool) -> IntegrationResult;
137
138 async fn list_scenes(&self) -> IntegrationResult;
140 async fn activate_scene(&self, scene_id: &str) -> IntegrationResult;
141
142 async fn run_script(
144 &self,
145 script_id: &str,
146 data: Option<serde_json::Value>,
147 ) -> IntegrationResult;
148
149 async fn fire_event(
151 &self,
152 event_type: &str,
153 data: Option<serde_json::Value>,
154 ) -> IntegrationResult;
155
156 async fn notify(
158 &self,
159 message: &str,
160 title: Option<&str>,
161 data: Option<serde_json::Value>,
162 ) -> IntegrationResult;
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize)]
170pub struct HomeKitAccessory {
171 pub id: String,
172 pub name: String,
173 pub room: Option<String>,
174 pub accessory_type: String,
175 pub services: Vec<HomeKitService>,
176 pub is_reachable: bool,
177}
178
179#[derive(Debug, Clone, Serialize, Deserialize)]
180pub struct HomeKitService {
181 pub service_type: String,
182 pub characteristics: Vec<HomeKitCharacteristic>,
183}
184
185#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct HomeKitCharacteristic {
187 pub characteristic_type: String,
188 pub value: serde_json::Value,
189 pub is_readable: bool,
190 pub is_writable: bool,
191}
192
193#[async_trait::async_trait]
195pub trait HomeKitProvider: Send + Sync {
196 async fn list_homes(&self) -> IntegrationResult;
197 async fn list_rooms(&self, home_id: &str) -> IntegrationResult;
198 async fn list_accessories(&self, home_id: &str) -> IntegrationResult;
199 async fn get_accessory(&self, accessory_id: &str) -> IntegrationResult;
200 async fn set_characteristic(
201 &self,
202 accessory_id: &str,
203 service: &str,
204 characteristic: &str,
205 value: serde_json::Value,
206 ) -> IntegrationResult;
207 async fn list_scenes(&self, home_id: &str) -> IntegrationResult;
208 async fn run_scene(&self, scene_id: &str) -> IntegrationResult;
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize)]
216pub struct HueConfig {
217 pub bridge_ip: String,
218 pub username: String,
219}
220
221#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct HueLight {
223 pub id: String,
224 pub name: String,
225 pub is_on: bool,
226 pub brightness: u8, pub hue: Option<u16>, pub saturation: Option<u8>, pub color_temp: Option<u16>, pub is_reachable: bool,
231 pub light_type: String,
232}
233
234#[derive(Debug, Clone, Serialize, Deserialize)]
235pub struct HueGroup {
236 pub id: String,
237 pub name: String,
238 pub lights: Vec<String>,
239 pub group_type: String,
240 pub is_on: bool,
241}
242
243#[derive(Debug, Clone, Serialize, Deserialize)]
244pub struct HueScene {
245 pub id: String,
246 pub name: String,
247 pub group: Option<String>,
248 pub lights: Vec<String>,
249}
250
251#[async_trait::async_trait]
253pub trait HueProvider: Send + Sync {
254 async fn list_lights(&self) -> IntegrationResult;
256 async fn get_light(&self, light_id: &str) -> IntegrationResult;
257 async fn set_light_state(
258 &self,
259 light_id: &str,
260 on: Option<bool>,
261 brightness: Option<u8>,
262 color: Option<(u16, u8)>,
263 ) -> IntegrationResult;
264
265 async fn list_groups(&self) -> IntegrationResult;
267 async fn set_group_state(
268 &self,
269 group_id: &str,
270 on: Option<bool>,
271 brightness: Option<u8>,
272 ) -> IntegrationResult;
273
274 async fn list_scenes(&self) -> IntegrationResult;
276 async fn activate_scene(&self, scene_id: &str) -> IntegrationResult;
277
278 async fn set_color_loop(&self, light_id: &str, enabled: bool) -> IntegrationResult;
280 async fn alert(&self, light_id: &str) -> IntegrationResult;
281}
282
283#[derive(Debug, Clone, Serialize, Deserialize)]
288pub struct ThermostatState {
289 pub id: String,
290 pub name: String,
291 pub current_temperature: f32,
292 pub target_temperature: Option<f32>,
293 pub target_temperature_low: Option<f32>,
294 pub target_temperature_high: Option<f32>,
295 pub mode: ThermostatMode,
296 pub humidity: Option<u8>,
297 pub is_running: bool,
298 pub fan_mode: Option<FanMode>,
299}
300
301#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
302#[serde(rename_all = "snake_case")]
303pub enum ThermostatMode {
304 Off,
305 Heat,
306 Cool,
307 HeatCool,
308 Auto,
309 Eco,
310}
311
312#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
313#[serde(rename_all = "snake_case")]
314pub enum FanMode {
315 Auto,
316 On,
317 Circulate,
318}
319
320#[async_trait::async_trait]
322pub trait ThermostatProvider: Send + Sync {
323 async fn get_state(&self, thermostat_id: &str) -> IntegrationResult;
324 async fn set_temperature(&self, thermostat_id: &str, temperature: f32) -> IntegrationResult;
325 async fn set_mode(&self, thermostat_id: &str, mode: ThermostatMode) -> IntegrationResult;
326 async fn set_fan_mode(&self, thermostat_id: &str, fan_mode: FanMode) -> IntegrationResult;
327 async fn set_schedule(
328 &self,
329 thermostat_id: &str,
330 schedule: serde_json::Value,
331 ) -> IntegrationResult;
332}
333
334#[derive(Debug, Clone, Serialize, Deserialize)]
339pub struct LockState {
340 pub id: String,
341 pub name: String,
342 pub is_locked: bool,
343 pub is_jammed: bool,
344 pub battery_level: Option<u8>,
345 pub last_activity: Option<String>,
346}
347
348#[async_trait::async_trait]
350pub trait LockProvider: Send + Sync {
351 async fn get_state(&self, lock_id: &str) -> IntegrationResult;
352 async fn lock(&self, lock_id: &str) -> IntegrationResult;
353 async fn unlock(&self, lock_id: &str) -> IntegrationResult;
354 async fn get_activity(&self, lock_id: &str, limit: u32) -> IntegrationResult;
355}
356
357#[derive(Debug, Clone, Serialize, Deserialize)]
362pub struct Camera {
363 pub id: String,
364 pub name: String,
365 pub is_online: bool,
366 pub is_recording: bool,
367 pub has_motion: bool,
368 pub battery_level: Option<u8>,
369 pub stream_url: Option<String>,
370}
371
372#[async_trait::async_trait]
374pub trait CameraProvider: Send + Sync {
375 async fn list_cameras(&self) -> IntegrationResult;
376 async fn get_camera(&self, camera_id: &str) -> IntegrationResult;
377 async fn get_stream_url(&self, camera_id: &str) -> IntegrationResult;
378 async fn get_snapshot(&self, camera_id: &str) -> IntegrationResult;
379 async fn get_events(&self, camera_id: &str, limit: u32) -> IntegrationResult;
380}
381
382#[derive(Debug, Clone, Serialize, Deserialize)]
387pub struct Sensor {
388 pub id: String,
389 pub name: String,
390 pub sensor_type: SensorType,
391 pub value: serde_json::Value,
392 pub unit: Option<String>,
393 pub battery_level: Option<u8>,
394 pub last_updated: String,
395}
396
397#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
398#[serde(rename_all = "snake_case")]
399pub enum SensorType {
400 Temperature,
401 Humidity,
402 Motion,
403 Contact,
404 Light,
405 Smoke,
406 CarbonMonoxide,
407 Water,
408 Vibration,
409 Pressure,
410 AirQuality,
411 Power,
412 Energy,
413}
414
415#[async_trait::async_trait]
417pub trait SensorProvider: Send + Sync {
418 async fn list_sensors(&self) -> IntegrationResult;
419 async fn get_sensor(&self, sensor_id: &str) -> IntegrationResult;
420 async fn get_history(&self, sensor_id: &str, start: &str, end: &str) -> IntegrationResult;
421}