Compare commits

...

6 Commits

Author SHA1 Message Date
fd4a228086 re-run through ruff formatter 2025-01-15 11:10:45 +00:00
b45abf2492 reformat snippets in readme 2025-01-15 10:57:39 +00:00
53ad8fdff5 re-run through ruff formatter 2025-01-15 10:54:52 +00:00
5a988e8d37 remake pyproject with poetry 2 2025-01-15 10:54:36 +00:00
1ada889135 add tox env for obs example
add headamp script to poe tasks
2025-01-15 10:22:46 +00:00
7ede9b1ef3 freeze dataclasses 2025-01-15 10:21:22 +00:00
28 changed files with 597 additions and 531 deletions

View File

@ -39,18 +39,18 @@ import xair_api
def main(): def main():
kind_id = "XR18" kind_id = 'XR18'
ip = "<ip address>" ip = '<ip address>'
with xair_api.connect(kind_id, ip=ip) as mixer: with xair_api.connect(kind_id, ip=ip) as mixer:
mixer.strip[8].config.name = "sm7b" mixer.strip[8].config.name = 'sm7b'
mixer.strip[8].mix.on = True mixer.strip[8].mix.on = True
print( print(
f"strip 09 ({mixer.strip[8].config.name}) on has been set to {mixer.strip[8].mix.on}" f'strip 09 ({mixer.strip[8].config.name}) on has been set to {mixer.strip[8].mix.on}'
) )
if __name__ == "__main__": if __name__ == '__main__':
main() main()
``` ```
@ -314,8 +314,8 @@ Send an OSC command directly to the mixer
for example: for example:
```python ```python
mixer.send("/ch/01/mix/on", 1) mixer.send('/ch/01/mix/on', 1)
mixer.send("/bus/2/config/name", "somename") mixer.send('/bus/2/config/name', 'somename')
``` ```
Query the value of a command: Query the value of a command:
@ -325,7 +325,7 @@ Query the value of a command:
for example: for example:
```python ```python
print(mixer.query("/ch/01/mix/on")) print(mixer.query('/ch/01/mix/on'))
``` ```
### Errors ### Errors

View File

@ -2,16 +2,16 @@ import xair_api
def main(): def main():
kind_id = "XR18" kind_id = 'XR18'
ip = "<ip address>" ip = '<ip address>'
with xair_api.connect(kind_id, ip=ip) as mixer: with xair_api.connect(kind_id, ip=ip) as mixer:
mixer.strip[8].config.name = "sm7b" mixer.strip[8].config.name = 'sm7b'
mixer.strip[8].config.on = True mixer.strip[8].config.on = True
print( print(
f"strip 09 ({mixer.strip[8].config.name}) has been set to {mixer.strip[8].config.on}" f'strip 09 ({mixer.strip[8].config.name}) has been set to {mixer.strip[8].config.on}'
) )
if __name__ == "__main__": if __name__ == '__main__':
main() main()

View File

@ -8,13 +8,13 @@ logging.basicConfig(level=logging.DEBUG)
def main(): def main():
with xair_api.connect("XR18", ip="mixer.local") as mixer: with xair_api.connect('XR18', ip='mixer.local') as mixer:
mixer.headamp[8].phantom = True mixer.headamp[8].phantom = True
for i in range(-12, -6): for i in range(-12, -6):
mixer.headamp[8].gain = i mixer.headamp[8].gain = i
print(mixer.headamp[8].gain) print(mixer.headamp[8].gain)
input("Press Enter to continue...") input('Press Enter to continue...')
if __name__ == "__main__": if __name__ == '__main__':
main() main()

View File

@ -6,7 +6,7 @@ logging.basicConfig(level=logging.DEBUG)
def main(): def main():
with xair_api.connect("XR18", ip="mixer.local") as mixer: with xair_api.connect('XR18', ip='mixer.local') as mixer:
for send in mixer.strip[0].send: for send in mixer.strip[0].send:
send.level = -22.8 send.level = -22.8
@ -20,5 +20,5 @@ def main():
print(mixer.fxreturn[0].send[0].level) print(mixer.fxreturn[0].send[0].level)
if __name__ == "__main__": if __name__ == '__main__':
main() main()

View File

@ -17,28 +17,28 @@ class Observer:
def on_current_program_scene_changed(self, data): def on_current_program_scene_changed(self, data):
scene = data.scene_name scene = data.scene_name
print(f"Switched to scene {scene}") print(f'Switched to scene {scene}')
match scene: match scene:
case "START": case 'START':
print("Toggling strip 01 on") print('Toggling strip 01 on')
self._mixer.strip[0].mix.on = not self._mixer.strip[0].mix.on self._mixer.strip[0].mix.on = not self._mixer.strip[0].mix.on
case "BRB": case 'BRB':
print("Setting strip 08 fader") print('Setting strip 08 fader')
self._mixer.strip[7].mix.fader = -12.8 self._mixer.strip[7].mix.fader = -12.8
case "END": case 'END':
print("Settings strip 02 color") print('Settings strip 02 color')
self._mixer.strip[1].config.color = 8 self._mixer.strip[1].config.color = 8
case "LIVE": case 'LIVE':
self._mixer.config.mute_group[0].on = True self._mixer.config.mute_group[0].on = True
print(f"Mute Group 1 is {self._mixer.config.mute_group[0].on}") print(f'Mute Group 1 is {self._mixer.config.mute_group[0].on}')
def main(): def main():
with xair_api.connect("MR18", ip="mixer.local") as mixer: with xair_api.connect('MR18', ip='mixer.local') as mixer:
with Observer(mixer): with Observer(mixer):
while _ := input("Press <Enter> to exit\n"): while _ := input('Press <Enter> to exit\n'):
pass pass
if __name__ == "__main__": if __name__ == '__main__':
main() main()

116
poetry.lock generated
View File

@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. # This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand.
[[package]] [[package]]
name = "cachetools" name = "cachetools"
@ -6,6 +6,7 @@ version = "5.5.0"
description = "Extensible memoizing collections and decorators" description = "Extensible memoizing collections and decorators"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
groups = ["dev"]
files = [ files = [
{file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"},
{file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"},
@ -17,6 +18,7 @@ version = "5.2.0"
description = "Universal encoding detector for Python 3" description = "Universal encoding detector for Python 3"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
groups = ["dev"]
files = [ files = [
{file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
{file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
@ -28,6 +30,7 @@ version = "0.4.6"
description = "Cross-platform colored terminal text." description = "Cross-platform colored terminal text."
optional = false optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
groups = ["dev"]
files = [ files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
@ -39,6 +42,7 @@ version = "0.3.9"
description = "Distribution utilities" description = "Distribution utilities"
optional = false optional = false
python-versions = "*" python-versions = "*"
groups = ["dev"]
files = [ files = [
{file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"},
{file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"},
@ -46,13 +50,15 @@ files = [
[[package]] [[package]]
name = "exceptiongroup" name = "exceptiongroup"
version = "1.2.0" version = "1.2.2"
description = "Backport of PEP 654 (exception groups)" description = "Backport of PEP 654 (exception groups)"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
groups = ["dev"]
markers = "python_version < \"3.11\""
files = [ files = [
{file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
{file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
] ]
[package.extras] [package.extras]
@ -64,6 +70,7 @@ version = "3.16.1"
description = "A platform independent file lock." description = "A platform independent file lock."
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["dev"]
files = [ files = [
{file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"},
{file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"},
@ -76,13 +83,14 @@ typing = ["typing-extensions (>=4.12.2)"]
[[package]] [[package]]
name = "iniconfig" name = "iniconfig"
version = "1.1.1" version = "2.0.0"
description = "iniconfig: brain-dead simple config-ini parsing" description = "brain-dead simple config-ini parsing"
optional = false optional = false
python-versions = "*" python-versions = ">=3.7"
groups = ["dev"]
files = [ files = [
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
] ]
[[package]] [[package]]
@ -91,6 +99,7 @@ version = "24.2"
description = "Core utilities for Python packages" description = "Core utilities for Python packages"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["dev"]
files = [ files = [
{file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
@ -102,6 +111,7 @@ version = "4.3.6"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["dev"]
files = [ files = [
{file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"},
{file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"},
@ -118,6 +128,7 @@ version = "1.5.0"
description = "plugin and hook calling mechanisms for python" description = "plugin and hook calling mechanisms for python"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["dev"]
files = [ files = [
{file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
{file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
@ -133,6 +144,7 @@ version = "0.4.0"
description = "An auxiliary library for the virtualenv-pyenv and tox-pyenv-redux plugins" description = "An auxiliary library for the virtualenv-pyenv and tox-pyenv-redux plugins"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["dev"]
files = [ files = [
{file = "pyenv-inspect-0.4.0.tar.gz", hash = "sha256:ec429d1d81b67ab0b08a0408414722a79d24fd1845a5b264267e44e19d8d60f0"}, {file = "pyenv-inspect-0.4.0.tar.gz", hash = "sha256:ec429d1d81b67ab0b08a0408414722a79d24fd1845a5b264267e44e19d8d60f0"},
{file = "pyenv_inspect-0.4.0-py3-none-any.whl", hash = "sha256:618683ae7d3e6db14778d58aa0fc6b3170180d944669b5d35a8aa4fb7db550d2"}, {file = "pyenv_inspect-0.4.0-py3-none-any.whl", hash = "sha256:618683ae7d3e6db14778d58aa0fc6b3170180d944669b5d35a8aa4fb7db550d2"},
@ -144,6 +156,7 @@ version = "1.8.0"
description = "API to interact with the python pyproject.toml based projects" description = "API to interact with the python pyproject.toml based projects"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["dev"]
files = [ files = [
{file = "pyproject_api-1.8.0-py3-none-any.whl", hash = "sha256:3d7d347a047afe796fd5d1885b1e391ba29be7169bd2f102fcd378f04273d228"}, {file = "pyproject_api-1.8.0-py3-none-any.whl", hash = "sha256:3d7d347a047afe796fd5d1885b1e391ba29be7169bd2f102fcd378f04273d228"},
{file = "pyproject_api-1.8.0.tar.gz", hash = "sha256:77b8049f2feb5d33eefcc21b57f1e279636277a8ac8ad6b5871037b243778496"}, {file = "pyproject_api-1.8.0.tar.gz", hash = "sha256:77b8049f2feb5d33eefcc21b57f1e279636277a8ac8ad6b5871037b243778496"},
@ -159,13 +172,14 @@ testing = ["covdefaults (>=2.3)", "pytest (>=8.3.3)", "pytest-cov (>=5)", "pytes
[[package]] [[package]]
name = "pytest" name = "pytest"
version = "7.4.4" version = "8.3.4"
description = "pytest: simple powerful testing with Python" description = "pytest: simple powerful testing with Python"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.8"
groups = ["dev"]
files = [ files = [
{file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"},
{file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"},
] ]
[package.dependencies] [package.dependencies]
@ -173,21 +187,22 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*" iniconfig = "*"
packaging = "*" packaging = "*"
pluggy = ">=0.12,<2.0" pluggy = ">=1.5,<2"
tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} tomli = {version = ">=1", markers = "python_version < \"3.11\""}
[package.extras] [package.extras]
testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
[[package]] [[package]]
name = "pytest-randomly" name = "pytest-randomly"
version = "3.12.0" version = "3.16.0"
description = "Pytest plugin to randomly order tests and control random.seed." description = "Pytest plugin to randomly order tests and control random.seed."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.9"
groups = ["dev"]
files = [ files = [
{file = "pytest-randomly-3.12.0.tar.gz", hash = "sha256:d60c2db71ac319aee0fc6c4110a7597d611a8b94a5590918bfa8583f00caccb2"}, {file = "pytest_randomly-3.16.0-py3-none-any.whl", hash = "sha256:8633d332635a1a0983d3bba19342196807f6afb17c3eef78e02c2f85dade45d6"},
{file = "pytest_randomly-3.12.0-py3-none-any.whl", hash = "sha256:f4f2e803daf5d1ba036cc22bf4fe9dbbf99389ec56b00e5cba732fb5c1d07fdd"}, {file = "pytest_randomly-3.16.0.tar.gz", hash = "sha256:11bf4d23a26484de7860d82f726c0629837cf4064b79157bd18ec9d41d7feb26"},
] ]
[package.dependencies] [package.dependencies]
@ -195,13 +210,14 @@ pytest = "*"
[[package]] [[package]]
name = "python-osc" name = "python-osc"
version = "1.8.0" version = "1.9.3"
description = "Open Sound Control server and client implementations in pure Python" description = "Open Sound Control server and client implementations in pure Python"
optional = false optional = false
python-versions = "*" python-versions = ">=3.10"
groups = ["main"]
files = [ files = [
{file = "python-osc-1.8.0.tar.gz", hash = "sha256:2f8c187c68d239960fb2eddcb5346a62a9b35e64f2de045b3e5e509f475ca73d"}, {file = "python_osc-1.9.3-py3-none-any.whl", hash = "sha256:7def2075be72f07bae5a4c1a55cc7d907b247f4a5d910f3159ed30ac2b1f17cc"},
{file = "python_osc-1.8.0-py3-none-any.whl", hash = "sha256:9e2abb2fc9ba2c356f8e951609a03c9c7017bf0bad82cca8490e9b8af9e92a0b"}, {file = "python_osc-1.9.3.tar.gz", hash = "sha256:bd0fa40def43ce509894709feb0e18f02192aca192c5e6c8fe2ba69e58f21794"},
] ]
[[package]] [[package]]
@ -210,6 +226,7 @@ version = "0.8.6"
description = "An extremely fast Python linter and code formatter, written in Rust." description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
groups = ["dev"]
files = [ files = [
{file = "ruff-0.8.6-py3-none-linux_armv6l.whl", hash = "sha256:defed167955d42c68b407e8f2e6f56ba52520e790aba4ca707a9c88619e580e3"}, {file = "ruff-0.8.6-py3-none-linux_armv6l.whl", hash = "sha256:defed167955d42c68b407e8f2e6f56ba52520e790aba4ca707a9c88619e580e3"},
{file = "ruff-0.8.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:54799ca3d67ae5e0b7a7ac234baa657a9c1784b48ec954a094da7c206e0365b1"}, {file = "ruff-0.8.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:54799ca3d67ae5e0b7a7ac234baa657a9c1784b48ec954a094da7c206e0365b1"},
@ -233,13 +250,45 @@ files = [
[[package]] [[package]]
name = "tomli" name = "tomli"
version = "2.0.1" version = "2.2.1"
description = "A lil' TOML parser" description = "A lil' TOML parser"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.8"
groups = ["main", "dev"]
markers = "python_version < \"3.11\""
files = [ files = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
{file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
{file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
{file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
{file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
{file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
{file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
{file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
{file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
{file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
{file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
{file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
{file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
] ]
[[package]] [[package]]
@ -248,6 +297,7 @@ version = "4.23.2"
description = "tox is a generic virtualenv management and test command line tool" description = "tox is a generic virtualenv management and test command line tool"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["dev"]
files = [ files = [
{file = "tox-4.23.2-py3-none-any.whl", hash = "sha256:452bc32bb031f2282881a2118923176445bac783ab97c874b8770ab4c3b76c38"}, {file = "tox-4.23.2-py3-none-any.whl", hash = "sha256:452bc32bb031f2282881a2118923176445bac783ab97c874b8770ab4c3b76c38"},
{file = "tox-4.23.2.tar.gz", hash = "sha256:86075e00e555df6e82e74cfc333917f91ecb47ffbc868dcafbd2672e332f4a2c"}, {file = "tox-4.23.2.tar.gz", hash = "sha256:86075e00e555df6e82e74cfc333917f91ecb47ffbc868dcafbd2672e332f4a2c"},
@ -275,6 +325,8 @@ version = "4.12.2"
description = "Backported and Experimental Type Hints for Python 3.8+" description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["dev"]
markers = "python_version < \"3.11\""
files = [ files = [
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
@ -286,6 +338,7 @@ version = "20.28.1"
description = "Virtual Python Environment builder" description = "Virtual Python Environment builder"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["dev"]
files = [ files = [
{file = "virtualenv-20.28.1-py3-none-any.whl", hash = "sha256:412773c85d4dab0409b83ec36f7a6499e72eaf08c80e81e9576bca61831c71cb"}, {file = "virtualenv-20.28.1-py3-none-any.whl", hash = "sha256:412773c85d4dab0409b83ec36f7a6499e72eaf08c80e81e9576bca61831c71cb"},
{file = "virtualenv-20.28.1.tar.gz", hash = "sha256:5d34ab240fdb5d21549b76f9e8ff3af28252f5499fb6d6f031adac4e5a8c5329"}, {file = "virtualenv-20.28.1.tar.gz", hash = "sha256:5d34ab240fdb5d21549b76f9e8ff3af28252f5499fb6d6f031adac4e5a8c5329"},
@ -306,6 +359,7 @@ version = "0.5.0"
description = "A virtualenv Python discovery plugin for pyenv-installed interpreters" description = "A virtualenv Python discovery plugin for pyenv-installed interpreters"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["dev"]
files = [ files = [
{file = "virtualenv-pyenv-0.5.0.tar.gz", hash = "sha256:7b0e5fe3dfbdf484f4cf9b01e1f98111e398db6942237910f666356e6293597f"}, {file = "virtualenv-pyenv-0.5.0.tar.gz", hash = "sha256:7b0e5fe3dfbdf484f4cf9b01e1f98111e398db6942237910f666356e6293597f"},
{file = "virtualenv_pyenv-0.5.0-py3-none-any.whl", hash = "sha256:21750247e36c55b3c547cfdeb08f51a3867fe7129922991a4f9c96980c0a4a5d"}, {file = "virtualenv_pyenv-0.5.0-py3-none-any.whl", hash = "sha256:21750247e36c55b3c547cfdeb08f51a3867fe7129922991a4f9c96980c0a4a5d"},
@ -316,6 +370,6 @@ pyenv-inspect = ">=0.4,<0.5"
virtualenv = "*" virtualenv = "*"
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.1"
python-versions = "^3.10" python-versions = "<4.0,>=3.10"
content-hash = "03c4b24c8bf12ad78f55f6e99a5001183bbb855bf8ef841dd3522fb79c1f7288" content-hash = "6cd4c5329b1df022fdec343a52a0fda804c33234b208aab94025e6798ea6820d"

View File

@ -1,34 +1,36 @@
[tool.poetry] [project]
name = "xair-api" name = "xair-api"
version = "2.4.0" version = "2.4.1"
description = "Remote control Behringer X-Air | Midas MR mixers through OSC" description = "Remote control Behringer X-Air | Midas MR mixers through OSC"
authors = ["onyx-and-iris <code@onyxandiris.online>"] authors = [
license = "MIT" {name = "Onyx and Iris",email = "code@onyxandiris.online"}
]
license = {text = "MIT"}
readme = "README.md" readme = "README.md"
repository = "https://github.com/onyx-and-iris/xair-api-python" requires-python = "<4.0,>=3.10"
dependencies = [
"python-osc (>=1.9.3,<2.0.0)",
"tomli (>=2.0.1,<3.0) ; python_version < '3.11'"
]
[tool.poetry.requires-plugins] [tool.poetry.requires-plugins]
poethepoet = "^0.32.1" poethepoet = "^0.32.1"
[tool.poetry.dependencies]
python = "^3.10"
python-osc = "^1.8.0"
tomli = { version = "^2.0.1", python = "<3.11" }
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
pytest = "^7.4.4" pytest = "^8.3.4"
pytest-randomly = "^3.12.0" pytest-randomly = "^3.16.0"
ruff = "^0.8.6" ruff = "^0.8.6"
tox = "^4.23.2" tox = "^4.23.2"
virtualenv-pyenv = "^0.5.0" virtualenv-pyenv = "^0.5.0"
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"
[tool.poe.tasks] [tool.poe.tasks]
obs.script = "scripts:ex_obs" obs.script = "scripts:ex_obs"
sends.script = "scripts:ex_sends" sends.script = "scripts:ex_sends"
headamp.script = "scripts:ex_headamp"
xair.script = "scripts:test_xair" xair.script = "scripts:test_xair"
x32.script = "scripts:test_x32" x32.script = "scripts:test_x32"
all.script = "scripts:test_all" all.script = "scripts:test_all"
@ -44,6 +46,14 @@ allowlist_externals = poetry
commands = commands =
poetry install -v poetry install -v
poetry run pytest tests/ poetry run pytest tests/
[testenv:obs]
setenv = VIRTUALENV_DISCOVERY=pyenv
allowlist_externals = poetry
deps = obsws-python
commands =
poetry install -v --without dev
poetry run python examples/xair_obs/
""" """
[tool.ruff] [tool.ruff]
@ -93,8 +103,8 @@ unfixable = []
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
[tool.ruff.format] [tool.ruff.format]
# Like Black, use double quotes for strings. # Unlike Black, use single quotes for strings.
quote-style = "double" quote-style = "single"
# Like Black, indent with spaces, rather than tabs. # Like Black, indent with spaces, rather than tabs.
indent-style = "space" indent-style = "space"

View File

@ -4,8 +4,7 @@ from pathlib import Path
def ex_obs(): def ex_obs():
path = Path.cwd() / "examples" / "xair_obs" / "." subprocess.run(["tox", "r", "-e", "obs"])
subprocess.run([sys.executable, str(path)])
def ex_sends(): def ex_sends():
@ -13,6 +12,11 @@ def ex_sends():
subprocess.run([sys.executable, str(path)]) subprocess.run([sys.executable, str(path)])
def ex_headamp():
path = Path.cwd() / "examples" / "headamp" / "."
subprocess.run([sys.executable, str(path)])
def test_xair(): def test_xair():
path = Path.cwd() / "tests" / "xair" path = Path.cwd() / "tests" / "xair"
subprocess.run(["pytest", "-v", str(path)]) subprocess.run(["pytest", "-v", str(path)])

View File

@ -5,8 +5,8 @@ from dataclasses import dataclass
import xair_api import xair_api
from xair_api import kinds from xair_api import kinds
kind_id = "X32" kind_id = 'X32'
ip = "x32.local" ip = 'x32.local'
tests = xair_api.connect(kind_id, ip=ip) tests = xair_api.connect(kind_id, ip=ip)
@ -30,7 +30,7 @@ data = Data()
def setup_module(): def setup_module():
print(f"\nRunning tests for kind [{data.name}]\n", file=sys.stdout) print(f'\nRunning tests for kind [{data.name}]\n', file=sys.stdout)
tests.worker = threading.Thread(target=tests.run_server) tests.worker = threading.Thread(target=tests.run_server)
tests.worker.daemon = True tests.worker.daemon = True
tests.worker.start() tests.worker.start()

View File

@ -11,11 +11,11 @@ class TestSetAndGetStripMuteHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "strip")[data.strip] self.target = getattr(tests, 'strip')[data.strip]
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("mute", True), ("mute", False)], [('mute', True), ('mute', False)],
) )
def test_it_sets_and_gets_strip_mute_bool_params(self, param, value): def test_it_sets_and_gets_strip_mute_bool_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -28,12 +28,12 @@ class TestSetAndGetStripMixHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "strip") self.target = getattr(tests, 'strip')
self.target = getattr(self.target[data.strip], "mix") self.target = getattr(self.target[data.strip], 'mix')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("on", True), ("on", False)], [('on', True), ('on', False)],
) )
def test_it_sets_and_gets_strip_bool_params(self, param, value): def test_it_sets_and_gets_strip_bool_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -49,12 +49,12 @@ class TestSetAndGetBusConfigHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "bus") self.target = getattr(tests, 'bus')
self.target = getattr(self.target[data.bus], "config") self.target = getattr(self.target[data.bus], 'config')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("color", 0), ("color", 15)], [('color', 0), ('color', 15)],
) )
def test_it_sets_and_gets_bus_int_params(self, param, value): def test_it_sets_and_gets_bus_int_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -70,12 +70,12 @@ class TestSetAndGetAuxInPreampHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "auxin") self.target = getattr(tests, 'auxin')
self.target = getattr(self.target[data.auxrtn], "preamp") self.target = getattr(self.target[data.auxrtn], 'preamp')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("invert", True), ("invert", False)], [('invert', True), ('invert', False)],
) )
def test_it_sets_and_gets_auxrtn_bool_params(self, param, value): def test_it_sets_and_gets_auxrtn_bool_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -91,12 +91,12 @@ class TestSetAndGetFXReturnEQHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "fxreturn") self.target = getattr(tests, 'fxreturn')
self.target = getattr(self.target[data.fx], "eq") self.target = getattr(self.target[data.fx], 'eq')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("on", True), ("on", False)], [('on', True), ('on', False)],
) )
def test_it_sets_and_gets_fxrtn_bool_params(self, param, value): def test_it_sets_and_gets_fxrtn_bool_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -112,12 +112,12 @@ class TestSetAndGetMatrixDynHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "matrix") self.target = getattr(tests, 'matrix')
self.target = getattr(self.target[data.matrix], "dyn") self.target = getattr(self.target[data.matrix], 'dyn')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("mode", "comp"), ("mode", "exp")], [('mode', 'comp'), ('mode', 'exp')],
) )
def test_it_sets_and_gets_matrix_string_params(self, param, value): def test_it_sets_and_gets_matrix_string_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -133,11 +133,11 @@ class TestSetAndGetMainStereoInsertHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "mainst") self.target = getattr(tests, 'mainst')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("mode", "comp"), ("mode", "exp")], [('mode', 'comp'), ('mode', 'exp')],
) )
def test_it_sets_and_gets_mainst_string_params(self, param, value): def test_it_sets_and_gets_mainst_string_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)

View File

@ -5,8 +5,8 @@ from dataclasses import dataclass
import xair_api import xair_api
from xair_api import kinds from xair_api import kinds
kind_id = "MR18" kind_id = 'MR18'
ip = "mixer.local" ip = 'mixer.local'
tests = xair_api.connect(kind_id, ip=ip) tests = xair_api.connect(kind_id, ip=ip)
@ -28,7 +28,7 @@ data = Data()
def setup_module(): def setup_module():
print(f"\nRunning tests for kind [{data.name}]\n", file=sys.stdout) print(f'\nRunning tests for kind [{data.name}]\n', file=sys.stdout)
tests.worker = threading.Thread(target=tests.run_server) tests.worker = threading.Thread(target=tests.run_server)
tests.worker.daemon = True tests.worker.daemon = True
tests.worker.start() tests.worker.start()

View File

@ -19,20 +19,20 @@ class TestSetAndGetLRMixHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "lr") self.target = getattr(tests, 'lr')
self.target = getattr(self.target, "mix") self.target = getattr(self.target, 'mix')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("on", True), ("on", False)], [('on', True), ('on', False)],
) )
def test_it_sets_and_gets_lr_bool_params(self, param, value): def test_it_sets_and_gets_lr_bool_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
assert getattr(self.target, param) == value assert getattr(self.target, param) == value
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("fader", -80.6), ("fader", -67.0)], [('fader', -80.6), ('fader', -67.0)],
) )
def test_it_sets_and_gets_lr_float_params(self, param, value): def test_it_sets_and_gets_lr_float_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -45,10 +45,10 @@ class TestSetAndGetLRConfigHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "lr") self.target = getattr(tests, 'lr')
self.target = getattr(self.target, "config") self.target = getattr(self.target, 'config')
@pytest.mark.parametrize("param,value", [("name", "test0"), ("name", "test1")]) @pytest.mark.parametrize('param,value', [('name', 'test0'), ('name', 'test1')])
def test_it_sets_and_gets_lr_string_params(self, param, value): def test_it_sets_and_gets_lr_string_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
assert getattr(self.target, param) == value assert getattr(self.target, param) == value
@ -60,20 +60,20 @@ class TestSetAndGetLRInsertHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "lr") self.target = getattr(tests, 'lr')
self.target = getattr(self.target, "insert") self.target = getattr(self.target, 'insert')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("on", True), ("on", False)], [('on', True), ('on', False)],
) )
def test_it_sets_and_gets_lr_bool_params(self, param, value): def test_it_sets_and_gets_lr_bool_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
assert getattr(self.target, param) == value assert getattr(self.target, param) == value
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("sel", 0), ("sel", 4)], [('sel', 0), ('sel', 4)],
) )
def test_it_sets_and_gets_lr_int_params(self, param, value): def test_it_sets_and_gets_lr_int_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -86,16 +86,16 @@ class TestSetAndGetLRGEQHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "lr") self.target = getattr(tests, 'lr')
self.target = getattr(self.target, "geq") self.target = getattr(self.target, 'geq')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[ [
("slider_20", -13.5), ('slider_20', -13.5),
("slider_20", 5.5), ('slider_20', 5.5),
("slider_6k3", -8.5), ('slider_6k3', -8.5),
("slider_6k3", 8.5), ('slider_6k3', 8.5),
], ],
) )
def test_it_sets_and_gets_lr_int_params(self, param, value): def test_it_sets_and_gets_lr_int_params(self, param, value):
@ -112,11 +112,11 @@ class TestSetAndGetStripMuteHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "strip")[data.strip] self.target = getattr(tests, 'strip')[data.strip]
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("mute", True), ("mute", False)], [('mute', True), ('mute', False)],
) )
def test_it_sets_and_gets_strip_mute_bool_params(self, param, value): def test_it_sets_and_gets_strip_mute_bool_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -129,12 +129,12 @@ class TestSetAndGetStripMixHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "strip") self.target = getattr(tests, 'strip')
self.target = getattr(self.target[data.strip], "mix") self.target = getattr(self.target[data.strip], 'mix')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("on", True), ("on", False), ("lr", True), ("lr", False)], [('on', True), ('on', False), ('lr', True), ('lr', False)],
) )
def test_it_sets_and_gets_strip_bool_params(self, param, value): def test_it_sets_and_gets_strip_bool_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -147,16 +147,16 @@ class TestSetAndGetStripPreampHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "strip") self.target = getattr(tests, 'strip')
self.target = getattr(self.target[data.strip], "preamp") self.target = getattr(self.target[data.strip], 'preamp')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[ [
("highpasson", True), ('highpasson', True),
("highpasson", False), ('highpasson', False),
("usbinput", True), ('usbinput', True),
("usbinput", False), ('usbinput', False),
], ],
) )
def test_it_sets_and_gets_strip_bool_params(self, param, value): def test_it_sets_and_gets_strip_bool_params(self, param, value):
@ -164,16 +164,16 @@ class TestSetAndGetStripPreampHigher:
assert getattr(self.target, param) == value assert getattr(self.target, param) == value
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("highpassfilter", 20), ("highpassfilter", 399)], [('highpassfilter', 20), ('highpassfilter', 399)],
) )
def test_it_sets_and_gets_strip_int_params(self, param, value): def test_it_sets_and_gets_strip_int_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
assert getattr(self.target, param) == value assert getattr(self.target, param) == value
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("usbtrim", -16.5), ("usbtrim", 5.5)], [('usbtrim', -16.5), ('usbtrim', 5.5)],
) )
def test_it_sets_and_gets_strip_float_params(self, param, value): def test_it_sets_and_gets_strip_float_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -186,12 +186,12 @@ class TestSetAndGetStripConfigHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "strip") self.target = getattr(tests, 'strip')
self.target = getattr(self.target[data.strip], "config") self.target = getattr(self.target[data.strip], 'config')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("inputsource", 0), ("inputsource", 18), ("usbreturn", 3), ("usbreturn", 12)], [('inputsource', 0), ('inputsource', 18), ('usbreturn', 3), ('usbreturn', 12)],
) )
def test_it_sets_and_gets_strip_int_params(self, param, value): def test_it_sets_and_gets_strip_int_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -204,18 +204,18 @@ class TestSetAndGetStripGateHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "strip") self.target = getattr(tests, 'strip')
self.target = getattr(self.target[data.strip], "gate") self.target = getattr(self.target[data.strip], 'gate')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[ [
("on", True), ('on', True),
("on", False), ('on', False),
("invert", True), ('invert', True),
("invert", False), ('invert', False),
("filteron", True), ('filteron', True),
("filteron", False), ('filteron', False),
], ],
) )
def test_it_sets_and_gets_strip_bool_params(self, param, value): def test_it_sets_and_gets_strip_bool_params(self, param, value):
@ -223,16 +223,16 @@ class TestSetAndGetStripGateHigher:
assert getattr(self.target, param) == value assert getattr(self.target, param) == value
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[ [
("range", 11), ('range', 11),
("range", 48), ('range', 48),
("attack", 5), ('attack', 5),
("attack", 110), ('attack', 110),
("release", 360), ('release', 360),
("release", 2505), ('release', 2505),
("filtertype", 0), ('filtertype', 0),
("filtertype", 8), ('filtertype', 8),
], ],
) )
def test_it_sets_and_gets_strip_int_params(self, param, value): def test_it_sets_and_gets_strip_int_params(self, param, value):
@ -240,22 +240,22 @@ class TestSetAndGetStripGateHigher:
assert getattr(self.target, param) == value assert getattr(self.target, param) == value
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("mode", "exp2"), ("mode", "duck")], [('mode', 'exp2'), ('mode', 'duck')],
) )
def test_it_sets_and_gets_strip_string_params(self, param, value): def test_it_sets_and_gets_strip_string_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
assert getattr(self.target, param) == value assert getattr(self.target, param) == value
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[ [
("threshold", -80.0), ('threshold', -80.0),
("threshold", 0.0), ('threshold', 0.0),
("hold", 355), ('hold', 355),
("hold", 63.2), ('hold', 63.2),
("filterfreq", 37.2), ('filterfreq', 37.2),
("filterfreq", 12765), ('filterfreq', 12765),
], ],
) )
def test_it_sets_and_gets_strip_float_params(self, param, value): def test_it_sets_and_gets_strip_float_params(self, param, value):
@ -269,20 +269,20 @@ class TestSetAndGetStripAutomixHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "strip") self.target = getattr(tests, 'strip')
self.target = getattr(self.target[data.strip], "automix") self.target = getattr(self.target[data.strip], 'automix')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("group", 0), ("group", 2)], [('group', 0), ('group', 2)],
) )
def test_it_sets_and_gets_strip_int_params(self, param, value): def test_it_sets_and_gets_strip_int_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
assert getattr(self.target, param) == value assert getattr(self.target, param) == value
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("weight", -10.5), ("weight", 3.5)], [('weight', -10.5), ('weight', 3.5)],
) )
def test_it_sets_and_gets_strip_float_params(self, param, value): def test_it_sets_and_gets_strip_float_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -298,12 +298,12 @@ class TestSetAndGetBusConfigHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "bus") self.target = getattr(tests, 'bus')
self.target = getattr(self.target[data.bus], "config") self.target = getattr(self.target[data.bus], 'config')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("color", 0), ("color", 15)], [('color', 0), ('color', 15)],
) )
def test_it_sets_and_gets_bus_bool_params(self, param, value): def test_it_sets_and_gets_bus_bool_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -316,26 +316,26 @@ class TestSetAndGetBusDynHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "bus") self.target = getattr(tests, 'bus')
self.target = getattr(self.target[data.bus], "dyn") self.target = getattr(self.target[data.bus], 'dyn')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("on", True), ("on", False)], [('on', True), ('on', False)],
) )
def test_it_sets_and_gets_bus_bool_params(self, param, value): def test_it_sets_and_gets_bus_bool_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
assert getattr(self.target, param) == value assert getattr(self.target, param) == value
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[ [
("mode", "comp"), ('mode', 'comp'),
("mode", "exp"), ('mode', 'exp'),
("env", "lin"), ('env', 'lin'),
("env", "log"), ('env', 'log'),
("det", "peak"), ('det', 'peak'),
("det", "rms"), ('det', 'rms'),
], ],
) )
def test_it_sets_and_gets_bus_string_params(self, param, value): def test_it_sets_and_gets_bus_string_params(self, param, value):
@ -349,20 +349,20 @@ class TestSetAndGetBusEQHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "bus") self.target = getattr(tests, 'bus')
self.target = getattr(self.target[data.bus], "eq") self.target = getattr(self.target[data.bus], 'eq')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("on", True), ("on", False)], [('on', True), ('on', False)],
) )
def test_it_sets_and_gets_bus_bool_params(self, param, value): def test_it_sets_and_gets_bus_bool_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
assert getattr(self.target, param) == value assert getattr(self.target, param) == value
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("mode", "peq"), ("mode", "geq"), ("mode", "teq")], [('mode', 'peq'), ('mode', 'geq'), ('mode', 'teq')],
) )
def test_it_sets_and_gets_bus_string_params(self, param, value): def test_it_sets_and_gets_bus_string_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)
@ -378,12 +378,12 @@ class TestSetAndGetFXSendGroupHigher:
__test__ = True __test__ = True
def setup_class(self): def setup_class(self):
self.target = getattr(tests, "fxsend") self.target = getattr(tests, 'fxsend')
self.target = getattr(self.target[data.fx], "group") self.target = getattr(self.target[data.fx], 'group')
@pytest.mark.parametrize( @pytest.mark.parametrize(
"param,value", 'param,value',
[("dca", 0), ("dca", 12), ("mute", 3), ("mute", 8)], [('dca', 0), ('dca', 12), ('mute', 3), ('mute', 8)],
) )
def test_it_sets_and_gets_fxsend_int_params(self, param, value): def test_it_sets_and_gets_fxsend_int_params(self, param, value):
setattr(self.target, param, value) setattr(self.target, param, value)

View File

@ -1,3 +1,3 @@
from .xair import request_remote_obj as connect from .xair import request_remote_obj as connect
_ALL__ = ["connect"] _ALL__ = ['connect']

View File

@ -8,40 +8,40 @@ from .rtn import FxRtn as IFxRtn
class Bus(IBus): class Bus(IBus):
@property @property
def address(self): def address(self):
return f"/bus/{str(self.index).zfill(2)}" return f'/bus/{str(self.index).zfill(2)}'
class AuxRtn(IAuxRtn): class AuxRtn(IAuxRtn):
@property @property
def address(self): def address(self):
return f"/auxin/{str(self.index).zfill(2)}" return f'/auxin/{str(self.index).zfill(2)}'
class FxRtn(IFxRtn): class FxRtn(IFxRtn):
@property @property
def address(self): def address(self):
return f"/fxrtn/{str(self.index).zfill(2)}" return f'/fxrtn/{str(self.index).zfill(2)}'
class MainStereo(ILR): class MainStereo(ILR):
@property @property
def address(self) -> str: def address(self) -> str:
return "/main/st" return '/main/st'
class MainMono(ILR): class MainMono(ILR):
@property @property
def address(self) -> str: def address(self) -> str:
return "/main/m" return '/main/m'
class Matrix(ILR): class Matrix(ILR):
@property @property
def address(self) -> str: def address(self) -> str:
return f"/mtx/{str(self.index).zfill(2)}" return f'/mtx/{str(self.index).zfill(2)}'
class HeadAmp(IHeadAmp): class HeadAmp(IHeadAmp):
@property @property
def address(self): def address(self):
return f"/headamp/{str(self.index).zfill(3)}" return f'/headamp/{str(self.index).zfill(3)}'

View File

@ -16,10 +16,10 @@ class IBus(abc.ABC):
self.logger = logger.getChild(self.__class__.__name__) self.logger = logger.getChild(self.__class__.__name__)
def getter(self, param: str): def getter(self, param: str):
return self._remote.query(f"{self.address}/{param}") return self._remote.query(f'{self.address}/{param}')
def setter(self, param: str, val: int): def setter(self, param: str, val: int):
self._remote.send(f"{self.address}/{param}", val) self._remote.send(f'{self.address}/{param}', val)
@abc.abstractmethod @abc.abstractmethod
def address(self): def address(self):
@ -39,12 +39,12 @@ class Bus(IBus):
Returns a Bus class of a kind. Returns a Bus class of a kind.
""" """
BUS_cls = type( BUS_cls = type(
f"Bus{remote.kind}", f'Bus{remote.kind}',
(cls,), (cls,),
{ {
**{ **{
_cls.__name__.lower(): type( _cls.__name__.lower(): type(
f"{_cls.__name__}{remote.kind}", (_cls, cls), {} f'{_cls.__name__}{remote.kind}', (_cls, cls), {}
)(remote, index) )(remote, index)
for _cls in ( for _cls in (
Config, Config,
@ -56,11 +56,11 @@ class Bus(IBus):
Group, Group,
) )
}, },
"mute": mute_prop(), 'mute': mute_prop(),
}, },
) )
return BUS_cls(remote, index) return BUS_cls(remote, index)
@property @property
def address(self) -> str: def address(self) -> str:
return f"/bus/{self.index}" return f'/bus/{self.index}'

View File

@ -15,10 +15,10 @@ class IConfig(abc.ABC):
self.logger = logger.getChild(self.__class__.__name__) self.logger = logger.getChild(self.__class__.__name__)
def getter(self, param: str): def getter(self, param: str):
return self._remote.query(f"{self.address}/{param}") return self._remote.query(f'{self.address}/{param}')
def setter(self, param: str, val: int): def setter(self, param: str, val: int):
self._remote.send(f"{self.address}/{param}", val) self._remote.send(f'{self.address}/{param}', val)
@abc.abstractmethod @abc.abstractmethod
def address(self): def address(self):
@ -36,37 +36,37 @@ class Config(IConfig):
Returns a Config class of a kind. Returns a Config class of a kind.
""" """
LINKS_cls = _make_links_mixins[remote.kind.id_] LINKS_cls = _make_links_mixins[remote.kind.id_]
MUTEGROUP_cls = type("MuteGroup", (Config.MuteGroup, cls), {}) MUTEGROUP_cls = type('MuteGroup', (Config.MuteGroup, cls), {})
MONITOR_cls = type("ConfigMonitor", (Config.Monitor, cls), {}) MONITOR_cls = type('ConfigMonitor', (Config.Monitor, cls), {})
CONFIG_cls = type( CONFIG_cls = type(
f"Config{remote.kind}", f'Config{remote.kind}',
(cls, LINKS_cls), (cls, LINKS_cls),
{ {
"mute_group": tuple(MUTEGROUP_cls(remote, i) for i in range(4)), 'mute_group': tuple(MUTEGROUP_cls(remote, i) for i in range(4)),
"monitor": MONITOR_cls(remote), 'monitor': MONITOR_cls(remote),
}, },
) )
return CONFIG_cls(remote) return CONFIG_cls(remote)
@property @property
def address(self) -> str: def address(self) -> str:
return "/config" return '/config'
@property @property
def amixenable(self) -> bool: def amixenable(self) -> bool:
return self.getter("mute")[0] == 1 return self.getter('mute')[0] == 1
@amixenable.setter @amixenable.setter
def amixenable(self, val: bool): def amixenable(self, val: bool):
self.setter("amixenable", 1 if val else 0) self.setter('amixenable', 1 if val else 0)
@property @property
def amixlock(self) -> bool: def amixlock(self) -> bool:
return self.getter("amixlock")[0] == 1 return self.getter('amixlock')[0] == 1
@amixlock.setter @amixlock.setter
def amixlock(self, val: bool): def amixlock(self, val: bool):
self.setter("amixlock", 1 if val else 0) self.setter('amixlock', 1 if val else 0)
class MuteGroup: class MuteGroup:
def __init__(self, remote, i): def __init__(self, remote, i):
@ -76,128 +76,128 @@ class Config(IConfig):
@property @property
def address(self) -> str: def address(self) -> str:
root = super(Config.MuteGroup, self).address root = super(Config.MuteGroup, self).address
return f"{root}/mute" return f'{root}/mute'
@property @property
def on(self) -> bool: def on(self) -> bool:
return self.getter(f"{self.i}")[0] == 1 return self.getter(f'{self.i}')[0] == 1
@on.setter @on.setter
def on(self, val: bool): def on(self, val: bool):
self.setter(f"{self.i}", 1 if val else 0) self.setter(f'{self.i}', 1 if val else 0)
class Monitor: class Monitor:
@property @property
def address(self) -> str: def address(self) -> str:
root = super(Config.Monitor, self).address root = super(Config.Monitor, self).address
return f"{root}/solo" return f'{root}/solo'
@property @property
@util.db_from @util.db_from
def level(self) -> float: def level(self) -> float:
return self.getter("level")[0] return self.getter('level')[0]
@level.setter @level.setter
@util.db_to @util.db_to
def level(self, val: float): def level(self, val: float):
self.setter("level", val) self.setter('level', val)
@property @property
def source(self) -> int: def source(self) -> int:
return int(self.getter("source")[0]) return int(self.getter('source')[0])
@source.setter @source.setter
def source(self, val: int): def source(self, val: int):
self.setter("source", val) self.setter('source', val)
@property @property
def sourcetrim(self) -> float: def sourcetrim(self) -> float:
return round(util.lin_get(-18, 18, self.getter("sourcetrim")[0]), 1) return round(util.lin_get(-18, 18, self.getter('sourcetrim')[0]), 1)
@sourcetrim.setter @sourcetrim.setter
def sourcetrim(self, val: float): def sourcetrim(self, val: float):
if not -18 <= val <= 18: if not -18 <= val <= 18:
self.logger.warning( self.logger.warning(
f"sourcetrim got {val}, expected value in range -18.0 to 18.0" f'sourcetrim got {val}, expected value in range -18.0 to 18.0'
) )
self.setter("sourcetrim", util.lin_set(-18, 18, val)) self.setter('sourcetrim', util.lin_set(-18, 18, val))
@property @property
def chmode(self) -> bool: def chmode(self) -> bool:
return self.getter("chmode")[0] == 1 return self.getter('chmode')[0] == 1
@chmode.setter @chmode.setter
def chmode(self, val: bool): def chmode(self, val: bool):
self.setter("chmode", 1 if val else 0) self.setter('chmode', 1 if val else 0)
@property @property
def busmode(self) -> bool: def busmode(self) -> bool:
return self.getter("busmode")[0] == 1 return self.getter('busmode')[0] == 1
@busmode.setter @busmode.setter
def busmode(self, val: bool): def busmode(self, val: bool):
self.setter("busmode", 1 if val else 0) self.setter('busmode', 1 if val else 0)
@property @property
def dimgain(self) -> int: def dimgain(self) -> int:
return int(util.lin_get(-40, 0, self.getter("dimatt")[0])) return int(util.lin_get(-40, 0, self.getter('dimatt')[0]))
@dimgain.setter @dimgain.setter
def dimgain(self, val: int): def dimgain(self, val: int):
if not -40 <= val <= 0: if not -40 <= val <= 0:
self.logger.warning( self.logger.warning(
f"dimgain got {val}, expected value in range -40 to 0" f'dimgain got {val}, expected value in range -40 to 0'
) )
self.setter("dimatt", util.lin_set(-40, 0, val)) self.setter('dimatt', util.lin_set(-40, 0, val))
@property @property
def dim(self) -> bool: def dim(self) -> bool:
return self.getter("dim")[0] == 1 return self.getter('dim')[0] == 1
@dim.setter @dim.setter
def dim(self, val: bool): def dim(self, val: bool):
self.setter("dim", 1 if val else 0) self.setter('dim', 1 if val else 0)
@property @property
def mono(self) -> bool: def mono(self) -> bool:
return self.getter("mono")[0] == 1 return self.getter('mono')[0] == 1
@mono.setter @mono.setter
def mono(self, val: bool): def mono(self, val: bool):
self.setter("mono", 1 if val else 0) self.setter('mono', 1 if val else 0)
@property @property
def mute(self) -> bool: def mute(self) -> bool:
return self.getter("mute")[0] == 1 return self.getter('mute')[0] == 1
@mute.setter @mute.setter
def mute(self, val: bool): def mute(self, val: bool):
self.setter("mute", 1 if val else 0) self.setter('mute', 1 if val else 0)
@property @property
def dimfpl(self) -> bool: def dimfpl(self) -> bool:
return self.getter("dimfpl")[0] == 1 return self.getter('dimfpl')[0] == 1
@dimfpl.setter @dimfpl.setter
def dimfpl(self, val: bool): def dimfpl(self, val: bool):
self.setter("dimfpl", 1 if val else 0) self.setter('dimfpl', 1 if val else 0)
def _make_links_mixin(kind): def _make_links_mixin(kind):
"""Creates a links mixin""" """Creates a links mixin"""
return type( return type(
f"Links{kind}", f'Links{kind}',
(), (),
{ {
"link_eq": bool_prop("linkcfg/eq"), 'link_eq': bool_prop('linkcfg/eq'),
"link_dyn": bool_prop("linkcfg/dyn"), 'link_dyn': bool_prop('linkcfg/dyn'),
"link_fader_mute": bool_prop("linkcfg/fdrmute"), 'link_fader_mute': bool_prop('linkcfg/fdrmute'),
**{ **{
f"chlink{i}_{i+1}": bool_prop(f"chlink/{i}-{i+1}") f'chlink{i}_{i+1}': bool_prop(f'chlink/{i}-{i+1}')
for i in range(1, kind.num_strip, 2) for i in range(1, kind.num_strip, 2)
}, },
**{ **{
f"buslink{i}_{i+1}": bool_prop(f"buslink/{i}-{i+1}") f'buslink{i}_{i+1}': bool_prop(f'buslink/{i}-{i+1}')
for i in range(1, kind.num_bus, 2) for i in range(1, kind.num_bus, 2)
}, },
}, },

View File

@ -13,10 +13,10 @@ class IDCA(abc.ABC):
self.logger = logger.getChild(self.__class__.__name__) self.logger = logger.getChild(self.__class__.__name__)
def getter(self, param: str) -> tuple: def getter(self, param: str) -> tuple:
return self._remote.query(f"{self.address}/{param}") return self._remote.query(f'{self.address}/{param}')
def setter(self, param: str, val: int): def setter(self, param: str, val: int):
self._remote.send(f"{self.address}/{param}", val) self._remote.send(f'{self.address}/{param}', val)
@abc.abstractmethod @abc.abstractmethod
def address(self): def address(self):
@ -28,15 +28,15 @@ class DCA(IDCA):
@property @property
def address(self) -> str: def address(self) -> str:
return f"/dca/{self.index}" return f'/dca/{self.index}'
@property @property
def on(self) -> bool: def on(self) -> bool:
return self.getter("on")[0] == 1 return self.getter('on')[0] == 1
@on.setter @on.setter
def on(self, val: bool): def on(self, val: bool):
self.setter("on", 1 if val else 0) self.setter('on', 1 if val else 0)
@property @property
def mute(self) -> bool: def mute(self) -> bool:
@ -48,16 +48,16 @@ class DCA(IDCA):
@property @property
def name(self) -> str: def name(self) -> str:
return self.getter("config/name")[0] return self.getter('config/name')[0]
@name.setter @name.setter
def name(self, val: str): def name(self, val: str):
self.setter("config/name", val) self.setter('config/name', val)
@property @property
def color(self) -> int: def color(self) -> int:
return self.getter("config/color")[0] return self.getter('config/color')[0]
@color.setter @color.setter
def color(self, val: int): def color(self, val: int):
self.setter("config/color", val) self.setter('config/color', val)

View File

@ -10,5 +10,5 @@ class XAirRemoteConnectionTimeoutError(XAirRemoteError):
self.port = port self.port = port
super().__init__( super().__init__(
f"Timeout attempting to connect to mixer at {self.ip}:{self.port}" f'Timeout attempting to connect to mixer at {self.ip}:{self.port}'
) )

View File

@ -16,10 +16,10 @@ class IFX(abc.ABC):
self.logger = logger.getChild(self.__class__.__name__) self.logger = logger.getChild(self.__class__.__name__)
def getter(self, param: str): def getter(self, param: str):
return self._remote.query(f"{self.address}/{param}") return self._remote.query(f'{self.address}/{param}')
def setter(self, param: str, val: int): def setter(self, param: str, val: int):
self._remote.send(f"{self.address}/{param}", val) self._remote.send(f'{self.address}/{param}', val)
@abc.abstractmethod @abc.abstractmethod
def address(self): def address(self):
@ -31,15 +31,15 @@ class FX(IFX):
@property @property
def address(self) -> str: def address(self) -> str:
return f"/fx/{self.index}" return f'/fx/{self.index}'
@property @property
def type(self) -> int: def type(self) -> int:
return self.getter("type")[0] return self.getter('type')[0]
@type.setter @type.setter
def type(self, val: int): def type(self, val: int):
self.setter("type", val) self.setter('type', val)
class FXSend(IFX): class FXSend(IFX):
@ -55,20 +55,20 @@ class FXSend(IFX):
Returns an FXSend class of a kind. Returns an FXSend class of a kind.
""" """
FXSEND_cls = type( FXSEND_cls = type(
f"FXSend{remote.kind}", f'FXSend{remote.kind}',
(cls,), (cls,),
{ {
**{ **{
_cls.__name__.lower(): type( _cls.__name__.lower(): type(
f"{_cls.__name__}{remote.kind}", (_cls, cls), {} f'{_cls.__name__}{remote.kind}', (_cls, cls), {}
)(remote, index) )(remote, index)
for _cls in (Config, Mix, Group) for _cls in (Config, Mix, Group)
}, },
"mute": mute_prop(), 'mute': mute_prop(),
}, },
) )
return FXSEND_cls(remote, index) return FXSEND_cls(remote, index)
@property @property
def address(self) -> str: def address(self) -> str:
return f"/fxsend/{self.index}" return f'/fxsend/{self.index}'

View File

@ -15,10 +15,10 @@ class IHeadAmp(abc.ABC):
self.logger = logger.getChild(self.__class__.__name__) self.logger = logger.getChild(self.__class__.__name__)
def getter(self, param: str): def getter(self, param: str):
return self._remote.query(f"{self.address}/{param}") return self._remote.query(f'{self.address}/{param}')
def setter(self, param: str, val: int): def setter(self, param: str, val: int):
self._remote.send(f"{self.address}/{param}", val) self._remote.send(f'{self.address}/{param}', val)
@abc.abstractmethod @abc.abstractmethod
def address(self): def address(self):
@ -30,20 +30,20 @@ class HeadAmp(IHeadAmp):
@property @property
def address(self): def address(self):
return f"/headamp/{str(self.index).zfill(2)}" return f'/headamp/{str(self.index).zfill(2)}'
@property @property
def gain(self): def gain(self):
return round(util.lin_get(-12, 60, self.getter("gain")[0]), 1) return round(util.lin_get(-12, 60, self.getter('gain')[0]), 1)
@gain.setter @gain.setter
def gain(self, val): def gain(self, val):
self.setter("gain", util.lin_set(-12, 60, val)) self.setter('gain', util.lin_set(-12, 60, val))
@property @property
def phantom(self): def phantom(self):
return self.getter("phantom")[0] == 1 return self.getter('phantom')[0] == 1
@phantom.setter @phantom.setter
def phantom(self, val): def phantom(self, val):
self.setter("phantom", 1 if val else 0) self.setter('phantom', 1 if val else 0)

View File

@ -1,15 +1,16 @@
from dataclasses import dataclass from dataclasses import dataclass
@dataclass @dataclass(frozen=True)
class KindMap: class KindMap:
id_: str
def __str__(self) -> str: def __str__(self) -> str:
return self.id_ return self.id_
@dataclass @dataclass(frozen=True)
class X32KindMap(KindMap): class X32KindMap(KindMap):
id_: str
num_dca: int = 8 num_dca: int = 8
num_strip: int = 32 num_strip: int = 32
num_bus: int = 16 num_bus: int = 16
@ -19,28 +20,25 @@ class X32KindMap(KindMap):
num_headamp: int = 127 num_headamp: int = 127
@dataclass @dataclass(frozen=True)
class XR18KindMap(KindMap): class XR18KindMap(KindMap):
# note ch 17-18 defined as aux return # note ch 17-18 defined as aux return
id_: str
num_dca: int = 4 num_dca: int = 4
num_strip: int = 16 num_strip: int = 16
num_bus: int = 6 num_bus: int = 6
num_fx: int = 4 num_fx: int = 4
@dataclass @dataclass(frozen=True)
class XR16KindMap(KindMap): class XR16KindMap(KindMap):
id_: str
num_dca: int = 4 num_dca: int = 4
num_strip: int = 16 num_strip: int = 16
num_bus: int = 4 num_bus: int = 4
num_fx: int = 4 num_fx: int = 4
@dataclass @dataclass(frozen=True)
class XR12KindMap(KindMap): class XR12KindMap(KindMap):
id_: str
num_dca: int = 4 num_dca: int = 4
num_strip: int = 12 num_strip: int = 12
num_bus: int = 2 num_bus: int = 2
@ -48,11 +46,11 @@ class XR12KindMap(KindMap):
_kinds = { _kinds = {
"X32": X32KindMap(id_="X32"), 'X32': X32KindMap(id_='X32'),
"MR18": XR18KindMap(id_="MR18"), 'MR18': XR18KindMap(id_='MR18'),
"XR18": XR18KindMap(id_="XR18"), 'XR18': XR18KindMap(id_='XR18'),
"XR16": XR16KindMap(id_="XR16"), 'XR16': XR16KindMap(id_='XR16'),
"XR12": XR12KindMap(id_="XR12"), 'XR12': XR12KindMap(id_='XR12'),
} }
@ -60,4 +58,4 @@ def get(kind_id):
return _kinds[kind_id] return _kinds[kind_id]
all = list(kind for kind in _kinds.values()) all = list(_kinds.values())

View File

@ -18,10 +18,10 @@ class ILR(abc.ABC):
self.logger = logger.getChild(self.__class__.__name__) self.logger = logger.getChild(self.__class__.__name__)
def getter(self, param: str): def getter(self, param: str):
return self._remote.query(f"{self.address}/{param}") return self._remote.query(f'{self.address}/{param}')
def setter(self, param: str, val: int): def setter(self, param: str, val: int):
self._remote.send(f"{self.address}/{param}", val) self._remote.send(f'{self.address}/{param}', val)
@abc.abstractmethod @abc.abstractmethod
def address(self): def address(self):
@ -41,12 +41,12 @@ class LR(ILR):
Returns an LR class of a kind. Returns an LR class of a kind.
""" """
LR_cls = type( LR_cls = type(
f"LR{remote.kind}", f'LR{remote.kind}',
(cls,), (cls,),
{ {
**{ **{
_cls.__name__.lower(): type( _cls.__name__.lower(): type(
f"{_cls.__name__}{remote.kind}", (_cls, cls), {} f'{_cls.__name__}{remote.kind}', (_cls, cls), {}
)(remote, index) )(remote, index)
for _cls in ( for _cls in (
Config, Config,
@ -57,11 +57,11 @@ class LR(ILR):
Mix, Mix,
) )
}, },
"mute": mute_prop(), 'mute': mute_prop(),
}, },
) )
return LR_cls(remote, index) return LR_cls(remote, index)
@property @property
def address(self) -> str: def address(self) -> str:
return "/lr" return '/lr'

View File

@ -50,7 +50,7 @@ def float_prop(param):
def geq_prop(param): def geq_prop(param):
param = param.replace("_", ".") param = param.replace('_', '.')
def fget(self) -> float: def fget(self) -> float:
return round(lin_get(-15, 15, self.getter(param)[0]), 1) return round(lin_get(-15, 15, self.getter(param)[0]), 1)
@ -58,7 +58,7 @@ def geq_prop(param):
def fset(self, val): def fset(self, val):
if not -15 <= val <= 15: if not -15 <= val <= 15:
self.logger.warning( self.logger.warning(
f"slider_{param} got {val}, expected value in range -15.0 to 15.0" f'slider_{param} got {val}, expected value in range -15.0 to 15.0'
) )
self.setter(param, lin_set(-15, 15, val)) self.setter(param, lin_set(-15, 15, val))

View File

@ -18,10 +18,10 @@ class IRtn(abc.ABC):
self.logger = logger.getChild(self.__class__.__name__) self.logger = logger.getChild(self.__class__.__name__)
def getter(self, param: str): def getter(self, param: str):
return self._remote.query(f"{self.address}/{param}") return self._remote.query(f'{self.address}/{param}')
def setter(self, param: str, val: int): def setter(self, param: str, val: int):
self._remote.send(f"{self.address}/{param}", val) self._remote.send(f'{self.address}/{param}', val)
@abc.abstractmethod @abc.abstractmethod
def address(self): def address(self):
@ -41,12 +41,12 @@ class AuxRtn(IRtn):
Returns an AuxRtn class of a kind. Returns an AuxRtn class of a kind.
""" """
AUXRTN_cls = type( AUXRTN_cls = type(
f"AuxRtn{remote.kind}", f'AuxRtn{remote.kind}',
(cls,), (cls,),
{ {
**{ **{
_cls.__name__.lower(): type( _cls.__name__.lower(): type(
f"{_cls.__name__}{remote.kind}", (_cls, cls), {} f'{_cls.__name__}{remote.kind}', (_cls, cls), {}
)(remote, index) )(remote, index)
for _cls in ( for _cls in (
Config, Config,
@ -56,18 +56,18 @@ class AuxRtn(IRtn):
Group, Group,
) )
}, },
"send": tuple( 'send': tuple(
Send.make(cls, i, remote) Send.make(cls, i, remote)
for i in range(remote.kind.num_bus + remote.kind.num_fx) for i in range(remote.kind.num_bus + remote.kind.num_fx)
), ),
"mute": mute_prop(), 'mute': mute_prop(),
}, },
) )
return AUXRTN_cls(remote, index) return AUXRTN_cls(remote, index)
@property @property
def address(self): def address(self):
return "/rtn/aux" return '/rtn/aux'
class FxRtn(IRtn): class FxRtn(IRtn):
@ -83,12 +83,12 @@ class FxRtn(IRtn):
Returns an FxRtn class of a kind. Returns an FxRtn class of a kind.
""" """
FXRTN_cls = type( FXRTN_cls = type(
f"FxRtn{remote.kind}", f'FxRtn{remote.kind}',
(cls,), (cls,),
{ {
**{ **{
_cls.__name__.lower(): type( _cls.__name__.lower(): type(
f"{_cls.__name__}{remote.kind}", (_cls, cls), {} f'{_cls.__name__}{remote.kind}', (_cls, cls), {}
)(remote, index) )(remote, index)
for _cls in ( for _cls in (
Config, Config,
@ -98,15 +98,15 @@ class FxRtn(IRtn):
Group, Group,
) )
}, },
"send": tuple( 'send': tuple(
Send.make(cls, i, remote, index) Send.make(cls, i, remote, index)
for i in range(remote.kind.num_bus + remote.kind.num_fx) for i in range(remote.kind.num_bus + remote.kind.num_fx)
), ),
"mute": mute_prop(), 'mute': mute_prop(),
}, },
) )
return FXRTN_cls(remote, index) return FXRTN_cls(remote, index)
@property @property
def address(self): def address(self):
return f"/rtn/{self.index}" return f'/rtn/{self.index}'

View File

@ -12,473 +12,473 @@ class Config:
@property @property
def address(self) -> str: def address(self) -> str:
root = super(Config, self).address root = super(Config, self).address
return f"{root}/config" return f'{root}/config'
@property @property
def name(self) -> str: def name(self) -> str:
return self.getter("name")[0] return self.getter('name')[0]
@name.setter @name.setter
def name(self, val: str): def name(self, val: str):
self.setter("name", val) self.setter('name', val)
@property @property
def color(self) -> int: def color(self) -> int:
return self.getter("color")[0] return self.getter('color')[0]
@color.setter @color.setter
def color(self, val: int): def color(self, val: int):
self.setter("color", val) self.setter('color', val)
@property @property
def inputsource(self) -> int: def inputsource(self) -> int:
return self.getter("insrc")[0] return self.getter('insrc')[0]
@inputsource.setter @inputsource.setter
def inputsource(self, val: int): def inputsource(self, val: int):
self.setter("insrc", val) self.setter('insrc', val)
@property @property
def usbreturn(self) -> int: def usbreturn(self) -> int:
return self.getter("rtnsrc")[0] return self.getter('rtnsrc')[0]
@usbreturn.setter @usbreturn.setter
def usbreturn(self, val: int): def usbreturn(self, val: int):
self.setter("rtnsrc", val) self.setter('rtnsrc', val)
class Preamp: class Preamp:
@property @property
def address(self) -> str: def address(self) -> str:
root = super(Preamp, self).address root = super(Preamp, self).address
return f"{root}/preamp" return f'{root}/preamp'
@property @property
def usbtrim(self) -> float: def usbtrim(self) -> float:
return round(util.lin_get(-18, 18, self.getter("rtntrim")[0]), 1) return round(util.lin_get(-18, 18, self.getter('rtntrim')[0]), 1)
@usbtrim.setter @usbtrim.setter
def usbtrim(self, val: float): def usbtrim(self, val: float):
if not -18 <= val <= 18: if not -18 <= val <= 18:
self.logger.warning( self.logger.warning(
f"usbtrim got {val}, expected value in range -18.0 to 18.0" f'usbtrim got {val}, expected value in range -18.0 to 18.0'
) )
self.setter("rtntrim", util.lin_set(-18, 18, val)) self.setter('rtntrim', util.lin_set(-18, 18, val))
@property @property
def usbinput(self) -> bool: def usbinput(self) -> bool:
return self.getter("rtnsw")[0] == 1 return self.getter('rtnsw')[0] == 1
@usbinput.setter @usbinput.setter
def usbinput(self, val: bool): def usbinput(self, val: bool):
self.setter("rtnsw", 1 if val else 0) self.setter('rtnsw', 1 if val else 0)
@property @property
def invert(self) -> bool: def invert(self) -> bool:
return self.getter("invert")[0] == 1 return self.getter('invert')[0] == 1
@invert.setter @invert.setter
def invert(self, val: bool): def invert(self, val: bool):
self.setter("invert", 1 if val else 0) self.setter('invert', 1 if val else 0)
@property @property
def highpasson(self) -> bool: def highpasson(self) -> bool:
return self.getter("hpon")[0] == 1 return self.getter('hpon')[0] == 1
@highpasson.setter @highpasson.setter
def highpasson(self, val: bool): def highpasson(self, val: bool):
self.setter("hpon", 1 if val else 0) self.setter('hpon', 1 if val else 0)
@property @property
def highpassfilter(self) -> int: def highpassfilter(self) -> int:
return int(util.log_get(20, 400, self.getter("hpf")[0])) return int(util.log_get(20, 400, self.getter('hpf')[0]))
@highpassfilter.setter @highpassfilter.setter
def highpassfilter(self, val: int): def highpassfilter(self, val: int):
if not 20 <= val <= 400: if not 20 <= val <= 400:
self.logger.warning( self.logger.warning(
f"highpassfilter got {val}, expected value in range 20 to 400" f'highpassfilter got {val}, expected value in range 20 to 400'
) )
self.setter("hpf", util.log_set(20, 400, val)) self.setter('hpf', util.log_set(20, 400, val))
class Gate: class Gate:
@property @property
def address(self) -> str: def address(self) -> str:
root = super(Gate, self).address root = super(Gate, self).address
return f"{root}/gate" return f'{root}/gate'
@property @property
def on(self) -> bool: def on(self) -> bool:
return self.getter("on")[0] == 1 return self.getter('on')[0] == 1
@on.setter @on.setter
def on(self, val: bool): def on(self, val: bool):
self.setter("on", 1 if val else 0) self.setter('on', 1 if val else 0)
@property @property
def mode(self) -> str: def mode(self) -> str:
opts = ("gate", "exp2", "exp3", "exp4", "duck") opts = ('gate', 'exp2', 'exp3', 'exp4', 'duck')
return opts[self.getter("mode")[0]] return opts[self.getter('mode')[0]]
@mode.setter @mode.setter
def mode(self, val: str): def mode(self, val: str):
opts = ("gate", "exp2", "exp3", "exp4", "duck") opts = ('gate', 'exp2', 'exp3', 'exp4', 'duck')
if val not in opts: if val not in opts:
self.logger.warning(f"mode got {val}, expected one of {opts}") self.logger.warning(f'mode got {val}, expected one of {opts}')
self.setter("mode", opts.index(val)) self.setter('mode', opts.index(val))
@property @property
def threshold(self) -> float: def threshold(self) -> float:
return round(util.lin_get(-80, 0, self.getter("thr")[0]), 1) return round(util.lin_get(-80, 0, self.getter('thr')[0]), 1)
@threshold.setter @threshold.setter
def threshold(self, val: float): def threshold(self, val: float):
if not -80 <= val <= 0: if not -80 <= val <= 0:
self.logger.warning( self.logger.warning(
f"threshold got {val}, expected value in range -80.0 to 0.0" f'threshold got {val}, expected value in range -80.0 to 0.0'
) )
self.setter("thr", util.lin_set(-80, 0, val)) self.setter('thr', util.lin_set(-80, 0, val))
@property @property
def range(self) -> int: def range(self) -> int:
return int(util.lin_get(3, 60, self.getter("range")[0])) return int(util.lin_get(3, 60, self.getter('range')[0]))
@range.setter @range.setter
def range(self, val: int): def range(self, val: int):
if not 3 <= val <= 60: if not 3 <= val <= 60:
self.logger.warning(f"range got {val}, expected value in range 3 to 60") self.logger.warning(f'range got {val}, expected value in range 3 to 60')
self.setter("range", util.lin_set(3, 60, val)) self.setter('range', util.lin_set(3, 60, val))
@property @property
def attack(self) -> int: def attack(self) -> int:
return int(util.lin_get(0, 120, self.getter("attack")[0])) return int(util.lin_get(0, 120, self.getter('attack')[0]))
@attack.setter @attack.setter
def attack(self, val: int): def attack(self, val: int):
if not 0 <= val <= 120: if not 0 <= val <= 120:
self.logger.warning(f"attack got {val}, expected value in range 0 to 120") self.logger.warning(f'attack got {val}, expected value in range 0 to 120')
self.setter("attack", util.lin_set(0, 120, val)) self.setter('attack', util.lin_set(0, 120, val))
@property @property
def hold(self) -> Union[float, int]: def hold(self) -> Union[float, int]:
val = util.log_get(0.02, 2000, self.getter("hold")[0]) val = util.log_get(0.02, 2000, self.getter('hold')[0])
return round(val, 1) if val < 100 else int(val) return round(val, 1) if val < 100 else int(val)
@hold.setter @hold.setter
def hold(self, val: float): def hold(self, val: float):
if not 0.02 <= val <= 2000: if not 0.02 <= val <= 2000:
self.logger.warning( self.logger.warning(
f"hold got {val}, expected value in range 0.02 to 2000.0" f'hold got {val}, expected value in range 0.02 to 2000.0'
) )
self.setter("hold", util.log_set(0.02, 2000, val)) self.setter('hold', util.log_set(0.02, 2000, val))
@property @property
def release(self) -> int: def release(self) -> int:
return int(util.log_get(5, 4000, self.getter("release")[0])) return int(util.log_get(5, 4000, self.getter('release')[0]))
@release.setter @release.setter
def release(self, val: int): def release(self, val: int):
if not 5 <= val <= 4000: if not 5 <= val <= 4000:
self.logger.warning(f"release got {val}, expected value in range 5 to 4000") self.logger.warning(f'release got {val}, expected value in range 5 to 4000')
self.setter("release", util.log_set(5, 4000, val)) self.setter('release', util.log_set(5, 4000, val))
@property @property
def keysource(self): def keysource(self):
return self.getter("keysrc")[0] return self.getter('keysrc')[0]
@keysource.setter @keysource.setter
def keysource(self, val): def keysource(self, val):
self.setter("keysrc", val) self.setter('keysrc', val)
@property @property
def filteron(self): def filteron(self):
return self.getter("filter/on")[0] == 1 return self.getter('filter/on')[0] == 1
@filteron.setter @filteron.setter
def filteron(self, val: bool): def filteron(self, val: bool):
self.setter("filter/on", 1 if val else 0) self.setter('filter/on', 1 if val else 0)
@property @property
def filtertype(self) -> int: def filtertype(self) -> int:
return int(self.getter("filter/type")[0]) return int(self.getter('filter/type')[0])
@filtertype.setter @filtertype.setter
def filtertype(self, val: int): def filtertype(self, val: int):
self.setter("filter/type", val) self.setter('filter/type', val)
@property @property
def filterfreq(self) -> Union[float, int]: def filterfreq(self) -> Union[float, int]:
retval = util.log_get(20, 20000, self.getter("filter/f")[0]) retval = util.log_get(20, 20000, self.getter('filter/f')[0])
return int(retval) if retval > 1000 else round(retval, 1) return int(retval) if retval > 1000 else round(retval, 1)
@filterfreq.setter @filterfreq.setter
def filterfreq(self, val: Union[float, int]): def filterfreq(self, val: Union[float, int]):
if not 20 <= val <= 20000: if not 20 <= val <= 20000:
self.logger.warning( self.logger.warning(
f"filterfreq got {val}, expected value in range 20 to 20000" f'filterfreq got {val}, expected value in range 20 to 20000'
) )
self.setter("filter/f", util.log_set(20, 20000, val)) self.setter('filter/f', util.log_set(20, 20000, val))
class Dyn: class Dyn:
@property @property
def address(self) -> str: def address(self) -> str:
root = super(Dyn, self).address root = super(Dyn, self).address
return f"{root}/dyn" return f'{root}/dyn'
@property @property
def on(self) -> bool: def on(self) -> bool:
return self.getter("on")[0] == 1 return self.getter('on')[0] == 1
@on.setter @on.setter
def on(self, val: bool): def on(self, val: bool):
self.setter("on", 1 if val else 0) self.setter('on', 1 if val else 0)
@property @property
def mode(self) -> str: def mode(self) -> str:
opts = ("comp", "exp") opts = ('comp', 'exp')
return opts[self.getter("mode")[0]] return opts[self.getter('mode')[0]]
@mode.setter @mode.setter
def mode(self, val: str): def mode(self, val: str):
opts = ("comp", "exp") opts = ('comp', 'exp')
if val not in opts: if val not in opts:
self.logger.warning(f"mode got {val}, expected one of {opts}") self.logger.warning(f'mode got {val}, expected one of {opts}')
self.setter("mode", opts.index(val)) self.setter('mode', opts.index(val))
@property @property
def det(self) -> str: def det(self) -> str:
opts = ("peak", "rms") opts = ('peak', 'rms')
return opts[self.getter("det")[0]] return opts[self.getter('det')[0]]
@det.setter @det.setter
def det(self, val: str): def det(self, val: str):
opts = ("peak", "rms") opts = ('peak', 'rms')
if val not in opts: if val not in opts:
self.logger.warning(f"det got {val}, expected one of {opts}") self.logger.warning(f'det got {val}, expected one of {opts}')
self.setter("det", opts.index(val)) self.setter('det', opts.index(val))
@property @property
def env(self) -> str: def env(self) -> str:
opts = ("lin", "log") opts = ('lin', 'log')
return opts[self.getter("env")[0]] return opts[self.getter('env')[0]]
@env.setter @env.setter
def env(self, val: str): def env(self, val: str):
opts = ("lin", "log") opts = ('lin', 'log')
if val not in opts: if val not in opts:
self.logger.warning(f"env got {val}, expected one of {opts}") self.logger.warning(f'env got {val}, expected one of {opts}')
self.setter("env", opts.index(val)) self.setter('env', opts.index(val))
@property @property
def threshold(self) -> float: def threshold(self) -> float:
return round(util.lin_get(-60, 0, self.getter("thr")[0]), 1) return round(util.lin_get(-60, 0, self.getter('thr')[0]), 1)
@threshold.setter @threshold.setter
def threshold(self, val: float): def threshold(self, val: float):
if not -60 <= val <= 0: if not -60 <= val <= 0:
self.logger.warning( self.logger.warning(
f"threshold got {val}, expected value in range -60.0 to 0" f'threshold got {val}, expected value in range -60.0 to 0'
) )
self.setter("thr", util.lin_set(-60, 0, val)) self.setter('thr', util.lin_set(-60, 0, val))
@property @property
def ratio(self) -> Union[float, int]: def ratio(self) -> Union[float, int]:
opts = (1.1, 1.3, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 7.0, 10, 20, 100) opts = (1.1, 1.3, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 7.0, 10, 20, 100)
return opts[self.getter("ratio")[0]] return opts[self.getter('ratio')[0]]
@ratio.setter @ratio.setter
def ratio(self, val: int): def ratio(self, val: int):
self.setter("ratio", val) self.setter('ratio', val)
@property @property
def knee(self) -> int: def knee(self) -> int:
return int(util.lin_get(0, 5, self.getter("knee")[0])) return int(util.lin_get(0, 5, self.getter('knee')[0]))
@knee.setter @knee.setter
def knee(self, val: int): def knee(self, val: int):
if not 0 <= val <= 5: if not 0 <= val <= 5:
self.logger.warning(f"knee got {val}, expected value in range 0 to 5") self.logger.warning(f'knee got {val}, expected value in range 0 to 5')
self.setter("knee", util.lin_set(0, 5, val)) self.setter('knee', util.lin_set(0, 5, val))
@property @property
def mgain(self) -> float: def mgain(self) -> float:
return round(util.lin_get(0, 24, self.getter("mgain")[0]), 1) return round(util.lin_get(0, 24, self.getter('mgain')[0]), 1)
@mgain.setter @mgain.setter
def mgain(self, val: float): def mgain(self, val: float):
if not 0 <= val <= 24: if not 0 <= val <= 24:
self.logger.warning(f"mgain got {val}, expected value in range 0.0 to 24.0") self.logger.warning(f'mgain got {val}, expected value in range 0.0 to 24.0')
self.setter("mgain", util.lin_set(0, 24, val)) self.setter('mgain', util.lin_set(0, 24, val))
@property @property
def attack(self) -> int: def attack(self) -> int:
return int(util.lin_get(0, 120, self.getter("attack")[0])) return int(util.lin_get(0, 120, self.getter('attack')[0]))
@attack.setter @attack.setter
def attack(self, val: int): def attack(self, val: int):
if not 0 <= val <= 120: if not 0 <= val <= 120:
self.logger.warning(f"attack got {val}, expected value in range 0 to 120") self.logger.warning(f'attack got {val}, expected value in range 0 to 120')
self.setter("attack", util.lin_set(0, 120, val)) self.setter('attack', util.lin_set(0, 120, val))
@property @property
def hold(self) -> Union[float, int]: def hold(self) -> Union[float, int]:
val = util.log_get(0.02, 2000, self.getter("hold")[0]) val = util.log_get(0.02, 2000, self.getter('hold')[0])
return round(val, 1) if val < 100 else int(val) return round(val, 1) if val < 100 else int(val)
@hold.setter @hold.setter
def hold(self, val: float): def hold(self, val: float):
if not 0.02 <= val <= 2000: if not 0.02 <= val <= 2000:
self.logger.warning( self.logger.warning(
f"hold got {val}, expected value in range 0.02 to 2000.0" f'hold got {val}, expected value in range 0.02 to 2000.0'
) )
self.setter("hold", util.log_set(0.02, 2000, val)) self.setter('hold', util.log_set(0.02, 2000, val))
@property @property
def release(self) -> int: def release(self) -> int:
return int(util.log_get(5, 4000, self.getter("release")[0])) return int(util.log_get(5, 4000, self.getter('release')[0]))
@release.setter @release.setter
def release(self, val: int): def release(self, val: int):
if not 5 <= val <= 4000: if not 5 <= val <= 4000:
self.logger.warning(f"release got {val}, expected value in range 5 to 4000") self.logger.warning(f'release got {val}, expected value in range 5 to 4000')
self.setter("release", util.log_set(5, 4000, val)) self.setter('release', util.log_set(5, 4000, val))
@property @property
def mix(self) -> int: def mix(self) -> int:
return int(util.lin_get(0, 100, self.getter("mix")[0])) return int(util.lin_get(0, 100, self.getter('mix')[0]))
@mix.setter @mix.setter
def mix(self, val: int): def mix(self, val: int):
if not 0 <= val <= 100: if not 0 <= val <= 100:
self.logger.warning(f"mix got {val}, expected value in range 0 to 100") self.logger.warning(f'mix got {val}, expected value in range 0 to 100')
self.setter("mix", util.lin_set(0, 100, val)) self.setter('mix', util.lin_set(0, 100, val))
@property @property
def keysource(self): def keysource(self):
return self.getter("keysrc")[0] return self.getter('keysrc')[0]
@keysource.setter @keysource.setter
def keysource(self, val): def keysource(self, val):
self.setter("keysrc", val) self.setter('keysrc', val)
@property @property
def auto(self) -> bool: def auto(self) -> bool:
return self.getter("auto")[0] == 1 return self.getter('auto')[0] == 1
@auto.setter @auto.setter
def auto(self, val: bool): def auto(self, val: bool):
self.setter("auto", 1 if val else 0) self.setter('auto', 1 if val else 0)
@property @property
def filteron(self): def filteron(self):
return self.getter("filter/on")[0] == 1 return self.getter('filter/on')[0] == 1
@filteron.setter @filteron.setter
def filteron(self, val: bool): def filteron(self, val: bool):
self.setter("filter/on", 1 if val else 0) self.setter('filter/on', 1 if val else 0)
@property @property
def filtertype(self) -> int: def filtertype(self) -> int:
return int(self.getter("filter/type")[0]) return int(self.getter('filter/type')[0])
@filtertype.setter @filtertype.setter
def filtertype(self, val: int): def filtertype(self, val: int):
self.setter("filter/type", val) self.setter('filter/type', val)
@property @property
def filterfreq(self) -> Union[float, int]: def filterfreq(self) -> Union[float, int]:
retval = util.log_get(20, 20000, self.getter("filter/f")[0]) retval = util.log_get(20, 20000, self.getter('filter/f')[0])
return int(retval) if retval > 1000 else round(retval, 1) return int(retval) if retval > 1000 else round(retval, 1)
@filterfreq.setter @filterfreq.setter
def filterfreq(self, val: Union[float, int]): def filterfreq(self, val: Union[float, int]):
if not 20 <= val <= 20000: if not 20 <= val <= 20000:
self.logger.warning( self.logger.warning(
f"filterfreq got {val}, expected value in range 20 to 20000" f'filterfreq got {val}, expected value in range 20 to 20000'
) )
self.setter("filter/f", util.log_set(20, 20000, val)) self.setter('filter/f', util.log_set(20, 20000, val))
class Insert: class Insert:
@property @property
def address(self) -> str: def address(self) -> str:
root = super(Insert, self).address root = super(Insert, self).address
return f"{root}/insert" return f'{root}/insert'
@property @property
def on(self) -> bool: def on(self) -> bool:
return self.getter("on")[0] == 1 return self.getter('on')[0] == 1
@on.setter @on.setter
def on(self, val: bool): def on(self, val: bool):
self.setter("on", 1 if val else 0) self.setter('on', 1 if val else 0)
@property @property
def sel(self) -> int: def sel(self) -> int:
return self.getter("sel")[0] return self.getter('sel')[0]
@sel.setter @sel.setter
def sel(self, val: int): def sel(self, val: int):
self.setter("sel", val) self.setter('sel', val)
class EQ: class EQ:
@classmethod @classmethod
def make_fourband(cls, _cls, remote, index=None): def make_fourband(cls, _cls, remote, index=None):
EQBand_cls = type("EQBand", (EQ.EQBand, _cls), {}) EQBand_cls = type('EQBand', (EQ.EQBand, _cls), {})
return type( return type(
"EQ", 'EQ',
(cls,), (cls,),
{ {
"low": EQBand_cls(1, remote, index), 'low': EQBand_cls(1, remote, index),
"lomid": EQBand_cls(2, remote, index), 'lomid': EQBand_cls(2, remote, index),
"himid": EQBand_cls(3, remote, index), 'himid': EQBand_cls(3, remote, index),
"high": EQBand_cls(4, remote, index), 'high': EQBand_cls(4, remote, index),
}, },
) )
@classmethod @classmethod
def make_sixband(cls, _cls, remote, index=None): def make_sixband(cls, _cls, remote, index=None):
EQBand_cls = type("EQBand", (EQ.EQBand, _cls), {}) EQBand_cls = type('EQBand', (EQ.EQBand, _cls), {})
return type( return type(
"EQ", 'EQ',
(cls,), (cls,),
{ {
"low": EQBand_cls(1, remote, index), 'low': EQBand_cls(1, remote, index),
"low2": EQBand_cls(2, remote, index), 'low2': EQBand_cls(2, remote, index),
"lomid": EQBand_cls(3, remote, index), 'lomid': EQBand_cls(3, remote, index),
"himid": EQBand_cls(4, remote, index), 'himid': EQBand_cls(4, remote, index),
"high2": EQBand_cls(5, remote, index), 'high2': EQBand_cls(5, remote, index),
"high": EQBand_cls(6, remote, index), 'high': EQBand_cls(6, remote, index),
}, },
) )
@property @property
def address(self) -> str: def address(self) -> str:
root = super(EQ, self).address root = super(EQ, self).address
return f"{root}/eq" return f'{root}/eq'
@property @property
def on(self) -> bool: def on(self) -> bool:
return self.getter("on")[0] == 1 return self.getter('on')[0] == 1
@on.setter @on.setter
def on(self, val: bool): def on(self, val: bool):
self.setter("on", 1 if val else 0) self.setter('on', 1 if val else 0)
@property @property
def mode(self) -> str: def mode(self) -> str:
opts = ("peq", "geq", "teq") opts = ('peq', 'geq', 'teq')
return opts[self.getter("mode")[0]] return opts[self.getter('mode')[0]]
@mode.setter @mode.setter
def mode(self, val: str): def mode(self, val: str):
opts = ("peq", "geq", "teq") opts = ('peq', 'geq', 'teq')
if val not in opts: if val not in opts:
self.logger.warning(f"mode got {val}, expected one of {opts}") self.logger.warning(f'mode got {val}, expected one of {opts}')
self.setter("mode", opts.index(val)) self.setter('mode', opts.index(val))
class EQBand: class EQBand:
def __init__(self, i, remote, index): def __init__(self, i, remote, index):
@ -488,53 +488,53 @@ class EQ:
@property @property
def address(self) -> str: def address(self) -> str:
root = super(EQ.EQBand, self).address root = super(EQ.EQBand, self).address
return f"{root}/eq/{self.i}" return f'{root}/eq/{self.i}'
@property @property
def type(self) -> int: def type(self) -> int:
return int(self.getter("type")[0]) return int(self.getter('type')[0])
@type.setter @type.setter
def type(self, val: int): def type(self, val: int):
self.setter("type", val) self.setter('type', val)
@property @property
def frequency(self) -> float: def frequency(self) -> float:
retval = util.log_get(20, 20000, self.getter("f")[0]) retval = util.log_get(20, 20000, self.getter('f')[0])
return round(retval, 1) return round(retval, 1)
@frequency.setter @frequency.setter
def frequency(self, val: float): def frequency(self, val: float):
if not 20 <= val <= 20000: if not 20 <= val <= 20000:
self.logger.warning( self.logger.warning(
f"frequency got {val}, expected value in range 20.0 to 20000.0" f'frequency got {val}, expected value in range 20.0 to 20000.0'
) )
self.setter("f", util.log_set(20, 20000, val)) self.setter('f', util.log_set(20, 20000, val))
@property @property
def gain(self) -> float: def gain(self) -> float:
return round(util.lin_get(-15, 15, self.getter("g")[0]), 1) return round(util.lin_get(-15, 15, self.getter('g')[0]), 1)
@gain.setter @gain.setter
def gain(self, val: float): def gain(self, val: float):
if not -15 <= val <= 15: if not -15 <= val <= 15:
self.logger.warning( self.logger.warning(
f"gain got {val}, expected value in range -15.0 to 15.0" f'gain got {val}, expected value in range -15.0 to 15.0'
) )
self.setter("g", util.lin_set(-15, 15, val)) self.setter('g', util.lin_set(-15, 15, val))
@property @property
def quality(self) -> float: def quality(self) -> float:
retval = util.log_get(0.3, 10, self.getter("q")[0]) retval = util.log_get(0.3, 10, self.getter('q')[0])
return round(retval, 1) return round(retval, 1)
@quality.setter @quality.setter
def quality(self, val: float): def quality(self, val: float):
if not 0.3 <= val <= 10: if not 0.3 <= val <= 10:
self.logger.warning( self.logger.warning(
f"quality got {val}, expected value in range 0.3 to 10.0" f'quality got {val}, expected value in range 0.3 to 10.0'
) )
self.setter("q", util.log_set(0.3, 10, val)) self.setter('q', util.log_set(0.3, 10, val))
class GEQ: class GEQ:
@ -561,90 +561,90 @@ class GEQ:
@property @property
def address(self) -> str: def address(self) -> str:
root = super(GEQ, self).address root = super(GEQ, self).address
return f"{root}/geq" return f'{root}/geq'
class Mix: class Mix:
@property @property
def address(self) -> str: def address(self) -> str:
root = super(Mix, self).address root = super(Mix, self).address
return f"{root}/mix" return f'{root}/mix'
@property @property
def on(self) -> bool: def on(self) -> bool:
return self.getter("on")[0] == 1 return self.getter('on')[0] == 1
@on.setter @on.setter
def on(self, val: bool): def on(self, val: bool):
self.setter("on", 1 if val else 0) self.setter('on', 1 if val else 0)
@property @property
@util.db_from @util.db_from
def fader(self) -> float: def fader(self) -> float:
return self.getter("fader")[0] return self.getter('fader')[0]
@fader.setter @fader.setter
@util.db_to @util.db_to
def fader(self, val: float): def fader(self, val: float):
self.setter("fader", val) self.setter('fader', val)
@property @property
def lr(self) -> bool: def lr(self) -> bool:
return self.getter("lr")[0] == 1 return self.getter('lr')[0] == 1
@lr.setter @lr.setter
def lr(self, val: bool): def lr(self, val: bool):
self.setter("lr", 1 if val else 0) self.setter('lr', 1 if val else 0)
class Group: class Group:
@property @property
def address(self) -> str: def address(self) -> str:
root = super(Group, self).address root = super(Group, self).address
return f"{root}/grp" return f'{root}/grp'
@property @property
def dca(self) -> int: def dca(self) -> int:
return self.getter("dca")[0] return self.getter('dca')[0]
@dca.setter @dca.setter
def dca(self, val: int): def dca(self, val: int):
self.setter("dca", val) self.setter('dca', val)
@property @property
def mute(self) -> int: def mute(self) -> int:
return self.getter("mute")[0] return self.getter('mute')[0]
@mute.setter @mute.setter
def mute(self, val: int): def mute(self, val: int):
self.setter("mute", val) self.setter('mute', val)
class Automix: class Automix:
@property @property
def address(self) -> str: def address(self) -> str:
root = super(Automix, self).address root = super(Automix, self).address
return f"{root}/automix" return f'{root}/automix'
@property @property
def group(self) -> int: def group(self) -> int:
return self.getter("group")[0] return self.getter('group')[0]
@group.setter @group.setter
def group(self, val: int): def group(self, val: int):
self.setter("group", val) self.setter('group', val)
@property @property
def weight(self) -> float: def weight(self) -> float:
return round(util.lin_get(-12, 12, self.getter("weight")[0]), 1) return round(util.lin_get(-12, 12, self.getter('weight')[0]), 1)
@weight.setter @weight.setter
def weight(self, val: float): def weight(self, val: float):
if not -12 <= val <= 12: if not -12 <= val <= 12:
self.logger.warning( self.logger.warning(
f"weight got {val}, expected value in range -12.0 to 12.0" f'weight got {val}, expected value in range -12.0 to 12.0'
) )
self.setter("weight", util.lin_set(-12, 12, val)) self.setter('weight', util.lin_set(-12, 12, val))
class Send: class Send:
@ -654,20 +654,20 @@ class Send:
@classmethod @classmethod
def make(cls, _cls, i, remote, index=None): def make(cls, _cls, i, remote, index=None):
SEND_cls = type("Send", (cls, _cls), {}) SEND_cls = type('Send', (cls, _cls), {})
return SEND_cls(i, remote, index) return SEND_cls(i, remote, index)
@property @property
def address(self) -> str: def address(self) -> str:
root = super(Send, self).address root = super(Send, self).address
return f"{root}/mix/{str(self.i).zfill(2)}" return f'{root}/mix/{str(self.i).zfill(2)}'
@property @property
@util.db_from @util.db_from
def level(self) -> float: def level(self) -> float:
return self.getter("level")[0] return self.getter('level')[0]
@level.setter @level.setter
@util.db_to @util.db_to
def level(self, val: float): def level(self, val: float):
self.setter("level", val) self.setter('level', val)

View File

@ -16,10 +16,10 @@ class IStrip(abc.ABC):
self.logger = logger.getChild(self.__class__.__name__) self.logger = logger.getChild(self.__class__.__name__)
def getter(self, param: str) -> tuple: def getter(self, param: str) -> tuple:
return self._remote.query(f"{self.address}/{param}") return self._remote.query(f'{self.address}/{param}')
def setter(self, param: str, val: int): def setter(self, param: str, val: int):
self._remote.send(f"{self.address}/{param}", val) self._remote.send(f'{self.address}/{param}', val)
@abc.abstractmethod @abc.abstractmethod
def address(self): def address(self):
@ -40,12 +40,12 @@ class Strip(IStrip):
""" """
STRIP_cls = type( STRIP_cls = type(
f"Strip{remote.kind}", f'Strip{remote.kind}',
(cls,), (cls,),
{ {
**{ **{
_cls.__name__.lower(): type( _cls.__name__.lower(): type(
f"{_cls.__name__}{remote.kind}", (_cls, cls), {} f'{_cls.__name__}{remote.kind}', (_cls, cls), {}
)(remote, index) )(remote, index)
for _cls in ( for _cls in (
Config, Config,
@ -59,15 +59,15 @@ class Strip(IStrip):
Automix, Automix,
) )
}, },
"send": tuple( 'send': tuple(
Send.make(cls, i, remote, index) Send.make(cls, i, remote, index)
for i in range(remote.kind.num_bus + remote.kind.num_fx) for i in range(remote.kind.num_bus + remote.kind.num_fx)
), ),
"mute": mute_prop(), 'mute': mute_prop(),
}, },
) )
return STRIP_cls(remote, index) return STRIP_cls(remote, index)
@property @property
def address(self) -> str: def address(self) -> str:
return f"/ch/{str(self.index).zfill(2)}" return f'/ch/{str(self.index).zfill(2)}'

View File

@ -19,7 +19,7 @@ def timeout(func):
while time.time() < start + remote.connect_timeout: while time.time() < start + remote.connect_timeout:
try: try:
func(*args, **kwargs) func(*args, **kwargs)
remote.logger.debug(f"login time: {round(time.time() - start, 2)}") remote.logger.debug(f'login time: {round(time.time() - start, 2)}')
err = None err = None
break break
except XAirRemoteConnectionTimeoutError as e: except XAirRemoteConnectionTimeoutError as e:

View File

@ -31,7 +31,7 @@ logger = logging.getLogger(__name__)
class OSCClientServer(BlockingOSCUDPServer): class OSCClientServer(BlockingOSCUDPServer):
def __init__(self, address: str, dispatcher: Dispatcher): def __init__(self, address: str, dispatcher: Dispatcher):
super().__init__(("", 0), dispatcher) super().__init__(('', 0), dispatcher)
self.xr_address = address self.xr_address = address
def send_message(self, address: str, vals: Optional[Union[str, list]]): def send_message(self, address: str, vals: Optional[Union[str, list]]):
@ -53,13 +53,13 @@ class XAirRemote(abc.ABC):
def __init__(self, **kwargs): def __init__(self, **kwargs):
dispatcher = Dispatcher() dispatcher = Dispatcher()
dispatcher.set_default_handler(self.msg_handler) dispatcher.set_default_handler(self.msg_handler)
self.xair_ip = kwargs["ip"] or self._ip_from_toml() self.xair_ip = kwargs['ip'] or self._ip_from_toml()
self.xair_port = kwargs["port"] self.xair_port = kwargs['port']
self._delay = kwargs["delay"] self._delay = kwargs['delay']
self.connect_timeout = kwargs["connect_timeout"] self.connect_timeout = kwargs['connect_timeout']
self.logger = logger.getChild(self.__class__.__name__) self.logger = logger.getChild(self.__class__.__name__)
if not self.xair_ip: if not self.xair_ip:
raise XAirRemoteError("No valid ip detected") raise XAirRemoteError('No valid ip detected')
self.server = OSCClientServer((self.xair_ip, self.xair_port), dispatcher) self.server = OSCClientServer((self.xair_ip, self.xair_port), dispatcher)
def __enter__(self): def __enter__(self):
@ -69,17 +69,17 @@ class XAirRemote(abc.ABC):
return self return self
def _ip_from_toml(self) -> str: def _ip_from_toml(self) -> str:
filepath = Path.cwd() / "config.toml" filepath = Path.cwd() / 'config.toml'
with open(filepath, "rb") as f: with open(filepath, 'rb') as f:
conn = tomllib.load(f) conn = tomllib.load(f)
return conn["connection"].get("ip") return conn['connection'].get('ip')
@util.timeout @util.timeout
def validate_connection(self): def validate_connection(self):
if not self.query("/xinfo"): if not self.query('/xinfo'):
raise XAirRemoteConnectionTimeoutError(self.xair_ip, self.xair_port) raise XAirRemoteConnectionTimeoutError(self.xair_ip, self.xair_port)
self.logger.info( self.logger.info(
f"Successfully connected to {self.info_response[2]} at {self.info_response[0]}." f'Successfully connected to {self.info_response[2]} at {self.info_response[0]}.'
) )
@property @property
@ -115,10 +115,10 @@ def _make_remote(kind: KindMap) -> XAirRemote:
def init_x32(self, *args, **kwargs): def init_x32(self, *args, **kwargs):
defaultkwargs = { defaultkwargs = {
"ip": None, 'ip': None,
"port": 10023, 'port': 10023,
"delay": 0.02, 'delay': 0.02,
"connect_timeout": 2, 'connect_timeout': 2,
} }
kwargs = defaultkwargs | kwargs kwargs = defaultkwargs | kwargs
XAirRemote.__init__(self, *args, **kwargs) XAirRemote.__init__(self, *args, **kwargs)
@ -139,10 +139,10 @@ def _make_remote(kind: KindMap) -> XAirRemote:
def init_xair(self, *args, **kwargs): def init_xair(self, *args, **kwargs):
defaultkwargs = { defaultkwargs = {
"ip": None, 'ip': None,
"port": 10024, 'port': 10024,
"delay": 0.02, 'delay': 0.02,
"connect_timeout": 2, 'connect_timeout': 2,
} }
kwargs = defaultkwargs | kwargs kwargs = defaultkwargs | kwargs
XAirRemote.__init__(self, *args, **kwargs) XAirRemote.__init__(self, *args, **kwargs)
@ -158,19 +158,19 @@ def _make_remote(kind: KindMap) -> XAirRemote:
self.config = Config.make(self) self.config = Config.make(self)
self.headamp = tuple(HeadAmp(self, i) for i in range(kind.num_strip)) self.headamp = tuple(HeadAmp(self, i) for i in range(kind.num_strip))
if kind.id_ == "X32": if kind.id_ == 'X32':
return type( return type(
f"XAirRemote{kind}", f'XAirRemote{kind}',
(XAirRemote,), (XAirRemote,),
{ {
"__init__": init_x32, '__init__': init_x32,
}, },
) )
return type( return type(
f"XAirRemote{kind}", f'XAirRemote{kind}',
(XAirRemote,), (XAirRemote,),
{ {
"__init__": init_xair, '__init__': init_xair,
}, },
) )