mx-remote 4.7.5__tar.gz → 4.7.7__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 (175) hide show
  1. {mx_remote-4.7.5 → mx_remote-4.7.7}/PKG-INFO +1 -1
  2. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/Interface.py +5 -0
  3. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/Interface.pyi +3 -0
  4. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/const.py +1 -1
  5. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPBayMapping.py +4 -2
  6. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPSources.py +1 -1
  7. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/V2IPConfig.py +7 -1
  8. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/V2IPConfig.pyi +4 -1
  9. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/Bay.py +15 -11
  10. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/Device.py +14 -8
  11. {mx_remote-4.7.5 → mx_remote-4.7.7}/.claude/settings.local.json +0 -0
  12. {mx_remote-4.7.5 → mx_remote-4.7.7}/.gitignore +0 -0
  13. {mx_remote-4.7.5 → mx_remote-4.7.7}/LICENSE +0 -0
  14. {mx_remote-4.7.5 → mx_remote-4.7.7}/README.md +0 -0
  15. {mx_remote-4.7.5 → mx_remote-4.7.7}/hatch_build.py +0 -0
  16. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/Uid.py +0 -0
  17. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/Uid.pyi +0 -0
  18. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/__init__.py +0 -0
  19. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/__init__.pyi +0 -0
  20. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/const.pyi +0 -0
  21. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/main.py +0 -0
  22. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/main.pyi +0 -0
  23. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/BayConfig.py +0 -0
  24. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/BayConfig.pyi +0 -0
  25. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/Constants.py +0 -0
  26. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/Constants.pyi +0 -0
  27. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/Data.py +0 -0
  28. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/Data.pyi +0 -0
  29. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/Factory.py +0 -0
  30. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/Factory.pyi +0 -0
  31. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameAmpDolbySettings.py +0 -0
  32. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameAmpDolbySettings.pyi +0 -0
  33. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameAmpZoneSettings.py +0 -0
  34. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameAmpZoneSettings.pyi +0 -0
  35. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameBase.py +0 -0
  36. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameBase.pyi +0 -0
  37. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameBayConfig.py +0 -0
  38. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameBayConfig.pyi +0 -0
  39. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameBayConfigSecondary.py +0 -0
  40. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameBayConfigSecondary.pyi +0 -0
  41. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameBayHide.py +0 -0
  42. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameBayHide.pyi +0 -0
  43. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameBayStatus.py +0 -0
  44. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameBayStatus.pyi +0 -0
  45. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameConnectStatus.py +0 -0
  46. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameConnectStatus.pyi +0 -0
  47. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameDebug.py +0 -0
  48. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameDebug.pyi +0 -0
  49. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameDiscover.py +0 -0
  50. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameDiscover.pyi +0 -0
  51. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameEDID.py +0 -0
  52. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameEDID.pyi +0 -0
  53. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameEDIDProfile.py +0 -0
  54. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameEDIDProfile.pyi +0 -0
  55. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameFactoryReset.py +0 -0
  56. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameFactoryReset.pyi +0 -0
  57. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameFilterStatus.py +0 -0
  58. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameFilterStatus.pyi +0 -0
  59. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameFirmwareVersion.py +0 -0
  60. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameFirmwareVersion.pyi +0 -0
  61. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameHeader.py +0 -0
  62. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameHeader.pyi +0 -0
  63. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameHello.py +0 -0
  64. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameHello.pyi +0 -0
  65. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameLinks.py +0 -0
  66. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameLinks.pyi +0 -0
  67. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameMeshOperation.py +0 -0
  68. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameMeshOperation.pyi +0 -0
  69. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameMirrorStatus.py +0 -0
  70. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameMirrorStatus.pyi +0 -0
  71. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameMonitoringPulse.py +0 -0
  72. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameMonitoringPulse.pyi +0 -0
  73. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameNetworkStatus.py +0 -0
  74. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameNetworkStatus.pyi +0 -0
  75. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FramePDUState.py +0 -0
  76. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FramePDUState.pyi +0 -0
  77. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FramePowerChange.py +0 -0
  78. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FramePowerChange.pyi +0 -0
  79. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameRCAction.py +0 -0
  80. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameRCAction.pyi +0 -0
  81. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameRCIr.py +0 -0
  82. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameRCIr.pyi +0 -0
  83. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameRCKey.py +0 -0
  84. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameRCKey.pyi +0 -0
  85. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameRCSettings.py +0 -0
  86. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameRCSettings.pyi +0 -0
  87. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameReboot.py +0 -0
  88. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameReboot.pyi +0 -0
  89. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameRoutingChange.py +0 -0
  90. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameRoutingChange.pyi +0 -0
  91. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSetInstaller.py +0 -0
  92. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSetInstaller.pyi +0 -0
  93. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSetName.py +0 -0
  94. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSetName.pyi +0 -0
  95. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSetRoute.py +0 -0
  96. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSetRoute.pyi +0 -0
  97. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSetupStatus.py +0 -0
  98. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSetupStatus.pyi +0 -0
  99. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSignalStatus.py +0 -0
  100. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSignalStatus.pyi +0 -0
  101. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSignalStatusNew.py +0 -0
  102. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSignalStatusNew.pyi +0 -0
  103. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSysTemperature.py +0 -0
  104. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSysTemperature.pyi +0 -0
  105. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSystemStatus.py +0 -0
  106. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameSystemStatus.pyi +0 -0
  107. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameTXRCAction.py +0 -0
  108. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameTXRCAction.pyi +0 -0
  109. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameTopology.py +0 -0
  110. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameTopology.pyi +0 -0
  111. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameTxIR.py +0 -0
  112. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameTxIR.pyi +0 -0
  113. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameUpgradeFPGA.py +0 -0
  114. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameUpgradeFPGA.pyi +0 -0
  115. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPAudio.py +0 -0
  116. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPAudio.pyi +0 -0
  117. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPBayMapping.pyi +0 -0
  118. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPDeviceConfiguration.py +0 -0
  119. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPDeviceConfiguration.pyi +0 -0
  120. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPLink.py +0 -0
  121. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPLink.pyi +0 -0
  122. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPManualSourceSwitch.py +0 -0
  123. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPManualSourceSwitch.pyi +0 -0
  124. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPMultiviewer.py +0 -0
  125. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPMultiviewer.pyi +0 -0
  126. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPPowerSave.py +0 -0
  127. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPPowerSave.pyi +0 -0
  128. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPSetMaster.py +0 -0
  129. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPSetMaster.pyi +0 -0
  130. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPSourceSwitch.py +0 -0
  131. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPSourceSwitch.pyi +0 -0
  132. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPSources.pyi +0 -0
  133. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPStats.py +0 -0
  134. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPStats.pyi +0 -0
  135. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPStreamDetails.py +0 -0
  136. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPStreamDetails.pyi +0 -0
  137. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPTiling.py +0 -0
  138. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameV2IPTiling.pyi +0 -0
  139. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameVolume.py +0 -0
  140. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameVolume.pyi +0 -0
  141. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameVolumeDown.py +0 -0
  142. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameVolumeDown.pyi +0 -0
  143. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameVolumeSet.py +0 -0
  144. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameVolumeSet.pyi +0 -0
  145. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameVolumeUp.py +0 -0
  146. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/FrameVolumeUp.pyi +0 -0
  147. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/LinkConfig.py +0 -0
  148. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/LinkConfig.pyi +0 -0
  149. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/Multiviewer.py +0 -0
  150. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/Multiviewer.pyi +0 -0
  151. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/PDUState.py +0 -0
  152. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/PDUState.pyi +0 -0
  153. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/Svd.py +0 -0
  154. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/Svd.pyi +0 -0
  155. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/V2IPStats.py +0 -0
  156. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/V2IPStats.pyi +0 -0
  157. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/__init__.py +0 -0
  158. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/__init__.pyi +0 -0
  159. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/proto/svd.csv +0 -0
  160. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/py.typed +0 -0
  161. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/Bay.pyi +0 -0
  162. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/ConnectionAsync.py +0 -0
  163. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/ConnectionAsync.pyi +0 -0
  164. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/Device.pyi +0 -0
  165. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/Link.py +0 -0
  166. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/Link.pyi +0 -0
  167. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/P8PDU.py +0 -0
  168. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/P8PDU.pyi +0 -0
  169. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/Remote.py +0 -0
  170. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/Remote.pyi +0 -0
  171. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/State.py +0 -0
  172. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/State.pyi +0 -0
  173. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/V2IP.py +0 -0
  174. {mx_remote-4.7.5 → mx_remote-4.7.7}/mx_remote/remote/V2IP.pyi +0 -0
  175. {mx_remote-4.7.5 → mx_remote-4.7.7}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mx_remote
3
- Version: 4.7.5
3
+ Version: 4.7.7
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://github.com/opdenkamp/mx-remote/
@@ -332,6 +332,11 @@ class V2IPStreamSources:
332
332
  All V2IP multicast IP addresses and port numbers used by a device
333
333
  """
334
334
 
335
+ @property
336
+ @abstractmethod
337
+ def uid(self) -> MxrDeviceUid|None:
338
+ ''' uid of the originating source device, when known '''
339
+
335
340
  @property
336
341
  @abstractmethod
337
342
  def video(self) -> V2IPStreamSource:
@@ -102,6 +102,9 @@ class V2IPStreamSource(ABC):
102
102
  def port(self) -> int: ...
103
103
 
104
104
  class V2IPStreamSources:
105
+ @property
106
+ @abstractmethod
107
+ def uid(self) -> MxrDeviceUid | None: ...
105
108
  @property
106
109
  @abstractmethod
107
110
  def video(self) -> V2IPStreamSource: ...
@@ -14,7 +14,7 @@ Default communication modes:
14
14
  """
15
15
  import os
16
16
 
17
- VERSION = '4.7.5'
17
+ VERSION = '4.7.7'
18
18
  __version__ = VERSION
19
19
 
20
20
  MX_BCAST_UDP_PORT = 8811
@@ -24,10 +24,12 @@ class FrameV2IPBayMapping(FrameBase):
24
24
  @cached_property
25
25
  def is_input(self) -> bool:
26
26
  '''Whether these are input bay mappings.'''
27
+ # Wire format: firmware sets bit 0 to ((mode == MBAY_MODE_INPUT) ? 1 : 0),
28
+ # so an input frame carries bit 0 = 1 (not 0).
27
29
  val = self.payload_u16(0)
28
30
  if (val is None):
29
31
  return False
30
- return (val & 1 == 0)
32
+ return (val & 1 == 1)
31
33
 
32
34
  @cached_property
33
35
  def is_output(self) -> bool:
@@ -35,7 +37,7 @@ class FrameV2IPBayMapping(FrameBase):
35
37
  val = self.payload_u16(0)
36
38
  if (val is None):
37
39
  return False
38
- return (val & 1 == 1)
40
+ return (val & 1 == 0)
39
41
 
40
42
  @cached_property
41
43
  def first_bay_id(self) -> int|None:
@@ -29,7 +29,7 @@ class FrameV2IPSources(FrameBase):
29
29
  if (pl is None):
30
30
  break
31
31
  cfg = V2IPConfig(self, srcnum, pl)
32
- rv.append(V2IPStreamSourcesImpl(video=cfg.video, audio=cfg.audio, anc=cfg.anc))
32
+ rv.append(V2IPStreamSourcesImpl(video=cfg.video, audio=cfg.audio, anc=cfg.anc, uid=cfg.uid))
33
33
  srcnum += 1
34
34
  return rv
35
35
 
@@ -71,11 +71,17 @@ class V2IPConfig:
71
71
  class V2IPStreamSourcesImpl(V2IPStreamSources):
72
72
  '''Concrete collection of V2IP stream sources (video, audio, ancillary, ARC).'''
73
73
 
74
- def __init__(self, video:V2IPStreamSource, audio:V2IPStreamSource, anc:V2IPStreamSource, arc:V2IPStreamSource|None=None) -> None:
74
+ def __init__(self, video:V2IPStreamSource, audio:V2IPStreamSource, anc:V2IPStreamSource, arc:V2IPStreamSource|None=None, uid:MxrDeviceUid|None=None) -> None:
75
75
  self._video = video
76
76
  self._audio = audio
77
77
  self._anc = anc
78
78
  self._arc = arc
79
+ self._uid = uid
80
+
81
+ @property
82
+ @override
83
+ def uid(self) -> MxrDeviceUid|None:
84
+ return self._uid
79
85
 
80
86
  @property
81
87
  @override
@@ -28,7 +28,10 @@ class V2IPConfig:
28
28
  def uid(self) -> MxrDeviceUid: ...
29
29
 
30
30
  class V2IPStreamSourcesImpl(V2IPStreamSources):
31
- def __init__(self, video: V2IPStreamSource, audio: V2IPStreamSource, anc: V2IPStreamSource, arc: V2IPStreamSource | None = None) -> None: ...
31
+ def __init__(self, video: V2IPStreamSource, audio: V2IPStreamSource, anc: V2IPStreamSource, arc: V2IPStreamSource | None = None, uid: MxrDeviceUid | None = None) -> None: ...
32
+ @property
33
+ @override
34
+ def uid(self) -> MxrDeviceUid | None: ...
32
35
  @property
33
36
  @override
34
37
  def video(self) -> V2IPStreamSource: ...
@@ -143,17 +143,21 @@ class Bay(BayBase):
143
143
  @property
144
144
  @override
145
145
  def bay_uid(self) -> MxrBayUid:
146
- # In a OneIP mesh, the same physical source can be re-advertised by
147
- # multiple devices (e.g. forwarded through the mesh) under different
148
- # v2ip_uids. Dedup by multicast video IP that uniquely identifies a
149
- # stream and return the originating TX's first-input bay_uid so the
150
- # same source has the same bay_uid regardless of who is advertising it.
151
- if self.is_v2ip_source and ((stream := self.v2ip_source) is not None):
152
- video_ip = stream.video.ip if stream.video is not None else None
153
- if (video_ip is not None) and (video_ip != '0.0.0.0'):
154
- canonical = self.device.registry.get_by_stream_ip(ip=video_ip)
155
- if canonical is not None:
156
- return MxrBayUid(canonical.device.remote_id, canonical.port)
146
+ # In a OneIP mesh the same source can be advertised by multiple devices
147
+ # (mesh forwarding etc.). Resolve a v2ip source bay to (source_uid, 0)
148
+ # every OneIP unit has at most one input, always at port 0 — using the
149
+ # source uid from MXR_OP_SYS_BAY_V2IP_SOURCES, falling back to the bay
150
+ # mapping uid if the sources frame hasn't supplied one. Yields a single
151
+ # stable bay_uid regardless of who advertises the source.
152
+ if self.is_v2ip_source:
153
+ src_uid:MxrDeviceUid|None = None
154
+ stream = self.v2ip_source
155
+ if (stream is not None) and (stream.uid is not None) and not stream.uid.empty:
156
+ src_uid = stream.uid
157
+ elif (self._v2ip_uid is not None) and not self._v2ip_uid.empty:
158
+ src_uid = self._v2ip_uid
159
+ if src_uid is not None:
160
+ return MxrBayUid(src_uid, 0)
157
161
  return MxrBayUid(self.device.remote_id, self.port)
158
162
 
159
163
  @property
@@ -203,9 +203,15 @@ class Device(DeviceBase):
203
203
  return None
204
204
  if self._v2ip_sources is None:
205
205
  return None
206
- if bay.bay >= len(self._v2ip_sources):
206
+ # Firmware fills MXR_OP_SYS_BAY_V2IP_SOURCES by iterating bays in order
207
+ # (MBAY_ITERATE). Devices with no local input (pure RX) skip bay 0, so
208
+ # the list starts at bay 1 — shift the lookup so bay.bay still maps to
209
+ # the right entry.
210
+ offset = 0 if self.has_local_source else 1
211
+ idx = bay.bay - offset
212
+ if (idx < 0) or (idx >= len(self._v2ip_sources)):
207
213
  return None
208
- return self._v2ip_sources[bay.bay]
214
+ return self._v2ip_sources[idx]
209
215
 
210
216
  @property
211
217
  def v2ip_stats(self) -> V2IPDeviceStats|None:
@@ -619,13 +625,13 @@ class Device(DeviceBase):
619
625
  elif isinstance(data, FrameV2IPBayMapping):
620
626
  if data.first_bay_id is None:
621
627
  return
628
+ # Firmware iterates bays in MBAY_ITERATE order; the wire payload's
629
+ # first_bay_id tells us the bay number of payload[0], so payload[i]
630
+ # maps to bay number (first_bay_id + i). Devices without a local
631
+ # bay 0 (pure RX) emit first_bay_id=1 and skip the bay-0 slot.
632
+ mode = 'Input' if data.is_input else 'Output'
622
633
  for idx in range(data.nb_bays):
623
- if (idx == 0):
624
- if data.is_input and self.is_oneip_rx:
625
- continue
626
- if data.is_output and (self.is_oneip_tx or self.is_oneip_multiviewer):
627
- continue
628
- bay = self.get_by_mode_bay(mode=('Input' if data.is_input else 'Output'), bay=idx)
634
+ bay = self.get_by_mode_bay(mode=mode, bay=data.first_bay_id + idx)
629
635
  if (bay is not None):
630
636
  bay.v2ip_uid = data.bay(idx=idx) # pyright: ignore[reportAttributeAccessIssue]
631
637
  elif isinstance(data, FrameSystemStatus):
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