use crate::{
api::HueAPIError,
command::{merge_commands, GroupCommand},
service::{AlertState, Bridge, OnState, ResourceIdentifier, ResourceType, SignalType},
};
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
#[derive(Debug)]
pub struct Group<'a> {
bridge: &'a Bridge,
data: GroupData,
}
impl<'a> Group<'a> {
pub fn new(bridge: &'a Bridge, data: GroupData) -> Self {
Group { bridge, data }
}
pub fn data(&self) -> &GroupData {
&self.data
}
pub fn id(&self) -> &str {
&self.data.id
}
pub fn rid(&self) -> ResourceIdentifier {
self.data.rid()
}
pub fn is_on(&self) -> bool {
self.data
.on
.as_ref()
.and_then(|on| Some(on.on))
.unwrap_or_default()
}
pub async fn on(&self) -> Result<Vec<ResourceIdentifier>, HueAPIError> {
self.send(&[GroupCommand::On(true)]).await
}
pub async fn off(&self) -> Result<Vec<ResourceIdentifier>, HueAPIError> {
self.send(&[GroupCommand::On(false)]).await
}
pub async fn toggle(&self) -> Result<Vec<ResourceIdentifier>, HueAPIError> {
self.send(&[GroupCommand::On(!self.is_on())]).await
}
pub async fn send(
&self,
commands: &[GroupCommand],
) -> Result<Vec<ResourceIdentifier>, HueAPIError> {
let payload = merge_commands(commands);
self.bridge.api.put_grouped_light(self.id(), &payload).await
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GroupData {
pub id: String,
pub id_v1: Option<String>,
pub owner: ResourceIdentifier,
pub on: Option<OnState>,
pub dimming: Option<GroupDimmingState>,
pub alert: Option<AlertState>,
pub signaling: Option<GroupSignalingState>,
}
impl GroupData {
pub fn rid(&self) -> ResourceIdentifier {
ResourceIdentifier {
rid: self.id.to_owned(),
rtype: ResourceType::Group,
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GroupDimmingState {
pub brightness: f32,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GroupSignalingState {
pub signal_values: Option<HashSet<SignalType>>,
}