vsslctrl 0.1.14.dev1__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/PKG-INFO +75 -94
  2. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/README.md +72 -92
  3. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/pyproject.toml +1 -1
  4. vsslctrl-0.2.1/tests/test_api.py +64 -0
  5. vsslctrl-0.2.1/tests/test_device.py +87 -0
  6. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/tests/test_event_bus.py +5 -4
  7. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/tests/test_integration.py +116 -100
  8. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/tests/test_settings.py +11 -12
  9. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/tests/test_zone.py +2 -24
  10. vsslctrl-0.2.1/vsslctrl/__init__.py +7 -0
  11. vsslctrl-0.2.1/vsslctrl/api_alpha.py +1814 -0
  12. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/api_base.py +120 -165
  13. vsslctrl-0.2.1/vsslctrl/api_bravo.py +645 -0
  14. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/core.py +116 -124
  15. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/data_structure.py +156 -62
  16. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/decorators.py +46 -15
  17. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/device.py +58 -13
  18. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/discovery.py +42 -27
  19. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/event_bus.py +39 -3
  20. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/group.py +27 -55
  21. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/io.py +5 -14
  22. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/settings.py +162 -26
  23. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/track.py +3 -45
  24. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/transport.py +2 -2
  25. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/utils.py +8 -17
  26. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/zone.py +105 -117
  27. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl.egg-info/PKG-INFO +75 -94
  28. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl.egg-info/SOURCES.txt +2 -0
  29. vsslctrl-0.1.14.dev1/vsslctrl/__init__.py +0 -7
  30. vsslctrl-0.1.14.dev1/vsslctrl/api_alpha.py +0 -1265
  31. vsslctrl-0.1.14.dev1/vsslctrl/api_bravo.py +0 -427
  32. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/LICENSE +0 -0
  33. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/setup.cfg +0 -0
  34. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl/exceptions.py +0 -0
  35. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl.egg-info/dependency_links.txt +0 -0
  36. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl.egg-info/requires.txt +0 -0
  37. {vsslctrl-0.1.14.dev1 → vsslctrl-0.2.1}/vsslctrl.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: vsslctrl
3
- Version: 0.1.14.dev1
3
+ Version: 0.2.1
4
4
  Summary: Package for controlling VSSL's range of streaming amplifiers
5
5
  Author-email: vsslctrl <vsslcontrolled@proton.me>
6
6
  Classifier: Development Status :: 4 - Beta
@@ -18,28 +18,30 @@ Requires-Dist: pytest==8.1.1; extra == "dev"
18
18
  Requires-Dist: pytest_asyncio==0.23.6; extra == "dev"
19
19
  Provides-Extra: optional
20
20
  Requires-Dist: zeroconf==0.132.2; extra == "optional"
21
+ Dynamic: license-file
21
22
 
22
23
  # vsslctrl
23
24
 
24
- Package for controlling [VSSL's](https://www.vssl.com/) range of streaming amplifiers.
25
+ Python package for controlling [VSSL's](https://www.vssl.com/) range of streaming amplifiers.
25
26
 
26
27
  ## Coverage
27
28
 
28
- Tested on:
29
+ Test suite run on:
29
30
 
30
- | Model | Software Version | Note |
31
- | ------------|--------- | -------------
32
- | A.3x | p15305.016.3701 |
31
+ | Model | Software Version
32
+ | ------------|---------
33
+ | `A.1x` | p15243.022.3703
34
+ | `A.3x` | p15305.016.3701
33
35
 
34
36
 
35
37
  Home Assistant [integration](https://github.com/vsslctrl/integration.home-assistant) with basic functionality working on:
36
38
 
37
39
  | Model | Software Version | User Reported |
38
40
  | ------------|--------- | -------------
39
- | A.1 | p15265.033.3703 | ✔️
40
- | A.3 | p12013.141.3703 | ✔️
41
- | A.3x | p15305.016.3701 |
42
- | A.6x | p15305.017.3701 | ✔️
41
+ | `A.1` | p15265.033.3703 | ✔️
42
+ | `A.3` | p12013.141.3703 | ✔️
43
+ | `A.3x` | p15305.016.3701 |
44
+ | `A.6x` | p15305.017.3701 | ✔️
43
45
 
44
46
 
45
47
  ## Testers Needed
@@ -54,33 +56,28 @@ There should not be any *[VSSL Agent's](https://vssl.gitbook.io/vssl-rest-api/ge
54
56
 
55
57
  **`vsslctrl` is not endorsed or affiliated with [VSSL](https://www.vssl.com/) in any manner.**
56
58
 
57
- ## TODOs
58
-
59
- * Better test coverage
60
- * A.1(x) testing - e.g output settings
61
- * More controls - e.g IR Control
62
-
63
59
  ## Basic Usage
64
60
 
65
61
  `vsslctrl` needs to be running inside a **[asyncio](https://docs.python.org/3/library/asyncio.html)** event loop.
66
62
 
67
- ### A.1 Example
63
+ ### `A.1(x)` Example
68
64
 
69
65
  ```python
70
66
  import asyncio
71
- from vsslctrl import Vssl, DeviceModels, Zone, ZoneIDs
67
+ from vsslctrl import Vssl
72
68
 
73
69
  async def main():
74
70
 
75
71
  # Represents a physical VSSL amplifier
76
- vssl = Vssl(DeviceModels.A1)
72
+ vssl = Vssl()
73
+
77
74
  a1 = vssl.add_zone('192.168.1.10')
78
75
 
79
76
  # Connect and initialise zone.
80
77
  await vssl.initialise()
81
78
 
82
79
  """Control Examples"""
83
- # Print device name
80
+ # Print zone/device name
84
81
  print(a1.settings.name)
85
82
  # Set volume to 25%
86
83
  a1.volume = 25
@@ -95,21 +92,21 @@ async def main():
95
92
  asyncio.run(main())
96
93
  ```
97
94
 
98
- ### A.3x Example
95
+ ### `A.3(x)` Example
99
96
 
100
97
  ```python
101
98
  import asyncio
102
- from vsslctrl import Vssl, DeviceModels, Zone, ZoneIDs
99
+ from vsslctrl import Vssl
103
100
 
104
101
  async def main():
105
102
 
106
103
  # Represents a physical VSSL amplifier
107
- vssl = Vssl(DeviceModels.A3X)
104
+ vssl = Vssl()
108
105
 
109
106
  # Add each you wish to control
110
- zone1 = vssl.add_zone('192.168.1.10', ZoneIDs.ZONE_1)
111
- zone2 = vssl.add_zone('192.168.1.11', ZoneIDs.ZONE_2)
112
- zone3 = vssl.add_zone('192.168.1.12', ZoneIDs.ZONE_3)
107
+ zone1 = vssl.add_zone('192.168.1.10')
108
+ zone2 = vssl.add_zone('192.168.1.11')
109
+ zone3 = vssl.add_zone('192.168.1.12')
113
110
  #... up to 6 zones for A.6(x)
114
111
 
115
112
  # Connect and initialise zones.
@@ -191,7 +188,7 @@ print(zone1.settings.name)
191
188
  ```python
192
189
  from vsslctrl.settings import ZoneSettings
193
190
  # Setting the zone name and wait for feedback
194
- future_name = vssl.event_bus.future(ZoneSettings.Events.NAME_CHANGE, zone1.id)
191
+ future_name = vssl.event_bus.future(ZoneSettings.Events.NAME_CHANGE, zone1.host)
195
192
  zone1.settings.name = 'Bathroom'
196
193
  # Helper to await a future with timeout
197
194
  new_name = await vssl.event_bus.wait_future(future_name)
@@ -205,37 +202,6 @@ print(zone1.settings.name)
205
202
 
206
203
  # API Reference
207
204
 
208
- # `DeviceModels`
209
-
210
- A device model has to be passed to VSSL so it knows internally what features are supported by the device.
211
- This might be removed in the future if we can differentiate different models from the API.
212
-
213
- | Property | Description |
214
- | ------------|--------- |
215
- | `A1X` | A.1x |
216
- | `A3X` | A.3x |
217
- | `A6X` | A.6x |
218
- | `A1` | A1 |
219
- | `A3` | A3 |
220
- | `A6` | A6 |
221
-
222
- # `ZoneIDs`
223
-
224
- A `ZoneIDs` must be passed to each `zone` you which to control and it must match the zone on the VSSL device.
225
-
226
- If you are unsure of your `ZoneIDs` you could use the discovery helper to find out the correct mapping.
227
-
228
- | Property | Description | A.1(x) | A.3(x) | A.6(x)
229
- | ------------|--------- |-------- | -------- | -------- |
230
- | `A1` | |✔️ | | |
231
- | `ZONE_1` | Zone 1 | | ✔️| ✔️|
232
- | `ZONE_2` | Zone 2 | | ✔️| ✔️|
233
- | `ZONE_3` | Zone 3 | | ✔️| ✔️|
234
- | `ZONE_4` | Zone 4 | | | ✔️|
235
- | `ZONE_5` | Zone 5 | | | ✔️|
236
- | `ZONE_6` | Zone 6 | | | ✔️|
237
-
238
-
239
205
  # `Vssl`
240
206
 
241
207
  | Property | Description | Type |
@@ -257,13 +223,14 @@ vssl.factory_reset()
257
223
 
258
224
  ## `Vssl.settings`
259
225
 
226
+ `A.1(x)` doesn't use `Vssl.settings.name` use `Zone.settings.name` instead.
227
+
260
228
  | Property | Description | Type | Model: Default |
261
229
  | ---------------------- | ----------- | ----------- | ----------- |
262
- | `name` | Device name | `str` |
263
- | `bus_1_name` | Name of Bus 1 | `str` | <ul><li>A.1: Optical Input</li><li>A.3x/6x: Not Used</li></ul>
264
- | `bus_2_name` | Name of Bus 2 | `str` | <ul><li>A.1: Coax Input</li><li>A.3x/6x: Optical Input</li></ul>
265
- | `bluetooth` | Bluetooth enabled / disabled | `bool` |
266
- | `bluetooth_toggle()` | Toggle Bluetooth | `func` |
230
+ | `name` | Device name | `str` |
231
+ | `bus_1_name` | Name of Bus 1 | `str` | <ul><li>`A.1`: Optical Input</li><li>`A.3x`/`A.6x`: Not Used</li></ul>
232
+ | `bus_2_name` | Name of Bus 2 | `str` | <ul><li>`A.1`: Coax Input</li><li>`A.3x`/`A.6x`: Optical Input</li></ul>
233
+ | `status_light_mode` | Status lights - Normal or Dark Mode | `str` | [`VsslSettings.StatusLightModes`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/settings.py#L17)
267
234
 
268
235
  ```python
269
236
  """Example"""
@@ -271,17 +238,35 @@ vssl.factory_reset()
271
238
  vssl.settings.name = 'My House'
272
239
  # Setting bus 2 name
273
240
  vssl.settings.bus_2_name = 'Optical Input'
241
+ ```
242
+
243
+ ## `Vssl.settings.bluetooth`
244
+
245
+ `A.1(x)` only.
246
+
247
+ | Property | Description | Type | Values |
248
+ | ---------------------- | ----------- | ----------- |----------- |
249
+ | `state` | Bluetooth state | `int` readonly | [`BluetoothSettings.States`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/settings.py#L130)
250
+ | `on()` | Enable Bluetooth | `func`
251
+ | `off()` | Disable Bluetooth | `func`
252
+ | `clear_pairs()` | Clear pairings | `func`
253
+ | `enter_pairing()` | Enter pairing | `func`
254
+ | `exit_pairing()` | Exit pairing | `func`
255
+ | `toggle()` | Toggle Bluetooth | `func` |
256
+
257
+ ```python
258
+ """Example"""
274
259
  # Enable Bluetooth
275
- vssl.settings.bluetooth = True
260
+ vssl.settings.bluetooth.on()
276
261
  # Toggle Bluetooth
277
- vssl.settings.bluetooth_toggle()
262
+ vssl.settings.bluetooth.toggle()
278
263
  ```
279
264
 
280
265
  ## `Vssl.settings.power`
281
266
 
282
267
  | Property | Description | Type | Values |
283
268
  | ---------------------- | ----------- | ----------- |----------- |
284
- | `state` | Power state | `int` readonly | `VsslPowerSettings.States`
269
+ | `state` | Power state | `int` readonly | [`VsslPowerSettings.States`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/settings.py#L243)
285
270
  | `adaptive` | Power adaptive | `bool`
286
271
 
287
272
  ```python
@@ -295,7 +280,7 @@ vssl.settings.power.adaptive = True
295
280
 
296
281
  | Property | Description | Type | Values |
297
282
  | ---------------------- | ----------- | ----------- |----------- |
298
- | `id` | Zone number / ID | `int` readonly | `ZoneIDs`
283
+ | `id` | Zone number / ID | `int` readonly | [`ZoneIDs`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/data_structure.py#L75)
299
284
  | `host` | IP address | `str` readonly
300
285
  | `volume` | Volume | `int` | `0...100`
301
286
  | `volume_raise([step=1])` | Raise volume by `step` | `func` | step: `int` `1...100`
@@ -308,8 +293,9 @@ vssl.settings.power.adaptive = True
308
293
  | `next()` | Next track | `func` |
309
294
  | `prev()` | Begining of track or previous track | `func` |
310
295
  | `reboot()` | Reboot zone | `func` |
311
- | `play_url([url], [all_zones])` | Play a URL | `func` | url: `str`, all_zones: `bool`
296
+ | `play_url([url], [all_zones], [volume])` | Play a URL | `func` | url: `str`<br/>all_zones: `bool`<br/>volume: `int` `1...100`
312
297
 
298
+ **Note:** `play_url()` is intended as a PA system. The zone will stop repsonding to commands (e.g transport, volume etc.) until the requested file has finished playing.
313
299
 
314
300
  ```python
315
301
  """Examples"""
@@ -325,19 +311,19 @@ zone1.mute_toggle()
325
311
  zone1.pause()
326
312
  # Next track
327
313
  zone1.next()
328
- # Play a URL on this zone1
329
- zone1.play_url('http://soundbible.com/grab.php?id=2217&type=mp3')
330
- # Play a URL on all zones
314
+ # Play a URL on this zone1 at 15% volume
315
+ zone1.play_url('http://soundbible.com/grab.php?id=2217&type=mp3', volume=15)
316
+ # Play a URL on all zones at current volume level
331
317
  zone1.play_url('http://soundbible.com/grab.php?id=2217&type=mp3', True)
332
318
  ```
333
319
 
334
320
  ## `Zone.transport`
335
321
 
336
- A VSSL amplifier can not start a stream except for playing a URL directly. This is a limitation of the hardware itself.
322
+ A VSSL amplifier can not start a stream except for when using `zone.play_url()`. This is a limitation of the hardware itself.
337
323
 
338
324
  | Property | Description | Type | Values |
339
325
  | ---------------------- | ----------- | ----------- |----------- |
340
- | `state` | Transport state. i.e Play, Stop, Pause | `int` | `ZoneTransport.States`
326
+ | `state` | Transport state. i.e Play, Stop, Pause | `int` | [`ZoneTransport.States`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/transport.py#L9)
341
327
  | `play()` | Play | `func` |
342
328
  | `stop()` | Stop | `func` |
343
329
  | `pause()` | Pause | `func` |
@@ -346,7 +332,7 @@ A VSSL amplifier can not start a stream except for playing a URL directly. This
346
332
  | `is_playing` | Is the zone playing | `bool` readonly
347
333
  | `is_stopped` | Is the zone stopped | `bool` readonly
348
334
  | `is_pasued` | Is the zone pasued | `bool` readonly
349
- | `is_repeat` | Repeat state. i.e all, one, off | `int` readonly | `ZoneTransport.Repeat`
335
+ | `is_repeat` | Repeat state. i.e all, one, off | `int` readonly | [`ZoneTransport.Repeat`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/transport.py#L19)
350
336
  | `is_shuffle` | Is shuffle enabled | `bool` readonly
351
337
  | `has_next` | Is the next button enabled | `bool` readonly
352
338
  | `has_prev` | Is the prev button enabled | `bool` readonly
@@ -373,7 +359,7 @@ zone1.transport.state = ZoneTransport.States.PAUSE
373
359
  | `duration` | Length in miliseconds (ms) | `int` readonly |
374
360
  | `progress` | Current position in miliseconds (ms) | `int` readonly |
375
361
  | `cover_art_url` | URL to cover art | `str` readonly |
376
- | `source` | Track source e.g Spotify | `int` readonly | `TrackMetadata.Sources`
362
+ | `source` | Track source e.g Spotify | `int` readonly | [`TrackMetadata.Sources`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/track.py#L28)
377
363
  | `url` | URL of file or track | `str` readonly |
378
364
 
379
365
 
@@ -381,12 +367,12 @@ zone1.transport.state = ZoneTransport.States.PAUSE
381
367
 
382
368
  | Property | Description | Type | Values |
383
369
  | ---------------------- | ----------- | ----------- |----------- |
384
- | `source` | Change input source.<br/>Source to be played out the zones speakers | `int` | `InputRouter.Sources`
385
- | `priority` | Change input priority.<br/>Stream or local to have precedence | `int` | `InputRouter.Priorities`
370
+ | `source` | Change input source.<br/>Source to be played out the zones speakers | `int` | [`InputRouter.Sources`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/io.py#L35)
371
+ | `priority` | Change input priority.<br/>Stream or local to have precedence | `int` | [`InputRouter.Priorities`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/io.py#L23)
386
372
 
387
373
 
388
- ### A.1(x) Source Routing Order
389
- A.1 and A.1x don't support manually changing the input source. Instead a fixed source routing order is used:
374
+ ### `A.1(x)` Source Routing Order
375
+ `A.1` and `A.1x` don't support manually changing the input source. Instead a fixed source routing order is used:
390
376
 
391
377
  1. Optical Input
392
378
  2. Coaxial Input
@@ -412,14 +398,12 @@ zone1.input.priority = InputRouter.Priorities.LOCAL
412
398
 
413
399
  ## `Zone.group`
414
400
 
415
- Unsupported on X series amplifiers.
416
-
417
401
  | Property | Description | Type | Values |
418
402
  | ---------------------- | ----------- | ----------- |----------- |
419
- | `source` | Zone ID of group master / source | `int` readonly | `ZoneIDs`
403
+ | `source` | Zone ID of group master / source | `int` readonly | [`ZoneIDs`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/data_structure.py#L75)
420
404
  | `is_master` | This zone is the group master | `bool` readonly
421
- | `add_member()` | Add zone to group / create group | `func` | `ZoneIDs`
422
- | `remove_member()` | Remove zone from group | `func` | `ZoneIDs`
405
+ | `add_member()` | Add zone to group / create group | `func` | [`ZoneIDs`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/data_structure.py#L75)
406
+ | `remove_member()` | Remove zone from group | `func` | [`ZoneIDs`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/data_structure.py#L75)
423
407
  | `dissolve()` | Dissolve group / remove all members | `func` |
424
408
  | `leave()` | Leave the group if a member | `func` |
425
409
  | `is_party_zone_member` | Member of Party Zone | `bool` |
@@ -443,7 +427,7 @@ zone1.group.is_party_zone_member_toggle()
443
427
 
444
428
  | Property | Description | Type | Values | Default |
445
429
  | ---------------------- | ----------- | ----------- |----------- |----------- |
446
- | `source` | Where the AO is routed from. i.e stream, optical input or off | `int` | `AnalogOutput.Sources` | `Off`
430
+ | `source` | Where the AO is routed from. i.e stream, optical input or off | `int` | [`AnalogOutput.Sources`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/io.py#L150) | `Off`
447
431
  | `is_fixed_volume` | Fix the output volume. Output wont respond to volume control | `bool` | |`False`
448
432
  | `is_fixed_volume_toggle()` | Toggle fixed volume | `func` |
449
433
 
@@ -466,7 +450,7 @@ zone1.analog_output.is_fixed_volume = True
466
450
  | `name` | Name | `str` |
467
451
  | `disabled` | Disable the zone | `bool` || `False`
468
452
  | `disabled_toggle()` | disable / enable | `func` |
469
- | `mono` | Set output to mono or stereo | `int` | `ZoneSettings.StereoMono` | `Stereo`
453
+ | `mono` | Set output to mono or stereo | `int` | [`ZoneSettings.StereoMono`](https://github.com/vsslctrl/vsslctrl/blob/644586fa183def1f23f0bfd239454fa8422e3dbe/vsslctrl/settings.py#L310) | `STEREO`
470
454
  | `mono_toggle()` | Toggle mono or stereo | `func` |
471
455
 
472
456
  ```python
@@ -474,9 +458,9 @@ zone1.analog_output.is_fixed_volume = True
474
458
  # Set name
475
459
  zone1.settings.name = 'Living Room'
476
460
  # Disable Zone
477
- zone1.disabled = True
461
+ zone1.settings.disabled = True
478
462
  # Toggle mono output
479
- zone1.mono_toggle()
463
+ zone1.settings.mono_toggle()
480
464
  ```
481
465
 
482
466
  ## `Zone.settings.analog_input`
@@ -509,7 +493,7 @@ zone1.settings.analog_input.fixed_gain = 50
509
493
  # Set default on volume to 50%
510
494
  zone1.settings.volume.default_on = 50
511
495
  # Set maximum volume for left channel to 75%
512
- zone1.settings.volume.default_on = 75
496
+ zone1.settings.volume.max_left = 75
513
497
  ```
514
498
 
515
499
  ## `Zone.settings.eq`
@@ -538,7 +522,7 @@ zone1.settings.eq.khz1_db = -2
538
522
 
539
523
  ## `Zone.settings.subwoofer`
540
524
 
541
- * **A.1 and A.1x only**
525
+ * **`A.1` and `A.1x` only**
542
526
  * Set `0` for full frequency range
543
527
 
544
528
  | Property | Description | Type | Values | Default |
@@ -561,12 +545,9 @@ Motivation for this project was to integrate VSSLs amplifiers into [Home Assista
561
545
 
562
546
  ## Known Issues & Limitiations
563
547
 
564
- * Not tested on A.1x or original A series range of amplifiers (testers welcome)
565
548
  * VSSL can not start a stream except for playing a URL directly. This is a limitation of the hardware itself.
566
549
  * Not all sources set the volume to 0 when the zone is muted
567
550
  * Airplay `Zone.track.progress` is not available.
568
- * Cant stop a URL playback, feedback is worng at least
569
551
  * VSSL likes to cache old track metadata. For example when playing a URL after Spotify, often the device will respond with the previous (Spotify) tracks metadata
570
552
  * `stop()` is intended to disconnect the client and pause the stream. Doesn’t always function this way, depending on stream source
571
- * Occasionally a zones might stop responding to certain commands, issuing the `reboot` command generally corrects
572
553