machine-logic-sdk 3.0.2__tar.gz → 3.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/PKG-INFO +4 -17
  2. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/README.md +1 -13
  3. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/event_listener.py +1 -3
  4. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/iactuator.py +9 -2
  5. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/iactuator_group.py +1 -1
  6. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/icalibration_frame.py +18 -4
  7. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/idigital_input.py +18 -4
  8. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/idigital_io_shared.py +24 -1
  9. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/idigital_output.py +16 -1
  10. machine_logic_sdk-3.1.0/machinelogic/ivention/iethernet_ip.py +79 -0
  11. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/imachine.py +48 -5
  12. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/imachine_motion.py +11 -0
  13. machine_logic_sdk-3.1.0/machinelogic/ivention/imqtt.py +62 -0
  14. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/irobot.py +147 -1
  15. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/irobot_move_sequence.py +40 -2
  16. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/machine_configuration.py +4 -6
  17. machine_logic_sdk-3.1.0/machinelogic/ivention/move_until_tool_contact_result.py +34 -0
  18. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/test_imachine.py +59 -3
  19. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/test_mqtt_client.py +49 -9
  20. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/robot_types.py +1 -0
  21. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/ac_motor.py +1 -1
  22. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/actuator.py +1 -1
  23. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/actuator_group.py +1 -1
  24. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/calibration_frame.py +1 -1
  25. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/camera.py +1 -1
  26. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/cartesian_target.py +1 -1
  27. machine_logic_sdk-3.1.0/machinelogic/machinelogic/communication/ethernet_ip.py +75 -0
  28. machine_logic_sdk-3.1.0/machinelogic/machinelogic/communication/ethernet_ip_client_adapter.py +102 -0
  29. machine_logic_sdk-3.1.0/machinelogic/machinelogic/communication/mqtt.py +44 -0
  30. {machine_logic_sdk-3.0.2/machinelogic/ivention → machine_logic_sdk-3.1.0/machinelogic/machinelogic/communication}/mqtt_client.py +40 -48
  31. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/env_conf.py +11 -0
  32. machine_logic_sdk-3.1.0/machinelogic/machinelogic/external_apis/__init__.py +1 -0
  33. machine_logic_sdk-3.1.0/machinelogic/machinelogic/external_apis/async_grpc_client.py +83 -0
  34. {machine_logic_sdk-3.0.2/machinelogic/machinelogic → machine_logic_sdk-3.1.0/machinelogic/machinelogic/external_apis}/execution_engine_api.py +2 -2
  35. {machine_logic_sdk-3.0.2/machinelogic/machinelogic → machine_logic_sdk-3.1.0/machinelogic/machinelogic/external_apis}/firmware_api.py +24 -3
  36. machine_logic_sdk-3.1.0/machinelogic/machinelogic/external_apis/sync_grpc_client.py +137 -0
  37. {machine_logic_sdk-3.0.2/machinelogic/machinelogic → machine_logic_sdk-3.1.0/machinelogic/machinelogic/io}/digital_input.py +3 -3
  38. machine_logic_sdk-3.1.0/machinelogic/machinelogic/io/digital_output.py +47 -0
  39. machine_logic_sdk-3.1.0/machinelogic/machinelogic/io/io_module_service_client_adapter.py +243 -0
  40. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/joint_target.py +1 -1
  41. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/machine.py +102 -17
  42. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/machine_motion.py +1 -1
  43. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/path_follower.py +1 -1
  44. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/pneumatic.py +3 -3
  45. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/reference_frame.py +1 -1
  46. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/robot/robot.py +87 -5
  47. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/robot/robot_move.py +10 -16
  48. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/robot/robot_move_sequence.py +82 -8
  49. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/robot/robot_state.py +1 -1
  50. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/robot/vrmcs_client_adapter.py +157 -50
  51. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/scene.py +1 -1
  52. machine_logic_sdk-3.1.0/machinelogic/machinelogic/tests/test_async_grpc_client.py +211 -0
  53. machine_logic_sdk-3.1.0/machinelogic/machinelogic/tests/test_env_conf.py +94 -0
  54. machine_logic_sdk-3.1.0/machinelogic/machinelogic/tests/test_ethernet_ip.py +214 -0
  55. machine_logic_sdk-3.1.0/machinelogic/machinelogic/tests/test_ethernet_ip_adapter.py +269 -0
  56. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_firmware_api.py +47 -8
  57. machine_logic_sdk-3.1.0/machinelogic/machinelogic/tests/test_io_module_client_adapter.py +584 -0
  58. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_listener.py +1 -1
  59. machine_logic_sdk-3.1.0/machinelogic/machinelogic/tests/test_machine.py +679 -0
  60. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_robot.py +256 -2
  61. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_robot_move.py +4 -13
  62. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_robot_move_sequence.py +186 -1
  63. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_robot_state.py +1 -1
  64. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_robot_transforms.py +73 -0
  65. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_scene.py +1 -1
  66. machine_logic_sdk-3.1.0/machinelogic/machinelogic/tests/test_sync_grpc_client.py +350 -0
  67. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_vrmcs_client_adapter.py +339 -50
  68. machine_logic_sdk-3.1.0/machinelogic/machinelogic/utils/listener.py +47 -0
  69. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/utils/robot_transforms.py +41 -0
  70. machine_logic_sdk-3.1.0/machinelogic/measurements/__init__.py +0 -0
  71. machine_logic_sdk-3.1.0/machinelogic/measurements/tests/__init__.py +0 -0
  72. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/pyproject.toml +3 -5
  73. machine_logic_sdk-3.0.2/machinelogic/machinelogic/digital_output.py +0 -17
  74. machine_logic_sdk-3.0.2/machinelogic/machinelogic/robot/listener.py +0 -37
  75. machine_logic_sdk-3.0.2/machinelogic/machinelogic/tests/test_env_conf.py +0 -73
  76. machine_logic_sdk-3.0.2/machinelogic/machinelogic/tests/test_machine.py +0 -356
  77. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/__init__.py +0 -0
  78. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/decorators/__init__.py +0 -0
  79. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/decorators/deprecated.py +0 -0
  80. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/decorators/future_api.py +0 -0
  81. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/decorators/tests/__init__.py +0 -0
  82. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/decorators/tests/test_deprecated.py +0 -0
  83. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/decorators/tests/test_future_api.py +0 -0
  84. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/decorators/tests/test_undocumented.py +0 -0
  85. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/decorators/undocumented.py +0 -0
  86. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/__init__.py +0 -0
  87. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/exception.py +0 -0
  88. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/handle.py +0 -0
  89. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/iac_motor.py +0 -0
  90. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/icamera.py +0 -0
  91. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/icartesian_target.py +0 -0
  92. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/igeneric_joint_constraint.py +0 -0
  93. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/ijoint_target.py +0 -0
  94. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/ipath_follower.py +0 -0
  95. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/ipneumatic.py +0 -0
  96. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/ireference_frame.py +0 -0
  97. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/irobot_alarm.py +0 -0
  98. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/iscene.py +0 -0
  99. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/__init__.py +0 -0
  100. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/test_batch_move.py +0 -0
  101. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/test_event_listener.py +0 -0
  102. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/test_icartesian_target.py +0 -0
  103. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/test_idigital_input.py +0 -0
  104. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/test_idigital_output.py +0 -0
  105. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/test_igeneric_joint_constraint.py +0 -0
  106. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/test_ijoint_target.py +0 -0
  107. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/test_ipath_follower.py +0 -0
  108. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/test_ireference_frame.py +0 -0
  109. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/tests/test_irobot.py +0 -0
  110. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/__init__.py +0 -0
  111. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/ac_motor_details.py +0 -0
  112. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/actuator_details.py +0 -0
  113. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/batch_move.py +0 -0
  114. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/estop_status.py +0 -0
  115. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/input_details.py +0 -0
  116. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/output_details.py +0 -0
  117. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/path_follower_status.py +0 -0
  118. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/path_follower_tool.py +0 -0
  119. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/pneumatic_details.py +0 -0
  120. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/robot_calibration.py +0 -0
  121. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/robot_pose.py +0 -0
  122. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/robot_tcp.py +0 -0
  123. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/types/scene_assets.py +0 -0
  124. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/util/__init__.py +0 -0
  125. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/ivention/util/inheritance.py +0 -0
  126. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/__init__.py +0 -0
  127. {machine_logic_sdk-3.0.2/machinelogic/machinelogic/robot → machine_logic_sdk-3.1.0/machinelogic/machinelogic/communication}/__init__.py +0 -0
  128. {machine_logic_sdk-3.0.2/machinelogic/machinelogic/utils → machine_logic_sdk-3.1.0/machinelogic/machinelogic/io}/__init__.py +0 -0
  129. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/motion_profile.py +0 -0
  130. {machine_logic_sdk-3.0.2/machinelogic/measurements → machine_logic_sdk-3.1.0/machinelogic/machinelogic/robot}/__init__.py +0 -0
  131. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/robot/generic_joint_constraint.py +0 -0
  132. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/robot/robot_alarm.py +0 -0
  133. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/robot/robot_utils.py +0 -0
  134. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/MatrixAssertionsMixin.py +0 -0
  135. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/__init__.py +0 -0
  136. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_ac_motor.py +0 -0
  137. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_actuator.py +0 -0
  138. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_actuator_group.py +0 -0
  139. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_calibration_frame.py +0 -0
  140. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_cartesian_target.py +0 -0
  141. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_compute_position_relative_to_base.py +0 -0
  142. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_joint_target.py +0 -0
  143. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_path_follower.py +0 -0
  144. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_pneumatic.py +0 -0
  145. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_pose_conversions.py +0 -0
  146. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/tests/test_reference_frame.py +0 -0
  147. {machine_logic_sdk-3.0.2/machinelogic/measurements/tests → machine_logic_sdk-3.1.0/machinelogic/machinelogic/utils}/__init__.py +0 -0
  148. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/utils/compute_position_relative_to_base.py +0 -0
  149. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/machinelogic/utils/robot_pose_conversions.py +0 -0
  150. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/measurements/angle.py +0 -0
  151. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/measurements/distance.py +0 -0
  152. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/measurements/tests/angle_test.py +0 -0
  153. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/measurements/tests/distance_test.py +0 -0
  154. {machine_logic_sdk-3.0.2 → machine_logic_sdk-3.1.0}/machinelogic/types/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: machine-logic-sdk
3
- Version: 3.0.2
3
+ Version: 3.1.0
4
4
  Summary: SDK for controlling Vention hardware
5
5
  License: Proprietary
6
6
  Keywords: Vention,MachineLogic,SDK,Robot,Automation
@@ -16,13 +16,12 @@ Requires-Dist: numpy (>=1.21,<2.0)
16
16
  Requires-Dist: paho-mqtt (>=1.5,<2.0)
17
17
  Requires-Dist: python-statemachine (>=2.5,<3.0)
18
18
  Requires-Dist: requests (>=2.28,<3.0)
19
- Requires-Dist: roslibpy (>=1.4,<2.0)
20
19
  Requires-Dist: scipy (>=1.8,<2.0)
21
20
  Requires-Dist: toml (>=0.10,<0.11)
22
21
  Requires-Dist: typing_extensions (>=4.8,<5.0)
23
22
  Requires-Dist: urllib3 (>=2.6.3)
24
- Requires-Dist: uv (>=0.6,<0.7)
25
- Requires-Dist: vention-firmware-grpc-client (==0.1.1)
23
+ Requires-Dist: uv (>=0.9.6,<0.10)
24
+ Requires-Dist: vention-firmware-grpc-client (==1.1.0)
26
25
  Project-URL: Documentation, https://vention.io/resources/guides/machinelogic-python-programming-514
27
26
  Description-Content-Type: text/markdown
28
27
 
@@ -38,18 +37,6 @@ Provides a programmatic interface in Python to control Vention hardware and coor
38
37
  - **Real-time Monitoring**: Access live robot positions, states, and sensor data
39
38
  - **Safety Integration**: Built-in safety state monitoring and emergency stops
40
39
 
41
- ## Table of Contents
42
-
43
- 1. [Installation](#installation)
44
- 2. [Quick Start](#quick-start)
45
- 3. [Requirements](#requirements)
46
- 4. [Basic Usage](#basic-usage)
47
- 5. [Examples](#examples)
48
- 6. [Development](#development)
49
- 7. [Documentation](#documentation)
50
- 8. [Contributing](#contributing)
51
- 9. [Support](#support)
52
-
53
40
  ## Installation
54
41
 
55
42
  Install the machine-logic-sdk from PyPI:
@@ -63,7 +50,7 @@ pip install machine-logic-sdk
63
50
  Please pay close attention to the compatibility table provided in the [Official machine-logic-sdk Documentation](https://docs.vention.io/docs/en/vention-python-api)
64
51
  to determine which version of the sdk is compatible with your version of MachineMotion.
65
52
 
66
- For development installations, see the [Development](#development) section below.
53
+ For development installations, see the Development section below.
67
54
 
68
55
  ## Quick Start
69
56
 
@@ -10,18 +10,6 @@ Provides a programmatic interface in Python to control Vention hardware and coor
10
10
  - **Real-time Monitoring**: Access live robot positions, states, and sensor data
11
11
  - **Safety Integration**: Built-in safety state monitoring and emergency stops
12
12
 
13
- ## Table of Contents
14
-
15
- 1. [Installation](#installation)
16
- 2. [Quick Start](#quick-start)
17
- 3. [Requirements](#requirements)
18
- 4. [Basic Usage](#basic-usage)
19
- 5. [Examples](#examples)
20
- 6. [Development](#development)
21
- 7. [Documentation](#documentation)
22
- 8. [Contributing](#contributing)
23
- 9. [Support](#support)
24
-
25
13
  ## Installation
26
14
 
27
15
  Install the machine-logic-sdk from PyPI:
@@ -35,7 +23,7 @@ pip install machine-logic-sdk
35
23
  Please pay close attention to the compatibility table provided in the [Official machine-logic-sdk Documentation](https://docs.vention.io/docs/en/vention-python-api)
36
24
  to determine which version of the sdk is compatible with your version of MachineMotion.
37
25
 
38
- For development installations, see the [Development](#development) section below.
26
+ For development installations, see the Development section below.
39
27
 
40
28
  ## Quick Start
41
29
 
@@ -2,8 +2,6 @@
2
2
 
3
3
  from typing import Callable, Optional
4
4
 
5
- import paho.mqtt.client as mqtt
6
-
7
5
  from .handle import Handle
8
6
 
9
7
  EventCallback = Callable[[str, Optional[str]], None]
@@ -76,5 +74,5 @@ class EventListenerManager:
76
74
  message (str): Message
77
75
  """
78
76
  for listener in self._listeners:
79
- if mqtt.topic_matches_sub(listener.topic, topic):
77
+ if listener.topic == topic:
80
78
  listener.callback(topic, message)
@@ -43,12 +43,14 @@ class ActuatorState:
43
43
 
44
44
  @property
45
45
  def end_sensors(self) -> Tuple[bool, bool]:
46
- """A tuple representing the state of the [ home, end ] sensors."""
46
+ """A tuple representing the state of the [ home, end ] sensors.
47
+ On machines without end sensors wired, both values remain False."""
47
48
  return self._end_sensors
48
49
 
49
50
  @property
50
51
  def move_in_progress(self) -> bool:
51
- """The boolean is True if a move is in progress, otherwise False."""
52
+ """The boolean is True if the actuator has not yet reached its target position, otherwise False.
53
+ Always False during continuous moves, which have no target position."""
52
54
  return self._move_in_progress
53
55
 
54
56
 
@@ -183,6 +185,8 @@ class IActuator(ABC):
183
185
  """
184
186
  Moves absolute synchronously to the specified position.
185
187
 
188
+ Absolute positions are only meaningful after the actuator has been homed.
189
+
186
190
  Args:
187
191
  position (float): The position to move to.
188
192
  motion_profile (MotionProfile): The motion profile to move with. See MotionProfile class.
@@ -242,6 +246,9 @@ class IActuator(ABC):
242
246
  """
243
247
  Home the Actuator synchronously.
244
248
 
249
+ Homing establishes the actuator's position reference. Absolute positions are
250
+ only meaningful after the actuator has been homed.
251
+
245
252
  Args:
246
253
  timeout (float): The timeout in seconds.
247
254
 
@@ -22,7 +22,7 @@ class ActuatorGroupState:
22
22
 
23
23
  @property
24
24
  def move_in_progress(self) -> bool:
25
- """The boolean is True if the ActuatorGroup has at least one Actuator in progress"""
25
+ """The boolean is True if at least one Actuator in the ActuatorGroup has not yet reached its target position."""
26
26
  for actuator_state in self._actuator_states:
27
27
  if actuator_state.move_in_progress:
28
28
  return True
@@ -43,7 +43,8 @@ class ICalibrationFrameConfiguration(ABC):
43
43
  @abstractmethod
44
44
  def calibrated_value(self) -> Union[CartesianPose, None]:
45
45
  """The calibrated value of the Calibration Frame,
46
- in mm and degrees, where the angles are extrinsic Euler angles in XYZ order."""
46
+ in mm and degrees, where the angles are extrinsic Euler angles in XYZ order.
47
+ None until the frame has been calibrated at runtime."""
47
48
 
48
49
 
49
50
  class ICalibrationFrame(ABC):
@@ -61,7 +62,9 @@ class ICalibrationFrame(ABC):
61
62
 
62
63
  @abstractmethod
63
64
  def get_default_value(self) -> CartesianPose:
64
- """Gets the calibration frame's default values.
65
+ """Gets the calibration frame's default (nominal) value, as defined in the scene.
66
+ This value is always available and is the safe fallback when
67
+ get_calibrated_value() returns None.
65
68
 
66
69
  Raises:
67
70
  SceneException: If failed to get the default value
@@ -75,12 +78,23 @@ class ICalibrationFrame(ABC):
75
78
  def get_calibrated_value(self) -> Union[CartesianPose, None]:
76
79
  """Gets the calibration frame's calibrated values.
77
80
 
81
+ Returns None until the frame has been calibrated at runtime (for example by a
82
+ camera calibration routine or by set_calibrated_value). Always fall back to the
83
+ nominal value when no calibration exists:
84
+
85
+ pose = frame.get_calibrated_value() or frame.get_default_value()
86
+
87
+ Passing the result of get_calibrated_value() directly into a robot move is not
88
+ recommended: if the frame has not been calibrated the value is None and the
89
+ move will fail.
90
+
78
91
  Raises:
79
92
  SceneException: If failed to get the calibrated value
80
93
 
81
94
  Returns:
82
- CartesianPose: The calibrated value of the calibration frame
83
- in mm and degrees, where the angles are extrinsic Euler angles in XYZ order.
95
+ Union[CartesianPose, None]: The calibrated value of the calibration frame
96
+ in mm and degrees, where the angles are extrinsic Euler angles in XYZ order,
97
+ or None if the frame has not been calibrated.
84
98
  """
85
99
 
86
100
  @abstractmethod
@@ -1,4 +1,5 @@
1
1
  from abc import ABC
2
+ from datetime import datetime
2
3
  from typing import Callable, Optional, Union
3
4
 
4
5
  from ..decorators.future_api import future_api
@@ -79,12 +80,25 @@ class IDigitalInput(ABC):
79
80
 
80
81
  def _set_value(self, new_value: bool) -> None:
81
82
  """
82
- Sets the DigitalInput state to the provided new_value. Listeners
83
- will be notified.
83
+ Sets the DigitalInput state to the provided new_value.
84
+ Listeners will be notified.
84
85
 
85
86
  Args:
86
87
  new_value (bool): The new value for the DigitalInput state.
87
88
  """
88
- # move honest new_value into the state object.
89
- self._state._value = bool(new_value) # pylint: disable=protected-access
89
+ self._state._value = new_value
90
+ self._state._timestamp = datetime.now()
91
+ self._event_listener_manager.notify_listeners("onchange")
92
+
93
+ def _set_value_with_timestamp(self, new_value: bool, timestamp: datetime) -> None:
94
+ """
95
+ Sets the DigitalInput state value and timestamp from a gRPC stream update.
96
+ Listeners will be notified.
97
+
98
+ Args:
99
+ new_value (bool): The new value for the DigitalInput state.
100
+ timestamp (datetime): The timestamp of the state update from gRPC.
101
+ """
102
+ self._state._value = new_value
103
+ self._state._timestamp = timestamp
90
104
  self._event_listener_manager.notify_listeners("onchange")
@@ -1,5 +1,8 @@
1
1
  from abc import ABC
2
- from typing import Literal
2
+ from datetime import datetime
3
+ from typing import Literal, Optional
4
+
5
+ IO_MODULE_DEVICE_TYPES = frozenset({"digitalIOModule", "pushButtonModule", "powerSwitchModule"})
3
6
 
4
7
 
5
8
  class DigitalIOState:
@@ -12,6 +15,7 @@ class DigitalIOState:
12
15
  # attribute (and have it work throughout the application).
13
16
  self._configuration = configuration
14
17
  self._value: bool = False # honest value, ignoring "active_high" flips.
18
+ self._timestamp: Optional[datetime] = None
15
19
 
16
20
  @property
17
21
  def value(self) -> bool:
@@ -23,6 +27,14 @@ class DigitalIOState:
23
27
  return not self._value
24
28
  return self._value
25
29
 
30
+ @property
31
+ def timestamp(self) -> Optional[datetime]:
32
+ """
33
+ Timestamp of the last state update.
34
+ Returns None if no update has been received yet.
35
+ """
36
+ return self._timestamp
37
+
26
38
 
27
39
  class DigitalIOConfiguration(ABC):
28
40
  """
@@ -40,6 +52,7 @@ class DigitalIOConfiguration(ABC):
40
52
  controller_port: int,
41
53
  pin: int | Literal["A", "B"],
42
54
  active_high: bool,
55
+ device_type: str = "",
43
56
  ) -> None:
44
57
  self._uuid: str = uuid
45
58
  self._name: str = name
@@ -48,6 +61,7 @@ class DigitalIOConfiguration(ABC):
48
61
  self._controller_port: int = controller_port
49
62
  self._pin: int | Literal["A", "B"] = pin
50
63
  self._active_high: bool = active_high
64
+ self._device_type: str = device_type
51
65
 
52
66
  @property
53
67
  def name(self) -> str:
@@ -88,3 +102,12 @@ class DigitalIOConfiguration(ABC):
88
102
  def uuid(self) -> str:
89
103
  """The unique ID of the DigitalInput/DigitalOutput."""
90
104
  return self._uuid
105
+
106
+ @property
107
+ def device_type(self) -> str:
108
+ """The device type string (e.g. 'digitalIOModule', 'pushButtonModule', 'powerSwitchModule', 'motor')."""
109
+ return self._device_type
110
+
111
+ @property
112
+ def _is_io_module(self) -> bool:
113
+ return self._device_type in IO_MODULE_DEVICE_TYPES
@@ -1,4 +1,5 @@
1
1
  from abc import ABC, abstractmethod
2
+ from datetime import datetime
2
3
 
3
4
  from ..decorators.future_api import future_api
4
5
  from .idigital_io_shared import DigitalIOConfiguration, DigitalIOState
@@ -74,4 +75,18 @@ class IDigitalOutput(ABC):
74
75
  Args:
75
76
  new_value (bool): The new value for the Output state.
76
77
  """
77
- self._state._value = new_value # pylint: disable=protected-access
78
+ # pylint: disable=protected-access
79
+ self._state._value = new_value
80
+ self._state._timestamp = datetime.now()
81
+
82
+ def _set_value_with_timestamp(self, new_value: bool, timestamp: datetime) -> None:
83
+ """
84
+ Sets the Output state value and timestamp from a gRPC output event stream.
85
+
86
+ Args:
87
+ new_value (bool): The new value for the Output state.
88
+ timestamp (datetime): The timestamp of the state update from gRPC.
89
+ """
90
+ # pylint: disable=protected-access
91
+ self._state._value = new_value
92
+ self._state._timestamp = timestamp
@@ -0,0 +1,79 @@
1
+ """Interface for the EtherNet/IP communication module."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from typing import Callable
5
+
6
+ from machinelogic.decorators.undocumented import undocumented
7
+
8
+
9
+ class IEthernetIp(ABC):
10
+ """
11
+ A software representation of an EtherNet/IP (EIP) communication interface.
12
+
13
+ EtherNet/IP allows the Machine to exchange data with external PLCs.
14
+ User Inputs are values sent from the Machine to the PLC, and User Outputs
15
+ are values received from the PLC.
16
+
17
+ It is not recommended that you construct this object yourself.
18
+ Instead, access it via the Machine instance:
19
+
20
+ E.g.:
21
+ machine = Machine()
22
+ machine.ethernet_ip.connect()
23
+ """
24
+
25
+ @abstractmethod
26
+ def connect(self) -> None:
27
+ """
28
+ Establish a connection to the EtherNet/IP service.
29
+
30
+ This must be called before any other EtherNet/IP operations.
31
+
32
+ Raises:
33
+ RuntimeError: If the connection cannot be established.
34
+ """
35
+
36
+ @abstractmethod
37
+ def set_user_input(self, parameter_name: str, value: int) -> None:
38
+ """
39
+ Set a User Input value to be sent to the PLC.
40
+
41
+ Args:
42
+ parameter_name (str): The name of the User Input param as defined in the EDS file.
43
+ value (int): The integer value to set.
44
+
45
+ Raises:
46
+ RuntimeError: If not connected.
47
+ """
48
+
49
+ @abstractmethod
50
+ def on_user_output(self, parameter_name: str, callback: Callable[[int], None]) -> int:
51
+ """
52
+ Register a callback that fires whenever the specified User Output value
53
+ changes. When the PLC changes the User Output values, the callback receives
54
+ the corresponding new integer value.
55
+
56
+ Args:
57
+ parameter_name (str): The name of the User Output parameter as defined in the EDS file.
58
+ callback (Callable[[int], None]): A function that receives the new User Output value as an integer.
59
+
60
+ Returns:
61
+ int: A handle that can be passed to ``remove_on_user_output_callback`` to unregister.
62
+
63
+ Raises:
64
+ RuntimeError: If not connected.
65
+ """
66
+
67
+ @abstractmethod
68
+ def remove_on_user_output_callback(self, callback_id: int) -> None:
69
+ """
70
+ Remove a previously registered callback for User Output changes.
71
+
72
+ Args:
73
+ callback_id (int): The ID of the callback to remove.
74
+ """
75
+
76
+ @abstractmethod
77
+ @undocumented
78
+ def _cleanup(self) -> None:
79
+ """Release all resources and close the connection."""
@@ -4,6 +4,9 @@ from abc import ABC, abstractmethod
4
4
  from enum import Enum
5
5
  from typing import Callable, Optional, Union
6
6
 
7
+ from machinelogic.machinelogic.communication.mqtt_client import MqttClient
8
+
9
+ from ..decorators.deprecated import deprecated
7
10
  from ..decorators.future_api import future_api
8
11
  from .exception import MachineException, MachineMotionException
9
12
  from .iac_motor import IACMotor
@@ -11,11 +14,12 @@ from .iactuator import IActuator
11
14
  from .icamera import ICamera
12
15
  from .idigital_input import IDigitalInput
13
16
  from .idigital_output import IDigitalOutput
17
+ from .iethernet_ip import IEthernetIp
14
18
  from .imachine_motion import IMachineMotion
19
+ from .imqtt import IMqtt
15
20
  from .ipneumatic import IPneumatic
16
21
  from .irobot import IRobot
17
22
  from .iscene import IScene
18
- from .mqtt_client import MqttClient
19
23
 
20
24
 
21
25
  class MachineOperationalState(Enum):
@@ -71,22 +75,36 @@ class IMachine(ABC):
71
75
  machine_motions: list[IMachineMotion],
72
76
  mqtt_client: MqttClient,
73
77
  scene: IScene,
78
+ ethernet_ip: IEthernetIp,
74
79
  ) -> None:
75
80
  """
76
81
  Args:
77
82
  machine_motions (list[IMachineMotion]): The list of MachineMotions.
78
83
  mqtt_client (MqttClient): The Mqtt client.
79
84
  scene (IScene): The scene instance.
85
+ ethernet_ip (IEthernetIp): The EthernetIP communication interface.
80
86
  """
81
87
  self._machine_motions = machine_motions
82
88
  self._mqtt_client = mqtt_client
83
89
  self._scene = scene
90
+ self._mqtt_event_callback_ids: dict[str, int] = {}
91
+ self._ethernet_ip = ethernet_ip
92
+
93
+ @property
94
+ def ethernet_ip(self) -> IEthernetIp:
95
+ """The EthernetIP communication interface for exchanging data with external PLCs."""
96
+ return self._ethernet_ip
84
97
 
85
98
  @property
86
99
  @abstractmethod
87
100
  def state(self) -> IMachineState:
88
101
  """The state of the Machine."""
89
102
 
103
+ @property
104
+ @abstractmethod
105
+ def mqtt(self) -> IMqtt:
106
+ """The MQTT interface for subscribing to and publishing events."""
107
+
90
108
  @abstractmethod
91
109
  def reset(self) -> bool:
92
110
  """
@@ -208,6 +226,10 @@ class IMachine(ABC):
208
226
  """
209
227
  Retrieves an DigitalInput by name.
210
228
 
229
+ The name must match the input pin's friendly name exactly as it appears in the
230
+ machine configuration (for example "Input C0"), not the display name of a device
231
+ wired to it.
232
+
211
233
  Args:
212
234
  name (str): The name of the DigitalInput.
213
235
 
@@ -229,6 +251,10 @@ class IMachine(ABC):
229
251
  """
230
252
  Retrieves an Output by name.
231
253
 
254
+ The name must match the output pin's friendly name exactly as it appears in the
255
+ machine configuration (for example "Output C0"), not the display name of a device
256
+ wired to it.
257
+
232
258
  Args:
233
259
  name (str): The name of the Output
234
260
 
@@ -297,21 +323,38 @@ class IMachine(ABC):
297
323
  callback (Callable[[MachineOperationalState, MachineSafetyState], None]): The callback
298
324
  """
299
325
 
300
- def on_mqtt_event(self, topic: str, callback: Callable[[str, Optional[str]], None]) -> None:
326
+ @deprecated
327
+ def on_mqtt_event(self, topic: str, callback: Optional[Callable[[str, Optional[str]], None]]) -> None:
301
328
  """
302
329
  Attach a callback function to an MQTT topic.
303
330
 
331
+ .. deprecated::
332
+ Use ``machine.mqtt.on_event`` instead. To remove a callback, use
333
+ ``machine.mqtt.remove_on_event_callback`` with the ID returned by ``on_event``.
334
+
304
335
  Args:
305
336
  topic (str): The topic to listen on.
306
- callback (Union[Callable[[str, str], None], None]): A callback where the first argument is the topic and the second is the message.
307
-
337
+ callback (Optional[Callable[[str, str], None]]): A callback where the first argument is the topic and the second is the message. Pass ``None`` to remove the callback.
308
338
  """
309
- self._mqtt_client.subscribe(topic, callback)
339
+ if callback is None:
340
+ callback_id = self._mqtt_event_callback_ids.pop(topic, None)
341
+ if callback_id is not None:
342
+ self.mqtt.remove_on_event_callback(callback_id)
343
+ return
310
344
 
345
+ if topic in self._mqtt_event_callback_ids:
346
+ self.mqtt.remove_on_event_callback(self._mqtt_event_callback_ids[topic])
347
+
348
+ self._mqtt_event_callback_ids[topic] = self.mqtt.on_event(topic, callback)
349
+
350
+ @deprecated
311
351
  def publish_mqtt_event(self, topic: str, message: Optional[str] = None) -> None:
312
352
  """
313
353
  Publish an MQTT event.
314
354
 
355
+ .. deprecated::
356
+ Use ``machine.mqtt.publish_event`` instead.
357
+
315
358
  Args:
316
359
  topic (str): Topic to publish.
317
360
  message (Optional[str], optional): Optional message. Defaults to None.
@@ -221,6 +221,17 @@ class IMachineMotion(ABC):
221
221
 
222
222
  raise MachineMotionException(f"Failed to find AC motor with name: {name}")
223
223
 
224
+ @undocumented
225
+ def has_io_module_devices(self) -> bool:
226
+ """Whether this MachineMotion has any inputs or outputs hosted on an IO Module."""
227
+ for input_item in self._input_list:
228
+ if input_item.configuration._is_io_module:
229
+ return True
230
+ for output_item in self._output_list:
231
+ if output_item.configuration._is_io_module:
232
+ return True
233
+ return False
234
+
224
235
  @undocumented
225
236
  def list_components(
226
237
  self,
@@ -0,0 +1,62 @@
1
+ """Interface for the MQTT communication module."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from typing import Callable, Optional
5
+
6
+ from ..decorators.undocumented import undocumented
7
+
8
+
9
+ class IMqtt(ABC):
10
+ """
11
+ A software representation of the MQTT communication interface.
12
+
13
+ MQTT allows the Machine to subscribe to and publish events on topics.
14
+
15
+ It is not recommended that you construct this object yourself.
16
+ Instead, access it via the Machine instance:
17
+
18
+ E.g.:
19
+ machine = Machine()
20
+ callback_id = machine.mqtt.on_event("my/topic", my_callback)
21
+ machine.mqtt.publish_event("my/topic", "my message")
22
+ machine.mqtt.remove_on_event_callback(callback_id)
23
+ """
24
+
25
+ @abstractmethod
26
+ def on_event(self, topic: str, callback: Callable[[str, Optional[str]], None]) -> int:
27
+ """
28
+ Register a callback that fires whenever a message is received on the given topic.
29
+
30
+ Multiple callbacks can be registered on the same topic.
31
+
32
+ Args:
33
+ topic (str): The MQTT topic to subscribe to. Supports wildcards (e.g. ``"sensor/+/value"``).
34
+ callback (Callable[[str, Optional[str]], None]): A function called with ``(topic, message)`` when a message arrives.
35
+
36
+ Returns:
37
+ int: A callback ID that can be passed to ``remove_on_event_callback`` to unregister.
38
+ """
39
+
40
+ @abstractmethod
41
+ def remove_on_event_callback(self, callback_id: int) -> None:
42
+ """
43
+ Remove a previously registered event callback.
44
+
45
+ Args:
46
+ callback_id (int): The ID returned by ``on_event``.
47
+ """
48
+
49
+ @abstractmethod
50
+ def publish_event(self, topic: str, message: Optional[str] = None) -> None:
51
+ """
52
+ Publish a message to an MQTT topic.
53
+
54
+ Args:
55
+ topic (str): The topic to publish to.
56
+ message (Optional[str]): The message payload. Defaults to ``None``.
57
+ """
58
+
59
+ @abstractmethod
60
+ @undocumented
61
+ def _cleanup(self) -> None:
62
+ """Release all resources and close the connection."""