mx-remote 9.1.0__tar.gz → 9.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-9.1.0 → mx_remote-9.2.0}/PKG-INFO +1 -1
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/oneip.md +22 -13
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/Interface.py +33 -15
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/Interface.pyi +4 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/const.py +1 -1
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/Constants.py +5 -1
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/Device.py +22 -8
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/Device.pyi +1 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/Remote.py +6 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/Remote.pyi +1 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/v2ipsettings.py +41 -1
- {mx_remote-9.1.0 → mx_remote-9.2.0}/.gitignore +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/AGENTS.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/CLAUDE.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/LICENSE +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/README.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/README.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/_static/brand.css +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/_static/favicon.svg +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/_static/logo-dark.svg +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/_static/logo.svg +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/api.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/audio.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/callbacks.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/conf.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/configuration.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/devices-and-bays.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/diagnostics.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/index.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/multiviewer.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/requirements.txt +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/docs/routing.md +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/hatch_build.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/Uid.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/Uid.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/__init__.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/__init__.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/compat.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/compat.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/const.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/deprecated.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/deprecated.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/main.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/main.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/BayConfig.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/BayConfig.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/Constants.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/Data.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/Data.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/Factory.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/Factory.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameAmpDolbySettings.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameAmpDolbySettings.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameAmpZoneSettings.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameAmpZoneSettings.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameAudioClip.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameAudioClip.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameAudioSetRoute.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameAudioSetRoute.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameBase.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameBase.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameBayConfig.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameBayConfig.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameBayConfigSecondary.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameBayConfigSecondary.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameBayContent.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameBayContent.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameBayHide.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameBayHide.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameBayStatus.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameBayStatus.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameConnectStatus.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameConnectStatus.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameDebug.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameDebug.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameDiscover.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameDiscover.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameEDID.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameEDID.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameEDIDProfile.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameEDIDProfile.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameFactoryReset.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameFactoryReset.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameFilterStatus.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameFilterStatus.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameFirmwareVersion.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameFirmwareVersion.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameHeader.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameHeader.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameHello.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameHello.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameLinks.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameLinks.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameMeshOperation.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameMeshOperation.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameMirrorStatus.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameMirrorStatus.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameMonitoringPulse.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameMonitoringPulse.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameNetworkStatus.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameNetworkStatus.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FramePing.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FramePing.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FramePowerChange.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FramePowerChange.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameRCAction.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameRCAction.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameRCIr.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameRCIr.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameRCKey.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameRCKey.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameRCSettings.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameRCSettings.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameReboot.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameReboot.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameRoutingChange.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameRoutingChange.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSetInstaller.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSetInstaller.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSetName.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSetName.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSetRoute.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSetRoute.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSetupStatus.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSetupStatus.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSignalStatus.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSignalStatus.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSignalStatusNew.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSignalStatusNew.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSysTemperature.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSysTemperature.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSystemStatus.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameSystemStatus.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameTXRCAction.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameTXRCAction.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameTXRCKey.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameTXRCKey.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameTime.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameTime.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameTimeZone.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameTimeZone.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameTopology.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameTopology.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameTxIR.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameTxIR.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameUnitCommand.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameUnitCommand.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameUnitStatus.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameUnitStatus.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameUpgradeFPGA.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameUpgradeFPGA.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPAudio.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPAudio.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPBayMapping.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPBayMapping.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPDetectBays.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPDetectBays.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPDeviceConfiguration.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPDeviceConfiguration.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPLink.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPLink.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPManualSourceSwitch.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPManualSourceSwitch.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPMultiviewer.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPMultiviewer.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPOsdSync.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPOsdSync.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPPowerSave.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPPowerSave.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPPrivacy.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPPrivacy.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPSetMaster.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPSetMaster.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPSettingsAll.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPSettingsAll.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPSinkSdp.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPSinkSdp.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPSourceSwitch.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPSourceSwitch.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPSources.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPSources.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPStats.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPStats.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPTestcard.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPTestcard.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPTiling.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPTiling.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPVideoWall.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameV2IPVideoWall.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameVolume.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameVolume.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameVolumeDown.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameVolumeDown.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameVolumeSet.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameVolumeSet.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameVolumeUp.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/FrameVolumeUp.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/LinkConfig.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/LinkConfig.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/Multiviewer.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/Multiviewer.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/Svd.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/Svd.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/V2IPConfig.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/V2IPConfig.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/V2IPStats.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/V2IPStats.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/__init__.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/__init__.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/proto/svd.csv +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/py.typed +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/Bay.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/Bay.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/ConnectionAsync.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/ConnectionAsync.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/Link.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/Link.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/OsdSync.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/OsdSync.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/State.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/State.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/V2IP.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/mx_remote/remote/V2IP.pyi +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/pyproject.toml +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/audio_ir.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/audiolock.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/baycontent.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/capture.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/complete.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/deprecated.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/downmix.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/e2e.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/entry.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/handlers.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/handlers_cover.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/hello.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/idempotent.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/lengths.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/merge.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/mesh.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/meshbays.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/newops.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/offline.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/offsets.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/osdmessage.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/osdsync.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/ping.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/privacy.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/proto_stamp.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/protogate.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/rcsettings.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/roundtrip.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/routes.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/run.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/smoke.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/sources.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/staterequest.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/stats.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/structs.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/txresult.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/uid.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/unit.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/unknowns.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/v2ipptp.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/v2ipscaling.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/v2ipsdp.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/v2ipsubject.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/v2iptestcard.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/v2ipvlan.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.0}/tests/vdetails.py +0 -0
- {mx_remote-9.1.0 → mx_remote-9.2.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.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/
|
|
@@ -225,27 +225,36 @@ goes out at 176 bytes: a receiver with the schedule ignores the settings of a
|
|
|
225
225
|
shorter frame, and one whose settings end at the idle minutes takes it all the
|
|
226
226
|
same.
|
|
227
227
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
228
|
+
Power save is switched on or off. Switched on, a device powers down by itself
|
|
229
|
+
to its power save level: reduced, low or off, each powering more down than the
|
|
230
|
+
one before. The device picks the level itself, the one that saves the most
|
|
231
|
+
while its input and display can still wake it, and reports it. Its unit status
|
|
232
|
+
says which levels it supports and what wakes it at each.
|
|
231
233
|
|
|
232
234
|
```python
|
|
233
235
|
from mx_remote import OneIPPowerSaveLevel, UnitPowerSave
|
|
234
236
|
|
|
235
|
-
print(settings.
|
|
237
|
+
print(settings.get(OneIPDeviceSetting.POWER_SAVE_DISABLED)) # False: switched on
|
|
238
|
+
print(settings.power_save_level) # the level it picked
|
|
236
239
|
print(device.unit_status.power_save_level(OneIPPowerSaveLevel.LOW)) # e.g. SUPPORTED|INPUT_WAKE
|
|
237
240
|
|
|
238
|
-
await device.
|
|
241
|
+
await device.set_oneip_power_save(True)
|
|
242
|
+
await mx.set_all_oneip_power_save(False) # every OneIP device of the mesh
|
|
239
243
|
```
|
|
240
244
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
Switched off, `OneIPDeviceSetting.POWER_SAVE_DISABLED` is on: the device does
|
|
246
|
+
not power down by itself, and a power save request still powers it down.
|
|
247
|
+
Switching on is written as a mesh controller writes it, with that switch clear
|
|
248
|
+
and the power save level at 0, so a device whose firmware still takes the level
|
|
249
|
+
as its setting returns to its own default.
|
|
250
|
+
|
|
251
|
+
`set_oneip_power_save_level()` writes a level, which switches power save on. A
|
|
252
|
+
current device ignores the level; one whose firmware predates picking it takes
|
|
253
|
+
it. A written level is never cached, from this client or another controller:
|
|
254
|
+
`power_save_level` is what the device reports. A level write without the switch
|
|
255
|
+
only clears `POWER_SAVE_DISABLED` on a device that reports it. A level this
|
|
256
|
+
library does not name is refused before it is sent. Firmware without the switch
|
|
257
|
+
never reports it, and switching is refused there.
|
|
249
258
|
|
|
250
259
|
`OneIPDeviceSetting.CLOUD` is a switch for whether a device connects to the
|
|
251
260
|
cloud service. A device that does not report it connects regardless, and the
|
|
@@ -2712,6 +2712,16 @@ class OneIPDeviceSettings:
|
|
|
2712
2712
|
self._power_save_level = int(power_save_level)
|
|
2713
2713
|
self._ptp_messages = ptp_messages if (ptp_messages is not None) else OneIPPtpMessages()
|
|
2714
2714
|
|
|
2715
|
+
@classmethod
|
|
2716
|
+
def power_save_switch(cls, enabled:bool) -> 'OneIPDeviceSettings':
|
|
2717
|
+
"""The settings that switch a device's power save on or off. On is both
|
|
2718
|
+
POWER_SAVE_DISABLED, clear, and POWER_SAVE_LEVEL, at 0."""
|
|
2719
|
+
disabled = OneIPDeviceSetting.POWER_SAVE_DISABLED
|
|
2720
|
+
if enabled:
|
|
2721
|
+
return cls(valid=(disabled | OneIPDeviceSetting.POWER_SAVE_LEVEL),
|
|
2722
|
+
power_save_level=OneIPPowerSaveLevel.NONE)
|
|
2723
|
+
return cls(valid=disabled, flags=disabled)
|
|
2724
|
+
|
|
2715
2725
|
@property
|
|
2716
2726
|
def valid(self) -> OneIPDeviceSetting:
|
|
2717
2727
|
"""The settings reported so far."""
|
|
@@ -2791,8 +2801,9 @@ class OneIPDeviceSettings:
|
|
|
2791
2801
|
|
|
2792
2802
|
@property
|
|
2793
2803
|
def power_save_level(self) -> OneIPPowerSaveLevel|int|None:
|
|
2794
|
-
"""The level the device powers down to in power save,
|
|
2795
|
-
this library does not name, None while it is
|
|
2804
|
+
"""The level the device powers down to in power save, which it picks
|
|
2805
|
+
itself, a raw int for one this library does not name, None while it is
|
|
2806
|
+
not reported."""
|
|
2796
2807
|
if (OneIPDeviceSetting.POWER_SAVE_LEVEL not in self._valid):
|
|
2797
2808
|
return None
|
|
2798
2809
|
return _wire_enum(OneIPPowerSaveLevel, self._power_save_level)
|
|
@@ -2812,18 +2823,14 @@ class OneIPDeviceSettings:
|
|
|
2812
2823
|
|
|
2813
2824
|
Each bit in this block's ``valid`` replaces its own setting and leaves
|
|
2814
2825
|
the others alone, so a write about one setting does not clear what was
|
|
2815
|
-
known about the rest.
|
|
2816
|
-
takes a power save level as switching it off.
|
|
2826
|
+
known about the rest.
|
|
2817
2827
|
"""
|
|
2818
2828
|
if (previous is None):
|
|
2819
2829
|
previous = OneIPDeviceSettings()
|
|
2820
2830
|
valid = self._valid
|
|
2821
|
-
flags = (previous._flags & ~valid) | (self._flags & valid)
|
|
2822
|
-
if (OneIPDeviceSetting.POWER_SAVE_LEVEL in valid) and (OneIPDeviceSetting.POWER_SAVE_DISABLED not in valid):
|
|
2823
|
-
flags &= ~OneIPDeviceSetting.POWER_SAVE_DISABLED
|
|
2824
2831
|
return OneIPDeviceSettings(
|
|
2825
2832
|
valid=(previous._valid | valid),
|
|
2826
|
-
flags=
|
|
2833
|
+
flags=((previous._flags & ~valid) | (self._flags & valid)),
|
|
2827
2834
|
ir_profiles=(self._ir_profiles if (OneIPDeviceSetting.IR_PROFILES in valid)
|
|
2828
2835
|
else previous._ir_profiles),
|
|
2829
2836
|
ir_profile=(self._ir_profile if (OneIPDeviceSetting.IR_PROFILE in valid)
|
|
@@ -2850,9 +2857,11 @@ class OneIPDeviceSettings:
|
|
|
2850
2857
|
write about it.
|
|
2851
2858
|
|
|
2852
2859
|
A device applies a setting only if it has it, a profile, PTP mode, PTP
|
|
2853
|
-
domain
|
|
2854
|
-
|
|
2855
|
-
|
|
2860
|
+
domain or PTP DSCP only within its range, a stream TTL only when it is
|
|
2861
|
+
not 0, a rotation only by its own step, and never what only it can
|
|
2862
|
+
report about itself. The step stays the device's. It picks its power
|
|
2863
|
+
save level itself, and takes a level it is written, without
|
|
2864
|
+
POWER_SAVE_DISABLED, as switching power save on.
|
|
2856
2865
|
|
|
2857
2866
|
reported may be only the bits the device reported, which says nothing
|
|
2858
2867
|
of its step, so a rotation other than 0 is then left out.
|
|
@@ -2871,15 +2880,20 @@ class OneIPDeviceSettings:
|
|
|
2871
2880
|
valid &= ~OneIPDeviceSetting.PTP_MODE
|
|
2872
2881
|
if (self._ptp_domain > ONEIP_PTP_DOMAIN_MAX):
|
|
2873
2882
|
valid &= ~OneIPDeviceSetting.PTP_DOMAIN
|
|
2874
|
-
if (self._power_save_level > OneIPPowerSaveLevel.OFF):
|
|
2875
|
-
valid &= ~OneIPDeviceSetting.POWER_SAVE_LEVEL
|
|
2876
2883
|
if (self._ptp_messages.dscp > ONEIP_DSCP_MAX):
|
|
2877
2884
|
valid &= ~OneIPDeviceSetting.PTP_DSCP
|
|
2878
2885
|
if (self._ptp_messages.stream_ttl == 0):
|
|
2879
2886
|
valid &= ~OneIPDeviceSetting.STREAM_TTL
|
|
2880
2887
|
if not own.takes_sink_rotation(self._ptp_messages.sink_rotation):
|
|
2881
2888
|
valid &= ~OneIPDeviceSetting.SINK_ROTATION
|
|
2882
|
-
|
|
2889
|
+
flags = self._flags
|
|
2890
|
+
if (OneIPDeviceSetting.POWER_SAVE_LEVEL in valid):
|
|
2891
|
+
valid &= ~OneIPDeviceSetting.POWER_SAVE_LEVEL
|
|
2892
|
+
if (OneIPDeviceSetting.POWER_SAVE_DISABLED not in valid) \
|
|
2893
|
+
and (OneIPDeviceSetting.POWER_SAVE_DISABLED in reported._valid):
|
|
2894
|
+
valid |= OneIPDeviceSetting.POWER_SAVE_DISABLED
|
|
2895
|
+
flags &= ~OneIPDeviceSetting.POWER_SAVE_DISABLED
|
|
2896
|
+
return OneIPDeviceSettings(valid=valid, flags=flags, ir_profiles=self._ir_profiles,
|
|
2883
2897
|
ir_profile=self._ir_profile, ir_profile_sink=self._ir_profile_sink,
|
|
2884
2898
|
auto_power_save=self._auto_power_save, power_save=self._power_save,
|
|
2885
2899
|
ptp_mode=self._ptp_mode, ptp_domain=self._ptp_domain,
|
|
@@ -3572,9 +3586,13 @@ class DeviceBase(ABC):
|
|
|
3572
3586
|
async def set_oneip_ptp_priority1(self, priority1:int) -> bool:
|
|
3573
3587
|
'''set the priority1 the device announces as a PTP grandmaster'''
|
|
3574
3588
|
|
|
3589
|
+
@abstractmethod
|
|
3590
|
+
async def set_oneip_power_save(self, enabled:bool) -> bool:
|
|
3591
|
+
'''switch power save on, so the device powers down by itself to the level it picks, or off'''
|
|
3592
|
+
|
|
3575
3593
|
@abstractmethod
|
|
3576
3594
|
async def set_oneip_power_save_level(self, level:OneIPPowerSaveLevel) -> bool:
|
|
3577
|
-
'''
|
|
3595
|
+
'''write the level the device powers down to in power save, which switches power save on'''
|
|
3578
3596
|
|
|
3579
3597
|
@abstractmethod
|
|
3580
3598
|
async def set_oneip_ptp_messages(self, which:OneIPDeviceSetting, messages:OneIPPtpMessages) -> bool:
|
|
@@ -962,6 +962,8 @@ class OneIPTestcard:
|
|
|
962
962
|
|
|
963
963
|
class OneIPDeviceSettings:
|
|
964
964
|
def __init__(self, valid: OneIPDeviceSetting = ..., flags: OneIPDeviceSetting = ..., ir_profiles: int = 0, ir_profile: int = 0, ir_profile_sink: int = 0, auto_power_save: int = 0, power_save: OneIPPowerSaveSchedule | None = None, ptp_mode: OneIPPtpMode | int = ..., ptp_domain: int = 0, ptp_priority1: int = 0, power_save_level: OneIPPowerSaveLevel | int = ..., ptp_messages: OneIPPtpMessages | None = None) -> None: ...
|
|
965
|
+
@classmethod
|
|
966
|
+
def power_save_switch(cls, enabled: bool) -> OneIPDeviceSettings: ...
|
|
965
967
|
@property
|
|
966
968
|
def valid(self) -> OneIPDeviceSetting: ...
|
|
967
969
|
@property
|
|
@@ -1330,6 +1332,8 @@ class DeviceBase(ABC):
|
|
|
1330
1332
|
@abstractmethod
|
|
1331
1333
|
async def set_oneip_ptp_priority1(self, priority1: int) -> bool: ...
|
|
1332
1334
|
@abstractmethod
|
|
1335
|
+
async def set_oneip_power_save(self, enabled: bool) -> bool: ...
|
|
1336
|
+
@abstractmethod
|
|
1333
1337
|
async def set_oneip_power_save_level(self, level: OneIPPowerSaveLevel) -> bool: ...
|
|
1334
1338
|
@abstractmethod
|
|
1335
1339
|
async def set_oneip_ptp_messages(self, which: OneIPDeviceSetting, messages: OneIPPtpMessages) -> bool: ...
|
|
@@ -349,7 +349,11 @@ class OneIPDeviceSetting(IntFlag):
|
|
|
349
349
|
AES67 = (1 << 17)
|
|
350
350
|
'''Sends the source's audio as an AES67 flow, where the source allows.'''
|
|
351
351
|
POWER_SAVE_LEVEL = (1 << 18)
|
|
352
|
-
'''The
|
|
352
|
+
'''The level the device powers down to in power save. A device picks it
|
|
353
|
+
itself: the level that saves the most while its input and display can
|
|
354
|
+
still wake it. Written without POWER_SAVE_DISABLED, it switches power save
|
|
355
|
+
on, and the level written is ignored, except by a device whose firmware
|
|
356
|
+
predates picking it, which takes the level as its setting.'''
|
|
353
357
|
PTP_ANNOUNCE = (1 << 19)
|
|
354
358
|
'''The interval between the device's PTP announce messages.'''
|
|
355
359
|
PTP_SYNC = (1 << 20)
|
|
@@ -76,7 +76,6 @@ from typing import Any, Callable
|
|
|
76
76
|
from ..compat import override
|
|
77
77
|
from datetime import datetime
|
|
78
78
|
from enum import Enum
|
|
79
|
-
import dataclasses
|
|
80
79
|
import logging
|
|
81
80
|
import time
|
|
82
81
|
|
|
@@ -1572,12 +1571,28 @@ class Device(DeviceBase):
|
|
|
1572
1571
|
return self._send_v2ip_settings(OneIPDeviceSettings(
|
|
1573
1572
|
valid=OneIPDeviceSetting.PTP_PRIORITY1, ptp_priority1=priority1))
|
|
1574
1573
|
|
|
1575
|
-
async def
|
|
1576
|
-
'''
|
|
1574
|
+
async def set_oneip_power_save(self, enabled:bool) -> bool:
|
|
1575
|
+
'''Switch this OneIP device's power save on, so it powers down by itself
|
|
1576
|
+
to the level it picks, or off, so it powers down only when asked.
|
|
1577
1577
|
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1578
|
+
On is written as a mesh controller writes it: both POWER_SAVE_DISABLED,
|
|
1579
|
+
clear, and POWER_SAVE_LEVEL, at 0, so a device whose firmware takes the
|
|
1580
|
+
level as its setting returns to its own default. The terms of
|
|
1581
|
+
set_oneip_setting() apply.
|
|
1582
|
+
'''
|
|
1583
|
+
return self._send_v2ip_settings(OneIPDeviceSettings.power_save_switch(enabled))
|
|
1584
|
+
|
|
1585
|
+
async def set_oneip_power_save_level(self, level:OneIPPowerSaveLevel) -> bool:
|
|
1586
|
+
'''Write the level this OneIP device powers down to in power save, which
|
|
1587
|
+
switches power save on.
|
|
1588
|
+
|
|
1589
|
+
A device picks its level itself and ignores the one written, except one
|
|
1590
|
+
whose firmware predates picking it, which takes the level as its
|
|
1591
|
+
setting. A level that unit does not offer is one its unit_status
|
|
1592
|
+
reports without UnitPowerSave.SUPPORTED. A level this library does not
|
|
1593
|
+
name is refused. The level is not cached: oneip_settings reads what the
|
|
1594
|
+
device reports. set_oneip_power_save() switches power save on or off
|
|
1595
|
+
without naming a level. The terms of set_oneip_setting() apply.
|
|
1581
1596
|
'''
|
|
1582
1597
|
if not (OneIPPowerSaveLevel.NONE <= level <= OneIPPowerSaveLevel.OFF):
|
|
1583
1598
|
_LOGGER.warning(f"not setting power save level {level} on {self}: no such level")
|
|
@@ -1612,7 +1627,6 @@ class Device(DeviceBase):
|
|
|
1612
1627
|
_LOGGER.warning(f"not turning the output of {self} by {messages.sink_rotation} degrees: "
|
|
1613
1628
|
f"it turns by steps of {own.sink_rotation_step}")
|
|
1614
1629
|
return False
|
|
1615
|
-
messages = dataclasses.replace(messages, sink_rotation_step=own.sink_rotation_step)
|
|
1616
1630
|
return self._send_v2ip_settings(OneIPDeviceSettings(valid=which, ptp_messages=messages))
|
|
1617
1631
|
|
|
1618
1632
|
def _on_oneip_downmix(self, downmix:OneIPDownmix|None, reported:bool) -> None:
|
|
@@ -1932,7 +1946,7 @@ class Device(DeviceBase):
|
|
|
1932
1946
|
return False
|
|
1933
1947
|
if self.registry.transmit(frame.frame) != len(frame.frame):
|
|
1934
1948
|
return False
|
|
1935
|
-
self._merge_v2ip_settings(settings)
|
|
1949
|
+
self._merge_v2ip_settings(settings.as_applied_to(reported))
|
|
1936
1950
|
return True
|
|
1937
1951
|
|
|
1938
1952
|
@property
|
|
@@ -270,6 +270,7 @@ class Device(DeviceBase):
|
|
|
270
270
|
async def set_oneip_ptp_mode(self, mode: OneIPPtpMode) -> bool: ...
|
|
271
271
|
async def set_oneip_ptp_domain(self, domain: int) -> bool: ...
|
|
272
272
|
async def set_oneip_ptp_priority1(self, priority1: int) -> bool: ...
|
|
273
|
+
async def set_oneip_power_save(self, enabled: bool) -> bool: ...
|
|
273
274
|
async def set_oneip_power_save_level(self, level: OneIPPowerSaveLevel) -> bool: ...
|
|
274
275
|
async def set_oneip_ptp_messages(self, which: OneIPDeviceSetting, messages: OneIPPtpMessages) -> bool: ...
|
|
275
276
|
async def set_oneip_downmix(self, downmix: OneIPDownmix) -> bool: ...
|
|
@@ -561,6 +561,12 @@ class Remote(DeviceRegistry, ConnectionCallbacks):
|
|
|
561
561
|
return False
|
|
562
562
|
return self._send_to_all(FrameV2IPSettingsAll.construct(mxr=self, settings=settings))
|
|
563
563
|
|
|
564
|
+
async def set_all_oneip_power_save(self, enabled:bool) -> bool:
|
|
565
|
+
'''Switch power save on or off on every OneIP device of the mesh with
|
|
566
|
+
one frame, written as Device.set_oneip_power_save() writes it.
|
|
567
|
+
Otherwise as set_all_oneip_device_settings().'''
|
|
568
|
+
return await self.set_all_oneip_device_settings(OneIPDeviceSettings.power_save_switch(enabled))
|
|
569
|
+
|
|
564
570
|
async def request_all_oneip_privacy(self) -> bool:
|
|
565
571
|
'''Ask every OneIP source unit of the mesh how its streams are
|
|
566
572
|
encrypted, as Device.request_oneip_privacy() asks one. A unit below
|
|
@@ -73,6 +73,7 @@ class Remote(DeviceRegistry, ConnectionCallbacks):
|
|
|
73
73
|
def transmit(self, data: bytes) -> int: ...
|
|
74
74
|
def tx_discover(self) -> int: ...
|
|
75
75
|
async def set_all_oneip_device_settings(self, settings: OneIPDeviceSettings) -> bool: ...
|
|
76
|
+
async def set_all_oneip_power_save(self, enabled: bool) -> bool: ...
|
|
76
77
|
async def request_all_oneip_privacy(self) -> bool: ...
|
|
77
78
|
async def set_mesh_time_zone(self, zone: str, rule: str) -> bool: ...
|
|
78
79
|
async def clear_mesh_time_zone(self) -> bool: ...
|
|
@@ -373,7 +373,8 @@ assert call(level.set_oneip_power_save_level(mx_remote.OneIPPowerSaveLevel.OFF))
|
|
|
373
373
|
block = sent[-1][24 + 128:]
|
|
374
374
|
assert struct.unpack('<I', block[:4])[0] == int(S.POWER_SAVE_LEVEL)
|
|
375
375
|
assert block[44:48] == bytes([0, 0, 0, 3]), block[44:48].hex()
|
|
376
|
-
assert level.oneip_settings.power_save_level is mx_remote.OneIPPowerSaveLevel.
|
|
376
|
+
assert level.oneip_settings.power_save_level is mx_remote.OneIPPowerSaveLevel.LOW, 'a written level was cached'
|
|
377
|
+
assert level.oneip_settings.get(S.POWER_SAVE_DISABLED) is None, 'a switch the device does not have'
|
|
377
378
|
assert call(level.set_oneip_setting(S.AES67, False)) is True, 'AES67 is not switched'
|
|
378
379
|
assert level.oneip_settings.get(S.AES67) is False
|
|
379
380
|
refused(level.set_oneip_power_save_level(4), 'a power save level with no name')
|
|
@@ -397,6 +398,35 @@ assert struct.unpack('<II', sent[-1][24 + 128:24 + 136]) == (DIS, DIS)
|
|
|
397
398
|
refused(ptp.set_oneip_setting(S.POWER_SAVE_DISABLED, True), 'a unit that never reported the bit')
|
|
398
399
|
print('ps disabled : a switch, and a level switches it off')
|
|
399
400
|
|
|
401
|
+
# Power save is switched on as a mesh controller switches it, with both bits
|
|
402
|
+
# and a level of 0, and off with the switch alone. A device picks its level
|
|
403
|
+
# itself, so a written level, ours or another sender's, is never cached, and
|
|
404
|
+
# only switches power save on.
|
|
405
|
+
BOTH = int(S.POWER_SAVE_LEVEL) | DIS
|
|
406
|
+
rx(uid(0x22), 0x3C, cfg_level(uid(0x22), LEVEL | DIS, 2, flags=DIS))
|
|
407
|
+
cached = lambda: (level.oneip_settings.get(S.POWER_SAVE_DISABLED), level.oneip_settings.power_save_level)
|
|
408
|
+
LOW = mx_remote.OneIPPowerSaveLevel.LOW
|
|
409
|
+
assert call(level.set_oneip_power_save(True)) is True
|
|
410
|
+
block = sent[-1][24 + 128:]
|
|
411
|
+
assert struct.unpack('<II', block[:8]) == (BOTH, 0), block[:8].hex()
|
|
412
|
+
assert block[47] == 0, 'the level'
|
|
413
|
+
assert cached() == (False, LOW), cached()
|
|
414
|
+
assert call(level.set_oneip_power_save(False)) is True
|
|
415
|
+
block = sent[-1][24 + 128:]
|
|
416
|
+
assert struct.unpack('<II', block[:8]) == (DIS, DIS), block[:8].hex()
|
|
417
|
+
assert cached() == (True, LOW), cached()
|
|
418
|
+
assert call(level.set_oneip_power_save_level(mx_remote.OneIPPowerSaveLevel.OFF)) is True
|
|
419
|
+
assert cached() == (False, LOW), "our level"
|
|
420
|
+
# Another sender's level: a flag outside valid says nothing, and one behind its
|
|
421
|
+
# own bit decides.
|
|
422
|
+
assert call(level.set_oneip_power_save(False)) is True
|
|
423
|
+
rx(uid(0x04), 0x3C, cfg_level(uid(0x22), int(S.POWER_SAVE_LEVEL), 3, flags=DIS))
|
|
424
|
+
assert cached() == (False, LOW), "another sender's level"
|
|
425
|
+
rx(uid(0x04), 0x3C, cfg_level(uid(0x22), BOTH, 3, flags=DIS))
|
|
426
|
+
assert cached() == (True, LOW), 'and its switch'
|
|
427
|
+
refused(ptp.set_oneip_power_save(True), 'a unit that never reported the bits')
|
|
428
|
+
print('ps switch : both bits and level 0 on, the switch alone off; the level is the device\'s')
|
|
429
|
+
|
|
400
430
|
# The cloud connection is a switch too. A unit without the bit connects
|
|
401
431
|
# regardless, and never reports it, so the switch is refused there.
|
|
402
432
|
CLOUD = int(S.CLOUD)
|
|
@@ -540,6 +570,16 @@ write = mx_remote.OneIPDeviceSettings(valid=S.STATUS_LED | S.SINK_ROTATION,
|
|
|
540
570
|
assert write.as_applied_to(S.STATUS_LED | S.SINK_ROTATION).valid == S.STATUS_LED
|
|
541
571
|
print('rotation : a u16 at 10, by the unit\'s own step, which a write leaves 0')
|
|
542
572
|
|
|
573
|
+
# The mesh-wide power save switch writes what the per-device one does, in the
|
|
574
|
+
# frame every unit of the mesh applies.
|
|
575
|
+
for enabled, valid, flags in ((True, BOTH, 0), (False, DIS, DIS)):
|
|
576
|
+
assert call(mx.set_all_oneip_power_save(enabled)) is True, enabled
|
|
577
|
+
p = sent[-1][24:]
|
|
578
|
+
assert len(p) == 48, (enabled, len(p))
|
|
579
|
+
assert struct.unpack('<II', p[:8]) == (valid, flags), (enabled, p[:8].hex())
|
|
580
|
+
assert p[47] == 0, enabled
|
|
581
|
+
print('ps all : the mesh-wide switch is the per-device one')
|
|
582
|
+
|
|
543
583
|
# What the builder writes, the decoder reads back as the same settings.
|
|
544
584
|
assert call(target.set_oneip_ir_profile(7)) is True
|
|
545
585
|
rx(uid(0x10), 0x3C, sent[-1][24:])
|
|
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
|