xair-api 2.4.1__py3-none-any.whl → 2.4.2__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.
xair_api/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
- from .xair import request_remote_obj as connect
2
-
3
- _ALL__ = ['connect']
1
+ from .xair import request_remote_obj as connect
2
+
3
+ _ALL__ = ['connect']
xair_api/adapter.py CHANGED
@@ -1,47 +1,47 @@
1
- from .bus import Bus as IBus
2
- from .headamp import HeadAmp as IHeadAmp
3
- from .lr import LR as ILR
4
- from .rtn import AuxRtn as IAuxRtn
5
- from .rtn import FxRtn as IFxRtn
6
-
7
-
8
- class Bus(IBus):
9
- @property
10
- def address(self):
11
- return f'/bus/{str(self.index).zfill(2)}'
12
-
13
-
14
- class AuxRtn(IAuxRtn):
15
- @property
16
- def address(self):
17
- return f'/auxin/{str(self.index).zfill(2)}'
18
-
19
-
20
- class FxRtn(IFxRtn):
21
- @property
22
- def address(self):
23
- return f'/fxrtn/{str(self.index).zfill(2)}'
24
-
25
-
26
- class MainStereo(ILR):
27
- @property
28
- def address(self) -> str:
29
- return '/main/st'
30
-
31
-
32
- class MainMono(ILR):
33
- @property
34
- def address(self) -> str:
35
- return '/main/m'
36
-
37
-
38
- class Matrix(ILR):
39
- @property
40
- def address(self) -> str:
41
- return f'/mtx/{str(self.index).zfill(2)}'
42
-
43
-
44
- class HeadAmp(IHeadAmp):
45
- @property
46
- def address(self):
47
- return f'/headamp/{str(self.index).zfill(3)}'
1
+ from .bus import Bus as IBus
2
+ from .headamp import HeadAmp as IHeadAmp
3
+ from .lr import LR as ILR
4
+ from .rtn import AuxRtn as IAuxRtn
5
+ from .rtn import FxRtn as IFxRtn
6
+
7
+
8
+ class Bus(IBus):
9
+ @property
10
+ def address(self):
11
+ return f'/bus/{str(self.index).zfill(2)}'
12
+
13
+
14
+ class AuxRtn(IAuxRtn):
15
+ @property
16
+ def address(self):
17
+ return f'/auxin/{str(self.index).zfill(2)}'
18
+
19
+
20
+ class FxRtn(IFxRtn):
21
+ @property
22
+ def address(self):
23
+ return f'/fxrtn/{str(self.index).zfill(2)}'
24
+
25
+
26
+ class MainStereo(ILR):
27
+ @property
28
+ def address(self) -> str:
29
+ return '/main/st'
30
+
31
+
32
+ class MainMono(ILR):
33
+ @property
34
+ def address(self) -> str:
35
+ return '/main/m'
36
+
37
+
38
+ class Matrix(ILR):
39
+ @property
40
+ def address(self) -> str:
41
+ return f'/mtx/{str(self.index).zfill(2)}'
42
+
43
+
44
+ class HeadAmp(IHeadAmp):
45
+ @property
46
+ def address(self):
47
+ return f'/headamp/{str(self.index).zfill(3)}'
xair_api/bus.py CHANGED
@@ -1,66 +1,66 @@
1
- import abc
2
- import logging
3
-
4
- from .meta import mute_prop
5
- from .shared import EQ, GEQ, Config, Dyn, Group, Insert, Mix
6
-
7
- logger = logging.getLogger(__name__)
8
-
9
-
10
- class IBus(abc.ABC):
11
- """Abstract Base Class for buses"""
12
-
13
- def __init__(self, remote, index: int):
14
- self._remote = remote
15
- self.index = index + 1
16
- self.logger = logger.getChild(self.__class__.__name__)
17
-
18
- def getter(self, param: str):
19
- return self._remote.query(f'{self.address}/{param}')
20
-
21
- def setter(self, param: str, val: int):
22
- self._remote.send(f'{self.address}/{param}', val)
23
-
24
- @abc.abstractmethod
25
- def address(self):
26
- pass
27
-
28
-
29
- class Bus(IBus):
30
- """Concrete class for buses"""
31
-
32
- @classmethod
33
- def make(cls, remote, index):
34
- """
35
- Factory function for buses
36
-
37
- Creates a mixin of shared subclasses, sets them as class attributes.
38
-
39
- Returns a Bus class of a kind.
40
- """
41
- BUS_cls = type(
42
- f'Bus{remote.kind}',
43
- (cls,),
44
- {
45
- **{
46
- _cls.__name__.lower(): type(
47
- f'{_cls.__name__}{remote.kind}', (_cls, cls), {}
48
- )(remote, index)
49
- for _cls in (
50
- Config,
51
- Dyn,
52
- Insert,
53
- GEQ.make(),
54
- EQ.make_sixband(cls, remote, index),
55
- Mix,
56
- Group,
57
- )
58
- },
59
- 'mute': mute_prop(),
60
- },
61
- )
62
- return BUS_cls(remote, index)
63
-
64
- @property
65
- def address(self) -> str:
66
- return f'/bus/{self.index}'
1
+ import abc
2
+ import logging
3
+
4
+ from .meta import mute_prop
5
+ from .shared import EQ, GEQ, Config, Dyn, Group, Insert, Mix
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ class IBus(abc.ABC):
11
+ """Abstract Base Class for buses"""
12
+
13
+ def __init__(self, remote, index: int):
14
+ self._remote = remote
15
+ self.index = index + 1
16
+ self.logger = logger.getChild(self.__class__.__name__)
17
+
18
+ def getter(self, param: str):
19
+ return self._remote.query(f'{self.address}/{param}')
20
+
21
+ def setter(self, param: str, val: int):
22
+ self._remote.send(f'{self.address}/{param}', val)
23
+
24
+ @abc.abstractmethod
25
+ def address(self):
26
+ pass
27
+
28
+
29
+ class Bus(IBus):
30
+ """Concrete class for buses"""
31
+
32
+ @classmethod
33
+ def make(cls, remote, index):
34
+ """
35
+ Factory function for buses
36
+
37
+ Creates a mixin of shared subclasses, sets them as class attributes.
38
+
39
+ Returns a Bus class of a kind.
40
+ """
41
+ BUS_cls = type(
42
+ f'Bus{remote.kind}',
43
+ (cls,),
44
+ {
45
+ **{
46
+ _cls.__name__.lower(): type(
47
+ f'{_cls.__name__}{remote.kind}', (_cls, cls), {}
48
+ )(remote, index)
49
+ for _cls in (
50
+ Config,
51
+ Dyn,
52
+ Insert,
53
+ GEQ.make(),
54
+ EQ.make_sixband(cls, remote, index),
55
+ Mix,
56
+ Group,
57
+ )
58
+ },
59
+ 'mute': mute_prop(),
60
+ },
61
+ )
62
+ return BUS_cls(remote, index)
63
+
64
+ @property
65
+ def address(self) -> str:
66
+ return f'/bus/{self.index}'
xair_api/config.py CHANGED
@@ -1,207 +1,207 @@
1
- import abc
2
- import logging
3
-
4
- from . import kinds, util
5
- from .meta import bool_prop
6
-
7
- logger = logging.getLogger(__name__)
8
-
9
-
10
- class IConfig(abc.ABC):
11
- """Abstract Base Class for config"""
12
-
13
- def __init__(self, remote):
14
- self._remote = remote
15
- self.logger = logger.getChild(self.__class__.__name__)
16
-
17
- def getter(self, param: str):
18
- return self._remote.query(f'{self.address}/{param}')
19
-
20
- def setter(self, param: str, val: int):
21
- self._remote.send(f'{self.address}/{param}', val)
22
-
23
- @abc.abstractmethod
24
- def address(self):
25
- pass
26
-
27
-
28
- class Config(IConfig):
29
- """Concrete class for config"""
30
-
31
- @classmethod
32
- def make(cls, remote):
33
- """
34
- Factory function for Config
35
-
36
- Returns a Config class of a kind.
37
- """
38
- LINKS_cls = _make_links_mixins[remote.kind.id_]
39
- MUTEGROUP_cls = type('MuteGroup', (Config.MuteGroup, cls), {})
40
- MONITOR_cls = type('ConfigMonitor', (Config.Monitor, cls), {})
41
- CONFIG_cls = type(
42
- f'Config{remote.kind}',
43
- (cls, LINKS_cls),
44
- {
45
- 'mute_group': tuple(MUTEGROUP_cls(remote, i) for i in range(4)),
46
- 'monitor': MONITOR_cls(remote),
47
- },
48
- )
49
- return CONFIG_cls(remote)
50
-
51
- @property
52
- def address(self) -> str:
53
- return '/config'
54
-
55
- @property
56
- def amixenable(self) -> bool:
57
- return self.getter('mute')[0] == 1
58
-
59
- @amixenable.setter
60
- def amixenable(self, val: bool):
61
- self.setter('amixenable', 1 if val else 0)
62
-
63
- @property
64
- def amixlock(self) -> bool:
65
- return self.getter('amixlock')[0] == 1
66
-
67
- @amixlock.setter
68
- def amixlock(self, val: bool):
69
- self.setter('amixlock', 1 if val else 0)
70
-
71
- class MuteGroup:
72
- def __init__(self, remote, i):
73
- super(Config.MuteGroup, self).__init__(remote)
74
- self.i = i + 1
75
-
76
- @property
77
- def address(self) -> str:
78
- root = super(Config.MuteGroup, self).address
79
- return f'{root}/mute'
80
-
81
- @property
82
- def on(self) -> bool:
83
- return self.getter(f'{self.i}')[0] == 1
84
-
85
- @on.setter
86
- def on(self, val: bool):
87
- self.setter(f'{self.i}', 1 if val else 0)
88
-
89
- class Monitor:
90
- @property
91
- def address(self) -> str:
92
- root = super(Config.Monitor, self).address
93
- return f'{root}/solo'
94
-
95
- @property
96
- @util.db_from
97
- def level(self) -> float:
98
- return self.getter('level')[0]
99
-
100
- @level.setter
101
- @util.db_to
102
- def level(self, val: float):
103
- self.setter('level', val)
104
-
105
- @property
106
- def source(self) -> int:
107
- return int(self.getter('source')[0])
108
-
109
- @source.setter
110
- def source(self, val: int):
111
- self.setter('source', val)
112
-
113
- @property
114
- def sourcetrim(self) -> float:
115
- return round(util.lin_get(-18, 18, self.getter('sourcetrim')[0]), 1)
116
-
117
- @sourcetrim.setter
118
- def sourcetrim(self, val: float):
119
- if not -18 <= val <= 18:
120
- self.logger.warning(
121
- f'sourcetrim got {val}, expected value in range -18.0 to 18.0'
122
- )
123
- self.setter('sourcetrim', util.lin_set(-18, 18, val))
124
-
125
- @property
126
- def chmode(self) -> bool:
127
- return self.getter('chmode')[0] == 1
128
-
129
- @chmode.setter
130
- def chmode(self, val: bool):
131
- self.setter('chmode', 1 if val else 0)
132
-
133
- @property
134
- def busmode(self) -> bool:
135
- return self.getter('busmode')[0] == 1
136
-
137
- @busmode.setter
138
- def busmode(self, val: bool):
139
- self.setter('busmode', 1 if val else 0)
140
-
141
- @property
142
- def dimgain(self) -> int:
143
- return int(util.lin_get(-40, 0, self.getter('dimatt')[0]))
144
-
145
- @dimgain.setter
146
- def dimgain(self, val: int):
147
- if not -40 <= val <= 0:
148
- self.logger.warning(
149
- f'dimgain got {val}, expected value in range -40 to 0'
150
- )
151
- self.setter('dimatt', util.lin_set(-40, 0, val))
152
-
153
- @property
154
- def dim(self) -> bool:
155
- return self.getter('dim')[0] == 1
156
-
157
- @dim.setter
158
- def dim(self, val: bool):
159
- self.setter('dim', 1 if val else 0)
160
-
161
- @property
162
- def mono(self) -> bool:
163
- return self.getter('mono')[0] == 1
164
-
165
- @mono.setter
166
- def mono(self, val: bool):
167
- self.setter('mono', 1 if val else 0)
168
-
169
- @property
170
- def mute(self) -> bool:
171
- return self.getter('mute')[0] == 1
172
-
173
- @mute.setter
174
- def mute(self, val: bool):
175
- self.setter('mute', 1 if val else 0)
176
-
177
- @property
178
- def dimfpl(self) -> bool:
179
- return self.getter('dimfpl')[0] == 1
180
-
181
- @dimfpl.setter
182
- def dimfpl(self, val: bool):
183
- self.setter('dimfpl', 1 if val else 0)
184
-
185
-
186
- def _make_links_mixin(kind):
187
- """Creates a links mixin"""
188
- return type(
189
- f'Links{kind}',
190
- (),
191
- {
192
- 'link_eq': bool_prop('linkcfg/eq'),
193
- 'link_dyn': bool_prop('linkcfg/dyn'),
194
- 'link_fader_mute': bool_prop('linkcfg/fdrmute'),
195
- **{
196
- f'chlink{i}_{i+1}': bool_prop(f'chlink/{i}-{i+1}')
197
- for i in range(1, kind.num_strip, 2)
198
- },
199
- **{
200
- f'buslink{i}_{i+1}': bool_prop(f'buslink/{i}-{i+1}')
201
- for i in range(1, kind.num_bus, 2)
202
- },
203
- },
204
- )
205
-
206
-
207
- _make_links_mixins = {kind.id_: _make_links_mixin(kind) for kind in kinds.all}
1
+ import abc
2
+ import logging
3
+
4
+ from . import kinds, util
5
+ from .meta import bool_prop
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ class IConfig(abc.ABC):
11
+ """Abstract Base Class for config"""
12
+
13
+ def __init__(self, remote):
14
+ self._remote = remote
15
+ self.logger = logger.getChild(self.__class__.__name__)
16
+
17
+ def getter(self, param: str):
18
+ return self._remote.query(f'{self.address}/{param}')
19
+
20
+ def setter(self, param: str, val: int):
21
+ self._remote.send(f'{self.address}/{param}', val)
22
+
23
+ @abc.abstractmethod
24
+ def address(self):
25
+ pass
26
+
27
+
28
+ class Config(IConfig):
29
+ """Concrete class for config"""
30
+
31
+ @classmethod
32
+ def make(cls, remote):
33
+ """
34
+ Factory function for Config
35
+
36
+ Returns a Config class of a kind.
37
+ """
38
+ LINKS_cls = _make_links_mixins[remote.kind.id_]
39
+ MUTEGROUP_cls = type('MuteGroup', (Config.MuteGroup, cls), {})
40
+ MONITOR_cls = type('ConfigMonitor', (Config.Monitor, cls), {})
41
+ CONFIG_cls = type(
42
+ f'Config{remote.kind}',
43
+ (cls, LINKS_cls),
44
+ {
45
+ 'mute_group': tuple(MUTEGROUP_cls(remote, i) for i in range(4)),
46
+ 'monitor': MONITOR_cls(remote),
47
+ },
48
+ )
49
+ return CONFIG_cls(remote)
50
+
51
+ @property
52
+ def address(self) -> str:
53
+ return '/config'
54
+
55
+ @property
56
+ def amixenable(self) -> bool:
57
+ return self.getter('mute')[0] == 1
58
+
59
+ @amixenable.setter
60
+ def amixenable(self, val: bool):
61
+ self.setter('amixenable', 1 if val else 0)
62
+
63
+ @property
64
+ def amixlock(self) -> bool:
65
+ return self.getter('amixlock')[0] == 1
66
+
67
+ @amixlock.setter
68
+ def amixlock(self, val: bool):
69
+ self.setter('amixlock', 1 if val else 0)
70
+
71
+ class MuteGroup:
72
+ def __init__(self, remote, i):
73
+ super(Config.MuteGroup, self).__init__(remote)
74
+ self.i = i + 1
75
+
76
+ @property
77
+ def address(self) -> str:
78
+ root = super(Config.MuteGroup, self).address
79
+ return f'{root}/mute'
80
+
81
+ @property
82
+ def on(self) -> bool:
83
+ return self.getter(f'{self.i}')[0] == 1
84
+
85
+ @on.setter
86
+ def on(self, val: bool):
87
+ self.setter(f'{self.i}', 1 if val else 0)
88
+
89
+ class Monitor:
90
+ @property
91
+ def address(self) -> str:
92
+ root = super(Config.Monitor, self).address
93
+ return f'{root}/solo'
94
+
95
+ @property
96
+ @util.db_from
97
+ def level(self) -> float:
98
+ return self.getter('level')[0]
99
+
100
+ @level.setter
101
+ @util.db_to
102
+ def level(self, val: float):
103
+ self.setter('level', val)
104
+
105
+ @property
106
+ def source(self) -> int:
107
+ return int(self.getter('source')[0])
108
+
109
+ @source.setter
110
+ def source(self, val: int):
111
+ self.setter('source', val)
112
+
113
+ @property
114
+ def sourcetrim(self) -> float:
115
+ return round(util.lin_get(-18, 18, self.getter('sourcetrim')[0]), 1)
116
+
117
+ @sourcetrim.setter
118
+ def sourcetrim(self, val: float):
119
+ if not -18 <= val <= 18:
120
+ self.logger.warning(
121
+ f'sourcetrim got {val}, expected value in range -18.0 to 18.0'
122
+ )
123
+ self.setter('sourcetrim', util.lin_set(-18, 18, val))
124
+
125
+ @property
126
+ def chmode(self) -> bool:
127
+ return self.getter('chmode')[0] == 1
128
+
129
+ @chmode.setter
130
+ def chmode(self, val: bool):
131
+ self.setter('chmode', 1 if val else 0)
132
+
133
+ @property
134
+ def busmode(self) -> bool:
135
+ return self.getter('busmode')[0] == 1
136
+
137
+ @busmode.setter
138
+ def busmode(self, val: bool):
139
+ self.setter('busmode', 1 if val else 0)
140
+
141
+ @property
142
+ def dimgain(self) -> int:
143
+ return int(util.lin_get(-40, 0, self.getter('dimatt')[0]))
144
+
145
+ @dimgain.setter
146
+ def dimgain(self, val: int):
147
+ if not -40 <= val <= 0:
148
+ self.logger.warning(
149
+ f'dimgain got {val}, expected value in range -40 to 0'
150
+ )
151
+ self.setter('dimatt', util.lin_set(-40, 0, val))
152
+
153
+ @property
154
+ def dim(self) -> bool:
155
+ return self.getter('dim')[0] == 1
156
+
157
+ @dim.setter
158
+ def dim(self, val: bool):
159
+ self.setter('dim', 1 if val else 0)
160
+
161
+ @property
162
+ def mono(self) -> bool:
163
+ return self.getter('mono')[0] == 1
164
+
165
+ @mono.setter
166
+ def mono(self, val: bool):
167
+ self.setter('mono', 1 if val else 0)
168
+
169
+ @property
170
+ def mute(self) -> bool:
171
+ return self.getter('mute')[0] == 1
172
+
173
+ @mute.setter
174
+ def mute(self, val: bool):
175
+ self.setter('mute', 1 if val else 0)
176
+
177
+ @property
178
+ def dimfpl(self) -> bool:
179
+ return self.getter('dimfpl')[0] == 1
180
+
181
+ @dimfpl.setter
182
+ def dimfpl(self, val: bool):
183
+ self.setter('dimfpl', 1 if val else 0)
184
+
185
+
186
+ def _make_links_mixin(kind):
187
+ """Creates a links mixin"""
188
+ return type(
189
+ f'Links{kind}',
190
+ (),
191
+ {
192
+ 'link_eq': bool_prop('linkcfg/eq'),
193
+ 'link_dyn': bool_prop('linkcfg/dyn'),
194
+ 'link_fader_mute': bool_prop('linkcfg/fdrmute'),
195
+ **{
196
+ f'chlink{i}_{i+1}': bool_prop(f'chlink/{i}-{i+1}')
197
+ for i in range(1, kind.num_strip, 2)
198
+ },
199
+ **{
200
+ f'buslink{i}_{i+1}': bool_prop(f'buslink/{i}-{i+1}')
201
+ for i in range(1, kind.num_bus, 2)
202
+ },
203
+ },
204
+ )
205
+
206
+
207
+ _make_links_mixins = {kind.id_: _make_links_mixin(kind) for kind in kinds.all}