12 Commits

Author SHA1 Message Date
3010b44b09 minor version bump
add 2.4.0 section to CHANGELOG

upd README with HeadAmp class

closes #10
2025-01-04 18:59:01 +00:00
f26de42b89 add headamp class 2025-01-03 10:19:06 +00:00
6bdd4a0040 Merge pull request #9 from onyx-and-iris/dependabot/pip/black-24.3.0
Bump black from 22.8.0 to 24.3.0
2024-03-28 14:59:43 +00:00
dependabot[bot]
b53ed46014 Bump black from 22.8.0 to 24.3.0
Bumps [black](https://github.com/psf/black) from 22.8.0 to 24.3.0.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/compare/22.8.0...24.3.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-28 14:59:15 +00:00
caaf2689ff upd docstring 2024-02-16 12:53:34 +00:00
7e7aa1b4de 2.3.2 section added to CHANGELOG
patch bump
2024-02-16 12:50:54 +00:00
2dc096e306 connect_timeout kwarg added to README
Errors section added to README
2024-02-16 12:37:15 +00:00
ed397e57aa XAirRemoteConnectionTimeoutError added to errors 2024-02-16 12:26:24 +00:00
718ecbd982 timeout decorator func added to util 2024-02-16 12:26:00 +00:00
69cabb3db0 add configurable kwarg connect_timeout 2024-02-16 12:25:41 +00:00
6a2df6352d add tox tests 2024-02-15 23:54:31 +00:00
9c1fa36aed upd pytest dep version 2024-02-15 18:47:11 +00:00
15 changed files with 498 additions and 175 deletions

4
.gitignore vendored
View File

@@ -130,4 +130,6 @@ dmypy.json
# config, quick test # config, quick test
config.toml config.toml
quick.py quick.py
.vscode/

View File

@@ -9,7 +9,22 @@ Before any major/minor/patch bump all unit tests will be run to verify they pass
## [Unreleased] ## [Unreleased]
- [ ] - [ ]
## [2.4.0] - 2025-01-04
### Added
- HeadAmp class to all kinds for enabling phantom power and setting preamp gain.
- headamp example.
## [2.3.2] - 2024-02-16
### Added
- Configurable kwarg `connect_timeout` added. Defaults to 2 seconds.
- New error class `XAirRemoteConnectionTimeoutError`. Raised if a connection validation times out.
- timeout kwarg + Errors section added to README.
## [2.3.1] - 2024-02-15 ## [2.3.1] - 2024-02-15

View File

@@ -1,7 +1,6 @@
[![PyPI version](https://badge.fury.io/py/xair-api.svg)](https://badge.fury.io/py/xair-api) [![PyPI version](https://badge.fury.io/py/xair-api.svg)](https://badge.fury.io/py/xair-api)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/onyx-and-iris/xair-api-python/blob/dev/LICENSE) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/onyx-and-iris/xair-api-python/blob/dev/LICENSE)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)
![Tests Status](./tests/xair/MR18.svg?dummy=8484744) ![Tests Status](./tests/xair/MR18.svg?dummy=8484744)
# Xair API # Xair API
@@ -55,7 +54,7 @@ if __name__ == "__main__":
main() main()
``` ```
#### `xair_api.connect(kind_id, ip=ip, delay=delay)` #### `xair_api.connect(kind_id, ip=ip, delay=0.02, connect_timeout=2)`
Currently the following devices are supported: Currently the following devices are supported:
@@ -72,6 +71,7 @@ The following keyword arguments may be passed:
- `port`: mixer port, defaults to 10023 for x32 and 10024 for xair - `port`: mixer port, defaults to 10023 for x32 and 10024 for xair
- `delay`: a delay between each command (applies to the getters). Defaults to 20ms. - `delay`: a delay between each command (applies to the getters). Defaults to 20ms.
- a note about delay, stability may rely on network connection. For wired connections the delay can be safely reduced. - a note about delay, stability may rely on network connection. For wired connections the delay can be safely reduced.
- `connect_timeout`: amount of time to wait for a validated connection. Defaults to 2s.
## API ## API
@@ -113,6 +113,10 @@ A class representing auxreturn channel
A class representing the main config settings A class representing the main config settings
`mixer.headamp`
A class representing the channel preamps (phantom power/gain).
### `LR` ### `LR`
Contains the subclasses: Contains the subclasses:
@@ -143,6 +147,13 @@ Contains the subclasses:
Contains the subclasses: Contains the subclasses:
(`Config`, `Preamp`, `EQ`, `Mix`, `Group`, `Send`) (`Config`, `Preamp`, `EQ`, `Mix`, `Group`, `Send`)
### `HeadAmp`
The following properties are available:
- `gain`: float, from -12.0 to 60.0
- `phantom`: bool
### `Subclasses` ### `Subclasses`
For each subclass the corresponding properties are available. For each subclass the corresponding properties are available.
@@ -317,6 +328,14 @@ for example:
print(mixer.query("/ch/01/mix/on")) print(mixer.query("/ch/01/mix/on"))
``` ```
### Errors
- `errors.XAirRemoteError`: Base error class for XAIR Remote.
- `errors.XAirRemoteConnectionTimeoutError`:Exception raised when a connection attempt times out.
- The following attributes are available:
- `ip`: IP of the mixer.
- `port`: Port of the mixer.
### `Tests` ### `Tests`
Unplug any expensive equipment before running tests. Unplug any expensive equipment before running tests.

View File

@@ -0,0 +1,20 @@
# Warning this script enables the phantom power for strip 09
import logging
import xair_api
logging.basicConfig(level=logging.DEBUG)
def main():
with xair_api.connect("XR18", ip="mixer.local") as mixer:
mixer.headamp[8].phantom = True
for i in range(-12, -6):
mixer.headamp[8].gain = i
print(mixer.headamp[8].gain)
input("Press Enter to continue...")
if __name__ == "__main__":
main()

354
poetry.lock generated
View File

@@ -1,92 +1,79 @@
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. # This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
[[package]] [[package]]
name = "attrs" name = "cachetools"
version = "22.1.0" version = "5.5.0"
description = "Classes Without Boilerplate" description = "Extensible memoizing collections and decorators"
optional = false
python-versions = ">=3.5"
files = [
{file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"},
{file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"},
]
[package.extras]
dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"]
docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"]
tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"]
tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"]
[[package]]
name = "black"
version = "22.8.0"
description = "The uncompromising code formatter."
optional = false
python-versions = ">=3.6.2"
files = [
{file = "black-22.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ce957f1d6b78a8a231b18e0dd2d94a33d2ba738cd88a7fe64f53f659eea49fdd"},
{file = "black-22.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5107ea36b2b61917956d018bd25129baf9ad1125e39324a9b18248d362156a27"},
{file = "black-22.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8166b7bfe5dcb56d325385bd1d1e0f635f24aae14b3ae437102dedc0c186747"},
{file = "black-22.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd82842bb272297503cbec1a2600b6bfb338dae017186f8f215c8958f8acf869"},
{file = "black-22.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d839150f61d09e7217f52917259831fe2b689f5c8e5e32611736351b89bb2a90"},
{file = "black-22.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a05da0430bd5ced89176db098567973be52ce175a55677436a271102d7eaa3fe"},
{file = "black-22.8.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a098a69a02596e1f2a58a2a1c8d5a05d5a74461af552b371e82f9fa4ada8342"},
{file = "black-22.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5594efbdc35426e35a7defa1ea1a1cb97c7dbd34c0e49af7fb593a36bd45edab"},
{file = "black-22.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a983526af1bea1e4cf6768e649990f28ee4f4137266921c2c3cee8116ae42ec3"},
{file = "black-22.8.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b2c25f8dea5e8444bdc6788a2f543e1fb01494e144480bc17f806178378005e"},
{file = "black-22.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:78dd85caaab7c3153054756b9fe8c611efa63d9e7aecfa33e533060cb14b6d16"},
{file = "black-22.8.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:cea1b2542d4e2c02c332e83150e41e3ca80dc0fb8de20df3c5e98e242156222c"},
{file = "black-22.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5b879eb439094751185d1cfdca43023bc6786bd3c60372462b6f051efa6281a5"},
{file = "black-22.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0a12e4e1353819af41df998b02c6742643cfef58282915f781d0e4dd7a200411"},
{file = "black-22.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3a73f66b6d5ba7288cd5d6dad9b4c9b43f4e8a4b789a94bf5abfb878c663eb3"},
{file = "black-22.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:e981e20ec152dfb3e77418fb616077937378b322d7b26aa1ff87717fb18b4875"},
{file = "black-22.8.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8ce13ffed7e66dda0da3e0b2eb1bdfc83f5812f66e09aca2b0978593ed636b6c"},
{file = "black-22.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:32a4b17f644fc288c6ee2bafdf5e3b045f4eff84693ac069d87b1a347d861497"},
{file = "black-22.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ad827325a3a634bae88ae7747db1a395d5ee02cf05d9aa7a9bd77dfb10e940c"},
{file = "black-22.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53198e28a1fb865e9fe97f88220da2e44df6da82b18833b588b1883b16bb5d41"},
{file = "black-22.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:bc4d4123830a2d190e9cc42a2e43570f82ace35c3aeb26a512a2102bce5af7ec"},
{file = "black-22.8.0-py3-none-any.whl", hash = "sha256:d2c21d439b2baf7aa80d6dd4e3659259be64c6f49dfd0f32091063db0e006db4"},
{file = "black-22.8.0.tar.gz", hash = "sha256:792f7eb540ba9a17e8656538701d3eb1afcb134e3b45b71f20b25c77a8db7e6e"},
]
[package.dependencies]
click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
pathspec = ">=0.9.0"
platformdirs = ">=2"
tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""}
[package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.7.4)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "click"
version = "8.1.3"
description = "Composable command line interface toolkit"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"},
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"},
] ]
[package.dependencies] [[package]]
colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "chardet"
version = "5.2.0"
description = "Universal encoding detector for Python 3"
optional = false
python-versions = ">=3.7"
files = [
{file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
{file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
]
[[package]] [[package]]
name = "colorama" name = "colorama"
version = "0.4.5" version = "0.4.6"
description = "Cross-platform colored terminal text." description = "Cross-platform colored terminal text."
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
files = [ files = [
{file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
] ]
[[package]]
name = "distlib"
version = "0.3.9"
description = "Distribution utilities"
optional = false
python-versions = "*"
files = [
{file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"},
{file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"},
]
[[package]]
name = "exceptiongroup"
version = "1.2.0"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
files = [
{file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"},
{file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"},
]
[package.extras]
test = ["pytest (>=6)"]
[[package]]
name = "filelock"
version = "3.16.1"
description = "A platform independent file lock."
optional = false
python-versions = ">=3.8"
files = [
{file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"},
{file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"},
]
[package.extras]
docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"]
testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"]
typing = ["typing-extensions (>=4.12.2)"]
[[package]] [[package]]
name = "iniconfig" name = "iniconfig"
version = "1.1.1" version = "1.1.1"
@@ -98,83 +85,42 @@ files = [
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
] ]
[[package]]
name = "isort"
version = "5.10.1"
description = "A Python utility / library to sort Python imports."
optional = false
python-versions = ">=3.6.1,<4.0"
files = [
{file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"},
{file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"},
]
[package.extras]
colors = ["colorama (>=0.4.3,<0.5.0)"]
pipfile-deprecated-finder = ["pipreqs", "requirementslib"]
plugins = ["setuptools"]
requirements-deprecated-finder = ["pip-api", "pipreqs"]
[[package]]
name = "mypy-extensions"
version = "0.4.3"
description = "Experimental type system extensions for programs checked with the mypy typechecker."
optional = false
python-versions = "*"
files = [
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
]
[[package]] [[package]]
name = "packaging" name = "packaging"
version = "21.3" version = "24.2"
description = "Core utilities for Python packages" description = "Core utilities for Python packages"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.8"
files = [ files = [
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
]
[package.dependencies]
pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
[[package]]
name = "pathspec"
version = "0.10.1"
description = "Utility library for gitignore style pattern matching of file paths."
optional = false
python-versions = ">=3.7"
files = [
{file = "pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"},
{file = "pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"},
] ]
[[package]] [[package]]
name = "platformdirs" name = "platformdirs"
version = "2.5.2" version = "4.3.6"
description = "A small Python module 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.7" python-versions = ">=3.8"
files = [ files = [
{file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"},
{file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"},
] ]
[package.extras] [package.extras]
docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)"] docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"]
test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"]
type = ["mypy (>=1.11.2)"]
[[package]] [[package]]
name = "pluggy" name = "pluggy"
version = "1.0.0" 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.6" python-versions = ">=3.8"
files = [ files = [
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
] ]
[package.extras] [package.extras]
@@ -182,52 +128,56 @@ dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"] testing = ["pytest", "pytest-benchmark"]
[[package]] [[package]]
name = "py" name = "pyenv-inspect"
version = "1.11.0" version = "0.4.0"
description = "library with cross-python path, ini-parsing, io, code, log facilities" description = "An auxiliary library for the virtualenv-pyenv and tox-pyenv-redux plugins"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" python-versions = ">=3.8"
files = [ files = [
{file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "pyenv-inspect-0.4.0.tar.gz", hash = "sha256:ec429d1d81b67ab0b08a0408414722a79d24fd1845a5b264267e44e19d8d60f0"},
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, {file = "pyenv_inspect-0.4.0-py3-none-any.whl", hash = "sha256:618683ae7d3e6db14778d58aa0fc6b3170180d944669b5d35a8aa4fb7db550d2"},
] ]
[[package]] [[package]]
name = "pyparsing" name = "pyproject-api"
version = "3.0.9" version = "1.8.0"
description = "pyparsing module - Classes and methods to define and execute parsing grammars" description = "API to interact with the python pyproject.toml based projects"
optional = false optional = false
python-versions = ">=3.6.8" python-versions = ">=3.8"
files = [ files = [
{file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, {file = "pyproject_api-1.8.0-py3-none-any.whl", hash = "sha256:3d7d347a047afe796fd5d1885b1e391ba29be7169bd2f102fcd378f04273d228"},
{file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, {file = "pyproject_api-1.8.0.tar.gz", hash = "sha256:77b8049f2feb5d33eefcc21b57f1e279636277a8ac8ad6b5871037b243778496"},
] ]
[package.dependencies]
packaging = ">=24.1"
tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
[package.extras] [package.extras]
diagrams = ["jinja2", "railroad-diagrams"] docs = ["furo (>=2024.8.6)", "sphinx-autodoc-typehints (>=2.4.1)"]
testing = ["covdefaults (>=2.3)", "pytest (>=8.3.3)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "setuptools (>=75.1)"]
[[package]] [[package]]
name = "pytest" name = "pytest"
version = "7.1.3" version = "7.4.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.7"
files = [ files = [
{file = "pytest-7.1.3-py3-none-any.whl", hash = "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7"}, {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"},
{file = "pytest-7.1.3.tar.gz", hash = "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39"}, {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"},
] ]
[package.dependencies] [package.dependencies]
attrs = ">=19.2.0"
colorama = {version = "*", markers = "sys_platform == \"win32\""} colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*" iniconfig = "*"
packaging = "*" packaging = "*"
pluggy = ">=0.12,<2.0" pluggy = ">=0.12,<2.0"
py = ">=1.8.2" tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
tomli = ">=1.0.0"
[package.extras] [package.extras]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
[[package]] [[package]]
name = "pytest-randomly" name = "pytest-randomly"
@@ -254,6 +204,33 @@ files = [
{file = "python_osc-1.8.0-py3-none-any.whl", hash = "sha256:9e2abb2fc9ba2c356f8e951609a03c9c7017bf0bad82cca8490e9b8af9e92a0b"}, {file = "python_osc-1.8.0-py3-none-any.whl", hash = "sha256:9e2abb2fc9ba2c356f8e951609a03c9c7017bf0bad82cca8490e9b8af9e92a0b"},
] ]
[[package]]
name = "ruff"
version = "0.8.6"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
{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_11_0_arm64.whl", hash = "sha256:e88b8f6d901477c41559ba540beeb5a671e14cd29ebd5683903572f4b40a9807"},
{file = "ruff-0.8.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0509e8da430228236a18a677fcdb0c1f102dd26d5520f71f79b094963322ed25"},
{file = "ruff-0.8.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:91a7ddb221779871cf226100e677b5ea38c2d54e9e2c8ed847450ebbdf99b32d"},
{file = "ruff-0.8.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:248b1fb3f739d01d528cc50b35ee9c4812aa58cc5935998e776bf8ed5b251e75"},
{file = "ruff-0.8.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:bc3c083c50390cf69e7e1b5a5a7303898966be973664ec0c4a4acea82c1d4315"},
{file = "ruff-0.8.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52d587092ab8df308635762386f45f4638badb0866355b2b86760f6d3c076188"},
{file = "ruff-0.8.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:61323159cf21bc3897674e5adb27cd9e7700bab6b84de40d7be28c3d46dc67cf"},
{file = "ruff-0.8.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ae4478b1471fc0c44ed52a6fb787e641a2ac58b1c1f91763bafbc2faddc5117"},
{file = "ruff-0.8.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0c000a471d519b3e6cfc9c6680025d923b4ca140ce3e4612d1a2ef58e11f11fe"},
{file = "ruff-0.8.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9257aa841e9e8d9b727423086f0fa9a86b6b420fbf4bf9e1465d1250ce8e4d8d"},
{file = "ruff-0.8.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:45a56f61b24682f6f6709636949ae8cc82ae229d8d773b4c76c09ec83964a95a"},
{file = "ruff-0.8.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:496dd38a53aa173481a7d8866bcd6451bd934d06976a2505028a50583e001b76"},
{file = "ruff-0.8.6-py3-none-win32.whl", hash = "sha256:e169ea1b9eae61c99b257dc83b9ee6c76f89042752cb2d83486a7d6e48e8f764"},
{file = "ruff-0.8.6-py3-none-win_amd64.whl", hash = "sha256:f1d70bef3d16fdc897ee290d7d20da3cbe4e26349f62e8a0274e7a3f4ce7a905"},
{file = "ruff-0.8.6-py3-none-win_arm64.whl", hash = "sha256:7d7fc2377a04b6e04ffe588caad613d0c460eb2ecba4c0ccbbfe2bc973cbc162"},
{file = "ruff-0.8.6.tar.gz", hash = "sha256:dcad24b81b62650b0eb8814f576fc65cfee8674772a6e24c9b747911801eeaa5"},
]
[[package]] [[package]]
name = "tomli" name = "tomli"
version = "2.0.1" version = "2.0.1"
@@ -265,7 +242,80 @@ files = [
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
] ]
[[package]]
name = "tox"
version = "4.23.2"
description = "tox is a generic virtualenv management and test command line tool"
optional = false
python-versions = ">=3.8"
files = [
{file = "tox-4.23.2-py3-none-any.whl", hash = "sha256:452bc32bb031f2282881a2118923176445bac783ab97c874b8770ab4c3b76c38"},
{file = "tox-4.23.2.tar.gz", hash = "sha256:86075e00e555df6e82e74cfc333917f91ecb47ffbc868dcafbd2672e332f4a2c"},
]
[package.dependencies]
cachetools = ">=5.5"
chardet = ">=5.2"
colorama = ">=0.4.6"
filelock = ">=3.16.1"
packaging = ">=24.1"
platformdirs = ">=4.3.6"
pluggy = ">=1.5"
pyproject-api = ">=1.8"
tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
typing-extensions = {version = ">=4.12.2", markers = "python_version < \"3.11\""}
virtualenv = ">=20.26.6"
[package.extras]
test = ["devpi-process (>=1.0.2)", "pytest (>=8.3.3)", "pytest-mock (>=3.14)"]
[[package]]
name = "typing-extensions"
version = "4.12.2"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
]
[[package]]
name = "virtualenv"
version = "20.28.1"
description = "Virtual Python Environment builder"
optional = false
python-versions = ">=3.8"
files = [
{file = "virtualenv-20.28.1-py3-none-any.whl", hash = "sha256:412773c85d4dab0409b83ec36f7a6499e72eaf08c80e81e9576bca61831c71cb"},
{file = "virtualenv-20.28.1.tar.gz", hash = "sha256:5d34ab240fdb5d21549b76f9e8ff3af28252f5499fb6d6f031adac4e5a8c5329"},
]
[package.dependencies]
distlib = ">=0.3.7,<1"
filelock = ">=3.12.2,<4"
platformdirs = ">=3.9.1,<5"
[package.extras]
docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
[[package]]
name = "virtualenv-pyenv"
version = "0.5.0"
description = "A virtualenv Python discovery plugin for pyenv-installed interpreters"
optional = false
python-versions = ">=3.8"
files = [
{file = "virtualenv-pyenv-0.5.0.tar.gz", hash = "sha256:7b0e5fe3dfbdf484f4cf9b01e1f98111e398db6942237910f666356e6293597f"},
{file = "virtualenv_pyenv-0.5.0-py3-none-any.whl", hash = "sha256:21750247e36c55b3c547cfdeb08f51a3867fe7129922991a4f9c96980c0a4a5d"},
]
[package.dependencies]
pyenv-inspect = ">=0.4,<0.5"
virtualenv = "*"
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10" python-versions = "^3.10"
content-hash = "def96d1658f870a9820fef363ee6a04455f1d895e15a189ea4f39801f168552f" content-hash = "03c4b24c8bf12ad78f55f6e99a5001183bbb855bf8ef841dd3522fb79c1f7288"

View File

@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "xair-api" name = "xair-api"
version = "2.3.1" version = "2.4.0"
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 = ["onyx-and-iris <code@onyxandiris.online>"]
license = "MIT" license = "MIT"
@@ -13,10 +13,11 @@ python-osc = "^1.8.0"
tomli = { version = "^2.0.1", python = "<3.11" } tomli = { version = "^2.0.1", python = "<3.11" }
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
pytest = "^7.1.2" pytest = "^7.4.4"
pytest-randomly = "^3.12.0" pytest-randomly = "^3.12.0"
black = "^22.6.0" ruff = "^0.8.6"
isort = "^5.10.1" tox = "^4.23.2"
virtualenv-pyenv = "^0.5.0"
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]
@@ -27,3 +28,108 @@ obs = "scripts:ex_obs"
sends = "scripts:ex_sends" sends = "scripts:ex_sends"
xair = "scripts:test_xair" xair = "scripts:test_xair"
x32 = "scripts:test_x32" x32 = "scripts:test_x32"
all = "scripts:test_all"
[tool.tox]
legacy_tox_ini = """
[tox]
envlist = py310,py311,py312
[testenv]
setenv = VIRTUALENV_DISCOVERY=pyenv
allowlist_externals = poetry
commands =
poetry install -v
poetry run pytest tests/
"""
[tool.ruff]
lint.select = [
"E",
"F",
]
lint.ignore = [
"E501",
]
lint.fixable = [
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"I",
"N",
"Q",
"S",
"T",
"W",
"ANN",
"ARG",
"BLE",
"COM",
"DJ",
"DTZ",
"EM",
"ERA",
"EXE",
"FBT",
"ICN",
"INP",
"ISC",
"NPY",
"PD",
"PGH",
"PIE",
"PL",
"PT",
"PTH",
"PYI",
"RET",
"RSE",
"RUF",
"SIM",
"SLF",
"TCH",
"TID",
"TRY",
"UP",
"YTT",
]
lint.unfixable = []
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".mypy_cache",
".nox",
".pants.d",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"venv",
]
line-length = 88
lint.dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
target-version = "py312"
[tool.ruff.lint.mccabe]
max-complexity = 10
[tool.ruff.lint.per-file-ignores]
"__init__.py" = [
"E402",
"F401",
]

View File

@@ -21,3 +21,7 @@ def test_xair():
def test_x32(): def test_x32():
path = Path.cwd() / "tests" / "x32" path = Path.cwd() / "tests" / "x32"
subprocess.run(["pytest", "-v", str(path)]) subprocess.run(["pytest", "-v", str(path)])
def test_all():
subprocess.run(["tox"])

View File

@@ -8,7 +8,7 @@ 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, delay=0.008) tests = xair_api.connect(kind_id, ip=ip)
kind = kinds.get(kind_id) kind = kinds.get(kind_id)

View File

@@ -8,7 +8,7 @@ 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, delay=0.008) tests = xair_api.connect(kind_id, ip=ip)
kind = kinds.get(kind_id) kind = kinds.get(kind_id)

View File

@@ -1,4 +1,5 @@
from .bus import Bus as IBus from .bus import Bus as IBus
from .headamp import HeadAmp as IHeadAmp
from .lr import LR as ILR from .lr import LR as ILR
from .rtn import AuxRtn as IAuxRtn from .rtn import AuxRtn as IAuxRtn
from .rtn import FxRtn as IFxRtn from .rtn import FxRtn as IFxRtn
@@ -38,3 +39,9 @@ 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):
@property
def address(self):
return f"/headamp/{str(self.index).zfill(3)}"

View File

@@ -1,2 +1,14 @@
class XAirRemoteError(Exception): class XAirRemoteError(Exception):
"""Base error class for XAIR Remote.""" """Base error class for XAIR Remote."""
class XAirRemoteConnectionTimeoutError(XAirRemoteError):
"""Exception raised when a connection attempt times out"""
def __init__(self, ip, port):
self.ip = ip
self.port = port
super().__init__(
f"Timeout attempting to connect to mixer at {self.ip}:{self.port}"
)

49
xair_api/headamp.py Normal file
View File

@@ -0,0 +1,49 @@
import abc
import logging
from . import util
logger = logging.getLogger(__name__)
class IHeadAmp(abc.ABC):
"""Abstract Base Class for headamps"""
def __init__(self, remote, index: int):
self._remote = remote
self.index = index + 1
self.logger = logger.getChild(self.__class__.__name__)
def getter(self, param: str):
return self._remote.query(f"{self.address}/{param}")
def setter(self, param: str, val: int):
self._remote.send(f"{self.address}/{param}", val)
@abc.abstractmethod
def address(self):
pass
class HeadAmp(IHeadAmp):
"""Concrete class for headamps"""
@property
def address(self):
return f"/headamp/{str(self.index).zfill(2)}"
@property
def gain(self):
return round(util.lin_get(-12, 60, self.getter("gain")[0]), 1)
@gain.setter
def gain(self, val):
self.setter("gain", util.lin_set(-12, 60, val))
@property
def phantom(self):
return self.getter("phantom")[0] == 1
@phantom.setter
def phantom(self, val):
self.setter("phantom", 1 if val else 0)

View File

@@ -16,6 +16,7 @@ class X32KindMap(KindMap):
num_fx: int = 8 num_fx: int = 8
num_auxrtn: int = 8 num_auxrtn: int = 8
num_matrix: int = 6 num_matrix: int = 6
num_headamp: int = 127
@dataclass @dataclass

View File

@@ -1,6 +1,35 @@
import functools import functools
import time
from math import exp, log from math import exp, log
from .errors import XAirRemoteConnectionTimeoutError
def timeout(func):
"""
Times out the validate_connection function once time elapsed exceeds remote.connect_timeout.
"""
@functools.wraps(func)
def wrapper(*args, **kwargs):
remote, *_ = args
err = None
start = time.time()
while time.time() < start + remote.connect_timeout:
try:
func(*args, **kwargs)
remote.logger.debug(f"login time: {round(time.time() - start, 2)}")
err = None
break
except XAirRemoteConnectionTimeoutError as e:
err = e
continue
if err:
raise err
return wrapper
def lin_get(min, max, val): def lin_get(min, max, val):
return min + (max - min) * val return min + (max - min) * val

View File

@@ -14,12 +14,13 @@ from pythonosc.dispatcher import Dispatcher
from pythonosc.osc_message_builder import OscMessageBuilder from pythonosc.osc_message_builder import OscMessageBuilder
from pythonosc.osc_server import BlockingOSCUDPServer from pythonosc.osc_server import BlockingOSCUDPServer
from . import adapter, kinds from . import adapter, kinds, util
from .bus import Bus from .bus import Bus
from .config import Config from .config import Config
from .dca import DCA from .dca import DCA
from .errors import XAirRemoteError from .errors import XAirRemoteConnectionTimeoutError, XAirRemoteError
from .fx import FX, FXSend from .fx import FX, FXSend
from .headamp import HeadAmp
from .kinds import KindMap from .kinds import KindMap
from .lr import LR from .lr import LR
from .rtn import AuxRtn, FxRtn from .rtn import AuxRtn, FxRtn
@@ -47,8 +48,6 @@ class OSCClientServer(BlockingOSCUDPServer):
class XAirRemote(abc.ABC): class XAirRemote(abc.ABC):
"""Handles the communication with the mixer via the OSC protocol""" """Handles the communication with the mixer via the OSC protocol"""
_CONNECT_TIMEOUT = 0.5
_info_response = [] _info_response = []
def __init__(self, **kwargs): def __init__(self, **kwargs):
@@ -57,6 +56,7 @@ class XAirRemote(abc.ABC):
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.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")
@@ -74,13 +74,10 @@ class XAirRemote(abc.ABC):
conn = tomllib.load(f) conn = tomllib.load(f)
return conn["connection"].get("ip") return conn["connection"].get("ip")
@util.timeout
def validate_connection(self): def validate_connection(self):
self.send("/xinfo") if not self.query("/xinfo"):
time.sleep(self._CONNECT_TIMEOUT) raise XAirRemoteConnectionTimeoutError(self.xair_ip, self.xair_port)
if not self.info_response:
raise XAirRemoteError(
"Failed to setup OSC connection to mixer. Please check for correct ip address."
)
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]}."
) )
@@ -117,7 +114,12 @@ def _make_remote(kind: KindMap) -> XAirRemote:
""" """
def init_x32(self, *args, **kwargs): def init_x32(self, *args, **kwargs):
defaultkwargs = {"ip": None, "port": 10023, "delay": 0.02} defaultkwargs = {
"ip": None,
"port": 10023,
"delay": 0.02,
"connect_timeout": 2,
}
kwargs = defaultkwargs | kwargs kwargs = defaultkwargs | kwargs
XAirRemote.__init__(self, *args, **kwargs) XAirRemote.__init__(self, *args, **kwargs)
self.kind = kind self.kind = kind
@@ -133,9 +135,15 @@ def _make_remote(kind: KindMap) -> XAirRemote:
self.fxreturn = tuple(adapter.FxRtn.make(self, i) for i in range(kind.num_fx)) self.fxreturn = tuple(adapter.FxRtn.make(self, i) for i in range(kind.num_fx))
self.auxin = tuple(adapter.AuxRtn.make(self, i) for i in range(kind.num_auxrtn)) self.auxin = tuple(adapter.AuxRtn.make(self, i) for i in range(kind.num_auxrtn))
self.config = Config.make(self) self.config = Config.make(self)
self.headamp = tuple(adapter.HeadAmp(self, i) for i in range(kind.num_headamp))
def init_xair(self, *args, **kwargs): def init_xair(self, *args, **kwargs):
defaultkwargs = {"ip": None, "port": 10024, "delay": 0.02} defaultkwargs = {
"ip": None,
"port": 10024,
"delay": 0.02,
"connect_timeout": 2,
}
kwargs = defaultkwargs | kwargs kwargs = defaultkwargs | kwargs
XAirRemote.__init__(self, *args, **kwargs) XAirRemote.__init__(self, *args, **kwargs)
self.kind = kind self.kind = kind
@@ -148,6 +156,7 @@ def _make_remote(kind: KindMap) -> XAirRemote:
self.fxreturn = tuple(FxRtn.make(self, i) for i in range(kind.num_fx)) self.fxreturn = tuple(FxRtn.make(self, i) for i in range(kind.num_fx))
self.auxreturn = AuxRtn.make(self) self.auxreturn = AuxRtn.make(self)
self.config = Config.make(self) self.config = Config.make(self)
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(