mx-remote 9.0.0__tar.gz → 9.1.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-9.0.0 → mx_remote-9.1.0}/PKG-INFO +1 -1
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/api.md +17 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/oneip.md +25 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/Interface.py +52 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/Interface.pyi +15 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/Uid.py +11 -8
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/const.py +1 -1
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/Constants.py +19 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/Constants.pyi +11 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPDeviceConfiguration.py +66 -6
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPDeviceConfiguration.pyi +8 -2
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPSources.py +5 -6
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/Bay.py +2 -1
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/Device.py +51 -1
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/Device.pyi +6 -2
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/Remote.py +43 -16
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/complete.py +12 -0
- mx_remote-9.1.0/tests/downmix.py +124 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/run.py +2 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/staterequest.py +64 -0
- mx_remote-9.1.0/tests/uid.py +50 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/.gitignore +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/AGENTS.md +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/CLAUDE.md +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/LICENSE +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/README.md +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/README.md +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/_static/brand.css +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/_static/favicon.svg +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/_static/logo-dark.svg +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/_static/logo.svg +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/audio.md +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/callbacks.md +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/conf.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/configuration.md +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/devices-and-bays.md +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/diagnostics.md +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/index.md +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/multiviewer.md +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/requirements.txt +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/docs/routing.md +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/hatch_build.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/Uid.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/__init__.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/__init__.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/compat.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/compat.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/const.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/deprecated.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/deprecated.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/main.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/main.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/BayConfig.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/BayConfig.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/Data.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/Data.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/Factory.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/Factory.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameAmpDolbySettings.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameAmpDolbySettings.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameAmpZoneSettings.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameAmpZoneSettings.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameAudioClip.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameAudioClip.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameAudioSetRoute.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameAudioSetRoute.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameBase.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameBase.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameBayConfig.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameBayConfig.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameBayConfigSecondary.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameBayConfigSecondary.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameBayContent.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameBayContent.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameBayHide.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameBayHide.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameBayStatus.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameBayStatus.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameConnectStatus.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameConnectStatus.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameDebug.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameDebug.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameDiscover.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameDiscover.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameEDID.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameEDID.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameEDIDProfile.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameEDIDProfile.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameFactoryReset.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameFactoryReset.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameFilterStatus.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameFilterStatus.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameFirmwareVersion.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameFirmwareVersion.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameHeader.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameHeader.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameHello.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameHello.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameLinks.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameLinks.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameMeshOperation.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameMeshOperation.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameMirrorStatus.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameMirrorStatus.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameMonitoringPulse.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameMonitoringPulse.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameNetworkStatus.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameNetworkStatus.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FramePing.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FramePing.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FramePowerChange.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FramePowerChange.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameRCAction.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameRCAction.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameRCIr.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameRCIr.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameRCKey.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameRCKey.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameRCSettings.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameRCSettings.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameReboot.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameReboot.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameRoutingChange.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameRoutingChange.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSetInstaller.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSetInstaller.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSetName.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSetName.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSetRoute.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSetRoute.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSetupStatus.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSetupStatus.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSignalStatus.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSignalStatus.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSignalStatusNew.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSignalStatusNew.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSysTemperature.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSysTemperature.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSystemStatus.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameSystemStatus.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameTXRCAction.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameTXRCAction.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameTXRCKey.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameTXRCKey.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameTime.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameTime.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameTimeZone.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameTimeZone.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameTopology.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameTopology.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameTxIR.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameTxIR.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameUnitCommand.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameUnitCommand.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameUnitStatus.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameUnitStatus.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameUpgradeFPGA.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameUpgradeFPGA.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPAudio.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPAudio.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPBayMapping.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPBayMapping.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPDetectBays.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPDetectBays.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPLink.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPLink.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPManualSourceSwitch.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPManualSourceSwitch.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPMultiviewer.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPMultiviewer.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPOsdSync.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPOsdSync.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPPowerSave.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPPowerSave.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPPrivacy.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPPrivacy.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPSetMaster.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPSetMaster.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPSettingsAll.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPSettingsAll.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPSinkSdp.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPSinkSdp.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPSourceSwitch.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPSourceSwitch.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPSources.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPStats.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPStats.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPTestcard.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPTestcard.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPTiling.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPTiling.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPVideoWall.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameV2IPVideoWall.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameVolume.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameVolume.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameVolumeDown.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameVolumeDown.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameVolumeSet.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameVolumeSet.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameVolumeUp.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/FrameVolumeUp.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/LinkConfig.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/LinkConfig.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/Multiviewer.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/Multiviewer.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/Svd.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/Svd.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/V2IPConfig.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/V2IPConfig.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/V2IPStats.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/V2IPStats.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/__init__.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/__init__.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/proto/svd.csv +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/py.typed +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/Bay.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/ConnectionAsync.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/ConnectionAsync.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/Link.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/Link.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/OsdSync.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/OsdSync.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/Remote.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/State.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/State.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/V2IP.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/mx_remote/remote/V2IP.pyi +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/pyproject.toml +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/audio_ir.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/audiolock.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/baycontent.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/capture.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/deprecated.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/e2e.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/entry.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/handlers.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/handlers_cover.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/hello.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/idempotent.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/lengths.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/merge.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/mesh.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/meshbays.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/newops.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/offline.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/offsets.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/osdmessage.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/osdsync.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/ping.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/privacy.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/proto_stamp.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/protogate.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/rcsettings.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/roundtrip.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/routes.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/smoke.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/sources.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/stats.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/structs.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/txresult.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/unit.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/unknowns.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/v2ipptp.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/v2ipscaling.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/v2ipsdp.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/v2ipsettings.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/v2ipsubject.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/v2iptestcard.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/v2ipvlan.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/vdetails.py +0 -0
- {mx_remote-9.0.0 → mx_remote-9.1.0}/tests/wirefix.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: mx_remote
|
|
3
|
-
Version: 9.
|
|
3
|
+
Version: 9.1.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/
|
|
@@ -168,6 +168,23 @@ bit, and the range of the infrared profiles.
|
|
|
168
168
|
.. autodata:: mx_remote.proto.Constants.ONEIP_VLAN_ID_MAX
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
+
## OneIP stereo downmix
|
|
172
|
+
|
|
173
|
+
How a device's output mixes 5.1 and 7.1 PCM down to stereo.
|
|
174
|
+
|
|
175
|
+
```{eval-rst}
|
|
176
|
+
.. autoclass:: mx_remote.OneIPDownmix
|
|
177
|
+
:members:
|
|
178
|
+
|
|
179
|
+
.. autoclass:: mx_remote.proto.Constants.OneIPDownmixMode
|
|
180
|
+
:members:
|
|
181
|
+
|
|
182
|
+
.. autoclass:: mx_remote.proto.Constants.OneIPDownmixLevel
|
|
183
|
+
:members:
|
|
184
|
+
|
|
185
|
+
.. autodata:: mx_remote.proto.Constants.ONEIP_DOWNMIX_LFE_MAX
|
|
186
|
+
```
|
|
187
|
+
|
|
171
188
|
## OneIP PTP
|
|
172
189
|
|
|
173
190
|
A device's PTP settings, which it reports and a controller writes, and the PTP
|
|
@@ -318,6 +318,31 @@ if ptp is not None:
|
|
|
318
318
|
print(ptp.grandmaster) # its clock identity, None while there is none
|
|
319
319
|
```
|
|
320
320
|
|
|
321
|
+
### Stereo downmix
|
|
322
|
+
|
|
323
|
+
A device whose output can mix 5.1 and 7.1 PCM down to stereo reports how,
|
|
324
|
+
once its video processor has answered for it: a mode, a level and the percent
|
|
325
|
+
the LFE channel is mixed in at, which a controller writes, and the state and
|
|
326
|
+
channel count, which only the device reports. A device that reports none has
|
|
327
|
+
no downmix to set, so a write to one is refused, as is a mode, level or LFE
|
|
328
|
+
percent out of range. The write sends the mode, level and LFE together; the
|
|
329
|
+
state and channels are never sent.
|
|
330
|
+
|
|
331
|
+
```python
|
|
332
|
+
from mx_remote import OneIPDownmix
|
|
333
|
+
from mx_remote.proto.Constants import OneIPDownmixMode, OneIPDownmixLevel
|
|
334
|
+
|
|
335
|
+
downmix = device.oneip_downmix # None: no report yet, or no downmix
|
|
336
|
+
if downmix is not None:
|
|
337
|
+
print(downmix.mode, downmix.level, downmix.lfe) # LFE up to ONEIP_DOWNMIX_LFE_MAX
|
|
338
|
+
print(downmix.state, downmix.channels) # the device's own
|
|
339
|
+
await device.set_oneip_downmix(OneIPDownmix(mode=OneIPDownmixMode.AUTO,
|
|
340
|
+
level=OneIPDownmixLevel.NORMALISED, lfe=50))
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
The downmix ends the settings block, behind a second valid word, so the write
|
|
344
|
+
runs on to 248 bytes and carries no other setting.
|
|
345
|
+
|
|
321
346
|
### VLAN
|
|
322
347
|
|
|
323
348
|
A device that announces `DeviceFeature.VLAN` tags its uplink by a VLAN
|
|
@@ -2135,6 +2135,46 @@ class OneIPPtpState:
|
|
|
2135
2135
|
return (f"{mode} domain {self.domain} port state {self.port_state} {lock}"
|
|
2136
2136
|
f"{' followed' if self.followed else ''} clock {self.clock_identity.hex(':')} grandmaster {gm}")
|
|
2137
2137
|
|
|
2138
|
+
@dataclass(frozen=True)
|
|
2139
|
+
class OneIPDownmix:
|
|
2140
|
+
"""
|
|
2141
|
+
How a OneIP output mixes 5.1 and 7.1 PCM down to stereo, and whether it
|
|
2142
|
+
does now.
|
|
2143
|
+
|
|
2144
|
+
A device reports it once its video processor has answered for it, so never
|
|
2145
|
+
one whose output cannot mix down.
|
|
2146
|
+
"""
|
|
2147
|
+
mode: OneIPDownmixMode|int = OneIPDownmixMode.OFF
|
|
2148
|
+
"""When the output mixes down; a raw int for a mode this library does not
|
|
2149
|
+
name."""
|
|
2150
|
+
level: OneIPDownmixLevel|int = OneIPDownmixLevel.NORMALISED
|
|
2151
|
+
"""How loud the mix is; a raw int for a level this library does not name."""
|
|
2152
|
+
lfe: int = 0
|
|
2153
|
+
"""The percent the LFE channel is mixed in at, at most
|
|
2154
|
+
ONEIP_DOWNMIX_LFE_MAX; 0 leaves it out."""
|
|
2155
|
+
state: int = 0
|
|
2156
|
+
"""Why the stream is or is not mixed down, as the device's own code. Only
|
|
2157
|
+
the device reports it."""
|
|
2158
|
+
channels: int = 0
|
|
2159
|
+
"""The stream's channels while it is mixed down, else 0. Only the device
|
|
2160
|
+
reports it."""
|
|
2161
|
+
|
|
2162
|
+
def is_valid(self) -> bool:
|
|
2163
|
+
"""Whether the settings a write carries are in range."""
|
|
2164
|
+
return ((OneIPDownmixMode.OFF <= self.mode <= OneIPDownmixMode.ALWAYS)
|
|
2165
|
+
and (OneIPDownmixLevel.NORMALISED <= self.level <= OneIPDownmixLevel.UNSCALED)
|
|
2166
|
+
and (0 <= self.lfe <= ONEIP_DOWNMIX_LFE_MAX))
|
|
2167
|
+
|
|
2168
|
+
def written(self, write:'OneIPDownmix') -> 'OneIPDownmix':
|
|
2169
|
+
"""The settings of write applied to this report, which keeps what only
|
|
2170
|
+
the device reports."""
|
|
2171
|
+
return replace(self, mode=write.mode, level=write.level, lfe=write.lfe)
|
|
2172
|
+
|
|
2173
|
+
def __str__(self) -> str:
|
|
2174
|
+
mode = self.mode.name.lower() if isinstance(self.mode, OneIPDownmixMode) else self.mode
|
|
2175
|
+
level = self.level.name.lower() if isinstance(self.level, OneIPDownmixLevel) else self.level
|
|
2176
|
+
return f"{mode} {level} lfe {self.lfe}% state {self.state} channels {self.channels}"
|
|
2177
|
+
|
|
2138
2178
|
@dataclass(frozen=True)
|
|
2139
2179
|
class OneIPVlan:
|
|
2140
2180
|
"""
|
|
@@ -3239,6 +3279,14 @@ class DeviceBase(ABC):
|
|
|
3239
3279
|
async def confirm_unit_network(self) -> bool:
|
|
3240
3280
|
'''keep the unit's pending IP configuration'''
|
|
3241
3281
|
|
|
3282
|
+
@property
|
|
3283
|
+
@abstractmethod
|
|
3284
|
+
def oneip_downmix(self) -> OneIPDownmix|None:
|
|
3285
|
+
'''How this OneIP device's output mixes down to stereo, as it last
|
|
3286
|
+
reported, None while it reports no downmix: until its video processor
|
|
3287
|
+
has answered for it, and always for one whose output cannot mix
|
|
3288
|
+
down.'''
|
|
3289
|
+
|
|
3242
3290
|
@property
|
|
3243
3291
|
@abstractmethod
|
|
3244
3292
|
def oneip_ptp(self) -> OneIPPtpState|None:
|
|
@@ -3532,6 +3580,10 @@ class DeviceBase(ABC):
|
|
|
3532
3580
|
async def set_oneip_ptp_messages(self, which:OneIPDeviceSetting, messages:OneIPPtpMessages) -> bool:
|
|
3533
3581
|
'''set how the device paces its PTP messages, its SAP timings and its streams' TTL: the values of messages behind the bits of which'''
|
|
3534
3582
|
|
|
3583
|
+
@abstractmethod
|
|
3584
|
+
async def set_oneip_downmix(self, downmix:OneIPDownmix) -> bool:
|
|
3585
|
+
'''set how the device's output mixes down to stereo'''
|
|
3586
|
+
|
|
3535
3587
|
@abstractmethod
|
|
3536
3588
|
async def set_oneip_vlan(self, vlan:OneIPVlan) -> bool:
|
|
3537
3589
|
'''change the device's VLAN configuration'''
|
|
@@ -757,6 +757,16 @@ class OneIPPtpState:
|
|
|
757
757
|
@property
|
|
758
758
|
def grandmaster(self) -> bytes | None: ...
|
|
759
759
|
|
|
760
|
+
@dataclass(frozen=True)
|
|
761
|
+
class OneIPDownmix:
|
|
762
|
+
mode: OneIPDownmixMode | int = ...
|
|
763
|
+
level: OneIPDownmixLevel | int = ...
|
|
764
|
+
lfe: int = ...
|
|
765
|
+
state: int = ...
|
|
766
|
+
channels: int = ...
|
|
767
|
+
def is_valid(self) -> bool: ...
|
|
768
|
+
def written(self, write: OneIPDownmix) -> OneIPDownmix: ...
|
|
769
|
+
|
|
760
770
|
@dataclass(frozen=True)
|
|
761
771
|
class OneIPVlan:
|
|
762
772
|
flags: OneIPVlanFlag = ...
|
|
@@ -1183,6 +1193,9 @@ class DeviceBase(ABC):
|
|
|
1183
1193
|
async def confirm_unit_network(self) -> bool: ...
|
|
1184
1194
|
@property
|
|
1185
1195
|
@abstractmethod
|
|
1196
|
+
def oneip_downmix(self) -> OneIPDownmix | None: ...
|
|
1197
|
+
@property
|
|
1198
|
+
@abstractmethod
|
|
1186
1199
|
def oneip_ptp(self) -> OneIPPtpState | None: ...
|
|
1187
1200
|
@property
|
|
1188
1201
|
@abstractmethod
|
|
@@ -1321,6 +1334,8 @@ class DeviceBase(ABC):
|
|
|
1321
1334
|
@abstractmethod
|
|
1322
1335
|
async def set_oneip_ptp_messages(self, which: OneIPDeviceSetting, messages: OneIPPtpMessages) -> bool: ...
|
|
1323
1336
|
@abstractmethod
|
|
1337
|
+
async def set_oneip_downmix(self, downmix: OneIPDownmix) -> bool: ...
|
|
1338
|
+
@abstractmethod
|
|
1324
1339
|
async def set_oneip_vlan(self, vlan: OneIPVlan) -> bool: ...
|
|
1325
1340
|
@abstractmethod
|
|
1326
1341
|
async def set_audio_endpoint_locked(self, endpoint: int, locked: bool) -> bool: ...
|
|
@@ -14,6 +14,7 @@ class MxrDeviceUid:
|
|
|
14
14
|
|
|
15
15
|
def __init__(self, value: object) -> None:
|
|
16
16
|
self._value:bytes
|
|
17
|
+
self._str:str|None = None
|
|
17
18
|
|
|
18
19
|
if value is None:
|
|
19
20
|
self._value = bytes([ 0 for _ in range(16)])
|
|
@@ -44,11 +45,11 @@ class MxrDeviceUid:
|
|
|
44
45
|
|
|
45
46
|
@property
|
|
46
47
|
def value(self) -> str:
|
|
47
|
-
''' value as human
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
''.join(
|
|
51
|
-
|
|
48
|
+
''' value as human readable string, formatted once, as every hash and
|
|
49
|
+
comparison reads it '''
|
|
50
|
+
if (self._str is None):
|
|
51
|
+
self._str = '.'.join(self._value[i:i + 4][::-1].hex() for i in (0, 4, 8, 12))
|
|
52
|
+
return self._str
|
|
52
53
|
|
|
53
54
|
@property
|
|
54
55
|
def empty(self) -> bool:
|
|
@@ -70,12 +71,14 @@ class MxrDeviceUid:
|
|
|
70
71
|
return str(self)
|
|
71
72
|
|
|
72
73
|
def __eq__(self, value: object) -> bool:
|
|
73
|
-
if isinstance(value,
|
|
74
|
-
return
|
|
74
|
+
if isinstance(value, MxrDeviceUid):
|
|
75
|
+
return self.value == value.value
|
|
76
|
+
if isinstance(value, str):
|
|
77
|
+
return self.value == value
|
|
75
78
|
return False
|
|
76
79
|
|
|
77
80
|
def __hash__(self) -> int:
|
|
78
|
-
return hash(
|
|
81
|
+
return hash(self.value)
|
|
79
82
|
|
|
80
83
|
class MxrBayUidOld:
|
|
81
84
|
'''Legacy bay identifier using serial number and port name.'''
|
|
@@ -609,6 +609,25 @@ class OneIPPowerSaveLevel(IntEnum):
|
|
|
609
609
|
OFF = 3
|
|
610
610
|
'''Everything but the network powers down.'''
|
|
611
611
|
|
|
612
|
+
class OneIPDownmixMode(IntEnum):
|
|
613
|
+
'''When a OneIP output mixes 5.1 and 7.1 PCM down to stereo.'''
|
|
614
|
+
OFF = 0
|
|
615
|
+
'''Never.'''
|
|
616
|
+
AUTO = 1
|
|
617
|
+
'''When the display's EDID lists two PCM channels or fewer.'''
|
|
618
|
+
ALWAYS = 2
|
|
619
|
+
'''Always.'''
|
|
620
|
+
|
|
621
|
+
class OneIPDownmixLevel(IntEnum):
|
|
622
|
+
'''How loud a OneIP output's stereo downmix is.'''
|
|
623
|
+
NORMALISED = 0
|
|
624
|
+
'''Scaled so the mix never clips.'''
|
|
625
|
+
UNSCALED = 1
|
|
626
|
+
'''Unscaled, with dialogue at the level it has in stereo.'''
|
|
627
|
+
|
|
628
|
+
ONEIP_DOWNMIX_LFE_MAX = 100
|
|
629
|
+
"""The largest percent a OneIP output mixes its LFE channel in at."""
|
|
630
|
+
|
|
612
631
|
class UnitPowerSave(IntFlag):
|
|
613
632
|
'''What a unit offers at one power save level.'''
|
|
614
633
|
SUPPORTED = (1 << 0)
|
|
@@ -236,6 +236,17 @@ class OneIPPowerSaveLevel(IntEnum):
|
|
|
236
236
|
LOW: int
|
|
237
237
|
OFF: int
|
|
238
238
|
|
|
239
|
+
class OneIPDownmixMode(IntEnum):
|
|
240
|
+
OFF: int
|
|
241
|
+
AUTO: int
|
|
242
|
+
ALWAYS: int
|
|
243
|
+
|
|
244
|
+
class OneIPDownmixLevel(IntEnum):
|
|
245
|
+
NORMALISED: int
|
|
246
|
+
UNSCALED: int
|
|
247
|
+
|
|
248
|
+
ONEIP_DOWNMIX_LFE_MAX: int
|
|
249
|
+
|
|
239
250
|
class UnitPowerSave(IntFlag):
|
|
240
251
|
SUPPORTED: Incomplete
|
|
241
252
|
INPUT_WAKE: Incomplete
|
|
@@ -14,9 +14,9 @@ from .FrameHeader import FrameHeader
|
|
|
14
14
|
from ..Uid import MxrDeviceUid
|
|
15
15
|
from ..Interface import (DeviceBase, DeviceRegistry, DeviceOneIPDetails, DeviceOneIPScalingSettings,
|
|
16
16
|
DeviceOneIPSink, OneIPAudioFormat, OneIPDeviceSettings, OneIPDscpConfig,
|
|
17
|
-
OneIPPowerSaveSchedule, OneIPPtpMessages, OneIPPtpState,
|
|
18
|
-
OneIPVlan, _wire_enum)
|
|
19
|
-
from .Constants import (ONEIP_DEVICE_SETTINGS_BLOCK, ONEIP_DEVICE_SETTINGS_PTP, OneIPPtpFlag, OneIPPtpLock, OneIPPtpMode, OneIPDeviceSetting, OneIPVideoProcessorFeature, OneIPVlanFlag, MXR_SCALING_FLAG_AUTO_SCALING,
|
|
17
|
+
OneIPDownmix, OneIPPowerSaveSchedule, OneIPPtpMessages, OneIPPtpState,
|
|
18
|
+
OneIPStreamSource, OneIPVlan, _wire_enum)
|
|
19
|
+
from .Constants import (ONEIP_DEVICE_SETTINGS_BLOCK, ONEIP_DEVICE_SETTINGS_PTP, OneIPDownmixLevel, OneIPDownmixMode, OneIPPtpFlag, OneIPPtpLock, OneIPPtpMode, OneIPDeviceSetting, OneIPVideoProcessorFeature, OneIPVlanFlag, MXR_SCALING_FLAG_AUTO_SCALING,
|
|
20
20
|
MXR_SCALING_FLAG_MODE_VALID,
|
|
21
21
|
MXR_SCALING_FLAG_OPTIONS_VALID, MXR_SCALING_FLAG_OPTIONS2_VALID,
|
|
22
22
|
MXR_SCALING_OPTIONS2_SETTINGS, MxrSignalType, oneip_dscp_value,
|
|
@@ -48,13 +48,19 @@ from .V2IPConfig import V2IPStreamSourceImpl, parse_v2ip_av_source
|
|
|
48
48
|
# 216..224 the settings' own block: the PTP announce, sync and delay
|
|
49
49
|
# request intervals as i8, u8 announce timeout, u8 PTP DSCP,
|
|
50
50
|
# u8 SAP expiry in minutes, u16 SAP interval in seconds, and
|
|
51
|
-
# from a device with the stream TTL, u8 TTL
|
|
51
|
+
# from a device with the stream TTL, u8 TTL, a reserved byte,
|
|
52
|
+
# u16 output rotation and u16 rotation step at 224..230, 2
|
|
53
|
+
# reserved
|
|
54
|
+
# 232..248 from a device with the downmix: u32 second valid word, then
|
|
55
|
+
# the downmix's u8 mode, level, LFE percent, state and channels
|
|
56
|
+
# at 236..241, 7 reserved
|
|
52
57
|
#
|
|
53
58
|
# That block is the last of its frame, so it is read by its length: shorter
|
|
54
59
|
# than 8 carries none of its values, and 8, which every device without the TTL
|
|
55
60
|
# sends, carries all but the TTL. A write grows it to 16 only when it carries
|
|
56
|
-
# the TTL
|
|
57
|
-
# predate
|
|
61
|
+
# the TTL or the rotation, and to 32 only for the downmix, so the frames other
|
|
62
|
+
# writes send are unchanged for units that predate them. A block too short to
|
|
63
|
+
# hold the downmix's channels carries no bit of the second valid word.
|
|
58
64
|
#
|
|
59
65
|
# Each of those blocks was appended behind what came before it, leaving every
|
|
60
66
|
# offset ahead of it where it was, so the length is what says whether one is
|
|
@@ -136,6 +142,14 @@ _STREAM_TTL_AT = 8
|
|
|
136
142
|
_SINK_ROTATION_AT = 10
|
|
137
143
|
_SINK_ROTATION_STEP_AT = 12
|
|
138
144
|
_SETTINGS_BLOCK_LONG_SIZE = 16
|
|
145
|
+
_VALID_EXT_OFFSET = SETTINGS_BLOCK_OFFSET + _SETTINGS_BLOCK_LONG_SIZE
|
|
146
|
+
'''The second valid word of the settings, behind the block of their own.'''
|
|
147
|
+
_DOWNMIX_OFFSET = _VALID_EXT_OFFSET + 4
|
|
148
|
+
_DOWNMIX_SIZE = 5
|
|
149
|
+
_WITH_DOWNMIX_SIZE = SETTINGS_BLOCK_OFFSET + 32
|
|
150
|
+
'''The frame a downmix write sends: the settings block run on to 32 bytes.'''
|
|
151
|
+
_SETTING_EXT_DOWNMIX = 1 << 0
|
|
152
|
+
'''The bit of the second valid word that carries the downmix.'''
|
|
139
153
|
|
|
140
154
|
def carries_settings_block(settings:OneIPDeviceSettings) -> bool:
|
|
141
155
|
'''Whether settings carry a value only the block of their own can hold.'''
|
|
@@ -424,6 +438,28 @@ class FrameV2IPDeviceConfiguration(FrameBase):
|
|
|
424
438
|
payload += own_settings_block(settings)
|
|
425
439
|
return FrameBase.construct_base(target=target, mxr=mxr, opcode=_OPCODE, payload=bytes(payload))
|
|
426
440
|
|
|
441
|
+
@staticmethod
|
|
442
|
+
def construct_downmix(mxr:DeviceRegistry, target:Any, target_uid:MxrDeviceUid,
|
|
443
|
+
downmix:OneIPDownmix) -> FrameBase|None:
|
|
444
|
+
'''Build the 0x3C write that changes how a device's output mixes down to
|
|
445
|
+
stereo and nothing else.
|
|
446
|
+
|
|
447
|
+
248 bytes: the frame construct_settings() builds, with a settings block
|
|
448
|
+
that carries no setting, zeroed to 232, then the second valid word
|
|
449
|
+
carrying the downmix and its mode, level and LFE percent at 236..239.
|
|
450
|
+
The state and channels at 239 and 240 are the device's to report, and
|
|
451
|
+
are left 0.
|
|
452
|
+
'''
|
|
453
|
+
frame = FrameV2IPDeviceConfiguration.construct_settings(
|
|
454
|
+
mxr=mxr, target=target, target_uid=target_uid, settings=OneIPDeviceSettings())
|
|
455
|
+
if (frame is None):
|
|
456
|
+
return None
|
|
457
|
+
payload = bytearray(frame.payload or b"")
|
|
458
|
+
payload += bytes(_WITH_DOWNMIX_SIZE - len(payload))
|
|
459
|
+
struct.pack_into('<IBBB', payload, _VALID_EXT_OFFSET, _SETTING_EXT_DOWNMIX,
|
|
460
|
+
int(downmix.mode), int(downmix.level), downmix.lfe)
|
|
461
|
+
return FrameBase.construct_base(target=target, mxr=mxr, opcode=_OPCODE, payload=bytes(payload))
|
|
462
|
+
|
|
427
463
|
@staticmethod
|
|
428
464
|
def construct_vlan(mxr:DeviceRegistry, target:Any, target_uid:MxrDeviceUid,
|
|
429
465
|
vlan:OneIPVlan) -> FrameBase|None:
|
|
@@ -580,6 +616,28 @@ class FrameV2IPDeviceConfiguration(FrameBase):
|
|
|
580
616
|
port_state=port_state, lock=_wire_enum(OneIPPtpLock, lock),
|
|
581
617
|
clock_identity=clock, grandmaster_identity=grandmaster)
|
|
582
618
|
|
|
619
|
+
@property
|
|
620
|
+
def carries_downmix(self) -> bool:
|
|
621
|
+
'''Whether the frame is long enough to say whether it carries a downmix.'''
|
|
622
|
+
return (self.payload is not None) and (len(self.payload) >= (_DOWNMIX_OFFSET + _DOWNMIX_SIZE))
|
|
623
|
+
|
|
624
|
+
@cached_property
|
|
625
|
+
def downmix(self) -> OneIPDownmix|None:
|
|
626
|
+
'''The downmix the frame carries, None when it carries none: in a frame
|
|
627
|
+
too short to hold it, or without its bit of the second valid word.
|
|
628
|
+
|
|
629
|
+
From the subject itself, None reports that it has no downmix; from
|
|
630
|
+
another sender it is a write, of which only the mode, level and LFE
|
|
631
|
+
percent count.'''
|
|
632
|
+
if not self.carries_downmix:
|
|
633
|
+
return None
|
|
634
|
+
p = self.payload or b""
|
|
635
|
+
valid_ext, mode, level, lfe, state, channels = struct.unpack_from('<IBBBBB', p, _VALID_EXT_OFFSET)
|
|
636
|
+
if not (valid_ext & _SETTING_EXT_DOWNMIX):
|
|
637
|
+
return None
|
|
638
|
+
return OneIPDownmix(mode=_wire_enum(OneIPDownmixMode, mode), level=_wire_enum(OneIPDownmixLevel, level),
|
|
639
|
+
lfe=lfe, state=state, channels=channels)
|
|
640
|
+
|
|
583
641
|
def process(self) -> None:
|
|
584
642
|
'''Update the cache of the device this configuration names, not of its sender.'''
|
|
585
643
|
if ((dev := self.subject_device) is None):
|
|
@@ -595,6 +653,8 @@ class FrameV2IPDeviceConfiguration(FrameBase):
|
|
|
595
653
|
dev.on_mxr_update(vlan)
|
|
596
654
|
if ((ptp := self.ptp) is not None):
|
|
597
655
|
dev.on_mxr_update(ptp)
|
|
656
|
+
if self.carries_downmix:
|
|
657
|
+
dev.on_mxr_update(self)
|
|
598
658
|
|
|
599
659
|
def __str__(self) -> str:
|
|
600
660
|
sink_str = f" sink=[{self.sink}]" if (self.sink is not None) else ""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
from ..Interface import DeviceBase as DeviceBase, DeviceOneIPDetails as DeviceOneIPDetails, DeviceOneIPScalingSettings as DeviceOneIPScalingSettings, DeviceOneIPSink as DeviceOneIPSink, DeviceRegistry as DeviceRegistry, OneIPAudioFormat as OneIPAudioFormat, OneIPDeviceSettings as OneIPDeviceSettings, OneIPDscpConfig as OneIPDscpConfig, OneIPPowerSaveSchedule as OneIPPowerSaveSchedule, OneIPPtpMessages as OneIPPtpMessages, OneIPPtpState as OneIPPtpState, OneIPStreamSource as OneIPStreamSource, OneIPVlan as OneIPVlan
|
|
1
|
+
from ..Interface import DeviceBase as DeviceBase, DeviceOneIPDetails as DeviceOneIPDetails, DeviceOneIPScalingSettings as DeviceOneIPScalingSettings, DeviceOneIPSink as DeviceOneIPSink, DeviceRegistry as DeviceRegistry, OneIPAudioFormat as OneIPAudioFormat, OneIPDeviceSettings as OneIPDeviceSettings, OneIPDownmix as OneIPDownmix, OneIPDscpConfig as OneIPDscpConfig, OneIPPowerSaveSchedule as OneIPPowerSaveSchedule, OneIPPtpMessages as OneIPPtpMessages, OneIPPtpState as OneIPPtpState, OneIPStreamSource as OneIPStreamSource, OneIPVlan as OneIPVlan
|
|
2
2
|
from ..Uid import MxrDeviceUid as MxrDeviceUid
|
|
3
|
-
from .Constants import MXR_SCALING_FLAG_AUTO_SCALING as MXR_SCALING_FLAG_AUTO_SCALING, MXR_SCALING_FLAG_MODE_VALID as MXR_SCALING_FLAG_MODE_VALID, MXR_SCALING_FLAG_OPTIONS2_VALID as MXR_SCALING_FLAG_OPTIONS2_VALID, MXR_SCALING_FLAG_OPTIONS_VALID as MXR_SCALING_FLAG_OPTIONS_VALID, MXR_SCALING_OPTIONS2_SETTINGS as MXR_SCALING_OPTIONS2_SETTINGS, MxrSignalType as MxrSignalType, ONEIP_DEVICE_SETTINGS_BLOCK as ONEIP_DEVICE_SETTINGS_BLOCK, ONEIP_DEVICE_SETTINGS_PTP as ONEIP_DEVICE_SETTINGS_PTP, OneIPDeviceSetting as OneIPDeviceSetting, OneIPPtpFlag as OneIPPtpFlag, OneIPPtpLock as OneIPPtpLock, OneIPPtpMode as OneIPPtpMode, OneIPVideoProcessorFeature as OneIPVideoProcessorFeature, OneIPVlanFlag as OneIPVlanFlag, oneip_dscp_value as oneip_dscp_value, oneip_rate_valid as oneip_rate_valid
|
|
3
|
+
from .Constants import MXR_SCALING_FLAG_AUTO_SCALING as MXR_SCALING_FLAG_AUTO_SCALING, MXR_SCALING_FLAG_MODE_VALID as MXR_SCALING_FLAG_MODE_VALID, MXR_SCALING_FLAG_OPTIONS2_VALID as MXR_SCALING_FLAG_OPTIONS2_VALID, MXR_SCALING_FLAG_OPTIONS_VALID as MXR_SCALING_FLAG_OPTIONS_VALID, MXR_SCALING_OPTIONS2_SETTINGS as MXR_SCALING_OPTIONS2_SETTINGS, MxrSignalType as MxrSignalType, ONEIP_DEVICE_SETTINGS_BLOCK as ONEIP_DEVICE_SETTINGS_BLOCK, ONEIP_DEVICE_SETTINGS_PTP as ONEIP_DEVICE_SETTINGS_PTP, OneIPDeviceSetting as OneIPDeviceSetting, OneIPDownmixLevel as OneIPDownmixLevel, OneIPDownmixMode as OneIPDownmixMode, OneIPPtpFlag as OneIPPtpFlag, OneIPPtpLock as OneIPPtpLock, OneIPPtpMode as OneIPPtpMode, OneIPVideoProcessorFeature as OneIPVideoProcessorFeature, OneIPVlanFlag as OneIPVlanFlag, oneip_dscp_value as oneip_dscp_value, oneip_rate_valid as oneip_rate_valid
|
|
4
4
|
from .FrameBase import FrameBase as FrameBase
|
|
5
5
|
from .FrameHeader import FrameHeader as FrameHeader
|
|
6
6
|
from .V2IPConfig import V2IPStreamSourceImpl as V2IPStreamSourceImpl, parse_v2ip_av_source as parse_v2ip_av_source
|
|
@@ -48,6 +48,8 @@ class FrameV2IPDeviceConfiguration(FrameBase):
|
|
|
48
48
|
@staticmethod
|
|
49
49
|
def construct_settings(mxr: DeviceRegistry, target: Any, target_uid: MxrDeviceUid, settings: OneIPDeviceSettings) -> FrameBase | None: ...
|
|
50
50
|
@staticmethod
|
|
51
|
+
def construct_downmix(mxr: DeviceRegistry, target: Any, target_uid: MxrDeviceUid, downmix: OneIPDownmix) -> FrameBase | None: ...
|
|
52
|
+
@staticmethod
|
|
51
53
|
def construct_vlan(mxr: DeviceRegistry, target: Any, target_uid: MxrDeviceUid, vlan: OneIPVlan) -> FrameBase | None: ...
|
|
52
54
|
@property
|
|
53
55
|
def target_uid(self) -> MxrDeviceUid | None: ...
|
|
@@ -67,4 +69,8 @@ class FrameV2IPDeviceConfiguration(FrameBase):
|
|
|
67
69
|
def vlan(self) -> OneIPVlan | None: ...
|
|
68
70
|
@cached_property
|
|
69
71
|
def ptp(self) -> OneIPPtpState | None: ...
|
|
72
|
+
@property
|
|
73
|
+
def carries_downmix(self) -> bool: ...
|
|
74
|
+
@cached_property
|
|
75
|
+
def downmix(self) -> OneIPDownmix | None: ...
|
|
70
76
|
def process(self) -> None: ...
|
|
@@ -26,9 +26,10 @@ class FrameV2IPSources(FrameBase):
|
|
|
26
26
|
that list was when the frame was built. None when the payload is neither
|
|
27
27
|
form this opcode carries.
|
|
28
28
|
|
|
29
|
-
A list that fits one frame is sent as bare records from the first byte
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
A list that fits one frame is sent as bare records from the first byte,
|
|
30
|
+
and a unit that knows no source sends it with none. A longer one is
|
|
31
|
+
split into pages, each behind a header. That header is not a whole
|
|
32
|
+
record, so the remainder separates the two forms - and a
|
|
32
33
|
payload that is neither is refused rather than read from byte zero,
|
|
33
34
|
which would shift every record by the header's width and report a full
|
|
34
35
|
set of plausible addresses belonging to no bay.
|
|
@@ -37,9 +38,7 @@ class FrameV2IPSources(FrameBase):
|
|
|
37
38
|
rather than a promise about the set, so it says whether this frame is
|
|
38
39
|
the whole list and nothing more.
|
|
39
40
|
'''
|
|
40
|
-
pl = self.payload
|
|
41
|
-
if (pl is None):
|
|
42
|
-
return None
|
|
41
|
+
pl = self.payload or b''
|
|
43
42
|
rest = (len(pl) % _RECORD_SIZE)
|
|
44
43
|
if (rest == 0):
|
|
45
44
|
return (0, int(len(pl) / _RECORD_SIZE))
|
|
@@ -175,9 +175,10 @@ class Bay(BayBase):
|
|
|
175
175
|
device = self.device
|
|
176
176
|
if (getattr(device, 'local_bay')(self.is_input) is not self):
|
|
177
177
|
return []
|
|
178
|
+
owner = device.remote_id
|
|
178
179
|
return [bay for dev in device.registry.remotes.values() if (dev is not device)
|
|
179
180
|
for bay in dev.bays.values()
|
|
180
|
-
if isinstance(bay, Bay) and (bay.mesh_owner is self)]
|
|
181
|
+
if isinstance(bay, Bay) and (bay._v2ip_uid == owner) and (bay.mesh_owner is self)]
|
|
181
182
|
|
|
182
183
|
def register_callback(self, callback:Callable[[BayBase],None]) -> None:
|
|
183
184
|
'''register a callback, called when the device state changed'''
|
|
@@ -12,6 +12,7 @@ from ..Interface import (
|
|
|
12
12
|
OneIPStreamSources,
|
|
13
13
|
OneIPPtpMessages,
|
|
14
14
|
OneIPPtpState,
|
|
15
|
+
OneIPDownmix,
|
|
15
16
|
UnitNetConfig,
|
|
16
17
|
UnitStatus,
|
|
17
18
|
AmpDolbySettings,
|
|
@@ -81,7 +82,7 @@ import time
|
|
|
81
82
|
|
|
82
83
|
from ..Interface import DeviceBase, BayBase, DeviceRegistry
|
|
83
84
|
from ..proto.FrameBase import FrameBase
|
|
84
|
-
from ..proto.Constants import (MXR_PROTOCOL_VERSION_SLOW_HELLO, OSD_MESSAGE_TEXT_MAX, OsdMessageFlag, OsdMessagePriority, BayFeaturesMask, DeviceFeature, MxrSignalType, OneIPDeviceSetting, OneIPVideoProcessorFeature, OneIPVlanFlag,
|
|
85
|
+
from ..proto.Constants import (MXR_PROTOCOL_VERSION_SLOW_HELLO, ONEIP_DOWNMIX_LFE_MAX, OSD_MESSAGE_TEXT_MAX, OsdMessageFlag, OsdMessagePriority, BayFeaturesMask, DeviceFeature, MxrSignalType, OneIPDeviceSetting, OneIPVideoProcessorFeature, OneIPVlanFlag,
|
|
85
86
|
OneIPTestPattern, OneIPToneMode,
|
|
86
87
|
MXR_SCALING_FLAG_AUTO_SCALING, MXR_SCALING_FLAG_MODE_VALID,
|
|
87
88
|
MXR_SCALING_FLAG_OPTIONS_VALID, ONEIP_DEVICE_SETTING_SWITCHES,
|
|
@@ -173,6 +174,7 @@ class Device(DeviceBase):
|
|
|
173
174
|
self._v2ip_settings:OneIPDeviceSettings|None = None
|
|
174
175
|
self._v2ip_vlan:OneIPVlan|None = None
|
|
175
176
|
self._v2ip_ptp:OneIPPtpState|None = None
|
|
177
|
+
self._v2ip_downmix:OneIPDownmix|None = None
|
|
176
178
|
self._unit_status:UnitStatus|None = None
|
|
177
179
|
self._v2ip_testcard:OneIPTestcard|None = None
|
|
178
180
|
self._v2ip_sink_sdp:OneIPSinkSdp|None = None
|
|
@@ -453,6 +455,11 @@ class Device(DeviceBase):
|
|
|
453
455
|
def oneip_ptp(self) -> OneIPPtpState|None:
|
|
454
456
|
return self._v2ip_ptp
|
|
455
457
|
|
|
458
|
+
@property
|
|
459
|
+
@override
|
|
460
|
+
def oneip_downmix(self) -> OneIPDownmix|None:
|
|
461
|
+
return self._v2ip_downmix
|
|
462
|
+
|
|
456
463
|
@property
|
|
457
464
|
@override
|
|
458
465
|
def unit_status(self) -> UnitStatus|None:
|
|
@@ -1050,6 +1057,8 @@ class Device(DeviceBase):
|
|
|
1050
1057
|
if (self._v2ip_ptp != ptp):
|
|
1051
1058
|
self._v2ip_ptp = ptp
|
|
1052
1059
|
self.call_callbacks()
|
|
1060
|
+
elif isinstance(data, FrameV2IPDeviceConfiguration):
|
|
1061
|
+
self._on_oneip_downmix(data.downmix, reported=data.target_self)
|
|
1053
1062
|
elif isinstance(data, OneIPTestcard):
|
|
1054
1063
|
if (self._v2ip_testcard != data):
|
|
1055
1064
|
self._v2ip_testcard = data
|
|
@@ -1606,6 +1615,47 @@ class Device(DeviceBase):
|
|
|
1606
1615
|
messages = dataclasses.replace(messages, sink_rotation_step=own.sink_rotation_step)
|
|
1607
1616
|
return self._send_v2ip_settings(OneIPDeviceSettings(valid=which, ptp_messages=messages))
|
|
1608
1617
|
|
|
1618
|
+
def _on_oneip_downmix(self, downmix:OneIPDownmix|None, reported:bool) -> None:
|
|
1619
|
+
'''Take the downmix a configuration carries as the device takes it: a
|
|
1620
|
+
report replaces the one held, None included, and another sender's write
|
|
1621
|
+
is applied only to a device that reports a downmix, and never to what
|
|
1622
|
+
only the device reports.'''
|
|
1623
|
+
if not reported:
|
|
1624
|
+
if (downmix is None) or (self._v2ip_downmix is None):
|
|
1625
|
+
return
|
|
1626
|
+
downmix = self._v2ip_downmix.written(downmix)
|
|
1627
|
+
if (self._v2ip_downmix != downmix):
|
|
1628
|
+
self._v2ip_downmix = downmix
|
|
1629
|
+
self.call_callbacks()
|
|
1630
|
+
|
|
1631
|
+
async def set_oneip_downmix(self, downmix:OneIPDownmix) -> bool:
|
|
1632
|
+
'''Set how this OneIP device's output mixes 5.1 and 7.1 PCM down to
|
|
1633
|
+
stereo: the mode, level and LFE percent of downmix, which the device
|
|
1634
|
+
applies together. Its state and channels are the device's to report,
|
|
1635
|
+
and are not sent.
|
|
1636
|
+
|
|
1637
|
+
Refused before anything is sent for a mode, level or LFE percent out of
|
|
1638
|
+
range, and unless the device reports a downmix, which one whose output
|
|
1639
|
+
cannot mix down never does. The new downmix is cached once the frame is
|
|
1640
|
+
sent, and the device's next report replaces it.
|
|
1641
|
+
'''
|
|
1642
|
+
why = None
|
|
1643
|
+
if not downmix.is_valid():
|
|
1644
|
+
why = f'no such mode or level, or an LFE above {ONEIP_DOWNMIX_LFE_MAX} percent'
|
|
1645
|
+
elif (self._v2ip_settings is None):
|
|
1646
|
+
why = 'it has not reported its settings'
|
|
1647
|
+
elif ((reported := self._v2ip_downmix) is None):
|
|
1648
|
+
why = 'its output does not mix down'
|
|
1649
|
+
if (why is not None):
|
|
1650
|
+
_LOGGER.warning(f"not changing the downmix of {self}: {why}")
|
|
1651
|
+
return False
|
|
1652
|
+
frame = FrameV2IPDeviceConfiguration.construct_downmix(
|
|
1653
|
+
mxr=self.registry, target=self, target_uid=self.remote_id, downmix=downmix)
|
|
1654
|
+
if (frame is None) or (self.registry.transmit(frame.frame) != len(frame.frame)):
|
|
1655
|
+
return False
|
|
1656
|
+
self._on_oneip_downmix(reported.written(downmix), reported=True)
|
|
1657
|
+
return True
|
|
1658
|
+
|
|
1609
1659
|
async def set_oneip_vlan(self, vlan:OneIPVlan) -> bool:
|
|
1610
1660
|
'''Change this OneIP device's VLAN configuration.
|
|
1611
1661
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
from ..Interface import AmpDolbySettings as AmpDolbySettings, AudioChangeSource as AudioChangeSource, AudioEndpoint as AudioEndpoint, AudioEndpoints as AudioEndpoints, AudioLinks as AudioLinks, BayBase as BayBase, DeviceBase as DeviceBase, DeviceClock as DeviceClock, DeviceOneIPDetails as DeviceOneIPDetails, DeviceOneIPScalingSettings as DeviceOneIPScalingSettings, DeviceOneIPSink as DeviceOneIPSink, DeviceRegistry as DeviceRegistry, DeviceStatus as DeviceStatus, Multiviewer as Multiviewer, MxrCallbacks as MxrCallbacks, OneIPDeviceSettings as OneIPDeviceSettings, OneIPOutputMode as OneIPOutputMode, OneIPPowerSaveSchedule as OneIPPowerSaveSchedule, OneIPPrivacy as OneIPPrivacy, OneIPPtpMessages as OneIPPtpMessages, OneIPPtpState as OneIPPtpState, OneIPScalingSettings as OneIPScalingSettings, OneIPSinkSdp as OneIPSinkSdp, OneIPStreamSources as OneIPStreamSources, OneIPStreamSourcesList as OneIPStreamSourcesList, OneIPTestSync as OneIPTestSync, OneIPTestTone as OneIPTestTone, OneIPTestcard as OneIPTestcard, OneIPVlan as OneIPVlan, OsdMessage as OsdMessage, OsdSync as OsdSync, OsdSyncReport as OsdSyncReport, SystemTemperature as SystemTemperature, TimeZone as TimeZone, UnitNetConfig as UnitNetConfig, UnitStatus as UnitStatus
|
|
1
|
+
from ..Interface import AmpDolbySettings as AmpDolbySettings, AudioChangeSource as AudioChangeSource, AudioEndpoint as AudioEndpoint, AudioEndpoints as AudioEndpoints, AudioLinks as AudioLinks, BayBase as BayBase, DeviceBase as DeviceBase, DeviceClock as DeviceClock, DeviceOneIPDetails as DeviceOneIPDetails, DeviceOneIPScalingSettings as DeviceOneIPScalingSettings, DeviceOneIPSink as DeviceOneIPSink, DeviceRegistry as DeviceRegistry, DeviceStatus as DeviceStatus, Multiviewer as Multiviewer, MxrCallbacks as MxrCallbacks, OneIPDeviceSettings as OneIPDeviceSettings, OneIPDownmix as OneIPDownmix, OneIPOutputMode as OneIPOutputMode, OneIPPowerSaveSchedule as OneIPPowerSaveSchedule, OneIPPrivacy as OneIPPrivacy, OneIPPtpMessages as OneIPPtpMessages, OneIPPtpState as OneIPPtpState, OneIPScalingSettings as OneIPScalingSettings, OneIPSinkSdp as OneIPSinkSdp, OneIPStreamSources as OneIPStreamSources, OneIPStreamSourcesList as OneIPStreamSourcesList, OneIPTestSync as OneIPTestSync, OneIPTestTone as OneIPTestTone, OneIPTestcard as OneIPTestcard, OneIPVlan as OneIPVlan, OsdMessage as OsdMessage, OsdSync as OsdSync, OsdSyncReport as OsdSyncReport, SystemTemperature as SystemTemperature, TimeZone as TimeZone, UnitNetConfig as UnitNetConfig, UnitStatus as UnitStatus
|
|
2
2
|
from ..Uid import MxrDeviceUid as MxrDeviceUid
|
|
3
3
|
from ..compat import override as override
|
|
4
4
|
from ..const import MXR_CONFIG_TIMEOUT as MXR_CONFIG_TIMEOUT
|
|
5
5
|
from ..proto.BayConfig import BayConfig as BayConfig
|
|
6
|
-
from ..proto.Constants import BayFeaturesMask as BayFeaturesMask, DeviceFeature as DeviceFeature, MXR_PROTOCOL_VERSION_SLOW_HELLO as MXR_PROTOCOL_VERSION_SLOW_HELLO, MXR_SCALING_FLAG_AUTO_SCALING as MXR_SCALING_FLAG_AUTO_SCALING, MXR_SCALING_FLAG_MODE_VALID as MXR_SCALING_FLAG_MODE_VALID, MXR_SCALING_FLAG_OPTIONS_VALID as MXR_SCALING_FLAG_OPTIONS_VALID, MxrSignalType as MxrSignalType, ONEIP_DEVICE_SETTINGS_BLOCK as ONEIP_DEVICE_SETTINGS_BLOCK, ONEIP_DEVICE_SETTING_SWITCHES as ONEIP_DEVICE_SETTING_SWITCHES, ONEIP_DSCP_MAX as ONEIP_DSCP_MAX, ONEIP_IR_PROFILE_MAX as ONEIP_IR_PROFILE_MAX, ONEIP_IR_PROFILE_NOT_SET as ONEIP_IR_PROFILE_NOT_SET, ONEIP_PTP_DOMAIN_MAX as ONEIP_PTP_DOMAIN_MAX, ONEIP_SDP_MAX as ONEIP_SDP_MAX, ONEIP_VLAN_PORT_SFP as ONEIP_VLAN_PORT_SFP, OSD_MESSAGE_TEXT_MAX as OSD_MESSAGE_TEXT_MAX, OneIPDeviceSetting as OneIPDeviceSetting, OneIPPowerSaveLevel as OneIPPowerSaveLevel, OneIPPtpFlag as OneIPPtpFlag, OneIPPtpMode as OneIPPtpMode, OneIPTestPattern as OneIPTestPattern, OneIPToneMode as OneIPToneMode, OneIPVideoProcessorFeature as OneIPVideoProcessorFeature, OneIPVlanFlag as OneIPVlanFlag, OsdMessageFlag as OsdMessageFlag, OsdMessagePriority as OsdMessagePriority, UnitCommandFlag as UnitCommandFlag, UnitCommandKind as UnitCommandKind
|
|
6
|
+
from ..proto.Constants import BayFeaturesMask as BayFeaturesMask, DeviceFeature as DeviceFeature, MXR_PROTOCOL_VERSION_SLOW_HELLO as MXR_PROTOCOL_VERSION_SLOW_HELLO, MXR_SCALING_FLAG_AUTO_SCALING as MXR_SCALING_FLAG_AUTO_SCALING, MXR_SCALING_FLAG_MODE_VALID as MXR_SCALING_FLAG_MODE_VALID, MXR_SCALING_FLAG_OPTIONS_VALID as MXR_SCALING_FLAG_OPTIONS_VALID, MxrSignalType as MxrSignalType, ONEIP_DEVICE_SETTINGS_BLOCK as ONEIP_DEVICE_SETTINGS_BLOCK, ONEIP_DEVICE_SETTING_SWITCHES as ONEIP_DEVICE_SETTING_SWITCHES, ONEIP_DOWNMIX_LFE_MAX as ONEIP_DOWNMIX_LFE_MAX, ONEIP_DSCP_MAX as ONEIP_DSCP_MAX, ONEIP_IR_PROFILE_MAX as ONEIP_IR_PROFILE_MAX, ONEIP_IR_PROFILE_NOT_SET as ONEIP_IR_PROFILE_NOT_SET, ONEIP_PTP_DOMAIN_MAX as ONEIP_PTP_DOMAIN_MAX, ONEIP_SDP_MAX as ONEIP_SDP_MAX, ONEIP_VLAN_PORT_SFP as ONEIP_VLAN_PORT_SFP, OSD_MESSAGE_TEXT_MAX as OSD_MESSAGE_TEXT_MAX, OneIPDeviceSetting as OneIPDeviceSetting, OneIPPowerSaveLevel as OneIPPowerSaveLevel, OneIPPtpFlag as OneIPPtpFlag, OneIPPtpMode as OneIPPtpMode, OneIPTestPattern as OneIPTestPattern, OneIPToneMode as OneIPToneMode, OneIPVideoProcessorFeature as OneIPVideoProcessorFeature, OneIPVlanFlag as OneIPVlanFlag, OsdMessageFlag as OsdMessageFlag, OsdMessagePriority as OsdMessagePriority, UnitCommandFlag as UnitCommandFlag, UnitCommandKind as UnitCommandKind
|
|
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
|
|
@@ -111,6 +111,9 @@ class Device(DeviceBase):
|
|
|
111
111
|
def oneip_ptp(self) -> OneIPPtpState | None: ...
|
|
112
112
|
@property
|
|
113
113
|
@override
|
|
114
|
+
def oneip_downmix(self) -> OneIPDownmix | None: ...
|
|
115
|
+
@property
|
|
116
|
+
@override
|
|
114
117
|
def unit_status(self) -> UnitStatus | None: ...
|
|
115
118
|
@property
|
|
116
119
|
@override
|
|
@@ -269,6 +272,7 @@ class Device(DeviceBase):
|
|
|
269
272
|
async def set_oneip_ptp_priority1(self, priority1: int) -> bool: ...
|
|
270
273
|
async def set_oneip_power_save_level(self, level: OneIPPowerSaveLevel) -> bool: ...
|
|
271
274
|
async def set_oneip_ptp_messages(self, which: OneIPDeviceSetting, messages: OneIPPtpMessages) -> bool: ...
|
|
275
|
+
async def set_oneip_downmix(self, downmix: OneIPDownmix) -> bool: ...
|
|
272
276
|
async def set_oneip_vlan(self, vlan: OneIPVlan) -> bool: ...
|
|
273
277
|
async def set_audio_endpoint_locked(self, endpoint: int, locked: bool) -> bool: ...
|
|
274
278
|
async def request_oneip_testcard(self) -> bool: ...
|