vsslctrl 0.1.11.dev1__tar.gz → 0.1.12.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.
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/PKG-INFO +62 -82
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/README.md +61 -81
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/pyproject.toml +1 -1
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/tests/test_integration.py +319 -253
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/tests/test_settings.py +3 -2
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/tests/test_zone.py +3 -3
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/__init__.py +1 -1
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/api_alpha.py +27 -29
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/core.py +84 -97
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/data_structure.py +2 -1
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/event_bus.py +4 -4
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/group.py +1 -2
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/track.py +3 -4
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/transport.py +1 -1
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/utils.py +11 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/zone.py +25 -11
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl.egg-info/PKG-INFO +62 -82
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/LICENSE +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/setup.cfg +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/tests/test_event_bus.py +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/api_base.py +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/api_bravo.py +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/decorators.py +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/device.py +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/discovery.py +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/exceptions.py +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/io.py +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl/settings.py +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl.egg-info/SOURCES.txt +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl.egg-info/dependency_links.txt +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl.egg-info/requires.txt +0 -0
- {vsslctrl-0.1.11.dev1 → vsslctrl-0.1.12.dev1}/vsslctrl.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: vsslctrl
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.12.dev1
|
|
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
|
|
@@ -21,32 +21,44 @@ Requires-Dist: zeroconf==0.132.2; extra == "optional"
|
|
|
21
21
|
|
|
22
22
|
# vsslctrl
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Package for controlling [VSSL's](https://www.vssl.com/) range of streaming amplifiers.
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
## Coverage
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Tested on:
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
| Model | Software Version | Note |
|
|
31
|
+
| ------------|--------- | -------------
|
|
32
|
+
| A.3x | p15305.016.3701 |
|
|
31
33
|
|
|
32
|
-
Tested on:
|
|
33
|
-
- **A.3x** software version **p15305.016.3701**
|
|
34
34
|
|
|
35
35
|
Home Assistant [integration](https://github.com/vsslctrl/integration.home-assistant) with basic functionality working on:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
|
|
37
|
+
| Model | Software Version | User Reported |
|
|
38
|
+
| ------------|--------- | -------------
|
|
39
|
+
| A.1 | p15265.033.3703 | ✔️
|
|
40
|
+
| A.3 | p12013.141.3703 | ✔️
|
|
41
|
+
| A.3x | p15305.016.3701 |
|
|
42
|
+
| A.6x | p15305.017.3701 | ✔️
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## Testers Needed
|
|
46
|
+
|
|
47
|
+
I am looking for testers with any VSSL amplifier models, please get in touch if you interested in helping. <vsslcontrolled@proton.me>
|
|
48
|
+
|
|
49
|
+
|
|
40
50
|
|
|
41
51
|
## Important
|
|
42
52
|
|
|
43
|
-
There should not be any *[VSSL Agent's](https://vssl.gitbook.io/vssl-rest-api/getting-started/start)* running on the
|
|
53
|
+
There should not be any *[VSSL Agent's](https://vssl.gitbook.io/vssl-rest-api/getting-started/start)* running on the network. If you dont know what this is, then you can ignore this notice.
|
|
54
|
+
|
|
55
|
+
**`vsslctrl` is not endorsed or affiliated with [VSSL](https://www.vssl.com/) in any manner.**
|
|
44
56
|
|
|
45
57
|
## TODOs
|
|
46
58
|
|
|
47
|
-
* Correct IO mapping between models and versions
|
|
48
59
|
* Better test coverage
|
|
49
|
-
* A.1(x) testing
|
|
60
|
+
* A.1(x) testing - e.g output settings
|
|
61
|
+
* More controls - e.g IR Control
|
|
50
62
|
|
|
51
63
|
## Basic Usage
|
|
52
64
|
|
|
@@ -62,7 +74,7 @@ async def main():
|
|
|
62
74
|
|
|
63
75
|
# Represents a physical VSSL amplifier
|
|
64
76
|
vssl = Vssl(DeviceModels.A1)
|
|
65
|
-
a1 = vssl.add_zone(
|
|
77
|
+
a1 = vssl.add_zone('192.168.1.10')
|
|
66
78
|
|
|
67
79
|
# Connect and initiate zones.
|
|
68
80
|
await vssl.initialise()
|
|
@@ -92,14 +104,13 @@ from vsslctrl import Vssl, DeviceModels, Zone, ZoneIDs
|
|
|
92
104
|
async def main():
|
|
93
105
|
|
|
94
106
|
# Represents a physical VSSL amplifier
|
|
95
|
-
# If no DeviceModels is passed, vsslctrl will default to the feature set of the X series amps
|
|
96
107
|
vssl = Vssl(DeviceModels.A3X)
|
|
97
108
|
|
|
98
109
|
# Add each you wish to control
|
|
99
|
-
zone1 = vssl.add_zone(
|
|
100
|
-
zone2 = vssl.add_zone(
|
|
101
|
-
zone3 = vssl.add_zone(
|
|
102
|
-
#... up to 6 zones
|
|
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)
|
|
113
|
+
#... up to 6 zones for A.6(x)
|
|
103
114
|
|
|
104
115
|
# Connect and initiate zones.
|
|
105
116
|
await vssl.initialise()
|
|
@@ -123,9 +134,36 @@ async def main():
|
|
|
123
134
|
asyncio.run(main())
|
|
124
135
|
```
|
|
125
136
|
|
|
137
|
+
# `DeviceModels`
|
|
138
|
+
|
|
139
|
+
A device model has to be passed to VSSL so it knows internally what features are supported by the device.
|
|
140
|
+
This might be removed in the future if we can differentiate different models from the API.
|
|
141
|
+
|
|
142
|
+
| Property | Description |
|
|
143
|
+
| ------------|--------- |
|
|
144
|
+
| `A1X` | A.1x |
|
|
145
|
+
| `A3X` | A.3x |
|
|
146
|
+
| `A6X` | A.6x |
|
|
147
|
+
| `A1` | A1 |
|
|
148
|
+
| `A3` | A3 |
|
|
149
|
+
| `A6` | A6 |
|
|
150
|
+
|
|
151
|
+
# `ZoneIDs`
|
|
152
|
+
|
|
153
|
+
| Property | Description |
|
|
154
|
+
| ------------|--------- |
|
|
155
|
+
| `A1` | A.1(x) Only |
|
|
156
|
+
| `ZONE_1` | Zone 1 of A.3(x) and A.6(x) |
|
|
157
|
+
| `ZONE_2` | Zone 2 of A.3(x) and A.6(x) |
|
|
158
|
+
| `ZONE_3` | Zone 3 of A.3(x) and A.6(x) |
|
|
159
|
+
| `ZONE_4` | Zone 4 of A.6(x) |
|
|
160
|
+
| `ZONE_5` | Zone 5 of A.6(x) |
|
|
161
|
+
| `ZONE_6` | Zone 6 of A.6(x) |
|
|
162
|
+
|
|
163
|
+
|
|
126
164
|
# API
|
|
127
165
|
|
|
128
|
-
Most functionality is
|
|
166
|
+
Most functionality is achieved via `getters` and `setters` of the two main classes `Vssl`, `Zone`.
|
|
129
167
|
|
|
130
168
|
The classes will update the physical VSSL device when setting a property and once feedback has been received, the classes internal state will be updated. For example:
|
|
131
169
|
|
|
@@ -142,7 +180,6 @@ print(zone_name)
|
|
|
142
180
|
|
|
143
181
|
**Important** in the above example, `zone1.settings.name` wont be set to its new value until after the VSSL device has changed the name and the `Zone` class has received confirmation feedback. If you need to wait for the value change, you can await a `[property_name]_CHANGE` events.
|
|
144
182
|
|
|
145
|
-
|
|
146
183
|
# `Vssl`
|
|
147
184
|
|
|
148
185
|
| Property | Description | Type |
|
|
@@ -164,7 +201,7 @@ vssl.factory_reset()
|
|
|
164
201
|
|
|
165
202
|
## `Vssl.settings`
|
|
166
203
|
|
|
167
|
-
| Property | Description | Type |
|
|
204
|
+
| Property | Description | Type | Model: Default |
|
|
168
205
|
| ---------------------- | ----------- | ----------- | ----------- |
|
|
169
206
|
| `name` | Device name | `str` |
|
|
170
207
|
| `bus_1_name` | Name of Bus 1 | `str` | <ul><li>A.1: Optical Input</li><li>A.3x/6x: Not Used</li></ul>
|
|
@@ -313,13 +350,13 @@ Input `InputRouter.Priorities` still apply.
|
|
|
313
350
|
# Change zone 1 to listen to analog input 4
|
|
314
351
|
zone1.input.source = InputRouter.Sources.ANALOG_IN_4
|
|
315
352
|
|
|
316
|
-
# Change zone 1 to perfer
|
|
353
|
+
# Change zone 1 to perfer local inputs over stream
|
|
317
354
|
zone1.input.priority = InputRouter.Priorities.LOCAL
|
|
318
355
|
```
|
|
319
356
|
|
|
320
357
|
## `Zone.group`
|
|
321
358
|
|
|
322
|
-
|
|
359
|
+
Unsupported on X series amplifiers.
|
|
323
360
|
|
|
324
361
|
| Property | Description | Type | Values |
|
|
325
362
|
| ---------------------- | ----------- | ----------- |----------- |
|
|
@@ -458,55 +495,6 @@ zone1.settings.eq.khz1_db = -2
|
|
|
458
495
|
zone1.settings.subwoofer.crossover = 100
|
|
459
496
|
```
|
|
460
497
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
## Another (Lite) Way
|
|
464
|
-
|
|
465
|
-
If you perfer to not run the complete intergration, you can send basic HEX commands to the VSSL device using [Netcat](https://nc110.sourceforge.io/) (or any network tool) on port `50002`.
|
|
466
|
-
|
|
467
|
-
| HEX | Description |
|
|
468
|
-
| ---------------------- | ----------- |
|
|
469
|
-
| `\x10\x05\x03\x0{Zone Number}\xff\x03` | Volume Up
|
|
470
|
-
| `\x10\x05\x03\x0{Zone Number}\xfe\x03` | Volume Down
|
|
471
|
-
| `\x10\x11\x02\x0{Zone Number}\x01` | Mute
|
|
472
|
-
| All commands can be found by looking [here](https://github.com/vsslctrl/vsslctrl/blob/2c43c2f2393b94bc0e062d2ab90144343eca16ef/vsslctrl/api_alpha.py) |
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
The `volume up` HEX command for `Zone 2` would be `\x10\x05\x03\x02\xff\x03`
|
|
476
|
-
|
|
477
|
-
Now send the raw HEX using Netcat to the device using this syntax:
|
|
478
|
-
|
|
479
|
-
`echo -e "{HEX Command}" | nc {IP Address} 50002`
|
|
480
|
-
|
|
481
|
-
For example to send `volume up` to `Zone 2`:
|
|
482
|
-
|
|
483
|
-
`echo -e "\x10\x05\x03\x02\xff\x03" | nc 192.168.1.11 50002`
|
|
484
|
-
|
|
485
|
-
Home Assistant `Configuration.yaml` example:
|
|
486
|
-
|
|
487
|
-
```ymal
|
|
488
|
-
...
|
|
489
|
-
|
|
490
|
-
shell_command:
|
|
491
|
-
#Zone 1
|
|
492
|
-
vssl_zone_1_volume_up: 'echo -e "\x10\x05\x03\x01\xff\x03" | nc 192.168.1.10 50002'
|
|
493
|
-
vssl_zone_1_volume_down: 'echo -e "\x10\x05\x03\x01\xfe\x03" | nc 192.168.1.10 50002'
|
|
494
|
-
vssl_zone_1_mute: 'echo -e "\x10\x11\x02\x01\x01" | nc 192.168.1.10 50002'
|
|
495
|
-
vssl_zone_1_unmute: 'echo -e "\x10\x11\x02\x01\x00" | nc 192.168.1.10 50002'
|
|
496
|
-
#Zone 2
|
|
497
|
-
vssl_zone_2_volume_up: 'echo -e "\x10\x05\x03\x02\xff\x03" | nc 192.168.1.11 50002'
|
|
498
|
-
vssl_zone_2_volume_down: 'echo -e "\x10\x05\x03\x02\xfe\x03" | nc 192.168.1.11 50002'
|
|
499
|
-
vssl_zone_2_mute: 'echo -e "\x10\x11\x02\x02\x01" | nc 192.168.1.11 50002'
|
|
500
|
-
vssl_zone_2_unmute: 'echo -e "\x10\x11\x02\x02\x00" | nc 192.168.1.11 50002'
|
|
501
|
-
#Zone 3
|
|
502
|
-
vssl_zone_3_volume_up: 'echo -e "\x10\x05\x03\x03\xff\x03" | nc 192.168.1.12 50002'
|
|
503
|
-
vssl_zone_3_volume_down: 'echo -e "\x10\x05\x03\x03\xfe\x03" | nc 192.168.1.12 50002'
|
|
504
|
-
vssl_zone_3_mute: 'echo -e "\x10\x11\x02\x03\x01" | nc 192.168.1.12 50002'
|
|
505
|
-
vssl_zone_3_unmute: 'echo -e "\x10\x11\x02\x03\x00" | nc 192.168.1.12 50002'
|
|
506
|
-
|
|
507
|
-
...
|
|
508
|
-
```
|
|
509
|
-
|
|
510
498
|
## Credit
|
|
511
499
|
|
|
512
500
|
Thanks to [@dj-jam](https://github.com/dj-jam) for the continued testing.
|
|
@@ -520,17 +508,9 @@ Motivation for this project was to integrate VSSLs amplifiers into [Home Assista
|
|
|
520
508
|
* Not tested on A.1x or original A series range of amplifiers (testers welcome)
|
|
521
509
|
* VSSL can not start a stream except for playing a URL directly. This is a limitation of the hardware itself.
|
|
522
510
|
* Not all sources set the volume to 0 when the zone is muted
|
|
523
|
-
* Grouping feedback is flaky on the X series amplifiers
|
|
524
511
|
* Airplay `Zone.track.progress` is not available.
|
|
525
512
|
* Cant stop a URL playback, feedback is worng at least
|
|
526
513
|
* 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
|
|
527
514
|
* `stop()` is intended to disconnect the client and pause the stream. Doesn’t always function this way, depending on stream source
|
|
528
515
|
* Occasionally a zones might stop responding to certain commands, issuing the `reboot` command generally corrects
|
|
529
516
|
|
|
530
|
-
## Future
|
|
531
|
-
|
|
532
|
-
* A.1(x) coverage i.e Bluetooth
|
|
533
|
-
* REST API / Web App
|
|
534
|
-
* Save and recall EQ
|
|
535
|
-
* IR Control
|
|
536
|
-
|
|
@@ -1,31 +1,43 @@
|
|
|
1
1
|
# vsslctrl
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Package for controlling [VSSL's](https://www.vssl.com/) range of streaming amplifiers.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Coverage
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Tested on:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
| Model | Software Version | Note |
|
|
10
|
+
| ------------|--------- | -------------
|
|
11
|
+
| A.3x | p15305.016.3701 |
|
|
10
12
|
|
|
11
|
-
Tested on:
|
|
12
|
-
- **A.3x** software version **p15305.016.3701**
|
|
13
13
|
|
|
14
14
|
Home Assistant [integration](https://github.com/vsslctrl/integration.home-assistant) with basic functionality working on:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
|
|
16
|
+
| Model | Software Version | User Reported |
|
|
17
|
+
| ------------|--------- | -------------
|
|
18
|
+
| A.1 | p15265.033.3703 | ✔️
|
|
19
|
+
| A.3 | p12013.141.3703 | ✔️
|
|
20
|
+
| A.3x | p15305.016.3701 |
|
|
21
|
+
| A.6x | p15305.017.3701 | ✔️
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Testers Needed
|
|
25
|
+
|
|
26
|
+
I am looking for testers with any VSSL amplifier models, please get in touch if you interested in helping. <vsslcontrolled@proton.me>
|
|
27
|
+
|
|
28
|
+
|
|
19
29
|
|
|
20
30
|
## Important
|
|
21
31
|
|
|
22
|
-
There should not be any *[VSSL Agent's](https://vssl.gitbook.io/vssl-rest-api/getting-started/start)* running on the
|
|
32
|
+
There should not be any *[VSSL Agent's](https://vssl.gitbook.io/vssl-rest-api/getting-started/start)* running on the network. If you dont know what this is, then you can ignore this notice.
|
|
33
|
+
|
|
34
|
+
**`vsslctrl` is not endorsed or affiliated with [VSSL](https://www.vssl.com/) in any manner.**
|
|
23
35
|
|
|
24
36
|
## TODOs
|
|
25
37
|
|
|
26
|
-
* Correct IO mapping between models and versions
|
|
27
38
|
* Better test coverage
|
|
28
|
-
* A.1(x) testing
|
|
39
|
+
* A.1(x) testing - e.g output settings
|
|
40
|
+
* More controls - e.g IR Control
|
|
29
41
|
|
|
30
42
|
## Basic Usage
|
|
31
43
|
|
|
@@ -41,7 +53,7 @@ async def main():
|
|
|
41
53
|
|
|
42
54
|
# Represents a physical VSSL amplifier
|
|
43
55
|
vssl = Vssl(DeviceModels.A1)
|
|
44
|
-
a1 = vssl.add_zone(
|
|
56
|
+
a1 = vssl.add_zone('192.168.1.10')
|
|
45
57
|
|
|
46
58
|
# Connect and initiate zones.
|
|
47
59
|
await vssl.initialise()
|
|
@@ -71,14 +83,13 @@ from vsslctrl import Vssl, DeviceModels, Zone, ZoneIDs
|
|
|
71
83
|
async def main():
|
|
72
84
|
|
|
73
85
|
# Represents a physical VSSL amplifier
|
|
74
|
-
# If no DeviceModels is passed, vsslctrl will default to the feature set of the X series amps
|
|
75
86
|
vssl = Vssl(DeviceModels.A3X)
|
|
76
87
|
|
|
77
88
|
# Add each you wish to control
|
|
78
|
-
zone1 = vssl.add_zone(
|
|
79
|
-
zone2 = vssl.add_zone(
|
|
80
|
-
zone3 = vssl.add_zone(
|
|
81
|
-
#... up to 6 zones
|
|
89
|
+
zone1 = vssl.add_zone('192.168.1.10', ZoneIDs.ZONE_1)
|
|
90
|
+
zone2 = vssl.add_zone('192.168.1.11', ZoneIDs.ZONE_2)
|
|
91
|
+
zone3 = vssl.add_zone('192.168.1.12', ZoneIDs.ZONE_3)
|
|
92
|
+
#... up to 6 zones for A.6(x)
|
|
82
93
|
|
|
83
94
|
# Connect and initiate zones.
|
|
84
95
|
await vssl.initialise()
|
|
@@ -102,9 +113,36 @@ async def main():
|
|
|
102
113
|
asyncio.run(main())
|
|
103
114
|
```
|
|
104
115
|
|
|
116
|
+
# `DeviceModels`
|
|
117
|
+
|
|
118
|
+
A device model has to be passed to VSSL so it knows internally what features are supported by the device.
|
|
119
|
+
This might be removed in the future if we can differentiate different models from the API.
|
|
120
|
+
|
|
121
|
+
| Property | Description |
|
|
122
|
+
| ------------|--------- |
|
|
123
|
+
| `A1X` | A.1x |
|
|
124
|
+
| `A3X` | A.3x |
|
|
125
|
+
| `A6X` | A.6x |
|
|
126
|
+
| `A1` | A1 |
|
|
127
|
+
| `A3` | A3 |
|
|
128
|
+
| `A6` | A6 |
|
|
129
|
+
|
|
130
|
+
# `ZoneIDs`
|
|
131
|
+
|
|
132
|
+
| Property | Description |
|
|
133
|
+
| ------------|--------- |
|
|
134
|
+
| `A1` | A.1(x) Only |
|
|
135
|
+
| `ZONE_1` | Zone 1 of A.3(x) and A.6(x) |
|
|
136
|
+
| `ZONE_2` | Zone 2 of A.3(x) and A.6(x) |
|
|
137
|
+
| `ZONE_3` | Zone 3 of A.3(x) and A.6(x) |
|
|
138
|
+
| `ZONE_4` | Zone 4 of A.6(x) |
|
|
139
|
+
| `ZONE_5` | Zone 5 of A.6(x) |
|
|
140
|
+
| `ZONE_6` | Zone 6 of A.6(x) |
|
|
141
|
+
|
|
142
|
+
|
|
105
143
|
# API
|
|
106
144
|
|
|
107
|
-
Most functionality is
|
|
145
|
+
Most functionality is achieved via `getters` and `setters` of the two main classes `Vssl`, `Zone`.
|
|
108
146
|
|
|
109
147
|
The classes will update the physical VSSL device when setting a property and once feedback has been received, the classes internal state will be updated. For example:
|
|
110
148
|
|
|
@@ -121,7 +159,6 @@ print(zone_name)
|
|
|
121
159
|
|
|
122
160
|
**Important** in the above example, `zone1.settings.name` wont be set to its new value until after the VSSL device has changed the name and the `Zone` class has received confirmation feedback. If you need to wait for the value change, you can await a `[property_name]_CHANGE` events.
|
|
123
161
|
|
|
124
|
-
|
|
125
162
|
# `Vssl`
|
|
126
163
|
|
|
127
164
|
| Property | Description | Type |
|
|
@@ -143,7 +180,7 @@ vssl.factory_reset()
|
|
|
143
180
|
|
|
144
181
|
## `Vssl.settings`
|
|
145
182
|
|
|
146
|
-
| Property | Description | Type |
|
|
183
|
+
| Property | Description | Type | Model: Default |
|
|
147
184
|
| ---------------------- | ----------- | ----------- | ----------- |
|
|
148
185
|
| `name` | Device name | `str` |
|
|
149
186
|
| `bus_1_name` | Name of Bus 1 | `str` | <ul><li>A.1: Optical Input</li><li>A.3x/6x: Not Used</li></ul>
|
|
@@ -292,13 +329,13 @@ Input `InputRouter.Priorities` still apply.
|
|
|
292
329
|
# Change zone 1 to listen to analog input 4
|
|
293
330
|
zone1.input.source = InputRouter.Sources.ANALOG_IN_4
|
|
294
331
|
|
|
295
|
-
# Change zone 1 to perfer
|
|
332
|
+
# Change zone 1 to perfer local inputs over stream
|
|
296
333
|
zone1.input.priority = InputRouter.Priorities.LOCAL
|
|
297
334
|
```
|
|
298
335
|
|
|
299
336
|
## `Zone.group`
|
|
300
337
|
|
|
301
|
-
|
|
338
|
+
Unsupported on X series amplifiers.
|
|
302
339
|
|
|
303
340
|
| Property | Description | Type | Values |
|
|
304
341
|
| ---------------------- | ----------- | ----------- |----------- |
|
|
@@ -437,55 +474,6 @@ zone1.settings.eq.khz1_db = -2
|
|
|
437
474
|
zone1.settings.subwoofer.crossover = 100
|
|
438
475
|
```
|
|
439
476
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
## Another (Lite) Way
|
|
443
|
-
|
|
444
|
-
If you perfer to not run the complete intergration, you can send basic HEX commands to the VSSL device using [Netcat](https://nc110.sourceforge.io/) (or any network tool) on port `50002`.
|
|
445
|
-
|
|
446
|
-
| HEX | Description |
|
|
447
|
-
| ---------------------- | ----------- |
|
|
448
|
-
| `\x10\x05\x03\x0{Zone Number}\xff\x03` | Volume Up
|
|
449
|
-
| `\x10\x05\x03\x0{Zone Number}\xfe\x03` | Volume Down
|
|
450
|
-
| `\x10\x11\x02\x0{Zone Number}\x01` | Mute
|
|
451
|
-
| All commands can be found by looking [here](https://github.com/vsslctrl/vsslctrl/blob/2c43c2f2393b94bc0e062d2ab90144343eca16ef/vsslctrl/api_alpha.py) |
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
The `volume up` HEX command for `Zone 2` would be `\x10\x05\x03\x02\xff\x03`
|
|
455
|
-
|
|
456
|
-
Now send the raw HEX using Netcat to the device using this syntax:
|
|
457
|
-
|
|
458
|
-
`echo -e "{HEX Command}" | nc {IP Address} 50002`
|
|
459
|
-
|
|
460
|
-
For example to send `volume up` to `Zone 2`:
|
|
461
|
-
|
|
462
|
-
`echo -e "\x10\x05\x03\x02\xff\x03" | nc 192.168.1.11 50002`
|
|
463
|
-
|
|
464
|
-
Home Assistant `Configuration.yaml` example:
|
|
465
|
-
|
|
466
|
-
```ymal
|
|
467
|
-
...
|
|
468
|
-
|
|
469
|
-
shell_command:
|
|
470
|
-
#Zone 1
|
|
471
|
-
vssl_zone_1_volume_up: 'echo -e "\x10\x05\x03\x01\xff\x03" | nc 192.168.1.10 50002'
|
|
472
|
-
vssl_zone_1_volume_down: 'echo -e "\x10\x05\x03\x01\xfe\x03" | nc 192.168.1.10 50002'
|
|
473
|
-
vssl_zone_1_mute: 'echo -e "\x10\x11\x02\x01\x01" | nc 192.168.1.10 50002'
|
|
474
|
-
vssl_zone_1_unmute: 'echo -e "\x10\x11\x02\x01\x00" | nc 192.168.1.10 50002'
|
|
475
|
-
#Zone 2
|
|
476
|
-
vssl_zone_2_volume_up: 'echo -e "\x10\x05\x03\x02\xff\x03" | nc 192.168.1.11 50002'
|
|
477
|
-
vssl_zone_2_volume_down: 'echo -e "\x10\x05\x03\x02\xfe\x03" | nc 192.168.1.11 50002'
|
|
478
|
-
vssl_zone_2_mute: 'echo -e "\x10\x11\x02\x02\x01" | nc 192.168.1.11 50002'
|
|
479
|
-
vssl_zone_2_unmute: 'echo -e "\x10\x11\x02\x02\x00" | nc 192.168.1.11 50002'
|
|
480
|
-
#Zone 3
|
|
481
|
-
vssl_zone_3_volume_up: 'echo -e "\x10\x05\x03\x03\xff\x03" | nc 192.168.1.12 50002'
|
|
482
|
-
vssl_zone_3_volume_down: 'echo -e "\x10\x05\x03\x03\xfe\x03" | nc 192.168.1.12 50002'
|
|
483
|
-
vssl_zone_3_mute: 'echo -e "\x10\x11\x02\x03\x01" | nc 192.168.1.12 50002'
|
|
484
|
-
vssl_zone_3_unmute: 'echo -e "\x10\x11\x02\x03\x00" | nc 192.168.1.12 50002'
|
|
485
|
-
|
|
486
|
-
...
|
|
487
|
-
```
|
|
488
|
-
|
|
489
477
|
## Credit
|
|
490
478
|
|
|
491
479
|
Thanks to [@dj-jam](https://github.com/dj-jam) for the continued testing.
|
|
@@ -499,17 +487,9 @@ Motivation for this project was to integrate VSSLs amplifiers into [Home Assista
|
|
|
499
487
|
* Not tested on A.1x or original A series range of amplifiers (testers welcome)
|
|
500
488
|
* VSSL can not start a stream except for playing a URL directly. This is a limitation of the hardware itself.
|
|
501
489
|
* Not all sources set the volume to 0 when the zone is muted
|
|
502
|
-
* Grouping feedback is flaky on the X series amplifiers
|
|
503
490
|
* Airplay `Zone.track.progress` is not available.
|
|
504
491
|
* Cant stop a URL playback, feedback is worng at least
|
|
505
492
|
* 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
|
|
506
493
|
* `stop()` is intended to disconnect the client and pause the stream. Doesn’t always function this way, depending on stream source
|
|
507
494
|
* Occasionally a zones might stop responding to certain commands, issuing the `reboot` command generally corrects
|
|
508
495
|
|
|
509
|
-
## Future
|
|
510
|
-
|
|
511
|
-
* A.1(x) coverage i.e Bluetooth
|
|
512
|
-
* REST API / Web App
|
|
513
|
-
* Save and recall EQ
|
|
514
|
-
* IR Control
|
|
515
|
-
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "vsslctrl"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.12.dev1"
|
|
8
8
|
description = "Package for controlling VSSL's range of streaming amplifiers"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name="vsslctrl", email="vsslcontrolled@proton.me" },
|