Skip to content

Commit fecf2dd

Browse files
committed
+ Add initial support for Room updates, and corresponding api models
1 parent e319bb9 commit fecf2dd

File tree

4 files changed

+100
-10
lines changed

4 files changed

+100
-10
lines changed

src/hue/api/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub use light::{
1414
DimmingUpdate, GamutType, Light, LightColor, LightUpdate, MirekSchema, On,
1515
};
1616
pub use resource::{RType, ResourceLink, ResourceRecord};
17-
pub use room::{Room, RoomArchetype, RoomMetadata};
17+
pub use room::{Room, RoomArchetype, RoomMetadata, RoomMetadataUpdate, RoomUpdate};
1818
pub use scene::{
1919
Scene, SceneAction, SceneActionElement, SceneMetadata, SceneRecall, SceneStatus,
2020
SceneStatusUpdate, SceneUpdate,

src/hue/api/room.rs

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
1+
use std::ops::{AddAssign, Sub};
2+
13
use serde::{Deserialize, Serialize};
24

35
use crate::hue::api::{RType, ResourceLink};
46

5-
#[derive(Debug, Serialize, Deserialize, Clone)]
7+
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
68
pub struct RoomMetadata {
79
pub name: String,
810
pub archetype: RoomArchetype,
911
}
1012

11-
#[derive(Debug, Serialize, Deserialize, Clone)]
13+
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
14+
pub struct RoomMetadataUpdate {
15+
pub name: Option<String>,
16+
pub archetype: Option<RoomArchetype>,
17+
}
18+
19+
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
1220
pub struct Room {
1321
pub children: Vec<ResourceLink>,
1422
pub metadata: RoomMetadata,
1523
#[serde(default)]
1624
pub services: Vec<ResourceLink>,
1725
}
1826

27+
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
28+
pub struct RoomUpdate {
29+
pub children: Option<Vec<ResourceLink>>,
30+
pub metadata: Option<RoomMetadataUpdate>,
31+
}
32+
1933
impl Room {
2034
#[must_use]
2135
pub fn grouped_light_service(&self) -> Option<&ResourceLink> {
@@ -25,7 +39,25 @@ impl Room {
2539
}
2640
}
2741

28-
#[derive(Copy, Debug, Serialize, Deserialize, Clone)]
42+
impl RoomUpdate {
43+
#[must_use]
44+
pub fn new() -> Self {
45+
Self::default()
46+
}
47+
48+
#[must_use]
49+
pub fn with_metadata(self, metadata: RoomMetadata) -> Self {
50+
Self {
51+
metadata: Some(RoomMetadataUpdate {
52+
name: Some(metadata.name),
53+
archetype: Some(metadata.archetype),
54+
}),
55+
..self
56+
}
57+
}
58+
}
59+
60+
#[derive(Copy, Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
2961
#[serde(rename_all = "snake_case")]
3062
pub enum RoomArchetype {
3163
LivingRoom,
@@ -79,3 +111,54 @@ impl RoomMetadata {
79111
}
80112
}
81113
}
114+
115+
impl AddAssign<RoomMetadataUpdate> for RoomMetadata {
116+
fn add_assign(&mut self, upd: RoomMetadataUpdate) {
117+
if let Some(name) = upd.name {
118+
self.name = name;
119+
}
120+
if let Some(archetype) = upd.archetype {
121+
self.archetype = archetype;
122+
}
123+
}
124+
}
125+
126+
#[allow(clippy::if_not_else)]
127+
impl Sub<&RoomMetadata> for &RoomMetadata {
128+
type Output = RoomMetadataUpdate;
129+
130+
fn sub(self, rhs: &RoomMetadata) -> Self::Output {
131+
let mut upd = Self::Output::default();
132+
133+
if self != rhs {
134+
if self.name != rhs.name {
135+
upd.name = Some(rhs.name.clone());
136+
}
137+
if self.archetype != rhs.archetype {
138+
upd.archetype = Some(rhs.archetype);
139+
}
140+
}
141+
142+
upd
143+
}
144+
}
145+
146+
#[allow(clippy::if_not_else)]
147+
impl Sub<&Room> for &Room {
148+
type Output = RoomUpdate;
149+
150+
fn sub(self, rhs: &Room) -> Self::Output {
151+
let mut upd = Self::Output::default();
152+
153+
if self != rhs {
154+
if self.children != rhs.children {
155+
upd.children = Some(rhs.children.clone());
156+
}
157+
if self.metadata != rhs.metadata {
158+
upd.metadata = Some(&self.metadata - &rhs.metadata);
159+
}
160+
}
161+
162+
upd
163+
}
164+
}

src/hue/api/update.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use serde::{Deserialize, Serialize};
22
use uuid::Uuid;
33

4-
use crate::hue::api::{DeviceUpdate, GroupedLightUpdate, LightUpdate, RType, SceneUpdate};
4+
use crate::hue::api::{
5+
DeviceUpdate, GroupedLightUpdate, LightUpdate, RType, RoomUpdate, SceneUpdate,
6+
};
57

68
#[derive(Debug, Serialize, Deserialize, Clone)]
79
#[serde(tag = "type", rename_all = "snake_case")]
@@ -19,7 +21,7 @@ pub enum Update {
1921
Light(LightUpdate),
2022
/* Matter(MatterUpdate), */
2123
/* PublicImage(PublicImageUpdate), */
22-
/* Room(RoomUpdate), */
24+
Room(RoomUpdate),
2325
Scene(SceneUpdate),
2426
/* SmartScene(SmartSceneUpdate), */
2527
/* ZigbeeConnectivity(ZigbeeConnectivityUpdate), */
@@ -34,14 +36,15 @@ impl Update {
3436
Self::GroupedLight(_) => RType::GroupedLight,
3537
Self::Device(_) => RType::Device,
3638
Self::Light(_) => RType::Light,
39+
Self::Room(_) => RType::Room,
3740
Self::Scene(_) => RType::Scene,
3841
}
3942
}
4043

4144
#[must_use]
4245
pub fn id_v1_scope(&self, id: u32, uuid: &Uuid) -> Option<String> {
4346
match self {
44-
Self::GroupedLight(_) => Some(format!("/groups/{id}")),
47+
Self::Room(_) | Self::GroupedLight(_) => Some(format!("/groups/{id}")),
4548
Self::Device(_) => Some(format!("/device/{id}")),
4649
Self::Light(_) => Some(format!("/lights/{id}")),
4750
Self::Scene(_) => Some(format!("/scenes/{uuid}")),

src/resource.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use uuid::Uuid;
1010
use crate::error::{ApiError, ApiResult};
1111
use crate::hue::api::{
1212
Bridge, BridgeHome, Device, DeviceArchetype, DeviceProductData, DeviceUpdate, Metadata, RType,
13-
Resource, ResourceLink, ResourceRecord, TimeZone, ZigbeeConnectivity, ZigbeeConnectivityStatus,
14-
ZigbeeDeviceDiscovery,
13+
Resource, ResourceLink, ResourceRecord, RoomUpdate, TimeZone, ZigbeeConnectivity,
14+
ZigbeeConnectivityStatus, ZigbeeDeviceDiscovery,
1515
};
1616
use crate::hue::api::{GroupedLightUpdate, LightUpdate, SceneUpdate, Update};
1717
use crate::hue::event::EventBlock;
@@ -104,7 +104,11 @@ impl Resources {
104104

105105
Ok(Some(Update::Device(upd)))
106106
}
107-
Resource::Room(_) => Ok(None),
107+
Resource::Room(room) => {
108+
let upd = RoomUpdate::new().with_metadata(room.metadata.clone());
109+
110+
Ok(Some(Update::Room(upd)))
111+
}
108112
obj => Err(ApiError::UpdateUnsupported(obj.rtype())),
109113
}
110114
}

0 commit comments

Comments
 (0)