viam-sdk 0.41.1__py3-none-linux_armv6l.whl → 0.66.0__py3-none-linux_armv6l.whl

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.

Potentially problematic release.


This version of viam-sdk might be problematic. Click here for more details.

Files changed (225) hide show
  1. viam/app/app_client.py +225 -51
  2. viam/app/billing_client.py +47 -5
  3. viam/app/data_client.py +771 -234
  4. viam/app/ml_training_client.py +3 -5
  5. viam/app/provisioning_client.py +3 -5
  6. viam/app/viam_client.py +58 -11
  7. viam/components/arm/arm.py +1 -1
  8. viam/components/arm/service.py +1 -1
  9. viam/components/audio_in/__init__.py +24 -0
  10. viam/components/audio_in/audio_in.py +74 -0
  11. viam/components/audio_in/client.py +76 -0
  12. viam/components/audio_in/service.py +83 -0
  13. viam/components/audio_out/__init__.py +21 -0
  14. viam/components/audio_out/audio_out.py +72 -0
  15. viam/components/audio_out/client.py +67 -0
  16. viam/components/audio_out/service.py +63 -0
  17. viam/components/base/base.py +1 -1
  18. viam/components/board/board.py +8 -2
  19. viam/components/board/client.py +2 -1
  20. viam/components/board/service.py +1 -0
  21. viam/components/button/__init__.py +10 -0
  22. viam/components/button/button.py +41 -0
  23. viam/components/button/client.py +52 -0
  24. viam/components/button/service.py +46 -0
  25. viam/components/camera/camera.py +15 -30
  26. viam/components/camera/client.py +10 -21
  27. viam/components/camera/service.py +15 -28
  28. viam/components/component_base.py +2 -2
  29. viam/components/gantry/client.py +17 -2
  30. viam/components/gantry/gantry.py +32 -1
  31. viam/components/gantry/service.py +21 -5
  32. viam/components/gripper/__init__.py +2 -0
  33. viam/components/gripper/client.py +25 -2
  34. viam/components/gripper/gripper.py +76 -1
  35. viam/components/gripper/service.py +32 -3
  36. viam/components/input/input.py +1 -1
  37. viam/components/motor/motor.py +1 -1
  38. viam/components/power_sensor/power_sensor.py +1 -1
  39. viam/components/switch/__init__.py +10 -0
  40. viam/components/switch/client.py +83 -0
  41. viam/components/switch/service.py +72 -0
  42. viam/components/switch/switch.py +98 -0
  43. viam/gen/app/agent/v1/agent_pb2.py +1 -1
  44. viam/gen/app/cloudslam/v1/cloud_slam_pb2.py +1 -1
  45. viam/gen/app/data/v1/data_grpc.py +74 -2
  46. viam/gen/app/data/v1/data_pb2.py +198 -104
  47. viam/gen/app/data/v1/data_pb2.pyi +563 -31
  48. viam/gen/app/datapipelines/__init__.py +0 -0
  49. viam/gen/app/datapipelines/v1/__init__.py +0 -0
  50. viam/gen/app/datapipelines/v1/data_pipelines_grpc.py +84 -0
  51. viam/gen/app/datapipelines/v1/data_pipelines_pb2.py +57 -0
  52. viam/gen/app/datapipelines/v1/data_pipelines_pb2.pyi +387 -0
  53. viam/gen/app/dataset/v1/dataset_grpc.py +10 -2
  54. viam/gen/app/dataset/v1/dataset_pb2.py +8 -4
  55. viam/gen/app/dataset/v1/dataset_pb2.pyi +36 -1
  56. viam/gen/app/datasync/v1/data_sync_pb2.py +39 -35
  57. viam/gen/app/datasync/v1/data_sync_pb2.pyi +21 -8
  58. viam/gen/app/mlinference/v1/ml_inference_pb2.py +7 -7
  59. viam/gen/app/mlinference/v1/ml_inference_pb2.pyi +4 -2
  60. viam/gen/app/mltraining/v1/ml_training_grpc.py +10 -2
  61. viam/gen/app/mltraining/v1/ml_training_pb2.py +63 -43
  62. viam/gen/app/mltraining/v1/ml_training_pb2.pyi +112 -7
  63. viam/gen/app/packages/v1/packages_pb2.py +1 -1
  64. viam/gen/app/v1/app_grpc.py +74 -3
  65. viam/gen/app/v1/app_pb2.py +600 -545
  66. viam/gen/app/v1/app_pb2.pyi +1108 -258
  67. viam/gen/app/v1/billing_grpc.py +26 -2
  68. viam/gen/app/v1/billing_pb2.py +52 -36
  69. viam/gen/app/v1/billing_pb2.pyi +158 -4
  70. viam/gen/app/v1/end_user_pb2.py +1 -1
  71. viam/gen/app/v1/robot_pb2.py +95 -89
  72. viam/gen/app/v1/robot_pb2.pyi +121 -9
  73. viam/gen/common/v1/common_pb2.py +76 -58
  74. viam/gen/common/v1/common_pb2.pyi +186 -17
  75. viam/gen/component/arm/v1/arm_grpc.py +10 -2
  76. viam/gen/component/arm/v1/arm_pb2.py +5 -3
  77. viam/gen/component/audioin/__init__.py +0 -0
  78. viam/gen/component/audioin/v1/__init__.py +0 -0
  79. viam/gen/component/audioin/v1/audioin_grpc.py +54 -0
  80. viam/gen/component/audioin/v1/audioin_pb2.py +34 -0
  81. viam/gen/component/audioin/v1/audioin_pb2.pyi +94 -0
  82. viam/gen/component/audioinput/v1/audioinput_pb2.py +1 -1
  83. viam/gen/component/audioout/__init__.py +0 -0
  84. viam/gen/component/audioout/v1/__init__.py +0 -0
  85. viam/gen/component/audioout/v1/audioout_grpc.py +54 -0
  86. viam/gen/component/audioout/v1/audioout_pb2.py +32 -0
  87. viam/gen/component/audioout/v1/audioout_pb2.pyi +47 -0
  88. viam/gen/component/base/v1/base_pb2.py +1 -1
  89. viam/gen/component/board/v1/board_pb2.py +1 -1
  90. viam/gen/component/button/v1/button_pb2.py +1 -1
  91. viam/gen/component/camera/v1/camera_grpc.py +1 -0
  92. viam/gen/component/camera/v1/camera_pb2.py +37 -36
  93. viam/gen/component/camera/v1/camera_pb2.pyi +31 -4
  94. viam/gen/component/encoder/v1/encoder_pb2.py +1 -1
  95. viam/gen/component/gantry/v1/gantry_grpc.py +9 -1
  96. viam/gen/component/gantry/v1/gantry_pb2.py +5 -3
  97. viam/gen/component/generic/v1/generic_pb2.py +1 -1
  98. viam/gen/component/gripper/v1/gripper_grpc.py +18 -2
  99. viam/gen/component/gripper/v1/gripper_pb2.py +12 -4
  100. viam/gen/component/gripper/v1/gripper_pb2.pyi +43 -1
  101. viam/gen/component/inputcontroller/v1/input_controller_pb2.py +1 -1
  102. viam/gen/component/motor/v1/motor_pb2.py +1 -1
  103. viam/gen/component/movementsensor/v1/movementsensor_pb2.py +1 -1
  104. viam/gen/component/posetracker/v1/pose_tracker_pb2.py +1 -1
  105. viam/gen/component/powersensor/v1/powersensor_pb2.py +1 -1
  106. viam/gen/component/sensor/v1/sensor_pb2.py +1 -1
  107. viam/gen/component/servo/v1/servo_pb2.py +1 -1
  108. viam/gen/component/switch/v1/switch_pb2.py +5 -5
  109. viam/gen/component/switch/v1/switch_pb2.pyi +9 -2
  110. viam/gen/component/testecho/v1/testecho_pb2.py +1 -1
  111. viam/gen/module/v1/module_pb2.py +5 -5
  112. viam/gen/module/v1/module_pb2.pyi +7 -2
  113. viam/gen/opentelemetry/__init__.py +0 -0
  114. viam/gen/opentelemetry/proto/__init__.py +0 -0
  115. viam/gen/opentelemetry/proto/common/__init__.py +0 -0
  116. viam/gen/opentelemetry/proto/common/v1/__init__.py +0 -0
  117. viam/gen/opentelemetry/proto/common/v1/common_grpc.py +0 -0
  118. viam/gen/opentelemetry/proto/common/v1/common_pb2.py +27 -0
  119. viam/gen/opentelemetry/proto/common/v1/common_pb2.pyi +208 -0
  120. viam/gen/opentelemetry/proto/resource/__init__.py +0 -0
  121. viam/gen/opentelemetry/proto/resource/v1/__init__.py +0 -0
  122. viam/gen/opentelemetry/proto/resource/v1/resource_grpc.py +0 -0
  123. viam/gen/opentelemetry/proto/resource/v1/resource_pb2.py +18 -0
  124. viam/gen/opentelemetry/proto/resource/v1/resource_pb2.pyi +59 -0
  125. viam/gen/opentelemetry/proto/trace/__init__.py +0 -0
  126. viam/gen/opentelemetry/proto/trace/v1/__init__.py +0 -0
  127. viam/gen/opentelemetry/proto/trace/v1/trace_grpc.py +0 -0
  128. viam/gen/opentelemetry/proto/trace/v1/trace_pb2.py +37 -0
  129. viam/gen/opentelemetry/proto/trace/v1/trace_pb2.pyi +402 -0
  130. viam/gen/proto/rpc/examples/echo/v1/echo_pb2.py +1 -1
  131. viam/gen/proto/rpc/examples/echoresource/v1/echoresource_pb2.py +1 -1
  132. viam/gen/proto/rpc/v1/auth_pb2.py +1 -1
  133. viam/gen/proto/rpc/webrtc/v1/grpc_pb2.py +1 -1
  134. viam/gen/proto/rpc/webrtc/v1/signaling_pb2.py +1 -1
  135. viam/gen/provisioning/v1/provisioning_grpc.py +10 -2
  136. viam/gen/provisioning/v1/provisioning_pb2.py +32 -26
  137. viam/gen/provisioning/v1/provisioning_pb2.pyi +46 -5
  138. viam/gen/robot/v1/robot_grpc.py +51 -34
  139. viam/gen/robot/v1/robot_pb2.py +147 -142
  140. viam/gen/robot/v1/robot_pb2.pyi +153 -86
  141. viam/gen/service/datamanager/v1/data_manager_grpc.py +11 -2
  142. viam/gen/service/datamanager/v1/data_manager_pb2.py +15 -8
  143. viam/gen/service/datamanager/v1/data_manager_pb2.pyi +47 -1
  144. viam/gen/service/discovery/v1/discovery_pb2.py +1 -1
  145. viam/gen/service/generic/v1/generic_pb2.py +1 -1
  146. viam/gen/service/mlmodel/v1/mlmodel_pb2.py +1 -1
  147. viam/gen/service/motion/v1/motion_pb2.py +92 -62
  148. viam/gen/service/motion/v1/motion_pb2.pyi +130 -68
  149. viam/gen/service/navigation/v1/navigation_pb2.py +1 -1
  150. viam/gen/service/sensors/v1/sensors_pb2.py +1 -1
  151. viam/gen/service/shell/v1/shell_pb2.py +1 -1
  152. viam/gen/service/slam/v1/slam_pb2.py +1 -1
  153. viam/gen/service/slam/v1/slam_pb2.pyi +1 -1
  154. viam/gen/service/video/__init__.py +0 -0
  155. viam/gen/service/video/v1/__init__.py +0 -0
  156. viam/gen/service/video/v1/video_grpc.py +39 -0
  157. viam/gen/service/video/v1/video_pb2.py +29 -0
  158. viam/gen/service/video/v1/video_pb2.pyi +72 -0
  159. viam/gen/service/vision/v1/vision_pb2.py +27 -27
  160. viam/gen/service/vision/v1/vision_pb2.pyi +28 -3
  161. viam/gen/service/worldstatestore/__init__.py +0 -0
  162. viam/gen/service/worldstatestore/v1/__init__.py +0 -0
  163. viam/gen/service/worldstatestore/v1/world_state_store_grpc.py +55 -0
  164. viam/gen/service/worldstatestore/v1/world_state_store_pb2.py +39 -0
  165. viam/gen/service/worldstatestore/v1/world_state_store_pb2.pyi +171 -0
  166. viam/gen/stream/v1/stream_pb2.py +1 -1
  167. viam/gen/tagger/v1/tagger_pb2.py +1 -1
  168. viam/logging.py +9 -8
  169. viam/media/audio.py +22 -10
  170. viam/media/utils/pil/__init__.py +5 -1
  171. viam/media/video.py +54 -40
  172. viam/module/module.py +85 -16
  173. viam/module/resource_data_consumer.py +41 -0
  174. viam/module/service.py +9 -1
  175. viam/proto/app/__init__.py +68 -0
  176. viam/proto/app/billing.py +16 -0
  177. viam/proto/app/data/__init__.py +48 -0
  178. viam/proto/app/datapipelines/__init__.py +56 -0
  179. viam/proto/app/dataset/__init__.py +4 -0
  180. viam/proto/app/mltraining/__init__.py +6 -0
  181. viam/proto/app/robot.py +6 -0
  182. viam/proto/common/__init__.py +14 -0
  183. viam/proto/component/audioin/__init__.py +16 -0
  184. viam/proto/component/audioout/__init__.py +15 -0
  185. viam/proto/component/camera/__init__.py +0 -2
  186. viam/proto/component/gripper/__init__.py +4 -0
  187. viam/proto/opentelemetry/__init__.py +0 -0
  188. viam/proto/opentelemetry/proto/__init__.py +0 -0
  189. viam/proto/opentelemetry/proto/common/__init__.py +15 -0
  190. viam/proto/opentelemetry/proto/resource/__init__.py +10 -0
  191. viam/proto/opentelemetry/proto/trace/__init__.py +15 -0
  192. viam/proto/provisioning/__init__.py +6 -0
  193. viam/proto/robot/__init__.py +16 -8
  194. viam/proto/service/datamanager/__init__.py +8 -1
  195. viam/proto/service/motion/__init__.py +2 -0
  196. viam/proto/service/video/__init__.py +15 -0
  197. viam/proto/service/worldstatestore/__init__.py +32 -0
  198. viam/resource/easy_resource.py +5 -9
  199. viam/resource/manager.py +4 -3
  200. viam/resource/registry.py +2 -2
  201. viam/resource/types.py +2 -2
  202. viam/robot/client.py +38 -59
  203. viam/rpc/dial.py +48 -5
  204. viam/rpc/libviam_rust_utils.so +0 -0
  205. viam/rpc/server.py +24 -10
  206. viam/services/motion/client.py +8 -9
  207. viam/services/motion/motion.py +48 -46
  208. viam/services/navigation/navigation.py +2 -2
  209. viam/services/vision/client.py +1 -1
  210. viam/services/vision/service.py +5 -8
  211. viam/services/vision/vision.py +5 -3
  212. viam/services/worldstatestore/__init__.py +18 -0
  213. viam/services/worldstatestore/client.py +94 -0
  214. viam/services/worldstatestore/service.py +55 -0
  215. viam/services/worldstatestore/worldstatestore.py +90 -0
  216. viam/sessions_client.py +115 -46
  217. viam/version_metadata.py +2 -2
  218. {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/METADATA +10 -6
  219. {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/RECORD +221 -152
  220. {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/WHEEL +1 -1
  221. viam/components/audio_input/__init__.py +0 -18
  222. viam/components/audio_input/audio_input.py +0 -81
  223. viam/components/audio_input/client.py +0 -70
  224. viam/components/audio_input/service.py +0 -114
  225. {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/licenses/LICENSE +0 -0
@@ -68,7 +68,7 @@ class Board(ComponentBase):
68
68
  my_board = Board.from_robot(robot=machine, name="my_board")
69
69
 
70
70
  # Get the Analog "my_example_analog_reader".
71
- reader = await my_board.analog_reader_by_name(
71
+ reader = await my_board.analog_by_name(
72
72
  name="my_example_analog_reader")
73
73
 
74
74
  # Get the value of the digital signal "my_example_analog_reader" has most
@@ -366,7 +366,13 @@ class Board(ComponentBase):
366
366
 
367
367
  @abc.abstractmethod
368
368
  async def set_power_mode(
369
- self, mode: PowerMode.ValueType, duration: Optional[timedelta] = None, *, timeout: Optional[float] = None, **kwargs
369
+ self,
370
+ mode: PowerMode.ValueType,
371
+ duration: Optional[timedelta] = None,
372
+ *,
373
+ extra: Optional[Dict[str, Any]] = None,
374
+ timeout: Optional[float] = None,
375
+ **kwargs,
370
376
  ):
371
377
  """
372
378
  Set the board to the indicated power mode.
@@ -201,6 +201,7 @@ class BoardClient(Board, ReconfigurableResourceRPCClientBase):
201
201
  mode: PowerMode.ValueType,
202
202
  duration: Optional[timedelta] = None,
203
203
  *,
204
+ extra: Optional[Dict[str, Any]] = None,
204
205
  timeout: Optional[float] = None,
205
206
  **kwargs,
206
207
  ):
@@ -208,7 +209,7 @@ class BoardClient(Board, ReconfigurableResourceRPCClientBase):
208
209
  duration_pb: Optional[Duration] = None
209
210
  if duration is not None:
210
211
  duration_pb = [(d, d.FromTimedelta(duration)) for d in [Duration()]][0][0]
211
- request = SetPowerModeRequest(name=self.name, power_mode=mode, duration=duration_pb)
212
+ request = SetPowerModeRequest(name=self.name, power_mode=mode, duration=duration_pb, extra=dict_to_struct(extra))
212
213
  await self.client.SetPowerMode(request, timeout=timeout, metadata=md)
213
214
 
214
215
  async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> List[Geometry]:
@@ -164,6 +164,7 @@ class BoardRPCService(BoardServiceBase, ResourceRPCServiceBase[Board]):
164
164
  await board.set_power_mode(
165
165
  mode=request.power_mode,
166
166
  duration=request.duration.ToTimedelta(),
167
+ extra=struct_to_dict(request.extra),
167
168
  timeout=timeout,
168
169
  metadata=stream.metadata,
169
170
  )
@@ -0,0 +1,10 @@
1
+ import viam.gen.component.button.v1.button_pb2
2
+ from viam.resource.registry import Registry, ResourceRegistration
3
+
4
+ from .button import Button
5
+ from .client import ButtonClient
6
+ from .service import ButtonRPCService
7
+
8
+ __all__ = ["Button"]
9
+
10
+ Registry.register_api(ResourceRegistration(Button, ButtonRPCService, lambda name, channel: ButtonClient(name, channel)))
@@ -0,0 +1,41 @@
1
+ import abc
2
+ from typing import Any, Final, Mapping, Optional
3
+
4
+ from viam.components.component_base import ComponentBase
5
+ from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT
6
+
7
+
8
+ class Button(ComponentBase):
9
+ """
10
+ Button represents a device that can be pushed.
11
+
12
+ This acts as an abstract base class for any drivers representing specific
13
+ button implementations. This cannot be used on its own. If the ``__init__()`` function is
14
+ overridden, it must call the ``super().__init__()`` function.
15
+
16
+ ::
17
+
18
+ from viam.components.button import Button
19
+
20
+ For more information, see `Button component <https://docs.viam.com/dev/reference/apis/components/button/>` _.
21
+ """
22
+
23
+ API: Final = API( # pyright: ignore [reportIncompatibleVariableOverride]
24
+ RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT, "button"
25
+ )
26
+
27
+ @abc.abstractmethod
28
+ async def push(self, *, extra: Optional[Mapping[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> None:
29
+ """
30
+ Push the button.
31
+
32
+ ::
33
+
34
+ my_button = Button.from_robot(robot=machine, name="my_button")
35
+
36
+ # Push the button
37
+ await my_button.push()
38
+
39
+ For more information, see `Button component <https://docs.viam.com/dev/reference/apis/components/button/>` _.
40
+ """
41
+ ...
@@ -0,0 +1,52 @@
1
+ from typing import Any, Mapping, Optional
2
+
3
+ from grpclib.client import Channel
4
+
5
+ from viam.gen.component.button.v1.button_pb2 import PushRequest
6
+ from viam.proto.common import (
7
+ DoCommandRequest,
8
+ DoCommandResponse,
9
+ )
10
+ from viam.proto.component.button import ButtonServiceStub
11
+ from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase
12
+ from viam.utils import (
13
+ ValueTypes,
14
+ dict_to_struct,
15
+ struct_to_dict,
16
+ )
17
+
18
+ from .button import Button
19
+
20
+
21
+ class ButtonClient(Button, ReconfigurableResourceRPCClientBase):
22
+ """
23
+ gRPC client for Button component
24
+ """
25
+
26
+ def __init__(self, name: str, channel: Channel):
27
+ self.channel = channel
28
+ self.client = ButtonServiceStub(channel)
29
+ super().__init__(name)
30
+
31
+ async def push(
32
+ self,
33
+ *,
34
+ extra: Optional[Mapping[str, Any]] = None,
35
+ timeout: Optional[float] = None,
36
+ **kwargs,
37
+ ) -> None:
38
+ md = kwargs.get("metadata", self.Metadata()).proto
39
+ request = PushRequest(name=self.name, extra=dict_to_struct(extra))
40
+ await self.client.Push(request, timeout=timeout, metadata=md)
41
+
42
+ async def do_command(
43
+ self,
44
+ command: Mapping[str, ValueTypes],
45
+ *,
46
+ timeout: Optional[float] = None,
47
+ **kwargs,
48
+ ) -> Mapping[str, ValueTypes]:
49
+ md = kwargs.get("metadata", self.Metadata()).proto
50
+ request = DoCommandRequest(name=self.name, command=dict_to_struct(command))
51
+ response: DoCommandResponse = await self.client.DoCommand(request, timeout=timeout, metadata=md)
52
+ return struct_to_dict(response.result)
@@ -0,0 +1,46 @@
1
+ from grpclib.server import Stream
2
+
3
+ from viam.gen.component.button.v1.button_pb2 import (
4
+ PushRequest,
5
+ PushResponse,
6
+ )
7
+ from viam.proto.common import (
8
+ DoCommandRequest,
9
+ DoCommandResponse,
10
+ )
11
+ from viam.proto.component.button import ButtonServiceBase
12
+ from viam.resource.rpc_service_base import ResourceRPCServiceBase
13
+ from viam.utils import dict_to_struct, struct_to_dict
14
+
15
+ from .button import Button
16
+
17
+
18
+ class ButtonRPCService(ButtonServiceBase, ResourceRPCServiceBase[Button]):
19
+ """
20
+ gRPC Service for a generic Button
21
+ """
22
+
23
+ RESOURCE_TYPE = Button
24
+
25
+ async def Push(self, stream: Stream[PushRequest, PushResponse]) -> None:
26
+ request = await stream.recv_message()
27
+ assert request is not None
28
+ name = request.name
29
+ button = self.get_resource(name)
30
+ timeout = stream.deadline.time_remaining() if stream.deadline else None
31
+ await button.push(extra=struct_to_dict(request.extra), timeout=timeout, metadata=stream.metadata)
32
+ await stream.send_message(PushResponse())
33
+
34
+ async def DoCommand(self, stream: Stream[DoCommandRequest, DoCommandResponse]) -> None:
35
+ request = await stream.recv_message()
36
+ assert request is not None
37
+ name = request.name
38
+ button = self.get_resource(name)
39
+ timeout = stream.deadline.time_remaining() if stream.deadline else None
40
+ result = await button.do_command(
41
+ command=struct_to_dict(request.command),
42
+ timeout=timeout,
43
+ metadata=stream.metadata,
44
+ )
45
+ response = DoCommandResponse(result=dict_to_struct(result))
46
+ await stream.send_message(response)
@@ -1,8 +1,8 @@
1
1
  import abc
2
2
  import sys
3
- from typing import Any, Dict, Final, List, Optional, Tuple
3
+ from typing import Any, Dict, Final, Optional, Sequence, Tuple
4
4
 
5
- from viam.media.video import NamedImage, ViamImage
5
+ from viam.media.video import NamedImage
6
6
  from viam.proto.common import ResponseMetadata
7
7
  from viam.proto.component.camera import GetPropertiesResponse
8
8
  from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT
@@ -37,33 +37,14 @@ class Camera(ComponentBase):
37
37
  Properties: "TypeAlias" = GetPropertiesResponse
38
38
 
39
39
  @abc.abstractmethod
40
- async def get_image(
41
- self, mime_type: str = "", *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs
42
- ) -> ViamImage:
43
- """Get the next image from the camera as a ViamImage.
44
- Be sure to close the image when finished.
45
-
46
- NOTE: If the mime type is ``image/vnd.viam.dep`` you can use :func:`viam.media.video.ViamImage.bytes_to_depth_array`
47
- to convert the data to a standard representation.
48
-
49
- ::
50
-
51
- my_camera = Camera.from_robot(machine, "my_camera")
52
- frame = await my_camera.get_image()
53
- print(f"Frame: {frame}")
54
-
55
- Args:
56
- mime_type (str): The desired mime type of the image. This does not guarantee output type
57
-
58
- Returns:
59
- ViamImage: The frame.
60
-
61
- For more information, see `Camera component <https://docs.viam.com/dev/reference/apis/components/camera/#getimage>`_.
62
- """
63
- ...
64
-
65
- @abc.abstractmethod
66
- async def get_images(self, *, timeout: Optional[float] = None, **kwargs) -> Tuple[List[NamedImage], ResponseMetadata]:
40
+ async def get_images(
41
+ self,
42
+ *,
43
+ filter_source_names: Optional[Sequence[str]] = None,
44
+ extra: Optional[Dict[str, Any]] = None,
45
+ timeout: Optional[float] = None,
46
+ **kwargs,
47
+ ) -> Tuple[Sequence[NamedImage], ResponseMetadata]:
67
48
  """Get simultaneous images from different imagers, along with associated metadata.
68
49
  This should not be used for getting a time series of images from the same imager.
69
50
 
@@ -75,8 +56,12 @@ class Camera(ComponentBase):
75
56
  first_image = images[0]
76
57
  timestamp = metadata.captured_at
77
58
 
59
+ Args:
60
+ filter_source_names (Sequence[str]): The filter_source_names parameter can be used to filter only the images from the specified
61
+ source names. When unspecified, all images are returned.
62
+
78
63
  Returns:
79
- Tuple[List[NamedImage], ResponseMetadata]: A tuple containing two values; the first [0] a list of images
64
+ Tuple[Sequence[NamedImage], ResponseMetadata]: A tuple containing two values; the first [0] a list of images
80
65
  returned from the camera system, and the second [1] the metadata associated with this response.
81
66
 
82
67
  For more information, see `Camera component <https://docs.viam.com/dev/reference/apis/components/camera/#getimages>`_.
@@ -1,13 +1,11 @@
1
- from typing import Any, Dict, List, Mapping, Optional, Tuple
1
+ from typing import Any, Dict, Mapping, Optional, Sequence, Tuple
2
2
 
3
3
  from grpclib.client import Channel
4
4
 
5
- from viam.media.video import CameraMimeType, NamedImage, ViamImage
5
+ from viam.media.video import CameraMimeType, NamedImage
6
6
  from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry, ResponseMetadata
7
7
  from viam.proto.component.camera import (
8
8
  CameraServiceStub,
9
- GetImageRequest,
10
- GetImageResponse,
11
9
  GetImagesRequest,
12
10
  GetImagesResponse,
13
11
  GetPointCloudRequest,
@@ -30,31 +28,20 @@ class CameraClient(Camera, ReconfigurableResourceRPCClientBase):
30
28
  self.client = CameraServiceStub(channel)
31
29
  super().__init__(name)
32
30
 
33
- async def get_image(
34
- self,
35
- mime_type: str = "",
36
- *,
37
- extra: Optional[Dict[str, Any]] = None,
38
- timeout: Optional[float] = None,
39
- **kwargs,
40
- ) -> ViamImage:
41
- md = kwargs.get("metadata", self.Metadata()).proto
42
- request = GetImageRequest(name=self.name, mime_type=mime_type, extra=dict_to_struct(extra))
43
- response: GetImageResponse = await self.client.GetImage(request, timeout=timeout, metadata=md)
44
- return ViamImage(response.image, CameraMimeType.from_string(response.mime_type))
45
-
46
31
  async def get_images(
47
32
  self,
48
33
  *,
34
+ filter_source_names: Optional[Sequence[str]] = None,
35
+ extra: Optional[Dict[str, Any]] = None,
49
36
  timeout: Optional[float] = None,
50
37
  **kwargs,
51
- ) -> Tuple[List[NamedImage], ResponseMetadata]:
38
+ ) -> Tuple[Sequence[NamedImage], ResponseMetadata]:
52
39
  md = kwargs.get("metadata", self.Metadata()).proto
53
- request = GetImagesRequest(name=self.name)
40
+ request = GetImagesRequest(name=self.name, extra=dict_to_struct(extra), filter_source_names=filter_source_names)
54
41
  response: GetImagesResponse = await self.client.GetImages(request, timeout=timeout, metadata=md)
55
42
  imgs = []
56
43
  for img_data in response.images:
57
- mime_type = CameraMimeType.from_proto(img_data.format)
44
+ mime_type = CameraMimeType.from_string(img_data.mime_type)
58
45
  img = NamedImage(img_data.source_name, img_data.image, mime_type)
59
46
  imgs.append(img)
60
47
  resp_metadata: ResponseMetadata = response.response_metadata
@@ -93,6 +80,8 @@ class CameraClient(Camera, ReconfigurableResourceRPCClientBase):
93
80
  response: DoCommandResponse = await self.client.DoCommand(request, timeout=timeout, metadata=md)
94
81
  return struct_to_dict(response.result)
95
82
 
96
- async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> List[Geometry]:
83
+ async def get_geometries(
84
+ self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs
85
+ ) -> Sequence[Geometry]:
97
86
  md = kwargs.get("metadata", self.Metadata())
98
87
  return await get_geometries(self.client, self.name, extra, timeout, md)
@@ -1,13 +1,11 @@
1
1
  # TODO: Update type checking based with RSDK-4089
2
2
  # pyright: reportGeneralTypeIssues=false
3
- from google.api.httpbody_pb2 import HttpBody # type: ignore
4
3
  from grpclib.server import Stream
5
4
 
5
+ from viam.errors import NotSupportedError
6
6
  from viam.proto.common import DoCommandRequest, DoCommandResponse, GetGeometriesRequest, GetGeometriesResponse
7
7
  from viam.proto.component.camera import (
8
8
  CameraServiceBase,
9
- GetImageRequest,
10
- GetImageResponse,
11
9
  GetImagesRequest,
12
10
  GetImagesResponse,
13
11
  GetPointCloudRequest,
@@ -15,7 +13,6 @@ from viam.proto.component.camera import (
15
13
  GetPropertiesRequest,
16
14
  GetPropertiesResponse,
17
15
  Image,
18
- RenderFrameRequest,
19
16
  )
20
17
  from viam.resource.rpc_service_base import ResourceRPCServiceBase
21
18
  from viam.utils import dict_to_struct, struct_to_dict
@@ -30,43 +27,33 @@ class CameraRPCService(CameraServiceBase, ResourceRPCServiceBase[Camera]):
30
27
 
31
28
  RESOURCE_TYPE = Camera
32
29
 
33
- async def GetImage(self, stream: Stream[GetImageRequest, GetImageResponse]) -> None:
34
- request = await stream.recv_message()
35
- assert request is not None
36
- name = request.name
37
- camera = self.get_resource(name)
30
+ async def GetImage(self, stream: Stream) -> None:
31
+ """Deprecated: Use GetImages instead."""
32
+ raise NotSupportedError("GetImage is deprecated. Use GetImages instead.")
38
33
 
39
- timeout = stream.deadline.time_remaining() if stream.deadline else None
40
- image = await camera.get_image(request.mime_type, extra=struct_to_dict(request.extra), timeout=timeout, metadata=stream.metadata)
41
- response = GetImageResponse(mime_type=image.mime_type, image=image.data)
42
- await stream.send_message(response)
34
+ async def RenderFrame(self, stream: Stream) -> None:
35
+ """Deprecated: Use GetImages instead."""
36
+ raise NotSupportedError("RenderFrame is deprecated. Use GetImages instead.")
43
37
 
44
38
  async def GetImages(self, stream: Stream[GetImagesRequest, GetImagesResponse]) -> None:
45
39
  request = await stream.recv_message()
46
40
  assert request is not None
47
- name = request.name
48
- camera = self.get_resource(name)
41
+ camera = self.get_resource(request.name)
49
42
 
50
43
  timeout = stream.deadline.time_remaining() if stream.deadline else None
51
- images, metadata = await camera.get_images(timeout=timeout, metadata=stream.metadata)
44
+ images, metadata = await camera.get_images(
45
+ timeout=timeout,
46
+ metadata=stream.metadata,
47
+ extra=struct_to_dict(request.extra),
48
+ filter_source_names=request.filter_source_names,
49
+ )
52
50
  img_bytes_lst = []
53
51
  for img in images:
54
- fmt = img.mime_type.to_proto()
55
52
  img_bytes = img.data
56
- img_bytes_lst.append(Image(source_name=name, format=fmt, image=img_bytes))
53
+ img_bytes_lst.append(Image(source_name=img.name, mime_type=img.mime_type, image=img_bytes))
57
54
  response = GetImagesResponse(images=img_bytes_lst, response_metadata=metadata)
58
55
  await stream.send_message(response)
59
56
 
60
- async def RenderFrame(self, stream: Stream[RenderFrameRequest, HttpBody]) -> None: # pyright: ignore [reportInvalidTypeForm]
61
- request = await stream.recv_message()
62
- assert request is not None
63
- name = request.name
64
- camera = self.get_resource(name)
65
- timeout = stream.deadline.time_remaining() if stream.deadline else None
66
- image = await camera.get_image(request.mime_type, timeout=timeout, metadata=stream.metadata)
67
- response = HttpBody(data=image.data, content_type=image.mime_type) # type: ignore
68
- await stream.send_message(response)
69
-
70
57
  async def GetPointCloud(self, stream: Stream[GetPointCloudRequest, GetPointCloudResponse]) -> None:
71
58
  request = await stream.recv_message()
72
59
  assert request is not None
@@ -1,6 +1,6 @@
1
1
  import abc
2
2
  from logging import Logger
3
- from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Mapping, Optional, SupportsBytes, SupportsFloat, Union, cast
3
+ from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Mapping, Optional, Sequence, SupportsBytes, SupportsFloat, Union, cast
4
4
 
5
5
  from typing_extensions import Self
6
6
 
@@ -46,7 +46,7 @@ class ComponentBase(abc.ABC, ResourceBase):
46
46
  async def do_command(self, command: Mapping[str, ValueTypes], *, timeout: Optional[float] = None, **kwargs) -> Mapping[str, ValueTypes]:
47
47
  raise NotImplementedError()
48
48
 
49
- async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None) -> List[Geometry]:
49
+ async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None) -> Sequence[Geometry]:
50
50
  """
51
51
  Get all geometries associated with the component, in their current configuration, in the
52
52
  `frame <https://docs.viam.com/operate/mobility/define-geometry/>`__ of the component.
@@ -1,8 +1,15 @@
1
- from typing import Any, Dict, List, Mapping, Optional
1
+ from typing import Any, Dict, List, Mapping, Optional, Tuple
2
2
 
3
3
  from grpclib.client import Channel
4
4
 
5
- from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry
5
+ from viam.proto.common import (
6
+ DoCommandRequest,
7
+ DoCommandResponse,
8
+ Geometry,
9
+ GetKinematicsRequest,
10
+ GetKinematicsResponse,
11
+ KinematicsFileFormat,
12
+ )
6
13
  from viam.proto.component.gantry import (
7
14
  GantryServiceStub,
8
15
  GetLengthsRequest,
@@ -110,6 +117,14 @@ class GantryClient(Gantry, ReconfigurableResourceRPCClientBase):
110
117
  response: DoCommandResponse = await self.client.DoCommand(request, timeout=timeout, metadata=md)
111
118
  return struct_to_dict(response.result)
112
119
 
120
+ async def get_kinematics(
121
+ self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs
122
+ ) -> Tuple[KinematicsFileFormat.ValueType, bytes]:
123
+ md = kwargs.get("metadata", self.Metadata()).proto
124
+ request = GetKinematicsRequest(name=self.name, extra=dict_to_struct(extra))
125
+ response: GetKinematicsResponse = await self.client.GetKinematics(request, timeout=timeout, metadata=md)
126
+ return (response.format, response.kinematics_data)
127
+
113
128
  async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> List[Geometry]:
114
129
  md = kwargs.get("metadata", self.Metadata())
115
130
  return await get_geometries(self.client, self.name, extra, timeout, md)
@@ -1,6 +1,7 @@
1
1
  import abc
2
- from typing import Any, Dict, Final, List, Optional
2
+ from typing import Any, Dict, Final, List, Optional, Tuple
3
3
 
4
+ from viam.components.arm import KinematicsFileFormat
4
5
  from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT
5
6
 
6
7
  from ..component_base import ComponentBase
@@ -154,3 +155,33 @@ class Gantry(ComponentBase):
154
155
  For more information, see `Gantry component <https://docs.viam.com/dev/reference/apis/components/gantry/#ismoving>`_.
155
156
  """
156
157
  ...
158
+
159
+ @abc.abstractmethod
160
+ async def get_kinematics(
161
+ self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs
162
+ ) -> Tuple[KinematicsFileFormat.ValueType, bytes]:
163
+ """
164
+ Get the kinematics information associated with the gantry.
165
+
166
+ ::
167
+
168
+ my_gantry = Gantry.from_robot(robot=machine, name="my_gantry")
169
+
170
+ # Get the kinematics information associated with the gantry.
171
+ kinematics = await my_gantry.get_kinematics()
172
+
173
+ # Get the format of the kinematics file.
174
+ k_file = kinematics[0]
175
+
176
+ # Get the byte contents of the file.
177
+ k_bytes = kinematics[1]
178
+
179
+ Returns:
180
+ Tuple[KinematicsFileFormat.ValueType, bytes]: A tuple containing two values; the first [0] value represents the format of the
181
+ file, either in URDF format (``KinematicsFileFormat.KINEMATICS_FILE_FORMAT_URDF``) or
182
+ Viam's kinematic parameter format (spatial vector algebra) (``KinematicsFileFormat.KINEMATICS_FILE_FORMAT_SVA``),
183
+ and the second [1] value represents the byte contents of the file.
184
+
185
+ For more information, see `Arm component <https://docs.viam.com/dev/reference/apis/components/arm/#getkinematics>`_.
186
+ """
187
+ ...
@@ -1,8 +1,14 @@
1
1
  from grpclib.server import Stream
2
2
 
3
- from viam.proto.common import DoCommandRequest, DoCommandResponse, GetGeometriesRequest, GetGeometriesResponse
3
+ from viam.proto.common import (
4
+ DoCommandRequest,
5
+ DoCommandResponse,
6
+ GetGeometriesRequest,
7
+ GetGeometriesResponse,
8
+ GetKinematicsRequest,
9
+ GetKinematicsResponse,
10
+ )
4
11
  from viam.proto.component.gantry import (
5
- GantryServiceBase,
6
12
  GetLengthsRequest,
7
13
  GetLengthsResponse,
8
14
  GetPositionRequest,
@@ -15,6 +21,7 @@ from viam.proto.component.gantry import (
15
21
  MoveToPositionResponse,
16
22
  StopRequest,
17
23
  StopResponse,
24
+ UnimplementedGantryServiceBase,
18
25
  )
19
26
  from viam.resource.rpc_service_base import ResourceRPCServiceBase
20
27
  from viam.utils import dict_to_struct, struct_to_dict
@@ -22,7 +29,7 @@ from viam.utils import dict_to_struct, struct_to_dict
22
29
  from .gantry import Gantry
23
30
 
24
31
 
25
- class GantryRPCService(GantryServiceBase, ResourceRPCServiceBase[Gantry]):
32
+ class GantryRPCService(UnimplementedGantryServiceBase, ResourceRPCServiceBase[Gantry]):
26
33
  """
27
34
  gRPC Service for a Gantry
28
35
  """
@@ -103,11 +110,20 @@ class GantryRPCService(GantryServiceBase, ResourceRPCServiceBase[Gantry]):
103
110
  response = DoCommandResponse(result=dict_to_struct(result))
104
111
  await stream.send_message(response)
105
112
 
113
+ async def GetKinematics(self, stream: Stream[GetKinematicsRequest, GetKinematicsResponse]) -> None:
114
+ request = await stream.recv_message()
115
+ assert request is not None
116
+ gantry = self.get_resource(request.name)
117
+ timeout = stream.deadline.time_remaining() if stream.deadline else None
118
+ format, data = await gantry.get_kinematics(extra=struct_to_dict(request.extra), timeout=timeout, metadata=stream.metadata)
119
+ response = GetKinematicsResponse(format=format, kinematics_data=data)
120
+ await stream.send_message(response)
121
+
106
122
  async def GetGeometries(self, stream: Stream[GetGeometriesRequest, GetGeometriesResponse]) -> None:
107
123
  request = await stream.recv_message()
108
124
  assert request is not None
109
- arm = self.get_resource(request.name)
125
+ gantry = self.get_resource(request.name)
110
126
  timeout = stream.deadline.time_remaining() if stream.deadline else None
111
- geometries = await arm.get_geometries(extra=struct_to_dict(request.extra), timeout=timeout)
127
+ geometries = await gantry.get_geometries(extra=struct_to_dict(request.extra), timeout=timeout)
112
128
  response = GetGeometriesResponse(geometries=geometries)
113
129
  await stream.send_message(response)
@@ -1,3 +1,4 @@
1
+ from viam.proto.common import KinematicsFileFormat
1
2
  from viam.resource.registry import Registry, ResourceRegistration
2
3
 
3
4
  from .client import GripperClient
@@ -6,6 +7,7 @@ from .service import GripperRPCService
6
7
 
7
8
  __all__ = [
8
9
  "Gripper",
10
+ "KinematicsFileFormat",
9
11
  ]
10
12
 
11
13
  Registry.register_api(ResourceRegistration(Gripper, GripperRPCService, lambda name, channel: GripperClient(name, channel)))
@@ -1,12 +1,14 @@
1
- from typing import Any, Dict, List, Mapping, Optional
1
+ from typing import Any, Dict, List, Mapping, Optional, Tuple
2
2
 
3
3
  from grpclib.client import Channel
4
4
 
5
- from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry
5
+ from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry, GetKinematicsRequest, GetKinematicsResponse
6
6
  from viam.proto.component.gripper import (
7
7
  GrabRequest,
8
8
  GrabResponse,
9
9
  GripperServiceStub,
10
+ IsHoldingSomethingRequest,
11
+ IsHoldingSomethingResponse,
10
12
  IsMovingRequest,
11
13
  IsMovingResponse,
12
14
  OpenRequest,
@@ -15,6 +17,7 @@ from viam.proto.component.gripper import (
15
17
  from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase
16
18
  from viam.utils import ValueTypes, dict_to_struct, get_geometries, struct_to_dict
17
19
 
20
+ from . import KinematicsFileFormat
18
21
  from .gripper import Gripper
19
22
 
20
23
 
@@ -62,6 +65,14 @@ class GripperClient(Gripper, ReconfigurableResourceRPCClientBase):
62
65
  request = StopRequest(name=self.name, extra=dict_to_struct(extra))
63
66
  await self.client.Stop(request, timeout=timeout, metadata=md)
64
67
 
68
+ async def is_holding_something(
69
+ self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs
70
+ ) -> Gripper.HoldingStatus:
71
+ md = kwargs.get("metadata", self.Metadata()).proto
72
+ request = IsHoldingSomethingRequest(name=self.name, extra=dict_to_struct(extra))
73
+ response: IsHoldingSomethingResponse = await self.client.IsHoldingSomething(request, timeout=timeout, metadata=md)
74
+ return Gripper.HoldingStatus(response.is_holding_something, meta=struct_to_dict(response.meta))
75
+
65
76
  async def is_moving(self, *, timeout: Optional[float] = None, **kwargs) -> bool:
66
77
  md = kwargs.get("metadata", self.Metadata()).proto
67
78
  request = IsMovingRequest(name=self.name)
@@ -83,3 +94,15 @@ class GripperClient(Gripper, ReconfigurableResourceRPCClientBase):
83
94
  async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> List[Geometry]:
84
95
  md = kwargs.get("metadata", self.Metadata())
85
96
  return await get_geometries(self.client, self.name, extra, timeout, md)
97
+
98
+ async def get_kinematics(
99
+ self,
100
+ *,
101
+ extra: Optional[Dict[str, Any]] = None,
102
+ timeout: Optional[float] = None,
103
+ **kwargs,
104
+ ) -> Tuple[KinematicsFileFormat.ValueType, bytes]:
105
+ md = kwargs.get("metadata", self.Metadata()).proto
106
+ request = GetKinematicsRequest(name=self.name, extra=dict_to_struct(extra))
107
+ response: GetKinematicsResponse = await self.client.GetKinematics(request, timeout=timeout, metadata=md)
108
+ return (response.format, response.kinematics_data)