Skip to main content

hues/service/
entertainment.rs

1use crate::{
2    api::HueAPIError,
3    command::{merge_commands, EntertainmentConfigurationCommand},
4    service::{BasicMetadata, BasicStatus, Bridge, ResourceIdentifier, ResourceType},
5};
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug)]
9pub struct EntertainmentConfiguration<'a> {
10    bridge: &'a Bridge,
11    data: EntertainmentConfigurationData,
12}
13
14impl<'a> EntertainmentConfiguration<'a> {
15    pub fn new(bridge: &'a Bridge, data: EntertainmentConfigurationData) -> Self {
16        EntertainmentConfiguration { bridge, data }
17    }
18
19    pub fn data(&self) -> &EntertainmentConfigurationData {
20        &self.data
21    }
22
23    pub fn id(&self) -> &str {
24        &self.data.id
25    }
26
27    pub fn rid(&self) -> ResourceIdentifier {
28        self.data.rid()
29    }
30
31    pub async fn send(
32        &self,
33        commands: &[EntertainmentConfigurationCommand],
34    ) -> Result<Vec<ResourceIdentifier>, HueAPIError> {
35        let payload = merge_commands(commands);
36        self.bridge
37            .api
38            .put_entertainment_configuration(self.id(), &payload)
39            .await
40    }
41
42    #[cfg(feature = "streaming")]
43    pub async fn open_stream(&self) {}
44}
45
46/// Internal representation of an [EntertainmentConfiguration].
47#[derive(Clone, Debug, Deserialize, Serialize)]
48pub struct EntertainmentConfigurationData {
49    /// Unique identifier representing a specific resource instance.
50    pub id: String,
51    /// Clip v1 resource identifier.
52    pub id_v1: Option<String>,
53    pub metadata: BasicMetadata,
54    /// Friendly name of the entertainment configuration.
55    #[deprecated = "use `metadata.name`"]
56    pub name: Option<String>,
57    /// Defines for which type of application this channel assignment was optimized for.
58    pub configuration_type: EntertainmentConfigurationType,
59    /// Read-only field reporting if the stream is active or not.
60    pub status: BasicStatus,
61    /// Expected value is of a ResourceIdentifier of the type
62    /// [ResourceType::AuthV1] i.e. an application id, only available if status
63    /// is active.
64    pub active_streamer: Option<ResourceIdentifier>,
65    pub stream_proxy: StreamProxy,
66    /// Holds the channels. Each channel groups segments of one or more lights.
67    pub channels: Vec<EntertainmentChannel>,
68    /// Entertainment services of the lights that are in the zone have locations.
69    pub locations: EntertainmentServiceLocations,
70    /// List of light services that belong to this entertainment configuration.
71    #[deprecated = "resolve via entertainment services in locations object"]
72    pub light_services: Option<Vec<ResourceIdentifier>>,
73}
74
75impl EntertainmentConfigurationData {
76    pub fn rid(&self) -> ResourceIdentifier {
77        ResourceIdentifier {
78            rid: self.id.to_owned(),
79            rtype: ResourceType::EntertainmentConfiguration,
80        }
81    }
82}
83
84#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
85#[serde(rename_all = "snake_case")]
86pub enum EntertainmentConfigurationType {
87    /// Channels are organized around content from a screen.
88    Screen,
89    /// Channels are organized around content from one or several monitors.
90    Monitor,
91    /// Channels are organized for music synchronization.
92    Music,
93    /// Channels are organized to provide 3d spatial effects.
94    #[serde(rename = "3dspace")]
95    Space3D,
96    #[serde(other)]
97    /// General use-case.
98    Other,
99}
100
101#[derive(Clone, Debug, Deserialize, Serialize)]
102pub struct StreamProxy {
103    /// Proxymode used for this group.
104    pub mode: StreamProxyMode,
105    /// Reference to the device acting as proxy.
106    /// The proxy node relays the entertainment traffic and should be located in or close to all entertainment lamps in this group.
107    /// The node set by the application ([StreamProxyMode::Manual]) resp selected by the bridge ([StreamProxyMode::Auto]).
108    /// Writing sets `mode` to [StreamProxyMode::Manual]. Is not allowed to be combined with [StreamProxyMode::Auto].
109    /// Can be type [ResourceType::Bridge] or [ResourceType::ZigbeeConnectivity].
110    pub node: ResourceIdentifier,
111}
112
113#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
114#[serde(rename_all = "snake_case")]
115pub enum StreamProxyMode {
116    Auto,
117    Manual,
118}
119
120#[derive(Clone, Debug, Deserialize, Serialize)]
121pub struct EntertainmentChannel {
122    /// Bridge assigns a number upon creation. This is the number to be used by the HueStream API when addressing the channel
123    pub channel_id: u8,
124    /// xyz position of this channel. It is the average position of its members.
125    pub position: Position,
126    /// List that references segments that are members of that channel.
127    pub members: Vec<SegmentReference>,
128}
129
130#[derive(Clone, Debug, Deserialize, Serialize)]
131pub struct Position {
132    pub x: f32,
133    pub y: f32,
134    pub z: f32,
135}
136
137#[derive(Clone, Debug, Deserialize, Serialize)]
138pub struct SegmentReference {
139    pub service: ResourceIdentifier,
140    pub index: usize,
141}
142
143#[derive(Clone, Debug, Deserialize, Serialize)]
144pub struct EntertainmentServiceLocations {
145    pub service_locations: Vec<EntertainmentServiceLocation>,
146}
147
148#[derive(Clone, Debug, Deserialize, Serialize)]
149pub struct EntertainmentServiceLocation {
150    pub service: ResourceIdentifier,
151    #[deprecated = "use `positions`"]
152    /// Describes the location of the service.
153    pub position: Option<Position>,
154    /// Describes the location of the service.
155    pub positions: Vec<Position>,
156    /// Relative equalization factor applied to the entertainment service, to compensate for differences in brightness in the entertainment configuration.
157    /// Value cannot be `0`, writing `0` changes it to lowest possible value.
158    pub equalization_factor: f32,
159}
160
161#[derive(Debug)]
162pub struct Entertainment {
163    data: EntertainmentData,
164}
165
166impl Entertainment {
167    pub fn new(data: EntertainmentData) -> Self {
168        Entertainment { data }
169    }
170
171    pub fn data(&self) -> &EntertainmentData {
172        &self.data
173    }
174
175    pub fn id(&self) -> &str {
176        &self.data.id
177    }
178
179    pub fn rid(&self) -> ResourceIdentifier {
180        self.data.rid()
181    }
182}
183
184#[derive(Clone, Debug, Deserialize, Serialize)]
185pub struct EntertainmentData {
186    /// Unique identifier representing a specific resource instance.
187    pub id: String,
188    /// Clip v1 resource identifier.
189    pub id_v1: Option<String>,
190    /// Owner of the service, in case the owner service is deleted, the service also gets deleted.
191    pub owner: ResourceIdentifier,
192    /// Indicates if a lamp can be used for entertainment streaming as renderer.
193    pub renderer: bool,
194    /// Indicates which light service is linked to this entertainment service.
195    pub renderer_reference: Option<ResourceIdentifier>,
196    /// Indicates if a lamp can be used for entertainment streaming as a proxy node.
197    pub proxy: bool,
198    /// Indicates if a lamp can handle the equalization factor to dimming maximum brightness in a stream.
199    pub equalizer: bool,
200    /// Indicates the maximum number of parallel streaming sessions the bridge supports.
201    pub max_streams: Option<usize>,
202    /// Holds all parameters concerning the segmentations capabilities of a device.
203    pub segments: Option<SegmentData>,
204}
205
206impl EntertainmentData {
207    pub fn rid(&self) -> ResourceIdentifier {
208        ResourceIdentifier {
209            rid: self.id.to_owned(),
210            rtype: ResourceType::Entertainment,
211        }
212    }
213}
214
215#[derive(Clone, Debug, Deserialize, Serialize)]
216pub struct SegmentData {
217    /// Defines if the segmentation of the device are configurable or not.
218    pub configurable: bool,
219    pub max_segments: usize,
220    /// Contains the segments configuration of the device for entertainment purposes.
221    /// A device can be segmented in a single way.
222    pub segments: Vec<Segment>,
223}
224
225#[derive(Clone, Debug, Deserialize, Serialize)]
226pub struct Segment {
227    pub start: usize,
228    pub length: usize,
229}