google_smart_home/
sync.rs

1use crate::device;
2use serde::Deserialize;
3use serde::Serialize;
4
5/// Request types of the SYNC intent
6pub mod request {
7    use super::*;
8
9    /// SYNC request payload.
10    #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
11    #[serde(rename_all = "camelCase")]
12    pub struct Payload {}
13}
14
15/// Response types of the SYNC intent
16pub mod response {
17    use super::*;
18
19    /// SYNC response
20    #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
21    #[serde(rename_all = "camelCase")]
22    pub struct Response {
23        pub request_id: String,
24        pub payload: Payload,
25    }
26
27    /// SYNC response payload.
28    #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
29    #[serde(rename_all = "camelCase")]
30    pub struct Payload {
31        /// Reflects the unique (and immutable) user ID on the agent's platform.
32        pub agent_user_id: String,
33        /// An error code for the entire transaction for auth failures and developer system unavailability.
34        /// For individual device errors, use the errorCode within the device object.
35        #[serde(skip_serializing_if = "Option::is_none")]
36        pub error_code: Option<String>,
37        /// Detailed error which will never be presented to users but may be logged or used during development.
38        #[serde(skip_serializing_if = "Option::is_none")]
39        pub debug_string: Option<String>,
40        /// Reflects the unique (and immutable) user ID on the agent's platform.
41        pub devices: Vec<PayloadDevice>,
42    }
43
44    /// Device execution result.
45    #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
46    #[serde(rename_all = "camelCase")]
47    pub struct PayloadDevice {
48        /// The ID of the device in the developer's cloud.
49        /// This must be unique for the user and for the developer,
50        /// as in cases of sharing we may use this to dedupe multiple views of the same device.
51        /// It should be immutable for the device; if it changes, the Assistant will treat it as a new device.
52        pub id: String,
53        /// The hardware type of device.
54        #[serde(rename = "type")]
55        pub device_type: device::Type,
56        /// List of traits this device has. This defines the commands, attributes, and states that the device supports.
57        pub traits: Vec<device::Trait>,
58        /// Names of this device.
59        pub name: PayloadDeviceName,
60        /// Indicates whether this device will have its states updated by the Real Time Feed.
61        /// true to use the Real Time Feed for reporting state, and false to use the polling model.
62        pub will_report_state: bool,
63        /// Indicates whether notifications are enabled for the device.
64        #[serde(default)]
65        pub notification_supported_by_agent: bool,
66        /// Provides the current room of the device in the user's home to simplify setup.
67        #[serde(skip_serializing_if = "Option::is_none")]
68        pub room_hint: Option<String>,
69        /// Contains fields describing the device for use in one-off logic if needed (e.g. 'broken firmware version X of light Y requires adjusting color', or 'security flaw requires notifying all users of firmware Z').
70        #[serde(skip_serializing_if = "Option::is_none")]
71        pub device_info: Option<PayloadDeviceInfo>,
72        /// Aligned with per-trait attributes described in each trait schema reference.
73        #[serde(default)]
74        pub attributes: Attributes,
75        /// Object defined by the developer which will be attached to future QUERY and EXECUTE requests, maximum of 512 bytes per device. Use this object to store additional information about the device your cloud service may need, such as the global region of the device. Data in this object has a few constraints: No sensitive information, including but not limited to Personally Identifiable Information.
76        #[serde(default, skip_serializing_if = "Option::is_none")]
77        pub custom_data: Option<serde_json::Map<String, serde_json::Value>>,
78        /// List of alternate IDs used to identify a cloud synced device for local execution.
79        #[serde(skip_serializing_if = "Option::is_none")]
80        pub other_device_ids: Option<Vec<PayloadOtherDeviceID>>,
81    }
82
83    #[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
84    #[serde(rename_all = "camelCase")]
85    pub struct Attributes {
86        // Attributes for ColorSetting trait.
87        #[serde(skip_serializing_if = "Option::is_none")]
88        pub color_model: Option<ColorModel>,
89        #[serde(skip_serializing_if = "Option::is_none")]
90        pub color_temperature_range: Option<ColorTemperatureRange>,
91        #[serde(skip_serializing_if = "Option::is_none")]
92        pub command_only_color_setting: Option<bool>,
93
94        // Attributes for TemperatureSetting trait.
95        #[serde(skip_serializing_if = "Option::is_none")]
96        pub available_thermostat_modes: Option<Vec<String>>,
97        #[serde(skip_serializing_if = "Option::is_none")]
98        pub buffer_range_celsius: Option<f64>,
99        #[serde(skip_serializing_if = "Option::is_none")]
100        pub command_only_temperature_setting: Option<bool>,
101        #[serde(skip_serializing_if = "Option::is_none")]
102        pub query_only_temperature_setting: Option<bool>,
103        #[serde(skip_serializing_if = "Option::is_none")]
104        pub thermostat_temperature_range: Option<ThermostatTemperatureRange>,
105        #[serde(skip_serializing_if = "Option::is_none")]
106        pub thermostat_temperature_unit: Option<ThermostatTemperatureUnit>,
107    }
108
109    #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
110    #[serde(rename_all = "camelCase")]
111    pub struct ColorTemperatureRange {
112        pub temperature_min_k: u64,
113        pub temperature_max_k: u64,
114    }
115
116    #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
117    #[serde(rename_all = "camelCase")]
118    pub enum ColorModel {
119        Rgb,
120        Hsv,
121    }
122
123    #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
124    #[serde(rename_all = "camelCase")]
125    pub struct ThermostatTemperatureRange {
126        pub min_threshold_celsius: f64,
127        pub max_threshold_celcius: f64,
128    }
129
130    #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
131    pub enum ThermostatTemperatureUnit {
132        C,
133        F,
134    }
135
136    #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
137    #[serde(rename_all = "camelCase")]
138    pub struct PayloadDeviceName {
139        /// List of names provided by the developer rather than the user, often manufacturer names, SKUs, etc.
140        #[serde(skip_serializing_if = "Option::is_none")]
141        pub default_names: Option<Vec<String>>,
142        /// Primary name of the device, generally provided by the user.
143        /// This is also the name the Assistant will prefer to describe the device in responses.
144        pub name: String,
145        /// Additional names provided by the user for the device.
146        #[serde(skip_serializing_if = "Option::is_none")]
147        pub nicknames: Option<Vec<String>>,
148    }
149
150    #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
151    #[serde(rename_all = "camelCase")]
152    pub struct PayloadDeviceInfo {
153        /// Especially useful when the developer is a hub for other devices.
154        /// Google may provide a standard list of manufacturers here so that e.g. TP-Link and Smartthings both describe 'osram' the same way.
155        #[serde(skip_serializing_if = "Option::is_none")]
156        pub manufacturer: Option<String>,
157        /// The model or SKU identifier of the particular device.
158        #[serde(skip_serializing_if = "Option::is_none")]
159        pub model: Option<String>,
160        /// Specific version number attached to the hardware if available.
161        #[serde(skip_serializing_if = "Option::is_none")]
162        pub hw_version: Option<String>,
163        /// Specific version number attached to the software/firmware, if available.
164        #[serde(skip_serializing_if = "Option::is_none")]
165        pub sw_version: Option<String>,
166    }
167
168    #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
169    #[serde(rename_all = "camelCase")]
170    pub struct PayloadOtherDeviceID {
171        /// The agent's ID. Generally, this is the project ID in the Actions console.
172        #[serde(skip_serializing_if = "Option::is_none")]
173        pub agent_id: Option<String>,
174        /// Device ID defined by the agent. The device ID must be unique.
175        pub device_id: String,
176    }
177}
178
179#[cfg(test)]
180mod tests {
181    use super::*;
182
183    use serde_json::json;
184
185    #[test]
186    fn color_setting_attributes() {
187        let attributes = response::Attributes {
188            color_model: Some(response::ColorModel::Rgb),
189            command_only_color_setting: Some(true),
190            ..Default::default()
191        };
192        assert_eq!(
193            serde_json::to_string(&attributes).unwrap(),
194            json!({"colorModel": "rgb", "commandOnlyColorSetting": true}).to_string()
195        );
196    }
197}