mx-remote 6.0.0__tar.gz → 6.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. {mx_remote-6.0.0 → mx_remote-6.2.0}/PKG-INFO +1 -1
  2. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/oneip.md +7 -0
  3. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/Interface.py +4 -0
  4. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/Interface.pyi +2 -0
  5. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/const.py +1 -1
  6. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameMeshOperation.py +11 -0
  7. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameMeshOperation.pyi +3 -0
  8. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Device.py +25 -1
  9. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Device.pyi +2 -1
  10. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/mesh.py +38 -0
  11. {mx_remote-6.0.0 → mx_remote-6.2.0}/.gitignore +0 -0
  12. {mx_remote-6.0.0 → mx_remote-6.2.0}/AGENTS.md +0 -0
  13. {mx_remote-6.0.0 → mx_remote-6.2.0}/CLAUDE.md +0 -0
  14. {mx_remote-6.0.0 → mx_remote-6.2.0}/LICENSE +0 -0
  15. {mx_remote-6.0.0 → mx_remote-6.2.0}/README.md +0 -0
  16. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/README.md +0 -0
  17. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/_static/brand.css +0 -0
  18. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/_static/favicon.svg +0 -0
  19. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/_static/logo-dark.svg +0 -0
  20. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/_static/logo.svg +0 -0
  21. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/api.md +0 -0
  22. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/audio.md +0 -0
  23. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/callbacks.md +0 -0
  24. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/conf.py +0 -0
  25. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/configuration.md +0 -0
  26. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/devices-and-bays.md +0 -0
  27. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/diagnostics.md +0 -0
  28. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/index.md +0 -0
  29. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/multiviewer.md +0 -0
  30. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/requirements.txt +0 -0
  31. {mx_remote-6.0.0 → mx_remote-6.2.0}/docs/routing.md +0 -0
  32. {mx_remote-6.0.0 → mx_remote-6.2.0}/hatch_build.py +0 -0
  33. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/Uid.py +0 -0
  34. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/Uid.pyi +0 -0
  35. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/__init__.py +0 -0
  36. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/__init__.pyi +0 -0
  37. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/compat.py +0 -0
  38. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/compat.pyi +0 -0
  39. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/const.pyi +0 -0
  40. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/deprecated.py +0 -0
  41. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/deprecated.pyi +0 -0
  42. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/main.py +0 -0
  43. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/main.pyi +0 -0
  44. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/BayConfig.py +0 -0
  45. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/BayConfig.pyi +0 -0
  46. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Constants.py +0 -0
  47. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Constants.pyi +0 -0
  48. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Data.py +0 -0
  49. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Data.pyi +0 -0
  50. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Factory.py +0 -0
  51. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Factory.pyi +0 -0
  52. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAmpDolbySettings.py +0 -0
  53. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAmpDolbySettings.pyi +0 -0
  54. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAmpZoneSettings.py +0 -0
  55. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAmpZoneSettings.pyi +0 -0
  56. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAudioClip.py +0 -0
  57. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAudioClip.pyi +0 -0
  58. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAudioSetRoute.py +0 -0
  59. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameAudioSetRoute.pyi +0 -0
  60. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBase.py +0 -0
  61. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBase.pyi +0 -0
  62. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayConfig.py +0 -0
  63. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayConfig.pyi +0 -0
  64. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayConfigSecondary.py +0 -0
  65. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayConfigSecondary.pyi +0 -0
  66. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayHide.py +0 -0
  67. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayHide.pyi +0 -0
  68. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayStatus.py +0 -0
  69. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameBayStatus.pyi +0 -0
  70. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameConnectStatus.py +0 -0
  71. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameConnectStatus.pyi +0 -0
  72. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameDebug.py +0 -0
  73. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameDebug.pyi +0 -0
  74. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameDiscover.py +0 -0
  75. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameDiscover.pyi +0 -0
  76. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameEDID.py +0 -0
  77. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameEDID.pyi +0 -0
  78. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameEDIDProfile.py +0 -0
  79. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameEDIDProfile.pyi +0 -0
  80. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameFactoryReset.py +0 -0
  81. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameFactoryReset.pyi +0 -0
  82. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameFilterStatus.py +0 -0
  83. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameFilterStatus.pyi +0 -0
  84. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameFirmwareVersion.py +0 -0
  85. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameFirmwareVersion.pyi +0 -0
  86. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameHeader.py +0 -0
  87. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameHeader.pyi +0 -0
  88. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameHello.py +0 -0
  89. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameHello.pyi +0 -0
  90. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameLinks.py +0 -0
  91. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameLinks.pyi +0 -0
  92. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameMirrorStatus.py +0 -0
  93. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameMirrorStatus.pyi +0 -0
  94. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameMonitoringPulse.py +0 -0
  95. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameMonitoringPulse.pyi +0 -0
  96. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameNetworkStatus.py +0 -0
  97. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameNetworkStatus.pyi +0 -0
  98. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FramePing.py +0 -0
  99. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FramePing.pyi +0 -0
  100. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FramePowerChange.py +0 -0
  101. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FramePowerChange.pyi +0 -0
  102. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCAction.py +0 -0
  103. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCAction.pyi +0 -0
  104. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCIr.py +0 -0
  105. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCIr.pyi +0 -0
  106. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCKey.py +0 -0
  107. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCKey.pyi +0 -0
  108. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCSettings.py +0 -0
  109. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRCSettings.pyi +0 -0
  110. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameReboot.py +0 -0
  111. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameReboot.pyi +0 -0
  112. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRoutingChange.py +0 -0
  113. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameRoutingChange.pyi +0 -0
  114. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetInstaller.py +0 -0
  115. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetInstaller.pyi +0 -0
  116. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetName.py +0 -0
  117. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetName.pyi +0 -0
  118. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetRoute.py +0 -0
  119. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetRoute.pyi +0 -0
  120. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetupStatus.py +0 -0
  121. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSetupStatus.pyi +0 -0
  122. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSignalStatus.py +0 -0
  123. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSignalStatus.pyi +0 -0
  124. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSignalStatusNew.py +0 -0
  125. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSignalStatusNew.pyi +0 -0
  126. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSysTemperature.py +0 -0
  127. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSysTemperature.pyi +0 -0
  128. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSystemStatus.py +0 -0
  129. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameSystemStatus.pyi +0 -0
  130. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTXRCAction.py +0 -0
  131. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTXRCAction.pyi +0 -0
  132. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTXRCKey.py +0 -0
  133. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTXRCKey.pyi +0 -0
  134. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTime.py +0 -0
  135. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTime.pyi +0 -0
  136. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTimeZone.py +0 -0
  137. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTimeZone.pyi +0 -0
  138. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTopology.py +0 -0
  139. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTopology.pyi +0 -0
  140. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTxIR.py +0 -0
  141. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameTxIR.pyi +0 -0
  142. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameUpgradeFPGA.py +0 -0
  143. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameUpgradeFPGA.pyi +0 -0
  144. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPAudio.py +0 -0
  145. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPAudio.pyi +0 -0
  146. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPBayMapping.py +0 -0
  147. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPBayMapping.pyi +0 -0
  148. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPDetectBays.py +0 -0
  149. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPDetectBays.pyi +0 -0
  150. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPDeviceConfiguration.py +0 -0
  151. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPDeviceConfiguration.pyi +0 -0
  152. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPLink.py +0 -0
  153. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPLink.pyi +0 -0
  154. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPManualSourceSwitch.py +0 -0
  155. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPManualSourceSwitch.pyi +0 -0
  156. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPMultiviewer.py +0 -0
  157. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPMultiviewer.pyi +0 -0
  158. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPPowerSave.py +0 -0
  159. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPPowerSave.pyi +0 -0
  160. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSetMaster.py +0 -0
  161. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSetMaster.pyi +0 -0
  162. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSettingsAll.py +0 -0
  163. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSettingsAll.pyi +0 -0
  164. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSourceSwitch.py +0 -0
  165. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSourceSwitch.pyi +0 -0
  166. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSources.py +0 -0
  167. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPSources.pyi +0 -0
  168. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPStats.py +0 -0
  169. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPStats.pyi +0 -0
  170. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPTestcard.py +0 -0
  171. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPTestcard.pyi +0 -0
  172. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPTiling.py +0 -0
  173. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPTiling.pyi +0 -0
  174. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPVideoWall.py +0 -0
  175. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameV2IPVideoWall.pyi +0 -0
  176. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolume.py +0 -0
  177. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolume.pyi +0 -0
  178. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolumeDown.py +0 -0
  179. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolumeDown.pyi +0 -0
  180. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolumeSet.py +0 -0
  181. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolumeSet.pyi +0 -0
  182. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolumeUp.py +0 -0
  183. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/FrameVolumeUp.pyi +0 -0
  184. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/LinkConfig.py +0 -0
  185. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/LinkConfig.pyi +0 -0
  186. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Multiviewer.py +0 -0
  187. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Multiviewer.pyi +0 -0
  188. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Svd.py +0 -0
  189. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/Svd.pyi +0 -0
  190. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/V2IPConfig.py +0 -0
  191. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/V2IPConfig.pyi +0 -0
  192. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/V2IPStats.py +0 -0
  193. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/V2IPStats.pyi +0 -0
  194. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/__init__.py +0 -0
  195. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/__init__.pyi +0 -0
  196. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/proto/svd.csv +0 -0
  197. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/py.typed +0 -0
  198. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Bay.py +0 -0
  199. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Bay.pyi +0 -0
  200. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/ConnectionAsync.py +0 -0
  201. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/ConnectionAsync.pyi +0 -0
  202. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Link.py +0 -0
  203. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Link.pyi +0 -0
  204. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Remote.py +0 -0
  205. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/Remote.pyi +0 -0
  206. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/State.py +0 -0
  207. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/State.pyi +0 -0
  208. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/V2IP.py +0 -0
  209. {mx_remote-6.0.0 → mx_remote-6.2.0}/mx_remote/remote/V2IP.pyi +0 -0
  210. {mx_remote-6.0.0 → mx_remote-6.2.0}/pyproject.toml +0 -0
  211. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/audio_ir.py +0 -0
  212. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/audiolock.py +0 -0
  213. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/capture.py +0 -0
  214. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/complete.py +0 -0
  215. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/deprecated.py +0 -0
  216. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/e2e.py +0 -0
  217. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/entry.py +0 -0
  218. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/handlers.py +0 -0
  219. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/handlers_cover.py +0 -0
  220. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/hello.py +0 -0
  221. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/idempotent.py +0 -0
  222. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/lengths.py +0 -0
  223. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/merge.py +0 -0
  224. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/newops.py +0 -0
  225. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/offline.py +0 -0
  226. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/offsets.py +0 -0
  227. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/ping.py +0 -0
  228. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/proto_stamp.py +0 -0
  229. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/protogate.py +0 -0
  230. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/rcsettings.py +0 -0
  231. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/roundtrip.py +0 -0
  232. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/run.py +0 -0
  233. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/smoke.py +0 -0
  234. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/sources.py +0 -0
  235. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/stats.py +0 -0
  236. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/structs.py +0 -0
  237. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/txresult.py +0 -0
  238. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/unknowns.py +0 -0
  239. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/v2ipscaling.py +0 -0
  240. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/v2ipsettings.py +0 -0
  241. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/v2ipsubject.py +0 -0
  242. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/v2iptestcard.py +0 -0
  243. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/v2ipvlan.py +0 -0
  244. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/vdetails.py +0 -0
  245. {mx_remote-6.0.0 → mx_remote-6.2.0}/tests/wirefix.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: mx_remote
3
- Version: 6.0.0
3
+ Version: 6.2.0
4
4
  Summary: Python 3 library for interfacing with MX Remote compatible devices
5
5
  Project-URL: Homepage, https://github.com/opdenkamp/mx-remote/
6
6
  Project-URL: Documentation, https://opdenkamp.github.io/mx-remote/
@@ -308,6 +308,7 @@ itself, a profile out of range, or a schedule time that is not a time of day.
308
308
  # mesh operations
309
309
  await device.mesh_promote() # promote to mesh master
310
310
  await device.mesh_remove() # remove from mesh
311
+ await source.auto_assign_oneip_source_addresses() # drop addresses set by hand
311
312
 
312
313
  # firmware versions
313
314
  if device.oneip_firmware_versions:
@@ -315,6 +316,12 @@ if device.oneip_firmware_versions:
315
316
  print(f"{fw_type}: {fw.version}")
316
317
  ```
317
318
 
319
+ A OneIP source acts on `auto_assign_oneip_source_addresses()` only from
320
+ management, which this client announces itself as, and nothing acknowledges it:
321
+ the source's next configuration report carries the addresses it ends up with, in
322
+ `oneip_details`. A device that is not a source, or announces less than protocol
323
+ 0x2B, would ignore the operation, so it is refused before anything is sent.
324
+
318
325
  ### Time zone and time
319
326
 
320
327
  The mesh controller announces its time zone and clock with every periodic
@@ -2804,6 +2804,10 @@ class DeviceBase(ABC):
2804
2804
  async def mesh_promote(self) -> bool:
2805
2805
  '''promote to mesh master'''
2806
2806
 
2807
+ @abstractmethod
2808
+ async def auto_assign_oneip_source_addresses(self) -> bool:
2809
+ '''hand this OneIP source's stream addresses back to automatic assignment'''
2810
+
2807
2811
  @abstractmethod
2808
2812
  async def mesh_remove(self) -> bool:
2809
2813
  '''remove from mesh'''
@@ -1059,6 +1059,8 @@ class DeviceBase(ABC):
1059
1059
  @abstractmethod
1060
1060
  async def mesh_promote(self) -> bool: ...
1061
1061
  @abstractmethod
1062
+ async def auto_assign_oneip_source_addresses(self) -> bool: ...
1063
+ @abstractmethod
1062
1064
  async def mesh_remove(self) -> bool: ...
1063
1065
  @abstractmethod
1064
1066
  async def read_stats(self, enable: bool) -> bool: ...
@@ -14,7 +14,7 @@ Default communication modes:
14
14
  """
15
15
  import os
16
16
 
17
- VERSION = '6.0.0'
17
+ VERSION = '6.2.0'
18
18
  __version__ = VERSION
19
19
 
20
20
  MX_BCAST_UDP_PORT = 8811
@@ -22,6 +22,8 @@ class MeshOperation(IntEnum):
22
22
  REGENERATE_ADDRESSES = 3
23
23
  REPORT_CONTROLLER = 4
24
24
  PROMOTE_CONTROLLER = 5
25
+ AUTO_ADDRESSES = 6
26
+ '''Hand the target's source addresses back to automatic assignment.'''
25
27
  REPORT_MEMBERSHIP = 0xFF
26
28
 
27
29
  def __str__(self) -> str:
@@ -37,6 +39,8 @@ class MeshOperation(IntEnum):
37
39
  return "report controller"
38
40
  if self.value == MeshOperation.PROMOTE_CONTROLLER.value:
39
41
  return "promote controller"
42
+ if self.value == MeshOperation.AUTO_ADDRESSES.value:
43
+ return "automatic addresses"
40
44
  if self.value == MeshOperation.REPORT_MEMBERSHIP.value:
41
45
  return "report membership"
42
46
  return "unknown"
@@ -66,6 +70,13 @@ _WIRE_SIZE = 40
66
70
  _ACCEPT_PROTOCOL = 0x1A
67
71
  _INSTALLER_PROTOCOL = 0x1D
68
72
 
73
+ AUTO_ADDRESSES_PROTOCOL = 0x2B
74
+ '''The first protocol version whose devices can act on AUTO_ADDRESSES.
75
+
76
+ Not the stamp: that is this opcode's, and a device between the two takes the
77
+ frame and ignores an operation it does not know. Not every device on this
78
+ version has it either, but none below it does.'''
79
+
69
80
  class FrameMeshOperation(FrameBase):
70
81
  ''' Mesh operation '''
71
82
 
@@ -11,8 +11,11 @@ class MeshOperation(IntEnum):
11
11
  REGENERATE_ADDRESSES: int
12
12
  REPORT_CONTROLLER: int
13
13
  PROMOTE_CONTROLLER: int
14
+ AUTO_ADDRESSES: int
14
15
  REPORT_MEMBERSHIP: int
15
16
 
17
+ AUTO_ADDRESSES_PROTOCOL: int
18
+
16
19
  class FrameMeshOperation(FrameBase):
17
20
  @staticmethod
18
21
  def construct(mxr: DeviceRegistry, operation: MeshOperation, target: DeviceBase, option: DeviceBase | None = None) -> FrameBase | None: ...
@@ -35,7 +35,7 @@ from ..Interface import (
35
35
  )
36
36
  from ..proto.BayConfig import BayConfig
37
37
  from ..proto.FrameHello import FrameHello
38
- from ..proto.FrameMeshOperation import MeshOperation, FrameMeshOperation
38
+ from ..proto.FrameMeshOperation import AUTO_ADDRESSES_PROTOCOL, MeshOperation, FrameMeshOperation
39
39
  from ..proto.FrameV2IPStats import FrameV2IPStats
40
40
  from ..proto.FrameNetworkStatus import NetworkPortStatus
41
41
  from ..proto.FrameReboot import FrameReboot
@@ -1057,6 +1057,30 @@ class Device(DeviceBase):
1057
1057
  return True
1058
1058
  return False
1059
1059
 
1060
+ async def auto_assign_oneip_source_addresses(self) -> bool:
1061
+ '''Hand this OneIP source's stream addresses back to automatic assignment,
1062
+ undoing addresses that were set on it by hand.
1063
+
1064
+ The device takes this only from management, which this client announces
1065
+ itself as. Nothing acknowledges it: the device's next configuration
1066
+ report carries the addresses it ends up with, and oneip_details reads
1067
+ them.
1068
+
1069
+ Refused for a device that is not a OneIP source, and for one below
1070
+ protocol 0x2B, which predates the operation and ignores it.
1071
+ '''
1072
+ if (self.features is None) or (DeviceFeature.ONEIP_SOURCE not in self.features):
1073
+ _LOGGER.warning(f"not handing the addresses of {self} back to automatic assignment: it is not a OneIP source")
1074
+ return False
1075
+ if (self.protocol != 0) and (self.protocol < AUTO_ADDRESSES_PROTOCOL):
1076
+ _LOGGER.warning(f"not handing the addresses of {self} back to automatic assignment: it advertises "
1077
+ f"protocol {self.protocol:02X} and the operation needs {AUTO_ADDRESSES_PROTOCOL:02X}")
1078
+ return False
1079
+ frame = FrameMeshOperation.construct(mxr=self.registry, target=self, operation=MeshOperation.AUTO_ADDRESSES)
1080
+ if (frame is None):
1081
+ return False
1082
+ return self.registry.transmit(frame.frame) == len(frame.frame)
1083
+
1060
1084
  async def mesh_remove(self) -> bool:
1061
1085
  '''Remove this device from the mesh network.'''
1062
1086
  frame = FrameMeshOperation.construct(mxr=self.registry, target=self, operation=MeshOperation.UNREGISTER)
@@ -7,7 +7,7 @@ from ..proto.Constants import DeviceFeature as DeviceFeature, MXR_PROTOCOL_VERSI
7
7
  from ..proto.FrameBase import FrameBase as FrameBase
8
8
  from ..proto.FrameFirmwareVersion import FirmwareType as FirmwareType, FirmwareVersion as FirmwareVersion
9
9
  from ..proto.FrameHello import FrameHello as FrameHello
10
- from ..proto.FrameMeshOperation import FrameMeshOperation as FrameMeshOperation, MeshOperation as MeshOperation
10
+ from ..proto.FrameMeshOperation import AUTO_ADDRESSES_PROTOCOL as AUTO_ADDRESSES_PROTOCOL, FrameMeshOperation as FrameMeshOperation, MeshOperation as MeshOperation
11
11
  from ..proto.FrameNetworkStatus import NetworkPortStatus as NetworkPortStatus
12
12
  from ..proto.FramePing import FramePing as FramePing
13
13
  from ..proto.FrameReboot import FrameReboot as FrameReboot
@@ -223,6 +223,7 @@ class Device(DeviceBase):
223
223
  async def reboot(self) -> bool: ...
224
224
  async def ping(self) -> bool: ...
225
225
  async def mesh_promote(self) -> bool: ...
226
+ async def auto_assign_oneip_source_addresses(self) -> bool: ...
226
227
  async def mesh_remove(self) -> bool: ...
227
228
  async def read_stats(self, enable: bool) -> bool: ...
228
229
  async def set_oneip_auto_scaling(self, enabled: bool) -> bool: ...
@@ -20,6 +20,7 @@ import mx_remote
20
20
  from mx_remote import MxrDeviceUid, OneIPDeviceSetting as S, OneIPDeviceSettings, OneIPPowerSaveSchedule
21
21
  from mx_remote.proto.Constants import (ONEIP_IR_PROFILE_MAX, ONEIP_IR_PROFILE_NOT_SET,
22
22
  ONEIP_MINUTES_PER_DAY)
23
+ from mx_remote.proto.Constants import MXR_OPCODE_VERSIONS
23
24
  from mx_remote.proto.Factory import create_mxr_frame
24
25
 
25
26
  ADDR = ('192.0.2.9', 8812)
@@ -165,4 +166,41 @@ for ok in (OneIPDeviceSettings(valid=S.IR_PROFILE, ir_profile=ONEIP_IR_PROFILE_M
165
166
  assert call(mx.set_all_oneip_device_settings(ok)) is True, f'{ok} was refused'
166
167
  print('all refused : what every device would ignore is not sent')
167
168
 
169
+ # -------------------------------------------- a source's automatic addresses
170
+
171
+ # Mesh operation 6 names the source, with the parameter and padding zero, and
172
+ # is stamped as every mesh operation is.
173
+ def device(uid, protocol, features, serial):
174
+ rx_from(uid, 0x00, struct.pack('<H', protocol) + name('OneIP') + name(serial) + name('5.0.0')
175
+ + struct.pack('<I', int(features)), protocol=protocol)
176
+ return mx.get_by_uid(MxrDeviceUid(uid))
177
+
178
+ def rx_from(uid, opcode, payload, protocol):
179
+ frame = bytearray(create_mxr_frame(uid, opcode, payload))
180
+ frame[2] = protocol
181
+ mx.process_frame(time.time(), bytes(frame), ADDR)
182
+
183
+ SOURCE = mx_remote.DeviceFeature.ONEIP_SOURCE
184
+ src = device(bytes([0x50]) * 16, 0x2B, SOURCE, 'AA0001')
185
+ old = device(bytes([0x51]) * 16, 0x2A, SOURCE, 'AA0002')
186
+ sink_only = device(bytes([0x52]) * 16, 0x2B, mx_remote.DeviceFeature.ONEIP_SINK, 'AA0003')
187
+
188
+ sent.clear()
189
+ assert call(src.auto_assign_oneip_source_addresses()) is True
190
+ frame = sent.pop()
191
+ assert opcode(frame) == 0x3B and frame[2] == MXR_OPCODE_VERSIONS[0x3B], (opcode(frame), frame[2])
192
+ p = frame[24:]
193
+ assert len(p) == 40, 'a receiver drops a mesh operation shorter than 40 bytes'
194
+ assert p[:4] == bytes([6, 0, 0, 0]), p[:4].hex()
195
+ assert p[4:20] == bytes([0x50]) * 16, 'the frame names another device'
196
+ assert p[20:] == bytes(20), 'the parameter and padding'
197
+
198
+ refused(old.auto_assign_oneip_source_addresses(), 'a source below 0x2B, which ignores the operation')
199
+ refused(sink_only.auto_assign_oneip_source_addresses(), 'a device that is not a source')
200
+
201
+ mx.transmit = lambda data: 0
202
+ assert call(src.auto_assign_oneip_source_addresses()) is False, 'a failed send reported success'
203
+ mx.transmit = lambda data: (sent.append(data), len(data))[1]
204
+ print('auto addrs : mesh operation 6 to a source on 0x2B; anything else is refused')
205
+
168
206
  print('ALL OK')
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes