Skip to content

Commit

Permalink
+ Add initial support for Room updates, and corresponding api models
Browse files Browse the repository at this point in the history
  • Loading branch information
chrivers committed Jan 15, 2025
1 parent e319bb9 commit fecf2dd
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/hue/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub use light::{
DimmingUpdate, GamutType, Light, LightColor, LightUpdate, MirekSchema, On,
};
pub use resource::{RType, ResourceLink, ResourceRecord};
pub use room::{Room, RoomArchetype, RoomMetadata};
pub use room::{Room, RoomArchetype, RoomMetadata, RoomMetadataUpdate, RoomUpdate};
pub use scene::{
Scene, SceneAction, SceneActionElement, SceneMetadata, SceneRecall, SceneStatus,
SceneStatusUpdate, SceneUpdate,
Expand Down
89 changes: 86 additions & 3 deletions src/hue/api/room.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
use std::ops::{AddAssign, Sub};

use serde::{Deserialize, Serialize};

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

#[derive(Debug, Serialize, Deserialize, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct RoomMetadata {
pub name: String,
pub archetype: RoomArchetype,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct RoomMetadataUpdate {
pub name: Option<String>,
pub archetype: Option<RoomArchetype>,
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct Room {
pub children: Vec<ResourceLink>,
pub metadata: RoomMetadata,
#[serde(default)]
pub services: Vec<ResourceLink>,
}

#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct RoomUpdate {
pub children: Option<Vec<ResourceLink>>,
pub metadata: Option<RoomMetadataUpdate>,
}

impl Room {
#[must_use]
pub fn grouped_light_service(&self) -> Option<&ResourceLink> {
Expand All @@ -25,7 +39,25 @@ impl Room {
}
}

#[derive(Copy, Debug, Serialize, Deserialize, Clone)]
impl RoomUpdate {
#[must_use]
pub fn new() -> Self {
Self::default()
}

#[must_use]
pub fn with_metadata(self, metadata: RoomMetadata) -> Self {
Self {
metadata: Some(RoomMetadataUpdate {
name: Some(metadata.name),
archetype: Some(metadata.archetype),
}),
..self
}
}
}

#[derive(Copy, Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum RoomArchetype {
LivingRoom,
Expand Down Expand Up @@ -79,3 +111,54 @@ impl RoomMetadata {
}
}
}

impl AddAssign<RoomMetadataUpdate> for RoomMetadata {
fn add_assign(&mut self, upd: RoomMetadataUpdate) {
if let Some(name) = upd.name {
self.name = name;
}
if let Some(archetype) = upd.archetype {
self.archetype = archetype;
}
}
}

#[allow(clippy::if_not_else)]
impl Sub<&RoomMetadata> for &RoomMetadata {
type Output = RoomMetadataUpdate;

fn sub(self, rhs: &RoomMetadata) -> Self::Output {
let mut upd = Self::Output::default();

if self != rhs {
if self.name != rhs.name {
upd.name = Some(rhs.name.clone());
}
if self.archetype != rhs.archetype {
upd.archetype = Some(rhs.archetype);
}
}

upd
}
}

#[allow(clippy::if_not_else)]
impl Sub<&Room> for &Room {
type Output = RoomUpdate;

fn sub(self, rhs: &Room) -> Self::Output {
let mut upd = Self::Output::default();

if self != rhs {
if self.children != rhs.children {
upd.children = Some(rhs.children.clone());
}
if self.metadata != rhs.metadata {
upd.metadata = Some(&self.metadata - &rhs.metadata);
}
}

upd
}
}
9 changes: 6 additions & 3 deletions src/hue/api/update.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::hue::api::{DeviceUpdate, GroupedLightUpdate, LightUpdate, RType, SceneUpdate};
use crate::hue::api::{
DeviceUpdate, GroupedLightUpdate, LightUpdate, RType, RoomUpdate, SceneUpdate,
};

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(tag = "type", rename_all = "snake_case")]
Expand All @@ -19,7 +21,7 @@ pub enum Update {
Light(LightUpdate),
/* Matter(MatterUpdate), */
/* PublicImage(PublicImageUpdate), */
/* Room(RoomUpdate), */
Room(RoomUpdate),
Scene(SceneUpdate),
/* SmartScene(SmartSceneUpdate), */
/* ZigbeeConnectivity(ZigbeeConnectivityUpdate), */
Expand All @@ -34,14 +36,15 @@ impl Update {
Self::GroupedLight(_) => RType::GroupedLight,
Self::Device(_) => RType::Device,
Self::Light(_) => RType::Light,
Self::Room(_) => RType::Room,
Self::Scene(_) => RType::Scene,
}
}

#[must_use]
pub fn id_v1_scope(&self, id: u32, uuid: &Uuid) -> Option<String> {
match self {
Self::GroupedLight(_) => Some(format!("/groups/{id}")),
Self::Room(_) | Self::GroupedLight(_) => Some(format!("/groups/{id}")),
Self::Device(_) => Some(format!("/device/{id}")),
Self::Light(_) => Some(format!("/lights/{id}")),
Self::Scene(_) => Some(format!("/scenes/{uuid}")),
Expand Down
10 changes: 7 additions & 3 deletions src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use uuid::Uuid;
use crate::error::{ApiError, ApiResult};
use crate::hue::api::{
Bridge, BridgeHome, Device, DeviceArchetype, DeviceProductData, DeviceUpdate, Metadata, RType,
Resource, ResourceLink, ResourceRecord, TimeZone, ZigbeeConnectivity, ZigbeeConnectivityStatus,
ZigbeeDeviceDiscovery,
Resource, ResourceLink, ResourceRecord, RoomUpdate, TimeZone, ZigbeeConnectivity,
ZigbeeConnectivityStatus, ZigbeeDeviceDiscovery,
};
use crate::hue::api::{GroupedLightUpdate, LightUpdate, SceneUpdate, Update};
use crate::hue::event::EventBlock;
Expand Down Expand Up @@ -104,7 +104,11 @@ impl Resources {

Ok(Some(Update::Device(upd)))
}
Resource::Room(_) => Ok(None),
Resource::Room(room) => {
let upd = RoomUpdate::new().with_metadata(room.metadata.clone());

Ok(Some(Update::Room(upd)))
}
obj => Err(ApiError::UpdateUnsupported(obj.rtype())),
}
}
Expand Down

0 comments on commit fecf2dd

Please sign in to comment.