mx-remote 2.0.0__tar.gz → 4.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mx_remote-4.7.2/.claude/settings.local.json +13 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/.gitignore +1 -0
- mx_remote-4.7.2/PKG-INFO +515 -0
- mx_remote-4.7.2/README.md +483 -0
- mx_remote-4.7.2/hatch_build.py +53 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/Interface.py +1075 -404
- mx_remote-4.7.2/mx_remote/Interface.pyi +1056 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/Uid.py +16 -12
- mx_remote-4.7.2/mx_remote/Uid.pyi +31 -0
- mx_remote-4.7.2/mx_remote/__init__.py +33 -0
- mx_remote-4.7.2/mx_remote/__init__.pyi +5 -0
- mx_remote-4.7.2/mx_remote/const.py +29 -0
- mx_remote-4.7.2/mx_remote/const.pyi +8 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/main.py +39 -33
- mx_remote-4.7.2/mx_remote/main.pyi +7 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/BayConfig.py +38 -35
- mx_remote-4.7.2/mx_remote/proto/BayConfig.pyi +38 -0
- mx_remote-4.7.2/mx_remote/proto/Constants.py +537 -0
- mx_remote-4.7.2/mx_remote/proto/Constants.pyi +238 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/Data.py +17 -15
- mx_remote-4.7.2/mx_remote/proto/Data.pyi +42 -0
- mx_remote-4.7.2/mx_remote/proto/Factory.py +210 -0
- mx_remote-4.7.2/mx_remote/proto/Factory.pyi +6 -0
- mx_remote-4.7.2/mx_remote/proto/FrameAmpDolbySettings.py +76 -0
- mx_remote-4.7.2/mx_remote/proto/FrameAmpDolbySettings.pyi +20 -0
- mx_remote-4.7.2/mx_remote/proto/FrameAmpZoneSettings.py +151 -0
- mx_remote-4.7.2/mx_remote/proto/FrameAmpZoneSettings.pyi +47 -0
- mx_remote-4.7.2/mx_remote/proto/FrameBase.py +155 -0
- mx_remote-4.7.2/mx_remote/proto/FrameBase.pyi +46 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/FrameBayConfig.py +17 -17
- mx_remote-4.7.2/mx_remote/proto/FrameBayConfig.pyi +10 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/FrameBayConfigSecondary.py +20 -17
- mx_remote-4.7.2/mx_remote/proto/FrameBayConfigSecondary.pyi +10 -0
- mx_remote-4.7.2/mx_remote/proto/FrameBayHide.py +52 -0
- mx_remote-4.7.2/mx_remote/proto/FrameBayHide.pyi +14 -0
- mx_remote-4.7.2/mx_remote/proto/FrameBayStatus.py +60 -0
- mx_remote-4.7.2/mx_remote/proto/FrameBayStatus.pyi +15 -0
- mx_remote-4.7.2/mx_remote/proto/FrameConnectStatus.py +35 -0
- mx_remote-4.7.2/mx_remote/proto/FrameConnectStatus.pyi +10 -0
- mx_remote-4.7.2/mx_remote/proto/FrameDebug.py +18 -0
- mx_remote-4.7.2/mx_remote/proto/FrameDebug.pyi +4 -0
- mx_remote-4.7.2/mx_remote/proto/FrameDiscover.py +25 -0
- mx_remote-4.7.2/mx_remote/proto/FrameDiscover.pyi +8 -0
- mx_remote-4.7.2/mx_remote/proto/FrameEDID.py +23 -0
- mx_remote-4.7.2/mx_remote/proto/FrameEDID.pyi +6 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/FrameEDIDProfile.py +7 -8
- mx_remote-4.7.2/mx_remote/proto/FrameEDIDProfile.pyi +6 -0
- mx_remote-4.7.2/mx_remote/proto/FrameFactoryReset.py +38 -0
- mx_remote-4.7.2/mx_remote/proto/FrameFactoryReset.pyi +9 -0
- mx_remote-4.7.2/mx_remote/proto/FrameFilterStatus.py +37 -0
- mx_remote-4.7.2/mx_remote/proto/FrameFilterStatus.pyi +11 -0
- mx_remote-4.7.2/mx_remote/proto/FrameFirmwareVersion.py +55 -0
- mx_remote-4.7.2/mx_remote/proto/FrameFirmwareVersion.pyi +17 -0
- mx_remote-4.7.2/mx_remote/proto/FrameHeader.py +164 -0
- mx_remote-4.7.2/mx_remote/proto/FrameHeader.pyi +42 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/FrameHello.py +39 -33
- mx_remote-4.7.2/mx_remote/proto/FrameHello.pyi +25 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/FrameLinks.py +16 -15
- mx_remote-4.7.2/mx_remote/proto/FrameLinks.pyi +10 -0
- mx_remote-4.7.2/mx_remote/proto/FrameMeshOperation.py +84 -0
- mx_remote-4.7.2/mx_remote/proto/FrameMeshOperation.pyi +24 -0
- mx_remote-4.7.2/mx_remote/proto/FrameMirrorStatus.py +52 -0
- mx_remote-4.7.2/mx_remote/proto/FrameMirrorStatus.pyi +17 -0
- mx_remote-4.7.2/mx_remote/proto/FrameMonitoringPulse.py +19 -0
- mx_remote-4.7.2/mx_remote/proto/FrameMonitoringPulse.pyi +3 -0
- mx_remote-4.7.2/mx_remote/proto/FrameNetworkStatus.py +284 -0
- mx_remote-4.7.2/mx_remote/proto/FrameNetworkStatus.pyi +108 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/FramePDUState.py +12 -11
- mx_remote-4.7.2/mx_remote/proto/FramePDUState.pyi +23 -0
- mx_remote-4.7.2/mx_remote/proto/FramePowerChange.py +31 -0
- mx_remote-4.7.2/mx_remote/proto/FramePowerChange.pyi +10 -0
- mx_remote-4.7.2/mx_remote/proto/FrameRCAction.py +45 -0
- mx_remote-4.7.2/mx_remote/proto/FrameRCAction.pyi +13 -0
- mx_remote-4.7.2/mx_remote/proto/FrameRCIr.py +29 -0
- mx_remote-4.7.2/mx_remote/proto/FrameRCIr.pyi +9 -0
- mx_remote-4.7.2/mx_remote/proto/FrameRCKey.py +34 -0
- mx_remote-4.7.2/mx_remote/proto/FrameRCKey.pyi +11 -0
- mx_remote-4.7.2/mx_remote/proto/FrameRCSettings.py +18 -0
- mx_remote-4.7.2/mx_remote/proto/FrameRCSettings.pyi +4 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/FrameReboot.py +9 -14
- mx_remote-4.7.2/mx_remote/proto/FrameReboot.pyi +6 -0
- mx_remote-4.7.2/mx_remote/proto/FrameRoutingChange.py +46 -0
- mx_remote-4.7.2/mx_remote/proto/FrameRoutingChange.pyi +16 -0
- mx_remote-4.7.2/mx_remote/proto/FrameSetInstaller.py +24 -0
- mx_remote-4.7.2/mx_remote/proto/FrameSetInstaller.pyi +6 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/FrameSetName.py +9 -10
- mx_remote-4.7.2/mx_remote/proto/FrameSetName.pyi +6 -0
- mx_remote-4.7.2/mx_remote/proto/FrameSetRoute.py +39 -0
- mx_remote-4.7.2/mx_remote/proto/FrameSetRoute.pyi +12 -0
- mx_remote-4.7.2/mx_remote/proto/FrameSetupStatus.py +29 -0
- mx_remote-4.7.2/mx_remote/proto/FrameSetupStatus.pyi +6 -0
- mx_remote-4.7.2/mx_remote/proto/FrameSignalStatus.py +38 -0
- mx_remote-4.7.2/mx_remote/proto/FrameSignalStatus.pyi +12 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/FrameSignalStatusNew.py +86 -83
- mx_remote-4.7.2/mx_remote/proto/FrameSignalStatusNew.pyi +109 -0
- mx_remote-4.7.2/mx_remote/proto/FrameSysTemperature.py +41 -0
- mx_remote-4.7.2/mx_remote/proto/FrameSysTemperature.pyi +10 -0
- mx_remote-4.7.2/mx_remote/proto/FrameSystemStatus.py +31 -0
- mx_remote-4.7.2/mx_remote/proto/FrameSystemStatus.pyi +10 -0
- mx_remote-4.7.2/mx_remote/proto/FrameTXRCAction.py +58 -0
- mx_remote-4.7.2/mx_remote/proto/FrameTXRCAction.pyi +20 -0
- mx_remote-4.7.2/mx_remote/proto/FrameTopology.py +54 -0
- mx_remote-4.7.2/mx_remote/proto/FrameTopology.pyi +16 -0
- mx_remote-4.7.2/mx_remote/proto/FrameTxIR.py +79 -0
- mx_remote-4.7.2/mx_remote/proto/FrameTxIR.pyi +25 -0
- mx_remote-4.7.2/mx_remote/proto/FrameUpgradeFPGA.py +19 -0
- mx_remote-4.7.2/mx_remote/proto/FrameUpgradeFPGA.pyi +3 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPAudio.py +876 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPAudio.pyi +272 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPBayMapping.py +74 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPBayMapping.pyi +21 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPDeviceConfiguration.py +108 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPDeviceConfiguration.pyi +39 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/FrameV2IPLink.py +3 -5
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPLink.pyi +3 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPManualSourceSwitch.py +116 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPManualSourceSwitch.pyi +28 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPMultiviewer.py +396 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPMultiviewer.pyi +110 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPPowerSave.py +47 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPPowerSave.pyi +12 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/FrameV2IPSetMaster.py +3 -5
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPSetMaster.pyi +3 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPSourceSwitch.py +98 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPSourceSwitch.pyi +22 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPSources.py +44 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPSources.pyi +11 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPStats.py +80 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPStats.pyi +23 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPStreamDetails.py +60 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPStreamDetails.pyi +17 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPTiling.py +50 -0
- mx_remote-4.7.2/mx_remote/proto/FrameV2IPTiling.pyi +18 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/FrameVolume.py +23 -22
- mx_remote-4.7.2/mx_remote/proto/FrameVolume.pyi +15 -0
- mx_remote-4.7.2/mx_remote/proto/FrameVolumeDown.py +26 -0
- mx_remote-4.7.2/mx_remote/proto/FrameVolumeDown.pyi +9 -0
- mx_remote-4.7.2/mx_remote/proto/FrameVolumeSet.py +85 -0
- mx_remote-4.7.2/mx_remote/proto/FrameVolumeSet.pyi +22 -0
- mx_remote-4.7.2/mx_remote/proto/FrameVolumeUp.py +26 -0
- mx_remote-4.7.2/mx_remote/proto/FrameVolumeUp.pyi +9 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/LinkConfig.py +36 -22
- mx_remote-4.7.2/mx_remote/proto/LinkConfig.pyi +37 -0
- mx_remote-4.7.2/mx_remote/proto/Multiviewer.py +360 -0
- mx_remote-4.7.2/mx_remote/proto/Multiviewer.pyi +208 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/PDUState.py +19 -14
- mx_remote-4.7.2/mx_remote/proto/PDUState.pyi +29 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/Svd.py +19 -7
- mx_remote-4.7.2/mx_remote/proto/Svd.pyi +28 -0
- mx_remote-4.7.2/mx_remote/proto/V2IPConfig.py +133 -0
- mx_remote-4.7.2/mx_remote/proto/V2IPConfig.pyi +55 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/V2IPStats.py +34 -10
- mx_remote-4.7.2/mx_remote/proto/V2IPStats.pyi +50 -0
- mx_remote-4.7.2/mx_remote/proto/__init__.py +16 -0
- mx_remote-4.7.2/mx_remote/proto/__init__.pyi +1 -0
- mx_remote-4.7.2/mx_remote/py.typed +0 -0
- mx_remote-4.7.2/mx_remote/remote/Bay.py +1170 -0
- mx_remote-4.7.2/mx_remote/remote/Bay.pyi +314 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/remote/ConnectionAsync.py +25 -11
- mx_remote-4.7.2/mx_remote/remote/ConnectionAsync.pyi +25 -0
- mx_remote-4.7.2/mx_remote/remote/Device.py +1088 -0
- mx_remote-4.7.2/mx_remote/remote/Device.pyi +230 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/remote/Link.py +68 -70
- mx_remote-4.7.2/mx_remote/remote/Link.pyi +33 -0
- mx_remote-2.0.0/mx_remote/remote/PDU.py → mx_remote-4.7.2/mx_remote/remote/P8PDU.py +23 -19
- mx_remote-4.7.2/mx_remote/remote/P8PDU.pyi +46 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/remote/Remote.py +135 -54
- mx_remote-4.7.2/mx_remote/remote/Remote.pyi +70 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/remote/State.py +6 -1
- mx_remote-4.7.2/mx_remote/remote/State.pyi +9 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/remote/V2IP.py +16 -10
- mx_remote-4.7.2/mx_remote/remote/V2IP.pyi +28 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/pyproject.toml +8 -5
- mx_remote-2.0.0/PKG-INFO +0 -90
- mx_remote-2.0.0/README.md +0 -58
- mx_remote-2.0.0/mx_remote/__init__.py +0 -12
- mx_remote-2.0.0/mx_remote/api/BayConfig.py +0 -53
- mx_remote-2.0.0/mx_remote/api/__init__.py +0 -8
- mx_remote-2.0.0/mx_remote/const.py +0 -20
- mx_remote-2.0.0/mx_remote/proto/Constants.py +0 -382
- mx_remote-2.0.0/mx_remote/proto/Factory.py +0 -168
- mx_remote-2.0.0/mx_remote/proto/FrameAmpDolbySettings.py +0 -51
- mx_remote-2.0.0/mx_remote/proto/FrameAmpZoneSettings.py +0 -123
- mx_remote-2.0.0/mx_remote/proto/FrameBase.py +0 -80
- mx_remote-2.0.0/mx_remote/proto/FrameBayHide.py +0 -53
- mx_remote-2.0.0/mx_remote/proto/FrameBayStatus.py +0 -51
- mx_remote-2.0.0/mx_remote/proto/FrameConnectStatus.py +0 -38
- mx_remote-2.0.0/mx_remote/proto/FrameDiscover.py +0 -21
- mx_remote-2.0.0/mx_remote/proto/FrameEDID.py +0 -20
- mx_remote-2.0.0/mx_remote/proto/FrameFilterStatus.py +0 -39
- mx_remote-2.0.0/mx_remote/proto/FrameFirmwareVersion.py +0 -40
- mx_remote-2.0.0/mx_remote/proto/FrameHeader.py +0 -92
- mx_remote-2.0.0/mx_remote/proto/FrameMeshOperation.py +0 -66
- mx_remote-2.0.0/mx_remote/proto/FrameMirrorStatus.py +0 -49
- mx_remote-2.0.0/mx_remote/proto/FrameNetworkStatus.py +0 -163
- mx_remote-2.0.0/mx_remote/proto/FramePowerChange.py +0 -38
- mx_remote-2.0.0/mx_remote/proto/FrameRCAction.py +0 -50
- mx_remote-2.0.0/mx_remote/proto/FrameRCIr.py +0 -17
- mx_remote-2.0.0/mx_remote/proto/FrameRCKey.py +0 -40
- mx_remote-2.0.0/mx_remote/proto/FrameRoutingChange.py +0 -66
- mx_remote-2.0.0/mx_remote/proto/FrameSignalStatus.py +0 -46
- mx_remote-2.0.0/mx_remote/proto/FrameSysTemperature.py +0 -50
- mx_remote-2.0.0/mx_remote/proto/FrameTXRCAction.py +0 -58
- mx_remote-2.0.0/mx_remote/proto/FrameTopology.py +0 -36
- mx_remote-2.0.0/mx_remote/proto/FrameV2IPDeviceConfiguration.py +0 -86
- mx_remote-2.0.0/mx_remote/proto/FrameV2IPSourceSwitch.py +0 -84
- mx_remote-2.0.0/mx_remote/proto/FrameV2IPSources.py +0 -43
- mx_remote-2.0.0/mx_remote/proto/FrameV2IPStats.py +0 -55
- mx_remote-2.0.0/mx_remote/proto/FrameV2IPStreamDetails.py +0 -46
- mx_remote-2.0.0/mx_remote/proto/FrameVolumeDown.py +0 -28
- mx_remote-2.0.0/mx_remote/proto/FrameVolumeSet.py +0 -81
- mx_remote-2.0.0/mx_remote/proto/FrameVolumeUp.py +0 -28
- mx_remote-2.0.0/mx_remote/proto/V2IPConfig.py +0 -71
- mx_remote-2.0.0/mx_remote/proto/__init__.py +0 -8
- mx_remote-2.0.0/mx_remote/remote/Bay.py +0 -923
- mx_remote-2.0.0/mx_remote/remote/Device.py +0 -530
- {mx_remote-2.0.0 → mx_remote-4.7.2}/LICENSE +0 -0
- {mx_remote-2.0.0 → mx_remote-4.7.2}/mx_remote/proto/svd.csv +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(scp *)",
|
|
5
|
+
"Bash(ssh hass@home '~/venv-hass/bin/pip install --upgrade /tmp/mx_remote-4.3.0-py3-none-any.whl')",
|
|
6
|
+
"Bash(ssh hass@home *)",
|
|
7
|
+
"Bash(git reset *)",
|
|
8
|
+
"Bash(mount)",
|
|
9
|
+
"Bash(curl -s -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI1ZTU3MjI0Zjc3ZjQ0OWVkYjEzMzU5YjAyMTMzN2IzMiIsImlhdCI6MTc3NTQ4MjM0NiwiZXhwIjoyMDkwODQyMzQ2fQ.EzuPwl8JfzUFkWQIczcKGc_bUEfKKzXfday8t7EB93M' http://10.8.100.5:8123/api/states/media_player.video_output_kantoor)",
|
|
10
|
+
"Bash(git pull *)"
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
}
|
mx_remote-4.7.2/PKG-INFO
ADDED
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mx_remote
|
|
3
|
+
Version: 4.7.2
|
|
4
|
+
Summary: Python 3 library for interfacing with MX Remote compatible devices
|
|
5
|
+
Project-URL: Homepage, https://github.com/opdenkamp/mx-remote/
|
|
6
|
+
Project-URL: Documentation, https://github.com/opdenkamp/mx-remote/
|
|
7
|
+
Project-URL: Repository, https://github.com/opdenkamp/mx-remote.git
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/opdenkamp/mx-remote/issues
|
|
9
|
+
Author-email: Lars Op den Kamp <lars@opdenkamp.eu>
|
|
10
|
+
Maintainer-email: Lars Op den Kamp <lars@opdenkamp.eu>
|
|
11
|
+
License: Copyright 2024 Lars Op den Kamp <lars@opdenkamp.eu>
|
|
12
|
+
|
|
13
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
14
|
+
|
|
15
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
16
|
+
|
|
17
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
18
|
+
|
|
19
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
20
|
+
|
|
21
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Keywords: ampos,matrixos,oneip,pulse-eight
|
|
24
|
+
Classifier: Development Status :: 3 - Alpha
|
|
25
|
+
Classifier: Programming Language :: Python
|
|
26
|
+
Classifier: Topic :: System :: Networking :: Monitoring
|
|
27
|
+
Requires-Python: >=3.11
|
|
28
|
+
Requires-Dist: aiofiles>=24.1.0
|
|
29
|
+
Requires-Dist: aiohttp>=3.10.5
|
|
30
|
+
Requires-Dist: netifaces>=0.11.0
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# MX Remote Interface
|
|
34
|
+
|
|
35
|
+
Python 3 library for interfacing with [MX Remote](https://github.com/opdenkamp/mx-remote/) compatible devices over a local network. Supports device discovery, video/audio routing, volume control, remote control key passthrough, V2IP (OneIP) streaming, and more.
|
|
36
|
+
|
|
37
|
+
## Requirements
|
|
38
|
+
|
|
39
|
+
- Python 3.11 or later
|
|
40
|
+
- Network access to MX Remote compatible devices (multicast or broadcast)
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
The minimum code to discover devices on the network:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
import asyncio
|
|
54
|
+
import mx_remote
|
|
55
|
+
|
|
56
|
+
async def main():
|
|
57
|
+
mx = mx_remote.Remote()
|
|
58
|
+
await mx.start_async()
|
|
59
|
+
|
|
60
|
+
# wait for devices to be discovered
|
|
61
|
+
await asyncio.sleep(5)
|
|
62
|
+
|
|
63
|
+
for uid, device in mx.remotes.items():
|
|
64
|
+
print(f"{device.serial} ({device.name}) - {device.model_name} - {device.status}")
|
|
65
|
+
for port, bay in device.bays.items():
|
|
66
|
+
print(f" {bay.bay_label} [{bay.mode}] signal={bay.signal_detected}")
|
|
67
|
+
|
|
68
|
+
await mx.close()
|
|
69
|
+
|
|
70
|
+
asyncio.run(main())
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Core Concepts
|
|
74
|
+
|
|
75
|
+
### Remote
|
|
76
|
+
|
|
77
|
+
`Remote` is the main entry point. It manages the UDP connection (multicast or broadcast), handles device discovery, and maintains a registry of all discovered devices.
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
# default: multicast on 224.8.8.8:8812
|
|
81
|
+
mx = mx_remote.Remote()
|
|
82
|
+
|
|
83
|
+
# use broadcast instead
|
|
84
|
+
mx = mx_remote.Remote(broadcast=True)
|
|
85
|
+
|
|
86
|
+
# bind to a specific network interface
|
|
87
|
+
mx = mx_remote.Remote(local_ip="192.168.1.100")
|
|
88
|
+
|
|
89
|
+
# custom target address and port
|
|
90
|
+
mx = mx_remote.Remote(target_ip="10.8.8.255", port=8811)
|
|
91
|
+
|
|
92
|
+
# offline mode for processing capture files
|
|
93
|
+
mx = mx_remote.Remote(open_connection=False)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Device
|
|
97
|
+
|
|
98
|
+
A `DeviceBase` represents a physical device on the network (matrix, OneIP unit, amplifier). Devices are automatically registered when they respond to discovery requests.
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
# look up a device by serial number or unique ID
|
|
102
|
+
device = mx.get_by_serial("AB1234")
|
|
103
|
+
device = mx.get_by_uid(uid)
|
|
104
|
+
|
|
105
|
+
# device properties
|
|
106
|
+
device.serial # serial number
|
|
107
|
+
device.name # device name
|
|
108
|
+
device.model_name # model (e.g. "neo:8", "OneIP Transmitter")
|
|
109
|
+
device.address # IP address
|
|
110
|
+
device.version # firmware version
|
|
111
|
+
device.online # True if responding
|
|
112
|
+
device.status # DeviceStatus enum (ONLINE, OFFLINE, REBOOTING, BOOTING, INACTIVE)
|
|
113
|
+
device.features # DeviceFeatures bitmask
|
|
114
|
+
device.temperatures # dict of temperature sensor readings
|
|
115
|
+
|
|
116
|
+
# device type checks
|
|
117
|
+
device.is_v2ip # OneIP device
|
|
118
|
+
device.is_video_matrix # video matrix
|
|
119
|
+
device.is_audio_matrix # audio-only matrix
|
|
120
|
+
device.is_amp # audio amplifier
|
|
121
|
+
device.is_oneip_tx # OneIP transmitter
|
|
122
|
+
device.is_oneip_rx # OneIP receiver
|
|
123
|
+
device.is_oneip_tz # OneIP transceiver
|
|
124
|
+
device.is_oneip_multiviewer # OneIP multiviewer
|
|
125
|
+
|
|
126
|
+
# iterate bays
|
|
127
|
+
for port, bay in device.bays.items():
|
|
128
|
+
print(bay)
|
|
129
|
+
for name, bay in device.inputs.items():
|
|
130
|
+
print(f"Input: {name}")
|
|
131
|
+
for name, bay in device.outputs.items():
|
|
132
|
+
print(f"Output: {name}")
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Bay
|
|
136
|
+
|
|
137
|
+
A `BayBase` represents a single input or output on a device (e.g. "Input 1", "Output 3").
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
bay.bay_name # port name (e.g. "Input 1")
|
|
141
|
+
bay.user_name # user-assigned name
|
|
142
|
+
bay.is_input # True if source/input
|
|
143
|
+
bay.is_output # True if sink/output
|
|
144
|
+
bay.is_hdmi # True if HDMI
|
|
145
|
+
bay.is_audio # True if audio-only
|
|
146
|
+
bay.is_hdbaset # True if HDBaseT
|
|
147
|
+
bay.signal_detected # video/audio signal present
|
|
148
|
+
bay.power_status # PowerStatus enum (ON, OFF, UNKNOWN)
|
|
149
|
+
bay.faulty # fault detected
|
|
150
|
+
bay.hidden # hidden from UI
|
|
151
|
+
bay.online # device is online
|
|
152
|
+
bay.features # BayFeaturesMask
|
|
153
|
+
bay.status # DeviceStatus enum
|
|
154
|
+
|
|
155
|
+
# video/audio routing (output bays)
|
|
156
|
+
bay.video_source # currently selected video source bay
|
|
157
|
+
bay.audio_source # currently selected audio source bay
|
|
158
|
+
bay.available_video_sources # list of selectable video sources
|
|
159
|
+
bay.available_audio_sources # list of selectable audio sources
|
|
160
|
+
|
|
161
|
+
# volume (bays with volume control)
|
|
162
|
+
bay.volume # current volume percentage (or None)
|
|
163
|
+
bay.muted # True if muted (or None)
|
|
164
|
+
|
|
165
|
+
# EDID and remote control (input bays)
|
|
166
|
+
bay.edid_profile # EdidProfile enum
|
|
167
|
+
bay.rc_type # RCType enum (IR, CEC, Sky, TiVo, etc.)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Callbacks
|
|
171
|
+
|
|
172
|
+
Subclass `MxrCallbacks` to receive notifications when device or bay state changes:
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
class MyCallbacks(mx_remote.MxrCallbacks):
|
|
176
|
+
def on_device_config_complete(self, dev):
|
|
177
|
+
print(f"Device ready: {dev.serial} ({dev.name})")
|
|
178
|
+
|
|
179
|
+
def on_bay_registered(self, bay):
|
|
180
|
+
print(f"Bay found: {bay.bay_label}")
|
|
181
|
+
|
|
182
|
+
def on_video_source_changed(self, bay, video_source):
|
|
183
|
+
print(f"{bay.user_name} video source -> {video_source.user_name}")
|
|
184
|
+
|
|
185
|
+
def on_audio_source_changed(self, bay, audio_source):
|
|
186
|
+
print(f"{bay.user_name} audio source -> {audio_source.user_name}")
|
|
187
|
+
|
|
188
|
+
def on_volume_changed(self, bay, volume):
|
|
189
|
+
print(f"{bay.user_name} volume: {volume}")
|
|
190
|
+
|
|
191
|
+
def on_power_changed(self, bay, power):
|
|
192
|
+
print(f"{bay.user_name} power: {power}")
|
|
193
|
+
|
|
194
|
+
def on_device_online_status_changed(self, dev, online):
|
|
195
|
+
print(f"{dev.serial} {'online' if online else 'offline'}")
|
|
196
|
+
|
|
197
|
+
mx = mx_remote.Remote(callbacks=MyCallbacks())
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Available callback methods:
|
|
201
|
+
|
|
202
|
+
| Method | Trigger |
|
|
203
|
+
|---|---|
|
|
204
|
+
| `on_device_update` | any device property changed |
|
|
205
|
+
| `on_bay_update` | any bay property changed |
|
|
206
|
+
| `on_device_config_changed` | device configuration updated |
|
|
207
|
+
| `on_device_config_complete` | all device configuration received |
|
|
208
|
+
| `on_device_online_status_changed` | device went online/offline |
|
|
209
|
+
| `on_device_temperature_changed` | temperature readings changed |
|
|
210
|
+
| `on_bay_registered` | new bay discovered |
|
|
211
|
+
| `on_video_source_changed` | video routing changed |
|
|
212
|
+
| `on_audio_source_changed` | audio routing changed |
|
|
213
|
+
| `on_volume_changed` | volume or mute status changed |
|
|
214
|
+
| `on_power_changed` | CEC power status changed |
|
|
215
|
+
| `on_name_changed` | user-assigned bay name changed |
|
|
216
|
+
| `on_status_signal_detected_changed` | signal detect status changed |
|
|
217
|
+
| `on_status_faulty_changed` | fault status changed |
|
|
218
|
+
| `on_status_hidden_changed` | hidden status changed |
|
|
219
|
+
| `on_status_poe_powered_changed` | PoE power status changed |
|
|
220
|
+
| `on_status_hdbt_connected_changed` | HDBaseT link status changed |
|
|
221
|
+
| `on_status_signal_type_changed` | signal type changed |
|
|
222
|
+
| `on_status_hpd_detected_changed` | hotplug detect changed |
|
|
223
|
+
| `on_status_cec_detected_changed` | CEC device detected/lost |
|
|
224
|
+
| `on_status_arc_changed` | audio return channel status changed |
|
|
225
|
+
| `on_key_pressed` | remote control key press received |
|
|
226
|
+
| `on_action_received` | remote control action received |
|
|
227
|
+
| `on_bay_linked` | virtual link created |
|
|
228
|
+
| `on_bay_unlinked` | virtual link removed |
|
|
229
|
+
| `on_mirror_status_changed` | bay mirroring changed |
|
|
230
|
+
| `on_filter_status_changed` | bay filtering changed |
|
|
231
|
+
| `on_edid_profile_changed` | EDID profile changed |
|
|
232
|
+
| `on_rc_type_changed` | remote control type changed |
|
|
233
|
+
| `on_amp_zone_settings_changed` | amplifier zone settings changed |
|
|
234
|
+
| `on_amp_dolby_settings_changed` | amplifier Dolby settings changed |
|
|
235
|
+
|
|
236
|
+
You can also register per-device and per-bay callbacks:
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
def on_device_changed(device):
|
|
240
|
+
print(f"{device.serial} updated")
|
|
241
|
+
|
|
242
|
+
def on_bay_changed(bay):
|
|
243
|
+
print(f"{bay.bay_label} updated")
|
|
244
|
+
|
|
245
|
+
device.register_callback(on_device_changed)
|
|
246
|
+
bay.register_callback(on_bay_changed)
|
|
247
|
+
|
|
248
|
+
# to unregister:
|
|
249
|
+
device.unregister_callback(on_device_changed)
|
|
250
|
+
bay.unregister_callback(on_bay_changed)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Video and Audio Routing
|
|
254
|
+
|
|
255
|
+
Change video and audio sources on output bays:
|
|
256
|
+
|
|
257
|
+
```python
|
|
258
|
+
output = device.get_by_portname("Output 1")
|
|
259
|
+
|
|
260
|
+
# switch video source by port number
|
|
261
|
+
await output.select_video_source(port=0)
|
|
262
|
+
|
|
263
|
+
# switch video source by user-assigned name
|
|
264
|
+
await output.select_video_source_by_user_name("Blu-ray")
|
|
265
|
+
|
|
266
|
+
# switch audio source
|
|
267
|
+
await output.select_audio_source(source=0)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Volume Control
|
|
271
|
+
|
|
272
|
+
```python
|
|
273
|
+
bay.volume_up()
|
|
274
|
+
bay.volume_down()
|
|
275
|
+
bay.volume_set(volume=50) # set to 50%
|
|
276
|
+
bay.volume_set(volume=50, muted=False)
|
|
277
|
+
bay.mute_set(mute=True)
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Remote Control
|
|
281
|
+
|
|
282
|
+
Send remote control key presses and actions:
|
|
283
|
+
|
|
284
|
+
```python
|
|
285
|
+
from mx_remote import RCKey, RCAction
|
|
286
|
+
|
|
287
|
+
# send a key press
|
|
288
|
+
await bay.send_key(RCKey.KEY_SELECT)
|
|
289
|
+
await bay.send_key(RCKey.KEY_UP)
|
|
290
|
+
|
|
291
|
+
# send a remote control action
|
|
292
|
+
await bay.tx_action(RCAction.ACTION_POWER_ON)
|
|
293
|
+
await bay.tx_action(RCAction.ACTION_POWER_OFF)
|
|
294
|
+
await bay.tx_action(RCAction.ACTION_POWER_TOGGLE)
|
|
295
|
+
await bay.tx_action(RCAction.ACTION_VOLUME_UP)
|
|
296
|
+
await bay.tx_action(RCAction.ACTION_VOLUME_DOWN)
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## EDID Profiles
|
|
300
|
+
|
|
301
|
+
Change the EDID profile on input bays:
|
|
302
|
+
|
|
303
|
+
```python
|
|
304
|
+
from mx_remote import EdidProfile
|
|
305
|
+
|
|
306
|
+
await bay.select_edid_profile(EdidProfile.TEMPLATE_1080P_STEREO)
|
|
307
|
+
await bay.select_edid_profile(EdidProfile.TEMPLATE_4K_HDR_7_1)
|
|
308
|
+
await bay.select_edid_profile(EdidProfile.LOWEST_COMMON_DENOMINATOR)
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Bay Visibility
|
|
312
|
+
|
|
313
|
+
Hide or show bays:
|
|
314
|
+
|
|
315
|
+
```python
|
|
316
|
+
await bay.set_hidden(True) # hide
|
|
317
|
+
await bay.set_hidden(False) # show
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Bay Naming
|
|
321
|
+
|
|
322
|
+
```python
|
|
323
|
+
await bay.set_name("Living Room TV")
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Device Management
|
|
327
|
+
|
|
328
|
+
```python
|
|
329
|
+
# reboot a device
|
|
330
|
+
await device.reboot()
|
|
331
|
+
|
|
332
|
+
# read the device log
|
|
333
|
+
log = await device.get_log()
|
|
334
|
+
|
|
335
|
+
# call an HTTP API endpoint on the device
|
|
336
|
+
result = await device.get_api("system/status")
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## OneIP (V2IP) Devices
|
|
340
|
+
|
|
341
|
+
OneIP devices expose additional streaming properties:
|
|
342
|
+
|
|
343
|
+
```python
|
|
344
|
+
# V2IP stream source addresses
|
|
345
|
+
if device.is_v2ip and device.v2ip_sources:
|
|
346
|
+
for source in device.v2ip_sources:
|
|
347
|
+
print(f"Video: {source.video.ip}:{source.video.port}")
|
|
348
|
+
print(f"Audio: {source.audio.ip}:{source.audio.port}")
|
|
349
|
+
|
|
350
|
+
# V2IP device details (encoder/decoder config)
|
|
351
|
+
if device.v2ip_details:
|
|
352
|
+
details = device.v2ip_details
|
|
353
|
+
print(f"Video: {details.video}")
|
|
354
|
+
print(f"TX rate: {details.tx_rate}")
|
|
355
|
+
|
|
356
|
+
# V2IP statistics
|
|
357
|
+
await device.read_stats(enable=True) # start collecting
|
|
358
|
+
# ... later ...
|
|
359
|
+
stats = device.v2ip_stats
|
|
360
|
+
|
|
361
|
+
# mesh operations
|
|
362
|
+
await device.mesh_promote() # promote to mesh master
|
|
363
|
+
await device.mesh_remove() # remove from mesh
|
|
364
|
+
|
|
365
|
+
# firmware versions
|
|
366
|
+
if device.v2ip_firmware_versions:
|
|
367
|
+
for fw_type, fw in device.v2ip_firmware_versions.items():
|
|
368
|
+
print(f"{fw_type}: {fw.version}")
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## OneIP Multiviewer
|
|
372
|
+
|
|
373
|
+
Control multiviewer-specific settings:
|
|
374
|
+
|
|
375
|
+
```python
|
|
376
|
+
from mx_remote import (
|
|
377
|
+
MultiviewerViewMode,
|
|
378
|
+
MultiviewerSource,
|
|
379
|
+
MultiviewerEDIDTemplate,
|
|
380
|
+
MultiviewerPipSize,
|
|
381
|
+
MultiviewerPipPosition,
|
|
382
|
+
MultiviewerAspectRatio,
|
|
383
|
+
MultiviewerOutputMode,
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
mv = device.multiviewer
|
|
387
|
+
|
|
388
|
+
# view mode
|
|
389
|
+
await mv.set_view_mode(MultiviewerViewMode.QUAD)
|
|
390
|
+
|
|
391
|
+
# video sources per screen
|
|
392
|
+
await mv.set_video_source(screen=0, source=MultiviewerSource.INPUT_1)
|
|
393
|
+
|
|
394
|
+
# audio
|
|
395
|
+
await mv.set_audio_source(source=MultiviewerSource.INPUT_1)
|
|
396
|
+
await mv.set_audio_volume(volume=80, muted=False)
|
|
397
|
+
|
|
398
|
+
# picture-in-picture
|
|
399
|
+
await mv.set_pip_size(MultiviewerPipSize.MEDIUM)
|
|
400
|
+
await mv.set_pip_position(MultiviewerPipPosition.BOTTOM_RIGHT)
|
|
401
|
+
|
|
402
|
+
# output settings
|
|
403
|
+
await mv.set_screen_aspect(MultiviewerAspectRatio.AR_16_9)
|
|
404
|
+
await mv.set_output_mode(MultiviewerOutputMode.MODE_1080P_60)
|
|
405
|
+
await mv.set_edid_template(MultiviewerEDIDTemplate.TEMPLATE_1080P)
|
|
406
|
+
|
|
407
|
+
# auto switching and HDCP
|
|
408
|
+
await mv.set_auto_switch(enable=True)
|
|
409
|
+
await mv.set_hdcp_mode(MultiviewerHDCPMode.AUTO)
|
|
410
|
+
|
|
411
|
+
# source mapping
|
|
412
|
+
await mv.set_connected_source(input=0, source=some_device_uid)
|
|
413
|
+
await mv.auto_route()
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## Network Status
|
|
417
|
+
|
|
418
|
+
Inspect network port details on supported devices:
|
|
419
|
+
|
|
420
|
+
```python
|
|
421
|
+
for port_id, port_status in device.network_status.items():
|
|
422
|
+
print(f"Port {port_status.name}: {port_status.link_speed} "
|
|
423
|
+
f"{'full' if port_status.link_full_duplex else 'half'} duplex")
|
|
424
|
+
if port_status.ip:
|
|
425
|
+
print(f" IP: {port_status.ip}")
|
|
426
|
+
if port_status.mac_address:
|
|
427
|
+
print(f" MAC: {port_status.mac_address}")
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
## Configuration Updates
|
|
431
|
+
|
|
432
|
+
Update connection settings at runtime:
|
|
433
|
+
|
|
434
|
+
```python
|
|
435
|
+
await mx.update_config(
|
|
436
|
+
target_ip="10.8.8.255",
|
|
437
|
+
port=8811,
|
|
438
|
+
local_ip="192.168.1.100",
|
|
439
|
+
broadcast=True,
|
|
440
|
+
callbacks=MyCallbacks(),
|
|
441
|
+
name="My Application",
|
|
442
|
+
)
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
## CLI Application
|
|
446
|
+
|
|
447
|
+
The `mxr` console application is installed with the package. It discovers devices and logs all received frames in human-readable form.
|
|
448
|
+
|
|
449
|
+
```
|
|
450
|
+
usage: mxr [-h] [-i INPUT] [-f FILTER] [-o OUTPUT] [-l LOCAL_IP] [-b]
|
|
451
|
+
|
|
452
|
+
MX Remote Manager / Debugger
|
|
453
|
+
|
|
454
|
+
options:
|
|
455
|
+
-h, --help show this help message and exit
|
|
456
|
+
-i INPUT capture file to process
|
|
457
|
+
-f FILTER only log frames from this ip address
|
|
458
|
+
-o OUTPUT write output to a file
|
|
459
|
+
-l LOCAL_IP local ip address of the network interface to use
|
|
460
|
+
-b use broadcast mode instead of multicast
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Examples
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
# discover devices and log frames to console
|
|
467
|
+
mxr
|
|
468
|
+
|
|
469
|
+
# bind to a specific network interface
|
|
470
|
+
mxr -l 192.168.1.100
|
|
471
|
+
|
|
472
|
+
# use broadcast mode
|
|
473
|
+
mxr -b
|
|
474
|
+
|
|
475
|
+
# log output to a file
|
|
476
|
+
mxr -o /path/to/output.txt
|
|
477
|
+
|
|
478
|
+
# process a capture file from MatrixOS
|
|
479
|
+
mxr -i /path/to/capture.bin
|
|
480
|
+
|
|
481
|
+
# process a capture file, filtering by IP address
|
|
482
|
+
mxr -i /path/to/capture.bin -f 10.8.8.1
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
## Programmatic Capture Processing
|
|
486
|
+
|
|
487
|
+
Process captured frames without a network connection:
|
|
488
|
+
|
|
489
|
+
```python
|
|
490
|
+
import mx_remote
|
|
491
|
+
|
|
492
|
+
mx_remote.proto_parser(
|
|
493
|
+
logger=my_logger,
|
|
494
|
+
file="/path/to/capture.bin",
|
|
495
|
+
filter="10.8.8.1", # optional IP filter
|
|
496
|
+
)
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
## API Documentation
|
|
500
|
+
|
|
501
|
+
Documentation is embedded in the Python code via docstrings. Most IDEs will display it automatically.
|
|
502
|
+
|
|
503
|
+
You can also use Python to browse the documentation:
|
|
504
|
+
|
|
505
|
+
```python
|
|
506
|
+
import mx_remote
|
|
507
|
+
help(mx_remote.Remote)
|
|
508
|
+
help(mx_remote.BayBase)
|
|
509
|
+
help(mx_remote.DeviceBase)
|
|
510
|
+
help(mx_remote.MxrCallbacks)
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
## License
|
|
514
|
+
|
|
515
|
+
BSD 3-Clause License. See [LICENSE](LICENSE) for details.
|