1use crate::upnp::DecodeXml;
4use crate::xmlutil::DecodeXmlString;
5use crate::{Result, SonosDevice};
6use instant_xml::{FromXml, ToXml};
7use std::str::FromStr;
8
9pub mod av_transport {
11 use super::*;
12
13 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:AVTransport:1";
16
17 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
18 #[xml(rename = "AddMultipleURIsToQueue", ns(SERVICE_TYPE))]
19 pub struct AddMultipleUrisToQueueRequest {
20 #[xml(rename = "InstanceID", ns(""))]
21 pub instance_id: u32,
22 #[xml(rename = "UpdateID", ns(""))]
23 pub update_id: u32,
24 #[xml(rename = "NumberOfURIs", ns(""))]
25 pub number_of_uris: u32,
26 #[xml(rename = "EnqueuedURIs", ns(""))]
27 pub enqueued_uris: String,
28 #[xml(rename = "EnqueuedURIsMetaData", ns(""))]
29 pub enqueued_uris_meta_data: String,
30 #[xml(rename = "ContainerURI", ns(""))]
31 pub container_uri: String,
32 #[xml(rename = "ContainerMetaData", ns(""))]
33 pub container_meta_data: String,
34 #[xml(rename = "DesiredFirstTrackNumberEnqueued", ns(""))]
35 pub desired_first_track_number_enqueued: u32,
36 #[xml(rename = "EnqueueAsNext", ns(""))]
37 pub enqueue_as_next: bool,
38 }
39
40 #[derive(FromXml, Debug, Clone, PartialEq)]
41 #[xml(rename = "AddMultipleURIsToQueueResponse", ns(SERVICE_TYPE))]
42 pub struct AddMultipleUrisToQueueResponse {
43 #[xml(rename = "FirstTrackNumberEnqueued", ns(""))]
44 pub first_track_number_enqueued: Option<u32>,
45 #[xml(rename = "NumTracksAdded", ns(""))]
46 pub num_tracks_added: Option<u32>,
47 #[xml(rename = "NewQueueLength", ns(""))]
48 pub new_queue_length: Option<u32>,
49 #[xml(rename = "NewUpdateID", ns(""))]
50 pub new_update_id: Option<u32>,
51 }
52
53 impl crate::DecodeSoapResponse for AddMultipleUrisToQueueResponse {
54 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
55 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
56 Ok(envelope.body.payload)
57 }
58 }
59
60 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
61 #[xml(rename = "AddURIToQueue", ns(SERVICE_TYPE))]
62 pub struct AddUriToQueueRequest {
63 #[xml(rename = "InstanceID", ns(""))]
64 pub instance_id: u32,
65 #[xml(rename = "EnqueuedURI", ns(""))]
66 pub enqueued_uri: String,
67 #[xml(rename = "EnqueuedURIMetaData", ns(""))]
68 pub enqueued_uri_meta_data: DecodeXmlString<crate::TrackMetaData>,
69 #[xml(rename = "DesiredFirstTrackNumberEnqueued", ns(""))]
71 pub desired_first_track_number_enqueued: u32,
72 #[xml(rename = "EnqueueAsNext", ns(""))]
73 pub enqueue_as_next: bool,
74 }
75
76 #[derive(FromXml, Debug, Clone, PartialEq)]
77 #[xml(rename = "AddURIToQueueResponse", ns(SERVICE_TYPE))]
78 pub struct AddUriToQueueResponse {
79 #[xml(rename = "FirstTrackNumberEnqueued", ns(""))]
80 pub first_track_number_enqueued: Option<u32>,
81 #[xml(rename = "NumTracksAdded", ns(""))]
82 pub num_tracks_added: Option<u32>,
83 #[xml(rename = "NewQueueLength", ns(""))]
84 pub new_queue_length: Option<u32>,
85 }
86
87 impl crate::DecodeSoapResponse for AddUriToQueueResponse {
88 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
89 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
90 Ok(envelope.body.payload)
91 }
92 }
93
94 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
95 #[xml(rename = "AddURIToSavedQueue", ns(SERVICE_TYPE))]
96 pub struct AddUriToSavedQueueRequest {
97 #[xml(rename = "InstanceID", ns(""))]
98 pub instance_id: u32,
99 #[xml(rename = "ObjectID", ns(""))]
100 pub object_id: String,
101 #[xml(rename = "UpdateID", ns(""))]
102 pub update_id: u32,
103 #[xml(rename = "EnqueuedURI", ns(""))]
104 pub enqueued_uri: String,
105 #[xml(rename = "EnqueuedURIMetaData", ns(""))]
106 pub enqueued_uri_meta_data: DecodeXmlString<crate::TrackMetaData>,
107 #[xml(rename = "AddAtIndex", ns(""))]
108 pub add_at_index: u32,
109 }
110
111 #[derive(FromXml, Debug, Clone, PartialEq)]
112 #[xml(rename = "AddURIToSavedQueueResponse", ns(SERVICE_TYPE))]
113 pub struct AddUriToSavedQueueResponse {
114 #[xml(rename = "NumTracksAdded", ns(""))]
115 pub num_tracks_added: Option<u32>,
116 #[xml(rename = "NewQueueLength", ns(""))]
117 pub new_queue_length: Option<u32>,
118 #[xml(rename = "NewUpdateID", ns(""))]
119 pub new_update_id: Option<u32>,
120 }
121
122 impl crate::DecodeSoapResponse for AddUriToSavedQueueResponse {
123 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
124 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
125 Ok(envelope.body.payload)
126 }
127 }
128
129 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
130 #[xml(rename = "BackupQueue", ns(SERVICE_TYPE))]
131 pub struct BackupQueueRequest {
132 #[xml(rename = "InstanceID", ns(""))]
133 pub instance_id: u32,
134 }
135
136 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
137 #[xml(rename = "BecomeCoordinatorOfStandaloneGroup", ns(SERVICE_TYPE))]
138 pub struct BecomeCoordinatorOfStandaloneGroupRequest {
139 #[xml(rename = "InstanceID", ns(""))]
140 pub instance_id: u32,
141 }
142
143 #[derive(FromXml, Debug, Clone, PartialEq)]
144 #[xml(
145 rename = "BecomeCoordinatorOfStandaloneGroupResponse",
146 ns(SERVICE_TYPE)
147 )]
148 pub struct BecomeCoordinatorOfStandaloneGroupResponse {
149 #[xml(rename = "DelegatedGroupCoordinatorID", ns(""))]
150 pub delegated_group_coordinator_id: Option<String>,
151 #[xml(rename = "NewGroupID", ns(""))]
152 pub new_group_id: Option<String>,
153 }
154
155 impl crate::DecodeSoapResponse for BecomeCoordinatorOfStandaloneGroupResponse {
156 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
157 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
158 Ok(envelope.body.payload)
159 }
160 }
161
162 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
163 #[xml(rename = "BecomeGroupCoordinator", ns(SERVICE_TYPE))]
164 pub struct BecomeGroupCoordinatorRequest {
165 #[xml(rename = "InstanceID", ns(""))]
166 pub instance_id: u32,
167 #[xml(rename = "CurrentCoordinator", ns(""))]
168 pub current_coordinator: String,
169 #[xml(rename = "CurrentGroupID", ns(""))]
170 pub current_group_id: String,
171 #[xml(rename = "OtherMembers", ns(""))]
172 pub other_members: String,
173 #[xml(rename = "TransportSettings", ns(""))]
174 pub transport_settings: String,
175 #[xml(rename = "CurrentURI", ns(""))]
176 pub current_uri: String,
177 #[xml(rename = "CurrentURIMetaData", ns(""))]
178 pub current_uri_meta_data: DecodeXmlString<crate::TrackMetaData>,
179 #[xml(rename = "SleepTimerState", ns(""))]
180 pub sleep_timer_state: String,
181 #[xml(rename = "AlarmState", ns(""))]
182 pub alarm_state: String,
183 #[xml(rename = "StreamRestartState", ns(""))]
184 pub stream_restart_state: String,
185 #[xml(rename = "CurrentQueueTrackList", ns(""))]
186 pub current_queue_track_list: String,
187 #[xml(rename = "CurrentVLIState", ns(""))]
188 pub current_vli_state: String,
189 }
190
191 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
192 #[xml(rename = "BecomeGroupCoordinatorAndSource", ns(SERVICE_TYPE))]
193 pub struct BecomeGroupCoordinatorAndSourceRequest {
194 #[xml(rename = "InstanceID", ns(""))]
195 pub instance_id: u32,
196 #[xml(rename = "CurrentCoordinator", ns(""))]
197 pub current_coordinator: String,
198 #[xml(rename = "CurrentGroupID", ns(""))]
199 pub current_group_id: String,
200 #[xml(rename = "OtherMembers", ns(""))]
201 pub other_members: String,
202 #[xml(rename = "CurrentURI", ns(""))]
203 pub current_uri: String,
204 #[xml(rename = "CurrentURIMetaData", ns(""))]
205 pub current_uri_meta_data: DecodeXmlString<crate::TrackMetaData>,
206 #[xml(rename = "SleepTimerState", ns(""))]
207 pub sleep_timer_state: String,
208 #[xml(rename = "AlarmState", ns(""))]
209 pub alarm_state: String,
210 #[xml(rename = "StreamRestartState", ns(""))]
211 pub stream_restart_state: String,
212 #[xml(rename = "CurrentAVTTrackList", ns(""))]
213 pub current_avt_track_list: String,
214 #[xml(rename = "CurrentQueueTrackList", ns(""))]
215 pub current_queue_track_list: String,
216 #[xml(rename = "CurrentSourceState", ns(""))]
217 pub current_source_state: String,
218 #[xml(rename = "ResumePlayback", ns(""))]
219 pub resume_playback: bool,
220 }
221
222 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
223 #[xml(rename = "ChangeCoordinator", ns(SERVICE_TYPE))]
224 pub struct ChangeCoordinatorRequest {
225 #[xml(rename = "InstanceID", ns(""))]
226 pub instance_id: u32,
227 #[xml(rename = "CurrentCoordinator", ns(""))]
228 pub current_coordinator: String,
229 #[xml(rename = "NewCoordinator", ns(""))]
230 pub new_coordinator: String,
231 #[xml(rename = "NewTransportSettings", ns(""))]
232 pub new_transport_settings: String,
233 #[xml(rename = "CurrentAVTransportURI", ns(""))]
234 pub current_av_transport_uri: String,
235 }
236
237 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
238 #[xml(rename = "ChangeTransportSettings", ns(SERVICE_TYPE))]
239 pub struct ChangeTransportSettingsRequest {
240 #[xml(rename = "InstanceID", ns(""))]
241 pub instance_id: u32,
242 #[xml(rename = "NewTransportSettings", ns(""))]
243 pub new_transport_settings: String,
244 #[xml(rename = "CurrentAVTransportURI", ns(""))]
245 pub current_av_transport_uri: String,
246 }
247
248 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
249 #[xml(rename = "ConfigureSleepTimer", ns(SERVICE_TYPE))]
250 pub struct ConfigureSleepTimerRequest {
251 #[xml(rename = "InstanceID", ns(""))]
252 pub instance_id: u32,
253 #[xml(rename = "NewSleepTimerDuration", ns(""))]
255 pub new_sleep_timer_duration: String,
256 }
257
258 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
259 #[xml(rename = "CreateSavedQueue", ns(SERVICE_TYPE))]
260 pub struct CreateSavedQueueRequest {
261 #[xml(rename = "InstanceID", ns(""))]
262 pub instance_id: u32,
263 #[xml(rename = "Title", ns(""))]
264 pub title: String,
265 #[xml(rename = "EnqueuedURI", ns(""))]
266 pub enqueued_uri: String,
267 #[xml(rename = "EnqueuedURIMetaData", ns(""))]
268 pub enqueued_uri_meta_data: DecodeXmlString<crate::TrackMetaData>,
269 }
270
271 #[derive(FromXml, Debug, Clone, PartialEq)]
272 #[xml(rename = "CreateSavedQueueResponse", ns(SERVICE_TYPE))]
273 pub struct CreateSavedQueueResponse {
274 #[xml(rename = "NumTracksAdded", ns(""))]
275 pub num_tracks_added: Option<u32>,
276 #[xml(rename = "NewQueueLength", ns(""))]
277 pub new_queue_length: Option<u32>,
278 #[xml(rename = "AssignedObjectID", ns(""))]
279 pub assigned_object_id: Option<String>,
280 #[xml(rename = "NewUpdateID", ns(""))]
281 pub new_update_id: Option<u32>,
282 }
283
284 impl crate::DecodeSoapResponse for CreateSavedQueueResponse {
285 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
286 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
287 Ok(envelope.body.payload)
288 }
289 }
290
291 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
292 #[xml(rename = "DelegateGroupCoordinationTo", ns(SERVICE_TYPE))]
293 pub struct DelegateGroupCoordinationToRequest {
294 #[xml(rename = "InstanceID", ns(""))]
295 pub instance_id: u32,
296 #[xml(rename = "NewCoordinator", ns(""))]
298 pub new_coordinator: String,
299 #[xml(rename = "RejoinGroup", ns(""))]
301 pub rejoin_group: bool,
302 }
303
304 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
305 #[xml(rename = "EndDirectControlSession", ns(SERVICE_TYPE))]
306 pub struct EndDirectControlSessionRequest {
307 #[xml(rename = "InstanceID", ns(""))]
308 pub instance_id: u32,
309 }
310
311 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
312 #[xml(rename = "GetCrossfadeMode", ns(SERVICE_TYPE))]
313 pub struct GetCrossfadeModeRequest {
314 #[xml(rename = "InstanceID", ns(""))]
315 pub instance_id: u32,
316 }
317
318 #[derive(FromXml, Debug, Clone, PartialEq)]
319 #[xml(rename = "GetCrossfadeModeResponse", ns(SERVICE_TYPE))]
320 pub struct GetCrossfadeModeResponse {
321 #[xml(rename = "CrossfadeMode", ns(""))]
322 pub crossfade_mode: Option<bool>,
323 }
324
325 impl crate::DecodeSoapResponse for GetCrossfadeModeResponse {
326 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
327 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
328 Ok(envelope.body.payload)
329 }
330 }
331
332 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
333 #[xml(rename = "GetCurrentTransportActions", ns(SERVICE_TYPE))]
334 pub struct GetCurrentTransportActionsRequest {
335 #[xml(rename = "InstanceID", ns(""))]
336 pub instance_id: u32,
337 }
338
339 #[derive(FromXml, Debug, Clone, PartialEq)]
340 #[xml(rename = "GetCurrentTransportActionsResponse", ns(SERVICE_TYPE))]
341 pub struct GetCurrentTransportActionsResponse {
342 #[xml(rename = "Actions", ns(""))]
343 pub actions: Option<String>,
344 }
345
346 impl crate::DecodeSoapResponse for GetCurrentTransportActionsResponse {
347 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
348 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
349 Ok(envelope.body.payload)
350 }
351 }
352
353 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
354 #[xml(rename = "GetDeviceCapabilities", ns(SERVICE_TYPE))]
355 pub struct GetDeviceCapabilitiesRequest {
356 #[xml(rename = "InstanceID", ns(""))]
357 pub instance_id: u32,
358 }
359
360 #[derive(FromXml, Debug, Clone, PartialEq)]
361 #[xml(rename = "GetDeviceCapabilitiesResponse", ns(SERVICE_TYPE))]
362 pub struct GetDeviceCapabilitiesResponse {
363 #[xml(rename = "PlayMedia", ns(""))]
364 pub play_media: Option<String>,
365 #[xml(rename = "RecMedia", ns(""))]
366 pub rec_media: Option<String>,
367 #[xml(rename = "RecQualityModes", ns(""))]
368 pub rec_quality_modes: Option<String>,
369 }
370
371 impl crate::DecodeSoapResponse for GetDeviceCapabilitiesResponse {
372 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
373 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
374 Ok(envelope.body.payload)
375 }
376 }
377
378 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
379 #[xml(rename = "GetMediaInfo", ns(SERVICE_TYPE))]
380 pub struct GetMediaInfoRequest {
381 #[xml(rename = "InstanceID", ns(""))]
382 pub instance_id: u32,
383 }
384
385 #[derive(FromXml, Debug, Clone, PartialEq)]
386 #[xml(rename = "GetMediaInfoResponse", ns(SERVICE_TYPE))]
387 pub struct GetMediaInfoResponse {
388 #[xml(rename = "NrTracks", ns(""))]
389 pub nr_tracks: Option<u32>,
390 #[xml(rename = "MediaDuration", ns(""))]
391 pub media_duration: Option<String>,
392 #[xml(rename = "CurrentURI", ns(""))]
393 pub current_uri: Option<String>,
394 #[xml(rename = "CurrentURIMetaData", ns(""))]
395 pub current_uri_meta_data: Option<DecodeXmlString<crate::TrackMetaData>>,
396 #[xml(rename = "NextURI", ns(""))]
397 pub next_uri: Option<String>,
398 #[xml(rename = "NextURIMetaData", ns(""))]
399 pub next_uri_meta_data: Option<String>,
400 #[xml(rename = "PlayMedium", ns(""))]
401 pub play_medium: Option<super::PlaybackStorageMedium>,
402 #[xml(rename = "RecordMedium", ns(""))]
403 pub record_medium: Option<String>,
404 #[xml(rename = "WriteStatus", ns(""))]
405 pub write_status: Option<String>,
406 }
407
408 impl crate::DecodeSoapResponse for GetMediaInfoResponse {
409 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
410 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
411 Ok(envelope.body.payload)
412 }
413 }
414
415 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
416 #[xml(rename = "GetPositionInfo", ns(SERVICE_TYPE))]
417 pub struct GetPositionInfoRequest {
418 #[xml(rename = "InstanceID", ns(""))]
419 pub instance_id: u32,
420 }
421
422 #[derive(FromXml, Debug, Clone, PartialEq)]
423 #[xml(rename = "GetPositionInfoResponse", ns(SERVICE_TYPE))]
424 pub struct GetPositionInfoResponse {
425 #[xml(rename = "Track", ns(""))]
426 pub track: Option<u32>,
427 #[xml(rename = "TrackDuration", ns(""))]
428 pub track_duration: Option<String>,
429 #[xml(rename = "TrackMetaData", ns(""))]
430 pub track_meta_data: Option<DecodeXmlString<crate::TrackMetaData>>,
431 #[xml(rename = "TrackURI", ns(""))]
432 pub track_uri: Option<String>,
433 #[xml(rename = "RelTime", ns(""))]
434 pub rel_time: Option<String>,
435 #[xml(rename = "AbsTime", ns(""))]
436 pub abs_time: Option<String>,
437 #[xml(rename = "RelCount", ns(""))]
438 pub rel_count: Option<i32>,
439 #[xml(rename = "AbsCount", ns(""))]
440 pub abs_count: Option<i32>,
441 }
442
443 impl crate::DecodeSoapResponse for GetPositionInfoResponse {
444 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
445 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
446 Ok(envelope.body.payload)
447 }
448 }
449
450 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
451 #[xml(rename = "GetRemainingSleepTimerDuration", ns(SERVICE_TYPE))]
452 pub struct GetRemainingSleepTimerDurationRequest {
453 #[xml(rename = "InstanceID", ns(""))]
454 pub instance_id: u32,
455 }
456
457 #[derive(FromXml, Debug, Clone, PartialEq)]
458 #[xml(rename = "GetRemainingSleepTimerDurationResponse", ns(SERVICE_TYPE))]
459 pub struct GetRemainingSleepTimerDurationResponse {
460 #[xml(rename = "RemainingSleepTimerDuration", ns(""))]
461 pub remaining_sleep_timer_duration: Option<String>,
462 #[xml(rename = "CurrentSleepTimerGeneration", ns(""))]
463 pub current_sleep_timer_generation: Option<u32>,
464 }
465
466 impl crate::DecodeSoapResponse for GetRemainingSleepTimerDurationResponse {
467 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
468 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
469 Ok(envelope.body.payload)
470 }
471 }
472
473 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
474 #[xml(rename = "GetRunningAlarmProperties", ns(SERVICE_TYPE))]
475 pub struct GetRunningAlarmPropertiesRequest {
476 #[xml(rename = "InstanceID", ns(""))]
477 pub instance_id: u32,
478 }
479
480 #[derive(FromXml, Debug, Clone, PartialEq)]
481 #[xml(rename = "GetRunningAlarmPropertiesResponse", ns(SERVICE_TYPE))]
482 pub struct GetRunningAlarmPropertiesResponse {
483 #[xml(rename = "AlarmID", ns(""))]
484 pub alarm_id: Option<u32>,
485 #[xml(rename = "GroupID", ns(""))]
486 pub group_id: Option<String>,
487 #[xml(rename = "LoggedStartTime", ns(""))]
488 pub logged_start_time: Option<String>,
489 }
490
491 impl crate::DecodeSoapResponse for GetRunningAlarmPropertiesResponse {
492 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
493 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
494 Ok(envelope.body.payload)
495 }
496 }
497
498 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
499 #[xml(rename = "GetTransportInfo", ns(SERVICE_TYPE))]
500 pub struct GetTransportInfoRequest {
501 #[xml(rename = "InstanceID", ns(""))]
502 pub instance_id: u32,
503 }
504
505 #[derive(FromXml, Debug, Clone, PartialEq)]
506 #[xml(rename = "GetTransportInfoResponse", ns(SERVICE_TYPE))]
507 pub struct GetTransportInfoResponse {
508 #[xml(rename = "CurrentTransportState", ns(""))]
509 pub current_transport_state: Option<super::TransportState>,
510 #[xml(rename = "CurrentTransportStatus", ns(""))]
511 pub current_transport_status: Option<String>,
512 #[xml(rename = "CurrentSpeed", ns(""))]
513 pub current_speed: Option<String>,
514 }
515
516 impl crate::DecodeSoapResponse for GetTransportInfoResponse {
517 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
518 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
519 Ok(envelope.body.payload)
520 }
521 }
522
523 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
524 #[xml(rename = "GetTransportSettings", ns(SERVICE_TYPE))]
525 pub struct GetTransportSettingsRequest {
526 #[xml(rename = "InstanceID", ns(""))]
527 pub instance_id: u32,
528 }
529
530 #[derive(FromXml, Debug, Clone, PartialEq)]
531 #[xml(rename = "GetTransportSettingsResponse", ns(SERVICE_TYPE))]
532 pub struct GetTransportSettingsResponse {
533 #[xml(rename = "PlayMode", ns(""))]
534 pub play_mode: Option<super::CurrentPlayMode>,
535 #[xml(rename = "RecQualityMode", ns(""))]
536 pub rec_quality_mode: Option<String>,
537 }
538
539 impl crate::DecodeSoapResponse for GetTransportSettingsResponse {
540 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
541 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
542 Ok(envelope.body.payload)
543 }
544 }
545
546 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
547 #[xml(rename = "Next", ns(SERVICE_TYPE))]
548 pub struct NextRequest {
549 #[xml(rename = "InstanceID", ns(""))]
550 pub instance_id: u32,
551 }
552
553 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
554 #[xml(rename = "NotifyDeletedURI", ns(SERVICE_TYPE))]
555 pub struct NotifyDeletedUriRequest {
556 #[xml(rename = "InstanceID", ns(""))]
557 pub instance_id: u32,
558 #[xml(rename = "DeletedURI", ns(""))]
559 pub deleted_uri: String,
560 }
561
562 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
563 #[xml(rename = "Pause", ns(SERVICE_TYPE))]
564 pub struct PauseRequest {
565 #[xml(rename = "InstanceID", ns(""))]
566 pub instance_id: u32,
567 }
568
569 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
570 #[xml(rename = "Play", ns(SERVICE_TYPE))]
571 pub struct PlayRequest {
572 #[xml(rename = "InstanceID", ns(""))]
573 pub instance_id: u32,
574 #[xml(rename = "Speed", ns(""))]
576 pub speed: String,
577 }
578
579 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
580 #[xml(rename = "Previous", ns(SERVICE_TYPE))]
581 pub struct PreviousRequest {
582 #[xml(rename = "InstanceID", ns(""))]
583 pub instance_id: u32,
584 }
585
586 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
587 #[xml(rename = "RemoveAllTracksFromQueue", ns(SERVICE_TYPE))]
588 pub struct RemoveAllTracksFromQueueRequest {
589 #[xml(rename = "InstanceID", ns(""))]
590 pub instance_id: u32,
591 }
592
593 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
594 #[xml(rename = "RemoveTrackFromQueue", ns(SERVICE_TYPE))]
595 pub struct RemoveTrackFromQueueRequest {
596 #[xml(rename = "InstanceID", ns(""))]
597 pub instance_id: u32,
598 #[xml(rename = "ObjectID", ns(""))]
599 pub object_id: String,
600 #[xml(rename = "UpdateID", ns(""))]
601 pub update_id: u32,
602 }
603
604 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
605 #[xml(rename = "RemoveTrackRangeFromQueue", ns(SERVICE_TYPE))]
606 pub struct RemoveTrackRangeFromQueueRequest {
607 #[xml(rename = "InstanceID", ns(""))]
608 pub instance_id: u32,
609 #[xml(rename = "UpdateID", ns(""))]
611 pub update_id: u32,
612 #[xml(rename = "StartingIndex", ns(""))]
614 pub starting_index: u32,
615 #[xml(rename = "NumberOfTracks", ns(""))]
616 pub number_of_tracks: u32,
617 }
618
619 #[derive(FromXml, Debug, Clone, PartialEq)]
620 #[xml(rename = "RemoveTrackRangeFromQueueResponse", ns(SERVICE_TYPE))]
621 pub struct RemoveTrackRangeFromQueueResponse {
622 #[xml(rename = "NewUpdateID", ns(""))]
623 pub new_update_id: Option<u32>,
624 }
625
626 impl crate::DecodeSoapResponse for RemoveTrackRangeFromQueueResponse {
627 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
628 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
629 Ok(envelope.body.payload)
630 }
631 }
632
633 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
634 #[xml(rename = "ReorderTracksInQueue", ns(SERVICE_TYPE))]
635 pub struct ReorderTracksInQueueRequest {
636 #[xml(rename = "InstanceID", ns(""))]
637 pub instance_id: u32,
638 #[xml(rename = "StartingIndex", ns(""))]
639 pub starting_index: u32,
640 #[xml(rename = "NumberOfTracks", ns(""))]
641 pub number_of_tracks: u32,
642 #[xml(rename = "InsertBefore", ns(""))]
643 pub insert_before: u32,
644 #[xml(rename = "UpdateID", ns(""))]
645 pub update_id: u32,
646 }
647
648 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
649 #[xml(rename = "ReorderTracksInSavedQueue", ns(SERVICE_TYPE))]
650 pub struct ReorderTracksInSavedQueueRequest {
651 #[xml(rename = "InstanceID", ns(""))]
652 pub instance_id: u32,
653 #[xml(rename = "ObjectID", ns(""))]
654 pub object_id: String,
655 #[xml(rename = "UpdateID", ns(""))]
656 pub update_id: u32,
657 #[xml(rename = "TrackList", ns(""))]
658 pub track_list: String,
659 #[xml(rename = "NewPositionList", ns(""))]
660 pub new_position_list: String,
661 }
662
663 #[derive(FromXml, Debug, Clone, PartialEq)]
664 #[xml(rename = "ReorderTracksInSavedQueueResponse", ns(SERVICE_TYPE))]
665 pub struct ReorderTracksInSavedQueueResponse {
666 #[xml(rename = "QueueLengthChange", ns(""))]
667 pub queue_length_change: Option<i32>,
668 #[xml(rename = "NewQueueLength", ns(""))]
669 pub new_queue_length: Option<u32>,
670 #[xml(rename = "NewUpdateID", ns(""))]
671 pub new_update_id: Option<u32>,
672 }
673
674 impl crate::DecodeSoapResponse for ReorderTracksInSavedQueueResponse {
675 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
676 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
677 Ok(envelope.body.payload)
678 }
679 }
680
681 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
682 #[xml(rename = "RunAlarm", ns(SERVICE_TYPE))]
683 pub struct RunAlarmRequest {
684 #[xml(rename = "InstanceID", ns(""))]
685 pub instance_id: u32,
686 #[xml(rename = "AlarmID", ns(""))]
687 pub alarm_id: u32,
688 #[xml(rename = "LoggedStartTime", ns(""))]
689 pub logged_start_time: String,
690 #[xml(rename = "Duration", ns(""))]
691 pub duration: String,
692 #[xml(rename = "ProgramURI", ns(""))]
693 pub program_uri: String,
694 #[xml(rename = "ProgramMetaData", ns(""))]
695 pub program_meta_data: DecodeXmlString<crate::TrackMetaData>,
696 #[xml(rename = "PlayMode", ns(""))]
697 pub play_mode: super::CurrentPlayMode,
698 #[xml(rename = "Volume", ns(""))]
699 pub volume: u16,
700 #[xml(rename = "IncludeLinkedZones", ns(""))]
701 pub include_linked_zones: bool,
702 }
703
704 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
705 #[xml(rename = "SaveQueue", ns(SERVICE_TYPE))]
706 pub struct SaveQueueRequest {
707 #[xml(rename = "InstanceID", ns(""))]
708 pub instance_id: u32,
709 #[xml(rename = "Title", ns(""))]
711 pub title: String,
712 #[xml(rename = "ObjectID", ns(""))]
714 pub object_id: String,
715 }
716
717 #[derive(FromXml, Debug, Clone, PartialEq)]
718 #[xml(rename = "SaveQueueResponse", ns(SERVICE_TYPE))]
719 pub struct SaveQueueResponse {
720 #[xml(rename = "AssignedObjectID", ns(""))]
721 pub assigned_object_id: Option<String>,
722 }
723
724 impl crate::DecodeSoapResponse for SaveQueueResponse {
725 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
726 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
727 Ok(envelope.body.payload)
728 }
729 }
730
731 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
732 #[xml(rename = "Seek", ns(SERVICE_TYPE))]
733 pub struct SeekRequest {
734 #[xml(rename = "InstanceID", ns(""))]
735 pub instance_id: u32,
736 #[xml(rename = "Unit", ns(""))]
738 pub unit: super::SeekMode,
739 #[xml(rename = "Target", ns(""))]
741 pub target: String,
742 }
743
744 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
745 #[xml(rename = "SetAVTransportURI", ns(SERVICE_TYPE))]
746 pub struct SetAvTransportUriRequest {
747 #[xml(rename = "InstanceID", ns(""))]
748 pub instance_id: u32,
749 #[xml(rename = "CurrentURI", ns(""))]
751 pub current_uri: String,
752 #[xml(rename = "CurrentURIMetaData", ns(""))]
754 pub current_uri_meta_data: DecodeXmlString<crate::TrackMetaData>,
755 }
756
757 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
758 #[xml(rename = "SetCrossfadeMode", ns(SERVICE_TYPE))]
759 pub struct SetCrossfadeModeRequest {
760 #[xml(rename = "InstanceID", ns(""))]
761 pub instance_id: u32,
762 #[xml(rename = "CrossfadeMode", ns(""))]
763 pub crossfade_mode: bool,
764 }
765
766 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
767 #[xml(rename = "SetNextAVTransportURI", ns(SERVICE_TYPE))]
768 pub struct SetNextAvTransportUriRequest {
769 #[xml(rename = "InstanceID", ns(""))]
770 pub instance_id: u32,
771 #[xml(rename = "NextURI", ns(""))]
772 pub next_uri: String,
773 #[xml(rename = "NextURIMetaData", ns(""))]
774 pub next_uri_meta_data: String,
775 }
776
777 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
778 #[xml(rename = "SetPlayMode", ns(SERVICE_TYPE))]
779 pub struct SetPlayModeRequest {
780 #[xml(rename = "InstanceID", ns(""))]
781 pub instance_id: u32,
782 #[xml(rename = "NewPlayMode", ns(""))]
784 pub new_play_mode: super::CurrentPlayMode,
785 }
786
787 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
788 #[xml(rename = "SnoozeAlarm", ns(SERVICE_TYPE))]
789 pub struct SnoozeAlarmRequest {
790 #[xml(rename = "InstanceID", ns(""))]
791 pub instance_id: u32,
792 #[xml(rename = "Duration", ns(""))]
794 pub duration: String,
795 }
796
797 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
798 #[xml(rename = "StartAutoplay", ns(SERVICE_TYPE))]
799 pub struct StartAutoplayRequest {
800 #[xml(rename = "InstanceID", ns(""))]
801 pub instance_id: u32,
802 #[xml(rename = "ProgramURI", ns(""))]
803 pub program_uri: String,
804 #[xml(rename = "ProgramMetaData", ns(""))]
805 pub program_meta_data: DecodeXmlString<crate::TrackMetaData>,
806 #[xml(rename = "Volume", ns(""))]
807 pub volume: u16,
808 #[xml(rename = "IncludeLinkedZones", ns(""))]
809 pub include_linked_zones: bool,
810 #[xml(rename = "ResetVolumeAfter", ns(""))]
811 pub reset_volume_after: bool,
812 }
813
814 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
815 #[xml(rename = "Stop", ns(SERVICE_TYPE))]
816 pub struct StopRequest {
817 #[xml(rename = "InstanceID", ns(""))]
818 pub instance_id: u32,
819 }
820
821 #[derive(Debug, Clone, PartialEq, Default)]
825 pub struct AVTransportEvent {
826 pub last_change: Option<DecodeXmlString<AVTransportLastChangeMap>>,
827 }
828
829 #[derive(FromXml, Debug, Clone, PartialEq)]
830 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
831 struct AVTransportPropertySet {
832 pub properties: Vec<AVTransportProperty>,
833 }
834
835 #[derive(FromXml, Debug, Clone, PartialEq)]
836 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
837 struct AVTransportProperty {
838 #[xml(rename = "LastChange", ns(""))]
839 pub last_change: Option<DecodeXmlString<AVTransportLastChangeMap>>,
840 }
841
842 impl DecodeXml for AVTransportEvent {
843 fn decode_xml(xml: &str) -> crate::Result<Self> {
844 let mut result = Self::default();
845 let set: AVTransportPropertySet = instant_xml::from_str(xml)?;
846 for prop in set.properties {
847 if let Some(v) = prop.last_change {
848 result.last_change.replace(v);
849 }
850 }
851 Ok(result)
852 }
853 }
854
855 impl crate::SonosDevice {
856 pub async fn subscribe_av_transport(
858 &self,
859 ) -> crate::Result<crate::upnp::EventStream<AVTransportEvent>> {
860 self.subscribe_helper(&SERVICE_TYPE).await
861 }
862 }
863
864 #[derive(Debug, Clone, PartialEq, Default)]
865 pub struct AVTransportLastChange {
866 pub av_transport_uri: Option<String>,
867 pub av_transport_uri_meta_data: Option<DecodeXmlString<crate::TrackMetaData>>,
868 pub alarm_include_linked_zones: Option<bool>,
869 pub alarm_state: Option<String>,
870 pub alarm_volume: Option<u16>,
871 pub current_av_transport_uri: Option<String>,
872 pub enqueue_as_next: Option<bool>,
873 pub group_id: Option<String>,
874 pub iso8601_time: Option<String>,
875 pub instance_id: Option<u32>,
876 pub list_uri: Option<String>,
877 pub list_uri_meta_data: Option<String>,
878 pub member_id: Option<String>,
879 pub member_list: Option<String>,
880 pub num_tracks: Option<u32>,
881 pub num_tracks_change: Option<i32>,
882 pub object_id: Option<String>,
883 pub player_id: Option<String>,
884 pub queue: Option<String>,
885 pub rejoin_group: Option<bool>,
886 pub reset_volume_after: Option<bool>,
887 pub resume_playback: Option<bool>,
888 pub saved_queue_title: Option<String>,
889 pub seek_mode: Option<super::SeekMode>,
890 pub seek_target: Option<String>,
891 pub sleep_timer_state: Option<String>,
892 pub source_state: Option<String>,
893 pub stream_restart_state: Option<String>,
894 pub track_list: Option<String>,
895 pub track_number: Option<u32>,
896 pub transport_settings: Option<String>,
897 pub uri: Option<String>,
898 pub uri_meta_data: Option<String>,
899 pub vli_state: Option<String>,
900 pub absolute_counter_position: Option<i32>,
901 pub absolute_time_position: Option<String>,
902 pub alarm_id_running: Option<u32>,
903 pub alarm_logged_start_time: Option<String>,
904 pub alarm_running: Option<bool>,
905 pub current_crossfade_mode: Option<bool>,
906 pub current_media_duration: Option<String>,
907 pub current_play_mode: Option<super::CurrentPlayMode>,
908 pub current_record_quality_mode: Option<String>,
909 pub current_section: Option<u32>,
910 pub current_track: Option<u32>,
911 pub current_track_duration: Option<String>,
912 pub current_track_meta_data: Option<DecodeXmlString<crate::TrackMetaData>>,
913 pub current_track_uri: Option<String>,
914 pub current_transport_actions: Option<String>,
915 pub current_valid_play_modes: Option<String>,
916 pub direct_control_account_id: Option<String>,
917 pub direct_control_client_id: Option<String>,
918 pub direct_control_is_suspended: Option<bool>,
919 pub enqueued_transport_uri: Option<String>,
920 pub enqueued_transport_uri_meta_data: Option<DecodeXmlString<crate::TrackMetaData>>,
921 pub muse_sessions: Option<String>,
922 pub next_av_transport_uri: Option<String>,
923 pub next_av_transport_uri_meta_data: Option<String>,
924 pub next_track_meta_data: Option<String>,
925 pub next_track_uri: Option<String>,
926 pub number_of_tracks: Option<u32>,
927 pub playback_storage_medium: Option<super::PlaybackStorageMedium>,
928 pub possible_playback_storage_media: Option<String>,
929 pub possible_record_quality_modes: Option<String>,
930 pub possible_record_storage_media: Option<String>,
931 pub queue_update_id: Option<u32>,
932 pub record_medium_write_status: Option<String>,
933 pub record_storage_medium: Option<String>,
934 pub relative_counter_position: Option<i32>,
935 pub relative_time_position: Option<String>,
936 pub restart_pending: Option<bool>,
937 pub sleep_timer_generation: Option<u32>,
938 pub snooze_running: Option<bool>,
939 pub transport_error_description: Option<String>,
940 pub transport_error_http_code: Option<String>,
941 pub transport_error_http_headers: Option<String>,
942 pub transport_error_uri: Option<String>,
943 pub transport_play_speed: Option<String>,
944 pub transport_state: Option<super::TransportState>,
945 pub transport_status: Option<String>,
946 }
947
948 #[derive(FromXml)]
949 #[xml(rename = "AVTransportURI", ns(LAST_CHANGE_NS))]
950 #[allow(non_camel_case_types)]
951 struct AVTransportLastChangeAVTransportURI {
952 #[xml(attribute)]
953 val: Option<String>,
954 }
955
956 #[derive(FromXml)]
957 #[xml(rename = "AVTransportURIMetaData", ns(LAST_CHANGE_NS))]
958 #[allow(non_camel_case_types)]
959 struct AVTransportLastChangeAVTransportURIMetaData {
960 #[xml(attribute)]
961 val: Option<DecodeXmlString<crate::TrackMetaData>>,
962 }
963
964 #[derive(FromXml)]
965 #[xml(rename = "AlarmIncludeLinkedZones", ns(LAST_CHANGE_NS))]
966 #[allow(non_camel_case_types)]
967 struct AVTransportLastChangeAlarmIncludeLinkedZones {
968 #[xml(attribute)]
969 val: Option<bool>,
970 }
971
972 #[derive(FromXml)]
973 #[xml(rename = "AlarmState", ns(LAST_CHANGE_NS))]
974 #[allow(non_camel_case_types)]
975 struct AVTransportLastChangeAlarmState {
976 #[xml(attribute)]
977 val: Option<String>,
978 }
979
980 #[derive(FromXml)]
981 #[xml(rename = "AlarmVolume", ns(LAST_CHANGE_NS))]
982 #[allow(non_camel_case_types)]
983 struct AVTransportLastChangeAlarmVolume {
984 #[xml(attribute)]
985 val: Option<u16>,
986 }
987
988 #[derive(FromXml)]
989 #[xml(rename = "CurrentAVTransportURI", ns(LAST_CHANGE_NS))]
990 #[allow(non_camel_case_types)]
991 struct AVTransportLastChangeCurrentAVTransportURI {
992 #[xml(attribute)]
993 val: Option<String>,
994 }
995
996 #[derive(FromXml)]
997 #[xml(rename = "EnqueueAsNext", ns(LAST_CHANGE_NS))]
998 #[allow(non_camel_case_types)]
999 struct AVTransportLastChangeEnqueueAsNext {
1000 #[xml(attribute)]
1001 val: Option<bool>,
1002 }
1003
1004 #[derive(FromXml)]
1005 #[xml(rename = "GroupID", ns(LAST_CHANGE_NS))]
1006 #[allow(non_camel_case_types)]
1007 struct AVTransportLastChangeGroupID {
1008 #[xml(attribute)]
1009 val: Option<String>,
1010 }
1011
1012 #[derive(FromXml)]
1013 #[xml(rename = "ISO8601Time", ns(LAST_CHANGE_NS))]
1014 #[allow(non_camel_case_types)]
1015 struct AVTransportLastChangeISO8601Time {
1016 #[xml(attribute)]
1017 val: Option<String>,
1018 }
1019
1020 #[derive(FromXml)]
1021 #[xml(rename = "InstanceID", ns(LAST_CHANGE_NS))]
1022 #[allow(non_camel_case_types)]
1023 struct AVTransportLastChangeInstanceID {
1024 #[xml(attribute)]
1025 val: Option<u32>,
1026 }
1027
1028 #[derive(FromXml)]
1029 #[xml(rename = "LIST_URI", ns(LAST_CHANGE_NS))]
1030 #[allow(non_camel_case_types)]
1031 struct AVTransportLastChangeLIST_URI {
1032 #[xml(attribute)]
1033 val: Option<String>,
1034 }
1035
1036 #[derive(FromXml)]
1037 #[xml(rename = "LIST_URIMetaData", ns(LAST_CHANGE_NS))]
1038 #[allow(non_camel_case_types)]
1039 struct AVTransportLastChangeLIST_URIMetaData {
1040 #[xml(attribute)]
1041 val: Option<String>,
1042 }
1043
1044 #[derive(FromXml)]
1045 #[xml(rename = "MemberID", ns(LAST_CHANGE_NS))]
1046 #[allow(non_camel_case_types)]
1047 struct AVTransportLastChangeMemberID {
1048 #[xml(attribute)]
1049 val: Option<String>,
1050 }
1051
1052 #[derive(FromXml)]
1053 #[xml(rename = "MemberList", ns(LAST_CHANGE_NS))]
1054 #[allow(non_camel_case_types)]
1055 struct AVTransportLastChangeMemberList {
1056 #[xml(attribute)]
1057 val: Option<String>,
1058 }
1059
1060 #[derive(FromXml)]
1061 #[xml(rename = "NumTracks", ns(LAST_CHANGE_NS))]
1062 #[allow(non_camel_case_types)]
1063 struct AVTransportLastChangeNumTracks {
1064 #[xml(attribute)]
1065 val: Option<u32>,
1066 }
1067
1068 #[derive(FromXml)]
1069 #[xml(rename = "NumTracksChange", ns(LAST_CHANGE_NS))]
1070 #[allow(non_camel_case_types)]
1071 struct AVTransportLastChangeNumTracksChange {
1072 #[xml(attribute)]
1073 val: Option<i32>,
1074 }
1075
1076 #[derive(FromXml)]
1077 #[xml(rename = "ObjectID", ns(LAST_CHANGE_NS))]
1078 #[allow(non_camel_case_types)]
1079 struct AVTransportLastChangeObjectID {
1080 #[xml(attribute)]
1081 val: Option<String>,
1082 }
1083
1084 #[derive(FromXml)]
1085 #[xml(rename = "PlayerID", ns(LAST_CHANGE_NS))]
1086 #[allow(non_camel_case_types)]
1087 struct AVTransportLastChangePlayerID {
1088 #[xml(attribute)]
1089 val: Option<String>,
1090 }
1091
1092 #[derive(FromXml)]
1093 #[xml(rename = "Queue", ns(LAST_CHANGE_NS))]
1094 #[allow(non_camel_case_types)]
1095 struct AVTransportLastChangeQueue {
1096 #[xml(attribute)]
1097 val: Option<String>,
1098 }
1099
1100 #[derive(FromXml)]
1101 #[xml(rename = "RejoinGroup", ns(LAST_CHANGE_NS))]
1102 #[allow(non_camel_case_types)]
1103 struct AVTransportLastChangeRejoinGroup {
1104 #[xml(attribute)]
1105 val: Option<bool>,
1106 }
1107
1108 #[derive(FromXml)]
1109 #[xml(rename = "ResetVolumeAfter", ns(LAST_CHANGE_NS))]
1110 #[allow(non_camel_case_types)]
1111 struct AVTransportLastChangeResetVolumeAfter {
1112 #[xml(attribute)]
1113 val: Option<bool>,
1114 }
1115
1116 #[derive(FromXml)]
1117 #[xml(rename = "ResumePlayback", ns(LAST_CHANGE_NS))]
1118 #[allow(non_camel_case_types)]
1119 struct AVTransportLastChangeResumePlayback {
1120 #[xml(attribute)]
1121 val: Option<bool>,
1122 }
1123
1124 #[derive(FromXml)]
1125 #[xml(rename = "SavedQueueTitle", ns(LAST_CHANGE_NS))]
1126 #[allow(non_camel_case_types)]
1127 struct AVTransportLastChangeSavedQueueTitle {
1128 #[xml(attribute)]
1129 val: Option<String>,
1130 }
1131
1132 #[derive(FromXml)]
1133 #[xml(rename = "SeekMode", ns(LAST_CHANGE_NS))]
1134 #[allow(non_camel_case_types)]
1135 struct AVTransportLastChangeSeekMode {
1136 #[xml(attribute)]
1137 val: Option<super::SeekMode>,
1138 }
1139
1140 #[derive(FromXml)]
1141 #[xml(rename = "SeekTarget", ns(LAST_CHANGE_NS))]
1142 #[allow(non_camel_case_types)]
1143 struct AVTransportLastChangeSeekTarget {
1144 #[xml(attribute)]
1145 val: Option<String>,
1146 }
1147
1148 #[derive(FromXml)]
1149 #[xml(rename = "SleepTimerState", ns(LAST_CHANGE_NS))]
1150 #[allow(non_camel_case_types)]
1151 struct AVTransportLastChangeSleepTimerState {
1152 #[xml(attribute)]
1153 val: Option<String>,
1154 }
1155
1156 #[derive(FromXml)]
1157 #[xml(rename = "SourceState", ns(LAST_CHANGE_NS))]
1158 #[allow(non_camel_case_types)]
1159 struct AVTransportLastChangeSourceState {
1160 #[xml(attribute)]
1161 val: Option<String>,
1162 }
1163
1164 #[derive(FromXml)]
1165 #[xml(rename = "StreamRestartState", ns(LAST_CHANGE_NS))]
1166 #[allow(non_camel_case_types)]
1167 struct AVTransportLastChangeStreamRestartState {
1168 #[xml(attribute)]
1169 val: Option<String>,
1170 }
1171
1172 #[derive(FromXml)]
1173 #[xml(rename = "TrackList", ns(LAST_CHANGE_NS))]
1174 #[allow(non_camel_case_types)]
1175 struct AVTransportLastChangeTrackList {
1176 #[xml(attribute)]
1177 val: Option<String>,
1178 }
1179
1180 #[derive(FromXml)]
1181 #[xml(rename = "TrackNumber", ns(LAST_CHANGE_NS))]
1182 #[allow(non_camel_case_types)]
1183 struct AVTransportLastChangeTrackNumber {
1184 #[xml(attribute)]
1185 val: Option<u32>,
1186 }
1187
1188 #[derive(FromXml)]
1189 #[xml(rename = "TransportSettings", ns(LAST_CHANGE_NS))]
1190 #[allow(non_camel_case_types)]
1191 struct AVTransportLastChangeTransportSettings {
1192 #[xml(attribute)]
1193 val: Option<String>,
1194 }
1195
1196 #[derive(FromXml)]
1197 #[xml(rename = "URI", ns(LAST_CHANGE_NS))]
1198 #[allow(non_camel_case_types)]
1199 struct AVTransportLastChangeURI {
1200 #[xml(attribute)]
1201 val: Option<String>,
1202 }
1203
1204 #[derive(FromXml)]
1205 #[xml(rename = "URIMetaData", ns(LAST_CHANGE_NS))]
1206 #[allow(non_camel_case_types)]
1207 struct AVTransportLastChangeURIMetaData {
1208 #[xml(attribute)]
1209 val: Option<String>,
1210 }
1211
1212 #[derive(FromXml)]
1213 #[xml(rename = "VLIState", ns(LAST_CHANGE_NS))]
1214 #[allow(non_camel_case_types)]
1215 struct AVTransportLastChangeVLIState {
1216 #[xml(attribute)]
1217 val: Option<String>,
1218 }
1219
1220 #[derive(FromXml)]
1221 #[xml(rename = "AbsoluteCounterPosition", ns(LAST_CHANGE_NS))]
1222 #[allow(non_camel_case_types)]
1223 struct AVTransportLastChangeAbsoluteCounterPosition {
1224 #[xml(attribute)]
1225 val: Option<i32>,
1226 }
1227
1228 #[derive(FromXml)]
1229 #[xml(rename = "AbsoluteTimePosition", ns(LAST_CHANGE_NS))]
1230 #[allow(non_camel_case_types)]
1231 struct AVTransportLastChangeAbsoluteTimePosition {
1232 #[xml(attribute)]
1233 val: Option<String>,
1234 }
1235
1236 #[derive(FromXml)]
1237 #[xml(rename = "AlarmIDRunning", ns(LAST_CHANGE_NS))]
1238 #[allow(non_camel_case_types)]
1239 struct AVTransportLastChangeAlarmIDRunning {
1240 #[xml(attribute)]
1241 val: Option<u32>,
1242 }
1243
1244 #[derive(FromXml)]
1245 #[xml(rename = "AlarmLoggedStartTime", ns(LAST_CHANGE_NS))]
1246 #[allow(non_camel_case_types)]
1247 struct AVTransportLastChangeAlarmLoggedStartTime {
1248 #[xml(attribute)]
1249 val: Option<String>,
1250 }
1251
1252 #[derive(FromXml)]
1253 #[xml(
1254 rename = "AlarmRunning",
1255 ns("urn:schemas-rinconnetworks-com:metadata-1-0/")
1256 )]
1257 #[allow(non_camel_case_types)]
1258 struct AVTransportLastChangeAlarmRunning {
1259 #[xml(attribute)]
1260 val: Option<bool>,
1261 }
1262
1263 #[derive(FromXml)]
1264 #[xml(rename = "CurrentCrossfadeMode", ns(LAST_CHANGE_NS))]
1265 #[allow(non_camel_case_types)]
1266 struct AVTransportLastChangeCurrentCrossfadeMode {
1267 #[xml(attribute)]
1268 val: Option<bool>,
1269 }
1270
1271 #[derive(FromXml)]
1272 #[xml(rename = "CurrentMediaDuration", ns(LAST_CHANGE_NS))]
1273 #[allow(non_camel_case_types)]
1274 struct AVTransportLastChangeCurrentMediaDuration {
1275 #[xml(attribute)]
1276 val: Option<String>,
1277 }
1278
1279 #[derive(FromXml)]
1280 #[xml(rename = "CurrentPlayMode", ns(LAST_CHANGE_NS))]
1281 #[allow(non_camel_case_types)]
1282 struct AVTransportLastChangeCurrentPlayMode {
1283 #[xml(attribute)]
1284 val: Option<super::CurrentPlayMode>,
1285 }
1286
1287 #[derive(FromXml)]
1288 #[xml(rename = "CurrentRecordQualityMode", ns(LAST_CHANGE_NS))]
1289 #[allow(non_camel_case_types)]
1290 struct AVTransportLastChangeCurrentRecordQualityMode {
1291 #[xml(attribute)]
1292 val: Option<String>,
1293 }
1294
1295 #[derive(FromXml)]
1296 #[xml(rename = "CurrentSection", ns(LAST_CHANGE_NS))]
1297 #[allow(non_camel_case_types)]
1298 struct AVTransportLastChangeCurrentSection {
1299 #[xml(attribute)]
1300 val: Option<u32>,
1301 }
1302
1303 #[derive(FromXml)]
1304 #[xml(rename = "CurrentTrack", ns(LAST_CHANGE_NS))]
1305 #[allow(non_camel_case_types)]
1306 struct AVTransportLastChangeCurrentTrack {
1307 #[xml(attribute)]
1308 val: Option<u32>,
1309 }
1310
1311 #[derive(FromXml)]
1312 #[xml(rename = "CurrentTrackDuration", ns(LAST_CHANGE_NS))]
1313 #[allow(non_camel_case_types)]
1314 struct AVTransportLastChangeCurrentTrackDuration {
1315 #[xml(attribute)]
1316 val: Option<String>,
1317 }
1318
1319 #[derive(FromXml)]
1320 #[xml(rename = "CurrentTrackMetaData", ns(LAST_CHANGE_NS))]
1321 #[allow(non_camel_case_types)]
1322 struct AVTransportLastChangeCurrentTrackMetaData {
1323 #[xml(attribute)]
1324 val: Option<DecodeXmlString<crate::TrackMetaData>>,
1325 }
1326
1327 #[derive(FromXml)]
1328 #[xml(rename = "CurrentTrackURI", ns(LAST_CHANGE_NS))]
1329 #[allow(non_camel_case_types)]
1330 struct AVTransportLastChangeCurrentTrackURI {
1331 #[xml(attribute)]
1332 val: Option<String>,
1333 }
1334
1335 #[derive(FromXml)]
1336 #[xml(rename = "CurrentTransportActions", ns(LAST_CHANGE_NS))]
1337 #[allow(non_camel_case_types)]
1338 struct AVTransportLastChangeCurrentTransportActions {
1339 #[xml(attribute)]
1340 val: Option<String>,
1341 }
1342
1343 #[derive(FromXml)]
1344 #[xml(
1345 rename = "CurrentValidPlayModes",
1346 ns("urn:schemas-rinconnetworks-com:metadata-1-0/")
1347 )]
1348 #[allow(non_camel_case_types)]
1349 struct AVTransportLastChangeCurrentValidPlayModes {
1350 #[xml(attribute)]
1351 val: Option<String>,
1352 }
1353
1354 #[derive(FromXml)]
1355 #[xml(
1356 rename = "DirectControlAccountID",
1357 ns("urn:schemas-rinconnetworks-com:metadata-1-0/")
1358 )]
1359 #[allow(non_camel_case_types)]
1360 struct AVTransportLastChangeDirectControlAccountID {
1361 #[xml(attribute)]
1362 val: Option<String>,
1363 }
1364
1365 #[derive(FromXml)]
1366 #[xml(
1367 rename = "DirectControlClientID",
1368 ns("urn:schemas-rinconnetworks-com:metadata-1-0/")
1369 )]
1370 #[allow(non_camel_case_types)]
1371 struct AVTransportLastChangeDirectControlClientID {
1372 #[xml(attribute)]
1373 val: Option<String>,
1374 }
1375
1376 #[derive(FromXml)]
1377 #[xml(
1378 rename = "DirectControlIsSuspended",
1379 ns("urn:schemas-rinconnetworks-com:metadata-1-0/")
1380 )]
1381 #[allow(non_camel_case_types)]
1382 struct AVTransportLastChangeDirectControlIsSuspended {
1383 #[xml(attribute)]
1384 val: Option<bool>,
1385 }
1386
1387 #[derive(FromXml)]
1388 #[xml(
1389 rename = "EnqueuedTransportURI",
1390 ns("urn:schemas-rinconnetworks-com:metadata-1-0/")
1391 )]
1392 #[allow(non_camel_case_types)]
1393 struct AVTransportLastChangeEnqueuedTransportURI {
1394 #[xml(attribute)]
1395 val: Option<String>,
1396 }
1397
1398 #[derive(FromXml)]
1399 #[xml(
1400 rename = "EnqueuedTransportURIMetaData",
1401 ns("urn:schemas-rinconnetworks-com:metadata-1-0/")
1402 )]
1403 #[allow(non_camel_case_types)]
1404 struct AVTransportLastChangeEnqueuedTransportURIMetaData {
1405 #[xml(attribute)]
1406 val: Option<DecodeXmlString<crate::TrackMetaData>>,
1407 }
1408
1409 #[derive(FromXml)]
1410 #[xml(rename = "MuseSessions", ns(LAST_CHANGE_NS))]
1411 #[allow(non_camel_case_types)]
1412 struct AVTransportLastChangeMuseSessions {
1413 #[xml(attribute)]
1414 val: Option<String>,
1415 }
1416
1417 #[derive(FromXml)]
1418 #[xml(rename = "NextAVTransportURI", ns(LAST_CHANGE_NS))]
1419 #[allow(non_camel_case_types)]
1420 struct AVTransportLastChangeNextAVTransportURI {
1421 #[xml(attribute)]
1422 val: Option<String>,
1423 }
1424
1425 #[derive(FromXml)]
1426 #[xml(rename = "NextAVTransportURIMetaData", ns(LAST_CHANGE_NS))]
1427 #[allow(non_camel_case_types)]
1428 struct AVTransportLastChangeNextAVTransportURIMetaData {
1429 #[xml(attribute)]
1430 val: Option<String>,
1431 }
1432
1433 #[derive(FromXml)]
1434 #[xml(
1435 rename = "NextTrackMetaData",
1436 ns("urn:schemas-rinconnetworks-com:metadata-1-0/")
1437 )]
1438 #[allow(non_camel_case_types)]
1439 struct AVTransportLastChangeNextTrackMetaData {
1440 #[xml(attribute)]
1441 val: Option<String>,
1442 }
1443
1444 #[derive(FromXml)]
1445 #[xml(
1446 rename = "NextTrackURI",
1447 ns("urn:schemas-rinconnetworks-com:metadata-1-0/")
1448 )]
1449 #[allow(non_camel_case_types)]
1450 struct AVTransportLastChangeNextTrackURI {
1451 #[xml(attribute)]
1452 val: Option<String>,
1453 }
1454
1455 #[derive(FromXml)]
1456 #[xml(rename = "NumberOfTracks", ns(LAST_CHANGE_NS))]
1457 #[allow(non_camel_case_types)]
1458 struct AVTransportLastChangeNumberOfTracks {
1459 #[xml(attribute)]
1460 val: Option<u32>,
1461 }
1462
1463 #[derive(FromXml)]
1464 #[xml(rename = "PlaybackStorageMedium", ns(LAST_CHANGE_NS))]
1465 #[allow(non_camel_case_types)]
1466 struct AVTransportLastChangePlaybackStorageMedium {
1467 #[xml(attribute)]
1468 val: Option<super::PlaybackStorageMedium>,
1469 }
1470
1471 #[derive(FromXml)]
1472 #[xml(rename = "PossiblePlaybackStorageMedia", ns(LAST_CHANGE_NS))]
1473 #[allow(non_camel_case_types)]
1474 struct AVTransportLastChangePossiblePlaybackStorageMedia {
1475 #[xml(attribute)]
1476 val: Option<String>,
1477 }
1478
1479 #[derive(FromXml)]
1480 #[xml(rename = "PossibleRecordQualityModes", ns(LAST_CHANGE_NS))]
1481 #[allow(non_camel_case_types)]
1482 struct AVTransportLastChangePossibleRecordQualityModes {
1483 #[xml(attribute)]
1484 val: Option<String>,
1485 }
1486
1487 #[derive(FromXml)]
1488 #[xml(rename = "PossibleRecordStorageMedia", ns(LAST_CHANGE_NS))]
1489 #[allow(non_camel_case_types)]
1490 struct AVTransportLastChangePossibleRecordStorageMedia {
1491 #[xml(attribute)]
1492 val: Option<String>,
1493 }
1494
1495 #[derive(FromXml)]
1496 #[xml(rename = "QueueUpdateID", ns(LAST_CHANGE_NS))]
1497 #[allow(non_camel_case_types)]
1498 struct AVTransportLastChangeQueueUpdateID {
1499 #[xml(attribute)]
1500 val: Option<u32>,
1501 }
1502
1503 #[derive(FromXml)]
1504 #[xml(rename = "RecordMediumWriteStatus", ns(LAST_CHANGE_NS))]
1505 #[allow(non_camel_case_types)]
1506 struct AVTransportLastChangeRecordMediumWriteStatus {
1507 #[xml(attribute)]
1508 val: Option<String>,
1509 }
1510
1511 #[derive(FromXml)]
1512 #[xml(rename = "RecordStorageMedium", ns(LAST_CHANGE_NS))]
1513 #[allow(non_camel_case_types)]
1514 struct AVTransportLastChangeRecordStorageMedium {
1515 #[xml(attribute)]
1516 val: Option<String>,
1517 }
1518
1519 #[derive(FromXml)]
1520 #[xml(rename = "RelativeCounterPosition", ns(LAST_CHANGE_NS))]
1521 #[allow(non_camel_case_types)]
1522 struct AVTransportLastChangeRelativeCounterPosition {
1523 #[xml(attribute)]
1524 val: Option<i32>,
1525 }
1526
1527 #[derive(FromXml)]
1528 #[xml(rename = "RelativeTimePosition", ns(LAST_CHANGE_NS))]
1529 #[allow(non_camel_case_types)]
1530 struct AVTransportLastChangeRelativeTimePosition {
1531 #[xml(attribute)]
1532 val: Option<String>,
1533 }
1534
1535 #[derive(FromXml)]
1536 #[xml(
1537 rename = "RestartPending",
1538 ns("urn:schemas-rinconnetworks-com:metadata-1-0/")
1539 )]
1540 #[allow(non_camel_case_types)]
1541 struct AVTransportLastChangeRestartPending {
1542 #[xml(attribute)]
1543 val: Option<bool>,
1544 }
1545
1546 #[derive(FromXml)]
1547 #[xml(
1548 rename = "SleepTimerGeneration",
1549 ns("urn:schemas-rinconnetworks-com:metadata-1-0/")
1550 )]
1551 #[allow(non_camel_case_types)]
1552 struct AVTransportLastChangeSleepTimerGeneration {
1553 #[xml(attribute)]
1554 val: Option<u32>,
1555 }
1556
1557 #[derive(FromXml)]
1558 #[xml(
1559 rename = "SnoozeRunning",
1560 ns("urn:schemas-rinconnetworks-com:metadata-1-0/")
1561 )]
1562 #[allow(non_camel_case_types)]
1563 struct AVTransportLastChangeSnoozeRunning {
1564 #[xml(attribute)]
1565 val: Option<bool>,
1566 }
1567
1568 #[derive(FromXml)]
1569 #[xml(rename = "TransportErrorDescription", ns(LAST_CHANGE_NS))]
1570 #[allow(non_camel_case_types)]
1571 struct AVTransportLastChangeTransportErrorDescription {
1572 #[xml(attribute)]
1573 val: Option<String>,
1574 }
1575
1576 #[derive(FromXml)]
1577 #[xml(rename = "TransportErrorHttpCode", ns(LAST_CHANGE_NS))]
1578 #[allow(non_camel_case_types)]
1579 struct AVTransportLastChangeTransportErrorHttpCode {
1580 #[xml(attribute)]
1581 val: Option<String>,
1582 }
1583
1584 #[derive(FromXml)]
1585 #[xml(rename = "TransportErrorHttpHeaders", ns(LAST_CHANGE_NS))]
1586 #[allow(non_camel_case_types)]
1587 struct AVTransportLastChangeTransportErrorHttpHeaders {
1588 #[xml(attribute)]
1589 val: Option<String>,
1590 }
1591
1592 #[derive(FromXml)]
1593 #[xml(rename = "TransportErrorURI", ns(LAST_CHANGE_NS))]
1594 #[allow(non_camel_case_types)]
1595 struct AVTransportLastChangeTransportErrorURI {
1596 #[xml(attribute)]
1597 val: Option<String>,
1598 }
1599
1600 #[derive(FromXml)]
1601 #[xml(rename = "TransportPlaySpeed", ns(LAST_CHANGE_NS))]
1602 #[allow(non_camel_case_types)]
1603 struct AVTransportLastChangeTransportPlaySpeed {
1604 #[xml(attribute)]
1605 val: Option<String>,
1606 }
1607
1608 #[derive(FromXml)]
1609 #[xml(rename = "TransportState", ns(LAST_CHANGE_NS))]
1610 #[allow(non_camel_case_types)]
1611 struct AVTransportLastChangeTransportState {
1612 #[xml(attribute)]
1613 val: Option<super::TransportState>,
1614 }
1615
1616 #[derive(FromXml)]
1617 #[xml(rename = "TransportStatus", ns(LAST_CHANGE_NS))]
1618 #[allow(non_camel_case_types)]
1619 struct AVTransportLastChangeTransportStatus {
1620 #[xml(attribute)]
1621 val: Option<String>,
1622 }
1623
1624 const LAST_CHANGE_NS: &str = "urn:schemas-upnp-org:metadata-1-0/AVT/";
1625
1626 #[derive(FromXml)]
1627 #[xml(rename = "InstanceID", ns(LAST_CHANGE_NS))]
1628 struct AVTransportLastChangeRootObject {
1629 #[xml(rename = "val", attribute)]
1630 object_instance_id_: u32,
1631
1632 av_transport_uri: Option<AVTransportLastChangeAVTransportURI>,
1633 av_transport_uri_meta_data: Option<AVTransportLastChangeAVTransportURIMetaData>,
1634 alarm_include_linked_zones: Option<AVTransportLastChangeAlarmIncludeLinkedZones>,
1635 alarm_state: Option<AVTransportLastChangeAlarmState>,
1636 alarm_volume: Option<AVTransportLastChangeAlarmVolume>,
1637 current_av_transport_uri: Option<AVTransportLastChangeCurrentAVTransportURI>,
1638 enqueue_as_next: Option<AVTransportLastChangeEnqueueAsNext>,
1639 group_id: Option<AVTransportLastChangeGroupID>,
1640 iso8601_time: Option<AVTransportLastChangeISO8601Time>,
1641 instance_id: Option<AVTransportLastChangeInstanceID>,
1642 list_uri: Option<AVTransportLastChangeLIST_URI>,
1643 list_uri_meta_data: Option<AVTransportLastChangeLIST_URIMetaData>,
1644 member_id: Option<AVTransportLastChangeMemberID>,
1645 member_list: Option<AVTransportLastChangeMemberList>,
1646 num_tracks: Option<AVTransportLastChangeNumTracks>,
1647 num_tracks_change: Option<AVTransportLastChangeNumTracksChange>,
1648 object_id: Option<AVTransportLastChangeObjectID>,
1649 player_id: Option<AVTransportLastChangePlayerID>,
1650 queue: Option<AVTransportLastChangeQueue>,
1651 rejoin_group: Option<AVTransportLastChangeRejoinGroup>,
1652 reset_volume_after: Option<AVTransportLastChangeResetVolumeAfter>,
1653 resume_playback: Option<AVTransportLastChangeResumePlayback>,
1654 saved_queue_title: Option<AVTransportLastChangeSavedQueueTitle>,
1655 seek_mode: Option<AVTransportLastChangeSeekMode>,
1656 seek_target: Option<AVTransportLastChangeSeekTarget>,
1657 sleep_timer_state: Option<AVTransportLastChangeSleepTimerState>,
1658 source_state: Option<AVTransportLastChangeSourceState>,
1659 stream_restart_state: Option<AVTransportLastChangeStreamRestartState>,
1660 track_list: Option<AVTransportLastChangeTrackList>,
1661 track_number: Option<AVTransportLastChangeTrackNumber>,
1662 transport_settings: Option<AVTransportLastChangeTransportSettings>,
1663 uri: Option<AVTransportLastChangeURI>,
1664 uri_meta_data: Option<AVTransportLastChangeURIMetaData>,
1665 vli_state: Option<AVTransportLastChangeVLIState>,
1666 absolute_counter_position: Option<AVTransportLastChangeAbsoluteCounterPosition>,
1667 absolute_time_position: Option<AVTransportLastChangeAbsoluteTimePosition>,
1668 alarm_id_running: Option<AVTransportLastChangeAlarmIDRunning>,
1669 alarm_logged_start_time: Option<AVTransportLastChangeAlarmLoggedStartTime>,
1670 alarm_running: Option<AVTransportLastChangeAlarmRunning>,
1671 current_crossfade_mode: Option<AVTransportLastChangeCurrentCrossfadeMode>,
1672 current_media_duration: Option<AVTransportLastChangeCurrentMediaDuration>,
1673 current_play_mode: Option<AVTransportLastChangeCurrentPlayMode>,
1674 current_record_quality_mode: Option<AVTransportLastChangeCurrentRecordQualityMode>,
1675 current_section: Option<AVTransportLastChangeCurrentSection>,
1676 current_track: Option<AVTransportLastChangeCurrentTrack>,
1677 current_track_duration: Option<AVTransportLastChangeCurrentTrackDuration>,
1678 current_track_meta_data: Option<AVTransportLastChangeCurrentTrackMetaData>,
1679 current_track_uri: Option<AVTransportLastChangeCurrentTrackURI>,
1680 current_transport_actions: Option<AVTransportLastChangeCurrentTransportActions>,
1681 current_valid_play_modes: Option<AVTransportLastChangeCurrentValidPlayModes>,
1682 direct_control_account_id: Option<AVTransportLastChangeDirectControlAccountID>,
1683 direct_control_client_id: Option<AVTransportLastChangeDirectControlClientID>,
1684 direct_control_is_suspended: Option<AVTransportLastChangeDirectControlIsSuspended>,
1685 enqueued_transport_uri: Option<AVTransportLastChangeEnqueuedTransportURI>,
1686 enqueued_transport_uri_meta_data: Option<AVTransportLastChangeEnqueuedTransportURIMetaData>,
1687 muse_sessions: Option<AVTransportLastChangeMuseSessions>,
1688 next_av_transport_uri: Option<AVTransportLastChangeNextAVTransportURI>,
1689 next_av_transport_uri_meta_data: Option<AVTransportLastChangeNextAVTransportURIMetaData>,
1690 next_track_meta_data: Option<AVTransportLastChangeNextTrackMetaData>,
1691 next_track_uri: Option<AVTransportLastChangeNextTrackURI>,
1692 number_of_tracks: Option<AVTransportLastChangeNumberOfTracks>,
1693 playback_storage_medium: Option<AVTransportLastChangePlaybackStorageMedium>,
1694 possible_playback_storage_media: Option<AVTransportLastChangePossiblePlaybackStorageMedia>,
1695 possible_record_quality_modes: Option<AVTransportLastChangePossibleRecordQualityModes>,
1696 possible_record_storage_media: Option<AVTransportLastChangePossibleRecordStorageMedia>,
1697 queue_update_id: Option<AVTransportLastChangeQueueUpdateID>,
1698 record_medium_write_status: Option<AVTransportLastChangeRecordMediumWriteStatus>,
1699 record_storage_medium: Option<AVTransportLastChangeRecordStorageMedium>,
1700 relative_counter_position: Option<AVTransportLastChangeRelativeCounterPosition>,
1701 relative_time_position: Option<AVTransportLastChangeRelativeTimePosition>,
1702 restart_pending: Option<AVTransportLastChangeRestartPending>,
1703 sleep_timer_generation: Option<AVTransportLastChangeSleepTimerGeneration>,
1704 snooze_running: Option<AVTransportLastChangeSnoozeRunning>,
1705 transport_error_description: Option<AVTransportLastChangeTransportErrorDescription>,
1706 transport_error_http_code: Option<AVTransportLastChangeTransportErrorHttpCode>,
1707 transport_error_http_headers: Option<AVTransportLastChangeTransportErrorHttpHeaders>,
1708 transport_error_uri: Option<AVTransportLastChangeTransportErrorURI>,
1709 transport_play_speed: Option<AVTransportLastChangeTransportPlaySpeed>,
1710 transport_state: Option<AVTransportLastChangeTransportState>,
1711 transport_status: Option<AVTransportLastChangeTransportStatus>,
1712 }
1713
1714 #[derive(Debug, Clone, PartialEq, Default)]
1715 pub struct AVTransportLastChangeMap {
1716 pub map: std::collections::BTreeMap<u32, AVTransportLastChange>,
1717 }
1718
1719 impl DecodeXml for AVTransportLastChangeMap {
1720 fn decode_xml(xml: &str) -> crate::Result<Self> {
1721 #[derive(FromXml)]
1722 #[xml(ns(LAST_CHANGE_NS, r = "urn:schemas-rinconnetworks-com:metadata-1-0/"))]
1723 struct Event {
1724 instance: Vec<AVTransportLastChangeRootObject>,
1725 }
1726
1727 let last_change: Event = instant_xml::from_str(xml)?;
1728 let mut map = std::collections::BTreeMap::new();
1729
1730 for item in last_change.instance {
1731 let mut result = AVTransportLastChange::default();
1732
1733 result.av_transport_uri = item.av_transport_uri.and_then(|v| v.val);
1734
1735 result.av_transport_uri_meta_data =
1736 item.av_transport_uri_meta_data.and_then(|v| v.val);
1737
1738 result.alarm_include_linked_zones =
1739 item.alarm_include_linked_zones.and_then(|v| v.val);
1740
1741 result.alarm_state = item.alarm_state.and_then(|v| v.val);
1742
1743 result.alarm_volume = item.alarm_volume.and_then(|v| v.val);
1744
1745 result.current_av_transport_uri = item.current_av_transport_uri.and_then(|v| v.val);
1746
1747 result.enqueue_as_next = item.enqueue_as_next.and_then(|v| v.val);
1748
1749 result.group_id = item.group_id.and_then(|v| v.val);
1750
1751 result.iso8601_time = item.iso8601_time.and_then(|v| v.val);
1752
1753 result.instance_id = item.instance_id.and_then(|v| v.val);
1754
1755 result.list_uri = item.list_uri.and_then(|v| v.val);
1756
1757 result.list_uri_meta_data = item.list_uri_meta_data.and_then(|v| v.val);
1758
1759 result.member_id = item.member_id.and_then(|v| v.val);
1760
1761 result.member_list = item.member_list.and_then(|v| v.val);
1762
1763 result.num_tracks = item.num_tracks.and_then(|v| v.val);
1764
1765 result.num_tracks_change = item.num_tracks_change.and_then(|v| v.val);
1766
1767 result.object_id = item.object_id.and_then(|v| v.val);
1768
1769 result.player_id = item.player_id.and_then(|v| v.val);
1770
1771 result.queue = item.queue.and_then(|v| v.val);
1772
1773 result.rejoin_group = item.rejoin_group.and_then(|v| v.val);
1774
1775 result.reset_volume_after = item.reset_volume_after.and_then(|v| v.val);
1776
1777 result.resume_playback = item.resume_playback.and_then(|v| v.val);
1778
1779 result.saved_queue_title = item.saved_queue_title.and_then(|v| v.val);
1780
1781 result.seek_mode = item.seek_mode.and_then(|v| v.val);
1782
1783 result.seek_target = item.seek_target.and_then(|v| v.val);
1784
1785 result.sleep_timer_state = item.sleep_timer_state.and_then(|v| v.val);
1786
1787 result.source_state = item.source_state.and_then(|v| v.val);
1788
1789 result.stream_restart_state = item.stream_restart_state.and_then(|v| v.val);
1790
1791 result.track_list = item.track_list.and_then(|v| v.val);
1792
1793 result.track_number = item.track_number.and_then(|v| v.val);
1794
1795 result.transport_settings = item.transport_settings.and_then(|v| v.val);
1796
1797 result.uri = item.uri.and_then(|v| v.val);
1798
1799 result.uri_meta_data = item.uri_meta_data.and_then(|v| v.val);
1800
1801 result.vli_state = item.vli_state.and_then(|v| v.val);
1802
1803 result.absolute_counter_position =
1804 item.absolute_counter_position.and_then(|v| v.val);
1805
1806 result.absolute_time_position = item.absolute_time_position.and_then(|v| v.val);
1807
1808 result.alarm_id_running = item.alarm_id_running.and_then(|v| v.val);
1809
1810 result.alarm_logged_start_time = item.alarm_logged_start_time.and_then(|v| v.val);
1811
1812 result.alarm_running = item.alarm_running.and_then(|v| v.val);
1813
1814 result.current_crossfade_mode = item.current_crossfade_mode.and_then(|v| v.val);
1815
1816 result.current_media_duration = item.current_media_duration.and_then(|v| v.val);
1817
1818 result.current_play_mode = item.current_play_mode.and_then(|v| v.val);
1819
1820 result.current_record_quality_mode =
1821 item.current_record_quality_mode.and_then(|v| v.val);
1822
1823 result.current_section = item.current_section.and_then(|v| v.val);
1824
1825 result.current_track = item.current_track.and_then(|v| v.val);
1826
1827 result.current_track_duration = item.current_track_duration.and_then(|v| v.val);
1828
1829 result.current_track_meta_data = item.current_track_meta_data.and_then(|v| v.val);
1830
1831 result.current_track_uri = item.current_track_uri.and_then(|v| v.val);
1832
1833 result.current_transport_actions =
1834 item.current_transport_actions.and_then(|v| v.val);
1835
1836 result.current_valid_play_modes = item.current_valid_play_modes.and_then(|v| v.val);
1837
1838 result.direct_control_account_id =
1839 item.direct_control_account_id.and_then(|v| v.val);
1840
1841 result.direct_control_client_id = item.direct_control_client_id.and_then(|v| v.val);
1842
1843 result.direct_control_is_suspended =
1844 item.direct_control_is_suspended.and_then(|v| v.val);
1845
1846 result.enqueued_transport_uri = item.enqueued_transport_uri.and_then(|v| v.val);
1847
1848 result.enqueued_transport_uri_meta_data =
1849 item.enqueued_transport_uri_meta_data.and_then(|v| v.val);
1850
1851 result.muse_sessions = item.muse_sessions.and_then(|v| v.val);
1852
1853 result.next_av_transport_uri = item.next_av_transport_uri.and_then(|v| v.val);
1854
1855 result.next_av_transport_uri_meta_data =
1856 item.next_av_transport_uri_meta_data.and_then(|v| v.val);
1857
1858 result.next_track_meta_data = item.next_track_meta_data.and_then(|v| v.val);
1859
1860 result.next_track_uri = item.next_track_uri.and_then(|v| v.val);
1861
1862 result.number_of_tracks = item.number_of_tracks.and_then(|v| v.val);
1863
1864 result.playback_storage_medium = item.playback_storage_medium.and_then(|v| v.val);
1865
1866 result.possible_playback_storage_media =
1867 item.possible_playback_storage_media.and_then(|v| v.val);
1868
1869 result.possible_record_quality_modes =
1870 item.possible_record_quality_modes.and_then(|v| v.val);
1871
1872 result.possible_record_storage_media =
1873 item.possible_record_storage_media.and_then(|v| v.val);
1874
1875 result.queue_update_id = item.queue_update_id.and_then(|v| v.val);
1876
1877 result.record_medium_write_status =
1878 item.record_medium_write_status.and_then(|v| v.val);
1879
1880 result.record_storage_medium = item.record_storage_medium.and_then(|v| v.val);
1881
1882 result.relative_counter_position =
1883 item.relative_counter_position.and_then(|v| v.val);
1884
1885 result.relative_time_position = item.relative_time_position.and_then(|v| v.val);
1886
1887 result.restart_pending = item.restart_pending.and_then(|v| v.val);
1888
1889 result.sleep_timer_generation = item.sleep_timer_generation.and_then(|v| v.val);
1890
1891 result.snooze_running = item.snooze_running.and_then(|v| v.val);
1892
1893 result.transport_error_description =
1894 item.transport_error_description.and_then(|v| v.val);
1895
1896 result.transport_error_http_code =
1897 item.transport_error_http_code.and_then(|v| v.val);
1898
1899 result.transport_error_http_headers =
1900 item.transport_error_http_headers.and_then(|v| v.val);
1901
1902 result.transport_error_uri = item.transport_error_uri.and_then(|v| v.val);
1903
1904 result.transport_play_speed = item.transport_play_speed.and_then(|v| v.val);
1905
1906 result.transport_state = item.transport_state.and_then(|v| v.val);
1907
1908 result.transport_status = item.transport_status.and_then(|v| v.val);
1909
1910 map.insert(item.object_instance_id_, result);
1911 }
1912
1913 Ok(AVTransportLastChangeMap { map })
1914 }
1915 }
1916}
1917
1918#[derive(PartialEq, Debug, Clone, Eq, Default)]
1919pub enum SeekMode {
1920 #[default]
1921 TrackNr,
1922 RelTime,
1923 TimeDelta,
1924
1925 Unspecified(String),
1929}
1930
1931impl ToString for SeekMode {
1932 fn to_string(&self) -> String {
1933 match self {
1934 SeekMode::TrackNr => "TRACK_NR".to_string(),
1935 SeekMode::RelTime => "REL_TIME".to_string(),
1936 SeekMode::TimeDelta => "TIME_DELTA".to_string(),
1937 SeekMode::Unspecified(s) => s.to_string(),
1938 }
1939 }
1940}
1941
1942impl FromStr for SeekMode {
1943 type Err = crate::Error;
1944 fn from_str(s: &str) -> Result<SeekMode> {
1945 match s {
1946 "TRACK_NR" => Ok(SeekMode::TrackNr),
1947 "REL_TIME" => Ok(SeekMode::RelTime),
1948 "TIME_DELTA" => Ok(SeekMode::TimeDelta),
1949 s => Ok(SeekMode::Unspecified(s.to_string())),
1950 }
1951 }
1952}
1953
1954impl instant_xml::ToXml for SeekMode {
1955 fn serialize<W: std::fmt::Write + ?Sized>(
1956 &self,
1957 field: Option<instant_xml::Id<'_>>,
1958 serializer: &mut instant_xml::Serializer<W>,
1959 ) -> std::result::Result<(), instant_xml::Error> {
1960 self.to_string().serialize(field, serializer)
1961 }
1962
1963 fn present(&self) -> bool {
1964 true
1965 }
1966}
1967
1968impl<'xml> instant_xml::FromXml<'xml> for SeekMode {
1969 #[inline]
1970 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
1971 match field {
1972 Some(field) => id == field,
1973 None => false,
1974 }
1975 }
1976
1977 fn deserialize<'cx>(
1978 into: &mut Self::Accumulator,
1979 field: &'static str,
1980 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
1981 ) -> std::result::Result<(), instant_xml::Error> {
1982 if into.is_some() {
1983 return Err(instant_xml::Error::DuplicateValue(field));
1984 }
1985
1986 match deserializer.take_str()? {
1987 Some(value) => {
1988 let parsed: SeekMode = value.parse().map_err(|err| {
1989 instant_xml::Error::Other(format!(
1990 "invalid value for field {field}: {value}: {err:#}"
1991 ))
1992 })?;
1993 *into = Some(parsed);
1994 Ok(())
1995 }
1996 None => Err(instant_xml::Error::MissingValue(field)),
1997 }
1998 }
1999
2000 type Accumulator = Option<SeekMode>;
2001 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
2002}
2003
2004#[derive(PartialEq, Debug, Clone, Eq, Default)]
2005pub enum CurrentPlayMode {
2006 #[default]
2007 Normal,
2008 RepeatAll,
2009 RepeatOne,
2010 ShuffleNorepeat,
2011 Shuffle,
2012 ShuffleRepeatOne,
2013
2014 Unspecified(String),
2018}
2019
2020impl ToString for CurrentPlayMode {
2021 fn to_string(&self) -> String {
2022 match self {
2023 CurrentPlayMode::Normal => "NORMAL".to_string(),
2024 CurrentPlayMode::RepeatAll => "REPEAT_ALL".to_string(),
2025 CurrentPlayMode::RepeatOne => "REPEAT_ONE".to_string(),
2026 CurrentPlayMode::ShuffleNorepeat => "SHUFFLE_NOREPEAT".to_string(),
2027 CurrentPlayMode::Shuffle => "SHUFFLE".to_string(),
2028 CurrentPlayMode::ShuffleRepeatOne => "SHUFFLE_REPEAT_ONE".to_string(),
2029 CurrentPlayMode::Unspecified(s) => s.to_string(),
2030 }
2031 }
2032}
2033
2034impl FromStr for CurrentPlayMode {
2035 type Err = crate::Error;
2036 fn from_str(s: &str) -> Result<CurrentPlayMode> {
2037 match s {
2038 "NORMAL" => Ok(CurrentPlayMode::Normal),
2039 "REPEAT_ALL" => Ok(CurrentPlayMode::RepeatAll),
2040 "REPEAT_ONE" => Ok(CurrentPlayMode::RepeatOne),
2041 "SHUFFLE_NOREPEAT" => Ok(CurrentPlayMode::ShuffleNorepeat),
2042 "SHUFFLE" => Ok(CurrentPlayMode::Shuffle),
2043 "SHUFFLE_REPEAT_ONE" => Ok(CurrentPlayMode::ShuffleRepeatOne),
2044 s => Ok(CurrentPlayMode::Unspecified(s.to_string())),
2045 }
2046 }
2047}
2048
2049impl instant_xml::ToXml for CurrentPlayMode {
2050 fn serialize<W: std::fmt::Write + ?Sized>(
2051 &self,
2052 field: Option<instant_xml::Id<'_>>,
2053 serializer: &mut instant_xml::Serializer<W>,
2054 ) -> std::result::Result<(), instant_xml::Error> {
2055 self.to_string().serialize(field, serializer)
2056 }
2057
2058 fn present(&self) -> bool {
2059 true
2060 }
2061}
2062
2063impl<'xml> instant_xml::FromXml<'xml> for CurrentPlayMode {
2064 #[inline]
2065 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
2066 match field {
2067 Some(field) => id == field,
2068 None => false,
2069 }
2070 }
2071
2072 fn deserialize<'cx>(
2073 into: &mut Self::Accumulator,
2074 field: &'static str,
2075 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
2076 ) -> std::result::Result<(), instant_xml::Error> {
2077 if into.is_some() {
2078 return Err(instant_xml::Error::DuplicateValue(field));
2079 }
2080
2081 match deserializer.take_str()? {
2082 Some(value) => {
2083 let parsed: CurrentPlayMode = value.parse().map_err(|err| {
2084 instant_xml::Error::Other(format!(
2085 "invalid value for field {field}: {value}: {err:#}"
2086 ))
2087 })?;
2088 *into = Some(parsed);
2089 Ok(())
2090 }
2091 None => Err(instant_xml::Error::MissingValue(field)),
2092 }
2093 }
2094
2095 type Accumulator = Option<CurrentPlayMode>;
2096 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
2097}
2098
2099#[derive(PartialEq, Debug, Clone, Eq, Default)]
2100pub enum PlaybackStorageMedium {
2101 #[default]
2102 None,
2103 Network,
2104
2105 Unspecified(String),
2109}
2110
2111impl ToString for PlaybackStorageMedium {
2112 fn to_string(&self) -> String {
2113 match self {
2114 PlaybackStorageMedium::None => "NONE".to_string(),
2115 PlaybackStorageMedium::Network => "NETWORK".to_string(),
2116 PlaybackStorageMedium::Unspecified(s) => s.to_string(),
2117 }
2118 }
2119}
2120
2121impl FromStr for PlaybackStorageMedium {
2122 type Err = crate::Error;
2123 fn from_str(s: &str) -> Result<PlaybackStorageMedium> {
2124 match s {
2125 "NONE" => Ok(PlaybackStorageMedium::None),
2126 "NETWORK" => Ok(PlaybackStorageMedium::Network),
2127 s => Ok(PlaybackStorageMedium::Unspecified(s.to_string())),
2128 }
2129 }
2130}
2131
2132impl instant_xml::ToXml for PlaybackStorageMedium {
2133 fn serialize<W: std::fmt::Write + ?Sized>(
2134 &self,
2135 field: Option<instant_xml::Id<'_>>,
2136 serializer: &mut instant_xml::Serializer<W>,
2137 ) -> std::result::Result<(), instant_xml::Error> {
2138 self.to_string().serialize(field, serializer)
2139 }
2140
2141 fn present(&self) -> bool {
2142 true
2143 }
2144}
2145
2146impl<'xml> instant_xml::FromXml<'xml> for PlaybackStorageMedium {
2147 #[inline]
2148 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
2149 match field {
2150 Some(field) => id == field,
2151 None => false,
2152 }
2153 }
2154
2155 fn deserialize<'cx>(
2156 into: &mut Self::Accumulator,
2157 field: &'static str,
2158 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
2159 ) -> std::result::Result<(), instant_xml::Error> {
2160 if into.is_some() {
2161 return Err(instant_xml::Error::DuplicateValue(field));
2162 }
2163
2164 match deserializer.take_str()? {
2165 Some(value) => {
2166 let parsed: PlaybackStorageMedium = value.parse().map_err(|err| {
2167 instant_xml::Error::Other(format!(
2168 "invalid value for field {field}: {value}: {err:#}"
2169 ))
2170 })?;
2171 *into = Some(parsed);
2172 Ok(())
2173 }
2174 None => Err(instant_xml::Error::MissingValue(field)),
2175 }
2176 }
2177
2178 type Accumulator = Option<PlaybackStorageMedium>;
2179 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
2180}
2181
2182#[derive(PartialEq, Debug, Clone, Eq, Default)]
2183pub enum TransportState {
2184 #[default]
2185 Stopped,
2186 Playing,
2187 PausedPlayback,
2188 Transitioning,
2189
2190 Unspecified(String),
2194}
2195
2196impl ToString for TransportState {
2197 fn to_string(&self) -> String {
2198 match self {
2199 TransportState::Stopped => "STOPPED".to_string(),
2200 TransportState::Playing => "PLAYING".to_string(),
2201 TransportState::PausedPlayback => "PAUSED_PLAYBACK".to_string(),
2202 TransportState::Transitioning => "TRANSITIONING".to_string(),
2203 TransportState::Unspecified(s) => s.to_string(),
2204 }
2205 }
2206}
2207
2208impl FromStr for TransportState {
2209 type Err = crate::Error;
2210 fn from_str(s: &str) -> Result<TransportState> {
2211 match s {
2212 "STOPPED" => Ok(TransportState::Stopped),
2213 "PLAYING" => Ok(TransportState::Playing),
2214 "PAUSED_PLAYBACK" => Ok(TransportState::PausedPlayback),
2215 "TRANSITIONING" => Ok(TransportState::Transitioning),
2216 s => Ok(TransportState::Unspecified(s.to_string())),
2217 }
2218 }
2219}
2220
2221impl instant_xml::ToXml for TransportState {
2222 fn serialize<W: std::fmt::Write + ?Sized>(
2223 &self,
2224 field: Option<instant_xml::Id<'_>>,
2225 serializer: &mut instant_xml::Serializer<W>,
2226 ) -> std::result::Result<(), instant_xml::Error> {
2227 self.to_string().serialize(field, serializer)
2228 }
2229
2230 fn present(&self) -> bool {
2231 true
2232 }
2233}
2234
2235impl<'xml> instant_xml::FromXml<'xml> for TransportState {
2236 #[inline]
2237 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
2238 match field {
2239 Some(field) => id == field,
2240 None => false,
2241 }
2242 }
2243
2244 fn deserialize<'cx>(
2245 into: &mut Self::Accumulator,
2246 field: &'static str,
2247 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
2248 ) -> std::result::Result<(), instant_xml::Error> {
2249 if into.is_some() {
2250 return Err(instant_xml::Error::DuplicateValue(field));
2251 }
2252
2253 match deserializer.take_str()? {
2254 Some(value) => {
2255 let parsed: TransportState = value.parse().map_err(|err| {
2256 instant_xml::Error::Other(format!(
2257 "invalid value for field {field}: {value}: {err:#}"
2258 ))
2259 })?;
2260 *into = Some(parsed);
2261 Ok(())
2262 }
2263 None => Err(instant_xml::Error::MissingValue(field)),
2264 }
2265 }
2266
2267 type Accumulator = Option<TransportState>;
2268 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
2269}
2270
2271pub mod alarm_clock {
2273 use super::*;
2274
2275 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:AlarmClock:1";
2278
2279 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2280 #[xml(rename = "CreateAlarm", ns(SERVICE_TYPE))]
2281 pub struct CreateAlarmRequest {
2282 #[xml(rename = "StartLocalTime", ns(""))]
2284 pub start_local_time: String,
2285 #[xml(rename = "Duration", ns(""))]
2287 pub duration: String,
2288 #[xml(rename = "Recurrence", ns(""))]
2290 pub recurrence: super::Recurrence,
2291 #[xml(rename = "Enabled", ns(""))]
2293 pub enabled: bool,
2294 #[xml(rename = "RoomUUID", ns(""))]
2296 pub room_uuid: String,
2297 #[xml(rename = "ProgramURI", ns(""))]
2299 pub program_uri: String,
2300 #[xml(rename = "ProgramMetaData", ns(""))]
2302 pub program_meta_data: String,
2303 #[xml(rename = "PlayMode", ns(""))]
2305 pub play_mode: super::AlarmPlayMode,
2306 #[xml(rename = "Volume", ns(""))]
2308 pub volume: u16,
2309 #[xml(rename = "IncludeLinkedZones", ns(""))]
2311 pub include_linked_zones: bool,
2312 }
2313
2314 #[derive(FromXml, Debug, Clone, PartialEq)]
2315 #[xml(rename = "CreateAlarmResponse", ns(SERVICE_TYPE))]
2316 pub struct CreateAlarmResponse {
2317 #[xml(rename = "AssignedID", ns(""))]
2318 pub assigned_id: Option<u32>,
2319 }
2320
2321 impl crate::DecodeSoapResponse for CreateAlarmResponse {
2322 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2323 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2324 Ok(envelope.body.payload)
2325 }
2326 }
2327
2328 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2329 #[xml(rename = "DestroyAlarm", ns(SERVICE_TYPE))]
2330 pub struct DestroyAlarmRequest {
2331 #[xml(rename = "ID", ns(""))]
2333 pub id: u32,
2334 }
2335
2336 #[derive(FromXml, Debug, Clone, PartialEq)]
2337 #[xml(rename = "GetDailyIndexRefreshTimeResponse", ns(SERVICE_TYPE))]
2338 pub struct GetDailyIndexRefreshTimeResponse {
2339 #[xml(rename = "CurrentDailyIndexRefreshTime", ns(""))]
2340 pub current_daily_index_refresh_time: Option<String>,
2341 }
2342
2343 impl crate::DecodeSoapResponse for GetDailyIndexRefreshTimeResponse {
2344 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2345 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2346 Ok(envelope.body.payload)
2347 }
2348 }
2349
2350 #[derive(FromXml, Debug, Clone, PartialEq)]
2351 #[xml(rename = "GetFormatResponse", ns(SERVICE_TYPE))]
2352 pub struct GetFormatResponse {
2353 #[xml(rename = "CurrentTimeFormat", ns(""))]
2354 pub current_time_format: Option<String>,
2355 #[xml(rename = "CurrentDateFormat", ns(""))]
2356 pub current_date_format: Option<String>,
2357 }
2358
2359 impl crate::DecodeSoapResponse for GetFormatResponse {
2360 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2361 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2362 Ok(envelope.body.payload)
2363 }
2364 }
2365
2366 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2367 #[xml(rename = "GetHouseholdTimeAtStamp", ns(SERVICE_TYPE))]
2368 pub struct GetHouseholdTimeAtStampRequest {
2369 #[xml(rename = "TimeStamp", ns(""))]
2370 pub time_stamp: String,
2371 }
2372
2373 #[derive(FromXml, Debug, Clone, PartialEq)]
2374 #[xml(rename = "GetHouseholdTimeAtStampResponse", ns(SERVICE_TYPE))]
2375 pub struct GetHouseholdTimeAtStampResponse {
2376 #[xml(rename = "HouseholdUTCTime", ns(""))]
2377 pub household_utc_time: Option<String>,
2378 }
2379
2380 impl crate::DecodeSoapResponse for GetHouseholdTimeAtStampResponse {
2381 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2382 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2383 Ok(envelope.body.payload)
2384 }
2385 }
2386
2387 #[derive(FromXml, Debug, Clone, PartialEq)]
2388 #[xml(rename = "GetTimeNowResponse", ns(SERVICE_TYPE))]
2389 pub struct GetTimeNowResponse {
2390 #[xml(rename = "CurrentUTCTime", ns(""))]
2391 pub current_utc_time: Option<String>,
2392 #[xml(rename = "CurrentLocalTime", ns(""))]
2393 pub current_local_time: Option<String>,
2394 #[xml(rename = "CurrentTimeZone", ns(""))]
2395 pub current_time_zone: Option<String>,
2396 #[xml(rename = "CurrentTimeGeneration", ns(""))]
2397 pub current_time_generation: Option<u32>,
2398 }
2399
2400 impl crate::DecodeSoapResponse for GetTimeNowResponse {
2401 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2402 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2403 Ok(envelope.body.payload)
2404 }
2405 }
2406
2407 #[derive(FromXml, Debug, Clone, PartialEq)]
2408 #[xml(rename = "GetTimeServerResponse", ns(SERVICE_TYPE))]
2409 pub struct GetTimeServerResponse {
2410 #[xml(rename = "CurrentTimeServer", ns(""))]
2411 pub current_time_server: Option<String>,
2412 }
2413
2414 impl crate::DecodeSoapResponse for GetTimeServerResponse {
2415 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2416 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2417 Ok(envelope.body.payload)
2418 }
2419 }
2420
2421 #[derive(FromXml, Debug, Clone, PartialEq)]
2422 #[xml(rename = "GetTimeZoneResponse", ns(SERVICE_TYPE))]
2423 pub struct GetTimeZoneResponse {
2424 #[xml(rename = "Index", ns(""))]
2425 pub index: Option<i32>,
2426 #[xml(rename = "AutoAdjustDst", ns(""))]
2427 pub auto_adjust_dst: Option<bool>,
2428 }
2429
2430 impl crate::DecodeSoapResponse for GetTimeZoneResponse {
2431 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2432 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2433 Ok(envelope.body.payload)
2434 }
2435 }
2436
2437 #[derive(FromXml, Debug, Clone, PartialEq)]
2438 #[xml(rename = "GetTimeZoneAndRuleResponse", ns(SERVICE_TYPE))]
2439 pub struct GetTimeZoneAndRuleResponse {
2440 #[xml(rename = "Index", ns(""))]
2441 pub index: Option<i32>,
2442 #[xml(rename = "AutoAdjustDst", ns(""))]
2443 pub auto_adjust_dst: Option<bool>,
2444 #[xml(rename = "CurrentTimeZone", ns(""))]
2445 pub current_time_zone: Option<String>,
2446 }
2447
2448 impl crate::DecodeSoapResponse for GetTimeZoneAndRuleResponse {
2449 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2450 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2451 Ok(envelope.body.payload)
2452 }
2453 }
2454
2455 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2456 #[xml(rename = "GetTimeZoneRule", ns(SERVICE_TYPE))]
2457 pub struct GetTimeZoneRuleRequest {
2458 #[xml(rename = "Index", ns(""))]
2459 pub index: i32,
2460 }
2461
2462 #[derive(FromXml, Debug, Clone, PartialEq)]
2463 #[xml(rename = "GetTimeZoneRuleResponse", ns(SERVICE_TYPE))]
2464 pub struct GetTimeZoneRuleResponse {
2465 #[xml(rename = "TimeZone", ns(""))]
2466 pub time_zone: Option<String>,
2467 }
2468
2469 impl crate::DecodeSoapResponse for GetTimeZoneRuleResponse {
2470 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2471 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2472 Ok(envelope.body.payload)
2473 }
2474 }
2475
2476 #[derive(FromXml, Debug, Clone, PartialEq)]
2477 #[xml(rename = "ListAlarmsResponse", ns(SERVICE_TYPE))]
2478 pub struct ListAlarmsResponse {
2479 #[xml(rename = "CurrentAlarmList", ns(""))]
2480 pub current_alarm_list: Option<String>,
2481 #[xml(rename = "CurrentAlarmListVersion", ns(""))]
2482 pub current_alarm_list_version: Option<String>,
2483 }
2484
2485 impl crate::DecodeSoapResponse for ListAlarmsResponse {
2486 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2487 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2488 Ok(envelope.body.payload)
2489 }
2490 }
2491
2492 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2493 #[xml(rename = "SetDailyIndexRefreshTime", ns(SERVICE_TYPE))]
2494 pub struct SetDailyIndexRefreshTimeRequest {
2495 #[xml(rename = "DesiredDailyIndexRefreshTime", ns(""))]
2496 pub desired_daily_index_refresh_time: String,
2497 }
2498
2499 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2500 #[xml(rename = "SetFormat", ns(SERVICE_TYPE))]
2501 pub struct SetFormatRequest {
2502 #[xml(rename = "DesiredTimeFormat", ns(""))]
2503 pub desired_time_format: String,
2504 #[xml(rename = "DesiredDateFormat", ns(""))]
2505 pub desired_date_format: String,
2506 }
2507
2508 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2509 #[xml(rename = "SetTimeNow", ns(SERVICE_TYPE))]
2510 pub struct SetTimeNowRequest {
2511 #[xml(rename = "DesiredTime", ns(""))]
2512 pub desired_time: String,
2513 #[xml(rename = "TimeZoneForDesiredTime", ns(""))]
2514 pub time_zone_for_desired_time: String,
2515 }
2516
2517 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2518 #[xml(rename = "SetTimeServer", ns(SERVICE_TYPE))]
2519 pub struct SetTimeServerRequest {
2520 #[xml(rename = "DesiredTimeServer", ns(""))]
2521 pub desired_time_server: String,
2522 }
2523
2524 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2525 #[xml(rename = "SetTimeZone", ns(SERVICE_TYPE))]
2526 pub struct SetTimeZoneRequest {
2527 #[xml(rename = "Index", ns(""))]
2528 pub index: i32,
2529 #[xml(rename = "AutoAdjustDst", ns(""))]
2530 pub auto_adjust_dst: bool,
2531 }
2532
2533 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2534 #[xml(rename = "UpdateAlarm", ns(SERVICE_TYPE))]
2535 pub struct UpdateAlarmRequest {
2536 #[xml(rename = "ID", ns(""))]
2538 pub id: u32,
2539 #[xml(rename = "StartLocalTime", ns(""))]
2541 pub start_local_time: String,
2542 #[xml(rename = "Duration", ns(""))]
2544 pub duration: String,
2545 #[xml(rename = "Recurrence", ns(""))]
2547 pub recurrence: super::Recurrence,
2548 #[xml(rename = "Enabled", ns(""))]
2550 pub enabled: bool,
2551 #[xml(rename = "RoomUUID", ns(""))]
2553 pub room_uuid: String,
2554 #[xml(rename = "ProgramURI", ns(""))]
2556 pub program_uri: String,
2557 #[xml(rename = "ProgramMetaData", ns(""))]
2559 pub program_meta_data: String,
2560 #[xml(rename = "PlayMode", ns(""))]
2562 pub play_mode: super::AlarmPlayMode,
2563 #[xml(rename = "Volume", ns(""))]
2565 pub volume: u16,
2566 #[xml(rename = "IncludeLinkedZones", ns(""))]
2568 pub include_linked_zones: bool,
2569 }
2570
2571 #[derive(Debug, Clone, PartialEq, Default)]
2575 pub struct AlarmClockEvent {
2576 pub alarm_list_version: Option<String>,
2577 pub daily_index_refresh_time: Option<String>,
2578 pub date_format: Option<String>,
2579 pub time_format: Option<String>,
2580 pub time_generation: Option<u32>,
2581 pub time_server: Option<String>,
2582 pub time_zone: Option<String>,
2583 }
2584
2585 #[derive(FromXml, Debug, Clone, PartialEq)]
2586 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
2587 struct AlarmClockPropertySet {
2588 pub properties: Vec<AlarmClockProperty>,
2589 }
2590
2591 #[derive(FromXml, Debug, Clone, PartialEq)]
2592 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
2593 struct AlarmClockProperty {
2594 #[xml(rename = "AlarmListVersion", ns(""))]
2595 pub alarm_list_version: Option<String>,
2596 #[xml(rename = "DailyIndexRefreshTime", ns(""))]
2597 pub daily_index_refresh_time: Option<String>,
2598 #[xml(rename = "DateFormat", ns(""))]
2599 pub date_format: Option<String>,
2600 #[xml(rename = "TimeFormat", ns(""))]
2601 pub time_format: Option<String>,
2602 #[xml(rename = "TimeGeneration", ns(""))]
2603 pub time_generation: Option<u32>,
2604 #[xml(rename = "TimeServer", ns(""))]
2605 pub time_server: Option<String>,
2606 #[xml(rename = "TimeZone", ns(""))]
2607 pub time_zone: Option<String>,
2608 }
2609
2610 impl DecodeXml for AlarmClockEvent {
2611 fn decode_xml(xml: &str) -> crate::Result<Self> {
2612 let mut result = Self::default();
2613 let set: AlarmClockPropertySet = instant_xml::from_str(xml)?;
2614 for prop in set.properties {
2615 if let Some(v) = prop.alarm_list_version {
2616 result.alarm_list_version.replace(v);
2617 }
2618
2619 if let Some(v) = prop.daily_index_refresh_time {
2620 result.daily_index_refresh_time.replace(v);
2621 }
2622
2623 if let Some(v) = prop.date_format {
2624 result.date_format.replace(v);
2625 }
2626
2627 if let Some(v) = prop.time_format {
2628 result.time_format.replace(v);
2629 }
2630
2631 if let Some(v) = prop.time_generation {
2632 result.time_generation.replace(v);
2633 }
2634
2635 if let Some(v) = prop.time_server {
2636 result.time_server.replace(v);
2637 }
2638
2639 if let Some(v) = prop.time_zone {
2640 result.time_zone.replace(v);
2641 }
2642 }
2643 Ok(result)
2644 }
2645 }
2646
2647 impl crate::SonosDevice {
2648 pub async fn subscribe_alarm_clock(
2650 &self,
2651 ) -> crate::Result<crate::upnp::EventStream<AlarmClockEvent>> {
2652 self.subscribe_helper(&SERVICE_TYPE).await
2653 }
2654 }
2655}
2656
2657#[derive(PartialEq, Debug, Clone, Eq, Default)]
2658pub enum AlarmPlayMode {
2659 #[default]
2660 Normal,
2661 RepeatAll,
2662 ShuffleNorepeat,
2663 Shuffle,
2664
2665 Unspecified(String),
2669}
2670
2671impl ToString for AlarmPlayMode {
2672 fn to_string(&self) -> String {
2673 match self {
2674 AlarmPlayMode::Normal => "NORMAL".to_string(),
2675 AlarmPlayMode::RepeatAll => "REPEAT_ALL".to_string(),
2676 AlarmPlayMode::ShuffleNorepeat => "SHUFFLE_NOREPEAT".to_string(),
2677 AlarmPlayMode::Shuffle => "SHUFFLE".to_string(),
2678 AlarmPlayMode::Unspecified(s) => s.to_string(),
2679 }
2680 }
2681}
2682
2683impl FromStr for AlarmPlayMode {
2684 type Err = crate::Error;
2685 fn from_str(s: &str) -> Result<AlarmPlayMode> {
2686 match s {
2687 "NORMAL" => Ok(AlarmPlayMode::Normal),
2688 "REPEAT_ALL" => Ok(AlarmPlayMode::RepeatAll),
2689 "SHUFFLE_NOREPEAT" => Ok(AlarmPlayMode::ShuffleNorepeat),
2690 "SHUFFLE" => Ok(AlarmPlayMode::Shuffle),
2691 s => Ok(AlarmPlayMode::Unspecified(s.to_string())),
2692 }
2693 }
2694}
2695
2696impl instant_xml::ToXml for AlarmPlayMode {
2697 fn serialize<W: std::fmt::Write + ?Sized>(
2698 &self,
2699 field: Option<instant_xml::Id<'_>>,
2700 serializer: &mut instant_xml::Serializer<W>,
2701 ) -> std::result::Result<(), instant_xml::Error> {
2702 self.to_string().serialize(field, serializer)
2703 }
2704
2705 fn present(&self) -> bool {
2706 true
2707 }
2708}
2709
2710impl<'xml> instant_xml::FromXml<'xml> for AlarmPlayMode {
2711 #[inline]
2712 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
2713 match field {
2714 Some(field) => id == field,
2715 None => false,
2716 }
2717 }
2718
2719 fn deserialize<'cx>(
2720 into: &mut Self::Accumulator,
2721 field: &'static str,
2722 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
2723 ) -> std::result::Result<(), instant_xml::Error> {
2724 if into.is_some() {
2725 return Err(instant_xml::Error::DuplicateValue(field));
2726 }
2727
2728 match deserializer.take_str()? {
2729 Some(value) => {
2730 let parsed: AlarmPlayMode = value.parse().map_err(|err| {
2731 instant_xml::Error::Other(format!(
2732 "invalid value for field {field}: {value}: {err:#}"
2733 ))
2734 })?;
2735 *into = Some(parsed);
2736 Ok(())
2737 }
2738 None => Err(instant_xml::Error::MissingValue(field)),
2739 }
2740 }
2741
2742 type Accumulator = Option<AlarmPlayMode>;
2743 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
2744}
2745
2746#[derive(PartialEq, Debug, Clone, Eq, Default)]
2747pub enum Recurrence {
2748 #[default]
2749 Once,
2750 Weekdays,
2751 Weekends,
2752 Daily,
2753
2754 Unspecified(String),
2758}
2759
2760impl ToString for Recurrence {
2761 fn to_string(&self) -> String {
2762 match self {
2763 Recurrence::Once => "ONCE".to_string(),
2764 Recurrence::Weekdays => "WEEKDAYS".to_string(),
2765 Recurrence::Weekends => "WEEKENDS".to_string(),
2766 Recurrence::Daily => "DAILY".to_string(),
2767 Recurrence::Unspecified(s) => s.to_string(),
2768 }
2769 }
2770}
2771
2772impl FromStr for Recurrence {
2773 type Err = crate::Error;
2774 fn from_str(s: &str) -> Result<Recurrence> {
2775 match s {
2776 "ONCE" => Ok(Recurrence::Once),
2777 "WEEKDAYS" => Ok(Recurrence::Weekdays),
2778 "WEEKENDS" => Ok(Recurrence::Weekends),
2779 "DAILY" => Ok(Recurrence::Daily),
2780 s => Ok(Recurrence::Unspecified(s.to_string())),
2781 }
2782 }
2783}
2784
2785impl instant_xml::ToXml for Recurrence {
2786 fn serialize<W: std::fmt::Write + ?Sized>(
2787 &self,
2788 field: Option<instant_xml::Id<'_>>,
2789 serializer: &mut instant_xml::Serializer<W>,
2790 ) -> std::result::Result<(), instant_xml::Error> {
2791 self.to_string().serialize(field, serializer)
2792 }
2793
2794 fn present(&self) -> bool {
2795 true
2796 }
2797}
2798
2799impl<'xml> instant_xml::FromXml<'xml> for Recurrence {
2800 #[inline]
2801 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
2802 match field {
2803 Some(field) => id == field,
2804 None => false,
2805 }
2806 }
2807
2808 fn deserialize<'cx>(
2809 into: &mut Self::Accumulator,
2810 field: &'static str,
2811 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
2812 ) -> std::result::Result<(), instant_xml::Error> {
2813 if into.is_some() {
2814 return Err(instant_xml::Error::DuplicateValue(field));
2815 }
2816
2817 match deserializer.take_str()? {
2818 Some(value) => {
2819 let parsed: Recurrence = value.parse().map_err(|err| {
2820 instant_xml::Error::Other(format!(
2821 "invalid value for field {field}: {value}: {err:#}"
2822 ))
2823 })?;
2824 *into = Some(parsed);
2825 Ok(())
2826 }
2827 None => Err(instant_xml::Error::MissingValue(field)),
2828 }
2829 }
2830
2831 type Accumulator = Option<Recurrence>;
2832 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
2833}
2834
2835pub mod audio_in {
2837 use super::*;
2838
2839 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:AudioIn:1";
2842
2843 #[derive(FromXml, Debug, Clone, PartialEq)]
2844 #[xml(rename = "GetAudioInputAttributesResponse", ns(SERVICE_TYPE))]
2845 pub struct GetAudioInputAttributesResponse {
2846 #[xml(rename = "CurrentName", ns(""))]
2847 pub current_name: Option<String>,
2848 #[xml(rename = "CurrentIcon", ns(""))]
2849 pub current_icon: Option<String>,
2850 }
2851
2852 impl crate::DecodeSoapResponse for GetAudioInputAttributesResponse {
2853 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2854 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2855 Ok(envelope.body.payload)
2856 }
2857 }
2858
2859 #[derive(FromXml, Debug, Clone, PartialEq)]
2860 #[xml(rename = "GetLineInLevelResponse", ns(SERVICE_TYPE))]
2861 pub struct GetLineInLevelResponse {
2862 #[xml(rename = "CurrentLeftLineInLevel", ns(""))]
2863 pub current_left_line_in_level: Option<i32>,
2864 #[xml(rename = "CurrentRightLineInLevel", ns(""))]
2865 pub current_right_line_in_level: Option<i32>,
2866 }
2867
2868 impl crate::DecodeSoapResponse for GetLineInLevelResponse {
2869 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2870 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2871 Ok(envelope.body.payload)
2872 }
2873 }
2874
2875 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2876 #[xml(rename = "SelectAudio", ns(SERVICE_TYPE))]
2877 pub struct SelectAudioRequest {
2878 #[xml(rename = "ObjectID", ns(""))]
2879 pub object_id: String,
2880 }
2881
2882 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2883 #[xml(rename = "SetAudioInputAttributes", ns(SERVICE_TYPE))]
2884 pub struct SetAudioInputAttributesRequest {
2885 #[xml(rename = "DesiredName", ns(""))]
2886 pub desired_name: String,
2887 #[xml(rename = "DesiredIcon", ns(""))]
2888 pub desired_icon: String,
2889 }
2890
2891 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2892 #[xml(rename = "SetLineInLevel", ns(SERVICE_TYPE))]
2893 pub struct SetLineInLevelRequest {
2894 #[xml(rename = "DesiredLeftLineInLevel", ns(""))]
2895 pub desired_left_line_in_level: i32,
2896 #[xml(rename = "DesiredRightLineInLevel", ns(""))]
2897 pub desired_right_line_in_level: i32,
2898 }
2899
2900 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2901 #[xml(rename = "StartTransmissionToGroup", ns(SERVICE_TYPE))]
2902 pub struct StartTransmissionToGroupRequest {
2903 #[xml(rename = "CoordinatorID", ns(""))]
2904 pub coordinator_id: String,
2905 }
2906
2907 #[derive(FromXml, Debug, Clone, PartialEq)]
2908 #[xml(rename = "StartTransmissionToGroupResponse", ns(SERVICE_TYPE))]
2909 pub struct StartTransmissionToGroupResponse {
2910 #[xml(rename = "CurrentTransportSettings", ns(""))]
2911 pub current_transport_settings: Option<String>,
2912 }
2913
2914 impl crate::DecodeSoapResponse for StartTransmissionToGroupResponse {
2915 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
2916 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
2917 Ok(envelope.body.payload)
2918 }
2919 }
2920
2921 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
2922 #[xml(rename = "StopTransmissionToGroup", ns(SERVICE_TYPE))]
2923 pub struct StopTransmissionToGroupRequest {
2924 #[xml(rename = "CoordinatorID", ns(""))]
2925 pub coordinator_id: String,
2926 }
2927
2928 #[derive(Debug, Clone, PartialEq, Default)]
2932 pub struct AudioInEvent {
2933 pub audio_input_name: Option<String>,
2934 pub icon: Option<String>,
2935 pub left_line_in_level: Option<i32>,
2936 pub line_in_connected: Option<bool>,
2937 pub playing: Option<bool>,
2938 pub right_line_in_level: Option<i32>,
2939 }
2940
2941 #[derive(FromXml, Debug, Clone, PartialEq)]
2942 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
2943 struct AudioInPropertySet {
2944 pub properties: Vec<AudioInProperty>,
2945 }
2946
2947 #[derive(FromXml, Debug, Clone, PartialEq)]
2948 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
2949 struct AudioInProperty {
2950 #[xml(rename = "AudioInputName", ns(""))]
2951 pub audio_input_name: Option<String>,
2952 #[xml(rename = "Icon", ns(""))]
2953 pub icon: Option<String>,
2954 #[xml(rename = "LeftLineInLevel", ns(""))]
2955 pub left_line_in_level: Option<i32>,
2956 #[xml(rename = "LineInConnected", ns(""))]
2957 pub line_in_connected: Option<bool>,
2958 #[xml(rename = "Playing", ns(""))]
2959 pub playing: Option<bool>,
2960 #[xml(rename = "RightLineInLevel", ns(""))]
2961 pub right_line_in_level: Option<i32>,
2962 }
2963
2964 impl DecodeXml for AudioInEvent {
2965 fn decode_xml(xml: &str) -> crate::Result<Self> {
2966 let mut result = Self::default();
2967 let set: AudioInPropertySet = instant_xml::from_str(xml)?;
2968 for prop in set.properties {
2969 if let Some(v) = prop.audio_input_name {
2970 result.audio_input_name.replace(v);
2971 }
2972
2973 if let Some(v) = prop.icon {
2974 result.icon.replace(v);
2975 }
2976
2977 if let Some(v) = prop.left_line_in_level {
2978 result.left_line_in_level.replace(v);
2979 }
2980
2981 if let Some(v) = prop.line_in_connected {
2982 result.line_in_connected.replace(v);
2983 }
2984
2985 if let Some(v) = prop.playing {
2986 result.playing.replace(v);
2987 }
2988
2989 if let Some(v) = prop.right_line_in_level {
2990 result.right_line_in_level.replace(v);
2991 }
2992 }
2993 Ok(result)
2994 }
2995 }
2996
2997 impl crate::SonosDevice {
2998 pub async fn subscribe_audio_in(
3000 &self,
3001 ) -> crate::Result<crate::upnp::EventStream<AudioInEvent>> {
3002 self.subscribe_helper(&SERVICE_TYPE).await
3003 }
3004 }
3005}
3006
3007pub mod connection_manager {
3009 use super::*;
3010
3011 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:ConnectionManager:1";
3014
3015 #[derive(FromXml, Debug, Clone, PartialEq)]
3016 #[xml(rename = "GetCurrentConnectionIDsResponse", ns(SERVICE_TYPE))]
3017 pub struct GetCurrentConnectionIdsResponse {
3018 #[xml(rename = "ConnectionIDs", ns(""))]
3019 pub connection_ids: Option<String>,
3020 }
3021
3022 impl crate::DecodeSoapResponse for GetCurrentConnectionIdsResponse {
3023 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3024 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3025 Ok(envelope.body.payload)
3026 }
3027 }
3028
3029 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3030 #[xml(rename = "GetCurrentConnectionInfo", ns(SERVICE_TYPE))]
3031 pub struct GetCurrentConnectionInfoRequest {
3032 #[xml(rename = "ConnectionID", ns(""))]
3033 pub connection_id: i32,
3034 }
3035
3036 #[derive(FromXml, Debug, Clone, PartialEq)]
3037 #[xml(rename = "GetCurrentConnectionInfoResponse", ns(SERVICE_TYPE))]
3038 pub struct GetCurrentConnectionInfoResponse {
3039 #[xml(rename = "RcsID", ns(""))]
3040 pub rcs_id: Option<i32>,
3041 #[xml(rename = "AVTransportID", ns(""))]
3042 pub av_transport_id: Option<i32>,
3043 #[xml(rename = "ProtocolInfo", ns(""))]
3044 pub protocol_info: Option<String>,
3045 #[xml(rename = "PeerConnectionManager", ns(""))]
3046 pub peer_connection_manager: Option<String>,
3047 #[xml(rename = "PeerConnectionID", ns(""))]
3048 pub peer_connection_id: Option<i32>,
3049 #[xml(rename = "Direction", ns(""))]
3050 pub direction: Option<super::Direction>,
3051 #[xml(rename = "Status", ns(""))]
3052 pub status: Option<super::ConnectionStatus>,
3053 }
3054
3055 impl crate::DecodeSoapResponse for GetCurrentConnectionInfoResponse {
3056 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3057 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3058 Ok(envelope.body.payload)
3059 }
3060 }
3061
3062 #[derive(FromXml, Debug, Clone, PartialEq)]
3063 #[xml(rename = "GetProtocolInfoResponse", ns(SERVICE_TYPE))]
3064 pub struct GetProtocolInfoResponse {
3065 #[xml(rename = "Source", ns(""))]
3066 pub source: Option<String>,
3067 #[xml(rename = "Sink", ns(""))]
3068 pub sink: Option<String>,
3069 }
3070
3071 impl crate::DecodeSoapResponse for GetProtocolInfoResponse {
3072 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3073 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3074 Ok(envelope.body.payload)
3075 }
3076 }
3077
3078 #[derive(Debug, Clone, PartialEq, Default)]
3082 pub struct ConnectionManagerEvent {
3083 pub current_connection_ids: Option<String>,
3084 pub sink_protocol_info: Option<String>,
3085 pub source_protocol_info: Option<String>,
3086 }
3087
3088 #[derive(FromXml, Debug, Clone, PartialEq)]
3089 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
3090 struct ConnectionManagerPropertySet {
3091 pub properties: Vec<ConnectionManagerProperty>,
3092 }
3093
3094 #[derive(FromXml, Debug, Clone, PartialEq)]
3095 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
3096 struct ConnectionManagerProperty {
3097 #[xml(rename = "CurrentConnectionIDs", ns(""))]
3098 pub current_connection_ids: Option<String>,
3099 #[xml(rename = "SinkProtocolInfo", ns(""))]
3100 pub sink_protocol_info: Option<String>,
3101 #[xml(rename = "SourceProtocolInfo", ns(""))]
3102 pub source_protocol_info: Option<String>,
3103 }
3104
3105 impl DecodeXml for ConnectionManagerEvent {
3106 fn decode_xml(xml: &str) -> crate::Result<Self> {
3107 let mut result = Self::default();
3108 let set: ConnectionManagerPropertySet = instant_xml::from_str(xml)?;
3109 for prop in set.properties {
3110 if let Some(v) = prop.current_connection_ids {
3111 result.current_connection_ids.replace(v);
3112 }
3113
3114 if let Some(v) = prop.sink_protocol_info {
3115 result.sink_protocol_info.replace(v);
3116 }
3117
3118 if let Some(v) = prop.source_protocol_info {
3119 result.source_protocol_info.replace(v);
3120 }
3121 }
3122 Ok(result)
3123 }
3124 }
3125
3126 impl crate::SonosDevice {
3127 pub async fn subscribe_connection_manager(
3129 &self,
3130 ) -> crate::Result<crate::upnp::EventStream<ConnectionManagerEvent>> {
3131 self.subscribe_helper(&SERVICE_TYPE).await
3132 }
3133 }
3134}
3135
3136#[derive(PartialEq, Debug, Clone, Eq, Default)]
3137pub enum ConnectionStatus {
3138 #[default]
3139 Ok,
3140 ContentFormatMismatch,
3141 InsufficientBandwidth,
3142 UnreliableChannel,
3143 Unknown,
3144
3145 Unspecified(String),
3149}
3150
3151impl ToString for ConnectionStatus {
3152 fn to_string(&self) -> String {
3153 match self {
3154 ConnectionStatus::Ok => "OK".to_string(),
3155 ConnectionStatus::ContentFormatMismatch => "ContentFormatMismatch".to_string(),
3156 ConnectionStatus::InsufficientBandwidth => "InsufficientBandwidth".to_string(),
3157 ConnectionStatus::UnreliableChannel => "UnreliableChannel".to_string(),
3158 ConnectionStatus::Unknown => "Unknown".to_string(),
3159 ConnectionStatus::Unspecified(s) => s.to_string(),
3160 }
3161 }
3162}
3163
3164impl FromStr for ConnectionStatus {
3165 type Err = crate::Error;
3166 fn from_str(s: &str) -> Result<ConnectionStatus> {
3167 match s {
3168 "OK" => Ok(ConnectionStatus::Ok),
3169 "ContentFormatMismatch" => Ok(ConnectionStatus::ContentFormatMismatch),
3170 "InsufficientBandwidth" => Ok(ConnectionStatus::InsufficientBandwidth),
3171 "UnreliableChannel" => Ok(ConnectionStatus::UnreliableChannel),
3172 "Unknown" => Ok(ConnectionStatus::Unknown),
3173 s => Ok(ConnectionStatus::Unspecified(s.to_string())),
3174 }
3175 }
3176}
3177
3178impl instant_xml::ToXml for ConnectionStatus {
3179 fn serialize<W: std::fmt::Write + ?Sized>(
3180 &self,
3181 field: Option<instant_xml::Id<'_>>,
3182 serializer: &mut instant_xml::Serializer<W>,
3183 ) -> std::result::Result<(), instant_xml::Error> {
3184 self.to_string().serialize(field, serializer)
3185 }
3186
3187 fn present(&self) -> bool {
3188 true
3189 }
3190}
3191
3192impl<'xml> instant_xml::FromXml<'xml> for ConnectionStatus {
3193 #[inline]
3194 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
3195 match field {
3196 Some(field) => id == field,
3197 None => false,
3198 }
3199 }
3200
3201 fn deserialize<'cx>(
3202 into: &mut Self::Accumulator,
3203 field: &'static str,
3204 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
3205 ) -> std::result::Result<(), instant_xml::Error> {
3206 if into.is_some() {
3207 return Err(instant_xml::Error::DuplicateValue(field));
3208 }
3209
3210 match deserializer.take_str()? {
3211 Some(value) => {
3212 let parsed: ConnectionStatus = value.parse().map_err(|err| {
3213 instant_xml::Error::Other(format!(
3214 "invalid value for field {field}: {value}: {err:#}"
3215 ))
3216 })?;
3217 *into = Some(parsed);
3218 Ok(())
3219 }
3220 None => Err(instant_xml::Error::MissingValue(field)),
3221 }
3222 }
3223
3224 type Accumulator = Option<ConnectionStatus>;
3225 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
3226}
3227
3228#[derive(PartialEq, Debug, Clone, Eq, Default)]
3229pub enum Direction {
3230 #[default]
3231 Input,
3232 Output,
3233
3234 Unspecified(String),
3238}
3239
3240impl ToString for Direction {
3241 fn to_string(&self) -> String {
3242 match self {
3243 Direction::Input => "Input".to_string(),
3244 Direction::Output => "Output".to_string(),
3245 Direction::Unspecified(s) => s.to_string(),
3246 }
3247 }
3248}
3249
3250impl FromStr for Direction {
3251 type Err = crate::Error;
3252 fn from_str(s: &str) -> Result<Direction> {
3253 match s {
3254 "Input" => Ok(Direction::Input),
3255 "Output" => Ok(Direction::Output),
3256 s => Ok(Direction::Unspecified(s.to_string())),
3257 }
3258 }
3259}
3260
3261impl instant_xml::ToXml for Direction {
3262 fn serialize<W: std::fmt::Write + ?Sized>(
3263 &self,
3264 field: Option<instant_xml::Id<'_>>,
3265 serializer: &mut instant_xml::Serializer<W>,
3266 ) -> std::result::Result<(), instant_xml::Error> {
3267 self.to_string().serialize(field, serializer)
3268 }
3269
3270 fn present(&self) -> bool {
3271 true
3272 }
3273}
3274
3275impl<'xml> instant_xml::FromXml<'xml> for Direction {
3276 #[inline]
3277 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
3278 match field {
3279 Some(field) => id == field,
3280 None => false,
3281 }
3282 }
3283
3284 fn deserialize<'cx>(
3285 into: &mut Self::Accumulator,
3286 field: &'static str,
3287 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
3288 ) -> std::result::Result<(), instant_xml::Error> {
3289 if into.is_some() {
3290 return Err(instant_xml::Error::DuplicateValue(field));
3291 }
3292
3293 match deserializer.take_str()? {
3294 Some(value) => {
3295 let parsed: Direction = value.parse().map_err(|err| {
3296 instant_xml::Error::Other(format!(
3297 "invalid value for field {field}: {value}: {err:#}"
3298 ))
3299 })?;
3300 *into = Some(parsed);
3301 Ok(())
3302 }
3303 None => Err(instant_xml::Error::MissingValue(field)),
3304 }
3305 }
3306
3307 type Accumulator = Option<Direction>;
3308 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
3309}
3310
3311pub mod content_directory {
3313 use super::*;
3314
3315 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:ContentDirectory:1";
3318
3319 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3320 #[xml(rename = "Browse", ns(SERVICE_TYPE))]
3321 pub struct BrowseRequest {
3322 #[xml(rename = "ObjectID", ns(""))]
3324 pub object_id: String,
3325 #[xml(rename = "BrowseFlag", ns(""))]
3327 pub browse_flag: super::BrowseFlag,
3328 #[xml(rename = "Filter", ns(""))]
3330 pub filter: String,
3331 #[xml(rename = "StartingIndex", ns(""))]
3333 pub starting_index: u32,
3334 #[xml(rename = "RequestedCount", ns(""))]
3336 pub requested_count: u32,
3337 #[xml(rename = "SortCriteria", ns(""))]
3339 pub sort_criteria: String,
3340 }
3341
3342 #[derive(FromXml, Debug, Clone, PartialEq)]
3343 #[xml(rename = "BrowseResponse", ns(SERVICE_TYPE))]
3344 pub struct BrowseResponse {
3345 #[xml(rename = "Result", ns(""))]
3346 pub result: Option<DecodeXmlString<crate::TrackMetaDataList>>,
3347 #[xml(rename = "NumberReturned", ns(""))]
3348 pub number_returned: Option<u32>,
3349 #[xml(rename = "TotalMatches", ns(""))]
3350 pub total_matches: Option<u32>,
3351 #[xml(rename = "UpdateID", ns(""))]
3352 pub update_id: Option<u32>,
3353 }
3354
3355 impl crate::DecodeSoapResponse for BrowseResponse {
3356 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3357 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3358 Ok(envelope.body.payload)
3359 }
3360 }
3361
3362 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3363 #[xml(rename = "CreateObject", ns(SERVICE_TYPE))]
3364 pub struct CreateObjectRequest {
3365 #[xml(rename = "ContainerID", ns(""))]
3366 pub container_id: String,
3367 #[xml(rename = "Elements", ns(""))]
3368 pub elements: String,
3369 }
3370
3371 #[derive(FromXml, Debug, Clone, PartialEq)]
3372 #[xml(rename = "CreateObjectResponse", ns(SERVICE_TYPE))]
3373 pub struct CreateObjectResponse {
3374 #[xml(rename = "ObjectID", ns(""))]
3375 pub object_id: Option<String>,
3376 #[xml(rename = "Result", ns(""))]
3377 pub result: Option<String>,
3378 }
3379
3380 impl crate::DecodeSoapResponse for CreateObjectResponse {
3381 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3382 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3383 Ok(envelope.body.payload)
3384 }
3385 }
3386
3387 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3388 #[xml(rename = "DestroyObject", ns(SERVICE_TYPE))]
3389 pub struct DestroyObjectRequest {
3390 #[xml(rename = "ObjectID", ns(""))]
3391 pub object_id: String,
3392 }
3393
3394 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3395 #[xml(rename = "FindPrefix", ns(SERVICE_TYPE))]
3396 pub struct FindPrefixRequest {
3397 #[xml(rename = "ObjectID", ns(""))]
3398 pub object_id: String,
3399 #[xml(rename = "Prefix", ns(""))]
3400 pub prefix: String,
3401 }
3402
3403 #[derive(FromXml, Debug, Clone, PartialEq)]
3404 #[xml(rename = "FindPrefixResponse", ns(SERVICE_TYPE))]
3405 pub struct FindPrefixResponse {
3406 #[xml(rename = "StartingIndex", ns(""))]
3407 pub starting_index: Option<u32>,
3408 #[xml(rename = "UpdateID", ns(""))]
3409 pub update_id: Option<u32>,
3410 }
3411
3412 impl crate::DecodeSoapResponse for FindPrefixResponse {
3413 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3414 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3415 Ok(envelope.body.payload)
3416 }
3417 }
3418
3419 #[derive(FromXml, Debug, Clone, PartialEq)]
3420 #[xml(rename = "GetAlbumArtistDisplayOptionResponse", ns(SERVICE_TYPE))]
3421 pub struct GetAlbumArtistDisplayOptionResponse {
3422 #[xml(rename = "AlbumArtistDisplayOption", ns(""))]
3423 pub album_artist_display_option: Option<String>,
3424 }
3425
3426 impl crate::DecodeSoapResponse for GetAlbumArtistDisplayOptionResponse {
3427 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3428 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3429 Ok(envelope.body.payload)
3430 }
3431 }
3432
3433 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3434 #[xml(rename = "GetAllPrefixLocations", ns(SERVICE_TYPE))]
3435 pub struct GetAllPrefixLocationsRequest {
3436 #[xml(rename = "ObjectID", ns(""))]
3437 pub object_id: String,
3438 }
3439
3440 #[derive(FromXml, Debug, Clone, PartialEq)]
3441 #[xml(rename = "GetAllPrefixLocationsResponse", ns(SERVICE_TYPE))]
3442 pub struct GetAllPrefixLocationsResponse {
3443 #[xml(rename = "TotalPrefixes", ns(""))]
3444 pub total_prefixes: Option<u32>,
3445 #[xml(rename = "PrefixAndIndexCSV", ns(""))]
3446 pub prefix_and_index_csv: Option<String>,
3447 #[xml(rename = "UpdateID", ns(""))]
3448 pub update_id: Option<u32>,
3449 }
3450
3451 impl crate::DecodeSoapResponse for GetAllPrefixLocationsResponse {
3452 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3453 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3454 Ok(envelope.body.payload)
3455 }
3456 }
3457
3458 #[derive(FromXml, Debug, Clone, PartialEq)]
3459 #[xml(rename = "GetBrowseableResponse", ns(SERVICE_TYPE))]
3460 pub struct GetBrowseableResponse {
3461 #[xml(rename = "IsBrowseable", ns(""))]
3462 pub is_browseable: Option<bool>,
3463 }
3464
3465 impl crate::DecodeSoapResponse for GetBrowseableResponse {
3466 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3467 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3468 Ok(envelope.body.payload)
3469 }
3470 }
3471
3472 #[derive(FromXml, Debug, Clone, PartialEq)]
3473 #[xml(rename = "GetLastIndexChangeResponse", ns(SERVICE_TYPE))]
3474 pub struct GetLastIndexChangeResponse {
3475 #[xml(rename = "LastIndexChange", ns(""))]
3476 pub last_index_change: Option<String>,
3477 }
3478
3479 impl crate::DecodeSoapResponse for GetLastIndexChangeResponse {
3480 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3481 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3482 Ok(envelope.body.payload)
3483 }
3484 }
3485
3486 #[derive(FromXml, Debug, Clone, PartialEq)]
3487 #[xml(rename = "GetSearchCapabilitiesResponse", ns(SERVICE_TYPE))]
3488 pub struct GetSearchCapabilitiesResponse {
3489 #[xml(rename = "SearchCaps", ns(""))]
3490 pub search_caps: Option<String>,
3491 }
3492
3493 impl crate::DecodeSoapResponse for GetSearchCapabilitiesResponse {
3494 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3495 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3496 Ok(envelope.body.payload)
3497 }
3498 }
3499
3500 #[derive(FromXml, Debug, Clone, PartialEq)]
3501 #[xml(rename = "GetShareIndexInProgressResponse", ns(SERVICE_TYPE))]
3502 pub struct GetShareIndexInProgressResponse {
3503 #[xml(rename = "IsIndexing", ns(""))]
3504 pub is_indexing: Option<bool>,
3505 }
3506
3507 impl crate::DecodeSoapResponse for GetShareIndexInProgressResponse {
3508 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3509 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3510 Ok(envelope.body.payload)
3511 }
3512 }
3513
3514 #[derive(FromXml, Debug, Clone, PartialEq)]
3515 #[xml(rename = "GetSortCapabilitiesResponse", ns(SERVICE_TYPE))]
3516 pub struct GetSortCapabilitiesResponse {
3517 #[xml(rename = "SortCaps", ns(""))]
3518 pub sort_caps: Option<String>,
3519 }
3520
3521 impl crate::DecodeSoapResponse for GetSortCapabilitiesResponse {
3522 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3523 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3524 Ok(envelope.body.payload)
3525 }
3526 }
3527
3528 #[derive(FromXml, Debug, Clone, PartialEq)]
3529 #[xml(rename = "GetSystemUpdateIDResponse", ns(SERVICE_TYPE))]
3530 pub struct GetSystemUpdateIdResponse {
3531 #[xml(rename = "Id", ns(""))]
3532 pub id: Option<u32>,
3533 }
3534
3535 impl crate::DecodeSoapResponse for GetSystemUpdateIdResponse {
3536 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3537 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3538 Ok(envelope.body.payload)
3539 }
3540 }
3541
3542 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3543 #[xml(rename = "RefreshShareIndex", ns(SERVICE_TYPE))]
3544 pub struct RefreshShareIndexRequest {
3545 #[xml(rename = "AlbumArtistDisplayOption", ns(""))]
3547 pub album_artist_display_option: String,
3548 }
3549
3550 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3551 #[xml(rename = "RequestResort", ns(SERVICE_TYPE))]
3552 pub struct RequestResortRequest {
3553 #[xml(rename = "SortOrder", ns(""))]
3554 pub sort_order: String,
3555 }
3556
3557 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3558 #[xml(rename = "SetBrowseable", ns(SERVICE_TYPE))]
3559 pub struct SetBrowseableRequest {
3560 #[xml(rename = "Browseable", ns(""))]
3561 pub browseable: bool,
3562 }
3563
3564 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3565 #[xml(rename = "UpdateObject", ns(SERVICE_TYPE))]
3566 pub struct UpdateObjectRequest {
3567 #[xml(rename = "ObjectID", ns(""))]
3568 pub object_id: String,
3569 #[xml(rename = "CurrentTagValue", ns(""))]
3570 pub current_tag_value: String,
3571 #[xml(rename = "NewTagValue", ns(""))]
3572 pub new_tag_value: String,
3573 }
3574
3575 #[derive(Debug, Clone, PartialEq, Default)]
3579 pub struct ContentDirectoryEvent {
3580 pub browseable: Option<bool>,
3581 pub container_update_ids: Option<String>,
3582 pub favorite_presets_update_id: Option<String>,
3583 pub favorites_update_id: Option<String>,
3584 pub radio_favorites_update_id: Option<u32>,
3585 pub radio_location_update_id: Option<u32>,
3586 pub recently_played_update_id: Option<String>,
3587 pub saved_queues_update_id: Option<String>,
3588 pub share_index_in_progress: Option<bool>,
3589 pub share_index_last_error: Option<String>,
3590 pub share_list_update_id: Option<String>,
3591 pub system_update_id: Option<u32>,
3592 pub user_radio_update_id: Option<String>,
3593 }
3594
3595 #[derive(FromXml, Debug, Clone, PartialEq)]
3596 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
3597 struct ContentDirectoryPropertySet {
3598 pub properties: Vec<ContentDirectoryProperty>,
3599 }
3600
3601 #[derive(FromXml, Debug, Clone, PartialEq)]
3602 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
3603 struct ContentDirectoryProperty {
3604 #[xml(rename = "Browseable", ns(""))]
3605 pub browseable: Option<bool>,
3606 #[xml(rename = "ContainerUpdateIDs", ns(""))]
3607 pub container_update_ids: Option<String>,
3608 #[xml(rename = "FavoritePresetsUpdateID", ns(""))]
3609 pub favorite_presets_update_id: Option<String>,
3610 #[xml(rename = "FavoritesUpdateID", ns(""))]
3611 pub favorites_update_id: Option<String>,
3612 #[xml(rename = "RadioFavoritesUpdateID", ns(""))]
3613 pub radio_favorites_update_id: Option<u32>,
3614 #[xml(rename = "RadioLocationUpdateID", ns(""))]
3615 pub radio_location_update_id: Option<u32>,
3616 #[xml(rename = "RecentlyPlayedUpdateID", ns(""))]
3617 pub recently_played_update_id: Option<String>,
3618 #[xml(rename = "SavedQueuesUpdateID", ns(""))]
3619 pub saved_queues_update_id: Option<String>,
3620 #[xml(rename = "ShareIndexInProgress", ns(""))]
3621 pub share_index_in_progress: Option<bool>,
3622 #[xml(rename = "ShareIndexLastError", ns(""))]
3623 pub share_index_last_error: Option<String>,
3624 #[xml(rename = "ShareListUpdateID", ns(""))]
3625 pub share_list_update_id: Option<String>,
3626 #[xml(rename = "SystemUpdateID", ns(""))]
3627 pub system_update_id: Option<u32>,
3628 #[xml(rename = "UserRadioUpdateID", ns(""))]
3629 pub user_radio_update_id: Option<String>,
3630 }
3631
3632 impl DecodeXml for ContentDirectoryEvent {
3633 fn decode_xml(xml: &str) -> crate::Result<Self> {
3634 let mut result = Self::default();
3635 let set: ContentDirectoryPropertySet = instant_xml::from_str(xml)?;
3636 for prop in set.properties {
3637 if let Some(v) = prop.browseable {
3638 result.browseable.replace(v);
3639 }
3640
3641 if let Some(v) = prop.container_update_ids {
3642 result.container_update_ids.replace(v);
3643 }
3644
3645 if let Some(v) = prop.favorite_presets_update_id {
3646 result.favorite_presets_update_id.replace(v);
3647 }
3648
3649 if let Some(v) = prop.favorites_update_id {
3650 result.favorites_update_id.replace(v);
3651 }
3652
3653 if let Some(v) = prop.radio_favorites_update_id {
3654 result.radio_favorites_update_id.replace(v);
3655 }
3656
3657 if let Some(v) = prop.radio_location_update_id {
3658 result.radio_location_update_id.replace(v);
3659 }
3660
3661 if let Some(v) = prop.recently_played_update_id {
3662 result.recently_played_update_id.replace(v);
3663 }
3664
3665 if let Some(v) = prop.saved_queues_update_id {
3666 result.saved_queues_update_id.replace(v);
3667 }
3668
3669 if let Some(v) = prop.share_index_in_progress {
3670 result.share_index_in_progress.replace(v);
3671 }
3672
3673 if let Some(v) = prop.share_index_last_error {
3674 result.share_index_last_error.replace(v);
3675 }
3676
3677 if let Some(v) = prop.share_list_update_id {
3678 result.share_list_update_id.replace(v);
3679 }
3680
3681 if let Some(v) = prop.system_update_id {
3682 result.system_update_id.replace(v);
3683 }
3684
3685 if let Some(v) = prop.user_radio_update_id {
3686 result.user_radio_update_id.replace(v);
3687 }
3688 }
3689 Ok(result)
3690 }
3691 }
3692
3693 impl crate::SonosDevice {
3694 pub async fn subscribe_content_directory(
3696 &self,
3697 ) -> crate::Result<crate::upnp::EventStream<ContentDirectoryEvent>> {
3698 self.subscribe_helper(&SERVICE_TYPE).await
3699 }
3700 }
3701}
3702
3703#[derive(PartialEq, Debug, Clone, Eq, Default)]
3704pub enum BrowseFlag {
3705 #[default]
3706 BrowseMetadata,
3707 BrowseDirectChildren,
3708
3709 Unspecified(String),
3713}
3714
3715impl ToString for BrowseFlag {
3716 fn to_string(&self) -> String {
3717 match self {
3718 BrowseFlag::BrowseMetadata => "BrowseMetadata".to_string(),
3719 BrowseFlag::BrowseDirectChildren => "BrowseDirectChildren".to_string(),
3720 BrowseFlag::Unspecified(s) => s.to_string(),
3721 }
3722 }
3723}
3724
3725impl FromStr for BrowseFlag {
3726 type Err = crate::Error;
3727 fn from_str(s: &str) -> Result<BrowseFlag> {
3728 match s {
3729 "BrowseMetadata" => Ok(BrowseFlag::BrowseMetadata),
3730 "BrowseDirectChildren" => Ok(BrowseFlag::BrowseDirectChildren),
3731 s => Ok(BrowseFlag::Unspecified(s.to_string())),
3732 }
3733 }
3734}
3735
3736impl instant_xml::ToXml for BrowseFlag {
3737 fn serialize<W: std::fmt::Write + ?Sized>(
3738 &self,
3739 field: Option<instant_xml::Id<'_>>,
3740 serializer: &mut instant_xml::Serializer<W>,
3741 ) -> std::result::Result<(), instant_xml::Error> {
3742 self.to_string().serialize(field, serializer)
3743 }
3744
3745 fn present(&self) -> bool {
3746 true
3747 }
3748}
3749
3750impl<'xml> instant_xml::FromXml<'xml> for BrowseFlag {
3751 #[inline]
3752 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
3753 match field {
3754 Some(field) => id == field,
3755 None => false,
3756 }
3757 }
3758
3759 fn deserialize<'cx>(
3760 into: &mut Self::Accumulator,
3761 field: &'static str,
3762 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
3763 ) -> std::result::Result<(), instant_xml::Error> {
3764 if into.is_some() {
3765 return Err(instant_xml::Error::DuplicateValue(field));
3766 }
3767
3768 match deserializer.take_str()? {
3769 Some(value) => {
3770 let parsed: BrowseFlag = value.parse().map_err(|err| {
3771 instant_xml::Error::Other(format!(
3772 "invalid value for field {field}: {value}: {err:#}"
3773 ))
3774 })?;
3775 *into = Some(parsed);
3776 Ok(())
3777 }
3778 None => Err(instant_xml::Error::MissingValue(field)),
3779 }
3780 }
3781
3782 type Accumulator = Option<BrowseFlag>;
3783 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
3784}
3785
3786pub mod device_properties {
3788 use super::*;
3789
3790 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:DeviceProperties:1";
3793
3794 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3795 #[xml(rename = "AddBondedZones", ns(SERVICE_TYPE))]
3796 pub struct AddBondedZonesRequest {
3797 #[xml(rename = "ChannelMapSet", ns(""))]
3798 pub channel_map_set: String,
3799 }
3800
3801 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3802 #[xml(rename = "AddHTSatellite", ns(SERVICE_TYPE))]
3803 pub struct AddHtSatelliteRequest {
3804 #[xml(rename = "HTSatChanMapSet", ns(""))]
3806 pub ht_sat_chan_map_set: String,
3807 }
3808
3809 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3810 #[xml(rename = "CreateStereoPair", ns(SERVICE_TYPE))]
3811 pub struct CreateStereoPairRequest {
3812 #[xml(rename = "ChannelMapSet", ns(""))]
3814 pub channel_map_set: String,
3815 }
3816
3817 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3818 #[xml(rename = "EnterConfigMode", ns(SERVICE_TYPE))]
3819 pub struct EnterConfigModeRequest {
3820 #[xml(rename = "Mode", ns(""))]
3821 pub mode: String,
3822 #[xml(rename = "Options", ns(""))]
3823 pub options: String,
3824 }
3825
3826 #[derive(FromXml, Debug, Clone, PartialEq)]
3827 #[xml(rename = "EnterConfigModeResponse", ns(SERVICE_TYPE))]
3828 pub struct EnterConfigModeResponse {
3829 #[xml(rename = "State", ns(""))]
3830 pub state: Option<String>,
3831 }
3832
3833 impl crate::DecodeSoapResponse for EnterConfigModeResponse {
3834 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3835 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3836 Ok(envelope.body.payload)
3837 }
3838 }
3839
3840 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3841 #[xml(rename = "ExitConfigMode", ns(SERVICE_TYPE))]
3842 pub struct ExitConfigModeRequest {
3843 #[xml(rename = "Options", ns(""))]
3844 pub options: String,
3845 }
3846
3847 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3848 #[xml(rename = "GetAutoplayLinkedZones", ns(SERVICE_TYPE))]
3849 pub struct GetAutoplayLinkedZonesRequest {
3850 #[xml(rename = "Source", ns(""))]
3851 pub source: String,
3852 }
3853
3854 #[derive(FromXml, Debug, Clone, PartialEq)]
3855 #[xml(rename = "GetAutoplayLinkedZonesResponse", ns(SERVICE_TYPE))]
3856 pub struct GetAutoplayLinkedZonesResponse {
3857 #[xml(rename = "IncludeLinkedZones", ns(""))]
3858 pub include_linked_zones: Option<bool>,
3859 }
3860
3861 impl crate::DecodeSoapResponse for GetAutoplayLinkedZonesResponse {
3862 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3863 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3864 Ok(envelope.body.payload)
3865 }
3866 }
3867
3868 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3869 #[xml(rename = "GetAutoplayRoomUUID", ns(SERVICE_TYPE))]
3870 pub struct GetAutoplayRoomUuidRequest {
3871 #[xml(rename = "Source", ns(""))]
3872 pub source: String,
3873 }
3874
3875 #[derive(FromXml, Debug, Clone, PartialEq)]
3876 #[xml(rename = "GetAutoplayRoomUUIDResponse", ns(SERVICE_TYPE))]
3877 pub struct GetAutoplayRoomUuidResponse {
3878 #[xml(rename = "RoomUUID", ns(""))]
3879 pub room_uuid: Option<String>,
3880 }
3881
3882 impl crate::DecodeSoapResponse for GetAutoplayRoomUuidResponse {
3883 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3884 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3885 Ok(envelope.body.payload)
3886 }
3887 }
3888
3889 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3890 #[xml(rename = "GetAutoplayVolume", ns(SERVICE_TYPE))]
3891 pub struct GetAutoplayVolumeRequest {
3892 #[xml(rename = "Source", ns(""))]
3893 pub source: String,
3894 }
3895
3896 #[derive(FromXml, Debug, Clone, PartialEq)]
3897 #[xml(rename = "GetAutoplayVolumeResponse", ns(SERVICE_TYPE))]
3898 pub struct GetAutoplayVolumeResponse {
3899 #[xml(rename = "CurrentVolume", ns(""))]
3900 pub current_volume: Option<u16>,
3901 }
3902
3903 impl crate::DecodeSoapResponse for GetAutoplayVolumeResponse {
3904 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3905 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3906 Ok(envelope.body.payload)
3907 }
3908 }
3909
3910 #[derive(FromXml, Debug, Clone, PartialEq)]
3911 #[xml(rename = "GetButtonLockStateResponse", ns(SERVICE_TYPE))]
3912 pub struct GetButtonLockStateResponse {
3913 #[xml(rename = "CurrentButtonLockState", ns(""))]
3914 pub current_button_lock_state: Option<super::ButtonLockState>,
3915 }
3916
3917 impl crate::DecodeSoapResponse for GetButtonLockStateResponse {
3918 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3919 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3920 Ok(envelope.body.payload)
3921 }
3922 }
3923
3924 #[derive(FromXml, Debug, Clone, PartialEq)]
3925 #[xml(rename = "GetButtonStateResponse", ns(SERVICE_TYPE))]
3926 pub struct GetButtonStateResponse {
3927 #[xml(rename = "State", ns(""))]
3928 pub state: Option<String>,
3929 }
3930
3931 impl crate::DecodeSoapResponse for GetButtonStateResponse {
3932 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3933 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3934 Ok(envelope.body.payload)
3935 }
3936 }
3937
3938 #[derive(FromXml, Debug, Clone, PartialEq)]
3939 #[xml(rename = "GetHTForwardStateResponse", ns(SERVICE_TYPE))]
3940 pub struct GetHtForwardStateResponse {
3941 #[xml(rename = "IsHTForwardEnabled", ns(""))]
3942 pub is_ht_forward_enabled: Option<bool>,
3943 }
3944
3945 impl crate::DecodeSoapResponse for GetHtForwardStateResponse {
3946 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3947 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3948 Ok(envelope.body.payload)
3949 }
3950 }
3951
3952 #[derive(FromXml, Debug, Clone, PartialEq)]
3953 #[xml(rename = "GetHouseholdIDResponse", ns(SERVICE_TYPE))]
3954 pub struct GetHouseholdIdResponse {
3955 #[xml(rename = "CurrentHouseholdID", ns(""))]
3956 pub current_household_id: Option<String>,
3957 }
3958
3959 impl crate::DecodeSoapResponse for GetHouseholdIdResponse {
3960 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3961 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3962 Ok(envelope.body.payload)
3963 }
3964 }
3965
3966 #[derive(FromXml, Debug, Clone, PartialEq)]
3967 #[xml(rename = "GetLEDStateResponse", ns(SERVICE_TYPE))]
3968 pub struct GetLedStateResponse {
3969 #[xml(rename = "CurrentLEDState", ns(""))]
3970 pub current_led_state: Option<super::LEDState>,
3971 }
3972
3973 impl crate::DecodeSoapResponse for GetLedStateResponse {
3974 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3975 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3976 Ok(envelope.body.payload)
3977 }
3978 }
3979
3980 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
3981 #[xml(rename = "GetUseAutoplayVolume", ns(SERVICE_TYPE))]
3982 pub struct GetUseAutoplayVolumeRequest {
3983 #[xml(rename = "Source", ns(""))]
3984 pub source: String,
3985 }
3986
3987 #[derive(FromXml, Debug, Clone, PartialEq)]
3988 #[xml(rename = "GetUseAutoplayVolumeResponse", ns(SERVICE_TYPE))]
3989 pub struct GetUseAutoplayVolumeResponse {
3990 #[xml(rename = "UseVolume", ns(""))]
3991 pub use_volume: Option<bool>,
3992 }
3993
3994 impl crate::DecodeSoapResponse for GetUseAutoplayVolumeResponse {
3995 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
3996 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
3997 Ok(envelope.body.payload)
3998 }
3999 }
4000
4001 #[derive(FromXml, Debug, Clone, PartialEq)]
4002 #[xml(rename = "GetZoneAttributesResponse", ns(SERVICE_TYPE))]
4003 pub struct GetZoneAttributesResponse {
4004 #[xml(rename = "CurrentZoneName", ns(""))]
4005 pub current_zone_name: Option<String>,
4006 #[xml(rename = "CurrentIcon", ns(""))]
4007 pub current_icon: Option<String>,
4008 #[xml(rename = "CurrentConfiguration", ns(""))]
4009 pub current_configuration: Option<String>,
4010 #[xml(rename = "CurrentTargetRoomName", ns(""))]
4011 pub current_target_room_name: Option<String>,
4012 }
4013
4014 impl crate::DecodeSoapResponse for GetZoneAttributesResponse {
4015 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
4016 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
4017 Ok(envelope.body.payload)
4018 }
4019 }
4020
4021 #[derive(FromXml, Debug, Clone, PartialEq)]
4022 #[xml(rename = "GetZoneInfoResponse", ns(SERVICE_TYPE))]
4023 pub struct GetZoneInfoResponse {
4024 #[xml(rename = "SerialNumber", ns(""))]
4025 pub serial_number: Option<String>,
4026 #[xml(rename = "SoftwareVersion", ns(""))]
4027 pub software_version: Option<String>,
4028 #[xml(rename = "DisplaySoftwareVersion", ns(""))]
4029 pub display_software_version: Option<String>,
4030 #[xml(rename = "HardwareVersion", ns(""))]
4031 pub hardware_version: Option<String>,
4032 #[xml(rename = "IPAddress", ns(""))]
4033 pub ip_address: Option<String>,
4034 #[xml(rename = "MACAddress", ns(""))]
4035 pub mac_address: Option<String>,
4036 #[xml(rename = "CopyrightInfo", ns(""))]
4037 pub copyright_info: Option<String>,
4038 #[xml(rename = "ExtraInfo", ns(""))]
4039 pub extra_info: Option<String>,
4040 #[xml(rename = "HTAudioIn", ns(""))]
4041 pub ht_audio_in: Option<u32>,
4042 #[xml(rename = "Flags", ns(""))]
4043 pub flags: Option<u32>,
4044 }
4045
4046 impl crate::DecodeSoapResponse for GetZoneInfoResponse {
4047 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
4048 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
4049 Ok(envelope.body.payload)
4050 }
4051 }
4052
4053 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4054 #[xml(rename = "RemoveBondedZones", ns(SERVICE_TYPE))]
4055 pub struct RemoveBondedZonesRequest {
4056 #[xml(rename = "ChannelMapSet", ns(""))]
4057 pub channel_map_set: String,
4058 #[xml(rename = "KeepGrouped", ns(""))]
4059 pub keep_grouped: bool,
4060 }
4061
4062 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4063 #[xml(rename = "RemoveHTSatellite", ns(SERVICE_TYPE))]
4064 pub struct RemoveHtSatelliteRequest {
4065 #[xml(rename = "SatRoomUUID", ns(""))]
4067 pub sat_room_uuid: String,
4068 }
4069
4070 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4071 #[xml(rename = "RoomDetectionStartChirping", ns(SERVICE_TYPE))]
4072 pub struct RoomDetectionStartChirpingRequest {
4073 #[xml(rename = "Channel", ns(""))]
4074 pub channel: u16,
4075 #[xml(rename = "DurationMilliseconds", ns(""))]
4076 pub duration_milliseconds: u32,
4077 #[xml(rename = "ChirpIfPlayingSwappableAudio", ns(""))]
4078 pub chirp_if_playing_swappable_audio: bool,
4079 }
4080
4081 #[derive(FromXml, Debug, Clone, PartialEq)]
4082 #[xml(rename = "RoomDetectionStartChirpingResponse", ns(SERVICE_TYPE))]
4083 pub struct RoomDetectionStartChirpingResponse {
4084 #[xml(rename = "PlayId", ns(""))]
4085 pub play_id: Option<u32>,
4086 #[xml(rename = "ChirpIfPlayingSwappableAudio", ns(""))]
4087 pub chirp_if_playing_swappable_audio: Option<bool>,
4088 }
4089
4090 impl crate::DecodeSoapResponse for RoomDetectionStartChirpingResponse {
4091 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
4092 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
4093 Ok(envelope.body.payload)
4094 }
4095 }
4096
4097 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4098 #[xml(rename = "RoomDetectionStopChirping", ns(SERVICE_TYPE))]
4099 pub struct RoomDetectionStopChirpingRequest {
4100 #[xml(rename = "PlayId", ns(""))]
4101 pub play_id: u32,
4102 }
4103
4104 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4105 #[xml(rename = "SeparateStereoPair", ns(SERVICE_TYPE))]
4106 pub struct SeparateStereoPairRequest {
4107 #[xml(rename = "ChannelMapSet", ns(""))]
4109 pub channel_map_set: String,
4110 }
4111
4112 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4113 #[xml(rename = "SetAutoplayLinkedZones", ns(SERVICE_TYPE))]
4114 pub struct SetAutoplayLinkedZonesRequest {
4115 #[xml(rename = "IncludeLinkedZones", ns(""))]
4116 pub include_linked_zones: bool,
4117 #[xml(rename = "Source", ns(""))]
4118 pub source: String,
4119 }
4120
4121 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4122 #[xml(rename = "SetAutoplayRoomUUID", ns(SERVICE_TYPE))]
4123 pub struct SetAutoplayRoomUuidRequest {
4124 #[xml(rename = "RoomUUID", ns(""))]
4125 pub room_uuid: String,
4126 #[xml(rename = "Source", ns(""))]
4127 pub source: String,
4128 }
4129
4130 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4131 #[xml(rename = "SetAutoplayVolume", ns(SERVICE_TYPE))]
4132 pub struct SetAutoplayVolumeRequest {
4133 #[xml(rename = "Volume", ns(""))]
4134 pub volume: u16,
4135 #[xml(rename = "Source", ns(""))]
4136 pub source: String,
4137 }
4138
4139 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4140 #[xml(rename = "SetButtonLockState", ns(SERVICE_TYPE))]
4141 pub struct SetButtonLockStateRequest {
4142 #[xml(rename = "DesiredButtonLockState", ns(""))]
4143 pub desired_button_lock_state: super::ButtonLockState,
4144 }
4145
4146 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4147 #[xml(rename = "SetLEDState", ns(SERVICE_TYPE))]
4148 pub struct SetLedStateRequest {
4149 #[xml(rename = "DesiredLEDState", ns(""))]
4150 pub desired_led_state: super::LEDState,
4151 }
4152
4153 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4154 #[xml(rename = "SetUseAutoplayVolume", ns(SERVICE_TYPE))]
4155 pub struct SetUseAutoplayVolumeRequest {
4156 #[xml(rename = "UseVolume", ns(""))]
4157 pub use_volume: bool,
4158 #[xml(rename = "Source", ns(""))]
4159 pub source: String,
4160 }
4161
4162 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4163 #[xml(rename = "SetZoneAttributes", ns(SERVICE_TYPE))]
4164 pub struct SetZoneAttributesRequest {
4165 #[xml(rename = "DesiredZoneName", ns(""))]
4166 pub desired_zone_name: String,
4167 #[xml(rename = "DesiredIcon", ns(""))]
4168 pub desired_icon: String,
4169 #[xml(rename = "DesiredConfiguration", ns(""))]
4170 pub desired_configuration: String,
4171 #[xml(rename = "DesiredTargetRoomName", ns(""))]
4172 pub desired_target_room_name: String,
4173 }
4174
4175 #[derive(Debug, Clone, PartialEq, Default)]
4179 pub struct DevicePropertiesEvent {
4180 pub air_play_enabled: Option<bool>,
4181 pub available_room_calibration: Option<String>,
4182 pub behind_wifi_extender: Option<u32>,
4183 pub channel_freq: Option<u32>,
4184 pub channel_map_set: Option<String>,
4185 pub config_mode: Option<String>,
4186 pub configuration: Option<String>,
4187 pub eth_link: Option<bool>,
4188 pub ht_bonded_zone_commit_state: Option<u32>,
4189 pub ht_freq: Option<u32>,
4190 pub ht_sat_chan_map_set: Option<String>,
4191 pub has_configured_ssid: Option<bool>,
4192 pub hdmi_cec_available: Option<bool>,
4193 pub icon: Option<String>,
4194 pub invisible: Option<bool>,
4195 pub is_idle: Option<bool>,
4196 pub is_zone_bridge: Option<bool>,
4197 pub last_changed_play_state: Option<String>,
4198 pub mic_enabled: Option<u32>,
4199 pub more_info: Option<String>,
4200 pub orientation: Option<i32>,
4201 pub room_calibration_state: Option<i32>,
4202 pub secure_reg_state: Option<u32>,
4203 pub settings_replication_state: Option<String>,
4204 pub supports_audio_clip: Option<bool>,
4205 pub supports_audio_in: Option<bool>,
4206 pub tv_configuration_error: Option<bool>,
4207 pub voice_config_state: Option<u32>,
4208 pub wifi_enabled: Option<bool>,
4209 pub wireless_leaf_only: Option<bool>,
4210 pub wireless_mode: Option<u32>,
4211 pub zone_name: Option<String>,
4212 }
4213
4214 #[derive(FromXml, Debug, Clone, PartialEq)]
4215 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
4216 struct DevicePropertiesPropertySet {
4217 pub properties: Vec<DevicePropertiesProperty>,
4218 }
4219
4220 #[derive(FromXml, Debug, Clone, PartialEq)]
4221 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
4222 struct DevicePropertiesProperty {
4223 #[xml(rename = "AirPlayEnabled", ns(""))]
4224 pub air_play_enabled: Option<bool>,
4225 #[xml(rename = "AvailableRoomCalibration", ns(""))]
4226 pub available_room_calibration: Option<String>,
4227 #[xml(rename = "BehindWifiExtender", ns(""))]
4228 pub behind_wifi_extender: Option<u32>,
4229 #[xml(rename = "ChannelFreq", ns(""))]
4230 pub channel_freq: Option<u32>,
4231 #[xml(rename = "ChannelMapSet", ns(""))]
4232 pub channel_map_set: Option<String>,
4233 #[xml(rename = "ConfigMode", ns(""))]
4234 pub config_mode: Option<String>,
4235 #[xml(rename = "Configuration", ns(""))]
4236 pub configuration: Option<String>,
4237 #[xml(rename = "EthLink", ns(""))]
4238 pub eth_link: Option<bool>,
4239 #[xml(rename = "HTBondedZoneCommitState", ns(""))]
4240 pub ht_bonded_zone_commit_state: Option<u32>,
4241 #[xml(rename = "HTFreq", ns(""))]
4242 pub ht_freq: Option<u32>,
4243 #[xml(rename = "HTSatChanMapSet", ns(""))]
4244 pub ht_sat_chan_map_set: Option<String>,
4245 #[xml(rename = "HasConfiguredSSID", ns(""))]
4246 pub has_configured_ssid: Option<bool>,
4247 #[xml(rename = "HdmiCecAvailable", ns(""))]
4248 pub hdmi_cec_available: Option<bool>,
4249 #[xml(rename = "Icon", ns(""))]
4250 pub icon: Option<String>,
4251 #[xml(rename = "Invisible", ns(""))]
4252 pub invisible: Option<bool>,
4253 #[xml(rename = "IsIdle", ns(""))]
4254 pub is_idle: Option<bool>,
4255 #[xml(rename = "IsZoneBridge", ns(""))]
4256 pub is_zone_bridge: Option<bool>,
4257 #[xml(rename = "LastChangedPlayState", ns(""))]
4258 pub last_changed_play_state: Option<String>,
4259 #[xml(rename = "MicEnabled", ns(""))]
4260 pub mic_enabled: Option<u32>,
4261 #[xml(rename = "MoreInfo", ns(""))]
4262 pub more_info: Option<String>,
4263 #[xml(rename = "Orientation", ns(""))]
4264 pub orientation: Option<i32>,
4265 #[xml(rename = "RoomCalibrationState", ns(""))]
4266 pub room_calibration_state: Option<i32>,
4267 #[xml(rename = "SecureRegState", ns(""))]
4268 pub secure_reg_state: Option<u32>,
4269 #[xml(rename = "SettingsReplicationState", ns(""))]
4270 pub settings_replication_state: Option<String>,
4271 #[xml(rename = "SupportsAudioClip", ns(""))]
4272 pub supports_audio_clip: Option<bool>,
4273 #[xml(rename = "SupportsAudioIn", ns(""))]
4274 pub supports_audio_in: Option<bool>,
4275 #[xml(rename = "TVConfigurationError", ns(""))]
4276 pub tv_configuration_error: Option<bool>,
4277 #[xml(rename = "VoiceConfigState", ns(""))]
4278 pub voice_config_state: Option<u32>,
4279 #[xml(rename = "WifiEnabled", ns(""))]
4280 pub wifi_enabled: Option<bool>,
4281 #[xml(rename = "WirelessLeafOnly", ns(""))]
4282 pub wireless_leaf_only: Option<bool>,
4283 #[xml(rename = "WirelessMode", ns(""))]
4284 pub wireless_mode: Option<u32>,
4285 #[xml(rename = "ZoneName", ns(""))]
4286 pub zone_name: Option<String>,
4287 }
4288
4289 impl DecodeXml for DevicePropertiesEvent {
4290 fn decode_xml(xml: &str) -> crate::Result<Self> {
4291 let mut result = Self::default();
4292 let set: DevicePropertiesPropertySet = instant_xml::from_str(xml)?;
4293 for prop in set.properties {
4294 if let Some(v) = prop.air_play_enabled {
4295 result.air_play_enabled.replace(v);
4296 }
4297
4298 if let Some(v) = prop.available_room_calibration {
4299 result.available_room_calibration.replace(v);
4300 }
4301
4302 if let Some(v) = prop.behind_wifi_extender {
4303 result.behind_wifi_extender.replace(v);
4304 }
4305
4306 if let Some(v) = prop.channel_freq {
4307 result.channel_freq.replace(v);
4308 }
4309
4310 if let Some(v) = prop.channel_map_set {
4311 result.channel_map_set.replace(v);
4312 }
4313
4314 if let Some(v) = prop.config_mode {
4315 result.config_mode.replace(v);
4316 }
4317
4318 if let Some(v) = prop.configuration {
4319 result.configuration.replace(v);
4320 }
4321
4322 if let Some(v) = prop.eth_link {
4323 result.eth_link.replace(v);
4324 }
4325
4326 if let Some(v) = prop.ht_bonded_zone_commit_state {
4327 result.ht_bonded_zone_commit_state.replace(v);
4328 }
4329
4330 if let Some(v) = prop.ht_freq {
4331 result.ht_freq.replace(v);
4332 }
4333
4334 if let Some(v) = prop.ht_sat_chan_map_set {
4335 result.ht_sat_chan_map_set.replace(v);
4336 }
4337
4338 if let Some(v) = prop.has_configured_ssid {
4339 result.has_configured_ssid.replace(v);
4340 }
4341
4342 if let Some(v) = prop.hdmi_cec_available {
4343 result.hdmi_cec_available.replace(v);
4344 }
4345
4346 if let Some(v) = prop.icon {
4347 result.icon.replace(v);
4348 }
4349
4350 if let Some(v) = prop.invisible {
4351 result.invisible.replace(v);
4352 }
4353
4354 if let Some(v) = prop.is_idle {
4355 result.is_idle.replace(v);
4356 }
4357
4358 if let Some(v) = prop.is_zone_bridge {
4359 result.is_zone_bridge.replace(v);
4360 }
4361
4362 if let Some(v) = prop.last_changed_play_state {
4363 result.last_changed_play_state.replace(v);
4364 }
4365
4366 if let Some(v) = prop.mic_enabled {
4367 result.mic_enabled.replace(v);
4368 }
4369
4370 if let Some(v) = prop.more_info {
4371 result.more_info.replace(v);
4372 }
4373
4374 if let Some(v) = prop.orientation {
4375 result.orientation.replace(v);
4376 }
4377
4378 if let Some(v) = prop.room_calibration_state {
4379 result.room_calibration_state.replace(v);
4380 }
4381
4382 if let Some(v) = prop.secure_reg_state {
4383 result.secure_reg_state.replace(v);
4384 }
4385
4386 if let Some(v) = prop.settings_replication_state {
4387 result.settings_replication_state.replace(v);
4388 }
4389
4390 if let Some(v) = prop.supports_audio_clip {
4391 result.supports_audio_clip.replace(v);
4392 }
4393
4394 if let Some(v) = prop.supports_audio_in {
4395 result.supports_audio_in.replace(v);
4396 }
4397
4398 if let Some(v) = prop.tv_configuration_error {
4399 result.tv_configuration_error.replace(v);
4400 }
4401
4402 if let Some(v) = prop.voice_config_state {
4403 result.voice_config_state.replace(v);
4404 }
4405
4406 if let Some(v) = prop.wifi_enabled {
4407 result.wifi_enabled.replace(v);
4408 }
4409
4410 if let Some(v) = prop.wireless_leaf_only {
4411 result.wireless_leaf_only.replace(v);
4412 }
4413
4414 if let Some(v) = prop.wireless_mode {
4415 result.wireless_mode.replace(v);
4416 }
4417
4418 if let Some(v) = prop.zone_name {
4419 result.zone_name.replace(v);
4420 }
4421 }
4422 Ok(result)
4423 }
4424 }
4425
4426 impl crate::SonosDevice {
4427 pub async fn subscribe_device_properties(
4429 &self,
4430 ) -> crate::Result<crate::upnp::EventStream<DevicePropertiesEvent>> {
4431 self.subscribe_helper(&SERVICE_TYPE).await
4432 }
4433 }
4434}
4435
4436#[derive(PartialEq, Debug, Clone, Eq, Default)]
4437pub enum ButtonLockState {
4438 #[default]
4439 On,
4440 Off,
4441
4442 Unspecified(String),
4446}
4447
4448impl ToString for ButtonLockState {
4449 fn to_string(&self) -> String {
4450 match self {
4451 ButtonLockState::On => "On".to_string(),
4452 ButtonLockState::Off => "Off".to_string(),
4453 ButtonLockState::Unspecified(s) => s.to_string(),
4454 }
4455 }
4456}
4457
4458impl FromStr for ButtonLockState {
4459 type Err = crate::Error;
4460 fn from_str(s: &str) -> Result<ButtonLockState> {
4461 match s {
4462 "On" => Ok(ButtonLockState::On),
4463 "Off" => Ok(ButtonLockState::Off),
4464 s => Ok(ButtonLockState::Unspecified(s.to_string())),
4465 }
4466 }
4467}
4468
4469impl instant_xml::ToXml for ButtonLockState {
4470 fn serialize<W: std::fmt::Write + ?Sized>(
4471 &self,
4472 field: Option<instant_xml::Id<'_>>,
4473 serializer: &mut instant_xml::Serializer<W>,
4474 ) -> std::result::Result<(), instant_xml::Error> {
4475 self.to_string().serialize(field, serializer)
4476 }
4477
4478 fn present(&self) -> bool {
4479 true
4480 }
4481}
4482
4483impl<'xml> instant_xml::FromXml<'xml> for ButtonLockState {
4484 #[inline]
4485 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
4486 match field {
4487 Some(field) => id == field,
4488 None => false,
4489 }
4490 }
4491
4492 fn deserialize<'cx>(
4493 into: &mut Self::Accumulator,
4494 field: &'static str,
4495 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
4496 ) -> std::result::Result<(), instant_xml::Error> {
4497 if into.is_some() {
4498 return Err(instant_xml::Error::DuplicateValue(field));
4499 }
4500
4501 match deserializer.take_str()? {
4502 Some(value) => {
4503 let parsed: ButtonLockState = value.parse().map_err(|err| {
4504 instant_xml::Error::Other(format!(
4505 "invalid value for field {field}: {value}: {err:#}"
4506 ))
4507 })?;
4508 *into = Some(parsed);
4509 Ok(())
4510 }
4511 None => Err(instant_xml::Error::MissingValue(field)),
4512 }
4513 }
4514
4515 type Accumulator = Option<ButtonLockState>;
4516 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
4517}
4518
4519#[derive(PartialEq, Debug, Clone, Eq, Default)]
4520pub enum LEDState {
4521 #[default]
4522 On,
4523 Off,
4524
4525 Unspecified(String),
4529}
4530
4531impl ToString for LEDState {
4532 fn to_string(&self) -> String {
4533 match self {
4534 LEDState::On => "On".to_string(),
4535 LEDState::Off => "Off".to_string(),
4536 LEDState::Unspecified(s) => s.to_string(),
4537 }
4538 }
4539}
4540
4541impl FromStr for LEDState {
4542 type Err = crate::Error;
4543 fn from_str(s: &str) -> Result<LEDState> {
4544 match s {
4545 "On" => Ok(LEDState::On),
4546 "Off" => Ok(LEDState::Off),
4547 s => Ok(LEDState::Unspecified(s.to_string())),
4548 }
4549 }
4550}
4551
4552impl instant_xml::ToXml for LEDState {
4553 fn serialize<W: std::fmt::Write + ?Sized>(
4554 &self,
4555 field: Option<instant_xml::Id<'_>>,
4556 serializer: &mut instant_xml::Serializer<W>,
4557 ) -> std::result::Result<(), instant_xml::Error> {
4558 self.to_string().serialize(field, serializer)
4559 }
4560
4561 fn present(&self) -> bool {
4562 true
4563 }
4564}
4565
4566impl<'xml> instant_xml::FromXml<'xml> for LEDState {
4567 #[inline]
4568 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
4569 match field {
4570 Some(field) => id == field,
4571 None => false,
4572 }
4573 }
4574
4575 fn deserialize<'cx>(
4576 into: &mut Self::Accumulator,
4577 field: &'static str,
4578 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
4579 ) -> std::result::Result<(), instant_xml::Error> {
4580 if into.is_some() {
4581 return Err(instant_xml::Error::DuplicateValue(field));
4582 }
4583
4584 match deserializer.take_str()? {
4585 Some(value) => {
4586 let parsed: LEDState = value.parse().map_err(|err| {
4587 instant_xml::Error::Other(format!(
4588 "invalid value for field {field}: {value}: {err:#}"
4589 ))
4590 })?;
4591 *into = Some(parsed);
4592 Ok(())
4593 }
4594 None => Err(instant_xml::Error::MissingValue(field)),
4595 }
4596 }
4597
4598 type Accumulator = Option<LEDState>;
4599 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
4600}
4601
4602pub mod group_management {
4604 use super::*;
4605
4606 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:GroupManagement:1";
4609
4610 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4611 #[xml(rename = "AddMember", ns(SERVICE_TYPE))]
4612 pub struct AddMemberRequest {
4613 #[xml(rename = "MemberID", ns(""))]
4614 pub member_id: String,
4615 #[xml(rename = "BootSeq", ns(""))]
4616 pub boot_seq: u32,
4617 }
4618
4619 #[derive(FromXml, Debug, Clone, PartialEq)]
4620 #[xml(rename = "AddMemberResponse", ns(SERVICE_TYPE))]
4621 pub struct AddMemberResponse {
4622 #[xml(rename = "CurrentTransportSettings", ns(""))]
4623 pub current_transport_settings: Option<String>,
4624 #[xml(rename = "CurrentURI", ns(""))]
4625 pub current_uri: Option<String>,
4626 #[xml(rename = "GroupUUIDJoined", ns(""))]
4627 pub group_uuid_joined: Option<String>,
4628 #[xml(rename = "ResetVolumeAfter", ns(""))]
4629 pub reset_volume_after: Option<bool>,
4630 #[xml(rename = "VolumeAVTransportURI", ns(""))]
4631 pub volume_av_transport_uri: Option<String>,
4632 }
4633
4634 impl crate::DecodeSoapResponse for AddMemberResponse {
4635 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
4636 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
4637 Ok(envelope.body.payload)
4638 }
4639 }
4640
4641 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4642 #[xml(rename = "RemoveMember", ns(SERVICE_TYPE))]
4643 pub struct RemoveMemberRequest {
4644 #[xml(rename = "MemberID", ns(""))]
4645 pub member_id: String,
4646 }
4647
4648 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4649 #[xml(rename = "ReportTrackBufferingResult", ns(SERVICE_TYPE))]
4650 pub struct ReportTrackBufferingResultRequest {
4651 #[xml(rename = "MemberID", ns(""))]
4652 pub member_id: String,
4653 #[xml(rename = "ResultCode", ns(""))]
4654 pub result_code: i32,
4655 }
4656
4657 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4658 #[xml(rename = "SetSourceAreaIds", ns(SERVICE_TYPE))]
4659 pub struct SetSourceAreaIdsRequest {
4660 #[xml(rename = "DesiredSourceAreaIds", ns(""))]
4661 pub desired_source_area_ids: String,
4662 }
4663
4664 #[derive(Debug, Clone, PartialEq, Default)]
4668 pub struct GroupManagementEvent {
4669 pub group_coordinator_is_local: Option<bool>,
4670 pub local_group_uuid: Option<String>,
4671 pub reset_volume_after: Option<bool>,
4672 pub virtual_line_in_group_id: Option<String>,
4673 pub volume_av_transport_uri: Option<String>,
4674 }
4675
4676 #[derive(FromXml, Debug, Clone, PartialEq)]
4677 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
4678 struct GroupManagementPropertySet {
4679 pub properties: Vec<GroupManagementProperty>,
4680 }
4681
4682 #[derive(FromXml, Debug, Clone, PartialEq)]
4683 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
4684 struct GroupManagementProperty {
4685 #[xml(rename = "GroupCoordinatorIsLocal", ns(""))]
4686 pub group_coordinator_is_local: Option<bool>,
4687 #[xml(rename = "LocalGroupUUID", ns(""))]
4688 pub local_group_uuid: Option<String>,
4689 #[xml(rename = "ResetVolumeAfter", ns(""))]
4690 pub reset_volume_after: Option<bool>,
4691 #[xml(rename = "VirtualLineInGroupID", ns(""))]
4692 pub virtual_line_in_group_id: Option<String>,
4693 #[xml(rename = "VolumeAVTransportURI", ns(""))]
4694 pub volume_av_transport_uri: Option<String>,
4695 }
4696
4697 impl DecodeXml for GroupManagementEvent {
4698 fn decode_xml(xml: &str) -> crate::Result<Self> {
4699 let mut result = Self::default();
4700 let set: GroupManagementPropertySet = instant_xml::from_str(xml)?;
4701 for prop in set.properties {
4702 if let Some(v) = prop.group_coordinator_is_local {
4703 result.group_coordinator_is_local.replace(v);
4704 }
4705
4706 if let Some(v) = prop.local_group_uuid {
4707 result.local_group_uuid.replace(v);
4708 }
4709
4710 if let Some(v) = prop.reset_volume_after {
4711 result.reset_volume_after.replace(v);
4712 }
4713
4714 if let Some(v) = prop.virtual_line_in_group_id {
4715 result.virtual_line_in_group_id.replace(v);
4716 }
4717
4718 if let Some(v) = prop.volume_av_transport_uri {
4719 result.volume_av_transport_uri.replace(v);
4720 }
4721 }
4722 Ok(result)
4723 }
4724 }
4725
4726 impl crate::SonosDevice {
4727 pub async fn subscribe_group_management(
4729 &self,
4730 ) -> crate::Result<crate::upnp::EventStream<GroupManagementEvent>> {
4731 self.subscribe_helper(&SERVICE_TYPE).await
4732 }
4733 }
4734}
4735
4736pub mod group_rendering_control {
4738 use super::*;
4739
4740 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:GroupRenderingControl:1";
4743
4744 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4745 #[xml(rename = "GetGroupMute", ns(SERVICE_TYPE))]
4746 pub struct GetGroupMuteRequest {
4747 #[xml(rename = "InstanceID", ns(""))]
4748 pub instance_id: u32,
4749 }
4750
4751 #[derive(FromXml, Debug, Clone, PartialEq)]
4752 #[xml(rename = "GetGroupMuteResponse", ns(SERVICE_TYPE))]
4753 pub struct GetGroupMuteResponse {
4754 #[xml(rename = "CurrentMute", ns(""))]
4755 pub current_mute: Option<bool>,
4756 }
4757
4758 impl crate::DecodeSoapResponse for GetGroupMuteResponse {
4759 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
4760 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
4761 Ok(envelope.body.payload)
4762 }
4763 }
4764
4765 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4766 #[xml(rename = "GetGroupVolume", ns(SERVICE_TYPE))]
4767 pub struct GetGroupVolumeRequest {
4768 #[xml(rename = "InstanceID", ns(""))]
4769 pub instance_id: u32,
4770 }
4771
4772 #[derive(FromXml, Debug, Clone, PartialEq)]
4773 #[xml(rename = "GetGroupVolumeResponse", ns(SERVICE_TYPE))]
4774 pub struct GetGroupVolumeResponse {
4775 #[xml(rename = "CurrentVolume", ns(""))]
4776 pub current_volume: Option<u16>,
4777 }
4778
4779 impl crate::DecodeSoapResponse for GetGroupVolumeResponse {
4780 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
4781 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
4782 Ok(envelope.body.payload)
4783 }
4784 }
4785
4786 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4787 #[xml(rename = "SetGroupMute", ns(SERVICE_TYPE))]
4788 pub struct SetGroupMuteRequest {
4789 #[xml(rename = "InstanceID", ns(""))]
4790 pub instance_id: u32,
4791 #[xml(rename = "DesiredMute", ns(""))]
4792 pub desired_mute: bool,
4793 }
4794
4795 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4796 #[xml(rename = "SetGroupVolume", ns(SERVICE_TYPE))]
4797 pub struct SetGroupVolumeRequest {
4798 #[xml(rename = "InstanceID", ns(""))]
4799 pub instance_id: u32,
4800 #[xml(rename = "DesiredVolume", ns(""))]
4802 pub desired_volume: u16,
4803 }
4804
4805 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4806 #[xml(rename = "SetRelativeGroupVolume", ns(SERVICE_TYPE))]
4807 pub struct SetRelativeGroupVolumeRequest {
4808 #[xml(rename = "InstanceID", ns(""))]
4809 pub instance_id: u32,
4810 #[xml(rename = "Adjustment", ns(""))]
4812 pub adjustment: i32,
4813 }
4814
4815 #[derive(FromXml, Debug, Clone, PartialEq)]
4816 #[xml(rename = "SetRelativeGroupVolumeResponse", ns(SERVICE_TYPE))]
4817 pub struct SetRelativeGroupVolumeResponse {
4818 #[xml(rename = "NewVolume", ns(""))]
4819 pub new_volume: Option<u16>,
4820 }
4821
4822 impl crate::DecodeSoapResponse for SetRelativeGroupVolumeResponse {
4823 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
4824 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
4825 Ok(envelope.body.payload)
4826 }
4827 }
4828
4829 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4830 #[xml(rename = "SnapshotGroupVolume", ns(SERVICE_TYPE))]
4831 pub struct SnapshotGroupVolumeRequest {
4832 #[xml(rename = "InstanceID", ns(""))]
4833 pub instance_id: u32,
4834 }
4835
4836 #[derive(Debug, Clone, PartialEq, Default)]
4840 pub struct GroupRenderingControlEvent {
4841 pub group_mute: Option<bool>,
4842 pub group_volume: Option<u16>,
4843 pub group_volume_changeable: Option<bool>,
4844 }
4845
4846 #[derive(FromXml, Debug, Clone, PartialEq)]
4847 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
4848 struct GroupRenderingControlPropertySet {
4849 pub properties: Vec<GroupRenderingControlProperty>,
4850 }
4851
4852 #[derive(FromXml, Debug, Clone, PartialEq)]
4853 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
4854 struct GroupRenderingControlProperty {
4855 #[xml(rename = "GroupMute", ns(""))]
4856 pub group_mute: Option<bool>,
4857 #[xml(rename = "GroupVolume", ns(""))]
4858 pub group_volume: Option<u16>,
4859 #[xml(rename = "GroupVolumeChangeable", ns(""))]
4860 pub group_volume_changeable: Option<bool>,
4861 }
4862
4863 impl DecodeXml for GroupRenderingControlEvent {
4864 fn decode_xml(xml: &str) -> crate::Result<Self> {
4865 let mut result = Self::default();
4866 let set: GroupRenderingControlPropertySet = instant_xml::from_str(xml)?;
4867 for prop in set.properties {
4868 if let Some(v) = prop.group_mute {
4869 result.group_mute.replace(v);
4870 }
4871
4872 if let Some(v) = prop.group_volume {
4873 result.group_volume.replace(v);
4874 }
4875
4876 if let Some(v) = prop.group_volume_changeable {
4877 result.group_volume_changeable.replace(v);
4878 }
4879 }
4880 Ok(result)
4881 }
4882 }
4883
4884 impl crate::SonosDevice {
4885 pub async fn subscribe_group_rendering_control(
4887 &self,
4888 ) -> crate::Result<crate::upnp::EventStream<GroupRenderingControlEvent>> {
4889 self.subscribe_helper(&SERVICE_TYPE).await
4890 }
4891 }
4892}
4893
4894pub mod ht_control {
4896 use super::*;
4897
4898 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:HTControl:1";
4901
4902 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4903 #[xml(rename = "CommitLearnedIRCodes", ns(SERVICE_TYPE))]
4904 pub struct CommitLearnedIrCodesRequest {
4905 #[xml(rename = "Name", ns(""))]
4906 pub name: String,
4907 }
4908
4909 #[derive(FromXml, Debug, Clone, PartialEq)]
4910 #[xml(rename = "GetIRRepeaterStateResponse", ns(SERVICE_TYPE))]
4911 pub struct GetIrRepeaterStateResponse {
4912 #[xml(rename = "CurrentIRRepeaterState", ns(""))]
4913 pub current_ir_repeater_state: Option<super::IRRepeaterState>,
4914 }
4915
4916 impl crate::DecodeSoapResponse for GetIrRepeaterStateResponse {
4917 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
4918 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
4919 Ok(envelope.body.payload)
4920 }
4921 }
4922
4923 #[derive(FromXml, Debug, Clone, PartialEq)]
4924 #[xml(rename = "GetLEDFeedbackStateResponse", ns(SERVICE_TYPE))]
4925 pub struct GetLedFeedbackStateResponse {
4926 #[xml(rename = "LEDFeedbackState", ns(""))]
4927 pub led_feedback_state: Option<super::LEDFeedbackState>,
4928 }
4929
4930 impl crate::DecodeSoapResponse for GetLedFeedbackStateResponse {
4931 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
4932 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
4933 Ok(envelope.body.payload)
4934 }
4935 }
4936
4937 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4938 #[xml(rename = "IdentifyIRRemote", ns(SERVICE_TYPE))]
4939 pub struct IdentifyIrRemoteRequest {
4940 #[xml(rename = "Timeout", ns(""))]
4941 pub timeout: u32,
4942 }
4943
4944 #[derive(FromXml, Debug, Clone, PartialEq)]
4945 #[xml(rename = "IsRemoteConfiguredResponse", ns(SERVICE_TYPE))]
4946 pub struct IsRemoteConfiguredResponse {
4947 #[xml(rename = "RemoteConfigured", ns(""))]
4948 pub remote_configured: Option<bool>,
4949 }
4950
4951 impl crate::DecodeSoapResponse for IsRemoteConfiguredResponse {
4952 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
4953 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
4954 Ok(envelope.body.payload)
4955 }
4956 }
4957
4958 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4959 #[xml(rename = "LearnIRCode", ns(SERVICE_TYPE))]
4960 pub struct LearnIrCodeRequest {
4961 #[xml(rename = "IRCode", ns(""))]
4962 pub ir_code: String,
4963 #[xml(rename = "Timeout", ns(""))]
4964 pub timeout: u32,
4965 }
4966
4967 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4968 #[xml(rename = "SetIRRepeaterState", ns(SERVICE_TYPE))]
4969 pub struct SetIrRepeaterStateRequest {
4970 #[xml(rename = "DesiredIRRepeaterState", ns(""))]
4971 pub desired_ir_repeater_state: super::IRRepeaterState,
4972 }
4973
4974 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
4975 #[xml(rename = "SetLEDFeedbackState", ns(SERVICE_TYPE))]
4976 pub struct SetLedFeedbackStateRequest {
4977 #[xml(rename = "LEDFeedbackState", ns(""))]
4978 pub led_feedback_state: super::LEDFeedbackState,
4979 }
4980
4981 #[derive(Debug, Clone, PartialEq, Default)]
4985 pub struct HTControlEvent {
4986 pub ir_repeater_state: Option<super::IRRepeaterState>,
4987 pub tos_link_connected: Option<bool>,
4988 }
4989
4990 #[derive(FromXml, Debug, Clone, PartialEq)]
4991 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
4992 struct HTControlPropertySet {
4993 pub properties: Vec<HTControlProperty>,
4994 }
4995
4996 #[derive(FromXml, Debug, Clone, PartialEq)]
4997 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
4998 struct HTControlProperty {
4999 #[xml(rename = "IRRepeaterState", ns(""))]
5000 pub ir_repeater_state: Option<super::IRRepeaterState>,
5001 #[xml(rename = "TOSLinkConnected", ns(""))]
5002 pub tos_link_connected: Option<bool>,
5003 }
5004
5005 impl DecodeXml for HTControlEvent {
5006 fn decode_xml(xml: &str) -> crate::Result<Self> {
5007 let mut result = Self::default();
5008 let set: HTControlPropertySet = instant_xml::from_str(xml)?;
5009 for prop in set.properties {
5010 if let Some(v) = prop.ir_repeater_state {
5011 result.ir_repeater_state.replace(v);
5012 }
5013
5014 if let Some(v) = prop.tos_link_connected {
5015 result.tos_link_connected.replace(v);
5016 }
5017 }
5018 Ok(result)
5019 }
5020 }
5021
5022 impl crate::SonosDevice {
5023 pub async fn subscribe_ht_control(
5025 &self,
5026 ) -> crate::Result<crate::upnp::EventStream<HTControlEvent>> {
5027 self.subscribe_helper(&SERVICE_TYPE).await
5028 }
5029 }
5030}
5031
5032#[derive(PartialEq, Debug, Clone, Eq, Default)]
5033pub enum IRRepeaterState {
5034 #[default]
5035 On,
5036 Off,
5037 Disabled,
5038
5039 Unspecified(String),
5043}
5044
5045impl ToString for IRRepeaterState {
5046 fn to_string(&self) -> String {
5047 match self {
5048 IRRepeaterState::On => "On".to_string(),
5049 IRRepeaterState::Off => "Off".to_string(),
5050 IRRepeaterState::Disabled => "Disabled".to_string(),
5051 IRRepeaterState::Unspecified(s) => s.to_string(),
5052 }
5053 }
5054}
5055
5056impl FromStr for IRRepeaterState {
5057 type Err = crate::Error;
5058 fn from_str(s: &str) -> Result<IRRepeaterState> {
5059 match s {
5060 "On" => Ok(IRRepeaterState::On),
5061 "Off" => Ok(IRRepeaterState::Off),
5062 "Disabled" => Ok(IRRepeaterState::Disabled),
5063 s => Ok(IRRepeaterState::Unspecified(s.to_string())),
5064 }
5065 }
5066}
5067
5068impl instant_xml::ToXml for IRRepeaterState {
5069 fn serialize<W: std::fmt::Write + ?Sized>(
5070 &self,
5071 field: Option<instant_xml::Id<'_>>,
5072 serializer: &mut instant_xml::Serializer<W>,
5073 ) -> std::result::Result<(), instant_xml::Error> {
5074 self.to_string().serialize(field, serializer)
5075 }
5076
5077 fn present(&self) -> bool {
5078 true
5079 }
5080}
5081
5082impl<'xml> instant_xml::FromXml<'xml> for IRRepeaterState {
5083 #[inline]
5084 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
5085 match field {
5086 Some(field) => id == field,
5087 None => false,
5088 }
5089 }
5090
5091 fn deserialize<'cx>(
5092 into: &mut Self::Accumulator,
5093 field: &'static str,
5094 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
5095 ) -> std::result::Result<(), instant_xml::Error> {
5096 if into.is_some() {
5097 return Err(instant_xml::Error::DuplicateValue(field));
5098 }
5099
5100 match deserializer.take_str()? {
5101 Some(value) => {
5102 let parsed: IRRepeaterState = value.parse().map_err(|err| {
5103 instant_xml::Error::Other(format!(
5104 "invalid value for field {field}: {value}: {err:#}"
5105 ))
5106 })?;
5107 *into = Some(parsed);
5108 Ok(())
5109 }
5110 None => Err(instant_xml::Error::MissingValue(field)),
5111 }
5112 }
5113
5114 type Accumulator = Option<IRRepeaterState>;
5115 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
5116}
5117
5118#[derive(PartialEq, Debug, Clone, Eq, Default)]
5119pub enum LEDFeedbackState {
5120 #[default]
5121 On,
5122 Off,
5123
5124 Unspecified(String),
5128}
5129
5130impl ToString for LEDFeedbackState {
5131 fn to_string(&self) -> String {
5132 match self {
5133 LEDFeedbackState::On => "On".to_string(),
5134 LEDFeedbackState::Off => "Off".to_string(),
5135 LEDFeedbackState::Unspecified(s) => s.to_string(),
5136 }
5137 }
5138}
5139
5140impl FromStr for LEDFeedbackState {
5141 type Err = crate::Error;
5142 fn from_str(s: &str) -> Result<LEDFeedbackState> {
5143 match s {
5144 "On" => Ok(LEDFeedbackState::On),
5145 "Off" => Ok(LEDFeedbackState::Off),
5146 s => Ok(LEDFeedbackState::Unspecified(s.to_string())),
5147 }
5148 }
5149}
5150
5151impl instant_xml::ToXml for LEDFeedbackState {
5152 fn serialize<W: std::fmt::Write + ?Sized>(
5153 &self,
5154 field: Option<instant_xml::Id<'_>>,
5155 serializer: &mut instant_xml::Serializer<W>,
5156 ) -> std::result::Result<(), instant_xml::Error> {
5157 self.to_string().serialize(field, serializer)
5158 }
5159
5160 fn present(&self) -> bool {
5161 true
5162 }
5163}
5164
5165impl<'xml> instant_xml::FromXml<'xml> for LEDFeedbackState {
5166 #[inline]
5167 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
5168 match field {
5169 Some(field) => id == field,
5170 None => false,
5171 }
5172 }
5173
5174 fn deserialize<'cx>(
5175 into: &mut Self::Accumulator,
5176 field: &'static str,
5177 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
5178 ) -> std::result::Result<(), instant_xml::Error> {
5179 if into.is_some() {
5180 return Err(instant_xml::Error::DuplicateValue(field));
5181 }
5182
5183 match deserializer.take_str()? {
5184 Some(value) => {
5185 let parsed: LEDFeedbackState = value.parse().map_err(|err| {
5186 instant_xml::Error::Other(format!(
5187 "invalid value for field {field}: {value}: {err:#}"
5188 ))
5189 })?;
5190 *into = Some(parsed);
5191 Ok(())
5192 }
5193 None => Err(instant_xml::Error::MissingValue(field)),
5194 }
5195 }
5196
5197 type Accumulator = Option<LEDFeedbackState>;
5198 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
5199}
5200
5201pub mod music_services {
5203 use super::*;
5204
5205 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:MusicServices:1";
5208
5209 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5210 #[xml(rename = "GetSessionId", ns(SERVICE_TYPE))]
5211 pub struct GetSessionIdRequest {
5212 #[xml(rename = "ServiceId", ns(""))]
5213 pub service_id: u32,
5214 #[xml(rename = "Username", ns(""))]
5215 pub username: String,
5216 }
5217
5218 #[derive(FromXml, Debug, Clone, PartialEq)]
5219 #[xml(rename = "GetSessionIdResponse", ns(SERVICE_TYPE))]
5220 pub struct GetSessionIdResponse {
5221 #[xml(rename = "SessionId", ns(""))]
5222 pub session_id: Option<String>,
5223 }
5224
5225 impl crate::DecodeSoapResponse for GetSessionIdResponse {
5226 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5227 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5228 Ok(envelope.body.payload)
5229 }
5230 }
5231
5232 #[derive(FromXml, Debug, Clone, PartialEq)]
5233 #[xml(rename = "ListAvailableServicesResponse", ns(SERVICE_TYPE))]
5234 pub struct ListAvailableServicesResponse {
5235 #[xml(rename = "AvailableServiceDescriptorList", ns(""))]
5236 pub available_service_descriptor_list: Option<String>,
5237 #[xml(rename = "AvailableServiceTypeList", ns(""))]
5238 pub available_service_type_list: Option<String>,
5239 #[xml(rename = "AvailableServiceListVersion", ns(""))]
5240 pub available_service_list_version: Option<String>,
5241 }
5242
5243 impl crate::DecodeSoapResponse for ListAvailableServicesResponse {
5244 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5245 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5246 Ok(envelope.body.payload)
5247 }
5248 }
5249
5250 #[derive(Debug, Clone, PartialEq, Default)]
5254 pub struct MusicServicesEvent {
5255 pub service_list_version: Option<String>,
5256 }
5257
5258 #[derive(FromXml, Debug, Clone, PartialEq)]
5259 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
5260 struct MusicServicesPropertySet {
5261 pub properties: Vec<MusicServicesProperty>,
5262 }
5263
5264 #[derive(FromXml, Debug, Clone, PartialEq)]
5265 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
5266 struct MusicServicesProperty {
5267 #[xml(rename = "ServiceListVersion", ns(""))]
5268 pub service_list_version: Option<String>,
5269 }
5270
5271 impl DecodeXml for MusicServicesEvent {
5272 fn decode_xml(xml: &str) -> crate::Result<Self> {
5273 let mut result = Self::default();
5274 let set: MusicServicesPropertySet = instant_xml::from_str(xml)?;
5275 for prop in set.properties {
5276 if let Some(v) = prop.service_list_version {
5277 result.service_list_version.replace(v);
5278 }
5279 }
5280 Ok(result)
5281 }
5282 }
5283
5284 impl crate::SonosDevice {
5285 pub async fn subscribe_music_services(
5287 &self,
5288 ) -> crate::Result<crate::upnp::EventStream<MusicServicesEvent>> {
5289 self.subscribe_helper(&SERVICE_TYPE).await
5290 }
5291 }
5292}
5293
5294pub mod q_play {
5296 use super::*;
5297
5298 pub const SERVICE_TYPE: &str = "urn:schemas-tencent-com:service:QPlay:1";
5301
5302 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5303 #[xml(rename = "QPlayAuth", ns(SERVICE_TYPE))]
5304 pub struct QPlayAuthRequest {
5305 #[xml(rename = "Seed", ns(""))]
5306 pub seed: String,
5307 }
5308
5309 #[derive(FromXml, Debug, Clone, PartialEq)]
5310 #[xml(rename = "QPlayAuthResponse", ns(SERVICE_TYPE))]
5311 pub struct QPlayAuthResponse {
5312 #[xml(rename = "Code", ns(""))]
5313 pub code: Option<String>,
5314 #[xml(rename = "MID", ns(""))]
5315 pub mid: Option<String>,
5316 #[xml(rename = "DID", ns(""))]
5317 pub did: Option<String>,
5318 }
5319
5320 impl crate::DecodeSoapResponse for QPlayAuthResponse {
5321 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5322 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5323 Ok(envelope.body.payload)
5324 }
5325 }
5326}
5327
5328pub mod queue {
5330 use super::*;
5331
5332 pub const SERVICE_TYPE: &str = "urn:schemas-sonos-com:service:Queue:1";
5335
5336 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5337 #[xml(rename = "AddMultipleURIs", ns(SERVICE_TYPE))]
5338 pub struct AddMultipleUrisRequest {
5339 #[xml(rename = "QueueID", ns(""))]
5340 pub queue_id: u32,
5341 #[xml(rename = "UpdateID", ns(""))]
5342 pub update_id: u32,
5343 #[xml(rename = "ContainerURI", ns(""))]
5344 pub container_uri: String,
5345 #[xml(rename = "ContainerMetaData", ns(""))]
5346 pub container_meta_data: String,
5347 #[xml(rename = "DesiredFirstTrackNumberEnqueued", ns(""))]
5348 pub desired_first_track_number_enqueued: u32,
5349 #[xml(rename = "EnqueueAsNext", ns(""))]
5350 pub enqueue_as_next: bool,
5351 #[xml(rename = "NumberOfURIs", ns(""))]
5352 pub number_of_uris: u32,
5353 #[xml(rename = "EnqueuedURIsAndMetaData", ns(""))]
5354 pub enqueued_uris_and_meta_data: String,
5355 }
5356
5357 #[derive(FromXml, Debug, Clone, PartialEq)]
5358 #[xml(rename = "AddMultipleURIsResponse", ns(SERVICE_TYPE))]
5359 pub struct AddMultipleUrisResponse {
5360 #[xml(rename = "FirstTrackNumberEnqueued", ns(""))]
5361 pub first_track_number_enqueued: Option<u32>,
5362 #[xml(rename = "NumTracksAdded", ns(""))]
5363 pub num_tracks_added: Option<u32>,
5364 #[xml(rename = "NewQueueLength", ns(""))]
5365 pub new_queue_length: Option<u32>,
5366 #[xml(rename = "NewUpdateID", ns(""))]
5367 pub new_update_id: Option<u32>,
5368 }
5369
5370 impl crate::DecodeSoapResponse for AddMultipleUrisResponse {
5371 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5372 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5373 Ok(envelope.body.payload)
5374 }
5375 }
5376
5377 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5378 #[xml(rename = "AddURI", ns(SERVICE_TYPE))]
5379 pub struct AddUriRequest {
5380 #[xml(rename = "QueueID", ns(""))]
5381 pub queue_id: u32,
5382 #[xml(rename = "UpdateID", ns(""))]
5383 pub update_id: u32,
5384 #[xml(rename = "EnqueuedURI", ns(""))]
5385 pub enqueued_uri: String,
5386 #[xml(rename = "EnqueuedURIMetaData", ns(""))]
5387 pub enqueued_uri_meta_data: DecodeXmlString<crate::TrackMetaData>,
5388 #[xml(rename = "DesiredFirstTrackNumberEnqueued", ns(""))]
5389 pub desired_first_track_number_enqueued: u32,
5390 #[xml(rename = "EnqueueAsNext", ns(""))]
5391 pub enqueue_as_next: bool,
5392 }
5393
5394 #[derive(FromXml, Debug, Clone, PartialEq)]
5395 #[xml(rename = "AddURIResponse", ns(SERVICE_TYPE))]
5396 pub struct AddUriResponse {
5397 #[xml(rename = "FirstTrackNumberEnqueued", ns(""))]
5398 pub first_track_number_enqueued: Option<u32>,
5399 #[xml(rename = "NumTracksAdded", ns(""))]
5400 pub num_tracks_added: Option<u32>,
5401 #[xml(rename = "NewQueueLength", ns(""))]
5402 pub new_queue_length: Option<u32>,
5403 #[xml(rename = "NewUpdateID", ns(""))]
5404 pub new_update_id: Option<u32>,
5405 }
5406
5407 impl crate::DecodeSoapResponse for AddUriResponse {
5408 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5409 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5410 Ok(envelope.body.payload)
5411 }
5412 }
5413
5414 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5415 #[xml(rename = "AttachQueue", ns(SERVICE_TYPE))]
5416 pub struct AttachQueueRequest {
5417 #[xml(rename = "QueueOwnerID", ns(""))]
5418 pub queue_owner_id: String,
5419 }
5420
5421 #[derive(FromXml, Debug, Clone, PartialEq)]
5422 #[xml(rename = "AttachQueueResponse", ns(SERVICE_TYPE))]
5423 pub struct AttachQueueResponse {
5424 #[xml(rename = "QueueID", ns(""))]
5425 pub queue_id: Option<u32>,
5426 #[xml(rename = "QueueOwnerContext", ns(""))]
5427 pub queue_owner_context: Option<String>,
5428 }
5429
5430 impl crate::DecodeSoapResponse for AttachQueueResponse {
5431 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5432 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5433 Ok(envelope.body.payload)
5434 }
5435 }
5436
5437 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5438 #[xml(rename = "Browse", ns(SERVICE_TYPE))]
5439 pub struct BrowseRequest {
5440 #[xml(rename = "QueueID", ns(""))]
5441 pub queue_id: u32,
5442 #[xml(rename = "StartingIndex", ns(""))]
5443 pub starting_index: u32,
5444 #[xml(rename = "RequestedCount", ns(""))]
5445 pub requested_count: u32,
5446 }
5447
5448 #[derive(FromXml, Debug, Clone, PartialEq)]
5449 #[xml(rename = "BrowseResponse", ns(SERVICE_TYPE))]
5450 pub struct BrowseResponse {
5451 #[xml(rename = "Result", ns(""))]
5452 pub result: Option<DecodeXmlString<crate::TrackMetaDataList>>,
5453 #[xml(rename = "NumberReturned", ns(""))]
5454 pub number_returned: Option<u32>,
5455 #[xml(rename = "TotalMatches", ns(""))]
5456 pub total_matches: Option<u32>,
5457 #[xml(rename = "UpdateID", ns(""))]
5458 pub update_id: Option<u32>,
5459 }
5460
5461 impl crate::DecodeSoapResponse for BrowseResponse {
5462 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5463 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5464 Ok(envelope.body.payload)
5465 }
5466 }
5467
5468 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5469 #[xml(rename = "CreateQueue", ns(SERVICE_TYPE))]
5470 pub struct CreateQueueRequest {
5471 #[xml(rename = "QueueOwnerID", ns(""))]
5472 pub queue_owner_id: String,
5473 #[xml(rename = "QueueOwnerContext", ns(""))]
5474 pub queue_owner_context: String,
5475 #[xml(rename = "QueuePolicy", ns(""))]
5476 pub queue_policy: String,
5477 }
5478
5479 #[derive(FromXml, Debug, Clone, PartialEq)]
5480 #[xml(rename = "CreateQueueResponse", ns(SERVICE_TYPE))]
5481 pub struct CreateQueueResponse {
5482 #[xml(rename = "QueueID", ns(""))]
5483 pub queue_id: Option<u32>,
5484 }
5485
5486 impl crate::DecodeSoapResponse for CreateQueueResponse {
5487 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5488 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5489 Ok(envelope.body.payload)
5490 }
5491 }
5492
5493 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5494 #[xml(rename = "RemoveAllTracks", ns(SERVICE_TYPE))]
5495 pub struct RemoveAllTracksRequest {
5496 #[xml(rename = "QueueID", ns(""))]
5497 pub queue_id: u32,
5498 #[xml(rename = "UpdateID", ns(""))]
5499 pub update_id: u32,
5500 }
5501
5502 #[derive(FromXml, Debug, Clone, PartialEq)]
5503 #[xml(rename = "RemoveAllTracksResponse", ns(SERVICE_TYPE))]
5504 pub struct RemoveAllTracksResponse {
5505 #[xml(rename = "NewUpdateID", ns(""))]
5506 pub new_update_id: Option<u32>,
5507 }
5508
5509 impl crate::DecodeSoapResponse for RemoveAllTracksResponse {
5510 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5511 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5512 Ok(envelope.body.payload)
5513 }
5514 }
5515
5516 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5517 #[xml(rename = "RemoveTrackRange", ns(SERVICE_TYPE))]
5518 pub struct RemoveTrackRangeRequest {
5519 #[xml(rename = "QueueID", ns(""))]
5520 pub queue_id: u32,
5521 #[xml(rename = "UpdateID", ns(""))]
5522 pub update_id: u32,
5523 #[xml(rename = "StartingIndex", ns(""))]
5524 pub starting_index: u32,
5525 #[xml(rename = "NumberOfTracks", ns(""))]
5526 pub number_of_tracks: u32,
5527 }
5528
5529 #[derive(FromXml, Debug, Clone, PartialEq)]
5530 #[xml(rename = "RemoveTrackRangeResponse", ns(SERVICE_TYPE))]
5531 pub struct RemoveTrackRangeResponse {
5532 #[xml(rename = "NewUpdateID", ns(""))]
5533 pub new_update_id: Option<u32>,
5534 }
5535
5536 impl crate::DecodeSoapResponse for RemoveTrackRangeResponse {
5537 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5538 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5539 Ok(envelope.body.payload)
5540 }
5541 }
5542
5543 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5544 #[xml(rename = "ReorderTracks", ns(SERVICE_TYPE))]
5545 pub struct ReorderTracksRequest {
5546 #[xml(rename = "QueueID", ns(""))]
5547 pub queue_id: u32,
5548 #[xml(rename = "StartingIndex", ns(""))]
5549 pub starting_index: u32,
5550 #[xml(rename = "NumberOfTracks", ns(""))]
5551 pub number_of_tracks: u32,
5552 #[xml(rename = "InsertBefore", ns(""))]
5553 pub insert_before: u32,
5554 #[xml(rename = "UpdateID", ns(""))]
5555 pub update_id: u32,
5556 }
5557
5558 #[derive(FromXml, Debug, Clone, PartialEq)]
5559 #[xml(rename = "ReorderTracksResponse", ns(SERVICE_TYPE))]
5560 pub struct ReorderTracksResponse {
5561 #[xml(rename = "NewUpdateID", ns(""))]
5562 pub new_update_id: Option<u32>,
5563 }
5564
5565 impl crate::DecodeSoapResponse for ReorderTracksResponse {
5566 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5567 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5568 Ok(envelope.body.payload)
5569 }
5570 }
5571
5572 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5573 #[xml(rename = "ReplaceAllTracks", ns(SERVICE_TYPE))]
5574 pub struct ReplaceAllTracksRequest {
5575 #[xml(rename = "QueueID", ns(""))]
5576 pub queue_id: u32,
5577 #[xml(rename = "UpdateID", ns(""))]
5578 pub update_id: u32,
5579 #[xml(rename = "ContainerURI", ns(""))]
5580 pub container_uri: String,
5581 #[xml(rename = "ContainerMetaData", ns(""))]
5582 pub container_meta_data: String,
5583 #[xml(rename = "CurrentTrackIndex", ns(""))]
5584 pub current_track_index: u32,
5585 #[xml(rename = "NewCurrentTrackIndices", ns(""))]
5586 pub new_current_track_indices: String,
5587 #[xml(rename = "NumberOfURIs", ns(""))]
5588 pub number_of_uris: u32,
5589 #[xml(rename = "EnqueuedURIsAndMetaData", ns(""))]
5590 pub enqueued_uris_and_meta_data: String,
5591 }
5592
5593 #[derive(FromXml, Debug, Clone, PartialEq)]
5594 #[xml(rename = "ReplaceAllTracksResponse", ns(SERVICE_TYPE))]
5595 pub struct ReplaceAllTracksResponse {
5596 #[xml(rename = "NewQueueLength", ns(""))]
5597 pub new_queue_length: Option<u32>,
5598 #[xml(rename = "NewUpdateID", ns(""))]
5599 pub new_update_id: Option<u32>,
5600 }
5601
5602 impl crate::DecodeSoapResponse for ReplaceAllTracksResponse {
5603 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5604 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5605 Ok(envelope.body.payload)
5606 }
5607 }
5608
5609 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5610 #[xml(rename = "SaveAsSonosPlaylist", ns(SERVICE_TYPE))]
5611 pub struct SaveAsSonosPlaylistRequest {
5612 #[xml(rename = "QueueID", ns(""))]
5613 pub queue_id: u32,
5614 #[xml(rename = "Title", ns(""))]
5615 pub title: String,
5616 #[xml(rename = "ObjectID", ns(""))]
5617 pub object_id: String,
5618 }
5619
5620 #[derive(FromXml, Debug, Clone, PartialEq)]
5621 #[xml(rename = "SaveAsSonosPlaylistResponse", ns(SERVICE_TYPE))]
5622 pub struct SaveAsSonosPlaylistResponse {
5623 #[xml(rename = "AssignedObjectID", ns(""))]
5624 pub assigned_object_id: Option<String>,
5625 }
5626
5627 impl crate::DecodeSoapResponse for SaveAsSonosPlaylistResponse {
5628 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5629 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5630 Ok(envelope.body.payload)
5631 }
5632 }
5633
5634 #[derive(Debug, Clone, PartialEq, Default)]
5638 pub struct QueueEvent {
5639 pub last_change: Option<DecodeXmlString<QueueLastChangeMap>>,
5640 }
5641
5642 #[derive(FromXml, Debug, Clone, PartialEq)]
5643 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
5644 struct QueuePropertySet {
5645 pub properties: Vec<QueueProperty>,
5646 }
5647
5648 #[derive(FromXml, Debug, Clone, PartialEq)]
5649 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
5650 struct QueueProperty {
5651 #[xml(rename = "LastChange", ns(""))]
5652 pub last_change: Option<DecodeXmlString<QueueLastChangeMap>>,
5653 }
5654
5655 impl DecodeXml for QueueEvent {
5656 fn decode_xml(xml: &str) -> crate::Result<Self> {
5657 let mut result = Self::default();
5658 let set: QueuePropertySet = instant_xml::from_str(xml)?;
5659 for prop in set.properties {
5660 if let Some(v) = prop.last_change {
5661 result.last_change.replace(v);
5662 }
5663 }
5664 Ok(result)
5665 }
5666 }
5667
5668 impl crate::SonosDevice {
5669 pub async fn subscribe_queue(&self) -> crate::Result<crate::upnp::EventStream<QueueEvent>> {
5671 self.subscribe_helper(&SERVICE_TYPE).await
5672 }
5673 }
5674
5675 #[derive(Debug, Clone, PartialEq, Default)]
5676 pub struct QueueLastChange {
5677 pub count: Option<u32>,
5678 pub enqueue_as_next: Option<bool>,
5679 pub index: Option<u32>,
5680 pub list_uri: Option<String>,
5681 pub list_uri_and_metadata: Option<String>,
5682 pub num_tracks: Option<u32>,
5683 pub object_id: Option<String>,
5684 pub queue_id: Option<u32>,
5685 pub queue_owner_context: Option<String>,
5686 pub queue_owner_id: Option<String>,
5687 pub queue_policy: Option<String>,
5688 pub result: Option<String>,
5689 pub saved_queue_title: Option<String>,
5690 pub track_number: Option<u32>,
5691 pub track_numbers_csv: Option<String>,
5692 pub uri: Option<String>,
5693 pub uri_meta_data: Option<String>,
5694 pub update_id: Option<u32>,
5695 pub curated: Option<bool>,
5696 }
5697
5698 #[derive(FromXml)]
5699 #[xml(rename = "Count", ns(LAST_CHANGE_NS))]
5700 #[allow(non_camel_case_types)]
5701 struct QueueLastChangeCount {
5702 #[xml(attribute)]
5703 val: Option<u32>,
5704 }
5705
5706 #[derive(FromXml)]
5707 #[xml(rename = "EnqueueAsNext", ns(LAST_CHANGE_NS))]
5708 #[allow(non_camel_case_types)]
5709 struct QueueLastChangeEnqueueAsNext {
5710 #[xml(attribute)]
5711 val: Option<bool>,
5712 }
5713
5714 #[derive(FromXml)]
5715 #[xml(rename = "Index", ns(LAST_CHANGE_NS))]
5716 #[allow(non_camel_case_types)]
5717 struct QueueLastChangeIndex {
5718 #[xml(attribute)]
5719 val: Option<u32>,
5720 }
5721
5722 #[derive(FromXml)]
5723 #[xml(rename = "LIST_URI", ns(LAST_CHANGE_NS))]
5724 #[allow(non_camel_case_types)]
5725 struct QueueLastChangeLIST_URI {
5726 #[xml(attribute)]
5727 val: Option<String>,
5728 }
5729
5730 #[derive(FromXml)]
5731 #[xml(rename = "LIST_URI_AND_METADATA", ns(LAST_CHANGE_NS))]
5732 #[allow(non_camel_case_types)]
5733 struct QueueLastChangeLIST_URI_AND_METADATA {
5734 #[xml(attribute)]
5735 val: Option<String>,
5736 }
5737
5738 #[derive(FromXml)]
5739 #[xml(rename = "NumTracks", ns(LAST_CHANGE_NS))]
5740 #[allow(non_camel_case_types)]
5741 struct QueueLastChangeNumTracks {
5742 #[xml(attribute)]
5743 val: Option<u32>,
5744 }
5745
5746 #[derive(FromXml)]
5747 #[xml(rename = "ObjectID", ns(LAST_CHANGE_NS))]
5748 #[allow(non_camel_case_types)]
5749 struct QueueLastChangeObjectID {
5750 #[xml(attribute)]
5751 val: Option<String>,
5752 }
5753
5754 #[derive(FromXml)]
5755 #[xml(rename = "QueueID", ns(LAST_CHANGE_NS))]
5756 #[allow(non_camel_case_types)]
5757 struct QueueLastChangeQueueID {
5758 #[xml(attribute)]
5759 val: Option<u32>,
5760 }
5761
5762 #[derive(FromXml)]
5763 #[xml(rename = "QueueOwnerContext", ns(LAST_CHANGE_NS))]
5764 #[allow(non_camel_case_types)]
5765 struct QueueLastChangeQueueOwnerContext {
5766 #[xml(attribute)]
5767 val: Option<String>,
5768 }
5769
5770 #[derive(FromXml)]
5771 #[xml(rename = "QueueOwnerID", ns(LAST_CHANGE_NS))]
5772 #[allow(non_camel_case_types)]
5773 struct QueueLastChangeQueueOwnerID {
5774 #[xml(attribute)]
5775 val: Option<String>,
5776 }
5777
5778 #[derive(FromXml)]
5779 #[xml(rename = "QueuePolicy", ns(LAST_CHANGE_NS))]
5780 #[allow(non_camel_case_types)]
5781 struct QueueLastChangeQueuePolicy {
5782 #[xml(attribute)]
5783 val: Option<String>,
5784 }
5785
5786 #[derive(FromXml)]
5787 #[xml(rename = "Result", ns(LAST_CHANGE_NS))]
5788 #[allow(non_camel_case_types)]
5789 struct QueueLastChangeResult {
5790 #[xml(attribute)]
5791 val: Option<String>,
5792 }
5793
5794 #[derive(FromXml)]
5795 #[xml(rename = "SavedQueueTitle", ns(LAST_CHANGE_NS))]
5796 #[allow(non_camel_case_types)]
5797 struct QueueLastChangeSavedQueueTitle {
5798 #[xml(attribute)]
5799 val: Option<String>,
5800 }
5801
5802 #[derive(FromXml)]
5803 #[xml(rename = "TrackNumber", ns(LAST_CHANGE_NS))]
5804 #[allow(non_camel_case_types)]
5805 struct QueueLastChangeTrackNumber {
5806 #[xml(attribute)]
5807 val: Option<u32>,
5808 }
5809
5810 #[derive(FromXml)]
5811 #[xml(rename = "TrackNumbersCSV", ns(LAST_CHANGE_NS))]
5812 #[allow(non_camel_case_types)]
5813 struct QueueLastChangeTrackNumbersCSV {
5814 #[xml(attribute)]
5815 val: Option<String>,
5816 }
5817
5818 #[derive(FromXml)]
5819 #[xml(rename = "URI", ns(LAST_CHANGE_NS))]
5820 #[allow(non_camel_case_types)]
5821 struct QueueLastChangeURI {
5822 #[xml(attribute)]
5823 val: Option<String>,
5824 }
5825
5826 #[derive(FromXml)]
5827 #[xml(rename = "URIMetaData", ns(LAST_CHANGE_NS))]
5828 #[allow(non_camel_case_types)]
5829 struct QueueLastChangeURIMetaData {
5830 #[xml(attribute)]
5831 val: Option<String>,
5832 }
5833
5834 #[derive(FromXml)]
5835 #[xml(rename = "UpdateID", ns(LAST_CHANGE_NS))]
5836 #[allow(non_camel_case_types)]
5837 struct QueueLastChangeUpdateID {
5838 #[xml(attribute)]
5839 val: Option<u32>,
5840 }
5841
5842 #[derive(FromXml)]
5843 #[xml(rename = "Curated", ns(LAST_CHANGE_NS))]
5844 #[allow(non_camel_case_types)]
5845 struct QueueLastChangeCurated {
5846 #[xml(attribute)]
5847 val: Option<bool>,
5848 }
5849
5850 const LAST_CHANGE_NS: &str = "urn:schemas-sonos-com:metadata-1-0/Queue/";
5851
5852 #[derive(FromXml)]
5853 #[xml(rename = "QueueID", ns(LAST_CHANGE_NS))]
5854 struct QueueLastChangeRootObject {
5855 #[xml(rename = "val", attribute)]
5856 object_instance_id_: u32,
5857
5858 count: Option<QueueLastChangeCount>,
5859 enqueue_as_next: Option<QueueLastChangeEnqueueAsNext>,
5860 index: Option<QueueLastChangeIndex>,
5861 list_uri: Option<QueueLastChangeLIST_URI>,
5862 list_uri_and_metadata: Option<QueueLastChangeLIST_URI_AND_METADATA>,
5863 num_tracks: Option<QueueLastChangeNumTracks>,
5864 object_id: Option<QueueLastChangeObjectID>,
5865 queue_id: Option<QueueLastChangeQueueID>,
5866 queue_owner_context: Option<QueueLastChangeQueueOwnerContext>,
5867 queue_owner_id: Option<QueueLastChangeQueueOwnerID>,
5868 queue_policy: Option<QueueLastChangeQueuePolicy>,
5869 result: Option<QueueLastChangeResult>,
5870 saved_queue_title: Option<QueueLastChangeSavedQueueTitle>,
5871 track_number: Option<QueueLastChangeTrackNumber>,
5872 track_numbers_csv: Option<QueueLastChangeTrackNumbersCSV>,
5873 uri: Option<QueueLastChangeURI>,
5874 uri_meta_data: Option<QueueLastChangeURIMetaData>,
5875 update_id: Option<QueueLastChangeUpdateID>,
5876 curated: Option<QueueLastChangeCurated>,
5877 }
5878
5879 #[derive(Debug, Clone, PartialEq, Default)]
5880 pub struct QueueLastChangeMap {
5881 pub map: std::collections::BTreeMap<u32, QueueLastChange>,
5882 }
5883
5884 impl DecodeXml for QueueLastChangeMap {
5885 fn decode_xml(xml: &str) -> crate::Result<Self> {
5886 #[derive(FromXml)]
5887 #[xml(ns(LAST_CHANGE_NS, r = "urn:schemas-rinconnetworks-com:metadata-1-0/"))]
5888 struct Event {
5889 instance: Vec<QueueLastChangeRootObject>,
5890 }
5891
5892 let last_change: Event = instant_xml::from_str(xml)?;
5893 let mut map = std::collections::BTreeMap::new();
5894
5895 for item in last_change.instance {
5896 let mut result = QueueLastChange::default();
5897
5898 result.count = item.count.and_then(|v| v.val);
5899
5900 result.enqueue_as_next = item.enqueue_as_next.and_then(|v| v.val);
5901
5902 result.index = item.index.and_then(|v| v.val);
5903
5904 result.list_uri = item.list_uri.and_then(|v| v.val);
5905
5906 result.list_uri_and_metadata = item.list_uri_and_metadata.and_then(|v| v.val);
5907
5908 result.num_tracks = item.num_tracks.and_then(|v| v.val);
5909
5910 result.object_id = item.object_id.and_then(|v| v.val);
5911
5912 result.queue_id = item.queue_id.and_then(|v| v.val);
5913
5914 result.queue_owner_context = item.queue_owner_context.and_then(|v| v.val);
5915
5916 result.queue_owner_id = item.queue_owner_id.and_then(|v| v.val);
5917
5918 result.queue_policy = item.queue_policy.and_then(|v| v.val);
5919
5920 result.result = item.result.and_then(|v| v.val);
5921
5922 result.saved_queue_title = item.saved_queue_title.and_then(|v| v.val);
5923
5924 result.track_number = item.track_number.and_then(|v| v.val);
5925
5926 result.track_numbers_csv = item.track_numbers_csv.and_then(|v| v.val);
5927
5928 result.uri = item.uri.and_then(|v| v.val);
5929
5930 result.uri_meta_data = item.uri_meta_data.and_then(|v| v.val);
5931
5932 result.update_id = item.update_id.and_then(|v| v.val);
5933
5934 result.curated = item.curated.and_then(|v| v.val);
5935
5936 map.insert(item.object_instance_id_, result);
5937 }
5938
5939 Ok(QueueLastChangeMap { map })
5940 }
5941 }
5942}
5943
5944pub mod rendering_control {
5946 use super::*;
5947
5948 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:RenderingControl:1";
5951
5952 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5953 #[xml(rename = "GetBass", ns(SERVICE_TYPE))]
5954 pub struct GetBassRequest {
5955 #[xml(rename = "InstanceID", ns(""))]
5956 pub instance_id: u32,
5957 }
5958
5959 #[derive(FromXml, Debug, Clone, PartialEq)]
5960 #[xml(rename = "GetBassResponse", ns(SERVICE_TYPE))]
5961 pub struct GetBassResponse {
5962 #[xml(rename = "CurrentBass", ns(""))]
5963 pub current_bass: Option<i16>,
5964 }
5965
5966 impl crate::DecodeSoapResponse for GetBassResponse {
5967 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5968 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5969 Ok(envelope.body.payload)
5970 }
5971 }
5972
5973 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5974 #[xml(rename = "GetEQ", ns(SERVICE_TYPE))]
5975 pub struct GetEqRequest {
5976 #[xml(rename = "InstanceID", ns(""))]
5977 pub instance_id: u32,
5978 #[xml(rename = "EQType", ns(""))]
5980 pub eq_type: String,
5981 }
5982
5983 #[derive(FromXml, Debug, Clone, PartialEq)]
5984 #[xml(rename = "GetEQResponse", ns(SERVICE_TYPE))]
5985 pub struct GetEqResponse {
5986 #[xml(rename = "CurrentValue", ns(""))]
5987 pub current_value: Option<i16>,
5988 }
5989
5990 impl crate::DecodeSoapResponse for GetEqResponse {
5991 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
5992 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
5993 Ok(envelope.body.payload)
5994 }
5995 }
5996
5997 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
5998 #[xml(rename = "GetHeadphoneConnected", ns(SERVICE_TYPE))]
5999 pub struct GetHeadphoneConnectedRequest {
6000 #[xml(rename = "InstanceID", ns(""))]
6001 pub instance_id: u32,
6002 }
6003
6004 #[derive(FromXml, Debug, Clone, PartialEq)]
6005 #[xml(rename = "GetHeadphoneConnectedResponse", ns(SERVICE_TYPE))]
6006 pub struct GetHeadphoneConnectedResponse {
6007 #[xml(rename = "CurrentHeadphoneConnected", ns(""))]
6008 pub current_headphone_connected: Option<bool>,
6009 }
6010
6011 impl crate::DecodeSoapResponse for GetHeadphoneConnectedResponse {
6012 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6013 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6014 Ok(envelope.body.payload)
6015 }
6016 }
6017
6018 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6019 #[xml(rename = "GetLoudness", ns(SERVICE_TYPE))]
6020 pub struct GetLoudnessRequest {
6021 #[xml(rename = "InstanceID", ns(""))]
6022 pub instance_id: u32,
6023 #[xml(rename = "Channel", ns(""))]
6024 pub channel: super::Channel,
6025 }
6026
6027 #[derive(FromXml, Debug, Clone, PartialEq)]
6028 #[xml(rename = "GetLoudnessResponse", ns(SERVICE_TYPE))]
6029 pub struct GetLoudnessResponse {
6030 #[xml(rename = "CurrentLoudness", ns(""))]
6031 pub current_loudness: Option<bool>,
6032 }
6033
6034 impl crate::DecodeSoapResponse for GetLoudnessResponse {
6035 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6036 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6037 Ok(envelope.body.payload)
6038 }
6039 }
6040
6041 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6042 #[xml(rename = "GetMute", ns(SERVICE_TYPE))]
6043 pub struct GetMuteRequest {
6044 #[xml(rename = "InstanceID", ns(""))]
6045 pub instance_id: u32,
6046 #[xml(rename = "Channel", ns(""))]
6047 pub channel: super::MuteChannel,
6048 }
6049
6050 #[derive(FromXml, Debug, Clone, PartialEq)]
6051 #[xml(rename = "GetMuteResponse", ns(SERVICE_TYPE))]
6052 pub struct GetMuteResponse {
6053 #[xml(rename = "CurrentMute", ns(""))]
6054 pub current_mute: Option<bool>,
6055 }
6056
6057 impl crate::DecodeSoapResponse for GetMuteResponse {
6058 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6059 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6060 Ok(envelope.body.payload)
6061 }
6062 }
6063
6064 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6065 #[xml(rename = "GetOutputFixed", ns(SERVICE_TYPE))]
6066 pub struct GetOutputFixedRequest {
6067 #[xml(rename = "InstanceID", ns(""))]
6068 pub instance_id: u32,
6069 }
6070
6071 #[derive(FromXml, Debug, Clone, PartialEq)]
6072 #[xml(rename = "GetOutputFixedResponse", ns(SERVICE_TYPE))]
6073 pub struct GetOutputFixedResponse {
6074 #[xml(rename = "CurrentFixed", ns(""))]
6075 pub current_fixed: Option<bool>,
6076 }
6077
6078 impl crate::DecodeSoapResponse for GetOutputFixedResponse {
6079 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6080 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6081 Ok(envelope.body.payload)
6082 }
6083 }
6084
6085 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6086 #[xml(rename = "GetRoomCalibrationStatus", ns(SERVICE_TYPE))]
6087 pub struct GetRoomCalibrationStatusRequest {
6088 #[xml(rename = "InstanceID", ns(""))]
6089 pub instance_id: u32,
6090 }
6091
6092 #[derive(FromXml, Debug, Clone, PartialEq)]
6093 #[xml(rename = "GetRoomCalibrationStatusResponse", ns(SERVICE_TYPE))]
6094 pub struct GetRoomCalibrationStatusResponse {
6095 #[xml(rename = "RoomCalibrationEnabled", ns(""))]
6096 pub room_calibration_enabled: Option<bool>,
6097 #[xml(rename = "RoomCalibrationAvailable", ns(""))]
6098 pub room_calibration_available: Option<bool>,
6099 }
6100
6101 impl crate::DecodeSoapResponse for GetRoomCalibrationStatusResponse {
6102 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6103 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6104 Ok(envelope.body.payload)
6105 }
6106 }
6107
6108 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6109 #[xml(rename = "GetSupportsOutputFixed", ns(SERVICE_TYPE))]
6110 pub struct GetSupportsOutputFixedRequest {
6111 #[xml(rename = "InstanceID", ns(""))]
6112 pub instance_id: u32,
6113 }
6114
6115 #[derive(FromXml, Debug, Clone, PartialEq)]
6116 #[xml(rename = "GetSupportsOutputFixedResponse", ns(SERVICE_TYPE))]
6117 pub struct GetSupportsOutputFixedResponse {
6118 #[xml(rename = "CurrentSupportsFixed", ns(""))]
6119 pub current_supports_fixed: Option<bool>,
6120 }
6121
6122 impl crate::DecodeSoapResponse for GetSupportsOutputFixedResponse {
6123 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6124 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6125 Ok(envelope.body.payload)
6126 }
6127 }
6128
6129 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6130 #[xml(rename = "GetTreble", ns(SERVICE_TYPE))]
6131 pub struct GetTrebleRequest {
6132 #[xml(rename = "InstanceID", ns(""))]
6133 pub instance_id: u32,
6134 }
6135
6136 #[derive(FromXml, Debug, Clone, PartialEq)]
6137 #[xml(rename = "GetTrebleResponse", ns(SERVICE_TYPE))]
6138 pub struct GetTrebleResponse {
6139 #[xml(rename = "CurrentTreble", ns(""))]
6140 pub current_treble: Option<i16>,
6141 }
6142
6143 impl crate::DecodeSoapResponse for GetTrebleResponse {
6144 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6145 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6146 Ok(envelope.body.payload)
6147 }
6148 }
6149
6150 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6151 #[xml(rename = "GetVolume", ns(SERVICE_TYPE))]
6152 pub struct GetVolumeRequest {
6153 #[xml(rename = "InstanceID", ns(""))]
6154 pub instance_id: u32,
6155 #[xml(rename = "Channel", ns(""))]
6156 pub channel: super::Channel,
6157 }
6158
6159 #[derive(FromXml, Debug, Clone, PartialEq)]
6160 #[xml(rename = "GetVolumeResponse", ns(SERVICE_TYPE))]
6161 pub struct GetVolumeResponse {
6162 #[xml(rename = "CurrentVolume", ns(""))]
6163 pub current_volume: Option<u16>,
6164 }
6165
6166 impl crate::DecodeSoapResponse for GetVolumeResponse {
6167 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6168 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6169 Ok(envelope.body.payload)
6170 }
6171 }
6172
6173 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6174 #[xml(rename = "GetVolumeDB", ns(SERVICE_TYPE))]
6175 pub struct GetVolumeDbRequest {
6176 #[xml(rename = "InstanceID", ns(""))]
6177 pub instance_id: u32,
6178 #[xml(rename = "Channel", ns(""))]
6179 pub channel: super::Channel,
6180 }
6181
6182 #[derive(FromXml, Debug, Clone, PartialEq)]
6183 #[xml(rename = "GetVolumeDBResponse", ns(SERVICE_TYPE))]
6184 pub struct GetVolumeDbResponse {
6185 #[xml(rename = "CurrentVolume", ns(""))]
6186 pub current_volume: Option<i16>,
6187 }
6188
6189 impl crate::DecodeSoapResponse for GetVolumeDbResponse {
6190 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6191 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6192 Ok(envelope.body.payload)
6193 }
6194 }
6195
6196 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6197 #[xml(rename = "GetVolumeDBRange", ns(SERVICE_TYPE))]
6198 pub struct GetVolumeDbRangeRequest {
6199 #[xml(rename = "InstanceID", ns(""))]
6200 pub instance_id: u32,
6201 #[xml(rename = "Channel", ns(""))]
6202 pub channel: super::Channel,
6203 }
6204
6205 #[derive(FromXml, Debug, Clone, PartialEq)]
6206 #[xml(rename = "GetVolumeDBRangeResponse", ns(SERVICE_TYPE))]
6207 pub struct GetVolumeDbRangeResponse {
6208 #[xml(rename = "MinValue", ns(""))]
6209 pub min_value: Option<i16>,
6210 #[xml(rename = "MaxValue", ns(""))]
6211 pub max_value: Option<i16>,
6212 }
6213
6214 impl crate::DecodeSoapResponse for GetVolumeDbRangeResponse {
6215 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6216 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6217 Ok(envelope.body.payload)
6218 }
6219 }
6220
6221 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6222 #[xml(rename = "RampToVolume", ns(SERVICE_TYPE))]
6223 pub struct RampToVolumeRequest {
6224 #[xml(rename = "InstanceID", ns(""))]
6225 pub instance_id: u32,
6226 #[xml(rename = "Channel", ns(""))]
6227 pub channel: super::Channel,
6228 #[xml(rename = "RampType", ns(""))]
6229 pub ramp_type: super::RampType,
6230 #[xml(rename = "DesiredVolume", ns(""))]
6231 pub desired_volume: u16,
6232 #[xml(rename = "ResetVolumeAfter", ns(""))]
6233 pub reset_volume_after: bool,
6234 #[xml(rename = "ProgramURI", ns(""))]
6235 pub program_uri: String,
6236 }
6237
6238 #[derive(FromXml, Debug, Clone, PartialEq)]
6239 #[xml(rename = "RampToVolumeResponse", ns(SERVICE_TYPE))]
6240 pub struct RampToVolumeResponse {
6241 #[xml(rename = "RampTime", ns(""))]
6242 pub ramp_time: Option<u32>,
6243 }
6244
6245 impl crate::DecodeSoapResponse for RampToVolumeResponse {
6246 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6247 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6248 Ok(envelope.body.payload)
6249 }
6250 }
6251
6252 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6253 #[xml(rename = "ResetBasicEQ", ns(SERVICE_TYPE))]
6254 pub struct ResetBasicEqRequest {
6255 #[xml(rename = "InstanceID", ns(""))]
6256 pub instance_id: u32,
6257 }
6258
6259 #[derive(FromXml, Debug, Clone, PartialEq)]
6260 #[xml(rename = "ResetBasicEQResponse", ns(SERVICE_TYPE))]
6261 pub struct ResetBasicEqResponse {
6262 #[xml(rename = "Bass", ns(""))]
6263 pub bass: Option<i16>,
6264 #[xml(rename = "Treble", ns(""))]
6265 pub treble: Option<i16>,
6266 #[xml(rename = "Loudness", ns(""))]
6267 pub loudness: Option<bool>,
6268 #[xml(rename = "LeftVolume", ns(""))]
6269 pub left_volume: Option<u16>,
6270 #[xml(rename = "RightVolume", ns(""))]
6271 pub right_volume: Option<u16>,
6272 }
6273
6274 impl crate::DecodeSoapResponse for ResetBasicEqResponse {
6275 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6276 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6277 Ok(envelope.body.payload)
6278 }
6279 }
6280
6281 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6282 #[xml(rename = "ResetExtEQ", ns(SERVICE_TYPE))]
6283 pub struct ResetExtEqRequest {
6284 #[xml(rename = "InstanceID", ns(""))]
6285 pub instance_id: u32,
6286 #[xml(rename = "EQType", ns(""))]
6287 pub eq_type: String,
6288 }
6289
6290 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6291 #[xml(rename = "RestoreVolumePriorToRamp", ns(SERVICE_TYPE))]
6292 pub struct RestoreVolumePriorToRampRequest {
6293 #[xml(rename = "InstanceID", ns(""))]
6294 pub instance_id: u32,
6295 #[xml(rename = "Channel", ns(""))]
6296 pub channel: super::Channel,
6297 }
6298
6299 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6300 #[xml(rename = "SetBass", ns(SERVICE_TYPE))]
6301 pub struct SetBassRequest {
6302 #[xml(rename = "InstanceID", ns(""))]
6303 pub instance_id: u32,
6304 #[xml(rename = "DesiredBass", ns(""))]
6305 pub desired_bass: i16,
6306 }
6307
6308 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6309 #[xml(rename = "SetChannelMap", ns(SERVICE_TYPE))]
6310 pub struct SetChannelMapRequest {
6311 #[xml(rename = "InstanceID", ns(""))]
6312 pub instance_id: u32,
6313 #[xml(rename = "ChannelMap", ns(""))]
6314 pub channel_map: String,
6315 }
6316
6317 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6318 #[xml(rename = "SetEQ", ns(SERVICE_TYPE))]
6319 pub struct SetEqRequest {
6320 #[xml(rename = "InstanceID", ns(""))]
6321 pub instance_id: u32,
6322 #[xml(rename = "EQType", ns(""))]
6324 pub eq_type: String,
6325 #[xml(rename = "DesiredValue", ns(""))]
6327 pub desired_value: i16,
6328 }
6329
6330 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6331 #[xml(rename = "SetLoudness", ns(SERVICE_TYPE))]
6332 pub struct SetLoudnessRequest {
6333 #[xml(rename = "InstanceID", ns(""))]
6334 pub instance_id: u32,
6335 #[xml(rename = "Channel", ns(""))]
6336 pub channel: super::Channel,
6337 #[xml(rename = "DesiredLoudness", ns(""))]
6338 pub desired_loudness: bool,
6339 }
6340
6341 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6342 #[xml(rename = "SetMute", ns(SERVICE_TYPE))]
6343 pub struct SetMuteRequest {
6344 #[xml(rename = "InstanceID", ns(""))]
6345 pub instance_id: u32,
6346 #[xml(rename = "Channel", ns(""))]
6347 pub channel: super::MuteChannel,
6348 #[xml(rename = "DesiredMute", ns(""))]
6349 pub desired_mute: bool,
6350 }
6351
6352 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6353 #[xml(rename = "SetOutputFixed", ns(SERVICE_TYPE))]
6354 pub struct SetOutputFixedRequest {
6355 #[xml(rename = "InstanceID", ns(""))]
6356 pub instance_id: u32,
6357 #[xml(rename = "DesiredFixed", ns(""))]
6358 pub desired_fixed: bool,
6359 }
6360
6361 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6362 #[xml(rename = "SetRelativeVolume", ns(SERVICE_TYPE))]
6363 pub struct SetRelativeVolumeRequest {
6364 #[xml(rename = "InstanceID", ns(""))]
6365 pub instance_id: u32,
6366 #[xml(rename = "Channel", ns(""))]
6367 pub channel: super::Channel,
6368 #[xml(rename = "Adjustment", ns(""))]
6369 pub adjustment: i32,
6370 }
6371
6372 #[derive(FromXml, Debug, Clone, PartialEq)]
6373 #[xml(rename = "SetRelativeVolumeResponse", ns(SERVICE_TYPE))]
6374 pub struct SetRelativeVolumeResponse {
6375 #[xml(rename = "NewVolume", ns(""))]
6376 pub new_volume: Option<u16>,
6377 }
6378
6379 impl crate::DecodeSoapResponse for SetRelativeVolumeResponse {
6380 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
6381 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
6382 Ok(envelope.body.payload)
6383 }
6384 }
6385
6386 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6387 #[xml(rename = "SetRoomCalibrationStatus", ns(SERVICE_TYPE))]
6388 pub struct SetRoomCalibrationStatusRequest {
6389 #[xml(rename = "InstanceID", ns(""))]
6390 pub instance_id: u32,
6391 #[xml(rename = "RoomCalibrationEnabled", ns(""))]
6392 pub room_calibration_enabled: bool,
6393 }
6394
6395 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6396 #[xml(rename = "SetRoomCalibrationX", ns(SERVICE_TYPE))]
6397 pub struct SetRoomCalibrationXRequest {
6398 #[xml(rename = "InstanceID", ns(""))]
6399 pub instance_id: u32,
6400 #[xml(rename = "CalibrationID", ns(""))]
6401 pub calibration_id: String,
6402 #[xml(rename = "Coefficients", ns(""))]
6403 pub coefficients: String,
6404 #[xml(rename = "CalibrationMode", ns(""))]
6405 pub calibration_mode: String,
6406 }
6407
6408 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6409 #[xml(rename = "SetTreble", ns(SERVICE_TYPE))]
6410 pub struct SetTrebleRequest {
6411 #[xml(rename = "InstanceID", ns(""))]
6412 pub instance_id: u32,
6413 #[xml(rename = "DesiredTreble", ns(""))]
6415 pub desired_treble: i16,
6416 }
6417
6418 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6419 #[xml(rename = "SetVolume", ns(SERVICE_TYPE))]
6420 pub struct SetVolumeRequest {
6421 #[xml(rename = "InstanceID", ns(""))]
6422 pub instance_id: u32,
6423 #[xml(rename = "Channel", ns(""))]
6424 pub channel: super::Channel,
6425 #[xml(rename = "DesiredVolume", ns(""))]
6426 pub desired_volume: u16,
6427 }
6428
6429 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
6430 #[xml(rename = "SetVolumeDB", ns(SERVICE_TYPE))]
6431 pub struct SetVolumeDbRequest {
6432 #[xml(rename = "InstanceID", ns(""))]
6433 pub instance_id: u32,
6434 #[xml(rename = "Channel", ns(""))]
6435 pub channel: super::Channel,
6436 #[xml(rename = "DesiredVolume", ns(""))]
6437 pub desired_volume: i16,
6438 }
6439
6440 #[derive(Debug, Clone, PartialEq, Default)]
6444 pub struct RenderingControlEvent {
6445 pub last_change: Option<DecodeXmlString<RenderingControlLastChangeMap>>,
6446 }
6447
6448 #[derive(FromXml, Debug, Clone, PartialEq)]
6449 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
6450 struct RenderingControlPropertySet {
6451 pub properties: Vec<RenderingControlProperty>,
6452 }
6453
6454 #[derive(FromXml, Debug, Clone, PartialEq)]
6455 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
6456 struct RenderingControlProperty {
6457 #[xml(rename = "LastChange", ns(""))]
6458 pub last_change: Option<DecodeXmlString<RenderingControlLastChangeMap>>,
6459 }
6460
6461 impl DecodeXml for RenderingControlEvent {
6462 fn decode_xml(xml: &str) -> crate::Result<Self> {
6463 let mut result = Self::default();
6464 let set: RenderingControlPropertySet = instant_xml::from_str(xml)?;
6465 for prop in set.properties {
6466 if let Some(v) = prop.last_change {
6467 result.last_change.replace(v);
6468 }
6469 }
6470 Ok(result)
6471 }
6472 }
6473
6474 impl crate::SonosDevice {
6475 pub async fn subscribe_rendering_control(
6477 &self,
6478 ) -> crate::Result<crate::upnp::EventStream<RenderingControlEvent>> {
6479 self.subscribe_helper(&SERVICE_TYPE).await
6480 }
6481 }
6482
6483 #[derive(Debug, Clone, PartialEq, Default)]
6484 pub struct RenderingControlLastChange {
6485 pub channel: Option<super::Channel>,
6486 pub channel_map: Option<String>,
6487 pub eq_type: Option<String>,
6488 pub instance_id: Option<u32>,
6489 pub left_volume: Option<u16>,
6490 pub mute_channel: Option<super::MuteChannel>,
6491 pub program_uri: Option<String>,
6492 pub ramp_time_seconds: Option<u32>,
6493 pub ramp_type: Option<super::RampType>,
6494 pub reset_volume_after: Option<bool>,
6495 pub right_volume: Option<u16>,
6496 pub volume_adjustment: Option<i32>,
6497 pub audio_delay: Option<String>,
6498 pub audio_delay_left_rear: Option<String>,
6499 pub audio_delay_right_rear: Option<String>,
6500 pub bass: Option<i16>,
6501 pub dialog_level: Option<String>,
6502 pub eq_value: Option<i16>,
6503 pub headphone_connected: Option<bool>,
6504 pub loudness: Option<bool>,
6505 pub music_surround_level: Option<String>,
6506 pub mute: Option<bool>,
6507 pub night_mode: Option<bool>,
6508 pub output_fixed: Option<bool>,
6509 pub preset_name_list: Option<String>,
6510 pub room_calibration_available: Option<bool>,
6511 pub room_calibration_calibration_mode: Option<String>,
6512 pub room_calibration_coefficients: Option<String>,
6513 pub room_calibration_enabled: Option<bool>,
6514 pub room_calibration_id: Option<String>,
6515 pub speaker_size: Option<u32>,
6516 pub sub_crossover: Option<String>,
6517 pub sub_enabled: Option<bool>,
6518 pub sub_gain: Option<String>,
6519 pub sub_polarity: Option<String>,
6520 pub supports_output_fixed: Option<bool>,
6521 pub surround_enabled: Option<bool>,
6522 pub surround_level: Option<String>,
6523 pub surround_mode: Option<String>,
6524 pub treble: Option<i16>,
6525 pub volume: Option<u16>,
6526 pub volume_db: Option<i16>,
6527 }
6528
6529 #[derive(FromXml)]
6530 #[xml(rename = "Channel", ns(LAST_CHANGE_NS))]
6531 #[allow(non_camel_case_types)]
6532 struct RenderingControlLastChangeChannel {
6533 #[xml(attribute)]
6534 val: Option<super::Channel>,
6535 }
6536
6537 #[derive(FromXml)]
6538 #[xml(rename = "ChannelMap", ns(LAST_CHANGE_NS))]
6539 #[allow(non_camel_case_types)]
6540 struct RenderingControlLastChangeChannelMap {
6541 #[xml(attribute)]
6542 val: Option<String>,
6543 }
6544
6545 #[derive(FromXml)]
6546 #[xml(rename = "EQType", ns(LAST_CHANGE_NS))]
6547 #[allow(non_camel_case_types)]
6548 struct RenderingControlLastChangeEQType {
6549 #[xml(attribute)]
6550 val: Option<String>,
6551 }
6552
6553 #[derive(FromXml)]
6554 #[xml(rename = "InstanceID", ns(LAST_CHANGE_NS))]
6555 #[allow(non_camel_case_types)]
6556 struct RenderingControlLastChangeInstanceID {
6557 #[xml(attribute)]
6558 val: Option<u32>,
6559 }
6560
6561 #[derive(FromXml)]
6562 #[xml(rename = "LeftVolume", ns(LAST_CHANGE_NS))]
6563 #[allow(non_camel_case_types)]
6564 struct RenderingControlLastChangeLeftVolume {
6565 #[xml(attribute)]
6566 val: Option<u16>,
6567 }
6568
6569 #[derive(FromXml)]
6570 #[xml(rename = "MuteChannel", ns(LAST_CHANGE_NS))]
6571 #[allow(non_camel_case_types)]
6572 struct RenderingControlLastChangeMuteChannel {
6573 #[xml(attribute)]
6574 val: Option<super::MuteChannel>,
6575 }
6576
6577 #[derive(FromXml)]
6578 #[xml(rename = "ProgramURI", ns(LAST_CHANGE_NS))]
6579 #[allow(non_camel_case_types)]
6580 struct RenderingControlLastChangeProgramURI {
6581 #[xml(attribute)]
6582 val: Option<String>,
6583 }
6584
6585 #[derive(FromXml)]
6586 #[xml(rename = "RampTimeSeconds", ns(LAST_CHANGE_NS))]
6587 #[allow(non_camel_case_types)]
6588 struct RenderingControlLastChangeRampTimeSeconds {
6589 #[xml(attribute)]
6590 val: Option<u32>,
6591 }
6592
6593 #[derive(FromXml)]
6594 #[xml(rename = "RampType", ns(LAST_CHANGE_NS))]
6595 #[allow(non_camel_case_types)]
6596 struct RenderingControlLastChangeRampType {
6597 #[xml(attribute)]
6598 val: Option<super::RampType>,
6599 }
6600
6601 #[derive(FromXml)]
6602 #[xml(rename = "ResetVolumeAfter", ns(LAST_CHANGE_NS))]
6603 #[allow(non_camel_case_types)]
6604 struct RenderingControlLastChangeResetVolumeAfter {
6605 #[xml(attribute)]
6606 val: Option<bool>,
6607 }
6608
6609 #[derive(FromXml)]
6610 #[xml(rename = "RightVolume", ns(LAST_CHANGE_NS))]
6611 #[allow(non_camel_case_types)]
6612 struct RenderingControlLastChangeRightVolume {
6613 #[xml(attribute)]
6614 val: Option<u16>,
6615 }
6616
6617 #[derive(FromXml)]
6618 #[xml(rename = "VolumeAdjustment", ns(LAST_CHANGE_NS))]
6619 #[allow(non_camel_case_types)]
6620 struct RenderingControlLastChangeVolumeAdjustment {
6621 #[xml(attribute)]
6622 val: Option<i32>,
6623 }
6624
6625 #[derive(FromXml)]
6626 #[xml(rename = "AudioDelay", ns(LAST_CHANGE_NS))]
6627 #[allow(non_camel_case_types)]
6628 struct RenderingControlLastChangeAudioDelay {
6629 #[xml(attribute)]
6630 val: Option<String>,
6631 }
6632
6633 #[derive(FromXml)]
6634 #[xml(rename = "AudioDelayLeftRear", ns(LAST_CHANGE_NS))]
6635 #[allow(non_camel_case_types)]
6636 struct RenderingControlLastChangeAudioDelayLeftRear {
6637 #[xml(attribute)]
6638 val: Option<String>,
6639 }
6640
6641 #[derive(FromXml)]
6642 #[xml(rename = "AudioDelayRightRear", ns(LAST_CHANGE_NS))]
6643 #[allow(non_camel_case_types)]
6644 struct RenderingControlLastChangeAudioDelayRightRear {
6645 #[xml(attribute)]
6646 val: Option<String>,
6647 }
6648
6649 #[derive(FromXml)]
6650 #[xml(rename = "Bass", ns(LAST_CHANGE_NS))]
6651 #[allow(non_camel_case_types)]
6652 struct RenderingControlLastChangeBass {
6653 #[xml(attribute)]
6654 val: Option<i16>,
6655 }
6656
6657 #[derive(FromXml)]
6658 #[xml(rename = "DialogLevel", ns(LAST_CHANGE_NS))]
6659 #[allow(non_camel_case_types)]
6660 struct RenderingControlLastChangeDialogLevel {
6661 #[xml(attribute)]
6662 val: Option<String>,
6663 }
6664
6665 #[derive(FromXml)]
6666 #[xml(rename = "EQValue", ns(LAST_CHANGE_NS))]
6667 #[allow(non_camel_case_types)]
6668 struct RenderingControlLastChangeEQValue {
6669 #[xml(attribute)]
6670 val: Option<i16>,
6671 }
6672
6673 #[derive(FromXml)]
6674 #[xml(rename = "HeadphoneConnected", ns(LAST_CHANGE_NS))]
6675 #[allow(non_camel_case_types)]
6676 struct RenderingControlLastChangeHeadphoneConnected {
6677 #[xml(attribute)]
6678 val: Option<bool>,
6679 }
6680
6681 #[derive(FromXml)]
6682 #[xml(rename = "Loudness", ns(LAST_CHANGE_NS))]
6683 #[allow(non_camel_case_types)]
6684 struct RenderingControlLastChangeLoudness {
6685 #[xml(attribute)]
6686 val: Option<bool>,
6687 }
6688
6689 #[derive(FromXml)]
6690 #[xml(rename = "MusicSurroundLevel", ns(LAST_CHANGE_NS))]
6691 #[allow(non_camel_case_types)]
6692 struct RenderingControlLastChangeMusicSurroundLevel {
6693 #[xml(attribute)]
6694 val: Option<String>,
6695 }
6696
6697 #[derive(FromXml)]
6698 #[xml(rename = "Mute", ns(LAST_CHANGE_NS))]
6699 #[allow(non_camel_case_types)]
6700 struct RenderingControlLastChangeMute {
6701 #[xml(attribute)]
6702 val: Option<bool>,
6703 }
6704
6705 #[derive(FromXml)]
6706 #[xml(rename = "NightMode", ns(LAST_CHANGE_NS))]
6707 #[allow(non_camel_case_types)]
6708 struct RenderingControlLastChangeNightMode {
6709 #[xml(attribute)]
6710 val: Option<bool>,
6711 }
6712
6713 #[derive(FromXml)]
6714 #[xml(rename = "OutputFixed", ns(LAST_CHANGE_NS))]
6715 #[allow(non_camel_case_types)]
6716 struct RenderingControlLastChangeOutputFixed {
6717 #[xml(attribute)]
6718 val: Option<bool>,
6719 }
6720
6721 #[derive(FromXml)]
6722 #[xml(rename = "PresetNameList", ns(LAST_CHANGE_NS))]
6723 #[allow(non_camel_case_types)]
6724 struct RenderingControlLastChangePresetNameList {
6725 #[xml(attribute)]
6726 val: Option<String>,
6727 }
6728
6729 #[derive(FromXml)]
6730 #[xml(rename = "RoomCalibrationAvailable", ns(LAST_CHANGE_NS))]
6731 #[allow(non_camel_case_types)]
6732 struct RenderingControlLastChangeRoomCalibrationAvailable {
6733 #[xml(attribute)]
6734 val: Option<bool>,
6735 }
6736
6737 #[derive(FromXml)]
6738 #[xml(rename = "RoomCalibrationCalibrationMode", ns(LAST_CHANGE_NS))]
6739 #[allow(non_camel_case_types)]
6740 struct RenderingControlLastChangeRoomCalibrationCalibrationMode {
6741 #[xml(attribute)]
6742 val: Option<String>,
6743 }
6744
6745 #[derive(FromXml)]
6746 #[xml(rename = "RoomCalibrationCoefficients", ns(LAST_CHANGE_NS))]
6747 #[allow(non_camel_case_types)]
6748 struct RenderingControlLastChangeRoomCalibrationCoefficients {
6749 #[xml(attribute)]
6750 val: Option<String>,
6751 }
6752
6753 #[derive(FromXml)]
6754 #[xml(rename = "RoomCalibrationEnabled", ns(LAST_CHANGE_NS))]
6755 #[allow(non_camel_case_types)]
6756 struct RenderingControlLastChangeRoomCalibrationEnabled {
6757 #[xml(attribute)]
6758 val: Option<bool>,
6759 }
6760
6761 #[derive(FromXml)]
6762 #[xml(rename = "RoomCalibrationID", ns(LAST_CHANGE_NS))]
6763 #[allow(non_camel_case_types)]
6764 struct RenderingControlLastChangeRoomCalibrationID {
6765 #[xml(attribute)]
6766 val: Option<String>,
6767 }
6768
6769 #[derive(FromXml)]
6770 #[xml(rename = "SpeakerSize", ns(LAST_CHANGE_NS))]
6771 #[allow(non_camel_case_types)]
6772 struct RenderingControlLastChangeSpeakerSize {
6773 #[xml(attribute)]
6774 val: Option<u32>,
6775 }
6776
6777 #[derive(FromXml)]
6778 #[xml(rename = "SubCrossover", ns(LAST_CHANGE_NS))]
6779 #[allow(non_camel_case_types)]
6780 struct RenderingControlLastChangeSubCrossover {
6781 #[xml(attribute)]
6782 val: Option<String>,
6783 }
6784
6785 #[derive(FromXml)]
6786 #[xml(rename = "SubEnabled", ns(LAST_CHANGE_NS))]
6787 #[allow(non_camel_case_types)]
6788 struct RenderingControlLastChangeSubEnabled {
6789 #[xml(attribute)]
6790 val: Option<bool>,
6791 }
6792
6793 #[derive(FromXml)]
6794 #[xml(rename = "SubGain", ns(LAST_CHANGE_NS))]
6795 #[allow(non_camel_case_types)]
6796 struct RenderingControlLastChangeSubGain {
6797 #[xml(attribute)]
6798 val: Option<String>,
6799 }
6800
6801 #[derive(FromXml)]
6802 #[xml(rename = "SubPolarity", ns(LAST_CHANGE_NS))]
6803 #[allow(non_camel_case_types)]
6804 struct RenderingControlLastChangeSubPolarity {
6805 #[xml(attribute)]
6806 val: Option<String>,
6807 }
6808
6809 #[derive(FromXml)]
6810 #[xml(rename = "SupportsOutputFixed", ns(LAST_CHANGE_NS))]
6811 #[allow(non_camel_case_types)]
6812 struct RenderingControlLastChangeSupportsOutputFixed {
6813 #[xml(attribute)]
6814 val: Option<bool>,
6815 }
6816
6817 #[derive(FromXml)]
6818 #[xml(rename = "SurroundEnabled", ns(LAST_CHANGE_NS))]
6819 #[allow(non_camel_case_types)]
6820 struct RenderingControlLastChangeSurroundEnabled {
6821 #[xml(attribute)]
6822 val: Option<bool>,
6823 }
6824
6825 #[derive(FromXml)]
6826 #[xml(rename = "SurroundLevel", ns(LAST_CHANGE_NS))]
6827 #[allow(non_camel_case_types)]
6828 struct RenderingControlLastChangeSurroundLevel {
6829 #[xml(attribute)]
6830 val: Option<String>,
6831 }
6832
6833 #[derive(FromXml)]
6834 #[xml(rename = "SurroundMode", ns(LAST_CHANGE_NS))]
6835 #[allow(non_camel_case_types)]
6836 struct RenderingControlLastChangeSurroundMode {
6837 #[xml(attribute)]
6838 val: Option<String>,
6839 }
6840
6841 #[derive(FromXml)]
6842 #[xml(rename = "Treble", ns(LAST_CHANGE_NS))]
6843 #[allow(non_camel_case_types)]
6844 struct RenderingControlLastChangeTreble {
6845 #[xml(attribute)]
6846 val: Option<i16>,
6847 }
6848
6849 #[derive(FromXml)]
6850 #[xml(rename = "Volume", ns(LAST_CHANGE_NS))]
6851 #[allow(non_camel_case_types)]
6852 struct RenderingControlLastChangeVolume {
6853 #[xml(attribute)]
6854 val: Option<u16>,
6855 }
6856
6857 #[derive(FromXml)]
6858 #[xml(rename = "VolumeDB", ns(LAST_CHANGE_NS))]
6859 #[allow(non_camel_case_types)]
6860 struct RenderingControlLastChangeVolumeDB {
6861 #[xml(attribute)]
6862 val: Option<i16>,
6863 }
6864
6865 const LAST_CHANGE_NS: &str = "urn:schemas-upnp-org:metadata-1-0/RCS/";
6866
6867 #[derive(FromXml)]
6868 #[xml(rename = "InstanceID", ns(LAST_CHANGE_NS))]
6869 struct RenderingControlLastChangeRootObject {
6870 #[xml(rename = "val", attribute)]
6871 object_instance_id_: u32,
6872
6873 channel: Option<RenderingControlLastChangeChannel>,
6874 channel_map: Option<RenderingControlLastChangeChannelMap>,
6875 eq_type: Option<RenderingControlLastChangeEQType>,
6876 instance_id: Option<RenderingControlLastChangeInstanceID>,
6877 left_volume: Option<RenderingControlLastChangeLeftVolume>,
6878 mute_channel: Option<RenderingControlLastChangeMuteChannel>,
6879 program_uri: Option<RenderingControlLastChangeProgramURI>,
6880 ramp_time_seconds: Option<RenderingControlLastChangeRampTimeSeconds>,
6881 ramp_type: Option<RenderingControlLastChangeRampType>,
6882 reset_volume_after: Option<RenderingControlLastChangeResetVolumeAfter>,
6883 right_volume: Option<RenderingControlLastChangeRightVolume>,
6884 volume_adjustment: Option<RenderingControlLastChangeVolumeAdjustment>,
6885 audio_delay: Option<RenderingControlLastChangeAudioDelay>,
6886 audio_delay_left_rear: Option<RenderingControlLastChangeAudioDelayLeftRear>,
6887 audio_delay_right_rear: Option<RenderingControlLastChangeAudioDelayRightRear>,
6888 bass: Option<RenderingControlLastChangeBass>,
6889 dialog_level: Option<RenderingControlLastChangeDialogLevel>,
6890 eq_value: Option<RenderingControlLastChangeEQValue>,
6891 headphone_connected: Option<RenderingControlLastChangeHeadphoneConnected>,
6892 loudness: Option<RenderingControlLastChangeLoudness>,
6893 music_surround_level: Option<RenderingControlLastChangeMusicSurroundLevel>,
6894 mute: Option<RenderingControlLastChangeMute>,
6895 night_mode: Option<RenderingControlLastChangeNightMode>,
6896 output_fixed: Option<RenderingControlLastChangeOutputFixed>,
6897 preset_name_list: Option<RenderingControlLastChangePresetNameList>,
6898 room_calibration_available: Option<RenderingControlLastChangeRoomCalibrationAvailable>,
6899 room_calibration_calibration_mode:
6900 Option<RenderingControlLastChangeRoomCalibrationCalibrationMode>,
6901 room_calibration_coefficients:
6902 Option<RenderingControlLastChangeRoomCalibrationCoefficients>,
6903 room_calibration_enabled: Option<RenderingControlLastChangeRoomCalibrationEnabled>,
6904 room_calibration_id: Option<RenderingControlLastChangeRoomCalibrationID>,
6905 speaker_size: Option<RenderingControlLastChangeSpeakerSize>,
6906 sub_crossover: Option<RenderingControlLastChangeSubCrossover>,
6907 sub_enabled: Option<RenderingControlLastChangeSubEnabled>,
6908 sub_gain: Option<RenderingControlLastChangeSubGain>,
6909 sub_polarity: Option<RenderingControlLastChangeSubPolarity>,
6910 supports_output_fixed: Option<RenderingControlLastChangeSupportsOutputFixed>,
6911 surround_enabled: Option<RenderingControlLastChangeSurroundEnabled>,
6912 surround_level: Option<RenderingControlLastChangeSurroundLevel>,
6913 surround_mode: Option<RenderingControlLastChangeSurroundMode>,
6914 treble: Option<RenderingControlLastChangeTreble>,
6915 volume: Option<RenderingControlLastChangeVolume>,
6916 volume_db: Option<RenderingControlLastChangeVolumeDB>,
6917 }
6918
6919 #[derive(Debug, Clone, PartialEq, Default)]
6920 pub struct RenderingControlLastChangeMap {
6921 pub map: std::collections::BTreeMap<u32, RenderingControlLastChange>,
6922 }
6923
6924 impl DecodeXml for RenderingControlLastChangeMap {
6925 fn decode_xml(xml: &str) -> crate::Result<Self> {
6926 #[derive(FromXml)]
6927 #[xml(ns(LAST_CHANGE_NS, r = "urn:schemas-rinconnetworks-com:metadata-1-0/"))]
6928 struct Event {
6929 instance: Vec<RenderingControlLastChangeRootObject>,
6930 }
6931
6932 let last_change: Event = instant_xml::from_str(xml)?;
6933 let mut map = std::collections::BTreeMap::new();
6934
6935 for item in last_change.instance {
6936 let mut result = RenderingControlLastChange::default();
6937
6938 result.channel = item.channel.and_then(|v| v.val);
6939
6940 result.channel_map = item.channel_map.and_then(|v| v.val);
6941
6942 result.eq_type = item.eq_type.and_then(|v| v.val);
6943
6944 result.instance_id = item.instance_id.and_then(|v| v.val);
6945
6946 result.left_volume = item.left_volume.and_then(|v| v.val);
6947
6948 result.mute_channel = item.mute_channel.and_then(|v| v.val);
6949
6950 result.program_uri = item.program_uri.and_then(|v| v.val);
6951
6952 result.ramp_time_seconds = item.ramp_time_seconds.and_then(|v| v.val);
6953
6954 result.ramp_type = item.ramp_type.and_then(|v| v.val);
6955
6956 result.reset_volume_after = item.reset_volume_after.and_then(|v| v.val);
6957
6958 result.right_volume = item.right_volume.and_then(|v| v.val);
6959
6960 result.volume_adjustment = item.volume_adjustment.and_then(|v| v.val);
6961
6962 result.audio_delay = item.audio_delay.and_then(|v| v.val);
6963
6964 result.audio_delay_left_rear = item.audio_delay_left_rear.and_then(|v| v.val);
6965
6966 result.audio_delay_right_rear = item.audio_delay_right_rear.and_then(|v| v.val);
6967
6968 result.bass = item.bass.and_then(|v| v.val);
6969
6970 result.dialog_level = item.dialog_level.and_then(|v| v.val);
6971
6972 result.eq_value = item.eq_value.and_then(|v| v.val);
6973
6974 result.headphone_connected = item.headphone_connected.and_then(|v| v.val);
6975
6976 result.loudness = item.loudness.and_then(|v| v.val);
6977
6978 result.music_surround_level = item.music_surround_level.and_then(|v| v.val);
6979
6980 result.mute = item.mute.and_then(|v| v.val);
6981
6982 result.night_mode = item.night_mode.and_then(|v| v.val);
6983
6984 result.output_fixed = item.output_fixed.and_then(|v| v.val);
6985
6986 result.preset_name_list = item.preset_name_list.and_then(|v| v.val);
6987
6988 result.room_calibration_available =
6989 item.room_calibration_available.and_then(|v| v.val);
6990
6991 result.room_calibration_calibration_mode =
6992 item.room_calibration_calibration_mode.and_then(|v| v.val);
6993
6994 result.room_calibration_coefficients =
6995 item.room_calibration_coefficients.and_then(|v| v.val);
6996
6997 result.room_calibration_enabled = item.room_calibration_enabled.and_then(|v| v.val);
6998
6999 result.room_calibration_id = item.room_calibration_id.and_then(|v| v.val);
7000
7001 result.speaker_size = item.speaker_size.and_then(|v| v.val);
7002
7003 result.sub_crossover = item.sub_crossover.and_then(|v| v.val);
7004
7005 result.sub_enabled = item.sub_enabled.and_then(|v| v.val);
7006
7007 result.sub_gain = item.sub_gain.and_then(|v| v.val);
7008
7009 result.sub_polarity = item.sub_polarity.and_then(|v| v.val);
7010
7011 result.supports_output_fixed = item.supports_output_fixed.and_then(|v| v.val);
7012
7013 result.surround_enabled = item.surround_enabled.and_then(|v| v.val);
7014
7015 result.surround_level = item.surround_level.and_then(|v| v.val);
7016
7017 result.surround_mode = item.surround_mode.and_then(|v| v.val);
7018
7019 result.treble = item.treble.and_then(|v| v.val);
7020
7021 result.volume = item.volume.and_then(|v| v.val);
7022
7023 result.volume_db = item.volume_db.and_then(|v| v.val);
7024
7025 map.insert(item.object_instance_id_, result);
7026 }
7027
7028 Ok(RenderingControlLastChangeMap { map })
7029 }
7030 }
7031}
7032
7033#[derive(PartialEq, Debug, Clone, Eq, Default)]
7034pub enum Channel {
7035 #[default]
7036 Master,
7037 Lf,
7038 Rf,
7039
7040 Unspecified(String),
7044}
7045
7046impl ToString for Channel {
7047 fn to_string(&self) -> String {
7048 match self {
7049 Channel::Master => "Master".to_string(),
7050 Channel::Lf => "LF".to_string(),
7051 Channel::Rf => "RF".to_string(),
7052 Channel::Unspecified(s) => s.to_string(),
7053 }
7054 }
7055}
7056
7057impl FromStr for Channel {
7058 type Err = crate::Error;
7059 fn from_str(s: &str) -> Result<Channel> {
7060 match s {
7061 "Master" => Ok(Channel::Master),
7062 "LF" => Ok(Channel::Lf),
7063 "RF" => Ok(Channel::Rf),
7064 s => Ok(Channel::Unspecified(s.to_string())),
7065 }
7066 }
7067}
7068
7069impl instant_xml::ToXml for Channel {
7070 fn serialize<W: std::fmt::Write + ?Sized>(
7071 &self,
7072 field: Option<instant_xml::Id<'_>>,
7073 serializer: &mut instant_xml::Serializer<W>,
7074 ) -> std::result::Result<(), instant_xml::Error> {
7075 self.to_string().serialize(field, serializer)
7076 }
7077
7078 fn present(&self) -> bool {
7079 true
7080 }
7081}
7082
7083impl<'xml> instant_xml::FromXml<'xml> for Channel {
7084 #[inline]
7085 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
7086 match field {
7087 Some(field) => id == field,
7088 None => false,
7089 }
7090 }
7091
7092 fn deserialize<'cx>(
7093 into: &mut Self::Accumulator,
7094 field: &'static str,
7095 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
7096 ) -> std::result::Result<(), instant_xml::Error> {
7097 if into.is_some() {
7098 return Err(instant_xml::Error::DuplicateValue(field));
7099 }
7100
7101 match deserializer.take_str()? {
7102 Some(value) => {
7103 let parsed: Channel = value.parse().map_err(|err| {
7104 instant_xml::Error::Other(format!(
7105 "invalid value for field {field}: {value}: {err:#}"
7106 ))
7107 })?;
7108 *into = Some(parsed);
7109 Ok(())
7110 }
7111 None => Err(instant_xml::Error::MissingValue(field)),
7112 }
7113 }
7114
7115 type Accumulator = Option<Channel>;
7116 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
7117}
7118
7119#[derive(PartialEq, Debug, Clone, Eq, Default)]
7120pub enum MuteChannel {
7121 #[default]
7122 Master,
7123 Lf,
7124 Rf,
7125 SpeakerOnly,
7126
7127 Unspecified(String),
7131}
7132
7133impl ToString for MuteChannel {
7134 fn to_string(&self) -> String {
7135 match self {
7136 MuteChannel::Master => "Master".to_string(),
7137 MuteChannel::Lf => "LF".to_string(),
7138 MuteChannel::Rf => "RF".to_string(),
7139 MuteChannel::SpeakerOnly => "SpeakerOnly".to_string(),
7140 MuteChannel::Unspecified(s) => s.to_string(),
7141 }
7142 }
7143}
7144
7145impl FromStr for MuteChannel {
7146 type Err = crate::Error;
7147 fn from_str(s: &str) -> Result<MuteChannel> {
7148 match s {
7149 "Master" => Ok(MuteChannel::Master),
7150 "LF" => Ok(MuteChannel::Lf),
7151 "RF" => Ok(MuteChannel::Rf),
7152 "SpeakerOnly" => Ok(MuteChannel::SpeakerOnly),
7153 s => Ok(MuteChannel::Unspecified(s.to_string())),
7154 }
7155 }
7156}
7157
7158impl instant_xml::ToXml for MuteChannel {
7159 fn serialize<W: std::fmt::Write + ?Sized>(
7160 &self,
7161 field: Option<instant_xml::Id<'_>>,
7162 serializer: &mut instant_xml::Serializer<W>,
7163 ) -> std::result::Result<(), instant_xml::Error> {
7164 self.to_string().serialize(field, serializer)
7165 }
7166
7167 fn present(&self) -> bool {
7168 true
7169 }
7170}
7171
7172impl<'xml> instant_xml::FromXml<'xml> for MuteChannel {
7173 #[inline]
7174 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
7175 match field {
7176 Some(field) => id == field,
7177 None => false,
7178 }
7179 }
7180
7181 fn deserialize<'cx>(
7182 into: &mut Self::Accumulator,
7183 field: &'static str,
7184 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
7185 ) -> std::result::Result<(), instant_xml::Error> {
7186 if into.is_some() {
7187 return Err(instant_xml::Error::DuplicateValue(field));
7188 }
7189
7190 match deserializer.take_str()? {
7191 Some(value) => {
7192 let parsed: MuteChannel = value.parse().map_err(|err| {
7193 instant_xml::Error::Other(format!(
7194 "invalid value for field {field}: {value}: {err:#}"
7195 ))
7196 })?;
7197 *into = Some(parsed);
7198 Ok(())
7199 }
7200 None => Err(instant_xml::Error::MissingValue(field)),
7201 }
7202 }
7203
7204 type Accumulator = Option<MuteChannel>;
7205 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
7206}
7207
7208#[derive(PartialEq, Debug, Clone, Eq, Default)]
7209pub enum RampType {
7210 #[default]
7211 SleepTimerRampType,
7212 AlarmRampType,
7213 AutoplayRampType,
7214
7215 Unspecified(String),
7219}
7220
7221impl ToString for RampType {
7222 fn to_string(&self) -> String {
7223 match self {
7224 RampType::SleepTimerRampType => "SLEEP_TIMER_RAMP_TYPE".to_string(),
7225 RampType::AlarmRampType => "ALARM_RAMP_TYPE".to_string(),
7226 RampType::AutoplayRampType => "AUTOPLAY_RAMP_TYPE".to_string(),
7227 RampType::Unspecified(s) => s.to_string(),
7228 }
7229 }
7230}
7231
7232impl FromStr for RampType {
7233 type Err = crate::Error;
7234 fn from_str(s: &str) -> Result<RampType> {
7235 match s {
7236 "SLEEP_TIMER_RAMP_TYPE" => Ok(RampType::SleepTimerRampType),
7237 "ALARM_RAMP_TYPE" => Ok(RampType::AlarmRampType),
7238 "AUTOPLAY_RAMP_TYPE" => Ok(RampType::AutoplayRampType),
7239 s => Ok(RampType::Unspecified(s.to_string())),
7240 }
7241 }
7242}
7243
7244impl instant_xml::ToXml for RampType {
7245 fn serialize<W: std::fmt::Write + ?Sized>(
7246 &self,
7247 field: Option<instant_xml::Id<'_>>,
7248 serializer: &mut instant_xml::Serializer<W>,
7249 ) -> std::result::Result<(), instant_xml::Error> {
7250 self.to_string().serialize(field, serializer)
7251 }
7252
7253 fn present(&self) -> bool {
7254 true
7255 }
7256}
7257
7258impl<'xml> instant_xml::FromXml<'xml> for RampType {
7259 #[inline]
7260 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
7261 match field {
7262 Some(field) => id == field,
7263 None => false,
7264 }
7265 }
7266
7267 fn deserialize<'cx>(
7268 into: &mut Self::Accumulator,
7269 field: &'static str,
7270 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
7271 ) -> std::result::Result<(), instant_xml::Error> {
7272 if into.is_some() {
7273 return Err(instant_xml::Error::DuplicateValue(field));
7274 }
7275
7276 match deserializer.take_str()? {
7277 Some(value) => {
7278 let parsed: RampType = value.parse().map_err(|err| {
7279 instant_xml::Error::Other(format!(
7280 "invalid value for field {field}: {value}: {err:#}"
7281 ))
7282 })?;
7283 *into = Some(parsed);
7284 Ok(())
7285 }
7286 None => Err(instant_xml::Error::MissingValue(field)),
7287 }
7288 }
7289
7290 type Accumulator = Option<RampType>;
7291 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
7292}
7293
7294pub mod system_properties {
7296 use super::*;
7297
7298 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:SystemProperties:1";
7301
7302 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7303 #[xml(rename = "AddAccountX", ns(SERVICE_TYPE))]
7304 pub struct AddAccountXRequest {
7305 #[xml(rename = "AccountType", ns(""))]
7306 pub account_type: u32,
7307 #[xml(rename = "AccountID", ns(""))]
7308 pub account_id: String,
7309 #[xml(rename = "AccountPassword", ns(""))]
7310 pub account_password: String,
7311 }
7312
7313 #[derive(FromXml, Debug, Clone, PartialEq)]
7314 #[xml(rename = "AddAccountXResponse", ns(SERVICE_TYPE))]
7315 pub struct AddAccountXResponse {
7316 #[xml(rename = "AccountUDN", ns(""))]
7317 pub account_udn: Option<String>,
7318 }
7319
7320 impl crate::DecodeSoapResponse for AddAccountXResponse {
7321 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
7322 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
7323 Ok(envelope.body.payload)
7324 }
7325 }
7326
7327 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7328 #[xml(rename = "AddOAuthAccountX", ns(SERVICE_TYPE))]
7329 pub struct AddOAuthAccountXRequest {
7330 #[xml(rename = "AccountType", ns(""))]
7331 pub account_type: u32,
7332 #[xml(rename = "AccountToken", ns(""))]
7333 pub account_token: String,
7334 #[xml(rename = "AccountKey", ns(""))]
7335 pub account_key: String,
7336 #[xml(rename = "OAuthDeviceID", ns(""))]
7337 pub o_auth_device_id: String,
7338 #[xml(rename = "AuthorizationCode", ns(""))]
7339 pub authorization_code: String,
7340 #[xml(rename = "RedirectURI", ns(""))]
7341 pub redirect_uri: String,
7342 #[xml(rename = "UserIdHashCode", ns(""))]
7343 pub user_id_hash_code: String,
7344 #[xml(rename = "AccountTier", ns(""))]
7345 pub account_tier: u32,
7346 }
7347
7348 #[derive(FromXml, Debug, Clone, PartialEq)]
7349 #[xml(rename = "AddOAuthAccountXResponse", ns(SERVICE_TYPE))]
7350 pub struct AddOAuthAccountXResponse {
7351 #[xml(rename = "AccountUDN", ns(""))]
7352 pub account_udn: Option<String>,
7353 #[xml(rename = "AccountNickname", ns(""))]
7354 pub account_nickname: Option<String>,
7355 }
7356
7357 impl crate::DecodeSoapResponse for AddOAuthAccountXResponse {
7358 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
7359 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
7360 Ok(envelope.body.payload)
7361 }
7362 }
7363
7364 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7365 #[xml(rename = "EditAccountMd", ns(SERVICE_TYPE))]
7366 pub struct EditAccountMdRequest {
7367 #[xml(rename = "AccountType", ns(""))]
7368 pub account_type: u32,
7369 #[xml(rename = "AccountID", ns(""))]
7370 pub account_id: String,
7371 #[xml(rename = "NewAccountMd", ns(""))]
7372 pub new_account_md: String,
7373 }
7374
7375 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7376 #[xml(rename = "EditAccountPasswordX", ns(SERVICE_TYPE))]
7377 pub struct EditAccountPasswordXRequest {
7378 #[xml(rename = "AccountType", ns(""))]
7379 pub account_type: u32,
7380 #[xml(rename = "AccountID", ns(""))]
7381 pub account_id: String,
7382 #[xml(rename = "NewAccountPassword", ns(""))]
7383 pub new_account_password: String,
7384 }
7385
7386 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7387 #[xml(rename = "EnableRDM", ns(SERVICE_TYPE))]
7388 pub struct EnableRdmRequest {
7389 #[xml(rename = "RDMValue", ns(""))]
7390 pub rdm_value: bool,
7391 }
7392
7393 #[derive(FromXml, Debug, Clone, PartialEq)]
7394 #[xml(rename = "GetRDMResponse", ns(SERVICE_TYPE))]
7395 pub struct GetRdmResponse {
7396 #[xml(rename = "RDMValue", ns(""))]
7397 pub rdm_value: Option<bool>,
7398 }
7399
7400 impl crate::DecodeSoapResponse for GetRdmResponse {
7401 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
7402 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
7403 Ok(envelope.body.payload)
7404 }
7405 }
7406
7407 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7408 #[xml(rename = "GetString", ns(SERVICE_TYPE))]
7409 pub struct GetStringRequest {
7410 #[xml(rename = "VariableName", ns(""))]
7412 pub variable_name: String,
7413 }
7414
7415 #[derive(FromXml, Debug, Clone, PartialEq)]
7416 #[xml(rename = "GetStringResponse", ns(SERVICE_TYPE))]
7417 pub struct GetStringResponse {
7418 #[xml(rename = "StringValue", ns(""))]
7419 pub string_value: Option<String>,
7420 }
7421
7422 impl crate::DecodeSoapResponse for GetStringResponse {
7423 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
7424 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
7425 Ok(envelope.body.payload)
7426 }
7427 }
7428
7429 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7430 #[xml(rename = "GetWebCode", ns(SERVICE_TYPE))]
7431 pub struct GetWebCodeRequest {
7432 #[xml(rename = "AccountType", ns(""))]
7433 pub account_type: u32,
7434 }
7435
7436 #[derive(FromXml, Debug, Clone, PartialEq)]
7437 #[xml(rename = "GetWebCodeResponse", ns(SERVICE_TYPE))]
7438 pub struct GetWebCodeResponse {
7439 #[xml(rename = "WebCode", ns(""))]
7440 pub web_code: Option<String>,
7441 }
7442
7443 impl crate::DecodeSoapResponse for GetWebCodeResponse {
7444 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
7445 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
7446 Ok(envelope.body.payload)
7447 }
7448 }
7449
7450 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7451 #[xml(rename = "ProvisionCredentialedTrialAccountX", ns(SERVICE_TYPE))]
7452 pub struct ProvisionCredentialedTrialAccountXRequest {
7453 #[xml(rename = "AccountType", ns(""))]
7454 pub account_type: u32,
7455 #[xml(rename = "AccountID", ns(""))]
7456 pub account_id: String,
7457 #[xml(rename = "AccountPassword", ns(""))]
7458 pub account_password: String,
7459 }
7460
7461 #[derive(FromXml, Debug, Clone, PartialEq)]
7462 #[xml(
7463 rename = "ProvisionCredentialedTrialAccountXResponse",
7464 ns(SERVICE_TYPE)
7465 )]
7466 pub struct ProvisionCredentialedTrialAccountXResponse {
7467 #[xml(rename = "IsExpired", ns(""))]
7468 pub is_expired: Option<bool>,
7469 #[xml(rename = "AccountUDN", ns(""))]
7470 pub account_udn: Option<String>,
7471 }
7472
7473 impl crate::DecodeSoapResponse for ProvisionCredentialedTrialAccountXResponse {
7474 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
7475 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
7476 Ok(envelope.body.payload)
7477 }
7478 }
7479
7480 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7481 #[xml(rename = "RefreshAccountCredentialsX", ns(SERVICE_TYPE))]
7482 pub struct RefreshAccountCredentialsXRequest {
7483 #[xml(rename = "AccountType", ns(""))]
7484 pub account_type: u32,
7485 #[xml(rename = "AccountUID", ns(""))]
7486 pub account_uid: u32,
7487 #[xml(rename = "AccountToken", ns(""))]
7488 pub account_token: String,
7489 #[xml(rename = "AccountKey", ns(""))]
7490 pub account_key: String,
7491 }
7492
7493 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7494 #[xml(rename = "Remove", ns(SERVICE_TYPE))]
7495 pub struct RemoveRequest {
7496 #[xml(rename = "VariableName", ns(""))]
7498 pub variable_name: String,
7499 }
7500
7501 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7502 #[xml(rename = "RemoveAccount", ns(SERVICE_TYPE))]
7503 pub struct RemoveAccountRequest {
7504 #[xml(rename = "AccountType", ns(""))]
7505 pub account_type: u32,
7506 #[xml(rename = "AccountID", ns(""))]
7507 pub account_id: String,
7508 }
7509
7510 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7511 #[xml(rename = "ReplaceAccountX", ns(SERVICE_TYPE))]
7512 pub struct ReplaceAccountXRequest {
7513 #[xml(rename = "AccountUDN", ns(""))]
7514 pub account_udn: String,
7515 #[xml(rename = "NewAccountID", ns(""))]
7516 pub new_account_id: String,
7517 #[xml(rename = "NewAccountPassword", ns(""))]
7518 pub new_account_password: String,
7519 #[xml(rename = "AccountToken", ns(""))]
7520 pub account_token: String,
7521 #[xml(rename = "AccountKey", ns(""))]
7522 pub account_key: String,
7523 #[xml(rename = "OAuthDeviceID", ns(""))]
7524 pub o_auth_device_id: String,
7525 }
7526
7527 #[derive(FromXml, Debug, Clone, PartialEq)]
7528 #[xml(rename = "ReplaceAccountXResponse", ns(SERVICE_TYPE))]
7529 pub struct ReplaceAccountXResponse {
7530 #[xml(rename = "NewAccountUDN", ns(""))]
7531 pub new_account_udn: Option<String>,
7532 }
7533
7534 impl crate::DecodeSoapResponse for ReplaceAccountXResponse {
7535 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
7536 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
7537 Ok(envelope.body.payload)
7538 }
7539 }
7540
7541 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7542 #[xml(rename = "SetAccountNicknameX", ns(SERVICE_TYPE))]
7543 pub struct SetAccountNicknameXRequest {
7544 #[xml(rename = "AccountUDN", ns(""))]
7545 pub account_udn: String,
7546 #[xml(rename = "AccountNickname", ns(""))]
7547 pub account_nickname: String,
7548 }
7549
7550 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7551 #[xml(rename = "SetString", ns(SERVICE_TYPE))]
7552 pub struct SetStringRequest {
7553 #[xml(rename = "VariableName", ns(""))]
7555 pub variable_name: String,
7556 #[xml(rename = "StringValue", ns(""))]
7557 pub string_value: String,
7558 }
7559
7560 #[derive(Debug, Clone, PartialEq, Default)]
7564 pub struct SystemPropertiesEvent {
7565 pub customer_id: Option<String>,
7566 pub third_party_hash: Option<String>,
7567 pub update_id: Option<u32>,
7568 pub update_idx: Option<u32>,
7569 pub voice_update_id: Option<u32>,
7570 }
7571
7572 #[derive(FromXml, Debug, Clone, PartialEq)]
7573 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
7574 struct SystemPropertiesPropertySet {
7575 pub properties: Vec<SystemPropertiesProperty>,
7576 }
7577
7578 #[derive(FromXml, Debug, Clone, PartialEq)]
7579 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
7580 struct SystemPropertiesProperty {
7581 #[xml(rename = "CustomerID", ns(""))]
7582 pub customer_id: Option<String>,
7583 #[xml(rename = "ThirdPartyHash", ns(""))]
7584 pub third_party_hash: Option<String>,
7585 #[xml(rename = "UpdateID", ns(""))]
7586 pub update_id: Option<u32>,
7587 #[xml(rename = "UpdateIDX", ns(""))]
7588 pub update_idx: Option<u32>,
7589 #[xml(rename = "VoiceUpdateID", ns(""))]
7590 pub voice_update_id: Option<u32>,
7591 }
7592
7593 impl DecodeXml for SystemPropertiesEvent {
7594 fn decode_xml(xml: &str) -> crate::Result<Self> {
7595 let mut result = Self::default();
7596 let set: SystemPropertiesPropertySet = instant_xml::from_str(xml)?;
7597 for prop in set.properties {
7598 if let Some(v) = prop.customer_id {
7599 result.customer_id.replace(v);
7600 }
7601
7602 if let Some(v) = prop.third_party_hash {
7603 result.third_party_hash.replace(v);
7604 }
7605
7606 if let Some(v) = prop.update_id {
7607 result.update_id.replace(v);
7608 }
7609
7610 if let Some(v) = prop.update_idx {
7611 result.update_idx.replace(v);
7612 }
7613
7614 if let Some(v) = prop.voice_update_id {
7615 result.voice_update_id.replace(v);
7616 }
7617 }
7618 Ok(result)
7619 }
7620 }
7621
7622 impl crate::SonosDevice {
7623 pub async fn subscribe_system_properties(
7625 &self,
7626 ) -> crate::Result<crate::upnp::EventStream<SystemPropertiesEvent>> {
7627 self.subscribe_helper(&SERVICE_TYPE).await
7628 }
7629 }
7630}
7631
7632pub mod virtual_line_in {
7634 use super::*;
7635
7636 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:VirtualLineIn:1";
7639
7640 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7641 #[xml(rename = "Next", ns(SERVICE_TYPE))]
7642 pub struct NextRequest {
7643 #[xml(rename = "InstanceID", ns(""))]
7644 pub instance_id: u32,
7645 }
7646
7647 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7648 #[xml(rename = "Pause", ns(SERVICE_TYPE))]
7649 pub struct PauseRequest {
7650 #[xml(rename = "InstanceID", ns(""))]
7651 pub instance_id: u32,
7652 }
7653
7654 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7655 #[xml(rename = "Play", ns(SERVICE_TYPE))]
7656 pub struct PlayRequest {
7657 #[xml(rename = "InstanceID", ns(""))]
7658 pub instance_id: u32,
7659 #[xml(rename = "Speed", ns(""))]
7660 pub speed: String,
7661 }
7662
7663 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7664 #[xml(rename = "Previous", ns(SERVICE_TYPE))]
7665 pub struct PreviousRequest {
7666 #[xml(rename = "InstanceID", ns(""))]
7667 pub instance_id: u32,
7668 }
7669
7670 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7671 #[xml(rename = "SetVolume", ns(SERVICE_TYPE))]
7672 pub struct SetVolumeRequest {
7673 #[xml(rename = "InstanceID", ns(""))]
7674 pub instance_id: u32,
7675 #[xml(rename = "DesiredVolume", ns(""))]
7676 pub desired_volume: u16,
7677 }
7678
7679 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7680 #[xml(rename = "StartTransmission", ns(SERVICE_TYPE))]
7681 pub struct StartTransmissionRequest {
7682 #[xml(rename = "InstanceID", ns(""))]
7683 pub instance_id: u32,
7684 #[xml(rename = "CoordinatorID", ns(""))]
7685 pub coordinator_id: String,
7686 }
7687
7688 #[derive(FromXml, Debug, Clone, PartialEq)]
7689 #[xml(rename = "StartTransmissionResponse", ns(SERVICE_TYPE))]
7690 pub struct StartTransmissionResponse {
7691 #[xml(rename = "CurrentTransportSettings", ns(""))]
7692 pub current_transport_settings: Option<String>,
7693 }
7694
7695 impl crate::DecodeSoapResponse for StartTransmissionResponse {
7696 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
7697 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
7698 Ok(envelope.body.payload)
7699 }
7700 }
7701
7702 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7703 #[xml(rename = "Stop", ns(SERVICE_TYPE))]
7704 pub struct StopRequest {
7705 #[xml(rename = "InstanceID", ns(""))]
7706 pub instance_id: u32,
7707 }
7708
7709 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7710 #[xml(rename = "StopTransmission", ns(SERVICE_TYPE))]
7711 pub struct StopTransmissionRequest {
7712 #[xml(rename = "InstanceID", ns(""))]
7713 pub instance_id: u32,
7714 #[xml(rename = "CoordinatorID", ns(""))]
7715 pub coordinator_id: String,
7716 }
7717
7718 #[derive(Debug, Clone, PartialEq, Default)]
7722 pub struct VirtualLineInEvent {
7723 pub current_track_meta_data: Option<DecodeXmlString<crate::TrackMetaData>>,
7724 pub last_change: Option<String>,
7725 }
7726
7727 #[derive(FromXml, Debug, Clone, PartialEq)]
7728 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
7729 struct VirtualLineInPropertySet {
7730 pub properties: Vec<VirtualLineInProperty>,
7731 }
7732
7733 #[derive(FromXml, Debug, Clone, PartialEq)]
7734 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
7735 struct VirtualLineInProperty {
7736 #[xml(rename = "CurrentTrackMetaData", ns(""))]
7737 pub current_track_meta_data: Option<DecodeXmlString<crate::TrackMetaData>>,
7738 #[xml(rename = "LastChange", ns(""))]
7739 pub last_change: Option<String>,
7740 }
7741
7742 impl DecodeXml for VirtualLineInEvent {
7743 fn decode_xml(xml: &str) -> crate::Result<Self> {
7744 let mut result = Self::default();
7745 let set: VirtualLineInPropertySet = instant_xml::from_str(xml)?;
7746 for prop in set.properties {
7747 if let Some(v) = prop.current_track_meta_data {
7748 result.current_track_meta_data.replace(v);
7749 }
7750
7751 if let Some(v) = prop.last_change {
7752 result.last_change.replace(v);
7753 }
7754 }
7755 Ok(result)
7756 }
7757 }
7758
7759 impl crate::SonosDevice {
7760 pub async fn subscribe_virtual_line_in(
7762 &self,
7763 ) -> crate::Result<crate::upnp::EventStream<VirtualLineInEvent>> {
7764 self.subscribe_helper(&SERVICE_TYPE).await
7765 }
7766 }
7767}
7768
7769pub mod zone_group_topology {
7771 use super::*;
7772
7773 pub const SERVICE_TYPE: &str = "urn:schemas-upnp-org:service:ZoneGroupTopology:1";
7776
7777 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7778 #[xml(rename = "BeginSoftwareUpdate", ns(SERVICE_TYPE))]
7779 pub struct BeginSoftwareUpdateRequest {
7780 #[xml(rename = "UpdateURL", ns(""))]
7781 pub update_url: String,
7782 #[xml(rename = "Flags", ns(""))]
7783 pub flags: u32,
7784 #[xml(rename = "ExtraOptions", ns(""))]
7785 pub extra_options: String,
7786 }
7787
7788 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7789 #[xml(rename = "CheckForUpdate", ns(SERVICE_TYPE))]
7790 pub struct CheckForUpdateRequest {
7791 #[xml(rename = "UpdateType", ns(""))]
7792 pub update_type: super::UpdateType,
7793 #[xml(rename = "CachedOnly", ns(""))]
7794 pub cached_only: bool,
7795 #[xml(rename = "Version", ns(""))]
7796 pub version: String,
7797 }
7798
7799 #[derive(FromXml, Debug, Clone, PartialEq)]
7800 #[xml(rename = "CheckForUpdateResponse", ns(SERVICE_TYPE))]
7801 pub struct CheckForUpdateResponse {
7802 #[xml(rename = "UpdateItem", ns(""))]
7803 pub update_item: Option<String>,
7804 }
7805
7806 impl crate::DecodeSoapResponse for CheckForUpdateResponse {
7807 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
7808 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
7809 Ok(envelope.body.payload)
7810 }
7811 }
7812
7813 #[derive(FromXml, Debug, Clone, PartialEq)]
7814 #[xml(rename = "GetZoneGroupAttributesResponse", ns(SERVICE_TYPE))]
7815 pub struct GetZoneGroupAttributesResponse {
7816 #[xml(rename = "CurrentZoneGroupName", ns(""))]
7817 pub current_zone_group_name: Option<String>,
7818 #[xml(rename = "CurrentZoneGroupID", ns(""))]
7819 pub current_zone_group_id: Option<String>,
7820 #[xml(rename = "CurrentZonePlayerUUIDsInGroup", ns(""))]
7821 pub current_zone_player_uuids_in_group: Option<String>,
7822 #[xml(rename = "CurrentMuseHouseholdId", ns(""))]
7823 pub current_muse_household_id: Option<String>,
7824 }
7825
7826 impl crate::DecodeSoapResponse for GetZoneGroupAttributesResponse {
7827 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
7828 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
7829 Ok(envelope.body.payload)
7830 }
7831 }
7832
7833 #[derive(FromXml, Debug, Clone, PartialEq)]
7834 #[xml(rename = "GetZoneGroupStateResponse", ns(SERVICE_TYPE))]
7835 pub struct GetZoneGroupStateResponse {
7836 #[xml(rename = "ZoneGroupState", ns(""))]
7837 pub zone_group_state: Option<DecodeXmlString<crate::ZoneGroupState>>,
7838 }
7839
7840 impl crate::DecodeSoapResponse for GetZoneGroupStateResponse {
7841 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
7842 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
7843 Ok(envelope.body.payload)
7844 }
7845 }
7846
7847 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7848 #[xml(rename = "RegisterMobileDevice", ns(SERVICE_TYPE))]
7849 pub struct RegisterMobileDeviceRequest {
7850 #[xml(rename = "MobileDeviceName", ns(""))]
7851 pub mobile_device_name: String,
7852 #[xml(rename = "MobileDeviceUDN", ns(""))]
7853 pub mobile_device_udn: String,
7854 #[xml(rename = "MobileIPAndPort", ns(""))]
7855 pub mobile_ip_and_port: String,
7856 }
7857
7858 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7859 #[xml(rename = "ReportUnresponsiveDevice", ns(SERVICE_TYPE))]
7860 pub struct ReportUnresponsiveDeviceRequest {
7861 #[xml(rename = "DeviceUUID", ns(""))]
7862 pub device_uuid: String,
7863 #[xml(rename = "DesiredAction", ns(""))]
7864 pub desired_action: super::UnresponsiveDeviceActionType,
7865 }
7866
7867 #[derive(ToXml, Debug, Clone, PartialEq, Default)]
7868 #[xml(rename = "SubmitDiagnostics", ns(SERVICE_TYPE))]
7869 pub struct SubmitDiagnosticsRequest {
7870 #[xml(rename = "IncludeControllers", ns(""))]
7871 pub include_controllers: bool,
7872 #[xml(rename = "Type", ns(""))]
7873 pub type_: String,
7874 }
7875
7876 #[derive(FromXml, Debug, Clone, PartialEq)]
7877 #[xml(rename = "SubmitDiagnosticsResponse", ns(SERVICE_TYPE))]
7878 pub struct SubmitDiagnosticsResponse {
7879 #[xml(rename = "DiagnosticID", ns(""))]
7880 pub diagnostic_id: Option<u32>,
7881 }
7882
7883 impl crate::DecodeSoapResponse for SubmitDiagnosticsResponse {
7884 fn decode_soap_xml(xml: &str) -> crate::Result<Self> {
7885 let envelope: crate::soap_resp::Envelope<Self> = instant_xml::from_str(xml)?;
7886 Ok(envelope.body.payload)
7887 }
7888 }
7889
7890 #[derive(Debug, Clone, PartialEq, Default)]
7894 pub struct ZoneGroupTopologyEvent {
7895 pub alarm_run_sequence: Option<String>,
7896 pub areas_update_id: Option<String>,
7897 pub available_software_update: Option<String>,
7898 pub muse_household_id: Option<String>,
7899 pub netsettings_update_id: Option<String>,
7900 pub source_areas_update_id: Option<String>,
7901 pub third_party_media_servers_x: Option<String>,
7902 pub zone_group_id: Option<String>,
7903 pub zone_group_name: Option<String>,
7904 pub zone_group_state: Option<DecodeXmlString<crate::ZoneGroupState>>,
7905 pub zone_player_uuids_in_group: Option<String>,
7906 }
7907
7908 #[derive(FromXml, Debug, Clone, PartialEq)]
7909 #[xml(rename="propertyset", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
7910 struct ZoneGroupTopologyPropertySet {
7911 pub properties: Vec<ZoneGroupTopologyProperty>,
7912 }
7913
7914 #[derive(FromXml, Debug, Clone, PartialEq)]
7915 #[xml(rename="property", ns(crate::upnp::UPNP_EVENT, e=crate::upnp::UPNP_EVENT))]
7916 struct ZoneGroupTopologyProperty {
7917 #[xml(rename = "AlarmRunSequence", ns(""))]
7918 pub alarm_run_sequence: Option<String>,
7919 #[xml(rename = "AreasUpdateID", ns(""))]
7920 pub areas_update_id: Option<String>,
7921 #[xml(rename = "AvailableSoftwareUpdate", ns(""))]
7922 pub available_software_update: Option<String>,
7923 #[xml(rename = "MuseHouseholdId", ns(""))]
7924 pub muse_household_id: Option<String>,
7925 #[xml(rename = "NetsettingsUpdateID", ns(""))]
7926 pub netsettings_update_id: Option<String>,
7927 #[xml(rename = "SourceAreasUpdateID", ns(""))]
7928 pub source_areas_update_id: Option<String>,
7929 #[xml(rename = "ThirdPartyMediaServersX", ns(""))]
7930 pub third_party_media_servers_x: Option<String>,
7931 #[xml(rename = "ZoneGroupID", ns(""))]
7932 pub zone_group_id: Option<String>,
7933 #[xml(rename = "ZoneGroupName", ns(""))]
7934 pub zone_group_name: Option<String>,
7935 #[xml(rename = "ZoneGroupState", ns(""))]
7936 pub zone_group_state: Option<DecodeXmlString<crate::ZoneGroupState>>,
7937 #[xml(rename = "ZonePlayerUUIDsInGroup", ns(""))]
7938 pub zone_player_uuids_in_group: Option<String>,
7939 }
7940
7941 impl DecodeXml for ZoneGroupTopologyEvent {
7942 fn decode_xml(xml: &str) -> crate::Result<Self> {
7943 let mut result = Self::default();
7944 let set: ZoneGroupTopologyPropertySet = instant_xml::from_str(xml)?;
7945 for prop in set.properties {
7946 if let Some(v) = prop.alarm_run_sequence {
7947 result.alarm_run_sequence.replace(v);
7948 }
7949
7950 if let Some(v) = prop.areas_update_id {
7951 result.areas_update_id.replace(v);
7952 }
7953
7954 if let Some(v) = prop.available_software_update {
7955 result.available_software_update.replace(v);
7956 }
7957
7958 if let Some(v) = prop.muse_household_id {
7959 result.muse_household_id.replace(v);
7960 }
7961
7962 if let Some(v) = prop.netsettings_update_id {
7963 result.netsettings_update_id.replace(v);
7964 }
7965
7966 if let Some(v) = prop.source_areas_update_id {
7967 result.source_areas_update_id.replace(v);
7968 }
7969
7970 if let Some(v) = prop.third_party_media_servers_x {
7971 result.third_party_media_servers_x.replace(v);
7972 }
7973
7974 if let Some(v) = prop.zone_group_id {
7975 result.zone_group_id.replace(v);
7976 }
7977
7978 if let Some(v) = prop.zone_group_name {
7979 result.zone_group_name.replace(v);
7980 }
7981
7982 if let Some(v) = prop.zone_group_state {
7983 result.zone_group_state.replace(v);
7984 }
7985
7986 if let Some(v) = prop.zone_player_uuids_in_group {
7987 result.zone_player_uuids_in_group.replace(v);
7988 }
7989 }
7990 Ok(result)
7991 }
7992 }
7993
7994 impl crate::SonosDevice {
7995 pub async fn subscribe_zone_group_topology(
7997 &self,
7998 ) -> crate::Result<crate::upnp::EventStream<ZoneGroupTopologyEvent>> {
7999 self.subscribe_helper(&SERVICE_TYPE).await
8000 }
8001 }
8002}
8003
8004#[derive(PartialEq, Debug, Clone, Eq, Default)]
8005pub enum UnresponsiveDeviceActionType {
8006 #[default]
8007 Remove,
8008 TopologyMonitorProbe,
8009 VerifyThenRemoveSystemwide,
8010
8011 Unspecified(String),
8015}
8016
8017impl ToString for UnresponsiveDeviceActionType {
8018 fn to_string(&self) -> String {
8019 match self {
8020 UnresponsiveDeviceActionType::Remove => "Remove".to_string(),
8021 UnresponsiveDeviceActionType::TopologyMonitorProbe => {
8022 "TopologyMonitorProbe".to_string()
8023 }
8024 UnresponsiveDeviceActionType::VerifyThenRemoveSystemwide => {
8025 "VerifyThenRemoveSystemwide".to_string()
8026 }
8027 UnresponsiveDeviceActionType::Unspecified(s) => s.to_string(),
8028 }
8029 }
8030}
8031
8032impl FromStr for UnresponsiveDeviceActionType {
8033 type Err = crate::Error;
8034 fn from_str(s: &str) -> Result<UnresponsiveDeviceActionType> {
8035 match s {
8036 "Remove" => Ok(UnresponsiveDeviceActionType::Remove),
8037 "TopologyMonitorProbe" => Ok(UnresponsiveDeviceActionType::TopologyMonitorProbe),
8038 "VerifyThenRemoveSystemwide" => {
8039 Ok(UnresponsiveDeviceActionType::VerifyThenRemoveSystemwide)
8040 }
8041 s => Ok(UnresponsiveDeviceActionType::Unspecified(s.to_string())),
8042 }
8043 }
8044}
8045
8046impl instant_xml::ToXml for UnresponsiveDeviceActionType {
8047 fn serialize<W: std::fmt::Write + ?Sized>(
8048 &self,
8049 field: Option<instant_xml::Id<'_>>,
8050 serializer: &mut instant_xml::Serializer<W>,
8051 ) -> std::result::Result<(), instant_xml::Error> {
8052 self.to_string().serialize(field, serializer)
8053 }
8054
8055 fn present(&self) -> bool {
8056 true
8057 }
8058}
8059
8060impl<'xml> instant_xml::FromXml<'xml> for UnresponsiveDeviceActionType {
8061 #[inline]
8062 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
8063 match field {
8064 Some(field) => id == field,
8065 None => false,
8066 }
8067 }
8068
8069 fn deserialize<'cx>(
8070 into: &mut Self::Accumulator,
8071 field: &'static str,
8072 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
8073 ) -> std::result::Result<(), instant_xml::Error> {
8074 if into.is_some() {
8075 return Err(instant_xml::Error::DuplicateValue(field));
8076 }
8077
8078 match deserializer.take_str()? {
8079 Some(value) => {
8080 let parsed: UnresponsiveDeviceActionType = value.parse().map_err(|err| {
8081 instant_xml::Error::Other(format!(
8082 "invalid value for field {field}: {value}: {err:#}"
8083 ))
8084 })?;
8085 *into = Some(parsed);
8086 Ok(())
8087 }
8088 None => Err(instant_xml::Error::MissingValue(field)),
8089 }
8090 }
8091
8092 type Accumulator = Option<UnresponsiveDeviceActionType>;
8093 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
8094}
8095
8096#[derive(PartialEq, Debug, Clone, Eq, Default)]
8097pub enum UpdateType {
8098 #[default]
8099 All,
8100 Software,
8101
8102 Unspecified(String),
8106}
8107
8108impl ToString for UpdateType {
8109 fn to_string(&self) -> String {
8110 match self {
8111 UpdateType::All => "All".to_string(),
8112 UpdateType::Software => "Software".to_string(),
8113 UpdateType::Unspecified(s) => s.to_string(),
8114 }
8115 }
8116}
8117
8118impl FromStr for UpdateType {
8119 type Err = crate::Error;
8120 fn from_str(s: &str) -> Result<UpdateType> {
8121 match s {
8122 "All" => Ok(UpdateType::All),
8123 "Software" => Ok(UpdateType::Software),
8124 s => Ok(UpdateType::Unspecified(s.to_string())),
8125 }
8126 }
8127}
8128
8129impl instant_xml::ToXml for UpdateType {
8130 fn serialize<W: std::fmt::Write + ?Sized>(
8131 &self,
8132 field: Option<instant_xml::Id<'_>>,
8133 serializer: &mut instant_xml::Serializer<W>,
8134 ) -> std::result::Result<(), instant_xml::Error> {
8135 self.to_string().serialize(field, serializer)
8136 }
8137
8138 fn present(&self) -> bool {
8139 true
8140 }
8141}
8142
8143impl<'xml> instant_xml::FromXml<'xml> for UpdateType {
8144 #[inline]
8145 fn matches(id: instant_xml::Id<'_>, field: Option<instant_xml::Id<'_>>) -> bool {
8146 match field {
8147 Some(field) => id == field,
8148 None => false,
8149 }
8150 }
8151
8152 fn deserialize<'cx>(
8153 into: &mut Self::Accumulator,
8154 field: &'static str,
8155 deserializer: &mut instant_xml::Deserializer<'cx, 'xml>,
8156 ) -> std::result::Result<(), instant_xml::Error> {
8157 if into.is_some() {
8158 return Err(instant_xml::Error::DuplicateValue(field));
8159 }
8160
8161 match deserializer.take_str()? {
8162 Some(value) => {
8163 let parsed: UpdateType = value.parse().map_err(|err| {
8164 instant_xml::Error::Other(format!(
8165 "invalid value for field {field}: {value}: {err:#}"
8166 ))
8167 })?;
8168 *into = Some(parsed);
8169 Ok(())
8170 }
8171 None => Err(instant_xml::Error::MissingValue(field)),
8172 }
8173 }
8174
8175 type Accumulator = Option<UpdateType>;
8176 const KIND: instant_xml::Kind = instant_xml::Kind::Scalar;
8177}
8178
8179#[allow(async_fn_in_trait)]
8180pub trait AVTransport {
8182 async fn add_multiple_uris_to_queue(
8183 &self,
8184 request: av_transport::AddMultipleUrisToQueueRequest,
8185 ) -> Result<av_transport::AddMultipleUrisToQueueResponse>;
8186 async fn add_uri_to_queue(
8188 &self,
8189 request: av_transport::AddUriToQueueRequest,
8190 ) -> Result<av_transport::AddUriToQueueResponse>;
8191 async fn add_uri_to_saved_queue(
8192 &self,
8193 request: av_transport::AddUriToSavedQueueRequest,
8194 ) -> Result<av_transport::AddUriToSavedQueueResponse>;
8195 async fn backup_queue(&self, request: av_transport::BackupQueueRequest) -> Result<()>;
8196 async fn become_coordinator_of_standalone_group(
8198 &self,
8199 request: av_transport::BecomeCoordinatorOfStandaloneGroupRequest,
8200 ) -> Result<av_transport::BecomeCoordinatorOfStandaloneGroupResponse>;
8201 async fn become_group_coordinator(
8202 &self,
8203 request: av_transport::BecomeGroupCoordinatorRequest,
8204 ) -> Result<()>;
8205 async fn become_group_coordinator_and_source(
8206 &self,
8207 request: av_transport::BecomeGroupCoordinatorAndSourceRequest,
8208 ) -> Result<()>;
8209 async fn change_coordinator(
8210 &self,
8211 request: av_transport::ChangeCoordinatorRequest,
8212 ) -> Result<()>;
8213 async fn change_transport_settings(
8214 &self,
8215 request: av_transport::ChangeTransportSettingsRequest,
8216 ) -> Result<()>;
8217 async fn configure_sleep_timer(
8219 &self,
8220 request: av_transport::ConfigureSleepTimerRequest,
8221 ) -> Result<()>;
8222 async fn create_saved_queue(
8223 &self,
8224 request: av_transport::CreateSavedQueueRequest,
8225 ) -> Result<av_transport::CreateSavedQueueResponse>;
8226 async fn delegate_group_coordination_to(
8228 &self,
8229 request: av_transport::DelegateGroupCoordinationToRequest,
8230 ) -> Result<()>;
8231 async fn end_direct_control_session(
8232 &self,
8233 request: av_transport::EndDirectControlSessionRequest,
8234 ) -> Result<()>;
8235 async fn get_crossfade_mode(
8237 &self,
8238 request: av_transport::GetCrossfadeModeRequest,
8239 ) -> Result<av_transport::GetCrossfadeModeResponse>;
8240 async fn get_current_transport_actions(
8242 &self,
8243 request: av_transport::GetCurrentTransportActionsRequest,
8244 ) -> Result<av_transport::GetCurrentTransportActionsResponse>;
8245 async fn get_device_capabilities(
8246 &self,
8247 request: av_transport::GetDeviceCapabilitiesRequest,
8248 ) -> Result<av_transport::GetDeviceCapabilitiesResponse>;
8249 async fn get_media_info(
8251 &self,
8252 request: av_transport::GetMediaInfoRequest,
8253 ) -> Result<av_transport::GetMediaInfoResponse>;
8254 async fn get_position_info(
8256 &self,
8257 request: av_transport::GetPositionInfoRequest,
8258 ) -> Result<av_transport::GetPositionInfoResponse>;
8259 async fn get_remaining_sleep_timer_duration(
8261 &self,
8262 request: av_transport::GetRemainingSleepTimerDurationRequest,
8263 ) -> Result<av_transport::GetRemainingSleepTimerDurationResponse>;
8264 async fn get_running_alarm_properties(
8265 &self,
8266 request: av_transport::GetRunningAlarmPropertiesRequest,
8267 ) -> Result<av_transport::GetRunningAlarmPropertiesResponse>;
8268 async fn get_transport_info(
8270 &self,
8271 request: av_transport::GetTransportInfoRequest,
8272 ) -> Result<av_transport::GetTransportInfoResponse>;
8273 async fn get_transport_settings(
8275 &self,
8276 request: av_transport::GetTransportSettingsRequest,
8277 ) -> Result<av_transport::GetTransportSettingsResponse>;
8278 async fn next(&self, request: av_transport::NextRequest) -> Result<()>;
8280 async fn notify_deleted_uri(
8281 &self,
8282 request: av_transport::NotifyDeletedUriRequest,
8283 ) -> Result<()>;
8284 async fn pause(&self, request: av_transport::PauseRequest) -> Result<()>;
8286 async fn play(&self, request: av_transport::PlayRequest) -> Result<()>;
8288 async fn previous(&self, request: av_transport::PreviousRequest) -> Result<()>;
8290 async fn remove_all_tracks_from_queue(
8292 &self,
8293 request: av_transport::RemoveAllTracksFromQueueRequest,
8294 ) -> Result<()>;
8295 async fn remove_track_from_queue(
8296 &self,
8297 request: av_transport::RemoveTrackFromQueueRequest,
8298 ) -> Result<()>;
8299 async fn remove_track_range_from_queue(
8301 &self,
8302 request: av_transport::RemoveTrackRangeFromQueueRequest,
8303 ) -> Result<av_transport::RemoveTrackRangeFromQueueResponse>;
8304 async fn reorder_tracks_in_queue(
8305 &self,
8306 request: av_transport::ReorderTracksInQueueRequest,
8307 ) -> Result<()>;
8308 async fn reorder_tracks_in_saved_queue(
8309 &self,
8310 request: av_transport::ReorderTracksInSavedQueueRequest,
8311 ) -> Result<av_transport::ReorderTracksInSavedQueueResponse>;
8312 async fn run_alarm(&self, request: av_transport::RunAlarmRequest) -> Result<()>;
8313 async fn save_queue(
8315 &self,
8316 request: av_transport::SaveQueueRequest,
8317 ) -> Result<av_transport::SaveQueueResponse>;
8318 async fn seek(&self, request: av_transport::SeekRequest) -> Result<()>;
8320 async fn set_av_transport_uri(
8322 &self,
8323 request: av_transport::SetAvTransportUriRequest,
8324 ) -> Result<()>;
8325 async fn set_crossfade_mode(
8327 &self,
8328 request: av_transport::SetCrossfadeModeRequest,
8329 ) -> Result<()>;
8330 async fn set_next_av_transport_uri(
8331 &self,
8332 request: av_transport::SetNextAvTransportUriRequest,
8333 ) -> Result<()>;
8334 async fn set_play_mode(&self, request: av_transport::SetPlayModeRequest) -> Result<()>;
8336 async fn snooze_alarm(&self, request: av_transport::SnoozeAlarmRequest) -> Result<()>;
8338 async fn start_autoplay(&self, request: av_transport::StartAutoplayRequest) -> Result<()>;
8339 async fn stop(&self, request: av_transport::StopRequest) -> Result<()>;
8341}
8342
8343#[allow(async_fn_in_trait)]
8344pub trait AlarmClock {
8346 async fn create_alarm(
8348 &self,
8349 request: alarm_clock::CreateAlarmRequest,
8350 ) -> Result<alarm_clock::CreateAlarmResponse>;
8351 async fn destroy_alarm(&self, request: alarm_clock::DestroyAlarmRequest) -> Result<()>;
8353 async fn get_daily_index_refresh_time(
8354 &self,
8355 ) -> Result<alarm_clock::GetDailyIndexRefreshTimeResponse>;
8356 async fn get_format(&self) -> Result<alarm_clock::GetFormatResponse>;
8357 async fn get_household_time_at_stamp(
8358 &self,
8359 request: alarm_clock::GetHouseholdTimeAtStampRequest,
8360 ) -> Result<alarm_clock::GetHouseholdTimeAtStampResponse>;
8361 async fn get_time_now(&self) -> Result<alarm_clock::GetTimeNowResponse>;
8362 async fn get_time_server(&self) -> Result<alarm_clock::GetTimeServerResponse>;
8363 async fn get_time_zone(&self) -> Result<alarm_clock::GetTimeZoneResponse>;
8364 async fn get_time_zone_and_rule(&self) -> Result<alarm_clock::GetTimeZoneAndRuleResponse>;
8365 async fn get_time_zone_rule(
8366 &self,
8367 request: alarm_clock::GetTimeZoneRuleRequest,
8368 ) -> Result<alarm_clock::GetTimeZoneRuleResponse>;
8369 async fn list_alarms(&self) -> Result<alarm_clock::ListAlarmsResponse>;
8371 async fn set_daily_index_refresh_time(
8372 &self,
8373 request: alarm_clock::SetDailyIndexRefreshTimeRequest,
8374 ) -> Result<()>;
8375 async fn set_format(&self, request: alarm_clock::SetFormatRequest) -> Result<()>;
8376 async fn set_time_now(&self, request: alarm_clock::SetTimeNowRequest) -> Result<()>;
8377 async fn set_time_server(&self, request: alarm_clock::SetTimeServerRequest) -> Result<()>;
8378 async fn set_time_zone(&self, request: alarm_clock::SetTimeZoneRequest) -> Result<()>;
8379 async fn update_alarm(&self, request: alarm_clock::UpdateAlarmRequest) -> Result<()>;
8381}
8382
8383#[allow(async_fn_in_trait)]
8384pub trait AudioIn {
8386 async fn get_audio_input_attributes(&self)
8387 -> Result<audio_in::GetAudioInputAttributesResponse>;
8388 async fn get_line_in_level(&self) -> Result<audio_in::GetLineInLevelResponse>;
8389 async fn select_audio(&self, request: audio_in::SelectAudioRequest) -> Result<()>;
8390 async fn set_audio_input_attributes(
8391 &self,
8392 request: audio_in::SetAudioInputAttributesRequest,
8393 ) -> Result<()>;
8394 async fn set_line_in_level(&self, request: audio_in::SetLineInLevelRequest) -> Result<()>;
8395 async fn start_transmission_to_group(
8396 &self,
8397 request: audio_in::StartTransmissionToGroupRequest,
8398 ) -> Result<audio_in::StartTransmissionToGroupResponse>;
8399 async fn stop_transmission_to_group(
8400 &self,
8401 request: audio_in::StopTransmissionToGroupRequest,
8402 ) -> Result<()>;
8403}
8404
8405#[allow(async_fn_in_trait)]
8406pub trait ConnectionManager {
8408 async fn get_current_connection_ids(
8409 &self,
8410 ) -> Result<connection_manager::GetCurrentConnectionIdsResponse>;
8411 async fn get_current_connection_info(
8412 &self,
8413 request: connection_manager::GetCurrentConnectionInfoRequest,
8414 ) -> Result<connection_manager::GetCurrentConnectionInfoResponse>;
8415 async fn get_protocol_info(&self) -> Result<connection_manager::GetProtocolInfoResponse>;
8416}
8417
8418#[allow(async_fn_in_trait)]
8419pub trait ContentDirectory {
8421 async fn browse(
8423 &self,
8424 request: content_directory::BrowseRequest,
8425 ) -> Result<content_directory::BrowseResponse>;
8426 async fn create_object(
8427 &self,
8428 request: content_directory::CreateObjectRequest,
8429 ) -> Result<content_directory::CreateObjectResponse>;
8430 async fn destroy_object(&self, request: content_directory::DestroyObjectRequest) -> Result<()>;
8431 async fn find_prefix(
8432 &self,
8433 request: content_directory::FindPrefixRequest,
8434 ) -> Result<content_directory::FindPrefixResponse>;
8435 async fn get_album_artist_display_option(
8437 &self,
8438 ) -> Result<content_directory::GetAlbumArtistDisplayOptionResponse>;
8439 async fn get_all_prefix_locations(
8440 &self,
8441 request: content_directory::GetAllPrefixLocationsRequest,
8442 ) -> Result<content_directory::GetAllPrefixLocationsResponse>;
8443 async fn get_browseable(&self) -> Result<content_directory::GetBrowseableResponse>;
8444 async fn get_last_index_change(&self) -> Result<content_directory::GetLastIndexChangeResponse>;
8445 async fn get_search_capabilities(
8446 &self,
8447 ) -> Result<content_directory::GetSearchCapabilitiesResponse>;
8448 async fn get_share_index_in_progress(
8449 &self,
8450 ) -> Result<content_directory::GetShareIndexInProgressResponse>;
8451 async fn get_sort_capabilities(&self)
8452 -> Result<content_directory::GetSortCapabilitiesResponse>;
8453 async fn get_system_update_id(&self) -> Result<content_directory::GetSystemUpdateIdResponse>;
8454 async fn refresh_share_index(
8456 &self,
8457 request: content_directory::RefreshShareIndexRequest,
8458 ) -> Result<()>;
8459 async fn request_resort(&self, request: content_directory::RequestResortRequest) -> Result<()>;
8460 async fn set_browseable(&self, request: content_directory::SetBrowseableRequest) -> Result<()>;
8461 async fn update_object(&self, request: content_directory::UpdateObjectRequest) -> Result<()>;
8462}
8463
8464#[allow(async_fn_in_trait)]
8465pub trait DeviceProperties {
8467 async fn add_bonded_zones(
8468 &self,
8469 request: device_properties::AddBondedZonesRequest,
8470 ) -> Result<()>;
8471 async fn add_ht_satellite(
8473 &self,
8474 request: device_properties::AddHtSatelliteRequest,
8475 ) -> Result<()>;
8476 async fn create_stereo_pair(
8478 &self,
8479 request: device_properties::CreateStereoPairRequest,
8480 ) -> Result<()>;
8481 async fn enter_config_mode(
8482 &self,
8483 request: device_properties::EnterConfigModeRequest,
8484 ) -> Result<device_properties::EnterConfigModeResponse>;
8485 async fn exit_config_mode(
8486 &self,
8487 request: device_properties::ExitConfigModeRequest,
8488 ) -> Result<()>;
8489 async fn get_autoplay_linked_zones(
8490 &self,
8491 request: device_properties::GetAutoplayLinkedZonesRequest,
8492 ) -> Result<device_properties::GetAutoplayLinkedZonesResponse>;
8493 async fn get_autoplay_room_uuid(
8494 &self,
8495 request: device_properties::GetAutoplayRoomUuidRequest,
8496 ) -> Result<device_properties::GetAutoplayRoomUuidResponse>;
8497 async fn get_autoplay_volume(
8498 &self,
8499 request: device_properties::GetAutoplayVolumeRequest,
8500 ) -> Result<device_properties::GetAutoplayVolumeResponse>;
8501 async fn get_button_lock_state(&self) -> Result<device_properties::GetButtonLockStateResponse>;
8503 async fn get_button_state(&self) -> Result<device_properties::GetButtonStateResponse>;
8504 async fn get_ht_forward_state(&self) -> Result<device_properties::GetHtForwardStateResponse>;
8505 async fn get_household_id(&self) -> Result<device_properties::GetHouseholdIdResponse>;
8506 async fn get_led_state(&self) -> Result<device_properties::GetLedStateResponse>;
8508 async fn get_use_autoplay_volume(
8509 &self,
8510 request: device_properties::GetUseAutoplayVolumeRequest,
8511 ) -> Result<device_properties::GetUseAutoplayVolumeResponse>;
8512 async fn get_zone_attributes(&self) -> Result<device_properties::GetZoneAttributesResponse>;
8513 async fn get_zone_info(&self) -> Result<device_properties::GetZoneInfoResponse>;
8515 async fn remove_bonded_zones(
8516 &self,
8517 request: device_properties::RemoveBondedZonesRequest,
8518 ) -> Result<()>;
8519 async fn remove_ht_satellite(
8521 &self,
8522 request: device_properties::RemoveHtSatelliteRequest,
8523 ) -> Result<()>;
8524 async fn room_detection_start_chirping(
8525 &self,
8526 request: device_properties::RoomDetectionStartChirpingRequest,
8527 ) -> Result<device_properties::RoomDetectionStartChirpingResponse>;
8528 async fn room_detection_stop_chirping(
8529 &self,
8530 request: device_properties::RoomDetectionStopChirpingRequest,
8531 ) -> Result<()>;
8532 async fn separate_stereo_pair(
8534 &self,
8535 request: device_properties::SeparateStereoPairRequest,
8536 ) -> Result<()>;
8537 async fn set_autoplay_linked_zones(
8538 &self,
8539 request: device_properties::SetAutoplayLinkedZonesRequest,
8540 ) -> Result<()>;
8541 async fn set_autoplay_room_uuid(
8542 &self,
8543 request: device_properties::SetAutoplayRoomUuidRequest,
8544 ) -> Result<()>;
8545 async fn set_autoplay_volume(
8546 &self,
8547 request: device_properties::SetAutoplayVolumeRequest,
8548 ) -> Result<()>;
8549 async fn set_button_lock_state(
8551 &self,
8552 request: device_properties::SetButtonLockStateRequest,
8553 ) -> Result<()>;
8554 async fn set_led_state(&self, request: device_properties::SetLedStateRequest) -> Result<()>;
8556 async fn set_use_autoplay_volume(
8557 &self,
8558 request: device_properties::SetUseAutoplayVolumeRequest,
8559 ) -> Result<()>;
8560 async fn set_zone_attributes(
8561 &self,
8562 request: device_properties::SetZoneAttributesRequest,
8563 ) -> Result<()>;
8564}
8565
8566#[allow(async_fn_in_trait)]
8567pub trait GroupManagement {
8569 async fn add_member(
8570 &self,
8571 request: group_management::AddMemberRequest,
8572 ) -> Result<group_management::AddMemberResponse>;
8573 async fn remove_member(&self, request: group_management::RemoveMemberRequest) -> Result<()>;
8574 async fn report_track_buffering_result(
8575 &self,
8576 request: group_management::ReportTrackBufferingResultRequest,
8577 ) -> Result<()>;
8578 async fn set_source_area_ids(
8579 &self,
8580 request: group_management::SetSourceAreaIdsRequest,
8581 ) -> Result<()>;
8582}
8583
8584#[allow(async_fn_in_trait)]
8585pub trait GroupRenderingControl {
8587 async fn get_group_mute(
8589 &self,
8590 request: group_rendering_control::GetGroupMuteRequest,
8591 ) -> Result<group_rendering_control::GetGroupMuteResponse>;
8592 async fn get_group_volume(
8594 &self,
8595 request: group_rendering_control::GetGroupVolumeRequest,
8596 ) -> Result<group_rendering_control::GetGroupVolumeResponse>;
8597 async fn set_group_mute(
8599 &self,
8600 request: group_rendering_control::SetGroupMuteRequest,
8601 ) -> Result<()>;
8602 async fn set_group_volume(
8604 &self,
8605 request: group_rendering_control::SetGroupVolumeRequest,
8606 ) -> Result<()>;
8607 async fn set_relative_group_volume(
8609 &self,
8610 request: group_rendering_control::SetRelativeGroupVolumeRequest,
8611 ) -> Result<group_rendering_control::SetRelativeGroupVolumeResponse>;
8612 async fn snapshot_group_volume(
8614 &self,
8615 request: group_rendering_control::SnapshotGroupVolumeRequest,
8616 ) -> Result<()>;
8617}
8618
8619#[allow(async_fn_in_trait)]
8620pub trait HTControl {
8622 async fn commit_learned_ir_codes(
8623 &self,
8624 request: ht_control::CommitLearnedIrCodesRequest,
8625 ) -> Result<()>;
8626 async fn get_ir_repeater_state(&self) -> Result<ht_control::GetIrRepeaterStateResponse>;
8627 async fn get_led_feedback_state(&self) -> Result<ht_control::GetLedFeedbackStateResponse>;
8628 async fn identify_ir_remote(&self, request: ht_control::IdentifyIrRemoteRequest) -> Result<()>;
8629 async fn is_remote_configured(&self) -> Result<ht_control::IsRemoteConfiguredResponse>;
8630 async fn learn_ir_code(&self, request: ht_control::LearnIrCodeRequest) -> Result<()>;
8631 async fn set_ir_repeater_state(
8632 &self,
8633 request: ht_control::SetIrRepeaterStateRequest,
8634 ) -> Result<()>;
8635 async fn set_led_feedback_state(
8636 &self,
8637 request: ht_control::SetLedFeedbackStateRequest,
8638 ) -> Result<()>;
8639}
8640
8641#[allow(async_fn_in_trait)]
8642pub trait MusicServices {
8644 async fn get_session_id(
8645 &self,
8646 request: music_services::GetSessionIdRequest,
8647 ) -> Result<music_services::GetSessionIdResponse>;
8648 async fn list_available_services(
8650 &self,
8651 ) -> Result<music_services::ListAvailableServicesResponse>;
8652 async fn update_available_services(&self) -> Result<()>;
8653}
8654
8655#[allow(async_fn_in_trait)]
8656pub trait QPlay {
8658 async fn q_play_auth(
8659 &self,
8660 request: q_play::QPlayAuthRequest,
8661 ) -> Result<q_play::QPlayAuthResponse>;
8662}
8663
8664#[allow(async_fn_in_trait)]
8665pub trait Queue {
8667 async fn add_multiple_uris(
8668 &self,
8669 request: queue::AddMultipleUrisRequest,
8670 ) -> Result<queue::AddMultipleUrisResponse>;
8671 async fn add_uri(&self, request: queue::AddUriRequest) -> Result<queue::AddUriResponse>;
8672 async fn attach_queue(
8673 &self,
8674 request: queue::AttachQueueRequest,
8675 ) -> Result<queue::AttachQueueResponse>;
8676 async fn backup(&self) -> Result<()>;
8677 async fn browse(&self, request: queue::BrowseRequest) -> Result<queue::BrowseResponse>;
8678 async fn create_queue(
8679 &self,
8680 request: queue::CreateQueueRequest,
8681 ) -> Result<queue::CreateQueueResponse>;
8682 async fn remove_all_tracks(
8683 &self,
8684 request: queue::RemoveAllTracksRequest,
8685 ) -> Result<queue::RemoveAllTracksResponse>;
8686 async fn remove_track_range(
8687 &self,
8688 request: queue::RemoveTrackRangeRequest,
8689 ) -> Result<queue::RemoveTrackRangeResponse>;
8690 async fn reorder_tracks(
8691 &self,
8692 request: queue::ReorderTracksRequest,
8693 ) -> Result<queue::ReorderTracksResponse>;
8694 async fn replace_all_tracks(
8695 &self,
8696 request: queue::ReplaceAllTracksRequest,
8697 ) -> Result<queue::ReplaceAllTracksResponse>;
8698 async fn save_as_sonos_playlist(
8699 &self,
8700 request: queue::SaveAsSonosPlaylistRequest,
8701 ) -> Result<queue::SaveAsSonosPlaylistResponse>;
8702}
8703
8704#[allow(async_fn_in_trait)]
8705pub trait RenderingControl {
8707 async fn get_bass(
8709 &self,
8710 request: rendering_control::GetBassRequest,
8711 ) -> Result<rendering_control::GetBassResponse>;
8712 async fn get_eq(
8714 &self,
8715 request: rendering_control::GetEqRequest,
8716 ) -> Result<rendering_control::GetEqResponse>;
8717 async fn get_headphone_connected(
8718 &self,
8719 request: rendering_control::GetHeadphoneConnectedRequest,
8720 ) -> Result<rendering_control::GetHeadphoneConnectedResponse>;
8721 async fn get_loudness(
8723 &self,
8724 request: rendering_control::GetLoudnessRequest,
8725 ) -> Result<rendering_control::GetLoudnessResponse>;
8726 async fn get_mute(
8727 &self,
8728 request: rendering_control::GetMuteRequest,
8729 ) -> Result<rendering_control::GetMuteResponse>;
8730 async fn get_output_fixed(
8731 &self,
8732 request: rendering_control::GetOutputFixedRequest,
8733 ) -> Result<rendering_control::GetOutputFixedResponse>;
8734 async fn get_room_calibration_status(
8735 &self,
8736 request: rendering_control::GetRoomCalibrationStatusRequest,
8737 ) -> Result<rendering_control::GetRoomCalibrationStatusResponse>;
8738 async fn get_supports_output_fixed(
8739 &self,
8740 request: rendering_control::GetSupportsOutputFixedRequest,
8741 ) -> Result<rendering_control::GetSupportsOutputFixedResponse>;
8742 async fn get_treble(
8744 &self,
8745 request: rendering_control::GetTrebleRequest,
8746 ) -> Result<rendering_control::GetTrebleResponse>;
8747 async fn get_volume(
8749 &self,
8750 request: rendering_control::GetVolumeRequest,
8751 ) -> Result<rendering_control::GetVolumeResponse>;
8752 async fn get_volume_db(
8753 &self,
8754 request: rendering_control::GetVolumeDbRequest,
8755 ) -> Result<rendering_control::GetVolumeDbResponse>;
8756 async fn get_volume_db_range(
8757 &self,
8758 request: rendering_control::GetVolumeDbRangeRequest,
8759 ) -> Result<rendering_control::GetVolumeDbRangeResponse>;
8760 async fn ramp_to_volume(
8761 &self,
8762 request: rendering_control::RampToVolumeRequest,
8763 ) -> Result<rendering_control::RampToVolumeResponse>;
8764 async fn reset_basic_eq(
8765 &self,
8766 request: rendering_control::ResetBasicEqRequest,
8767 ) -> Result<rendering_control::ResetBasicEqResponse>;
8768 async fn reset_ext_eq(&self, request: rendering_control::ResetExtEqRequest) -> Result<()>;
8769 async fn restore_volume_prior_to_ramp(
8770 &self,
8771 request: rendering_control::RestoreVolumePriorToRampRequest,
8772 ) -> Result<()>;
8773 async fn set_bass(&self, request: rendering_control::SetBassRequest) -> Result<()>;
8775 async fn set_channel_map(&self, request: rendering_control::SetChannelMapRequest)
8776 -> Result<()>;
8777 async fn set_eq(&self, request: rendering_control::SetEqRequest) -> Result<()>;
8779 async fn set_loudness(&self, request: rendering_control::SetLoudnessRequest) -> Result<()>;
8781 async fn set_mute(&self, request: rendering_control::SetMuteRequest) -> Result<()>;
8782 async fn set_output_fixed(
8783 &self,
8784 request: rendering_control::SetOutputFixedRequest,
8785 ) -> Result<()>;
8786 async fn set_relative_volume(
8787 &self,
8788 request: rendering_control::SetRelativeVolumeRequest,
8789 ) -> Result<rendering_control::SetRelativeVolumeResponse>;
8790 async fn set_room_calibration_status(
8791 &self,
8792 request: rendering_control::SetRoomCalibrationStatusRequest,
8793 ) -> Result<()>;
8794 async fn set_room_calibration_x(
8795 &self,
8796 request: rendering_control::SetRoomCalibrationXRequest,
8797 ) -> Result<()>;
8798 async fn set_treble(&self, request: rendering_control::SetTrebleRequest) -> Result<()>;
8800 async fn set_volume(&self, request: rendering_control::SetVolumeRequest) -> Result<()>;
8801 async fn set_volume_db(&self, request: rendering_control::SetVolumeDbRequest) -> Result<()>;
8802}
8803
8804#[allow(async_fn_in_trait)]
8805pub trait SystemProperties {
8807 async fn add_account_x(
8808 &self,
8809 request: system_properties::AddAccountXRequest,
8810 ) -> Result<system_properties::AddAccountXResponse>;
8811 async fn add_o_auth_account_x(
8812 &self,
8813 request: system_properties::AddOAuthAccountXRequest,
8814 ) -> Result<system_properties::AddOAuthAccountXResponse>;
8815 async fn do_post_update_tasks(&self) -> Result<()>;
8816 async fn edit_account_md(&self, request: system_properties::EditAccountMdRequest)
8817 -> Result<()>;
8818 async fn edit_account_password_x(
8819 &self,
8820 request: system_properties::EditAccountPasswordXRequest,
8821 ) -> Result<()>;
8822 async fn enable_rdm(&self, request: system_properties::EnableRdmRequest) -> Result<()>;
8823 async fn get_rdm(&self) -> Result<system_properties::GetRdmResponse>;
8824 async fn get_string(
8826 &self,
8827 request: system_properties::GetStringRequest,
8828 ) -> Result<system_properties::GetStringResponse>;
8829 async fn get_web_code(
8830 &self,
8831 request: system_properties::GetWebCodeRequest,
8832 ) -> Result<system_properties::GetWebCodeResponse>;
8833 async fn provision_credentialed_trial_account_x(
8834 &self,
8835 request: system_properties::ProvisionCredentialedTrialAccountXRequest,
8836 ) -> Result<system_properties::ProvisionCredentialedTrialAccountXResponse>;
8837 async fn refresh_account_credentials_x(
8838 &self,
8839 request: system_properties::RefreshAccountCredentialsXRequest,
8840 ) -> Result<()>;
8841 async fn remove(&self, request: system_properties::RemoveRequest) -> Result<()>;
8843 async fn remove_account(&self, request: system_properties::RemoveAccountRequest) -> Result<()>;
8844 async fn replace_account_x(
8845 &self,
8846 request: system_properties::ReplaceAccountXRequest,
8847 ) -> Result<system_properties::ReplaceAccountXResponse>;
8848 async fn reset_third_party_credentials(&self) -> Result<()>;
8849 async fn set_account_nickname_x(
8850 &self,
8851 request: system_properties::SetAccountNicknameXRequest,
8852 ) -> Result<()>;
8853 async fn set_string(&self, request: system_properties::SetStringRequest) -> Result<()>;
8855}
8856
8857#[allow(async_fn_in_trait)]
8858pub trait VirtualLineIn {
8859 async fn next(&self, request: virtual_line_in::NextRequest) -> Result<()>;
8860 async fn pause(&self, request: virtual_line_in::PauseRequest) -> Result<()>;
8861 async fn play(&self, request: virtual_line_in::PlayRequest) -> Result<()>;
8862 async fn previous(&self, request: virtual_line_in::PreviousRequest) -> Result<()>;
8863 async fn set_volume(&self, request: virtual_line_in::SetVolumeRequest) -> Result<()>;
8864 async fn start_transmission(
8865 &self,
8866 request: virtual_line_in::StartTransmissionRequest,
8867 ) -> Result<virtual_line_in::StartTransmissionResponse>;
8868 async fn stop(&self, request: virtual_line_in::StopRequest) -> Result<()>;
8869 async fn stop_transmission(
8870 &self,
8871 request: virtual_line_in::StopTransmissionRequest,
8872 ) -> Result<()>;
8873}
8874
8875#[allow(async_fn_in_trait)]
8876pub trait ZoneGroupTopology {
8878 async fn begin_software_update(
8879 &self,
8880 request: zone_group_topology::BeginSoftwareUpdateRequest,
8881 ) -> Result<()>;
8882 async fn check_for_update(
8883 &self,
8884 request: zone_group_topology::CheckForUpdateRequest,
8885 ) -> Result<zone_group_topology::CheckForUpdateResponse>;
8886 async fn get_zone_group_attributes(
8888 &self,
8889 ) -> Result<zone_group_topology::GetZoneGroupAttributesResponse>;
8890 async fn get_zone_group_state(&self) -> Result<zone_group_topology::GetZoneGroupStateResponse>;
8892 async fn register_mobile_device(
8893 &self,
8894 request: zone_group_topology::RegisterMobileDeviceRequest,
8895 ) -> Result<()>;
8896 async fn report_alarm_started_running(&self) -> Result<()>;
8897 async fn report_unresponsive_device(
8898 &self,
8899 request: zone_group_topology::ReportUnresponsiveDeviceRequest,
8900 ) -> Result<()>;
8901 async fn submit_diagnostics(
8902 &self,
8903 request: zone_group_topology::SubmitDiagnosticsRequest,
8904 ) -> Result<zone_group_topology::SubmitDiagnosticsResponse>;
8905}
8906
8907impl AVTransport for SonosDevice {
8908 async fn add_multiple_uris_to_queue(
8909 &self,
8910 request: av_transport::AddMultipleUrisToQueueRequest,
8911 ) -> Result<av_transport::AddMultipleUrisToQueueResponse> {
8912 self.action(
8913 &av_transport::SERVICE_TYPE,
8914 "AddMultipleURIsToQueue",
8915 request,
8916 )
8917 .await
8918 }
8919
8920 async fn add_uri_to_queue(
8921 &self,
8922 request: av_transport::AddUriToQueueRequest,
8923 ) -> Result<av_transport::AddUriToQueueResponse> {
8924 self.action(&av_transport::SERVICE_TYPE, "AddURIToQueue", request)
8925 .await
8926 }
8927
8928 async fn add_uri_to_saved_queue(
8929 &self,
8930 request: av_transport::AddUriToSavedQueueRequest,
8931 ) -> Result<av_transport::AddUriToSavedQueueResponse> {
8932 self.action(&av_transport::SERVICE_TYPE, "AddURIToSavedQueue", request)
8933 .await
8934 }
8935
8936 async fn backup_queue(&self, request: av_transport::BackupQueueRequest) -> Result<()> {
8937 self.action(&av_transport::SERVICE_TYPE, "BackupQueue", request)
8938 .await
8939 }
8940
8941 async fn become_coordinator_of_standalone_group(
8942 &self,
8943 request: av_transport::BecomeCoordinatorOfStandaloneGroupRequest,
8944 ) -> Result<av_transport::BecomeCoordinatorOfStandaloneGroupResponse> {
8945 self.action(
8946 &av_transport::SERVICE_TYPE,
8947 "BecomeCoordinatorOfStandaloneGroup",
8948 request,
8949 )
8950 .await
8951 }
8952
8953 async fn become_group_coordinator(
8954 &self,
8955 request: av_transport::BecomeGroupCoordinatorRequest,
8956 ) -> Result<()> {
8957 self.action(
8958 &av_transport::SERVICE_TYPE,
8959 "BecomeGroupCoordinator",
8960 request,
8961 )
8962 .await
8963 }
8964
8965 async fn become_group_coordinator_and_source(
8966 &self,
8967 request: av_transport::BecomeGroupCoordinatorAndSourceRequest,
8968 ) -> Result<()> {
8969 self.action(
8970 &av_transport::SERVICE_TYPE,
8971 "BecomeGroupCoordinatorAndSource",
8972 request,
8973 )
8974 .await
8975 }
8976
8977 async fn change_coordinator(
8978 &self,
8979 request: av_transport::ChangeCoordinatorRequest,
8980 ) -> Result<()> {
8981 self.action(&av_transport::SERVICE_TYPE, "ChangeCoordinator", request)
8982 .await
8983 }
8984
8985 async fn change_transport_settings(
8986 &self,
8987 request: av_transport::ChangeTransportSettingsRequest,
8988 ) -> Result<()> {
8989 self.action(
8990 &av_transport::SERVICE_TYPE,
8991 "ChangeTransportSettings",
8992 request,
8993 )
8994 .await
8995 }
8996
8997 async fn configure_sleep_timer(
8998 &self,
8999 request: av_transport::ConfigureSleepTimerRequest,
9000 ) -> Result<()> {
9001 self.action(&av_transport::SERVICE_TYPE, "ConfigureSleepTimer", request)
9002 .await
9003 }
9004
9005 async fn create_saved_queue(
9006 &self,
9007 request: av_transport::CreateSavedQueueRequest,
9008 ) -> Result<av_transport::CreateSavedQueueResponse> {
9009 self.action(&av_transport::SERVICE_TYPE, "CreateSavedQueue", request)
9010 .await
9011 }
9012
9013 async fn delegate_group_coordination_to(
9014 &self,
9015 request: av_transport::DelegateGroupCoordinationToRequest,
9016 ) -> Result<()> {
9017 self.action(
9018 &av_transport::SERVICE_TYPE,
9019 "DelegateGroupCoordinationTo",
9020 request,
9021 )
9022 .await
9023 }
9024
9025 async fn end_direct_control_session(
9026 &self,
9027 request: av_transport::EndDirectControlSessionRequest,
9028 ) -> Result<()> {
9029 self.action(
9030 &av_transport::SERVICE_TYPE,
9031 "EndDirectControlSession",
9032 request,
9033 )
9034 .await
9035 }
9036
9037 async fn get_crossfade_mode(
9038 &self,
9039 request: av_transport::GetCrossfadeModeRequest,
9040 ) -> Result<av_transport::GetCrossfadeModeResponse> {
9041 self.action(&av_transport::SERVICE_TYPE, "GetCrossfadeMode", request)
9042 .await
9043 }
9044
9045 async fn get_current_transport_actions(
9046 &self,
9047 request: av_transport::GetCurrentTransportActionsRequest,
9048 ) -> Result<av_transport::GetCurrentTransportActionsResponse> {
9049 self.action(
9050 &av_transport::SERVICE_TYPE,
9051 "GetCurrentTransportActions",
9052 request,
9053 )
9054 .await
9055 }
9056
9057 async fn get_device_capabilities(
9058 &self,
9059 request: av_transport::GetDeviceCapabilitiesRequest,
9060 ) -> Result<av_transport::GetDeviceCapabilitiesResponse> {
9061 self.action(
9062 &av_transport::SERVICE_TYPE,
9063 "GetDeviceCapabilities",
9064 request,
9065 )
9066 .await
9067 }
9068
9069 async fn get_media_info(
9070 &self,
9071 request: av_transport::GetMediaInfoRequest,
9072 ) -> Result<av_transport::GetMediaInfoResponse> {
9073 self.action(&av_transport::SERVICE_TYPE, "GetMediaInfo", request)
9074 .await
9075 }
9076
9077 async fn get_position_info(
9078 &self,
9079 request: av_transport::GetPositionInfoRequest,
9080 ) -> Result<av_transport::GetPositionInfoResponse> {
9081 self.action(&av_transport::SERVICE_TYPE, "GetPositionInfo", request)
9082 .await
9083 }
9084
9085 async fn get_remaining_sleep_timer_duration(
9086 &self,
9087 request: av_transport::GetRemainingSleepTimerDurationRequest,
9088 ) -> Result<av_transport::GetRemainingSleepTimerDurationResponse> {
9089 self.action(
9090 &av_transport::SERVICE_TYPE,
9091 "GetRemainingSleepTimerDuration",
9092 request,
9093 )
9094 .await
9095 }
9096
9097 async fn get_running_alarm_properties(
9098 &self,
9099 request: av_transport::GetRunningAlarmPropertiesRequest,
9100 ) -> Result<av_transport::GetRunningAlarmPropertiesResponse> {
9101 self.action(
9102 &av_transport::SERVICE_TYPE,
9103 "GetRunningAlarmProperties",
9104 request,
9105 )
9106 .await
9107 }
9108
9109 async fn get_transport_info(
9110 &self,
9111 request: av_transport::GetTransportInfoRequest,
9112 ) -> Result<av_transport::GetTransportInfoResponse> {
9113 self.action(&av_transport::SERVICE_TYPE, "GetTransportInfo", request)
9114 .await
9115 }
9116
9117 async fn get_transport_settings(
9118 &self,
9119 request: av_transport::GetTransportSettingsRequest,
9120 ) -> Result<av_transport::GetTransportSettingsResponse> {
9121 self.action(&av_transport::SERVICE_TYPE, "GetTransportSettings", request)
9122 .await
9123 }
9124
9125 async fn next(&self, request: av_transport::NextRequest) -> Result<()> {
9126 self.action(&av_transport::SERVICE_TYPE, "Next", request)
9127 .await
9128 }
9129
9130 async fn notify_deleted_uri(
9131 &self,
9132 request: av_transport::NotifyDeletedUriRequest,
9133 ) -> Result<()> {
9134 self.action(&av_transport::SERVICE_TYPE, "NotifyDeletedURI", request)
9135 .await
9136 }
9137
9138 async fn pause(&self, request: av_transport::PauseRequest) -> Result<()> {
9139 self.action(&av_transport::SERVICE_TYPE, "Pause", request)
9140 .await
9141 }
9142
9143 async fn play(&self, request: av_transport::PlayRequest) -> Result<()> {
9144 self.action(&av_transport::SERVICE_TYPE, "Play", request)
9145 .await
9146 }
9147
9148 async fn previous(&self, request: av_transport::PreviousRequest) -> Result<()> {
9149 self.action(&av_transport::SERVICE_TYPE, "Previous", request)
9150 .await
9151 }
9152
9153 async fn remove_all_tracks_from_queue(
9154 &self,
9155 request: av_transport::RemoveAllTracksFromQueueRequest,
9156 ) -> Result<()> {
9157 self.action(
9158 &av_transport::SERVICE_TYPE,
9159 "RemoveAllTracksFromQueue",
9160 request,
9161 )
9162 .await
9163 }
9164
9165 async fn remove_track_from_queue(
9166 &self,
9167 request: av_transport::RemoveTrackFromQueueRequest,
9168 ) -> Result<()> {
9169 self.action(&av_transport::SERVICE_TYPE, "RemoveTrackFromQueue", request)
9170 .await
9171 }
9172
9173 async fn remove_track_range_from_queue(
9174 &self,
9175 request: av_transport::RemoveTrackRangeFromQueueRequest,
9176 ) -> Result<av_transport::RemoveTrackRangeFromQueueResponse> {
9177 self.action(
9178 &av_transport::SERVICE_TYPE,
9179 "RemoveTrackRangeFromQueue",
9180 request,
9181 )
9182 .await
9183 }
9184
9185 async fn reorder_tracks_in_queue(
9186 &self,
9187 request: av_transport::ReorderTracksInQueueRequest,
9188 ) -> Result<()> {
9189 self.action(&av_transport::SERVICE_TYPE, "ReorderTracksInQueue", request)
9190 .await
9191 }
9192
9193 async fn reorder_tracks_in_saved_queue(
9194 &self,
9195 request: av_transport::ReorderTracksInSavedQueueRequest,
9196 ) -> Result<av_transport::ReorderTracksInSavedQueueResponse> {
9197 self.action(
9198 &av_transport::SERVICE_TYPE,
9199 "ReorderTracksInSavedQueue",
9200 request,
9201 )
9202 .await
9203 }
9204
9205 async fn run_alarm(&self, request: av_transport::RunAlarmRequest) -> Result<()> {
9206 self.action(&av_transport::SERVICE_TYPE, "RunAlarm", request)
9207 .await
9208 }
9209
9210 async fn save_queue(
9211 &self,
9212 request: av_transport::SaveQueueRequest,
9213 ) -> Result<av_transport::SaveQueueResponse> {
9214 self.action(&av_transport::SERVICE_TYPE, "SaveQueue", request)
9215 .await
9216 }
9217
9218 async fn seek(&self, request: av_transport::SeekRequest) -> Result<()> {
9219 self.action(&av_transport::SERVICE_TYPE, "Seek", request)
9220 .await
9221 }
9222
9223 async fn set_av_transport_uri(
9224 &self,
9225 request: av_transport::SetAvTransportUriRequest,
9226 ) -> Result<()> {
9227 self.action(&av_transport::SERVICE_TYPE, "SetAVTransportURI", request)
9228 .await
9229 }
9230
9231 async fn set_crossfade_mode(
9232 &self,
9233 request: av_transport::SetCrossfadeModeRequest,
9234 ) -> Result<()> {
9235 self.action(&av_transport::SERVICE_TYPE, "SetCrossfadeMode", request)
9236 .await
9237 }
9238
9239 async fn set_next_av_transport_uri(
9240 &self,
9241 request: av_transport::SetNextAvTransportUriRequest,
9242 ) -> Result<()> {
9243 self.action(
9244 &av_transport::SERVICE_TYPE,
9245 "SetNextAVTransportURI",
9246 request,
9247 )
9248 .await
9249 }
9250
9251 async fn set_play_mode(&self, request: av_transport::SetPlayModeRequest) -> Result<()> {
9252 self.action(&av_transport::SERVICE_TYPE, "SetPlayMode", request)
9253 .await
9254 }
9255
9256 async fn snooze_alarm(&self, request: av_transport::SnoozeAlarmRequest) -> Result<()> {
9257 self.action(&av_transport::SERVICE_TYPE, "SnoozeAlarm", request)
9258 .await
9259 }
9260
9261 async fn start_autoplay(&self, request: av_transport::StartAutoplayRequest) -> Result<()> {
9262 self.action(&av_transport::SERVICE_TYPE, "StartAutoplay", request)
9263 .await
9264 }
9265
9266 async fn stop(&self, request: av_transport::StopRequest) -> Result<()> {
9267 self.action(&av_transport::SERVICE_TYPE, "Stop", request)
9268 .await
9269 }
9270}
9271
9272impl AlarmClock for SonosDevice {
9273 async fn create_alarm(
9274 &self,
9275 request: alarm_clock::CreateAlarmRequest,
9276 ) -> Result<alarm_clock::CreateAlarmResponse> {
9277 self.action(&alarm_clock::SERVICE_TYPE, "CreateAlarm", request)
9278 .await
9279 }
9280
9281 async fn destroy_alarm(&self, request: alarm_clock::DestroyAlarmRequest) -> Result<()> {
9282 self.action(&alarm_clock::SERVICE_TYPE, "DestroyAlarm", request)
9283 .await
9284 }
9285
9286 async fn get_daily_index_refresh_time(
9287 &self,
9288 ) -> Result<alarm_clock::GetDailyIndexRefreshTimeResponse> {
9289 self.action(
9290 &alarm_clock::SERVICE_TYPE,
9291 "GetDailyIndexRefreshTime",
9292 crate::soap::Unit {},
9293 )
9294 .await
9295 }
9296
9297 async fn get_format(&self) -> Result<alarm_clock::GetFormatResponse> {
9298 self.action(
9299 &alarm_clock::SERVICE_TYPE,
9300 "GetFormat",
9301 crate::soap::Unit {},
9302 )
9303 .await
9304 }
9305
9306 async fn get_household_time_at_stamp(
9307 &self,
9308 request: alarm_clock::GetHouseholdTimeAtStampRequest,
9309 ) -> Result<alarm_clock::GetHouseholdTimeAtStampResponse> {
9310 self.action(
9311 &alarm_clock::SERVICE_TYPE,
9312 "GetHouseholdTimeAtStamp",
9313 request,
9314 )
9315 .await
9316 }
9317
9318 async fn get_time_now(&self) -> Result<alarm_clock::GetTimeNowResponse> {
9319 self.action(
9320 &alarm_clock::SERVICE_TYPE,
9321 "GetTimeNow",
9322 crate::soap::Unit {},
9323 )
9324 .await
9325 }
9326
9327 async fn get_time_server(&self) -> Result<alarm_clock::GetTimeServerResponse> {
9328 self.action(
9329 &alarm_clock::SERVICE_TYPE,
9330 "GetTimeServer",
9331 crate::soap::Unit {},
9332 )
9333 .await
9334 }
9335
9336 async fn get_time_zone(&self) -> Result<alarm_clock::GetTimeZoneResponse> {
9337 self.action(
9338 &alarm_clock::SERVICE_TYPE,
9339 "GetTimeZone",
9340 crate::soap::Unit {},
9341 )
9342 .await
9343 }
9344
9345 async fn get_time_zone_and_rule(&self) -> Result<alarm_clock::GetTimeZoneAndRuleResponse> {
9346 self.action(
9347 &alarm_clock::SERVICE_TYPE,
9348 "GetTimeZoneAndRule",
9349 crate::soap::Unit {},
9350 )
9351 .await
9352 }
9353
9354 async fn get_time_zone_rule(
9355 &self,
9356 request: alarm_clock::GetTimeZoneRuleRequest,
9357 ) -> Result<alarm_clock::GetTimeZoneRuleResponse> {
9358 self.action(&alarm_clock::SERVICE_TYPE, "GetTimeZoneRule", request)
9359 .await
9360 }
9361
9362 async fn list_alarms(&self) -> Result<alarm_clock::ListAlarmsResponse> {
9363 self.action(
9364 &alarm_clock::SERVICE_TYPE,
9365 "ListAlarms",
9366 crate::soap::Unit {},
9367 )
9368 .await
9369 }
9370
9371 async fn set_daily_index_refresh_time(
9372 &self,
9373 request: alarm_clock::SetDailyIndexRefreshTimeRequest,
9374 ) -> Result<()> {
9375 self.action(
9376 &alarm_clock::SERVICE_TYPE,
9377 "SetDailyIndexRefreshTime",
9378 request,
9379 )
9380 .await
9381 }
9382
9383 async fn set_format(&self, request: alarm_clock::SetFormatRequest) -> Result<()> {
9384 self.action(&alarm_clock::SERVICE_TYPE, "SetFormat", request)
9385 .await
9386 }
9387
9388 async fn set_time_now(&self, request: alarm_clock::SetTimeNowRequest) -> Result<()> {
9389 self.action(&alarm_clock::SERVICE_TYPE, "SetTimeNow", request)
9390 .await
9391 }
9392
9393 async fn set_time_server(&self, request: alarm_clock::SetTimeServerRequest) -> Result<()> {
9394 self.action(&alarm_clock::SERVICE_TYPE, "SetTimeServer", request)
9395 .await
9396 }
9397
9398 async fn set_time_zone(&self, request: alarm_clock::SetTimeZoneRequest) -> Result<()> {
9399 self.action(&alarm_clock::SERVICE_TYPE, "SetTimeZone", request)
9400 .await
9401 }
9402
9403 async fn update_alarm(&self, request: alarm_clock::UpdateAlarmRequest) -> Result<()> {
9404 self.action(&alarm_clock::SERVICE_TYPE, "UpdateAlarm", request)
9405 .await
9406 }
9407}
9408
9409impl AudioIn for SonosDevice {
9410 async fn get_audio_input_attributes(
9411 &self,
9412 ) -> Result<audio_in::GetAudioInputAttributesResponse> {
9413 self.action(
9414 &audio_in::SERVICE_TYPE,
9415 "GetAudioInputAttributes",
9416 crate::soap::Unit {},
9417 )
9418 .await
9419 }
9420
9421 async fn get_line_in_level(&self) -> Result<audio_in::GetLineInLevelResponse> {
9422 self.action(
9423 &audio_in::SERVICE_TYPE,
9424 "GetLineInLevel",
9425 crate::soap::Unit {},
9426 )
9427 .await
9428 }
9429
9430 async fn select_audio(&self, request: audio_in::SelectAudioRequest) -> Result<()> {
9431 self.action(&audio_in::SERVICE_TYPE, "SelectAudio", request)
9432 .await
9433 }
9434
9435 async fn set_audio_input_attributes(
9436 &self,
9437 request: audio_in::SetAudioInputAttributesRequest,
9438 ) -> Result<()> {
9439 self.action(&audio_in::SERVICE_TYPE, "SetAudioInputAttributes", request)
9440 .await
9441 }
9442
9443 async fn set_line_in_level(&self, request: audio_in::SetLineInLevelRequest) -> Result<()> {
9444 self.action(&audio_in::SERVICE_TYPE, "SetLineInLevel", request)
9445 .await
9446 }
9447
9448 async fn start_transmission_to_group(
9449 &self,
9450 request: audio_in::StartTransmissionToGroupRequest,
9451 ) -> Result<audio_in::StartTransmissionToGroupResponse> {
9452 self.action(&audio_in::SERVICE_TYPE, "StartTransmissionToGroup", request)
9453 .await
9454 }
9455
9456 async fn stop_transmission_to_group(
9457 &self,
9458 request: audio_in::StopTransmissionToGroupRequest,
9459 ) -> Result<()> {
9460 self.action(&audio_in::SERVICE_TYPE, "StopTransmissionToGroup", request)
9461 .await
9462 }
9463}
9464
9465impl ConnectionManager for SonosDevice {
9466 async fn get_current_connection_ids(
9467 &self,
9468 ) -> Result<connection_manager::GetCurrentConnectionIdsResponse> {
9469 self.action(
9470 &connection_manager::SERVICE_TYPE,
9471 "GetCurrentConnectionIDs",
9472 crate::soap::Unit {},
9473 )
9474 .await
9475 }
9476
9477 async fn get_current_connection_info(
9478 &self,
9479 request: connection_manager::GetCurrentConnectionInfoRequest,
9480 ) -> Result<connection_manager::GetCurrentConnectionInfoResponse> {
9481 self.action(
9482 &connection_manager::SERVICE_TYPE,
9483 "GetCurrentConnectionInfo",
9484 request,
9485 )
9486 .await
9487 }
9488
9489 async fn get_protocol_info(&self) -> Result<connection_manager::GetProtocolInfoResponse> {
9490 self.action(
9491 &connection_manager::SERVICE_TYPE,
9492 "GetProtocolInfo",
9493 crate::soap::Unit {},
9494 )
9495 .await
9496 }
9497}
9498
9499impl ContentDirectory for SonosDevice {
9500 async fn browse(
9501 &self,
9502 request: content_directory::BrowseRequest,
9503 ) -> Result<content_directory::BrowseResponse> {
9504 self.action(&content_directory::SERVICE_TYPE, "Browse", request)
9505 .await
9506 }
9507
9508 async fn create_object(
9509 &self,
9510 request: content_directory::CreateObjectRequest,
9511 ) -> Result<content_directory::CreateObjectResponse> {
9512 self.action(&content_directory::SERVICE_TYPE, "CreateObject", request)
9513 .await
9514 }
9515
9516 async fn destroy_object(&self, request: content_directory::DestroyObjectRequest) -> Result<()> {
9517 self.action(&content_directory::SERVICE_TYPE, "DestroyObject", request)
9518 .await
9519 }
9520
9521 async fn find_prefix(
9522 &self,
9523 request: content_directory::FindPrefixRequest,
9524 ) -> Result<content_directory::FindPrefixResponse> {
9525 self.action(&content_directory::SERVICE_TYPE, "FindPrefix", request)
9526 .await
9527 }
9528
9529 async fn get_album_artist_display_option(
9530 &self,
9531 ) -> Result<content_directory::GetAlbumArtistDisplayOptionResponse> {
9532 self.action(
9533 &content_directory::SERVICE_TYPE,
9534 "GetAlbumArtistDisplayOption",
9535 crate::soap::Unit {},
9536 )
9537 .await
9538 }
9539
9540 async fn get_all_prefix_locations(
9541 &self,
9542 request: content_directory::GetAllPrefixLocationsRequest,
9543 ) -> Result<content_directory::GetAllPrefixLocationsResponse> {
9544 self.action(
9545 &content_directory::SERVICE_TYPE,
9546 "GetAllPrefixLocations",
9547 request,
9548 )
9549 .await
9550 }
9551
9552 async fn get_browseable(&self) -> Result<content_directory::GetBrowseableResponse> {
9553 self.action(
9554 &content_directory::SERVICE_TYPE,
9555 "GetBrowseable",
9556 crate::soap::Unit {},
9557 )
9558 .await
9559 }
9560
9561 async fn get_last_index_change(&self) -> Result<content_directory::GetLastIndexChangeResponse> {
9562 self.action(
9563 &content_directory::SERVICE_TYPE,
9564 "GetLastIndexChange",
9565 crate::soap::Unit {},
9566 )
9567 .await
9568 }
9569
9570 async fn get_search_capabilities(
9571 &self,
9572 ) -> Result<content_directory::GetSearchCapabilitiesResponse> {
9573 self.action(
9574 &content_directory::SERVICE_TYPE,
9575 "GetSearchCapabilities",
9576 crate::soap::Unit {},
9577 )
9578 .await
9579 }
9580
9581 async fn get_share_index_in_progress(
9582 &self,
9583 ) -> Result<content_directory::GetShareIndexInProgressResponse> {
9584 self.action(
9585 &content_directory::SERVICE_TYPE,
9586 "GetShareIndexInProgress",
9587 crate::soap::Unit {},
9588 )
9589 .await
9590 }
9591
9592 async fn get_sort_capabilities(
9593 &self,
9594 ) -> Result<content_directory::GetSortCapabilitiesResponse> {
9595 self.action(
9596 &content_directory::SERVICE_TYPE,
9597 "GetSortCapabilities",
9598 crate::soap::Unit {},
9599 )
9600 .await
9601 }
9602
9603 async fn get_system_update_id(&self) -> Result<content_directory::GetSystemUpdateIdResponse> {
9604 self.action(
9605 &content_directory::SERVICE_TYPE,
9606 "GetSystemUpdateID",
9607 crate::soap::Unit {},
9608 )
9609 .await
9610 }
9611
9612 async fn refresh_share_index(
9613 &self,
9614 request: content_directory::RefreshShareIndexRequest,
9615 ) -> Result<()> {
9616 self.action(
9617 &content_directory::SERVICE_TYPE,
9618 "RefreshShareIndex",
9619 request,
9620 )
9621 .await
9622 }
9623
9624 async fn request_resort(&self, request: content_directory::RequestResortRequest) -> Result<()> {
9625 self.action(&content_directory::SERVICE_TYPE, "RequestResort", request)
9626 .await
9627 }
9628
9629 async fn set_browseable(&self, request: content_directory::SetBrowseableRequest) -> Result<()> {
9630 self.action(&content_directory::SERVICE_TYPE, "SetBrowseable", request)
9631 .await
9632 }
9633
9634 async fn update_object(&self, request: content_directory::UpdateObjectRequest) -> Result<()> {
9635 self.action(&content_directory::SERVICE_TYPE, "UpdateObject", request)
9636 .await
9637 }
9638}
9639
9640impl DeviceProperties for SonosDevice {
9641 async fn add_bonded_zones(
9642 &self,
9643 request: device_properties::AddBondedZonesRequest,
9644 ) -> Result<()> {
9645 self.action(&device_properties::SERVICE_TYPE, "AddBondedZones", request)
9646 .await
9647 }
9648
9649 async fn add_ht_satellite(
9650 &self,
9651 request: device_properties::AddHtSatelliteRequest,
9652 ) -> Result<()> {
9653 self.action(&device_properties::SERVICE_TYPE, "AddHTSatellite", request)
9654 .await
9655 }
9656
9657 async fn create_stereo_pair(
9658 &self,
9659 request: device_properties::CreateStereoPairRequest,
9660 ) -> Result<()> {
9661 self.action(
9662 &device_properties::SERVICE_TYPE,
9663 "CreateStereoPair",
9664 request,
9665 )
9666 .await
9667 }
9668
9669 async fn enter_config_mode(
9670 &self,
9671 request: device_properties::EnterConfigModeRequest,
9672 ) -> Result<device_properties::EnterConfigModeResponse> {
9673 self.action(&device_properties::SERVICE_TYPE, "EnterConfigMode", request)
9674 .await
9675 }
9676
9677 async fn exit_config_mode(
9678 &self,
9679 request: device_properties::ExitConfigModeRequest,
9680 ) -> Result<()> {
9681 self.action(&device_properties::SERVICE_TYPE, "ExitConfigMode", request)
9682 .await
9683 }
9684
9685 async fn get_autoplay_linked_zones(
9686 &self,
9687 request: device_properties::GetAutoplayLinkedZonesRequest,
9688 ) -> Result<device_properties::GetAutoplayLinkedZonesResponse> {
9689 self.action(
9690 &device_properties::SERVICE_TYPE,
9691 "GetAutoplayLinkedZones",
9692 request,
9693 )
9694 .await
9695 }
9696
9697 async fn get_autoplay_room_uuid(
9698 &self,
9699 request: device_properties::GetAutoplayRoomUuidRequest,
9700 ) -> Result<device_properties::GetAutoplayRoomUuidResponse> {
9701 self.action(
9702 &device_properties::SERVICE_TYPE,
9703 "GetAutoplayRoomUUID",
9704 request,
9705 )
9706 .await
9707 }
9708
9709 async fn get_autoplay_volume(
9710 &self,
9711 request: device_properties::GetAutoplayVolumeRequest,
9712 ) -> Result<device_properties::GetAutoplayVolumeResponse> {
9713 self.action(
9714 &device_properties::SERVICE_TYPE,
9715 "GetAutoplayVolume",
9716 request,
9717 )
9718 .await
9719 }
9720
9721 async fn get_button_lock_state(&self) -> Result<device_properties::GetButtonLockStateResponse> {
9722 self.action(
9723 &device_properties::SERVICE_TYPE,
9724 "GetButtonLockState",
9725 crate::soap::Unit {},
9726 )
9727 .await
9728 }
9729
9730 async fn get_button_state(&self) -> Result<device_properties::GetButtonStateResponse> {
9731 self.action(
9732 &device_properties::SERVICE_TYPE,
9733 "GetButtonState",
9734 crate::soap::Unit {},
9735 )
9736 .await
9737 }
9738
9739 async fn get_ht_forward_state(&self) -> Result<device_properties::GetHtForwardStateResponse> {
9740 self.action(
9741 &device_properties::SERVICE_TYPE,
9742 "GetHTForwardState",
9743 crate::soap::Unit {},
9744 )
9745 .await
9746 }
9747
9748 async fn get_household_id(&self) -> Result<device_properties::GetHouseholdIdResponse> {
9749 self.action(
9750 &device_properties::SERVICE_TYPE,
9751 "GetHouseholdID",
9752 crate::soap::Unit {},
9753 )
9754 .await
9755 }
9756
9757 async fn get_led_state(&self) -> Result<device_properties::GetLedStateResponse> {
9758 self.action(
9759 &device_properties::SERVICE_TYPE,
9760 "GetLEDState",
9761 crate::soap::Unit {},
9762 )
9763 .await
9764 }
9765
9766 async fn get_use_autoplay_volume(
9767 &self,
9768 request: device_properties::GetUseAutoplayVolumeRequest,
9769 ) -> Result<device_properties::GetUseAutoplayVolumeResponse> {
9770 self.action(
9771 &device_properties::SERVICE_TYPE,
9772 "GetUseAutoplayVolume",
9773 request,
9774 )
9775 .await
9776 }
9777
9778 async fn get_zone_attributes(&self) -> Result<device_properties::GetZoneAttributesResponse> {
9779 self.action(
9780 &device_properties::SERVICE_TYPE,
9781 "GetZoneAttributes",
9782 crate::soap::Unit {},
9783 )
9784 .await
9785 }
9786
9787 async fn get_zone_info(&self) -> Result<device_properties::GetZoneInfoResponse> {
9788 self.action(
9789 &device_properties::SERVICE_TYPE,
9790 "GetZoneInfo",
9791 crate::soap::Unit {},
9792 )
9793 .await
9794 }
9795
9796 async fn remove_bonded_zones(
9797 &self,
9798 request: device_properties::RemoveBondedZonesRequest,
9799 ) -> Result<()> {
9800 self.action(
9801 &device_properties::SERVICE_TYPE,
9802 "RemoveBondedZones",
9803 request,
9804 )
9805 .await
9806 }
9807
9808 async fn remove_ht_satellite(
9809 &self,
9810 request: device_properties::RemoveHtSatelliteRequest,
9811 ) -> Result<()> {
9812 self.action(
9813 &device_properties::SERVICE_TYPE,
9814 "RemoveHTSatellite",
9815 request,
9816 )
9817 .await
9818 }
9819
9820 async fn room_detection_start_chirping(
9821 &self,
9822 request: device_properties::RoomDetectionStartChirpingRequest,
9823 ) -> Result<device_properties::RoomDetectionStartChirpingResponse> {
9824 self.action(
9825 &device_properties::SERVICE_TYPE,
9826 "RoomDetectionStartChirping",
9827 request,
9828 )
9829 .await
9830 }
9831
9832 async fn room_detection_stop_chirping(
9833 &self,
9834 request: device_properties::RoomDetectionStopChirpingRequest,
9835 ) -> Result<()> {
9836 self.action(
9837 &device_properties::SERVICE_TYPE,
9838 "RoomDetectionStopChirping",
9839 request,
9840 )
9841 .await
9842 }
9843
9844 async fn separate_stereo_pair(
9845 &self,
9846 request: device_properties::SeparateStereoPairRequest,
9847 ) -> Result<()> {
9848 self.action(
9849 &device_properties::SERVICE_TYPE,
9850 "SeparateStereoPair",
9851 request,
9852 )
9853 .await
9854 }
9855
9856 async fn set_autoplay_linked_zones(
9857 &self,
9858 request: device_properties::SetAutoplayLinkedZonesRequest,
9859 ) -> Result<()> {
9860 self.action(
9861 &device_properties::SERVICE_TYPE,
9862 "SetAutoplayLinkedZones",
9863 request,
9864 )
9865 .await
9866 }
9867
9868 async fn set_autoplay_room_uuid(
9869 &self,
9870 request: device_properties::SetAutoplayRoomUuidRequest,
9871 ) -> Result<()> {
9872 self.action(
9873 &device_properties::SERVICE_TYPE,
9874 "SetAutoplayRoomUUID",
9875 request,
9876 )
9877 .await
9878 }
9879
9880 async fn set_autoplay_volume(
9881 &self,
9882 request: device_properties::SetAutoplayVolumeRequest,
9883 ) -> Result<()> {
9884 self.action(
9885 &device_properties::SERVICE_TYPE,
9886 "SetAutoplayVolume",
9887 request,
9888 )
9889 .await
9890 }
9891
9892 async fn set_button_lock_state(
9893 &self,
9894 request: device_properties::SetButtonLockStateRequest,
9895 ) -> Result<()> {
9896 self.action(
9897 &device_properties::SERVICE_TYPE,
9898 "SetButtonLockState",
9899 request,
9900 )
9901 .await
9902 }
9903
9904 async fn set_led_state(&self, request: device_properties::SetLedStateRequest) -> Result<()> {
9905 self.action(&device_properties::SERVICE_TYPE, "SetLEDState", request)
9906 .await
9907 }
9908
9909 async fn set_use_autoplay_volume(
9910 &self,
9911 request: device_properties::SetUseAutoplayVolumeRequest,
9912 ) -> Result<()> {
9913 self.action(
9914 &device_properties::SERVICE_TYPE,
9915 "SetUseAutoplayVolume",
9916 request,
9917 )
9918 .await
9919 }
9920
9921 async fn set_zone_attributes(
9922 &self,
9923 request: device_properties::SetZoneAttributesRequest,
9924 ) -> Result<()> {
9925 self.action(
9926 &device_properties::SERVICE_TYPE,
9927 "SetZoneAttributes",
9928 request,
9929 )
9930 .await
9931 }
9932}
9933
9934impl GroupManagement for SonosDevice {
9935 async fn add_member(
9936 &self,
9937 request: group_management::AddMemberRequest,
9938 ) -> Result<group_management::AddMemberResponse> {
9939 self.action(&group_management::SERVICE_TYPE, "AddMember", request)
9940 .await
9941 }
9942
9943 async fn remove_member(&self, request: group_management::RemoveMemberRequest) -> Result<()> {
9944 self.action(&group_management::SERVICE_TYPE, "RemoveMember", request)
9945 .await
9946 }
9947
9948 async fn report_track_buffering_result(
9949 &self,
9950 request: group_management::ReportTrackBufferingResultRequest,
9951 ) -> Result<()> {
9952 self.action(
9953 &group_management::SERVICE_TYPE,
9954 "ReportTrackBufferingResult",
9955 request,
9956 )
9957 .await
9958 }
9959
9960 async fn set_source_area_ids(
9961 &self,
9962 request: group_management::SetSourceAreaIdsRequest,
9963 ) -> Result<()> {
9964 self.action(&group_management::SERVICE_TYPE, "SetSourceAreaIds", request)
9965 .await
9966 }
9967}
9968
9969impl GroupRenderingControl for SonosDevice {
9970 async fn get_group_mute(
9971 &self,
9972 request: group_rendering_control::GetGroupMuteRequest,
9973 ) -> Result<group_rendering_control::GetGroupMuteResponse> {
9974 self.action(
9975 &group_rendering_control::SERVICE_TYPE,
9976 "GetGroupMute",
9977 request,
9978 )
9979 .await
9980 }
9981
9982 async fn get_group_volume(
9983 &self,
9984 request: group_rendering_control::GetGroupVolumeRequest,
9985 ) -> Result<group_rendering_control::GetGroupVolumeResponse> {
9986 self.action(
9987 &group_rendering_control::SERVICE_TYPE,
9988 "GetGroupVolume",
9989 request,
9990 )
9991 .await
9992 }
9993
9994 async fn set_group_mute(
9995 &self,
9996 request: group_rendering_control::SetGroupMuteRequest,
9997 ) -> Result<()> {
9998 self.action(
9999 &group_rendering_control::SERVICE_TYPE,
10000 "SetGroupMute",
10001 request,
10002 )
10003 .await
10004 }
10005
10006 async fn set_group_volume(
10007 &self,
10008 request: group_rendering_control::SetGroupVolumeRequest,
10009 ) -> Result<()> {
10010 self.action(
10011 &group_rendering_control::SERVICE_TYPE,
10012 "SetGroupVolume",
10013 request,
10014 )
10015 .await
10016 }
10017
10018 async fn set_relative_group_volume(
10019 &self,
10020 request: group_rendering_control::SetRelativeGroupVolumeRequest,
10021 ) -> Result<group_rendering_control::SetRelativeGroupVolumeResponse> {
10022 self.action(
10023 &group_rendering_control::SERVICE_TYPE,
10024 "SetRelativeGroupVolume",
10025 request,
10026 )
10027 .await
10028 }
10029
10030 async fn snapshot_group_volume(
10031 &self,
10032 request: group_rendering_control::SnapshotGroupVolumeRequest,
10033 ) -> Result<()> {
10034 self.action(
10035 &group_rendering_control::SERVICE_TYPE,
10036 "SnapshotGroupVolume",
10037 request,
10038 )
10039 .await
10040 }
10041}
10042
10043impl HTControl for SonosDevice {
10044 async fn commit_learned_ir_codes(
10045 &self,
10046 request: ht_control::CommitLearnedIrCodesRequest,
10047 ) -> Result<()> {
10048 self.action(&ht_control::SERVICE_TYPE, "CommitLearnedIRCodes", request)
10049 .await
10050 }
10051
10052 async fn get_ir_repeater_state(&self) -> Result<ht_control::GetIrRepeaterStateResponse> {
10053 self.action(
10054 &ht_control::SERVICE_TYPE,
10055 "GetIRRepeaterState",
10056 crate::soap::Unit {},
10057 )
10058 .await
10059 }
10060
10061 async fn get_led_feedback_state(&self) -> Result<ht_control::GetLedFeedbackStateResponse> {
10062 self.action(
10063 &ht_control::SERVICE_TYPE,
10064 "GetLEDFeedbackState",
10065 crate::soap::Unit {},
10066 )
10067 .await
10068 }
10069
10070 async fn identify_ir_remote(&self, request: ht_control::IdentifyIrRemoteRequest) -> Result<()> {
10071 self.action(&ht_control::SERVICE_TYPE, "IdentifyIRRemote", request)
10072 .await
10073 }
10074
10075 async fn is_remote_configured(&self) -> Result<ht_control::IsRemoteConfiguredResponse> {
10076 self.action(
10077 &ht_control::SERVICE_TYPE,
10078 "IsRemoteConfigured",
10079 crate::soap::Unit {},
10080 )
10081 .await
10082 }
10083
10084 async fn learn_ir_code(&self, request: ht_control::LearnIrCodeRequest) -> Result<()> {
10085 self.action(&ht_control::SERVICE_TYPE, "LearnIRCode", request)
10086 .await
10087 }
10088
10089 async fn set_ir_repeater_state(
10090 &self,
10091 request: ht_control::SetIrRepeaterStateRequest,
10092 ) -> Result<()> {
10093 self.action(&ht_control::SERVICE_TYPE, "SetIRRepeaterState", request)
10094 .await
10095 }
10096
10097 async fn set_led_feedback_state(
10098 &self,
10099 request: ht_control::SetLedFeedbackStateRequest,
10100 ) -> Result<()> {
10101 self.action(&ht_control::SERVICE_TYPE, "SetLEDFeedbackState", request)
10102 .await
10103 }
10104}
10105
10106impl MusicServices for SonosDevice {
10107 async fn get_session_id(
10108 &self,
10109 request: music_services::GetSessionIdRequest,
10110 ) -> Result<music_services::GetSessionIdResponse> {
10111 self.action(&music_services::SERVICE_TYPE, "GetSessionId", request)
10112 .await
10113 }
10114
10115 async fn list_available_services(
10116 &self,
10117 ) -> Result<music_services::ListAvailableServicesResponse> {
10118 self.action(
10119 &music_services::SERVICE_TYPE,
10120 "ListAvailableServices",
10121 crate::soap::Unit {},
10122 )
10123 .await
10124 }
10125
10126 async fn update_available_services(&self) -> Result<()> {
10127 self.action(
10128 &music_services::SERVICE_TYPE,
10129 "UpdateAvailableServices",
10130 crate::soap::Unit {},
10131 )
10132 .await
10133 }
10134}
10135
10136impl QPlay for SonosDevice {
10137 async fn q_play_auth(
10138 &self,
10139 request: q_play::QPlayAuthRequest,
10140 ) -> Result<q_play::QPlayAuthResponse> {
10141 self.action(&q_play::SERVICE_TYPE, "QPlayAuth", request)
10142 .await
10143 }
10144}
10145
10146impl Queue for SonosDevice {
10147 async fn add_multiple_uris(
10148 &self,
10149 request: queue::AddMultipleUrisRequest,
10150 ) -> Result<queue::AddMultipleUrisResponse> {
10151 self.action(&queue::SERVICE_TYPE, "AddMultipleURIs", request)
10152 .await
10153 }
10154
10155 async fn add_uri(&self, request: queue::AddUriRequest) -> Result<queue::AddUriResponse> {
10156 self.action(&queue::SERVICE_TYPE, "AddURI", request).await
10157 }
10158
10159 async fn attach_queue(
10160 &self,
10161 request: queue::AttachQueueRequest,
10162 ) -> Result<queue::AttachQueueResponse> {
10163 self.action(&queue::SERVICE_TYPE, "AttachQueue", request)
10164 .await
10165 }
10166
10167 async fn backup(&self) -> Result<()> {
10168 self.action(&queue::SERVICE_TYPE, "Backup", crate::soap::Unit {})
10169 .await
10170 }
10171
10172 async fn browse(&self, request: queue::BrowseRequest) -> Result<queue::BrowseResponse> {
10173 self.action(&queue::SERVICE_TYPE, "Browse", request).await
10174 }
10175
10176 async fn create_queue(
10177 &self,
10178 request: queue::CreateQueueRequest,
10179 ) -> Result<queue::CreateQueueResponse> {
10180 self.action(&queue::SERVICE_TYPE, "CreateQueue", request)
10181 .await
10182 }
10183
10184 async fn remove_all_tracks(
10185 &self,
10186 request: queue::RemoveAllTracksRequest,
10187 ) -> Result<queue::RemoveAllTracksResponse> {
10188 self.action(&queue::SERVICE_TYPE, "RemoveAllTracks", request)
10189 .await
10190 }
10191
10192 async fn remove_track_range(
10193 &self,
10194 request: queue::RemoveTrackRangeRequest,
10195 ) -> Result<queue::RemoveTrackRangeResponse> {
10196 self.action(&queue::SERVICE_TYPE, "RemoveTrackRange", request)
10197 .await
10198 }
10199
10200 async fn reorder_tracks(
10201 &self,
10202 request: queue::ReorderTracksRequest,
10203 ) -> Result<queue::ReorderTracksResponse> {
10204 self.action(&queue::SERVICE_TYPE, "ReorderTracks", request)
10205 .await
10206 }
10207
10208 async fn replace_all_tracks(
10209 &self,
10210 request: queue::ReplaceAllTracksRequest,
10211 ) -> Result<queue::ReplaceAllTracksResponse> {
10212 self.action(&queue::SERVICE_TYPE, "ReplaceAllTracks", request)
10213 .await
10214 }
10215
10216 async fn save_as_sonos_playlist(
10217 &self,
10218 request: queue::SaveAsSonosPlaylistRequest,
10219 ) -> Result<queue::SaveAsSonosPlaylistResponse> {
10220 self.action(&queue::SERVICE_TYPE, "SaveAsSonosPlaylist", request)
10221 .await
10222 }
10223}
10224
10225impl RenderingControl for SonosDevice {
10226 async fn get_bass(
10227 &self,
10228 request: rendering_control::GetBassRequest,
10229 ) -> Result<rendering_control::GetBassResponse> {
10230 self.action(&rendering_control::SERVICE_TYPE, "GetBass", request)
10231 .await
10232 }
10233
10234 async fn get_eq(
10235 &self,
10236 request: rendering_control::GetEqRequest,
10237 ) -> Result<rendering_control::GetEqResponse> {
10238 self.action(&rendering_control::SERVICE_TYPE, "GetEQ", request)
10239 .await
10240 }
10241
10242 async fn get_headphone_connected(
10243 &self,
10244 request: rendering_control::GetHeadphoneConnectedRequest,
10245 ) -> Result<rendering_control::GetHeadphoneConnectedResponse> {
10246 self.action(
10247 &rendering_control::SERVICE_TYPE,
10248 "GetHeadphoneConnected",
10249 request,
10250 )
10251 .await
10252 }
10253
10254 async fn get_loudness(
10255 &self,
10256 request: rendering_control::GetLoudnessRequest,
10257 ) -> Result<rendering_control::GetLoudnessResponse> {
10258 self.action(&rendering_control::SERVICE_TYPE, "GetLoudness", request)
10259 .await
10260 }
10261
10262 async fn get_mute(
10263 &self,
10264 request: rendering_control::GetMuteRequest,
10265 ) -> Result<rendering_control::GetMuteResponse> {
10266 self.action(&rendering_control::SERVICE_TYPE, "GetMute", request)
10267 .await
10268 }
10269
10270 async fn get_output_fixed(
10271 &self,
10272 request: rendering_control::GetOutputFixedRequest,
10273 ) -> Result<rendering_control::GetOutputFixedResponse> {
10274 self.action(&rendering_control::SERVICE_TYPE, "GetOutputFixed", request)
10275 .await
10276 }
10277
10278 async fn get_room_calibration_status(
10279 &self,
10280 request: rendering_control::GetRoomCalibrationStatusRequest,
10281 ) -> Result<rendering_control::GetRoomCalibrationStatusResponse> {
10282 self.action(
10283 &rendering_control::SERVICE_TYPE,
10284 "GetRoomCalibrationStatus",
10285 request,
10286 )
10287 .await
10288 }
10289
10290 async fn get_supports_output_fixed(
10291 &self,
10292 request: rendering_control::GetSupportsOutputFixedRequest,
10293 ) -> Result<rendering_control::GetSupportsOutputFixedResponse> {
10294 self.action(
10295 &rendering_control::SERVICE_TYPE,
10296 "GetSupportsOutputFixed",
10297 request,
10298 )
10299 .await
10300 }
10301
10302 async fn get_treble(
10303 &self,
10304 request: rendering_control::GetTrebleRequest,
10305 ) -> Result<rendering_control::GetTrebleResponse> {
10306 self.action(&rendering_control::SERVICE_TYPE, "GetTreble", request)
10307 .await
10308 }
10309
10310 async fn get_volume(
10311 &self,
10312 request: rendering_control::GetVolumeRequest,
10313 ) -> Result<rendering_control::GetVolumeResponse> {
10314 self.action(&rendering_control::SERVICE_TYPE, "GetVolume", request)
10315 .await
10316 }
10317
10318 async fn get_volume_db(
10319 &self,
10320 request: rendering_control::GetVolumeDbRequest,
10321 ) -> Result<rendering_control::GetVolumeDbResponse> {
10322 self.action(&rendering_control::SERVICE_TYPE, "GetVolumeDB", request)
10323 .await
10324 }
10325
10326 async fn get_volume_db_range(
10327 &self,
10328 request: rendering_control::GetVolumeDbRangeRequest,
10329 ) -> Result<rendering_control::GetVolumeDbRangeResponse> {
10330 self.action(
10331 &rendering_control::SERVICE_TYPE,
10332 "GetVolumeDBRange",
10333 request,
10334 )
10335 .await
10336 }
10337
10338 async fn ramp_to_volume(
10339 &self,
10340 request: rendering_control::RampToVolumeRequest,
10341 ) -> Result<rendering_control::RampToVolumeResponse> {
10342 self.action(&rendering_control::SERVICE_TYPE, "RampToVolume", request)
10343 .await
10344 }
10345
10346 async fn reset_basic_eq(
10347 &self,
10348 request: rendering_control::ResetBasicEqRequest,
10349 ) -> Result<rendering_control::ResetBasicEqResponse> {
10350 self.action(&rendering_control::SERVICE_TYPE, "ResetBasicEQ", request)
10351 .await
10352 }
10353
10354 async fn reset_ext_eq(&self, request: rendering_control::ResetExtEqRequest) -> Result<()> {
10355 self.action(&rendering_control::SERVICE_TYPE, "ResetExtEQ", request)
10356 .await
10357 }
10358
10359 async fn restore_volume_prior_to_ramp(
10360 &self,
10361 request: rendering_control::RestoreVolumePriorToRampRequest,
10362 ) -> Result<()> {
10363 self.action(
10364 &rendering_control::SERVICE_TYPE,
10365 "RestoreVolumePriorToRamp",
10366 request,
10367 )
10368 .await
10369 }
10370
10371 async fn set_bass(&self, request: rendering_control::SetBassRequest) -> Result<()> {
10372 self.action(&rendering_control::SERVICE_TYPE, "SetBass", request)
10373 .await
10374 }
10375
10376 async fn set_channel_map(
10377 &self,
10378 request: rendering_control::SetChannelMapRequest,
10379 ) -> Result<()> {
10380 self.action(&rendering_control::SERVICE_TYPE, "SetChannelMap", request)
10381 .await
10382 }
10383
10384 async fn set_eq(&self, request: rendering_control::SetEqRequest) -> Result<()> {
10385 self.action(&rendering_control::SERVICE_TYPE, "SetEQ", request)
10386 .await
10387 }
10388
10389 async fn set_loudness(&self, request: rendering_control::SetLoudnessRequest) -> Result<()> {
10390 self.action(&rendering_control::SERVICE_TYPE, "SetLoudness", request)
10391 .await
10392 }
10393
10394 async fn set_mute(&self, request: rendering_control::SetMuteRequest) -> Result<()> {
10395 self.action(&rendering_control::SERVICE_TYPE, "SetMute", request)
10396 .await
10397 }
10398
10399 async fn set_output_fixed(
10400 &self,
10401 request: rendering_control::SetOutputFixedRequest,
10402 ) -> Result<()> {
10403 self.action(&rendering_control::SERVICE_TYPE, "SetOutputFixed", request)
10404 .await
10405 }
10406
10407 async fn set_relative_volume(
10408 &self,
10409 request: rendering_control::SetRelativeVolumeRequest,
10410 ) -> Result<rendering_control::SetRelativeVolumeResponse> {
10411 self.action(
10412 &rendering_control::SERVICE_TYPE,
10413 "SetRelativeVolume",
10414 request,
10415 )
10416 .await
10417 }
10418
10419 async fn set_room_calibration_status(
10420 &self,
10421 request: rendering_control::SetRoomCalibrationStatusRequest,
10422 ) -> Result<()> {
10423 self.action(
10424 &rendering_control::SERVICE_TYPE,
10425 "SetRoomCalibrationStatus",
10426 request,
10427 )
10428 .await
10429 }
10430
10431 async fn set_room_calibration_x(
10432 &self,
10433 request: rendering_control::SetRoomCalibrationXRequest,
10434 ) -> Result<()> {
10435 self.action(
10436 &rendering_control::SERVICE_TYPE,
10437 "SetRoomCalibrationX",
10438 request,
10439 )
10440 .await
10441 }
10442
10443 async fn set_treble(&self, request: rendering_control::SetTrebleRequest) -> Result<()> {
10444 self.action(&rendering_control::SERVICE_TYPE, "SetTreble", request)
10445 .await
10446 }
10447
10448 async fn set_volume(&self, request: rendering_control::SetVolumeRequest) -> Result<()> {
10449 self.action(&rendering_control::SERVICE_TYPE, "SetVolume", request)
10450 .await
10451 }
10452
10453 async fn set_volume_db(&self, request: rendering_control::SetVolumeDbRequest) -> Result<()> {
10454 self.action(&rendering_control::SERVICE_TYPE, "SetVolumeDB", request)
10455 .await
10456 }
10457}
10458
10459impl SystemProperties for SonosDevice {
10460 async fn add_account_x(
10461 &self,
10462 request: system_properties::AddAccountXRequest,
10463 ) -> Result<system_properties::AddAccountXResponse> {
10464 self.action(&system_properties::SERVICE_TYPE, "AddAccountX", request)
10465 .await
10466 }
10467
10468 async fn add_o_auth_account_x(
10469 &self,
10470 request: system_properties::AddOAuthAccountXRequest,
10471 ) -> Result<system_properties::AddOAuthAccountXResponse> {
10472 self.action(
10473 &system_properties::SERVICE_TYPE,
10474 "AddOAuthAccountX",
10475 request,
10476 )
10477 .await
10478 }
10479
10480 async fn do_post_update_tasks(&self) -> Result<()> {
10481 self.action(
10482 &system_properties::SERVICE_TYPE,
10483 "DoPostUpdateTasks",
10484 crate::soap::Unit {},
10485 )
10486 .await
10487 }
10488
10489 async fn edit_account_md(
10490 &self,
10491 request: system_properties::EditAccountMdRequest,
10492 ) -> Result<()> {
10493 self.action(&system_properties::SERVICE_TYPE, "EditAccountMd", request)
10494 .await
10495 }
10496
10497 async fn edit_account_password_x(
10498 &self,
10499 request: system_properties::EditAccountPasswordXRequest,
10500 ) -> Result<()> {
10501 self.action(
10502 &system_properties::SERVICE_TYPE,
10503 "EditAccountPasswordX",
10504 request,
10505 )
10506 .await
10507 }
10508
10509 async fn enable_rdm(&self, request: system_properties::EnableRdmRequest) -> Result<()> {
10510 self.action(&system_properties::SERVICE_TYPE, "EnableRDM", request)
10511 .await
10512 }
10513
10514 async fn get_rdm(&self) -> Result<system_properties::GetRdmResponse> {
10515 self.action(
10516 &system_properties::SERVICE_TYPE,
10517 "GetRDM",
10518 crate::soap::Unit {},
10519 )
10520 .await
10521 }
10522
10523 async fn get_string(
10524 &self,
10525 request: system_properties::GetStringRequest,
10526 ) -> Result<system_properties::GetStringResponse> {
10527 self.action(&system_properties::SERVICE_TYPE, "GetString", request)
10528 .await
10529 }
10530
10531 async fn get_web_code(
10532 &self,
10533 request: system_properties::GetWebCodeRequest,
10534 ) -> Result<system_properties::GetWebCodeResponse> {
10535 self.action(&system_properties::SERVICE_TYPE, "GetWebCode", request)
10536 .await
10537 }
10538
10539 async fn provision_credentialed_trial_account_x(
10540 &self,
10541 request: system_properties::ProvisionCredentialedTrialAccountXRequest,
10542 ) -> Result<system_properties::ProvisionCredentialedTrialAccountXResponse> {
10543 self.action(
10544 &system_properties::SERVICE_TYPE,
10545 "ProvisionCredentialedTrialAccountX",
10546 request,
10547 )
10548 .await
10549 }
10550
10551 async fn refresh_account_credentials_x(
10552 &self,
10553 request: system_properties::RefreshAccountCredentialsXRequest,
10554 ) -> Result<()> {
10555 self.action(
10556 &system_properties::SERVICE_TYPE,
10557 "RefreshAccountCredentialsX",
10558 request,
10559 )
10560 .await
10561 }
10562
10563 async fn remove(&self, request: system_properties::RemoveRequest) -> Result<()> {
10564 self.action(&system_properties::SERVICE_TYPE, "Remove", request)
10565 .await
10566 }
10567
10568 async fn remove_account(&self, request: system_properties::RemoveAccountRequest) -> Result<()> {
10569 self.action(&system_properties::SERVICE_TYPE, "RemoveAccount", request)
10570 .await
10571 }
10572
10573 async fn replace_account_x(
10574 &self,
10575 request: system_properties::ReplaceAccountXRequest,
10576 ) -> Result<system_properties::ReplaceAccountXResponse> {
10577 self.action(&system_properties::SERVICE_TYPE, "ReplaceAccountX", request)
10578 .await
10579 }
10580
10581 async fn reset_third_party_credentials(&self) -> Result<()> {
10582 self.action(
10583 &system_properties::SERVICE_TYPE,
10584 "ResetThirdPartyCredentials",
10585 crate::soap::Unit {},
10586 )
10587 .await
10588 }
10589
10590 async fn set_account_nickname_x(
10591 &self,
10592 request: system_properties::SetAccountNicknameXRequest,
10593 ) -> Result<()> {
10594 self.action(
10595 &system_properties::SERVICE_TYPE,
10596 "SetAccountNicknameX",
10597 request,
10598 )
10599 .await
10600 }
10601
10602 async fn set_string(&self, request: system_properties::SetStringRequest) -> Result<()> {
10603 self.action(&system_properties::SERVICE_TYPE, "SetString", request)
10604 .await
10605 }
10606}
10607
10608impl VirtualLineIn for SonosDevice {
10609 async fn next(&self, request: virtual_line_in::NextRequest) -> Result<()> {
10610 self.action(&virtual_line_in::SERVICE_TYPE, "Next", request)
10611 .await
10612 }
10613
10614 async fn pause(&self, request: virtual_line_in::PauseRequest) -> Result<()> {
10615 self.action(&virtual_line_in::SERVICE_TYPE, "Pause", request)
10616 .await
10617 }
10618
10619 async fn play(&self, request: virtual_line_in::PlayRequest) -> Result<()> {
10620 self.action(&virtual_line_in::SERVICE_TYPE, "Play", request)
10621 .await
10622 }
10623
10624 async fn previous(&self, request: virtual_line_in::PreviousRequest) -> Result<()> {
10625 self.action(&virtual_line_in::SERVICE_TYPE, "Previous", request)
10626 .await
10627 }
10628
10629 async fn set_volume(&self, request: virtual_line_in::SetVolumeRequest) -> Result<()> {
10630 self.action(&virtual_line_in::SERVICE_TYPE, "SetVolume", request)
10631 .await
10632 }
10633
10634 async fn start_transmission(
10635 &self,
10636 request: virtual_line_in::StartTransmissionRequest,
10637 ) -> Result<virtual_line_in::StartTransmissionResponse> {
10638 self.action(&virtual_line_in::SERVICE_TYPE, "StartTransmission", request)
10639 .await
10640 }
10641
10642 async fn stop(&self, request: virtual_line_in::StopRequest) -> Result<()> {
10643 self.action(&virtual_line_in::SERVICE_TYPE, "Stop", request)
10644 .await
10645 }
10646
10647 async fn stop_transmission(
10648 &self,
10649 request: virtual_line_in::StopTransmissionRequest,
10650 ) -> Result<()> {
10651 self.action(&virtual_line_in::SERVICE_TYPE, "StopTransmission", request)
10652 .await
10653 }
10654}
10655
10656impl ZoneGroupTopology for SonosDevice {
10657 async fn begin_software_update(
10658 &self,
10659 request: zone_group_topology::BeginSoftwareUpdateRequest,
10660 ) -> Result<()> {
10661 self.action(
10662 &zone_group_topology::SERVICE_TYPE,
10663 "BeginSoftwareUpdate",
10664 request,
10665 )
10666 .await
10667 }
10668
10669 async fn check_for_update(
10670 &self,
10671 request: zone_group_topology::CheckForUpdateRequest,
10672 ) -> Result<zone_group_topology::CheckForUpdateResponse> {
10673 self.action(
10674 &zone_group_topology::SERVICE_TYPE,
10675 "CheckForUpdate",
10676 request,
10677 )
10678 .await
10679 }
10680
10681 async fn get_zone_group_attributes(
10682 &self,
10683 ) -> Result<zone_group_topology::GetZoneGroupAttributesResponse> {
10684 self.action(
10685 &zone_group_topology::SERVICE_TYPE,
10686 "GetZoneGroupAttributes",
10687 crate::soap::Unit {},
10688 )
10689 .await
10690 }
10691
10692 async fn get_zone_group_state(&self) -> Result<zone_group_topology::GetZoneGroupStateResponse> {
10693 self.action(
10694 &zone_group_topology::SERVICE_TYPE,
10695 "GetZoneGroupState",
10696 crate::soap::Unit {},
10697 )
10698 .await
10699 }
10700
10701 async fn register_mobile_device(
10702 &self,
10703 request: zone_group_topology::RegisterMobileDeviceRequest,
10704 ) -> Result<()> {
10705 self.action(
10706 &zone_group_topology::SERVICE_TYPE,
10707 "RegisterMobileDevice",
10708 request,
10709 )
10710 .await
10711 }
10712
10713 async fn report_alarm_started_running(&self) -> Result<()> {
10714 self.action(
10715 &zone_group_topology::SERVICE_TYPE,
10716 "ReportAlarmStartedRunning",
10717 crate::soap::Unit {},
10718 )
10719 .await
10720 }
10721
10722 async fn report_unresponsive_device(
10723 &self,
10724 request: zone_group_topology::ReportUnresponsiveDeviceRequest,
10725 ) -> Result<()> {
10726 self.action(
10727 &zone_group_topology::SERVICE_TYPE,
10728 "ReportUnresponsiveDevice",
10729 request,
10730 )
10731 .await
10732 }
10733
10734 async fn submit_diagnostics(
10735 &self,
10736 request: zone_group_topology::SubmitDiagnosticsRequest,
10737 ) -> Result<zone_group_topology::SubmitDiagnosticsResponse> {
10738 self.action(
10739 &zone_group_topology::SERVICE_TYPE,
10740 "SubmitDiagnostics",
10741 request,
10742 )
10743 .await
10744 }
10745}
10746
10747pub mod prelude {
10751 pub use super::{
10752 AVTransport, AlarmClock, AudioIn, ConnectionManager, ContentDirectory, DeviceProperties,
10753 GroupManagement, GroupRenderingControl, HTControl, MusicServices, QPlay, Queue,
10754 RenderingControl, SystemProperties, VirtualLineIn, ZoneGroupTopology,
10755 };
10756}