vsslctrl 0.1.0.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/__init__.py +4 -0
- vsslctrl/api_alpha.py +1040 -0
- vsslctrl/api_base.py +321 -0
- vsslctrl/api_bravo.py +419 -0
- vsslctrl/core.py +322 -0
- vsslctrl/data_structure.py +242 -0
- vsslctrl/decorators.py +61 -0
- vsslctrl/discovery.py +193 -0
- vsslctrl/event_bus.py +159 -0
- vsslctrl/exceptions.py +21 -0
- vsslctrl/group.py +187 -0
- vsslctrl/io.py +229 -0
- vsslctrl/settings.py +655 -0
- vsslctrl/track.py +337 -0
- vsslctrl/transport.py +242 -0
- vsslctrl/utils.py +75 -0
- vsslctrl/zone.py +452 -0
- vsslctrl-0.1.0.dev1.dist-info/LICENSE +21 -0
- vsslctrl-0.1.0.dev1.dist-info/METADATA +385 -0
- vsslctrl-0.1.0.dev1.dist-info/RECORD +22 -0
- vsslctrl-0.1.0.dev1.dist-info/WHEEL +5 -0
- vsslctrl-0.1.0.dev1.dist-info/top_level.txt +1 -0
vsslctrl/io.py
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from enum import IntEnum
|
|
3
|
+
from typing import Dict, Union
|
|
4
|
+
from .utils import clamp_volume
|
|
5
|
+
from .data_structure import VsslIntEnum, ZoneDataClass
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class InputRouter(ZoneDataClass):
|
|
9
|
+
#
|
|
10
|
+
# Input Priority
|
|
11
|
+
#
|
|
12
|
+
# 0: Stream -> Analog Input
|
|
13
|
+
# 1: Analog Input -> Stream (Local first in App)
|
|
14
|
+
#
|
|
15
|
+
# DO NOT CHANGE - VSSL Defined
|
|
16
|
+
#
|
|
17
|
+
class Priorities(VsslIntEnum):
|
|
18
|
+
STREAM = 0
|
|
19
|
+
LOCAL = 1
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Input Sources
|
|
23
|
+
#
|
|
24
|
+
# DO NOT CHANGE - VSSL Defined
|
|
25
|
+
#
|
|
26
|
+
class Sources(VsslIntEnum):
|
|
27
|
+
STREAM = 0
|
|
28
|
+
ANALOG_IN_1 = 3
|
|
29
|
+
ANALOG_IN_2 = 4
|
|
30
|
+
ANALOG_IN_3 = 5
|
|
31
|
+
ANALOG_IN_4 = 6
|
|
32
|
+
ANALOG_IN_5 = 7
|
|
33
|
+
ANALOG_IN_6 = 8
|
|
34
|
+
OPTICAL_IN = 16
|
|
35
|
+
|
|
36
|
+
#
|
|
37
|
+
# Router Events
|
|
38
|
+
#
|
|
39
|
+
class Events:
|
|
40
|
+
PREFIX = "zone.input_router."
|
|
41
|
+
PRIORITY_CHANGE = PREFIX + "priority_change"
|
|
42
|
+
SOURCE_CHANGE = PREFIX + "source_change"
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
# Defaults
|
|
46
|
+
#
|
|
47
|
+
DEFAULTS = {"priority": Priorities.STREAM, "source": Sources.STREAM}
|
|
48
|
+
|
|
49
|
+
def __init__(self, zone: "zone.Zone"):
|
|
50
|
+
self.zone = zone
|
|
51
|
+
|
|
52
|
+
self._priority = self.Priorities.STREAM
|
|
53
|
+
self._source = self.Sources.STREAM
|
|
54
|
+
|
|
55
|
+
#
|
|
56
|
+
# Input Priority
|
|
57
|
+
#
|
|
58
|
+
@property
|
|
59
|
+
def priority(self):
|
|
60
|
+
return self._priority
|
|
61
|
+
|
|
62
|
+
@priority.setter
|
|
63
|
+
def priority(self, priority: "InputRouter.Priorities"):
|
|
64
|
+
if self.Priorities.is_valid(priority):
|
|
65
|
+
self.zone.api_alpha.request_action_47(priority)
|
|
66
|
+
else:
|
|
67
|
+
self.zone._log_error(f"Input priority {priority} doesnt exist")
|
|
68
|
+
|
|
69
|
+
def _set_priority(self, priority: int):
|
|
70
|
+
if self.priority != priority:
|
|
71
|
+
if self.Priorities.is_valid(priority):
|
|
72
|
+
self._priority = self.Priorities(priority)
|
|
73
|
+
return True
|
|
74
|
+
else:
|
|
75
|
+
self.zone._log_error(f"InputRouter.Priorities {priority} doesnt exist")
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# Input Source
|
|
79
|
+
#
|
|
80
|
+
@property
|
|
81
|
+
def source(self):
|
|
82
|
+
return self._source
|
|
83
|
+
|
|
84
|
+
@source.setter
|
|
85
|
+
def source(self, src: "InputRouter.Sources"):
|
|
86
|
+
if self.Sources.is_valid(src):
|
|
87
|
+
self.zone.api_alpha.request_action_03(src)
|
|
88
|
+
else:
|
|
89
|
+
self.zone._log_error(f"InputRouter.Sources {src} doesnt exist")
|
|
90
|
+
|
|
91
|
+
def _set_source(self, src: int):
|
|
92
|
+
if self.source != src:
|
|
93
|
+
if self.Sources.is_valid(src):
|
|
94
|
+
self._source = self.Sources(src)
|
|
95
|
+
return True
|
|
96
|
+
else:
|
|
97
|
+
self.zone._log_error(f"InputRouter.Sources {src} doesnt exist")
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class AnalogOutput(ZoneDataClass):
|
|
101
|
+
"""
|
|
102
|
+
Should this be on the VSSL or Zone? For now its on the zone, because the zone will
|
|
103
|
+
receive feedback for the corrosponding analog output id
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
#
|
|
107
|
+
# Sources
|
|
108
|
+
#
|
|
109
|
+
# DO NOT CHANGE - VSSL Defined
|
|
110
|
+
#
|
|
111
|
+
class Sources(VsslIntEnum):
|
|
112
|
+
OFF = 0 # Disconnected / Off / No Output
|
|
113
|
+
ZONE_1 = 3
|
|
114
|
+
ZONE_2 = 4
|
|
115
|
+
ZONE_3 = 5
|
|
116
|
+
ZONE_4 = 6
|
|
117
|
+
ZONE_5 = 7
|
|
118
|
+
ZONE_6 = 8
|
|
119
|
+
OPTICAL_IN = 16
|
|
120
|
+
|
|
121
|
+
#
|
|
122
|
+
# Output Events
|
|
123
|
+
#
|
|
124
|
+
class Events:
|
|
125
|
+
PREFIX = "zone.analog_output."
|
|
126
|
+
IS_FIXED_VOLUME_CHANGE = PREFIX + "is_fixed_volume_change"
|
|
127
|
+
SOURCE_CHANGE = PREFIX + "source_change"
|
|
128
|
+
|
|
129
|
+
#
|
|
130
|
+
# Defaults
|
|
131
|
+
#
|
|
132
|
+
DEFAULTS = {"is_fixed_volume": False, "source": Sources.OFF}
|
|
133
|
+
|
|
134
|
+
def __init__(self, zone: "zone.Zone"):
|
|
135
|
+
self.zone = zone
|
|
136
|
+
|
|
137
|
+
self._is_fixed_volume = False
|
|
138
|
+
self._source = self.Sources(zone.id + 3)
|
|
139
|
+
|
|
140
|
+
#
|
|
141
|
+
# Analog Output Fix Volume. Output wont respond to volume control
|
|
142
|
+
#
|
|
143
|
+
@property
|
|
144
|
+
def is_fixed_volume(self):
|
|
145
|
+
return self._is_fixed_volume
|
|
146
|
+
|
|
147
|
+
@is_fixed_volume.setter
|
|
148
|
+
def is_fixed_volume(self, state: Union[bool, int]):
|
|
149
|
+
self.zone.api_alpha.request_action_49(state)
|
|
150
|
+
|
|
151
|
+
def is_fixed_volume_toggle(self):
|
|
152
|
+
self.is_fixed_volume = False if self.is_fixed_volume else True
|
|
153
|
+
|
|
154
|
+
#
|
|
155
|
+
# Analog Output Source
|
|
156
|
+
#
|
|
157
|
+
@property
|
|
158
|
+
def source(self):
|
|
159
|
+
return self._source
|
|
160
|
+
|
|
161
|
+
@source.setter
|
|
162
|
+
def source(self, src: "AnalogOutput.Sources"):
|
|
163
|
+
if self.Sources.is_valid(src):
|
|
164
|
+
self.zone.api_alpha.request_action_1D(src)
|
|
165
|
+
else:
|
|
166
|
+
self.zone._log_error(f"AnalogOutput.Sources {src} doesnt exist")
|
|
167
|
+
|
|
168
|
+
def _set_source(self, src: int):
|
|
169
|
+
if self.source != src:
|
|
170
|
+
if self.Sources.is_valid(src):
|
|
171
|
+
self._source = self.Sources(src)
|
|
172
|
+
return True
|
|
173
|
+
else:
|
|
174
|
+
self.zone._log_error(f"AnalogOutput.Sources {src} doesnt exist")
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class AnalogInput(ZoneDataClass):
|
|
178
|
+
#
|
|
179
|
+
# Analog Input Events
|
|
180
|
+
#
|
|
181
|
+
class Events:
|
|
182
|
+
PREFIX = "zone.analog_input."
|
|
183
|
+
NAME_CHANGE = PREFIX + "name_change"
|
|
184
|
+
FIXED_GAIN_CHANGE = PREFIX + "fixed_gain_change"
|
|
185
|
+
|
|
186
|
+
#
|
|
187
|
+
# Defaults
|
|
188
|
+
#
|
|
189
|
+
DEFAULTS = {"name": "Analog In", "fixed_gain": 0}
|
|
190
|
+
|
|
191
|
+
def __init__(self, zone: "zone.Zone"):
|
|
192
|
+
self.zone = zone
|
|
193
|
+
|
|
194
|
+
self._name = f"Analog In {self.zone.id}"
|
|
195
|
+
self._fixed_gain = 0
|
|
196
|
+
|
|
197
|
+
#
|
|
198
|
+
# Analog Input Name
|
|
199
|
+
#
|
|
200
|
+
@property
|
|
201
|
+
def name(self):
|
|
202
|
+
return self._name
|
|
203
|
+
|
|
204
|
+
@name.setter
|
|
205
|
+
def name(self, name: str):
|
|
206
|
+
self.zone.api_alpha.request_action_15(str(name))
|
|
207
|
+
|
|
208
|
+
#
|
|
209
|
+
# Analog Input Fixed Gain
|
|
210
|
+
#
|
|
211
|
+
# 0 is disabled or variable gain
|
|
212
|
+
#
|
|
213
|
+
@property
|
|
214
|
+
def fixed_gain(self):
|
|
215
|
+
return self._fixed_gain
|
|
216
|
+
|
|
217
|
+
@fixed_gain.setter
|
|
218
|
+
def fixed_gain(self, gain: int):
|
|
219
|
+
self.zone.api_alpha.request_action_05_00(gain)
|
|
220
|
+
|
|
221
|
+
def _set_fixed_gain(self, gain: int):
|
|
222
|
+
gain = clamp_volume(gain)
|
|
223
|
+
if self.fixed_gain != gain:
|
|
224
|
+
self._fixed_gain = gain
|
|
225
|
+
return True
|
|
226
|
+
|
|
227
|
+
@property
|
|
228
|
+
def has_fixed_gain(self):
|
|
229
|
+
return not self.fixed_gain == 0
|