mx-remote 6.0.0__tar.gz → 6.2.0__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-6.0.0 → mx_remote-6.2.0}/PKG-INFO +1 -1
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/oneip.md +7 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/Interface.py +4 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/Interface.pyi +2 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/const.py +1 -1
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameMeshOperation.py +11 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameMeshOperation.pyi +3 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Device.py +25 -1
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Device.pyi +2 -1
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/mesh.py +38 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/.gitignore +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/AGENTS.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/CLAUDE.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/LICENSE +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/README.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/README.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/_static/brand.css +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/_static/favicon.svg +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/_static/logo-dark.svg +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/_static/logo.svg +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/api.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/audio.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/callbacks.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/conf.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/configuration.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/devices-and-bays.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/diagnostics.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/index.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/multiviewer.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/requirements.txt +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/routing.md +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/hatch_build.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/Uid.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/Uid.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/__init__.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/__init__.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/compat.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/compat.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/const.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/deprecated.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/deprecated.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/main.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/main.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/BayConfig.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/BayConfig.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Constants.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Constants.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Data.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Data.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Factory.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Factory.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAmpDolbySettings.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAmpDolbySettings.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAmpZoneSettings.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAmpZoneSettings.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAudioClip.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAudioClip.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAudioSetRoute.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAudioSetRoute.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBase.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBase.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayConfig.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayConfig.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayConfigSecondary.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayConfigSecondary.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayHide.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayHide.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayStatus.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayStatus.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameConnectStatus.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameConnectStatus.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameDebug.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameDebug.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameDiscover.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameDiscover.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameEDID.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameEDID.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameEDIDProfile.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameEDIDProfile.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameFactoryReset.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameFactoryReset.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameFilterStatus.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameFilterStatus.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameFirmwareVersion.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameFirmwareVersion.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameHeader.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameHeader.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameHello.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameHello.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameLinks.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameLinks.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameMirrorStatus.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameMirrorStatus.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameMonitoringPulse.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameMonitoringPulse.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameNetworkStatus.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameNetworkStatus.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FramePing.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FramePing.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FramePowerChange.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FramePowerChange.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCAction.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCAction.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCIr.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCIr.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCKey.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCKey.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCSettings.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCSettings.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameReboot.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameReboot.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRoutingChange.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRoutingChange.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetInstaller.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetInstaller.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetName.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetName.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetRoute.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetRoute.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetupStatus.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetupStatus.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSignalStatus.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSignalStatus.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSignalStatusNew.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSignalStatusNew.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSysTemperature.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSysTemperature.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSystemStatus.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSystemStatus.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTXRCAction.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTXRCAction.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTXRCKey.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTXRCKey.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTime.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTime.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTimeZone.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTimeZone.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTopology.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTopology.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTxIR.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTxIR.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameUpgradeFPGA.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameUpgradeFPGA.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPAudio.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPAudio.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPBayMapping.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPBayMapping.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPDetectBays.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPDetectBays.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPDeviceConfiguration.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPDeviceConfiguration.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPLink.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPLink.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPManualSourceSwitch.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPManualSourceSwitch.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPMultiviewer.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPMultiviewer.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPPowerSave.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPPowerSave.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSetMaster.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSetMaster.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSettingsAll.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSettingsAll.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSourceSwitch.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSourceSwitch.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSources.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSources.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPStats.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPStats.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPTestcard.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPTestcard.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPTiling.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPTiling.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPVideoWall.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPVideoWall.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolume.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolume.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolumeDown.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolumeDown.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolumeSet.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolumeSet.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolumeUp.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolumeUp.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/LinkConfig.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/LinkConfig.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Multiviewer.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Multiviewer.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Svd.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Svd.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/V2IPConfig.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/V2IPConfig.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/V2IPStats.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/V2IPStats.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/__init__.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/__init__.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/svd.csv +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/py.typed +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Bay.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Bay.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/ConnectionAsync.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/ConnectionAsync.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Link.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Link.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Remote.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Remote.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/State.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/State.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/V2IP.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/V2IP.pyi +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/pyproject.toml +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/audio_ir.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/audiolock.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/capture.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/complete.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/deprecated.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/e2e.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/entry.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/handlers.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/handlers_cover.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/hello.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/idempotent.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/lengths.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/merge.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/newops.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/offline.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/offsets.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/ping.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/proto_stamp.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/protogate.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/rcsettings.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/roundtrip.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/run.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/smoke.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/sources.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/stats.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/structs.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/txresult.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/unknowns.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/v2ipscaling.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/v2ipsettings.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/v2ipsubject.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/v2iptestcard.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/v2ipvlan.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/vdetails.py +0 -0
- {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/wirefix.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: mx_remote
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.2.0
|
|
4
4
|
Summary: Python 3 library for interfacing with MX Remote compatible devices
|
|
5
5
|
Project-URL: Homepage, https://github.com/opdenkamp/mx-remote/
|
|
6
6
|
Project-URL: Documentation, https://opdenkamp.github.io/mx-remote/
|
|
@@ -308,6 +308,7 @@ itself, a profile out of range, or a schedule time that is not a time of day.
|
|
|
308
308
|
# mesh operations
|
|
309
309
|
await device.mesh_promote() # promote to mesh master
|
|
310
310
|
await device.mesh_remove() # remove from mesh
|
|
311
|
+
await source.auto_assign_oneip_source_addresses() # drop addresses set by hand
|
|
311
312
|
|
|
312
313
|
# firmware versions
|
|
313
314
|
if device.oneip_firmware_versions:
|
|
@@ -315,6 +316,12 @@ if device.oneip_firmware_versions:
|
|
|
315
316
|
print(f"{fw_type}: {fw.version}")
|
|
316
317
|
```
|
|
317
318
|
|
|
319
|
+
A OneIP source acts on `auto_assign_oneip_source_addresses()` only from
|
|
320
|
+
management, which this client announces itself as, and nothing acknowledges it:
|
|
321
|
+
the source's next configuration report carries the addresses it ends up with, in
|
|
322
|
+
`oneip_details`. A device that is not a source, or announces less than protocol
|
|
323
|
+
0x2B, would ignore the operation, so it is refused before anything is sent.
|
|
324
|
+
|
|
318
325
|
### Time zone and time
|
|
319
326
|
|
|
320
327
|
The mesh controller announces its time zone and clock with every periodic
|
|
@@ -2804,6 +2804,10 @@ class DeviceBase(ABC):
|
|
|
2804
2804
|
async def mesh_promote(self) -> bool:
|
|
2805
2805
|
'''promote to mesh master'''
|
|
2806
2806
|
|
|
2807
|
+
@abstractmethod
|
|
2808
|
+
async def auto_assign_oneip_source_addresses(self) -> bool:
|
|
2809
|
+
'''hand this OneIP source's stream addresses back to automatic assignment'''
|
|
2810
|
+
|
|
2807
2811
|
@abstractmethod
|
|
2808
2812
|
async def mesh_remove(self) -> bool:
|
|
2809
2813
|
'''remove from mesh'''
|
|
@@ -1059,6 +1059,8 @@ class DeviceBase(ABC):
|
|
|
1059
1059
|
@abstractmethod
|
|
1060
1060
|
async def mesh_promote(self) -> bool: ...
|
|
1061
1061
|
@abstractmethod
|
|
1062
|
+
async def auto_assign_oneip_source_addresses(self) -> bool: ...
|
|
1063
|
+
@abstractmethod
|
|
1062
1064
|
async def mesh_remove(self) -> bool: ...
|
|
1063
1065
|
@abstractmethod
|
|
1064
1066
|
async def read_stats(self, enable: bool) -> bool: ...
|
|
@@ -22,6 +22,8 @@ class MeshOperation(IntEnum):
|
|
|
22
22
|
REGENERATE_ADDRESSES = 3
|
|
23
23
|
REPORT_CONTROLLER = 4
|
|
24
24
|
PROMOTE_CONTROLLER = 5
|
|
25
|
+
AUTO_ADDRESSES = 6
|
|
26
|
+
'''Hand the target's source addresses back to automatic assignment.'''
|
|
25
27
|
REPORT_MEMBERSHIP = 0xFF
|
|
26
28
|
|
|
27
29
|
def __str__(self) -> str:
|
|
@@ -37,6 +39,8 @@ class MeshOperation(IntEnum):
|
|
|
37
39
|
return "report controller"
|
|
38
40
|
if self.value == MeshOperation.PROMOTE_CONTROLLER.value:
|
|
39
41
|
return "promote controller"
|
|
42
|
+
if self.value == MeshOperation.AUTO_ADDRESSES.value:
|
|
43
|
+
return "automatic addresses"
|
|
40
44
|
if self.value == MeshOperation.REPORT_MEMBERSHIP.value:
|
|
41
45
|
return "report membership"
|
|
42
46
|
return "unknown"
|
|
@@ -66,6 +70,13 @@ _WIRE_SIZE = 40
|
|
|
66
70
|
_ACCEPT_PROTOCOL = 0x1A
|
|
67
71
|
_INSTALLER_PROTOCOL = 0x1D
|
|
68
72
|
|
|
73
|
+
AUTO_ADDRESSES_PROTOCOL = 0x2B
|
|
74
|
+
'''The first protocol version whose devices can act on AUTO_ADDRESSES.
|
|
75
|
+
|
|
76
|
+
Not the stamp: that is this opcode's, and a device between the two takes the
|
|
77
|
+
frame and ignores an operation it does not know. Not every device on this
|
|
78
|
+
version has it either, but none below it does.'''
|
|
79
|
+
|
|
69
80
|
class FrameMeshOperation(FrameBase):
|
|
70
81
|
''' Mesh operation '''
|
|
71
82
|
|
|
@@ -11,8 +11,11 @@ class MeshOperation(IntEnum):
|
|
|
11
11
|
REGENERATE_ADDRESSES: int
|
|
12
12
|
REPORT_CONTROLLER: int
|
|
13
13
|
PROMOTE_CONTROLLER: int
|
|
14
|
+
AUTO_ADDRESSES: int
|
|
14
15
|
REPORT_MEMBERSHIP: int
|
|
15
16
|
|
|
17
|
+
AUTO_ADDRESSES_PROTOCOL: int
|
|
18
|
+
|
|
16
19
|
class FrameMeshOperation(FrameBase):
|
|
17
20
|
@staticmethod
|
|
18
21
|
def construct(mxr: DeviceRegistry, operation: MeshOperation, target: DeviceBase, option: DeviceBase | None = None) -> FrameBase | None: ...
|
|
@@ -35,7 +35,7 @@ from ..Interface import (
|
|
|
35
35
|
)
|
|
36
36
|
from ..proto.BayConfig import BayConfig
|
|
37
37
|
from ..proto.FrameHello import FrameHello
|
|
38
|
-
from ..proto.FrameMeshOperation import MeshOperation, FrameMeshOperation
|
|
38
|
+
from ..proto.FrameMeshOperation import AUTO_ADDRESSES_PROTOCOL, MeshOperation, FrameMeshOperation
|
|
39
39
|
from ..proto.FrameV2IPStats import FrameV2IPStats
|
|
40
40
|
from ..proto.FrameNetworkStatus import NetworkPortStatus
|
|
41
41
|
from ..proto.FrameReboot import FrameReboot
|
|
@@ -1057,6 +1057,30 @@ class Device(DeviceBase):
|
|
|
1057
1057
|
return True
|
|
1058
1058
|
return False
|
|
1059
1059
|
|
|
1060
|
+
async def auto_assign_oneip_source_addresses(self) -> bool:
|
|
1061
|
+
'''Hand this OneIP source's stream addresses back to automatic assignment,
|
|
1062
|
+
undoing addresses that were set on it by hand.
|
|
1063
|
+
|
|
1064
|
+
The device takes this only from management, which this client announces
|
|
1065
|
+
itself as. Nothing acknowledges it: the device's next configuration
|
|
1066
|
+
report carries the addresses it ends up with, and oneip_details reads
|
|
1067
|
+
them.
|
|
1068
|
+
|
|
1069
|
+
Refused for a device that is not a OneIP source, and for one below
|
|
1070
|
+
protocol 0x2B, which predates the operation and ignores it.
|
|
1071
|
+
'''
|
|
1072
|
+
if (self.features is None) or (DeviceFeature.ONEIP_SOURCE not in self.features):
|
|
1073
|
+
_LOGGER.warning(f"not handing the addresses of {self} back to automatic assignment: it is not a OneIP source")
|
|
1074
|
+
return False
|
|
1075
|
+
if (self.protocol != 0) and (self.protocol < AUTO_ADDRESSES_PROTOCOL):
|
|
1076
|
+
_LOGGER.warning(f"not handing the addresses of {self} back to automatic assignment: it advertises "
|
|
1077
|
+
f"protocol {self.protocol:02X} and the operation needs {AUTO_ADDRESSES_PROTOCOL:02X}")
|
|
1078
|
+
return False
|
|
1079
|
+
frame = FrameMeshOperation.construct(mxr=self.registry, target=self, operation=MeshOperation.AUTO_ADDRESSES)
|
|
1080
|
+
if (frame is None):
|
|
1081
|
+
return False
|
|
1082
|
+
return self.registry.transmit(frame.frame) == len(frame.frame)
|
|
1083
|
+
|
|
1060
1084
|
async def mesh_remove(self) -> bool:
|
|
1061
1085
|
'''Remove this device from the mesh network.'''
|
|
1062
1086
|
frame = FrameMeshOperation.construct(mxr=self.registry, target=self, operation=MeshOperation.UNREGISTER)
|
|
@@ -7,7 +7,7 @@ from ..proto.Constants import DeviceFeature as DeviceFeature, MXR_PROTOCOL_VERSI
|
|
|
7
7
|
from ..proto.FrameBase import FrameBase as FrameBase
|
|
8
8
|
from ..proto.FrameFirmwareVersion import FirmwareType as FirmwareType, FirmwareVersion as FirmwareVersion
|
|
9
9
|
from ..proto.FrameHello import FrameHello as FrameHello
|
|
10
|
-
from ..proto.FrameMeshOperation import FrameMeshOperation as FrameMeshOperation, MeshOperation as MeshOperation
|
|
10
|
+
from ..proto.FrameMeshOperation import AUTO_ADDRESSES_PROTOCOL as AUTO_ADDRESSES_PROTOCOL, FrameMeshOperation as FrameMeshOperation, MeshOperation as MeshOperation
|
|
11
11
|
from ..proto.FrameNetworkStatus import NetworkPortStatus as NetworkPortStatus
|
|
12
12
|
from ..proto.FramePing import FramePing as FramePing
|
|
13
13
|
from ..proto.FrameReboot import FrameReboot as FrameReboot
|
|
@@ -223,6 +223,7 @@ class Device(DeviceBase):
|
|
|
223
223
|
async def reboot(self) -> bool: ...
|
|
224
224
|
async def ping(self) -> bool: ...
|
|
225
225
|
async def mesh_promote(self) -> bool: ...
|
|
226
|
+
async def auto_assign_oneip_source_addresses(self) -> bool: ...
|
|
226
227
|
async def mesh_remove(self) -> bool: ...
|
|
227
228
|
async def read_stats(self, enable: bool) -> bool: ...
|
|
228
229
|
async def set_oneip_auto_scaling(self, enabled: bool) -> bool: ...
|
|
@@ -20,6 +20,7 @@ import mx_remote
|
|
|
20
20
|
from mx_remote import MxrDeviceUid, OneIPDeviceSetting as S, OneIPDeviceSettings, OneIPPowerSaveSchedule
|
|
21
21
|
from mx_remote.proto.Constants import (ONEIP_IR_PROFILE_MAX, ONEIP_IR_PROFILE_NOT_SET,
|
|
22
22
|
ONEIP_MINUTES_PER_DAY)
|
|
23
|
+
from mx_remote.proto.Constants import MXR_OPCODE_VERSIONS
|
|
23
24
|
from mx_remote.proto.Factory import create_mxr_frame
|
|
24
25
|
|
|
25
26
|
ADDR = ('192.0.2.9', 8812)
|
|
@@ -165,4 +166,41 @@ for ok in (OneIPDeviceSettings(valid=S.IR_PROFILE, ir_profile=ONEIP_IR_PROFILE_M
|
|
|
165
166
|
assert call(mx.set_all_oneip_device_settings(ok)) is True, f'{ok} was refused'
|
|
166
167
|
print('all refused : what every device would ignore is not sent')
|
|
167
168
|
|
|
169
|
+
# -------------------------------------------- a source's automatic addresses
|
|
170
|
+
|
|
171
|
+
# Mesh operation 6 names the source, with the parameter and padding zero, and
|
|
172
|
+
# is stamped as every mesh operation is.
|
|
173
|
+
def device(uid, protocol, features, serial):
|
|
174
|
+
rx_from(uid, 0x00, struct.pack('<H', protocol) + name('OneIP') + name(serial) + name('5.0.0')
|
|
175
|
+
+ struct.pack('<I', int(features)), protocol=protocol)
|
|
176
|
+
return mx.get_by_uid(MxrDeviceUid(uid))
|
|
177
|
+
|
|
178
|
+
def rx_from(uid, opcode, payload, protocol):
|
|
179
|
+
frame = bytearray(create_mxr_frame(uid, opcode, payload))
|
|
180
|
+
frame[2] = protocol
|
|
181
|
+
mx.process_frame(time.time(), bytes(frame), ADDR)
|
|
182
|
+
|
|
183
|
+
SOURCE = mx_remote.DeviceFeature.ONEIP_SOURCE
|
|
184
|
+
src = device(bytes([0x50]) * 16, 0x2B, SOURCE, 'AA0001')
|
|
185
|
+
old = device(bytes([0x51]) * 16, 0x2A, SOURCE, 'AA0002')
|
|
186
|
+
sink_only = device(bytes([0x52]) * 16, 0x2B, mx_remote.DeviceFeature.ONEIP_SINK, 'AA0003')
|
|
187
|
+
|
|
188
|
+
sent.clear()
|
|
189
|
+
assert call(src.auto_assign_oneip_source_addresses()) is True
|
|
190
|
+
frame = sent.pop()
|
|
191
|
+
assert opcode(frame) == 0x3B and frame[2] == MXR_OPCODE_VERSIONS[0x3B], (opcode(frame), frame[2])
|
|
192
|
+
p = frame[24:]
|
|
193
|
+
assert len(p) == 40, 'a receiver drops a mesh operation shorter than 40 bytes'
|
|
194
|
+
assert p[:4] == bytes([6, 0, 0, 0]), p[:4].hex()
|
|
195
|
+
assert p[4:20] == bytes([0x50]) * 16, 'the frame names another device'
|
|
196
|
+
assert p[20:] == bytes(20), 'the parameter and padding'
|
|
197
|
+
|
|
198
|
+
refused(old.auto_assign_oneip_source_addresses(), 'a source below 0x2B, which ignores the operation')
|
|
199
|
+
refused(sink_only.auto_assign_oneip_source_addresses(), 'a device that is not a source')
|
|
200
|
+
|
|
201
|
+
mx.transmit = lambda data: 0
|
|
202
|
+
assert call(src.auto_assign_oneip_source_addresses()) is False, 'a failed send reported success'
|
|
203
|
+
mx.transmit = lambda data: (sent.append(data), len(data))[1]
|
|
204
|
+
print('auto addrs : mesh operation 6 to a source on 0x2B; anything else is refused')
|
|
205
|
+
|
|
168
206
|
print('ALL OK')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|