vsslctrl 0.1.6.dev1__py3-none-any.whl → 0.1.8.dev1__py3-none-any.whl
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/api_alpha.py +117 -52
- vsslctrl/core.py +5 -0
- vsslctrl/data_structure.py +129 -8
- vsslctrl/device.py +159 -13
- vsslctrl/discovery.py +1 -1
- vsslctrl/io.py +18 -6
- vsslctrl/settings.py +94 -4
- vsslctrl/zone.py +4 -2
- {vsslctrl-0.1.6.dev1.dist-info → vsslctrl-0.1.8.dev1.dist-info}/METADATA +8 -1
- vsslctrl-0.1.8.dev1.dist-info/RECORD +23 -0
- vsslctrl-0.1.6.dev1.dist-info/RECORD +0 -23
- {vsslctrl-0.1.6.dev1.dist-info → vsslctrl-0.1.8.dev1.dist-info}/LICENSE +0 -0
- {vsslctrl-0.1.6.dev1.dist-info → vsslctrl-0.1.8.dev1.dist-info}/WHEEL +0 -0
- {vsslctrl-0.1.6.dev1.dist-info → vsslctrl-0.1.8.dev1.dist-info}/top_level.txt +0 -0
vsslctrl/api_alpha.py
CHANGED
|
@@ -16,6 +16,7 @@ from .data_structure import (
|
|
|
16
16
|
ZoneEQStatusExtKeys,
|
|
17
17
|
ZoneRouterStatusExtKeys,
|
|
18
18
|
DeviceStatusExtKeys,
|
|
19
|
+
DeviceStatusExtendedExtKeys,
|
|
19
20
|
)
|
|
20
21
|
|
|
21
22
|
|
|
@@ -94,10 +95,10 @@ class APIAlpha(APIBase):
|
|
|
94
95
|
|
|
95
96
|
#
|
|
96
97
|
# 00 [0] - 0B [11]
|
|
97
|
-
# Status
|
|
98
|
+
# Status device extended
|
|
98
99
|
#
|
|
99
100
|
def request_action_00_0B(self):
|
|
100
|
-
self._log_debug("Requesting status
|
|
101
|
+
self._log_debug("Requesting device status extended")
|
|
101
102
|
self.send(bytearray([16, 0, 1, 11])) # HEX: 1000010B
|
|
102
103
|
|
|
103
104
|
#
|
|
@@ -549,12 +550,22 @@ class APIAlpha(APIBase):
|
|
|
549
550
|
except Exception as error:
|
|
550
551
|
self._log_error(f"Couldnt parse JSON: {error} | {hexl}")
|
|
551
552
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
553
|
+
"""
|
|
554
|
+
00_00
|
|
555
|
+
Device Status 00
|
|
556
|
+
|
|
557
|
+
A.3x:
|
|
558
|
+
{
|
|
559
|
+
"B1Src": "3",
|
|
560
|
+
"B2Src": "4",
|
|
561
|
+
"B3Src": "5",
|
|
562
|
+
"B1Nm": "",
|
|
563
|
+
"B2Nm": "Optical In",
|
|
564
|
+
"dev": "Device Name",
|
|
565
|
+
"ver": "p15305.016.3701"
|
|
566
|
+
}
|
|
567
|
+
"""
|
|
568
|
+
|
|
558
569
|
def response_action_00_00(self, metadata: list):
|
|
559
570
|
self._log_debug(f"Received 00 Status: {metadata}")
|
|
560
571
|
|
|
@@ -588,13 +599,32 @@ class APIAlpha(APIBase):
|
|
|
588
599
|
"sw_version", metadata[DeviceStatusExtKeys.SW_VERSION].strip()
|
|
589
600
|
)
|
|
590
601
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
602
|
+
"""
|
|
603
|
+
00_08
|
|
604
|
+
Zone Status 08
|
|
605
|
+
|
|
606
|
+
A.3x:
|
|
607
|
+
{
|
|
608
|
+
"id": "1",
|
|
609
|
+
"ac": "0",
|
|
610
|
+
"mc": "XXXXXXXXXXXX",
|
|
611
|
+
"vol": "20",
|
|
612
|
+
"mt": "0",
|
|
613
|
+
"pa": "0",
|
|
614
|
+
"rm": "0",
|
|
615
|
+
"ts": "14",
|
|
616
|
+
"alex": "14",
|
|
617
|
+
"nmd": "0",
|
|
618
|
+
"ird": "14",
|
|
619
|
+
"lb": "24",
|
|
620
|
+
"tp": "13",
|
|
621
|
+
"wr": "0",
|
|
622
|
+
"as": "0",
|
|
623
|
+
"rg": "0"
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
"""
|
|
627
|
+
|
|
598
628
|
def response_action_00_08(self, metadata: list):
|
|
599
629
|
self._log_debug(f"Received 08 Status: {metadata}")
|
|
600
630
|
|
|
@@ -652,13 +682,27 @@ class APIAlpha(APIBase):
|
|
|
652
682
|
"disabled", bool(int(metadata[ZoneStatusExtKeys.DISABLED]))
|
|
653
683
|
)
|
|
654
684
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
685
|
+
"""
|
|
686
|
+
00_09
|
|
687
|
+
EQ Status
|
|
688
|
+
|
|
689
|
+
A.3x:
|
|
690
|
+
{
|
|
691
|
+
"mono": "0",
|
|
692
|
+
"AiNm": "Analog In 1",
|
|
693
|
+
"eq1": "100",
|
|
694
|
+
"eq2": "100",
|
|
695
|
+
"eq3": "100",
|
|
696
|
+
"eq4": "100",
|
|
697
|
+
"eq5": "100",
|
|
698
|
+
"eq6": "100",
|
|
699
|
+
"eq7": "100",
|
|
700
|
+
"voll": "75",
|
|
701
|
+
"volr": "75",
|
|
702
|
+
"vold": "0"
|
|
703
|
+
}
|
|
704
|
+
"""
|
|
705
|
+
|
|
662
706
|
def response_action_00_09(self, metadata: list):
|
|
663
707
|
self._log_debug(f"Received 09 Status: {metadata}")
|
|
664
708
|
|
|
@@ -677,13 +721,28 @@ class APIAlpha(APIBase):
|
|
|
677
721
|
self.zone.settings.eq._map_response_dict(metadata)
|
|
678
722
|
self.zone.settings.volume._map_response_dict(metadata)
|
|
679
723
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
724
|
+
"""
|
|
725
|
+
00_0A
|
|
726
|
+
System Status 0A (Output / Amp)
|
|
727
|
+
|
|
728
|
+
A.3x:
|
|
729
|
+
{
|
|
730
|
+
"ECO": "0",
|
|
731
|
+
"eqsw": "1",
|
|
732
|
+
"inSrc": "0",
|
|
733
|
+
"SP": "0",
|
|
734
|
+
"BF1": "0",
|
|
735
|
+
"BF2": "0",
|
|
736
|
+
"BF3": "0",
|
|
737
|
+
"GRM": "0",
|
|
738
|
+
"GRS": "255",
|
|
739
|
+
"Pwr": "0",
|
|
740
|
+
"Bvr": "1",
|
|
741
|
+
"fxv": "24",
|
|
742
|
+
"AtPwr": "1"
|
|
743
|
+
}
|
|
744
|
+
"""
|
|
745
|
+
|
|
687
746
|
def response_action_00_0A(self, metadata: list):
|
|
688
747
|
self._log_debug(f"Received 0A Status: {metadata}")
|
|
689
748
|
|
|
@@ -744,30 +803,36 @@ class APIAlpha(APIBase):
|
|
|
744
803
|
"adaptive", bool(int(metadata[ZoneRouterStatusExtKeys.ADAPTIVE_POWER]))
|
|
745
804
|
)
|
|
746
805
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
#
|
|
763
|
-
# Fes:
|
|
764
|
-
# This might stand for "Frequency" or "Filter Effect Setting," representing a parameter related to frequency or filtering effects.
|
|
765
|
-
#
|
|
766
|
-
# Drk: ?
|
|
767
|
-
#
|
|
806
|
+
"""
|
|
807
|
+
00_0B
|
|
808
|
+
Device Status Extended 0B
|
|
809
|
+
|
|
810
|
+
A.3x:
|
|
811
|
+
{
|
|
812
|
+
'IRMskL': '241',
|
|
813
|
+
'IRMskH': '255',
|
|
814
|
+
'BTSta': '0',
|
|
815
|
+
'Crs': '0',
|
|
816
|
+
'Fes': '0',
|
|
817
|
+
'Drk': '0'
|
|
818
|
+
}
|
|
819
|
+
"""
|
|
820
|
+
|
|
768
821
|
def response_action_00_0B(self, metadata: list):
|
|
769
822
|
self._log_debug(f"Received 0B Status: {metadata}")
|
|
770
|
-
|
|
823
|
+
|
|
824
|
+
# Bluetooth
|
|
825
|
+
if DeviceStatusExtendedExtKeys.BLUETOOTH_STATUS in metadata:
|
|
826
|
+
self.vssl.settings._set_property(
|
|
827
|
+
"bluetooth", int(metadata[DeviceStatusExtendedExtKeys.BLUETOOTH_STATUS])
|
|
828
|
+
)
|
|
829
|
+
|
|
830
|
+
# Subwoofer Crossover
|
|
831
|
+
if DeviceStatusExtendedExtKeys.SUBWOOFER_CROSSOVER in metadata:
|
|
832
|
+
self.zone.settings.subwoofer._set_property(
|
|
833
|
+
"crossover",
|
|
834
|
+
int(metadata[DeviceStatusExtendedExtKeys.SUBWOOFER_CROSSOVER]),
|
|
835
|
+
)
|
|
771
836
|
|
|
772
837
|
#
|
|
773
838
|
# 2A [42]
|
|
@@ -927,7 +992,7 @@ class APIAlpha(APIBase):
|
|
|
927
992
|
# Keep Alive
|
|
928
993
|
#
|
|
929
994
|
def response_action_17(self, hexl: list, response: bytes):
|
|
930
|
-
self._log_debug(f"
|
|
995
|
+
self._log_debug(f"Received keep alive: {response}")
|
|
931
996
|
# TODO
|
|
932
997
|
pass
|
|
933
998
|
|
vsslctrl/core.py
CHANGED
|
@@ -93,6 +93,11 @@ class Vssl:
|
|
|
93
93
|
await first_zone.disconnect()
|
|
94
94
|
raise VsslCtrlException(message)
|
|
95
95
|
|
|
96
|
+
# Output a bit of helpful info
|
|
97
|
+
self._log_info(f"Device Model: {self.model.name}")
|
|
98
|
+
self._log_info(f"Device SW Version: {self.sw_version}")
|
|
99
|
+
self._log_info(f"Device Serial: {self.serial}")
|
|
100
|
+
|
|
96
101
|
# Now we can init the rest of the zones
|
|
97
102
|
initialisations = [zone.initialise() for zone in zones_to_init.values()]
|
|
98
103
|
await asyncio.gather(*initialisations)
|
vsslctrl/data_structure.py
CHANGED
|
@@ -41,6 +41,7 @@ class ZoneIDs(VsslIntEnum):
|
|
|
41
41
|
ZONE_4 = 4
|
|
42
42
|
ZONE_5 = 5
|
|
43
43
|
ZONE_6 = 6
|
|
44
|
+
A1 = 7 # A.1 and A.1x
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
"""
|
|
@@ -48,7 +49,7 @@ JSON Structure
|
|
|
48
49
|
|
|
49
50
|
DO NOT CHANGE - VSSL Defined
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
A.3x
|
|
52
53
|
{
|
|
53
54
|
"B1Src": "3",
|
|
54
55
|
"B2Src": "4",
|
|
@@ -59,7 +60,17 @@ A3.x
|
|
|
59
60
|
"ver": "p15305.016.3701"
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
|
|
63
|
+
A.3
|
|
64
|
+
{
|
|
65
|
+
'B1Src': '1',
|
|
66
|
+
'B2Src': '2',
|
|
67
|
+
'B1Nm': '',
|
|
68
|
+
'B2Nm': '',
|
|
69
|
+
'dev': 'VSSL A.3',
|
|
70
|
+
'ver': '12013 .141.3703'
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
A.6x
|
|
63
74
|
{
|
|
64
75
|
"B1Src": "3",
|
|
65
76
|
"B2Src": "4",
|
|
@@ -97,7 +108,68 @@ JSON Structure
|
|
|
97
108
|
|
|
98
109
|
DO NOT CHANGE - VSSL Defined
|
|
99
110
|
|
|
100
|
-
|
|
111
|
+
|
|
112
|
+
IRMskL / IRMskH:
|
|
113
|
+
These could potentially be related to Infrared (IR) remote control signals. "IRMskL" and "IRMskH" might represent the low and high values of the modulation frequency or pulse width for an infrared signal.
|
|
114
|
+
|
|
115
|
+
BTSta:
|
|
116
|
+
This might represent the Bluetooth status, with "0" indicating that Bluetooth is currently not active or disconnected.
|
|
117
|
+
|
|
118
|
+
Crs:
|
|
119
|
+
It could stand for "Crossfade" and may represent a setting related to crossfading between audio tracks.
|
|
120
|
+
|
|
121
|
+
Fes:
|
|
122
|
+
This might stand for "Frequency" or "Filter Effect Setting," representing a parameter related to frequency or filtering effects.
|
|
123
|
+
|
|
124
|
+
Drk: ?
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
A.3x
|
|
128
|
+
{
|
|
129
|
+
'IRMskL': '241',
|
|
130
|
+
'IRMskH': '255',
|
|
131
|
+
'BTSta': '0',
|
|
132
|
+
'Crs': '0',
|
|
133
|
+
'Fes': '0',
|
|
134
|
+
'Drk': '0'
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
A.3
|
|
138
|
+
{
|
|
139
|
+
'IRMskL': '255',
|
|
140
|
+
'IRMskH': '255',
|
|
141
|
+
'BTSta': '0',
|
|
142
|
+
'Crs': '0',
|
|
143
|
+
'Fes': '0',
|
|
144
|
+
'Drk': '0'
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
A.6x
|
|
148
|
+
{
|
|
149
|
+
"IRMskL": "255",
|
|
150
|
+
"IRMskH": "255",
|
|
151
|
+
"BTSta": "0",
|
|
152
|
+
"Crs": "0",
|
|
153
|
+
"Fes": "0",
|
|
154
|
+
"Drk": "0"
|
|
155
|
+
'
|
|
156
|
+
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class DeviceStatusExtendedExtKeys:
|
|
161
|
+
IR_HIGH = "IRMskH" # Guess - To Confirm
|
|
162
|
+
IR_LOW = "IRMskL" # Guess - To Confirm
|
|
163
|
+
BLUETOOTH_STATUS = "BTSta" # Guess - To Confirm
|
|
164
|
+
SUBWOOFER_CROSSOVER = "Crs" # Guess - To Confirm
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
"""
|
|
168
|
+
JSON Structure
|
|
169
|
+
|
|
170
|
+
DO NOT CHANGE - VSSL Defined
|
|
171
|
+
|
|
172
|
+
A.3x
|
|
101
173
|
{
|
|
102
174
|
"id": "1",
|
|
103
175
|
"ac": "0",
|
|
@@ -117,7 +189,24 @@ A3.x
|
|
|
117
189
|
"rg": "0"
|
|
118
190
|
}
|
|
119
191
|
|
|
120
|
-
|
|
192
|
+
A.3
|
|
193
|
+
{
|
|
194
|
+
'id': '3',
|
|
195
|
+
'ac': '0',
|
|
196
|
+
'mc': 'XXXXXXXXXXXX',
|
|
197
|
+
'vol': '27',
|
|
198
|
+
'mt': '0',
|
|
199
|
+
'pa': '1',
|
|
200
|
+
'rm': '0',
|
|
201
|
+
'ts': '0',
|
|
202
|
+
'lb': '17',
|
|
203
|
+
'tp': '3',
|
|
204
|
+
'wr': '0',
|
|
205
|
+
'as': '0',
|
|
206
|
+
'rg': '0'
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
A.6x
|
|
121
210
|
{
|
|
122
211
|
"id": "1",
|
|
123
212
|
"ac": "0",
|
|
@@ -156,7 +245,7 @@ JSON Structure
|
|
|
156
245
|
|
|
157
246
|
DO NOT CHANGE - VSSL Defined
|
|
158
247
|
|
|
159
|
-
|
|
248
|
+
A.3x
|
|
160
249
|
{
|
|
161
250
|
"mono": "0",
|
|
162
251
|
"AiNm": "Analog In 1",
|
|
@@ -172,7 +261,23 @@ A3.x
|
|
|
172
261
|
"vold": "0"
|
|
173
262
|
}
|
|
174
263
|
|
|
175
|
-
|
|
264
|
+
A.3
|
|
265
|
+
{
|
|
266
|
+
'mono': '0',
|
|
267
|
+
'AiNm': 'Backup',
|
|
268
|
+
'eq1': '106',
|
|
269
|
+
'eq2': '102',
|
|
270
|
+
'eq3': '100',
|
|
271
|
+
'eq4': '100',
|
|
272
|
+
'eq5': '100',
|
|
273
|
+
'eq6': '101',
|
|
274
|
+
'eq7': '105',
|
|
275
|
+
'voll': '75',
|
|
276
|
+
'volr': '75',
|
|
277
|
+
'vold': '27'
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
A.6x
|
|
176
281
|
{
|
|
177
282
|
"mono": "0",
|
|
178
283
|
"AiNm": "",
|
|
@@ -210,7 +315,7 @@ JSON Structure
|
|
|
210
315
|
|
|
211
316
|
DO NOT CHANGE - VSSL Defined
|
|
212
317
|
|
|
213
|
-
|
|
318
|
+
A.3x
|
|
214
319
|
{
|
|
215
320
|
"ECO": "0",
|
|
216
321
|
"eqsw": "1",
|
|
@@ -227,7 +332,23 @@ A3.x
|
|
|
227
332
|
"AtPwr": "1"
|
|
228
333
|
}
|
|
229
334
|
|
|
230
|
-
|
|
335
|
+
A.3
|
|
336
|
+
{
|
|
337
|
+
"ECO": "0",
|
|
338
|
+
"eqsw": "1",
|
|
339
|
+
"inSrc": "0",
|
|
340
|
+
"SP": "0",
|
|
341
|
+
"BF1": "0",
|
|
342
|
+
"BF2": "0",
|
|
343
|
+
"GRM": "0",
|
|
344
|
+
"GRS": "255",
|
|
345
|
+
"Pwr": "0",
|
|
346
|
+
"Bvr": "15",
|
|
347
|
+
"fxv": "25",
|
|
348
|
+
"AtPwr": "1"
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
A.6x
|
|
231
352
|
{
|
|
232
353
|
"ECO": "0",
|
|
233
354
|
"eqsw": "1",
|
vsslctrl/device.py
CHANGED
|
@@ -1,41 +1,187 @@
|
|
|
1
1
|
from .data_structure import VsslEnum, VsslIntEnum, ZoneIDs
|
|
2
2
|
from .io import AnalogOutput, InputRouter
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Model Physical IOs, sourced from the product manuals
|
|
7
|
+
|
|
8
|
+
A.1x:
|
|
9
|
+
SUB OUT
|
|
10
|
+
ANALOG IN 1
|
|
11
|
+
ANALOG OUT 1
|
|
12
|
+
COAXIAL IN (Are Coxial and Optical inputs linked?)
|
|
13
|
+
COAXIAL OUT
|
|
14
|
+
OPTICAL IN
|
|
15
|
+
OPTICAL OUT
|
|
16
|
+
IR REMOTE
|
|
17
|
+
|
|
18
|
+
A1:
|
|
19
|
+
SUB OUT
|
|
20
|
+
ANALOG IN 1
|
|
21
|
+
ANALOG OUT 1
|
|
22
|
+
COAXIAL IN (Are Coxial and Optical inputs linked?)
|
|
23
|
+
COAXIAL OUT
|
|
24
|
+
OPTICAL IN
|
|
25
|
+
OPTICAL OUT
|
|
26
|
+
IR REMOTE
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
A.3x:
|
|
31
|
+
ANALOG IN 1
|
|
32
|
+
ANALOG IN 2
|
|
33
|
+
ANALOG IN 3
|
|
34
|
+
ANALOG OUT 1
|
|
35
|
+
ANALOG OUT 2
|
|
36
|
+
ANALOG OUT 3
|
|
37
|
+
OPTICAL IN
|
|
38
|
+
IR REMOTE
|
|
39
|
+
|
|
40
|
+
A3:
|
|
41
|
+
BUS 1 IN
|
|
42
|
+
BUS 1 OUT
|
|
43
|
+
ANALOG IN 1
|
|
44
|
+
ANALOG IN 2
|
|
45
|
+
ANALOG IN 3
|
|
46
|
+
OPTICAL IN
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
A.6x:
|
|
51
|
+
ANALOG IN 1
|
|
52
|
+
ANALOG IN 2
|
|
53
|
+
ANALOG IN 3
|
|
54
|
+
ANALOG IN 4
|
|
55
|
+
ANALOG IN 5
|
|
56
|
+
ANALOG IN 6
|
|
57
|
+
ANALOG OUT 1
|
|
58
|
+
ANALOG OUT 2
|
|
59
|
+
ANALOG OUT 3
|
|
60
|
+
ANALOG OUT 4
|
|
61
|
+
ANALOG OUT 5
|
|
62
|
+
ANALOG OUT 6
|
|
63
|
+
OPTICAL IN
|
|
64
|
+
IR REMOTE
|
|
65
|
+
|
|
66
|
+
A6:
|
|
67
|
+
BUS 1 IN
|
|
68
|
+
BUS 1 OUT
|
|
69
|
+
BUS 2 IN
|
|
70
|
+
BUS 2 OUT
|
|
71
|
+
ANALOG IN 1
|
|
72
|
+
ANALOG IN 2
|
|
73
|
+
ANALOG IN 3
|
|
74
|
+
ANALOG IN 4
|
|
75
|
+
ANALOG IN 5
|
|
76
|
+
ANALOG IN 6
|
|
77
|
+
|
|
78
|
+
---------------------------------
|
|
79
|
+
|
|
80
|
+
Analog Input Source legend: input: inputs specific to model (e.g. A3 does not have zones 4-6 or bus input 2, only A3 has optical input, ...)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
0 - none
|
|
84
|
+
1 - bus input 1
|
|
85
|
+
2 - bus input 2
|
|
86
|
+
3 - zone 1 local input
|
|
87
|
+
4 - zone 2 local input
|
|
88
|
+
5 - zone 3 local input
|
|
89
|
+
6 - zone 4 local input
|
|
90
|
+
7 - zone 5 local input
|
|
91
|
+
8 - zone 6 local input
|
|
92
|
+
16 - optical input
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
Source: https://vssl.gitbook.io/vssl-rest-api/zone-control/set-analog-input-source
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
"""
|
|
102
|
+
Zones
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
"""
|
|
106
|
+
SINGLE_ZONE = [ZoneIDs.A1]
|
|
5
107
|
THREE_ZONES = [ZoneIDs.ZONE_1, ZoneIDs.ZONE_2, ZoneIDs.ZONE_3]
|
|
6
|
-
SIX_ZONES =
|
|
108
|
+
SIX_ZONES = THREE_ZONES + [ZoneIDs.ZONE_4, ZoneIDs.ZONE_5, ZoneIDs.ZONE_6]
|
|
109
|
+
|
|
110
|
+
"""
|
|
111
|
+
Input Sources
|
|
7
112
|
|
|
113
|
+
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
# A.1 & A.1x
|
|
8
117
|
INPUT_SOURCES_FOR_1_ZONE_DEVICE = [
|
|
9
118
|
InputRouter.Sources.STREAM,
|
|
10
119
|
InputRouter.Sources.ANALOG_IN_1,
|
|
11
120
|
InputRouter.Sources.OPTICAL_IN,
|
|
12
121
|
]
|
|
13
122
|
|
|
123
|
+
# A.3x
|
|
14
124
|
INPUT_SOURCES_FOR_3_ZONE_DEVICE = INPUT_SOURCES_FOR_1_ZONE_DEVICE + [
|
|
15
125
|
InputRouter.Sources.ANALOG_IN_2,
|
|
16
126
|
InputRouter.Sources.ANALOG_IN_3,
|
|
17
127
|
]
|
|
18
128
|
|
|
19
|
-
|
|
129
|
+
# A.3
|
|
130
|
+
INPUT_SOURCES_FOR_A3 = INPUT_SOURCES_FOR_3_ZONE_DEVICE + [InputRouter.Sources.BUS_IN_1]
|
|
131
|
+
|
|
132
|
+
# A.6x
|
|
133
|
+
INPUT_SOURCES_FOR_6_ZONE_DEVICE = INPUT_SOURCES_FOR_3_ZONE_DEVICE + [
|
|
134
|
+
InputRouter.Sources.ANALOG_IN_4,
|
|
135
|
+
InputRouter.Sources.ANALOG_IN_5,
|
|
136
|
+
InputRouter.Sources.ANALOG_IN_6,
|
|
137
|
+
]
|
|
138
|
+
|
|
139
|
+
# A.6
|
|
140
|
+
INPUT_SOURCES_FOR_A6 = [
|
|
141
|
+
source for source in InputRouter.Sources if source != InputRouter.Sources.OPTICAL_IN
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
"""
|
|
146
|
+
Analog Output Sources
|
|
20
147
|
|
|
148
|
+
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
# A.1 & A.1x
|
|
21
152
|
ANALOG_OUTPUT_SOURCES_FOR_1_ZONE_DEVICE = [
|
|
22
153
|
AnalogOutput.Sources.OFF,
|
|
23
154
|
AnalogOutput.Sources.ZONE_1,
|
|
24
155
|
AnalogOutput.Sources.OPTICAL_IN,
|
|
25
156
|
]
|
|
26
157
|
|
|
158
|
+
# A.3x
|
|
27
159
|
ANALOG_OUTPUT_SOURCES_FOR_3_ZONE_DEVICE = ANALOG_OUTPUT_SOURCES_FOR_1_ZONE_DEVICE + [
|
|
28
160
|
AnalogOutput.Sources.ZONE_2,
|
|
29
161
|
AnalogOutput.Sources.ZONE_3,
|
|
30
162
|
]
|
|
31
163
|
|
|
32
|
-
|
|
164
|
+
# A.3
|
|
165
|
+
ANALOG_OUTPUT_SOURCES_FOR_A3 = ANALOG_OUTPUT_SOURCES_FOR_3_ZONE_DEVICE + [
|
|
166
|
+
AnalogOutput.Sources.BUS_IN_1
|
|
167
|
+
]
|
|
168
|
+
|
|
169
|
+
# A.6x
|
|
170
|
+
ANALOG_OUTPUT_SOURCES_FOR_6_ZONE_DEVICE = ANALOG_OUTPUT_SOURCES_FOR_3_ZONE_DEVICE + [
|
|
171
|
+
AnalogOutput.Sources.ZONE_4,
|
|
172
|
+
AnalogOutput.Sources.ZONE_5,
|
|
173
|
+
AnalogOutput.Sources.ZONE_6,
|
|
174
|
+
]
|
|
175
|
+
|
|
176
|
+
# A.6
|
|
177
|
+
ANALOG_OUTPUT_SOURCES_FOR_A6 = list(AnalogOutput.Sources)
|
|
33
178
|
|
|
34
179
|
|
|
35
180
|
class Features(VsslIntEnum):
|
|
36
181
|
GROUPING = 1000
|
|
37
182
|
BLUETOOTH = 1001
|
|
38
183
|
PARTY_MODE = 1002
|
|
184
|
+
SUBWOOFER_CROSSOVER = 1003
|
|
39
185
|
|
|
40
186
|
|
|
41
187
|
class Model:
|
|
@@ -61,28 +207,28 @@ class Model:
|
|
|
61
207
|
class Models(VsslEnum):
|
|
62
208
|
A1 = Model(
|
|
63
209
|
{
|
|
64
|
-
"name": "
|
|
210
|
+
"name": "A.1",
|
|
65
211
|
"zones": SINGLE_ZONE,
|
|
66
212
|
"input_sources": INPUT_SOURCES_FOR_1_ZONE_DEVICE,
|
|
67
213
|
"analog_output_sources": ANALOG_OUTPUT_SOURCES_FOR_1_ZONE_DEVICE,
|
|
68
|
-
"features": [Features.BLUETOOTH],
|
|
214
|
+
"features": [Features.BLUETOOTH, Features.SUBWOOFER_CROSSOVER],
|
|
69
215
|
}
|
|
70
216
|
)
|
|
71
217
|
A3 = Model(
|
|
72
218
|
{
|
|
73
|
-
"name": "
|
|
219
|
+
"name": "A.3",
|
|
74
220
|
"zones": THREE_ZONES,
|
|
75
|
-
"input_sources":
|
|
76
|
-
"analog_output_sources":
|
|
221
|
+
"input_sources": INPUT_SOURCES_FOR_A3,
|
|
222
|
+
"analog_output_sources": ANALOG_OUTPUT_SOURCES_FOR_A3,
|
|
77
223
|
"features": [Features.GROUPING, Features.PARTY_MODE],
|
|
78
224
|
}
|
|
79
225
|
)
|
|
80
226
|
A6 = Model(
|
|
81
227
|
{
|
|
82
|
-
"name": "
|
|
228
|
+
"name": "A.6",
|
|
83
229
|
"zones": SIX_ZONES,
|
|
84
|
-
"input_sources":
|
|
85
|
-
"analog_output_sources":
|
|
230
|
+
"input_sources": INPUT_SOURCES_FOR_A6,
|
|
231
|
+
"analog_output_sources": ANALOG_OUTPUT_SOURCES_FOR_A6,
|
|
86
232
|
"features": [Features.GROUPING, Features.PARTY_MODE],
|
|
87
233
|
}
|
|
88
234
|
)
|
|
@@ -92,7 +238,7 @@ class Models(VsslEnum):
|
|
|
92
238
|
"zones": SINGLE_ZONE,
|
|
93
239
|
"input_sources": INPUT_SOURCES_FOR_1_ZONE_DEVICE,
|
|
94
240
|
"analog_output_sources": ANALOG_OUTPUT_SOURCES_FOR_1_ZONE_DEVICE,
|
|
95
|
-
"features": [Features.
|
|
241
|
+
"features": [Features.BLUETOOTH, Features.SUBWOOFER_CROSSOVER],
|
|
96
242
|
}
|
|
97
243
|
)
|
|
98
244
|
A3X = Model(
|
vsslctrl/discovery.py
CHANGED
vsslctrl/io.py
CHANGED
|
@@ -9,8 +9,8 @@ class InputRouter(ZoneDataClass):
|
|
|
9
9
|
#
|
|
10
10
|
# Input Priority
|
|
11
11
|
#
|
|
12
|
-
# 0: Stream -> Analog Input
|
|
13
|
-
# 1: Analog Input -> Stream (Local
|
|
12
|
+
# 0: Stream -> Party Zone -> Bus 1 In -> Bus 2 In -> Analog Input (Stream First)
|
|
13
|
+
# 1: Bus 1 In -> Bus 2 In -> Analog Input -> Stream -> Party Zone (Local First)
|
|
14
14
|
#
|
|
15
15
|
# DO NOT CHANGE - VSSL Defined
|
|
16
16
|
#
|
|
@@ -25,6 +25,8 @@ class InputRouter(ZoneDataClass):
|
|
|
25
25
|
#
|
|
26
26
|
class Sources(VsslIntEnum):
|
|
27
27
|
STREAM = 0
|
|
28
|
+
BUS_IN_1 = 1 # TODO bus or party mode of original A series
|
|
29
|
+
BUS_IN_2 = 2 # TODO bus or party mode of original A series
|
|
28
30
|
ANALOG_IN_1 = 3
|
|
29
31
|
ANALOG_IN_2 = 4
|
|
30
32
|
ANALOG_IN_3 = 5
|
|
@@ -49,8 +51,8 @@ class InputRouter(ZoneDataClass):
|
|
|
49
51
|
def __init__(self, zone: "zone.Zone"):
|
|
50
52
|
self.zone = zone
|
|
51
53
|
|
|
52
|
-
self._priority = self.
|
|
53
|
-
self._source = self.
|
|
54
|
+
self._priority = self.DEFAULTS["priority"]
|
|
55
|
+
self._source = self.DEFAULTS["source"]
|
|
54
56
|
|
|
55
57
|
#
|
|
56
58
|
# Input Priority
|
|
@@ -103,8 +105,14 @@ class InputRouter(ZoneDataClass):
|
|
|
103
105
|
|
|
104
106
|
class AnalogOutput(ZoneDataClass):
|
|
105
107
|
"""
|
|
108
|
+
|
|
109
|
+
Analog output is the source which will play out the corrosponding analog output
|
|
110
|
+
|
|
111
|
+
|
|
106
112
|
Should this be on the VSSL or Zone? For now its on the zone, because the zone will
|
|
107
113
|
receive feedback for the corrosponding analog output id
|
|
114
|
+
|
|
115
|
+
Zones will be determined by source Input Priority
|
|
108
116
|
"""
|
|
109
117
|
|
|
110
118
|
#
|
|
@@ -114,6 +122,8 @@ class AnalogOutput(ZoneDataClass):
|
|
|
114
122
|
#
|
|
115
123
|
class Sources(VsslIntEnum):
|
|
116
124
|
OFF = 0 # Disconnected / Off / No Output
|
|
125
|
+
BUS_IN_1 = 1 # TODO bus or party mode of original A series
|
|
126
|
+
BUS_IN_2 = 2 # TODO bus or party mode of original A series
|
|
117
127
|
ZONE_1 = 3
|
|
118
128
|
ZONE_2 = 4
|
|
119
129
|
ZONE_3 = 5
|
|
@@ -138,7 +148,7 @@ class AnalogOutput(ZoneDataClass):
|
|
|
138
148
|
def __init__(self, zone: "zone.Zone"):
|
|
139
149
|
self.zone = zone
|
|
140
150
|
|
|
141
|
-
self._is_fixed_volume =
|
|
151
|
+
self._is_fixed_volume = self.DEFAULTS["is_fixed_volume"]
|
|
142
152
|
self._source = self.Sources(zone.id + 2)
|
|
143
153
|
|
|
144
154
|
#
|
|
@@ -158,6 +168,8 @@ class AnalogOutput(ZoneDataClass):
|
|
|
158
168
|
#
|
|
159
169
|
# Analog Output Source
|
|
160
170
|
#
|
|
171
|
+
# As in what audio is going to be sent to the analog output.
|
|
172
|
+
#
|
|
161
173
|
@property
|
|
162
174
|
def source(self):
|
|
163
175
|
return self._source
|
|
@@ -199,7 +211,7 @@ class AnalogInput(ZoneDataClass):
|
|
|
199
211
|
self.zone = zone
|
|
200
212
|
|
|
201
213
|
self._name = f"Analog In {self.zone.id}"
|
|
202
|
-
self._fixed_gain =
|
|
214
|
+
self._fixed_gain = self.DEFAULTS["fixed_gain"]
|
|
203
215
|
|
|
204
216
|
#
|
|
205
217
|
# Analog Input Name
|
vsslctrl/settings.py
CHANGED
|
@@ -2,6 +2,7 @@ import logging
|
|
|
2
2
|
from typing import Dict, Union
|
|
3
3
|
from .utils import clamp_volume
|
|
4
4
|
from .io import AnalogInput
|
|
5
|
+
from .device import Features as DeviceFeatures
|
|
5
6
|
from .data_structure import (
|
|
6
7
|
VsslIntEnum,
|
|
7
8
|
VsslDataClass,
|
|
@@ -16,6 +17,7 @@ class VsslSettings(VsslDataClass):
|
|
|
16
17
|
class Keys:
|
|
17
18
|
NAME = "name"
|
|
18
19
|
OPTICAL_INPUT_NAME = "optical_input_name"
|
|
20
|
+
BLUETOOTH = "bluetooth"
|
|
19
21
|
|
|
20
22
|
#
|
|
21
23
|
# VSSL Events
|
|
@@ -24,17 +26,23 @@ class VsslSettings(VsslDataClass):
|
|
|
24
26
|
PREFIX = VSSL_SETTINGS_EVENT_PREFIX
|
|
25
27
|
NAME_CHANGE = PREFIX + "name_changed"
|
|
26
28
|
OPTICAL_INPUT_NAME_CHANGE = PREFIX + "optical_input_name_changed"
|
|
29
|
+
BLUETOOTH_CHANGE = PREFIX + "bluetooth_changed"
|
|
27
30
|
|
|
28
31
|
#
|
|
29
32
|
# Defaults
|
|
30
33
|
#
|
|
31
|
-
DEFAULTS = {
|
|
34
|
+
DEFAULTS = {
|
|
35
|
+
Keys.NAME: None,
|
|
36
|
+
Keys.OPTICAL_INPUT_NAME: "Optical In",
|
|
37
|
+
Keys.BLUETOOTH: 0,
|
|
38
|
+
}
|
|
32
39
|
|
|
33
40
|
def __init__(self, vssl: "vsslctrl.Vssl"):
|
|
34
41
|
self._vssl = vssl
|
|
35
42
|
|
|
36
43
|
self._name = None # device name
|
|
37
44
|
self._optical_input_name = self.DEFAULTS[self.Keys.OPTICAL_INPUT_NAME]
|
|
45
|
+
self._bluetooth = self.DEFAULTS[self.Keys.BLUETOOTH]
|
|
38
46
|
self.power = VsslPowerSettings(vssl)
|
|
39
47
|
|
|
40
48
|
#
|
|
@@ -63,6 +71,30 @@ class VsslSettings(VsslDataClass):
|
|
|
63
71
|
if zone:
|
|
64
72
|
zone.api_alpha.request_action_15_12(name)
|
|
65
73
|
|
|
74
|
+
#
|
|
75
|
+
# Bluetooth
|
|
76
|
+
#
|
|
77
|
+
@property
|
|
78
|
+
def bluetooth(self):
|
|
79
|
+
return bool(self._bluetooth)
|
|
80
|
+
|
|
81
|
+
@bluetooth.setter
|
|
82
|
+
def bluetooth(self, enabled: bool):
|
|
83
|
+
if not self._vssl.model.supports_feature(DeviceFeatures.BLUETOOTH):
|
|
84
|
+
self._vssl._log_error(
|
|
85
|
+
f"VSSL {self._vssl.model.name} does not support Bluetooth"
|
|
86
|
+
)
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
zone = self._vssl.get_connected_zone()
|
|
90
|
+
if zone:
|
|
91
|
+
# TODO
|
|
92
|
+
# zone.api_alpha.request_action_bluetooth(not not enabled)
|
|
93
|
+
self._vssl._log_info(f"TODO - bluetooth set function")
|
|
94
|
+
|
|
95
|
+
def bluetooth_toggle(self):
|
|
96
|
+
self.bluetooth = False if self.bluetooth else True
|
|
97
|
+
|
|
66
98
|
|
|
67
99
|
class VsslPowerSettings(VsslDataClass):
|
|
68
100
|
#
|
|
@@ -86,13 +118,13 @@ class VsslPowerSettings(VsslDataClass):
|
|
|
86
118
|
#
|
|
87
119
|
# Defaults
|
|
88
120
|
#
|
|
89
|
-
DEFAULTS = {"state": States.ON, "adaptive":
|
|
121
|
+
DEFAULTS = {"state": States.ON, "adaptive": True}
|
|
90
122
|
|
|
91
123
|
def __init__(self, vssl: "vsslctrl.Vssl"):
|
|
92
124
|
self._vssl = vssl
|
|
93
125
|
|
|
94
|
-
self._state = self.
|
|
95
|
-
self._adaptive =
|
|
126
|
+
self._state = self.DEFAULTS["state"]
|
|
127
|
+
self._adaptive = self.DEFAULTS["adaptive"] # 1 = auto, 0 = always on
|
|
96
128
|
|
|
97
129
|
#
|
|
98
130
|
# Power State
|
|
@@ -165,6 +197,7 @@ class ZoneSettings(ZoneDataClass):
|
|
|
165
197
|
self._mono = self.StereoMono.Stereo
|
|
166
198
|
|
|
167
199
|
self.eq = EQSettings(zone)
|
|
200
|
+
self.subwoofer = SubwooferSettings(zone)
|
|
168
201
|
self.volume = VolumeSettings(zone)
|
|
169
202
|
self.analog_input = AnalogInput(zone)
|
|
170
203
|
|
|
@@ -653,3 +686,60 @@ class EQSettings(ZoneDataClass):
|
|
|
653
686
|
@khz15_db.setter
|
|
654
687
|
def khz15_db(self, val: int):
|
|
655
688
|
self._set_frequency_on_device_db(self.Freqs.KHZ15, val)
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
# Not in io.py to prevent circ import in device.py
|
|
692
|
+
class SubwooferSettings(ZoneDataClass):
|
|
693
|
+
MIN_VALUE = 0
|
|
694
|
+
MAX_VALUE = 1000
|
|
695
|
+
|
|
696
|
+
#
|
|
697
|
+
# Subwoofer events
|
|
698
|
+
#
|
|
699
|
+
class Events:
|
|
700
|
+
PREFIX = "zone.subwoofer."
|
|
701
|
+
CROSSOVER_CHANGE = PREFIX + "crossover_change"
|
|
702
|
+
|
|
703
|
+
#
|
|
704
|
+
# Defaults
|
|
705
|
+
#
|
|
706
|
+
DEFAULTS = {"crossover": 0}
|
|
707
|
+
|
|
708
|
+
def __init__(self, zone: "zone.Zone"):
|
|
709
|
+
self.zone = zone
|
|
710
|
+
|
|
711
|
+
self._crossover = self.DEFAULTS["crossover"]
|
|
712
|
+
|
|
713
|
+
#
|
|
714
|
+
# Clamp between min and max
|
|
715
|
+
#
|
|
716
|
+
def _clamp_crossover(self, value: int = 100):
|
|
717
|
+
return int(max(self.MIN_VALUE, min(value, self.MAX_VALUE)))
|
|
718
|
+
|
|
719
|
+
#
|
|
720
|
+
# Crossover freq
|
|
721
|
+
#
|
|
722
|
+
@property
|
|
723
|
+
def crossover(self):
|
|
724
|
+
return self._crossover
|
|
725
|
+
|
|
726
|
+
@crossover.setter
|
|
727
|
+
def crossover(self, freq: int):
|
|
728
|
+
if not self.zone.vssl.model.supports_feature(
|
|
729
|
+
DeviceFeatures.SUBWOOFER_CROSSOVER
|
|
730
|
+
):
|
|
731
|
+
self.zone._log_error(
|
|
732
|
+
f"VSSL {self.zone.vssl.model.name} does not have a subwoofer output"
|
|
733
|
+
)
|
|
734
|
+
return
|
|
735
|
+
#
|
|
736
|
+
# TODO
|
|
737
|
+
#
|
|
738
|
+
self.zone._log_info(f"TODO - crossover set function")
|
|
739
|
+
# self.zone.api_alpha.request_action_crossover(freq)
|
|
740
|
+
|
|
741
|
+
def _set_crossover(self, freq: int):
|
|
742
|
+
freq = self._clamp_crossover(freq)
|
|
743
|
+
if self.crossover != freq:
|
|
744
|
+
self._crossover = freq
|
|
745
|
+
return True
|
vsslctrl/zone.py
CHANGED
|
@@ -74,7 +74,7 @@ class Zone:
|
|
|
74
74
|
self._request_eq_status,
|
|
75
75
|
self._request_track,
|
|
76
76
|
self._request_name,
|
|
77
|
-
self.
|
|
77
|
+
self._request_status_extended,
|
|
78
78
|
],
|
|
79
79
|
)
|
|
80
80
|
|
|
@@ -128,6 +128,8 @@ class Zone:
|
|
|
128
128
|
self.initialisation.set()
|
|
129
129
|
self.vssl.event_bus.publish(self.Events.INITIALISED, self.id, self)
|
|
130
130
|
|
|
131
|
+
self._log_info(f"Zone {self.id} initialised")
|
|
132
|
+
|
|
131
133
|
return self
|
|
132
134
|
|
|
133
135
|
@property
|
|
@@ -406,7 +408,7 @@ class Zone:
|
|
|
406
408
|
self.api_alpha.request_action_00_0A()
|
|
407
409
|
return self
|
|
408
410
|
|
|
409
|
-
def
|
|
411
|
+
def _request_status_extended(self):
|
|
410
412
|
self.api_alpha.request_action_00_0B()
|
|
411
413
|
return self
|
|
412
414
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: vsslctrl
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8.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
|
|
@@ -247,6 +247,13 @@ zone1.transport.state = ZoneTransport.States.PAUSE
|
|
|
247
247
|
| `source` | Change input source | `int` | `InputRouter.Sources`
|
|
248
248
|
| `priority` | Change input priority. Stream or analog in higher priority | `int` | `InputRouter.Priorities`
|
|
249
249
|
|
|
250
|
+
### Priority Order:
|
|
251
|
+
|
|
252
|
+
| `InputRouter.Priorities` | Priority Order |
|
|
253
|
+
| ---------------------- | ----------- |
|
|
254
|
+
| **`STREAM`** | <ol><li>Stream</li><li>Party Zone</li><li>Bus 1 In</li><li>Bus 2 In</li><li>Analog Input</li></ol>
|
|
255
|
+
| **`LOCAL`** | <ol><li>Bus 1 In</li><li>Bus 2 In</li><li>Analog Input</li><li>Stream</li><li>Party Zone</li></ol>
|
|
256
|
+
|
|
250
257
|
```python
|
|
251
258
|
"""Example"""
|
|
252
259
|
# Change zone 1 to listen to analog input 4
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
vsslctrl/__init__.py,sha256=W7cljoE7L3DukAVr_TEqkxFycYrUbJiqaHrOlbPkmKU,145
|
|
2
|
+
vsslctrl/api_alpha.py,sha256=UxsMKOFK4Uit3QoF96Wa3VE1WdbCq7FOJjt-3fewAe0,33962
|
|
3
|
+
vsslctrl/api_base.py,sha256=a80CRtUkYK2OwXQOL8bP-YOvt4YE-ALd-VONza_gjK8,9623
|
|
4
|
+
vsslctrl/api_bravo.py,sha256=pchZN16KIvdSrqkI1WU9PA9IEmxkyyP-XifxpRC0jDE,12283
|
|
5
|
+
vsslctrl/core.py,sha256=vgwmiaJf46kL5O8-vQ4JXuMhj-ms8_qt-0PO7-1yEuk,9068
|
|
6
|
+
vsslctrl/data_structure.py,sha256=i6xG72kQqFDSoEhI307Iw9QXTquMNMc4qMUGOK0MEbw,9793
|
|
7
|
+
vsslctrl/decorators.py,sha256=lG8cYSSA-fNvdcp_90lv58tj50bF6iPoigLKcucWSSI,1707
|
|
8
|
+
vsslctrl/device.py,sha256=n4WbGHRJBw1k9eiG9DksxJtuFRaHBn7geOvrv0WLgkI,5560
|
|
9
|
+
vsslctrl/discovery.py,sha256=3z7z6YQUtvjFvRlQOZXIu6Wd4M896rMbi8SUkTub3AM,5568
|
|
10
|
+
vsslctrl/event_bus.py,sha256=9liAEJnZfthJwy5O-qc3pDIWRBv5AcV19PjMCwH_niU,5014
|
|
11
|
+
vsslctrl/exceptions.py,sha256=EEfNlu--9PMIidj3V3ZB8c7p3My8siqKw7YIOjPFaqE,419
|
|
12
|
+
vsslctrl/group.py,sha256=B7lmJb6DIwXGnMyTKsp-JfRWVCVRFQYzlvS71tutfx4,5368
|
|
13
|
+
vsslctrl/io.py,sha256=RZCLxa0RAnyhRdDTM7IFpLcpYeQfV90DzVEJdNjR6lQ,6684
|
|
14
|
+
vsslctrl/settings.py,sha256=ZUa_ixohGzowj6mhGlCcVAr_ZfsbpU_N5jK-7pEA5Jc,18997
|
|
15
|
+
vsslctrl/track.py,sha256=_lQNHYe8ZBm3v1lehFLjZruF5-Rz8PGWuQN-zISBgwc,10136
|
|
16
|
+
vsslctrl/transport.py,sha256=XJFy0kl9y7hm3YV4_9ElBrq3u6--_k73UKJqKdO6Rqg,6993
|
|
17
|
+
vsslctrl/utils.py,sha256=FWOMHM_sl1Cp1xab-V6b-A5B7qRmDN67hMMxV4ReWCk,2087
|
|
18
|
+
vsslctrl/zone.py,sha256=teSk8oE3LKteidRnuVK3koUOqtN-90LclEx0-T4FhAE,12978
|
|
19
|
+
vsslctrl-0.1.8.dev1.dist-info/LICENSE,sha256=67Ekj8PIxjEvkPd7L3GYJ8dyvn1EC4sPM3q3FKtpN6w,1065
|
|
20
|
+
vsslctrl-0.1.8.dev1.dist-info/METADATA,sha256=Mdh-StM-gY7AeaBQrg8wbSuki-lgmL-sNVufXs3oGkI,16990
|
|
21
|
+
vsslctrl-0.1.8.dev1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
22
|
+
vsslctrl-0.1.8.dev1.dist-info/top_level.txt,sha256=MRycO_RKageNX27UZ2bLJDMlfeWTQzUZlsd3hS-0u3Y,9
|
|
23
|
+
vsslctrl-0.1.8.dev1.dist-info/RECORD,,
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
vsslctrl/__init__.py,sha256=W7cljoE7L3DukAVr_TEqkxFycYrUbJiqaHrOlbPkmKU,145
|
|
2
|
-
vsslctrl/api_alpha.py,sha256=xJLTSEBWWKu5L9GLUbBv8LibZROEffOENc3vc22E1tw,33344
|
|
3
|
-
vsslctrl/api_base.py,sha256=a80CRtUkYK2OwXQOL8bP-YOvt4YE-ALd-VONza_gjK8,9623
|
|
4
|
-
vsslctrl/api_bravo.py,sha256=pchZN16KIvdSrqkI1WU9PA9IEmxkyyP-XifxpRC0jDE,12283
|
|
5
|
-
vsslctrl/core.py,sha256=13EEax6H3OWlkjIP49-l5z1nNyZQtb-BC_DwtVGPJuQ,8833
|
|
6
|
-
vsslctrl/data_structure.py,sha256=Gq1Ip3A-sr9Ber571SPmdh9pEgOOXnG96gIenqx0dFE,7683
|
|
7
|
-
vsslctrl/decorators.py,sha256=lG8cYSSA-fNvdcp_90lv58tj50bF6iPoigLKcucWSSI,1707
|
|
8
|
-
vsslctrl/device.py,sha256=P4sYiibPPFp6iDuF93-OKIsWBL_9vtIxBPDc5uRwvbA,3418
|
|
9
|
-
vsslctrl/discovery.py,sha256=81uA3rbm-X_CR0Q0LsCQJyCs7638Bb-mgqNZWqV_dq4,5572
|
|
10
|
-
vsslctrl/event_bus.py,sha256=9liAEJnZfthJwy5O-qc3pDIWRBv5AcV19PjMCwH_niU,5014
|
|
11
|
-
vsslctrl/exceptions.py,sha256=EEfNlu--9PMIidj3V3ZB8c7p3My8siqKw7YIOjPFaqE,419
|
|
12
|
-
vsslctrl/group.py,sha256=B7lmJb6DIwXGnMyTKsp-JfRWVCVRFQYzlvS71tutfx4,5368
|
|
13
|
-
vsslctrl/io.py,sha256=crzz5-vsdQfVFBL9a1Btle8mq5zx41SsVSt4N5cWPaE,6048
|
|
14
|
-
vsslctrl/settings.py,sha256=6zZUf2y-JvmEz6aREMZqxjTptMtVJFO6dGkXdCxR1NU,16587
|
|
15
|
-
vsslctrl/track.py,sha256=_lQNHYe8ZBm3v1lehFLjZruF5-Rz8PGWuQN-zISBgwc,10136
|
|
16
|
-
vsslctrl/transport.py,sha256=XJFy0kl9y7hm3YV4_9ElBrq3u6--_k73UKJqKdO6Rqg,6993
|
|
17
|
-
vsslctrl/utils.py,sha256=FWOMHM_sl1Cp1xab-V6b-A5B7qRmDN67hMMxV4ReWCk,2087
|
|
18
|
-
vsslctrl/zone.py,sha256=94Rq_IX9HObTx2nxdVlxs_ZnNrBqrewBA7ksatwT_78,12911
|
|
19
|
-
vsslctrl-0.1.6.dev1.dist-info/LICENSE,sha256=67Ekj8PIxjEvkPd7L3GYJ8dyvn1EC4sPM3q3FKtpN6w,1065
|
|
20
|
-
vsslctrl-0.1.6.dev1.dist-info/METADATA,sha256=7SK_zgiNWPIQJ7H55_fXjHbMdDVKcfjZ_10HUX802X8,16640
|
|
21
|
-
vsslctrl-0.1.6.dev1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
22
|
-
vsslctrl-0.1.6.dev1.dist-info/top_level.txt,sha256=MRycO_RKageNX27UZ2bLJDMlfeWTQzUZlsd3hS-0u3Y,9
|
|
23
|
-
vsslctrl-0.1.6.dev1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|