vsslctrl 0.1.5.dev1__tar.gz → 0.1.6.dev1__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 (32) hide show
  1. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/PKG-INFO +47 -48
  2. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/README.md +45 -46
  3. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/pyproject.toml +2 -2
  4. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/api_alpha.py +8 -6
  5. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/api_bravo.py +5 -3
  6. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/core.py +1 -1
  7. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/data_structure.py +6 -1
  8. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/utils.py +13 -0
  9. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/zone.py +5 -0
  10. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl.egg-info/PKG-INFO +47 -48
  11. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/LICENSE +0 -0
  12. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/setup.cfg +0 -0
  13. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/tests/test_event_bus.py +0 -0
  14. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/tests/test_integration.py +0 -0
  15. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/tests/test_settings.py +0 -0
  16. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/tests/test_zone.py +0 -0
  17. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/__init__.py +0 -0
  18. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/api_base.py +0 -0
  19. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/decorators.py +0 -0
  20. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/device.py +0 -0
  21. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/discovery.py +0 -0
  22. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/event_bus.py +0 -0
  23. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/exceptions.py +0 -0
  24. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/group.py +0 -0
  25. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/io.py +0 -0
  26. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/settings.py +0 -0
  27. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/track.py +0 -0
  28. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl/transport.py +0 -0
  29. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl.egg-info/SOURCES.txt +0 -0
  30. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl.egg-info/dependency_links.txt +0 -0
  31. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl.egg-info/requires.txt +0 -0
  32. {vsslctrl-0.1.5.dev1 → vsslctrl-0.1.6.dev1}/vsslctrl.egg-info/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vsslctrl
3
- Version: 0.1.5.dev1
4
- Summary: Package for controlling VSSL amplifiers
3
+ Version: 0.1.6.dev1
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
7
7
  Classifier: Programming Language :: Python :: 3
@@ -20,31 +20,30 @@ Provides-Extra: optional
20
20
  Requires-Dist: zeroconf==0.132.2; extra == "optional"
21
21
 
22
22
  # vsslctrl
23
- Package for controlling [VSSL](https://www.vssl.com/) range of streaming amplifiers.
23
+
24
+ Package for controlling [VSSL's](https://www.vssl.com/) range of streaming amplifiers.
24
25
 
25
26
  **`vsslctrl` is not endorsed or affiliated with [VSSL](https://www.vssl.com/) in any manner.**
26
27
 
27
- Motovation for this project was to intergrate VSSLs amplifiers into [Home Assistant](https://www.home-assistant.io/) and have control over different subnets (not mDNS dependant)
28
+ ## Help
28
29
 
29
- I am looking for testers with any VSSL amplifier models, please get in touch if you interested in helping.
30
+ I am looking for testers with any VSSL amplifier models, please get in touch if you interested in helping. <vsslcontrolled@proton.me>
30
31
 
31
- Important
32
- -----------
33
- Only tested on a VSSL **A.3x** software version **p15305.016.3701**.
32
+ Tested on:
33
+ - Test suite run on a VSSL **A.3x** software version **p15305.016.3701**
34
+ - The Home Assistant [integration](https://github.com/vsslctrl/integration.home-assistant) is reported working on a **A.6x** software version **p15305.017.3701**
34
35
 
35
- **Notice:** VSSLs new iOS app titled `VSSL`can cause connection refused issues if running at the same time as `vsslctrl`. Best to not use the iOS app togeather. The `VSSL Legacy` app works fine
36
+ ## Important
36
37
 
37
- **Warning:** no *[VSSL Agent](https://vssl.gitbook.io/vssl-rest-api/getting-started/start)* should be running on the same network. If you dont know what this is, then you can probably ignore this notice.
38
+ There should not be any *[VSSL Agent's](https://vssl.gitbook.io/vssl-rest-api/getting-started/start)* running on the same network. If you dont know what this is, then you can ignore this notice.
38
39
 
39
40
  ## TODOs
40
41
 
41
- * Test on other models (hardware needed)
42
- * Home Assistant integration. In progress, [here](https://github.com/vsslctrl/integration.home-assistant)
43
- * ~~Function scoping to supported feature / models~~ (needs tests)
42
+ * **A1(.x)** specific control e.g sub crossover, bluetooth
44
43
  * Better test coverage
45
44
 
46
- Basic Usage
47
- -----------
45
+ ## Basic Usage
46
+
48
47
  `vsslctrl` needs to be running inside a **[asyncio](https://docs.python.org/3/library/asyncio.html)** event loop.
49
48
 
50
49
  ```python
@@ -91,8 +90,7 @@ async def main():
91
90
  asyncio.run(main())
92
91
  ```
93
92
 
94
- API
95
- -----------
93
+ # API
96
94
 
97
95
  Most functionality is achived via `getters` and `setters` of the two main classes `Vssl`, `Zone`.
98
96
 
@@ -284,10 +282,10 @@ zone1.group.dissolve()
284
282
 
285
283
  ## `Zone.analog_output`
286
284
 
287
- | Property | Description | Type | Values |
288
- | ---------------------- | ----------- | ----------- |----------- |
289
- | `source` | Where the AO is routed from. i.e a zone, optical input or off | `int` | `AnalogOutput.Sources`
290
- | `is_fixed_volume` | Fix the output volume. Output wont respond to volume control | `bool` readonly
285
+ | Property | Description | Type | Values | Default |
286
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
287
+ | `source` | Where the AO is routed from. i.e a zone, optical input or off | `int` | `AnalogOutput.Sources` | `Off`
288
+ | `is_fixed_volume` | Fix the output volume. Output wont respond to volume control | `bool` | |`False`
291
289
  | `is_fixed_volume_toggle()` | Toggle fixed volume | `func` |
292
290
 
293
291
  ```python
@@ -304,12 +302,12 @@ zone1.analog_output.is_fixed_volume = True
304
302
 
305
303
  ## `Zone.settings`
306
304
 
307
- | Property | Description | Type | Values |
308
- | ---------------------- | ----------- | ----------- |----------- |
305
+ | Property | Description | Type | Values | Default |
306
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
309
307
  | `name` | Name | `str` |
310
- | `disabled` | Disable the zone | `bool`
308
+ | `disabled` | Disable the zone | `bool` || `False`
311
309
  | `disabled_toggle()` | disable / enable | `func` |
312
- | `mono` | Set output to mono or stereo | `int` | `ZoneSettings.StereoMono`
310
+ | `mono` | Set output to mono or stereo | `int` | `ZoneSettings.StereoMono` | `Stereo`
313
311
  | `mono_toggle()` | Toggle mono or stereo | `func` |
314
312
 
315
313
  ```python
@@ -324,10 +322,10 @@ zone1.mono_toggle()
324
322
 
325
323
  ## `Zone.settings.analog_input`
326
324
 
327
- | Property | Description | Type | Values |
328
- | ---------------------- | ----------- | ----------- |----------- |
325
+ | Property | Description | Type | Values | Default |
326
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
329
327
  | `name` | Name | `str` |
330
- | `fixed_gain` | Fix the input gain to a specific value |`int` | `0...100`
328
+ | `fixed_gain` | Fix the input gain to a specific value |`int` | `0...100` | `0` is disabled or variable gain
331
329
 
332
330
  ```python
333
331
  """Examples"""
@@ -341,11 +339,11 @@ zone1.settings.analog_input.fixed_gain = 50
341
339
 
342
340
  ## `Zone.settings.volume`
343
341
 
344
- | Property | Description | Type | Values |
345
- | ---------------------- | ----------- | ----------- |----------- |
346
- | `default_on` | Default on volume | `int` | `0...100`
347
- | `max_left` | Max volume left channel | `int` | `0...100`
348
- | `max_right` | Max volume right channel | `int` | `0...100`
342
+ | Property | Description | Type | Values | Default |
343
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
344
+ | `default_on` | Default on volume | `int` | `0...100` | `0` is disabled
345
+ | `max_left` | Max volume left channel | `int` | `0...100` | `75`
346
+ | `max_right` | Max volume right channel | `int` | `0...100` | `75`
349
347
 
350
348
  ```python
351
349
  """Examples"""
@@ -357,21 +355,21 @@ zone1.settings.volume.default_on = 75
357
355
 
358
356
  ## `Zone.settings.eq`
359
357
 
360
- | Property | Description | Type | Values |
361
- | ---------------------- | ----------- | ----------- |----------- |
362
- | `enabled` | Enable / disable EQ | `bool`
358
+ | Property | Description | Type | Values | Default |
359
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
360
+ | `enabled` | Enable / disable EQ | `bool` | | `False`
363
361
 
364
362
  EQ to be set in [decibel](https://en.wikipedia.org/wiki/Decibel) using a range `-10`dB to `+10`dB
365
363
 
366
- | Property | Description | Type | Values |
367
- | ---------------------- | ----------- | ----------- |----------- |
368
- | `hz60_db` | 60Hz | `int` | `-10...10`
369
- | `hz200_db` | 200Hz | `int` | `-10...10`
370
- | `hz500_db` | 500Hz | `int` | `-10...10`
371
- | `khz1_db` | 1kHz | `int` | `-10...10`
372
- | `khz4_db` | 4kHz | `int` | `-10...10`
373
- | `khz8_db` | 8kHz | `int` | `-10...10`
374
- | `khz15_db` | 15kHz | `int` | `-10...10`
364
+ | Property | Description | Type | Values | Default |
365
+ | ---------------------- | ----------- | ----------- |----------- | ----------- |
366
+ | `hz60_db` | 60Hz | `int` | `-10...10` | `0`
367
+ | `hz200_db` | 200Hz | `int` | `-10...10` | `0`
368
+ | `hz500_db` | 500Hz | `int` | `-10...10` | `0`
369
+ | `khz1_db` | 1kHz | `int` | `-10...10` | `0`
370
+ | `khz4_db` | 4kHz | `int` | `-10...10` | `0`
371
+ | `khz8_db` | 8kHz | `int` | `-10...10` | `0`
372
+ | `khz15_db` | 15kHz | `int` | `-10...10` | `0`
375
373
 
376
374
  ```python
377
375
  """Examples"""
@@ -430,10 +428,11 @@ shell_command:
430
428
 
431
429
  The VSSL API was reverse engineered using Wireshark, VSSLs native "legacy" iOS app and their deprecated [vsslagent](https://vssl.gitbook.io/vssl-rest-api/getting-started/start).
432
430
 
431
+ Motovation for this project was to intergrate VSSLs amplifiers into [Home Assistant](https://www.home-assistant.io/) and have control over different subnets (not mDNS dependant)
432
+
433
433
  ## Known Issues & Limitiations
434
434
 
435
- * Tested on VSSL **A.3x** software version **p15305.016.3701**
436
- * Not tested on A.1x, A.6.x or original A series range of amplifiers (testers welcome)
435
+ * Not tested on A.1x or original A series range of amplifiers (testers welcome)
437
436
  * VSSL can not start a stream except for playing a URL directly. This is a limitation of the hardware itself.
438
437
  * Not all sources set the volume to 0 when the zone is muted
439
438
  * Grouping feedback is flaky on the X series amplifiers
@@ -445,8 +444,8 @@ The VSSL API was reverse engineered using Wireshark, VSSLs native "legacy" iOS a
445
444
 
446
445
  ## Future
447
446
 
447
+ * A.1(x) coverage i.e Bluetooth and subwoofer control
448
448
  * REST API / Web App
449
449
  * Save and recall EQ
450
- * A.1(x) coverage i.e Bluetooth
451
450
  * IR Control
452
451
 
@@ -1,29 +1,28 @@
1
1
  # vsslctrl
2
- Package for controlling [VSSL](https://www.vssl.com/) range of streaming amplifiers.
2
+
3
+ Package for controlling [VSSL's](https://www.vssl.com/) range of streaming amplifiers.
3
4
 
4
5
  **`vsslctrl` is not endorsed or affiliated with [VSSL](https://www.vssl.com/) in any manner.**
5
6
 
6
- Motovation for this project was to intergrate VSSLs amplifiers into [Home Assistant](https://www.home-assistant.io/) and have control over different subnets (not mDNS dependant)
7
+ ## Help
7
8
 
8
- I am looking for testers with any VSSL amplifier models, please get in touch if you interested in helping.
9
+ I am looking for testers with any VSSL amplifier models, please get in touch if you interested in helping. <vsslcontrolled@proton.me>
9
10
 
10
- Important
11
- -----------
12
- Only tested on a VSSL **A.3x** software version **p15305.016.3701**.
11
+ Tested on:
12
+ - Test suite run on a VSSL **A.3x** software version **p15305.016.3701**
13
+ - The Home Assistant [integration](https://github.com/vsslctrl/integration.home-assistant) is reported working on a **A.6x** software version **p15305.017.3701**
13
14
 
14
- **Notice:** VSSLs new iOS app titled `VSSL`can cause connection refused issues if running at the same time as `vsslctrl`. Best to not use the iOS app togeather. The `VSSL Legacy` app works fine
15
+ ## Important
15
16
 
16
- **Warning:** no *[VSSL Agent](https://vssl.gitbook.io/vssl-rest-api/getting-started/start)* should be running on the same network. If you dont know what this is, then you can probably ignore this notice.
17
+ There should not be any *[VSSL Agent's](https://vssl.gitbook.io/vssl-rest-api/getting-started/start)* running on the same network. If you dont know what this is, then you can ignore this notice.
17
18
 
18
19
  ## TODOs
19
20
 
20
- * Test on other models (hardware needed)
21
- * Home Assistant integration. In progress, [here](https://github.com/vsslctrl/integration.home-assistant)
22
- * ~~Function scoping to supported feature / models~~ (needs tests)
21
+ * **A1(.x)** specific control e.g sub crossover, bluetooth
23
22
  * Better test coverage
24
23
 
25
- Basic Usage
26
- -----------
24
+ ## Basic Usage
25
+
27
26
  `vsslctrl` needs to be running inside a **[asyncio](https://docs.python.org/3/library/asyncio.html)** event loop.
28
27
 
29
28
  ```python
@@ -70,8 +69,7 @@ async def main():
70
69
  asyncio.run(main())
71
70
  ```
72
71
 
73
- API
74
- -----------
72
+ # API
75
73
 
76
74
  Most functionality is achived via `getters` and `setters` of the two main classes `Vssl`, `Zone`.
77
75
 
@@ -263,10 +261,10 @@ zone1.group.dissolve()
263
261
 
264
262
  ## `Zone.analog_output`
265
263
 
266
- | Property | Description | Type | Values |
267
- | ---------------------- | ----------- | ----------- |----------- |
268
- | `source` | Where the AO is routed from. i.e a zone, optical input or off | `int` | `AnalogOutput.Sources`
269
- | `is_fixed_volume` | Fix the output volume. Output wont respond to volume control | `bool` readonly
264
+ | Property | Description | Type | Values | Default |
265
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
266
+ | `source` | Where the AO is routed from. i.e a zone, optical input or off | `int` | `AnalogOutput.Sources` | `Off`
267
+ | `is_fixed_volume` | Fix the output volume. Output wont respond to volume control | `bool` | |`False`
270
268
  | `is_fixed_volume_toggle()` | Toggle fixed volume | `func` |
271
269
 
272
270
  ```python
@@ -283,12 +281,12 @@ zone1.analog_output.is_fixed_volume = True
283
281
 
284
282
  ## `Zone.settings`
285
283
 
286
- | Property | Description | Type | Values |
287
- | ---------------------- | ----------- | ----------- |----------- |
284
+ | Property | Description | Type | Values | Default |
285
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
288
286
  | `name` | Name | `str` |
289
- | `disabled` | Disable the zone | `bool`
287
+ | `disabled` | Disable the zone | `bool` || `False`
290
288
  | `disabled_toggle()` | disable / enable | `func` |
291
- | `mono` | Set output to mono or stereo | `int` | `ZoneSettings.StereoMono`
289
+ | `mono` | Set output to mono or stereo | `int` | `ZoneSettings.StereoMono` | `Stereo`
292
290
  | `mono_toggle()` | Toggle mono or stereo | `func` |
293
291
 
294
292
  ```python
@@ -303,10 +301,10 @@ zone1.mono_toggle()
303
301
 
304
302
  ## `Zone.settings.analog_input`
305
303
 
306
- | Property | Description | Type | Values |
307
- | ---------------------- | ----------- | ----------- |----------- |
304
+ | Property | Description | Type | Values | Default |
305
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
308
306
  | `name` | Name | `str` |
309
- | `fixed_gain` | Fix the input gain to a specific value |`int` | `0...100`
307
+ | `fixed_gain` | Fix the input gain to a specific value |`int` | `0...100` | `0` is disabled or variable gain
310
308
 
311
309
  ```python
312
310
  """Examples"""
@@ -320,11 +318,11 @@ zone1.settings.analog_input.fixed_gain = 50
320
318
 
321
319
  ## `Zone.settings.volume`
322
320
 
323
- | Property | Description | Type | Values |
324
- | ---------------------- | ----------- | ----------- |----------- |
325
- | `default_on` | Default on volume | `int` | `0...100`
326
- | `max_left` | Max volume left channel | `int` | `0...100`
327
- | `max_right` | Max volume right channel | `int` | `0...100`
321
+ | Property | Description | Type | Values | Default |
322
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
323
+ | `default_on` | Default on volume | `int` | `0...100` | `0` is disabled
324
+ | `max_left` | Max volume left channel | `int` | `0...100` | `75`
325
+ | `max_right` | Max volume right channel | `int` | `0...100` | `75`
328
326
 
329
327
  ```python
330
328
  """Examples"""
@@ -336,21 +334,21 @@ zone1.settings.volume.default_on = 75
336
334
 
337
335
  ## `Zone.settings.eq`
338
336
 
339
- | Property | Description | Type | Values |
340
- | ---------------------- | ----------- | ----------- |----------- |
341
- | `enabled` | Enable / disable EQ | `bool`
337
+ | Property | Description | Type | Values | Default |
338
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
339
+ | `enabled` | Enable / disable EQ | `bool` | | `False`
342
340
 
343
341
  EQ to be set in [decibel](https://en.wikipedia.org/wiki/Decibel) using a range `-10`dB to `+10`dB
344
342
 
345
- | Property | Description | Type | Values |
346
- | ---------------------- | ----------- | ----------- |----------- |
347
- | `hz60_db` | 60Hz | `int` | `-10...10`
348
- | `hz200_db` | 200Hz | `int` | `-10...10`
349
- | `hz500_db` | 500Hz | `int` | `-10...10`
350
- | `khz1_db` | 1kHz | `int` | `-10...10`
351
- | `khz4_db` | 4kHz | `int` | `-10...10`
352
- | `khz8_db` | 8kHz | `int` | `-10...10`
353
- | `khz15_db` | 15kHz | `int` | `-10...10`
343
+ | Property | Description | Type | Values | Default |
344
+ | ---------------------- | ----------- | ----------- |----------- | ----------- |
345
+ | `hz60_db` | 60Hz | `int` | `-10...10` | `0`
346
+ | `hz200_db` | 200Hz | `int` | `-10...10` | `0`
347
+ | `hz500_db` | 500Hz | `int` | `-10...10` | `0`
348
+ | `khz1_db` | 1kHz | `int` | `-10...10` | `0`
349
+ | `khz4_db` | 4kHz | `int` | `-10...10` | `0`
350
+ | `khz8_db` | 8kHz | `int` | `-10...10` | `0`
351
+ | `khz15_db` | 15kHz | `int` | `-10...10` | `0`
354
352
 
355
353
  ```python
356
354
  """Examples"""
@@ -409,10 +407,11 @@ shell_command:
409
407
 
410
408
  The VSSL API was reverse engineered using Wireshark, VSSLs native "legacy" iOS app and their deprecated [vsslagent](https://vssl.gitbook.io/vssl-rest-api/getting-started/start).
411
409
 
410
+ Motovation for this project was to intergrate VSSLs amplifiers into [Home Assistant](https://www.home-assistant.io/) and have control over different subnets (not mDNS dependant)
411
+
412
412
  ## Known Issues & Limitiations
413
413
 
414
- * Tested on VSSL **A.3x** software version **p15305.016.3701**
415
- * Not tested on A.1x, A.6.x or original A series range of amplifiers (testers welcome)
414
+ * Not tested on A.1x or original A series range of amplifiers (testers welcome)
416
415
  * VSSL can not start a stream except for playing a URL directly. This is a limitation of the hardware itself.
417
416
  * Not all sources set the volume to 0 when the zone is muted
418
417
  * Grouping feedback is flaky on the X series amplifiers
@@ -424,8 +423,8 @@ The VSSL API was reverse engineered using Wireshark, VSSLs native "legacy" iOS a
424
423
 
425
424
  ## Future
426
425
 
426
+ * A.1(x) coverage i.e Bluetooth and subwoofer control
427
427
  * REST API / Web App
428
428
  * Save and recall EQ
429
- * A.1(x) coverage i.e Bluetooth
430
429
  * IR Control
431
430
 
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "vsslctrl"
7
- version = "0.1.5.dev1"
8
- description = "Package for controlling VSSL amplifiers"
7
+ version = "0.1.6.dev1"
8
+ description = "Package for controlling VSSL's range of streaming amplifiers"
9
9
  authors = [
10
10
  { name="vsslctrl", email="vsslcontrolled@proton.me" },
11
11
  ]
@@ -9,7 +9,7 @@ from .api_base import APIBase
9
9
  from .transport import ZoneTransport
10
10
  from .settings import EQSettings
11
11
 
12
- from .utils import hex_to_int, clamp_volume
12
+ from .utils import hex_to_int, clamp_volume, hex_to_bytearray_string
13
13
  from .decorators import logging_helpers
14
14
  from .data_structure import (
15
15
  ZoneStatusExtKeys,
@@ -199,7 +199,7 @@ class APIAlpha(APIBase):
199
199
  # EQ
200
200
  #
201
201
  def request_action_0D(self, freq: "EQSettings.Freqs", value: int = 0):
202
- clamped = max(90, min(value, 110))
202
+ clamped = max(EQSettings.MIN_VALUE, min(value, EQSettings.MAX_VALUE))
203
203
  self._log_debug(
204
204
  f"Requesting to set EQ: {freq.name[1:]} ({freq.value}) to {clamped}"
205
205
  )
@@ -924,9 +924,9 @@ class APIAlpha(APIBase):
924
924
 
925
925
  #
926
926
  # 17 [23]
927
- # Received Keep Alive
927
+ # Keep Alive
928
928
  #
929
- def response_action_17(self, response: bytes):
929
+ def response_action_17(self, hexl: list, response: bytes):
930
930
  self._log_debug(f"Z{self.zone.id} Alpha - Received keep alive: {response}")
931
931
  # TODO
932
932
  pass
@@ -1026,8 +1026,9 @@ class APIAlpha(APIBase):
1026
1026
  # Command confimation
1027
1027
  #
1028
1028
  def response_action_confimation(self, response: bytes):
1029
+ cmd = response.hex()
1029
1030
  self._log_debug(
1030
- f"Received command confimation: {response[1]}. Hex: {response.hex()}"
1031
+ f"Received command confimation: {hex_to_bytearray_string(cmd)} Hex: {cmd}"
1031
1032
  )
1032
1033
 
1033
1034
  #
@@ -1035,6 +1036,7 @@ class APIAlpha(APIBase):
1035
1036
  # Default Action
1036
1037
  #
1037
1038
  def response_action_default(self, hexl: list, response: bytes):
1039
+ cmd = response.hex()
1038
1040
  self._log_debug(
1039
- f"Received unknown command {hexl[1].upper()}. Hex: {response.hex()}"
1041
+ f"Received unknown command: {hex_to_bytearray_string(cmd)} Hex: {cmd}"
1040
1042
  )
@@ -5,7 +5,7 @@ import struct
5
5
  import logging
6
6
 
7
7
  from .api_base import APIBase
8
- from .utils import hex_to_int
8
+ from .utils import hex_to_int, hex_to_bytearray_string
9
9
  from .decorators import logging_helpers
10
10
  from .data_structure import TrackMetadataExtKeys
11
11
 
@@ -407,8 +407,10 @@ class APIBravo(APIBase):
407
407
  #
408
408
  def response_action_70(self, hexl: list, response: bytes):
409
409
  length = 4 if hexl[0] == 16 else 10
410
- cmd = hexl[length:]
411
- self._log_debug(f"Command confirmation: {response[length:]}")
410
+ cmd = response[length:].hex()
411
+ self._log_debug(
412
+ f"Received command confimation: {hex_to_bytearray_string(cmd)} Hex: {cmd}"
413
+ )
412
414
 
413
415
  #
414
416
  # Default
@@ -69,7 +69,7 @@ class Vssl:
69
69
  self.Events.MODEL_CHANGE, self.ENTITY_ID
70
70
  )
71
71
 
72
- # Lets make sure the zone is initialised, otherwsie we fail all
72
+ # Lets make sure the zone is initialised, otherwsie we fail for all zones
73
73
  await first_zone.initialise()
74
74
 
75
75
  # Only continue after we have a model
@@ -253,7 +253,12 @@ class ZoneRouterStatusExtKeys:
253
253
  EQ_ENABLED = "eqsw"
254
254
  INPUT_SOURCE = "inSrc"
255
255
  SOURCE_PRIORITY = "SP"
256
- ANALOG_OUTPUT_FIXED_VOLUME_PREFIX = "BF"
256
+ ANALOG_OUTPUT_1_FIXED_VOLUME = "BF1"
257
+ ANALOG_OUTPUT_2_FIXED_VOLUME = "BF2"
258
+ ANALOG_OUTPUT_3_FIXED_VOLUME = "BF3"
259
+ ANALOG_OUTPUT_4_FIXED_VOLUME = "BF4"
260
+ ANALOG_OUTPUT_5_FIXED_VOLUME = "BF5"
261
+ ANALOG_OUTPUT_6_FIXED_VOLUME = "BF6"
257
262
  GROUP_SOURCE = "GRS"
258
263
  GROUP_MASTER = "GRM"
259
264
  POWER_STATE = "Pwr"
@@ -38,6 +38,19 @@ def group_list_by_property(input_list, property_key):
38
38
  return grouped_dict
39
39
 
40
40
 
41
+ #
42
+ # Logging Helper to show a command in bytearray([]) syntax
43
+ #
44
+ def hex_to_bytearray_string(hex_string):
45
+ # Convert the hex string to a bytearray
46
+ byte_array = bytearray.fromhex(hex_string)
47
+
48
+ # Create the bytearray string representation
49
+ bytearray_str = f'bytearray([{", ".join(map(str, byte_array))}])'
50
+
51
+ return bytearray_str
52
+
53
+
41
54
  #
42
55
  # Repeat Timer
43
56
  #
@@ -267,6 +267,11 @@ class Zone:
267
267
  def _set_mac_addr(self, mac: str):
268
268
  mac = mac.strip()
269
269
  if mac != self.mac_addr:
270
+ # Strip Wlan0: from beginging of string
271
+ # Original A series amps had this prefix
272
+ if mac.startswith("Wlan0:"):
273
+ mac = mac[len("Wlan0:") :]
274
+
270
275
  # Define the regular expression pattern for a MAC address
271
276
  mac_pattern = re.compile(r"^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$")
272
277
 
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vsslctrl
3
- Version: 0.1.5.dev1
4
- Summary: Package for controlling VSSL amplifiers
3
+ Version: 0.1.6.dev1
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
7
7
  Classifier: Programming Language :: Python :: 3
@@ -20,31 +20,30 @@ Provides-Extra: optional
20
20
  Requires-Dist: zeroconf==0.132.2; extra == "optional"
21
21
 
22
22
  # vsslctrl
23
- Package for controlling [VSSL](https://www.vssl.com/) range of streaming amplifiers.
23
+
24
+ Package for controlling [VSSL's](https://www.vssl.com/) range of streaming amplifiers.
24
25
 
25
26
  **`vsslctrl` is not endorsed or affiliated with [VSSL](https://www.vssl.com/) in any manner.**
26
27
 
27
- Motovation for this project was to intergrate VSSLs amplifiers into [Home Assistant](https://www.home-assistant.io/) and have control over different subnets (not mDNS dependant)
28
+ ## Help
28
29
 
29
- I am looking for testers with any VSSL amplifier models, please get in touch if you interested in helping.
30
+ I am looking for testers with any VSSL amplifier models, please get in touch if you interested in helping. <vsslcontrolled@proton.me>
30
31
 
31
- Important
32
- -----------
33
- Only tested on a VSSL **A.3x** software version **p15305.016.3701**.
32
+ Tested on:
33
+ - Test suite run on a VSSL **A.3x** software version **p15305.016.3701**
34
+ - The Home Assistant [integration](https://github.com/vsslctrl/integration.home-assistant) is reported working on a **A.6x** software version **p15305.017.3701**
34
35
 
35
- **Notice:** VSSLs new iOS app titled `VSSL`can cause connection refused issues if running at the same time as `vsslctrl`. Best to not use the iOS app togeather. The `VSSL Legacy` app works fine
36
+ ## Important
36
37
 
37
- **Warning:** no *[VSSL Agent](https://vssl.gitbook.io/vssl-rest-api/getting-started/start)* should be running on the same network. If you dont know what this is, then you can probably ignore this notice.
38
+ There should not be any *[VSSL Agent's](https://vssl.gitbook.io/vssl-rest-api/getting-started/start)* running on the same network. If you dont know what this is, then you can ignore this notice.
38
39
 
39
40
  ## TODOs
40
41
 
41
- * Test on other models (hardware needed)
42
- * Home Assistant integration. In progress, [here](https://github.com/vsslctrl/integration.home-assistant)
43
- * ~~Function scoping to supported feature / models~~ (needs tests)
42
+ * **A1(.x)** specific control e.g sub crossover, bluetooth
44
43
  * Better test coverage
45
44
 
46
- Basic Usage
47
- -----------
45
+ ## Basic Usage
46
+
48
47
  `vsslctrl` needs to be running inside a **[asyncio](https://docs.python.org/3/library/asyncio.html)** event loop.
49
48
 
50
49
  ```python
@@ -91,8 +90,7 @@ async def main():
91
90
  asyncio.run(main())
92
91
  ```
93
92
 
94
- API
95
- -----------
93
+ # API
96
94
 
97
95
  Most functionality is achived via `getters` and `setters` of the two main classes `Vssl`, `Zone`.
98
96
 
@@ -284,10 +282,10 @@ zone1.group.dissolve()
284
282
 
285
283
  ## `Zone.analog_output`
286
284
 
287
- | Property | Description | Type | Values |
288
- | ---------------------- | ----------- | ----------- |----------- |
289
- | `source` | Where the AO is routed from. i.e a zone, optical input or off | `int` | `AnalogOutput.Sources`
290
- | `is_fixed_volume` | Fix the output volume. Output wont respond to volume control | `bool` readonly
285
+ | Property | Description | Type | Values | Default |
286
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
287
+ | `source` | Where the AO is routed from. i.e a zone, optical input or off | `int` | `AnalogOutput.Sources` | `Off`
288
+ | `is_fixed_volume` | Fix the output volume. Output wont respond to volume control | `bool` | |`False`
291
289
  | `is_fixed_volume_toggle()` | Toggle fixed volume | `func` |
292
290
 
293
291
  ```python
@@ -304,12 +302,12 @@ zone1.analog_output.is_fixed_volume = True
304
302
 
305
303
  ## `Zone.settings`
306
304
 
307
- | Property | Description | Type | Values |
308
- | ---------------------- | ----------- | ----------- |----------- |
305
+ | Property | Description | Type | Values | Default |
306
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
309
307
  | `name` | Name | `str` |
310
- | `disabled` | Disable the zone | `bool`
308
+ | `disabled` | Disable the zone | `bool` || `False`
311
309
  | `disabled_toggle()` | disable / enable | `func` |
312
- | `mono` | Set output to mono or stereo | `int` | `ZoneSettings.StereoMono`
310
+ | `mono` | Set output to mono or stereo | `int` | `ZoneSettings.StereoMono` | `Stereo`
313
311
  | `mono_toggle()` | Toggle mono or stereo | `func` |
314
312
 
315
313
  ```python
@@ -324,10 +322,10 @@ zone1.mono_toggle()
324
322
 
325
323
  ## `Zone.settings.analog_input`
326
324
 
327
- | Property | Description | Type | Values |
328
- | ---------------------- | ----------- | ----------- |----------- |
325
+ | Property | Description | Type | Values | Default |
326
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
329
327
  | `name` | Name | `str` |
330
- | `fixed_gain` | Fix the input gain to a specific value |`int` | `0...100`
328
+ | `fixed_gain` | Fix the input gain to a specific value |`int` | `0...100` | `0` is disabled or variable gain
331
329
 
332
330
  ```python
333
331
  """Examples"""
@@ -341,11 +339,11 @@ zone1.settings.analog_input.fixed_gain = 50
341
339
 
342
340
  ## `Zone.settings.volume`
343
341
 
344
- | Property | Description | Type | Values |
345
- | ---------------------- | ----------- | ----------- |----------- |
346
- | `default_on` | Default on volume | `int` | `0...100`
347
- | `max_left` | Max volume left channel | `int` | `0...100`
348
- | `max_right` | Max volume right channel | `int` | `0...100`
342
+ | Property | Description | Type | Values | Default |
343
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
344
+ | `default_on` | Default on volume | `int` | `0...100` | `0` is disabled
345
+ | `max_left` | Max volume left channel | `int` | `0...100` | `75`
346
+ | `max_right` | Max volume right channel | `int` | `0...100` | `75`
349
347
 
350
348
  ```python
351
349
  """Examples"""
@@ -357,21 +355,21 @@ zone1.settings.volume.default_on = 75
357
355
 
358
356
  ## `Zone.settings.eq`
359
357
 
360
- | Property | Description | Type | Values |
361
- | ---------------------- | ----------- | ----------- |----------- |
362
- | `enabled` | Enable / disable EQ | `bool`
358
+ | Property | Description | Type | Values | Default |
359
+ | ---------------------- | ----------- | ----------- |----------- |----------- |
360
+ | `enabled` | Enable / disable EQ | `bool` | | `False`
363
361
 
364
362
  EQ to be set in [decibel](https://en.wikipedia.org/wiki/Decibel) using a range `-10`dB to `+10`dB
365
363
 
366
- | Property | Description | Type | Values |
367
- | ---------------------- | ----------- | ----------- |----------- |
368
- | `hz60_db` | 60Hz | `int` | `-10...10`
369
- | `hz200_db` | 200Hz | `int` | `-10...10`
370
- | `hz500_db` | 500Hz | `int` | `-10...10`
371
- | `khz1_db` | 1kHz | `int` | `-10...10`
372
- | `khz4_db` | 4kHz | `int` | `-10...10`
373
- | `khz8_db` | 8kHz | `int` | `-10...10`
374
- | `khz15_db` | 15kHz | `int` | `-10...10`
364
+ | Property | Description | Type | Values | Default |
365
+ | ---------------------- | ----------- | ----------- |----------- | ----------- |
366
+ | `hz60_db` | 60Hz | `int` | `-10...10` | `0`
367
+ | `hz200_db` | 200Hz | `int` | `-10...10` | `0`
368
+ | `hz500_db` | 500Hz | `int` | `-10...10` | `0`
369
+ | `khz1_db` | 1kHz | `int` | `-10...10` | `0`
370
+ | `khz4_db` | 4kHz | `int` | `-10...10` | `0`
371
+ | `khz8_db` | 8kHz | `int` | `-10...10` | `0`
372
+ | `khz15_db` | 15kHz | `int` | `-10...10` | `0`
375
373
 
376
374
  ```python
377
375
  """Examples"""
@@ -430,10 +428,11 @@ shell_command:
430
428
 
431
429
  The VSSL API was reverse engineered using Wireshark, VSSLs native "legacy" iOS app and their deprecated [vsslagent](https://vssl.gitbook.io/vssl-rest-api/getting-started/start).
432
430
 
431
+ Motovation for this project was to intergrate VSSLs amplifiers into [Home Assistant](https://www.home-assistant.io/) and have control over different subnets (not mDNS dependant)
432
+
433
433
  ## Known Issues & Limitiations
434
434
 
435
- * Tested on VSSL **A.3x** software version **p15305.016.3701**
436
- * Not tested on A.1x, A.6.x or original A series range of amplifiers (testers welcome)
435
+ * Not tested on A.1x or original A series range of amplifiers (testers welcome)
437
436
  * VSSL can not start a stream except for playing a URL directly. This is a limitation of the hardware itself.
438
437
  * Not all sources set the volume to 0 when the zone is muted
439
438
  * Grouping feedback is flaky on the X series amplifiers
@@ -445,8 +444,8 @@ The VSSL API was reverse engineered using Wireshark, VSSLs native "legacy" iOS a
445
444
 
446
445
  ## Future
447
446
 
447
+ * A.1(x) coverage i.e Bluetooth and subwoofer control
448
448
  * REST API / Web App
449
449
  * Save and recall EQ
450
- * A.1(x) coverage i.e Bluetooth
451
450
  * IR Control
452
451
 
File without changes
File without changes