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.
- viam/app/app_client.py +225 -51
- viam/app/billing_client.py +47 -5
- viam/app/data_client.py +771 -234
- viam/app/ml_training_client.py +3 -5
- viam/app/provisioning_client.py +3 -5
- viam/app/viam_client.py +58 -11
- viam/components/arm/arm.py +1 -1
- viam/components/arm/service.py +1 -1
- viam/components/audio_in/__init__.py +24 -0
- viam/components/audio_in/audio_in.py +74 -0
- viam/components/audio_in/client.py +76 -0
- viam/components/audio_in/service.py +83 -0
- viam/components/audio_out/__init__.py +21 -0
- viam/components/audio_out/audio_out.py +72 -0
- viam/components/audio_out/client.py +67 -0
- viam/components/audio_out/service.py +63 -0
- viam/components/base/base.py +1 -1
- viam/components/board/board.py +8 -2
- viam/components/board/client.py +2 -1
- viam/components/board/service.py +1 -0
- viam/components/button/__init__.py +10 -0
- viam/components/button/button.py +41 -0
- viam/components/button/client.py +52 -0
- viam/components/button/service.py +46 -0
- viam/components/camera/camera.py +15 -30
- viam/components/camera/client.py +10 -21
- viam/components/camera/service.py +15 -28
- viam/components/component_base.py +2 -2
- viam/components/gantry/client.py +17 -2
- viam/components/gantry/gantry.py +32 -1
- viam/components/gantry/service.py +21 -5
- viam/components/gripper/__init__.py +2 -0
- viam/components/gripper/client.py +25 -2
- viam/components/gripper/gripper.py +76 -1
- viam/components/gripper/service.py +32 -3
- viam/components/input/input.py +1 -1
- viam/components/motor/motor.py +1 -1
- viam/components/power_sensor/power_sensor.py +1 -1
- viam/components/switch/__init__.py +10 -0
- viam/components/switch/client.py +83 -0
- viam/components/switch/service.py +72 -0
- viam/components/switch/switch.py +98 -0
- viam/gen/app/agent/v1/agent_pb2.py +1 -1
- viam/gen/app/cloudslam/v1/cloud_slam_pb2.py +1 -1
- viam/gen/app/data/v1/data_grpc.py +74 -2
- viam/gen/app/data/v1/data_pb2.py +198 -104
- viam/gen/app/data/v1/data_pb2.pyi +563 -31
- viam/gen/app/datapipelines/__init__.py +0 -0
- viam/gen/app/datapipelines/v1/__init__.py +0 -0
- viam/gen/app/datapipelines/v1/data_pipelines_grpc.py +84 -0
- viam/gen/app/datapipelines/v1/data_pipelines_pb2.py +57 -0
- viam/gen/app/datapipelines/v1/data_pipelines_pb2.pyi +387 -0
- viam/gen/app/dataset/v1/dataset_grpc.py +10 -2
- viam/gen/app/dataset/v1/dataset_pb2.py +8 -4
- viam/gen/app/dataset/v1/dataset_pb2.pyi +36 -1
- viam/gen/app/datasync/v1/data_sync_pb2.py +39 -35
- viam/gen/app/datasync/v1/data_sync_pb2.pyi +21 -8
- viam/gen/app/mlinference/v1/ml_inference_pb2.py +7 -7
- viam/gen/app/mlinference/v1/ml_inference_pb2.pyi +4 -2
- viam/gen/app/mltraining/v1/ml_training_grpc.py +10 -2
- viam/gen/app/mltraining/v1/ml_training_pb2.py +63 -43
- viam/gen/app/mltraining/v1/ml_training_pb2.pyi +112 -7
- viam/gen/app/packages/v1/packages_pb2.py +1 -1
- viam/gen/app/v1/app_grpc.py +74 -3
- viam/gen/app/v1/app_pb2.py +600 -545
- viam/gen/app/v1/app_pb2.pyi +1108 -258
- viam/gen/app/v1/billing_grpc.py +26 -2
- viam/gen/app/v1/billing_pb2.py +52 -36
- viam/gen/app/v1/billing_pb2.pyi +158 -4
- viam/gen/app/v1/end_user_pb2.py +1 -1
- viam/gen/app/v1/robot_pb2.py +95 -89
- viam/gen/app/v1/robot_pb2.pyi +121 -9
- viam/gen/common/v1/common_pb2.py +76 -58
- viam/gen/common/v1/common_pb2.pyi +186 -17
- viam/gen/component/arm/v1/arm_grpc.py +10 -2
- viam/gen/component/arm/v1/arm_pb2.py +5 -3
- viam/gen/component/audioin/__init__.py +0 -0
- viam/gen/component/audioin/v1/__init__.py +0 -0
- viam/gen/component/audioin/v1/audioin_grpc.py +54 -0
- viam/gen/component/audioin/v1/audioin_pb2.py +34 -0
- viam/gen/component/audioin/v1/audioin_pb2.pyi +94 -0
- viam/gen/component/audioinput/v1/audioinput_pb2.py +1 -1
- viam/gen/component/audioout/__init__.py +0 -0
- viam/gen/component/audioout/v1/__init__.py +0 -0
- viam/gen/component/audioout/v1/audioout_grpc.py +54 -0
- viam/gen/component/audioout/v1/audioout_pb2.py +32 -0
- viam/gen/component/audioout/v1/audioout_pb2.pyi +47 -0
- viam/gen/component/base/v1/base_pb2.py +1 -1
- viam/gen/component/board/v1/board_pb2.py +1 -1
- viam/gen/component/button/v1/button_pb2.py +1 -1
- viam/gen/component/camera/v1/camera_grpc.py +1 -0
- viam/gen/component/camera/v1/camera_pb2.py +37 -36
- viam/gen/component/camera/v1/camera_pb2.pyi +31 -4
- viam/gen/component/encoder/v1/encoder_pb2.py +1 -1
- viam/gen/component/gantry/v1/gantry_grpc.py +9 -1
- viam/gen/component/gantry/v1/gantry_pb2.py +5 -3
- viam/gen/component/generic/v1/generic_pb2.py +1 -1
- viam/gen/component/gripper/v1/gripper_grpc.py +18 -2
- viam/gen/component/gripper/v1/gripper_pb2.py +12 -4
- viam/gen/component/gripper/v1/gripper_pb2.pyi +43 -1
- viam/gen/component/inputcontroller/v1/input_controller_pb2.py +1 -1
- viam/gen/component/motor/v1/motor_pb2.py +1 -1
- viam/gen/component/movementsensor/v1/movementsensor_pb2.py +1 -1
- viam/gen/component/posetracker/v1/pose_tracker_pb2.py +1 -1
- viam/gen/component/powersensor/v1/powersensor_pb2.py +1 -1
- viam/gen/component/sensor/v1/sensor_pb2.py +1 -1
- viam/gen/component/servo/v1/servo_pb2.py +1 -1
- viam/gen/component/switch/v1/switch_pb2.py +5 -5
- viam/gen/component/switch/v1/switch_pb2.pyi +9 -2
- viam/gen/component/testecho/v1/testecho_pb2.py +1 -1
- viam/gen/module/v1/module_pb2.py +5 -5
- viam/gen/module/v1/module_pb2.pyi +7 -2
- viam/gen/opentelemetry/__init__.py +0 -0
- viam/gen/opentelemetry/proto/__init__.py +0 -0
- viam/gen/opentelemetry/proto/common/__init__.py +0 -0
- viam/gen/opentelemetry/proto/common/v1/__init__.py +0 -0
- viam/gen/opentelemetry/proto/common/v1/common_grpc.py +0 -0
- viam/gen/opentelemetry/proto/common/v1/common_pb2.py +27 -0
- viam/gen/opentelemetry/proto/common/v1/common_pb2.pyi +208 -0
- viam/gen/opentelemetry/proto/resource/__init__.py +0 -0
- viam/gen/opentelemetry/proto/resource/v1/__init__.py +0 -0
- viam/gen/opentelemetry/proto/resource/v1/resource_grpc.py +0 -0
- viam/gen/opentelemetry/proto/resource/v1/resource_pb2.py +18 -0
- viam/gen/opentelemetry/proto/resource/v1/resource_pb2.pyi +59 -0
- viam/gen/opentelemetry/proto/trace/__init__.py +0 -0
- viam/gen/opentelemetry/proto/trace/v1/__init__.py +0 -0
- viam/gen/opentelemetry/proto/trace/v1/trace_grpc.py +0 -0
- viam/gen/opentelemetry/proto/trace/v1/trace_pb2.py +37 -0
- viam/gen/opentelemetry/proto/trace/v1/trace_pb2.pyi +402 -0
- viam/gen/proto/rpc/examples/echo/v1/echo_pb2.py +1 -1
- viam/gen/proto/rpc/examples/echoresource/v1/echoresource_pb2.py +1 -1
- viam/gen/proto/rpc/v1/auth_pb2.py +1 -1
- viam/gen/proto/rpc/webrtc/v1/grpc_pb2.py +1 -1
- viam/gen/proto/rpc/webrtc/v1/signaling_pb2.py +1 -1
- viam/gen/provisioning/v1/provisioning_grpc.py +10 -2
- viam/gen/provisioning/v1/provisioning_pb2.py +32 -26
- viam/gen/provisioning/v1/provisioning_pb2.pyi +46 -5
- viam/gen/robot/v1/robot_grpc.py +51 -34
- viam/gen/robot/v1/robot_pb2.py +147 -142
- viam/gen/robot/v1/robot_pb2.pyi +153 -86
- viam/gen/service/datamanager/v1/data_manager_grpc.py +11 -2
- viam/gen/service/datamanager/v1/data_manager_pb2.py +15 -8
- viam/gen/service/datamanager/v1/data_manager_pb2.pyi +47 -1
- viam/gen/service/discovery/v1/discovery_pb2.py +1 -1
- viam/gen/service/generic/v1/generic_pb2.py +1 -1
- viam/gen/service/mlmodel/v1/mlmodel_pb2.py +1 -1
- viam/gen/service/motion/v1/motion_pb2.py +92 -62
- viam/gen/service/motion/v1/motion_pb2.pyi +130 -68
- viam/gen/service/navigation/v1/navigation_pb2.py +1 -1
- viam/gen/service/sensors/v1/sensors_pb2.py +1 -1
- viam/gen/service/shell/v1/shell_pb2.py +1 -1
- viam/gen/service/slam/v1/slam_pb2.py +1 -1
- viam/gen/service/slam/v1/slam_pb2.pyi +1 -1
- viam/gen/service/video/__init__.py +0 -0
- viam/gen/service/video/v1/__init__.py +0 -0
- viam/gen/service/video/v1/video_grpc.py +39 -0
- viam/gen/service/video/v1/video_pb2.py +29 -0
- viam/gen/service/video/v1/video_pb2.pyi +72 -0
- viam/gen/service/vision/v1/vision_pb2.py +27 -27
- viam/gen/service/vision/v1/vision_pb2.pyi +28 -3
- viam/gen/service/worldstatestore/__init__.py +0 -0
- viam/gen/service/worldstatestore/v1/__init__.py +0 -0
- viam/gen/service/worldstatestore/v1/world_state_store_grpc.py +55 -0
- viam/gen/service/worldstatestore/v1/world_state_store_pb2.py +39 -0
- viam/gen/service/worldstatestore/v1/world_state_store_pb2.pyi +171 -0
- viam/gen/stream/v1/stream_pb2.py +1 -1
- viam/gen/tagger/v1/tagger_pb2.py +1 -1
- viam/logging.py +9 -8
- viam/media/audio.py +22 -10
- viam/media/utils/pil/__init__.py +5 -1
- viam/media/video.py +54 -40
- viam/module/module.py +85 -16
- viam/module/resource_data_consumer.py +41 -0
- viam/module/service.py +9 -1
- viam/proto/app/__init__.py +68 -0
- viam/proto/app/billing.py +16 -0
- viam/proto/app/data/__init__.py +48 -0
- viam/proto/app/datapipelines/__init__.py +56 -0
- viam/proto/app/dataset/__init__.py +4 -0
- viam/proto/app/mltraining/__init__.py +6 -0
- viam/proto/app/robot.py +6 -0
- viam/proto/common/__init__.py +14 -0
- viam/proto/component/audioin/__init__.py +16 -0
- viam/proto/component/audioout/__init__.py +15 -0
- viam/proto/component/camera/__init__.py +0 -2
- viam/proto/component/gripper/__init__.py +4 -0
- viam/proto/opentelemetry/__init__.py +0 -0
- viam/proto/opentelemetry/proto/__init__.py +0 -0
- viam/proto/opentelemetry/proto/common/__init__.py +15 -0
- viam/proto/opentelemetry/proto/resource/__init__.py +10 -0
- viam/proto/opentelemetry/proto/trace/__init__.py +15 -0
- viam/proto/provisioning/__init__.py +6 -0
- viam/proto/robot/__init__.py +16 -8
- viam/proto/service/datamanager/__init__.py +8 -1
- viam/proto/service/motion/__init__.py +2 -0
- viam/proto/service/video/__init__.py +15 -0
- viam/proto/service/worldstatestore/__init__.py +32 -0
- viam/resource/easy_resource.py +5 -9
- viam/resource/manager.py +4 -3
- viam/resource/registry.py +2 -2
- viam/resource/types.py +2 -2
- viam/robot/client.py +38 -59
- viam/rpc/dial.py +48 -5
- viam/rpc/libviam_rust_utils.so +0 -0
- viam/rpc/server.py +24 -10
- viam/services/motion/client.py +8 -9
- viam/services/motion/motion.py +48 -46
- viam/services/navigation/navigation.py +2 -2
- viam/services/vision/client.py +1 -1
- viam/services/vision/service.py +5 -8
- viam/services/vision/vision.py +5 -3
- viam/services/worldstatestore/__init__.py +18 -0
- viam/services/worldstatestore/client.py +94 -0
- viam/services/worldstatestore/service.py +55 -0
- viam/services/worldstatestore/worldstatestore.py +90 -0
- viam/sessions_client.py +115 -46
- viam/version_metadata.py +2 -2
- {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/METADATA +10 -6
- {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/RECORD +221 -152
- {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/WHEEL +1 -1
- viam/components/audio_input/__init__.py +0 -18
- viam/components/audio_input/audio_input.py +0 -81
- viam/components/audio_input/client.py +0 -70
- viam/components/audio_input/service.py +0 -114
- {viam_sdk-0.41.1.dist-info → viam_sdk-0.66.0.dist-info}/licenses/LICENSE +0 -0
viam/app/ml_training_client.py
CHANGED
|
@@ -46,11 +46,9 @@ class MLTrainingClient:
|
|
|
46
46
|
async def main():
|
|
47
47
|
|
|
48
48
|
# Make a ViamClient
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
viam_client.close()
|
|
49
|
+
async with await connect() as viam_client:
|
|
50
|
+
# Instantiate an MLTrainingClient to run ML training client API methods on
|
|
51
|
+
ml_training_client = viam_client.ml_training_client
|
|
54
52
|
|
|
55
53
|
if __name__ == '__main__':
|
|
56
54
|
asyncio.run(main())
|
viam/app/provisioning_client.py
CHANGED
|
@@ -41,11 +41,9 @@ class ProvisioningClient:
|
|
|
41
41
|
async def main():
|
|
42
42
|
|
|
43
43
|
# Make a ViamClient
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
viam_client.close()
|
|
44
|
+
async with await connect() as viam_client:
|
|
45
|
+
# Instantiate a ProvisioningClient to run provisioning client API methods on
|
|
46
|
+
provisioning_client = viam_client.provisioning_client
|
|
49
47
|
|
|
50
48
|
if __name__ == '__main__':
|
|
51
49
|
asyncio.run(main())
|
viam/app/viam_client.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import os
|
|
2
|
+
from typing import Any, Mapping, Optional
|
|
2
3
|
|
|
3
4
|
from grpclib.client import Channel
|
|
4
5
|
from typing_extensions import Self
|
|
@@ -10,7 +11,7 @@ from viam.app.data_client import DataClient
|
|
|
10
11
|
from viam.app.ml_training_client import MLTrainingClient
|
|
11
12
|
from viam.app.provisioning_client import ProvisioningClient
|
|
12
13
|
from viam.robot.client import RobotClient
|
|
13
|
-
from viam.rpc.dial import DialOptions, _dial_app, _get_access_token
|
|
14
|
+
from viam.rpc.dial import Credentials, DialOptions, _dial_app, _get_access_token
|
|
14
15
|
|
|
15
16
|
LOGGER = logging.getLogger(__name__)
|
|
16
17
|
|
|
@@ -19,19 +20,51 @@ class ViamClient:
|
|
|
19
20
|
"""gRPC client for all communication and interaction with app.
|
|
20
21
|
|
|
21
22
|
`ViamClient` class for creating and managing specialized client instances.
|
|
22
|
-
There
|
|
23
|
+
There are currently 2 ways to instantiate a `ViamClient` object::
|
|
23
24
|
|
|
24
25
|
ViamClient.create_from_dial_options(...)
|
|
26
|
+
ViamClient.create_from_env_vars()
|
|
25
27
|
"""
|
|
26
28
|
|
|
29
|
+
@classmethod
|
|
30
|
+
async def create_from_env_vars(cls, dial_options: Optional[DialOptions] = None, app_url: Optional[str] = None) -> Self:
|
|
31
|
+
"""Create `ViamClient` using credentials set in the environment as `VIAM_API_KEY` and `VIAM_API_KEY_ID`.
|
|
32
|
+
|
|
33
|
+
::
|
|
34
|
+
|
|
35
|
+
client = await ViamClient.create_from_env_vars()
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
dial_options (Optional[viam.rpc.dial.DialOptions]): Options for authorization and connection to app.
|
|
39
|
+
If not provided, default options will be selected. Note that `creds` and `auth_entity`
|
|
40
|
+
fields will be overwritten by the values set by a module.
|
|
41
|
+
app_url: (Optional[str]): URL of app. Uses app.viam.com if not specified.
|
|
42
|
+
|
|
43
|
+
Raises:
|
|
44
|
+
ValueError: If there are no env vars set by the module, or if they are set improperly
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
dial_options = dial_options if dial_options else DialOptions()
|
|
48
|
+
api_key = os.environ.get("VIAM_API_KEY")
|
|
49
|
+
if api_key is None:
|
|
50
|
+
raise ValueError("api key cannot be None")
|
|
51
|
+
api_key_id = os.environ.get("VIAM_API_KEY_ID")
|
|
52
|
+
if api_key_id is None:
|
|
53
|
+
raise ValueError("api key ID cannot be None")
|
|
54
|
+
credentials = Credentials(type="api-key", payload=api_key)
|
|
55
|
+
dial_options.credentials = credentials
|
|
56
|
+
dial_options.auth_entity = api_key_id
|
|
57
|
+
|
|
58
|
+
return await cls.create_from_dial_options(dial_options, app_url)
|
|
59
|
+
|
|
27
60
|
@classmethod
|
|
28
61
|
async def create_from_dial_options(cls, dial_options: DialOptions, app_url: Optional[str] = None) -> Self:
|
|
29
|
-
"""Create `ViamClient` that establishes a connection to
|
|
62
|
+
"""Create `ViamClient` that establishes a connection to Viam.
|
|
30
63
|
|
|
31
64
|
::
|
|
32
65
|
|
|
33
66
|
dial_options = DialOptions.with_api_key("<API-KEY>", "<API-KEY-ID>")
|
|
34
|
-
ViamClient.create_from_dial_options(dial_options)
|
|
67
|
+
client = await ViamClient.create_from_dial_options(dial_options)
|
|
35
68
|
|
|
36
69
|
Args:
|
|
37
70
|
dial_options (viam.rpc.dial.DialOptions): Required information for authorization and connection to app.
|
|
@@ -53,9 +86,6 @@ class ViamClient:
|
|
|
53
86
|
|
|
54
87
|
self = cls()
|
|
55
88
|
self._dial_options = dial_options
|
|
56
|
-
self._location_id = None
|
|
57
|
-
if dial_options.credentials.type == "robot-location-secret":
|
|
58
|
-
self._location_id = dial_options.auth_entity.split(".")[1]
|
|
59
89
|
if app_url is None:
|
|
60
90
|
app_url = "app.viam.com"
|
|
61
91
|
self._channel = await _dial_app(app_url)
|
|
@@ -66,7 +96,6 @@ class ViamClient:
|
|
|
66
96
|
_channel: Channel
|
|
67
97
|
_metadata: Mapping[str, str]
|
|
68
98
|
_closed: bool = False
|
|
69
|
-
_location_id: Optional[str]
|
|
70
99
|
_dial_options: DialOptions
|
|
71
100
|
|
|
72
101
|
@property
|
|
@@ -108,7 +137,7 @@ class ViamClient:
|
|
|
108
137
|
# Instantiate an AppClient called "fleet" to run fleet management API methods on
|
|
109
138
|
fleet = viam_client.app_client
|
|
110
139
|
"""
|
|
111
|
-
return AppClient(self._channel, self._metadata
|
|
140
|
+
return AppClient(self._channel, self._metadata)
|
|
112
141
|
|
|
113
142
|
@property
|
|
114
143
|
def ml_training_client(self) -> MLTrainingClient:
|
|
@@ -174,7 +203,25 @@ class ViamClient:
|
|
|
174
203
|
"""
|
|
175
204
|
return ProvisioningClient(self._channel, self._metadata)
|
|
176
205
|
|
|
177
|
-
def
|
|
206
|
+
async def __aenter__(self) -> "ViamClient":
|
|
207
|
+
"""A ViamClient can act as an asynchronous context manager. It will do nothing special when
|
|
208
|
+
the context is entered.
|
|
209
|
+
"""
|
|
210
|
+
return self
|
|
211
|
+
|
|
212
|
+
async def __aexit__(self, exc_type: Optional[type], exc_value: Optional[BaseException], traceback: Optional[Any]) -> None:
|
|
213
|
+
"""A ViamClient can act as an asynchronous context manager. It will close itself when
|
|
214
|
+
the context is exited.
|
|
215
|
+
|
|
216
|
+
::
|
|
217
|
+
|
|
218
|
+
async with ViamClient.create_from_dial_options(...) as client:
|
|
219
|
+
await do_something_with(client)
|
|
220
|
+
# client is closed here
|
|
221
|
+
"""
|
|
222
|
+
self.close()
|
|
223
|
+
|
|
224
|
+
def close(self) -> None:
|
|
178
225
|
"""Close opened channels used for the various service stubs initialized."""
|
|
179
226
|
if self._closed:
|
|
180
227
|
LOGGER.debug("ViamClient is already closed.")
|
viam/components/arm/arm.py
CHANGED
|
@@ -194,7 +194,7 @@ class Arm(ComponentBase):
|
|
|
194
194
|
|
|
195
195
|
@abc.abstractmethod
|
|
196
196
|
async def get_kinematics(
|
|
197
|
-
self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None
|
|
197
|
+
self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs
|
|
198
198
|
) -> Tuple[KinematicsFileFormat.ValueType, bytes]:
|
|
199
199
|
"""
|
|
200
200
|
Get the kinematics information associated with the arm.
|
viam/components/arm/service.py
CHANGED
|
@@ -109,7 +109,7 @@ class ArmRPCService(UnimplementedArmServiceBase, ResourceRPCServiceBase[Arm]):
|
|
|
109
109
|
assert request is not None
|
|
110
110
|
arm = self.get_resource(request.name)
|
|
111
111
|
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
112
|
-
format, kinematics_data = await arm.get_kinematics(extra=struct_to_dict(request.extra), timeout=timeout)
|
|
112
|
+
format, kinematics_data = await arm.get_kinematics(extra=struct_to_dict(request.extra), timeout=timeout, metadata=stream.metadata)
|
|
113
113
|
response = GetKinematicsResponse(format=format, kinematics_data=kinematics_data)
|
|
114
114
|
await stream.send_message(response)
|
|
115
115
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from viam.media.audio import AudioCodec
|
|
2
|
+
from viam.proto.common import AudioInfo
|
|
3
|
+
from viam.resource.registry import Registry, ResourceRegistration
|
|
4
|
+
|
|
5
|
+
from .audio_in import AudioIn
|
|
6
|
+
from .client import AudioInClient
|
|
7
|
+
from .service import AudioInRPCService
|
|
8
|
+
|
|
9
|
+
AudioResponse = AudioIn.AudioResponse
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"AudioIn",
|
|
13
|
+
"AudioResponse",
|
|
14
|
+
"AudioInfo",
|
|
15
|
+
"AudioCodec",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
Registry.register_api(
|
|
19
|
+
ResourceRegistration(
|
|
20
|
+
AudioIn,
|
|
21
|
+
AudioInRPCService,
|
|
22
|
+
lambda name, channel: AudioInClient(name, channel),
|
|
23
|
+
)
|
|
24
|
+
)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import sys
|
|
3
|
+
from typing import Final, Optional
|
|
4
|
+
|
|
5
|
+
from viam.proto.common import GetPropertiesResponse
|
|
6
|
+
from viam.proto.component.audioin import GetAudioResponse
|
|
7
|
+
from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT
|
|
8
|
+
from viam.streams import Stream
|
|
9
|
+
|
|
10
|
+
from ..component_base import ComponentBase
|
|
11
|
+
|
|
12
|
+
if sys.version_info >= (3, 10):
|
|
13
|
+
from typing import TypeAlias
|
|
14
|
+
else:
|
|
15
|
+
from typing_extensions import TypeAlias
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AudioIn(ComponentBase):
|
|
19
|
+
"""AudioIn represents a component that can capture audio.
|
|
20
|
+
|
|
21
|
+
This acts as an abstract base class for any drivers representing specific
|
|
22
|
+
audio input implementations. This cannot be used on its own. If the ``__init__()`` function is
|
|
23
|
+
overridden, it must call the ``super().__init__()`` function.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
API: Final = API( # pyright: ignore [reportIncompatibleVariableOverride]
|
|
27
|
+
RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT, "audio_in"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
Properties: "TypeAlias" = GetPropertiesResponse
|
|
31
|
+
AudioResponse: "TypeAlias" = GetAudioResponse
|
|
32
|
+
AudioStream = Stream[AudioResponse]
|
|
33
|
+
|
|
34
|
+
@abc.abstractmethod
|
|
35
|
+
async def get_audio(
|
|
36
|
+
self, codec: str, duration_seconds: float, previous_timestamp_ns: int, *, timeout: Optional[float] = None, **kwargs
|
|
37
|
+
) -> AudioStream:
|
|
38
|
+
"""
|
|
39
|
+
Get a stream of audio from the device
|
|
40
|
+
|
|
41
|
+
::
|
|
42
|
+
|
|
43
|
+
my_audio_in = AudioIn.from_robot(robot=machine, name="my_audio_in")
|
|
44
|
+
|
|
45
|
+
stream = await my_audio_in.get_audio(
|
|
46
|
+
codec=AudioCodec.PCM16,
|
|
47
|
+
duration_seconds=10.0,
|
|
48
|
+
previous_timestamp_ns=0
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
codec (str): The desired codec of the returned audio data
|
|
53
|
+
duration_seconds (float): duration of the stream. 0 = indefinite stream
|
|
54
|
+
previous_timestamp_ns (int): starting timestamp in nanoseconds for recording continuity.
|
|
55
|
+
Set to 0 to begin recording from the current time.
|
|
56
|
+
Returns:
|
|
57
|
+
AudioStream: stream of audio chunks.
|
|
58
|
+
...
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
@abc.abstractmethod
|
|
62
|
+
async def get_properties(self, *, timeout: Optional[float] = None, **kwargs) -> Properties:
|
|
63
|
+
"""
|
|
64
|
+
Get the audio device's properties
|
|
65
|
+
|
|
66
|
+
::
|
|
67
|
+
|
|
68
|
+
my_audio_in = AudioIn.from_robot(robot=machine, name="my_audio_in")
|
|
69
|
+
properties = await my_audio_in.get_properties()
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
Properties: The properties of the audio in device.
|
|
73
|
+
...
|
|
74
|
+
"""
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from typing import Any, Dict, List, Mapping, Optional
|
|
3
|
+
|
|
4
|
+
from grpclib.client import Channel
|
|
5
|
+
from grpclib.client import Stream as ClientStream
|
|
6
|
+
|
|
7
|
+
from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry, GetPropertiesRequest
|
|
8
|
+
from viam.proto.component.audioin import AudioInServiceStub, GetAudioRequest, GetAudioResponse
|
|
9
|
+
from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase
|
|
10
|
+
from viam.streams import StreamWithIterator
|
|
11
|
+
from viam.utils import ValueTypes, dict_to_struct, get_geometries, struct_to_dict
|
|
12
|
+
|
|
13
|
+
from .audio_in import AudioIn
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AudioInClient(AudioIn, ReconfigurableResourceRPCClientBase):
|
|
17
|
+
def __init__(self, name: str, channel: Channel) -> None:
|
|
18
|
+
self.channel = channel
|
|
19
|
+
self.client = AudioInServiceStub(channel)
|
|
20
|
+
super().__init__(name)
|
|
21
|
+
|
|
22
|
+
async def get_audio(
|
|
23
|
+
self,
|
|
24
|
+
codec: str,
|
|
25
|
+
duration_seconds: float,
|
|
26
|
+
previous_timestamp_ns: int,
|
|
27
|
+
*,
|
|
28
|
+
extra: Optional[Dict[str, Any]] = None,
|
|
29
|
+
**kwargs,
|
|
30
|
+
):
|
|
31
|
+
request = GetAudioRequest(
|
|
32
|
+
name=self.name,
|
|
33
|
+
codec=codec,
|
|
34
|
+
duration_seconds=duration_seconds,
|
|
35
|
+
previous_timestamp_nanoseconds=previous_timestamp_ns,
|
|
36
|
+
request_id=str(uuid.uuid4()),
|
|
37
|
+
extra=dict_to_struct(extra),
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
async def read():
|
|
41
|
+
md = kwargs.get("metadata", self.Metadata()).proto
|
|
42
|
+
audio_stream: ClientStream[GetAudioRequest, GetAudioResponse]
|
|
43
|
+
async with self.client.GetAudio.open(metadata=md) as audio_stream:
|
|
44
|
+
try:
|
|
45
|
+
await audio_stream.send_message(request, end=True)
|
|
46
|
+
async for response in audio_stream:
|
|
47
|
+
yield response
|
|
48
|
+
except Exception as e:
|
|
49
|
+
raise (e)
|
|
50
|
+
|
|
51
|
+
return StreamWithIterator(read())
|
|
52
|
+
|
|
53
|
+
async def get_properties(
|
|
54
|
+
self,
|
|
55
|
+
*,
|
|
56
|
+
timeout: Optional[float] = None,
|
|
57
|
+
**kwargs,
|
|
58
|
+
) -> AudioIn.Properties:
|
|
59
|
+
md = kwargs.get("metadata", self.Metadata()).proto
|
|
60
|
+
return await self.client.GetProperties(GetPropertiesRequest(name=self.name), timeout=timeout, metadata=md)
|
|
61
|
+
|
|
62
|
+
async def do_command(
|
|
63
|
+
self,
|
|
64
|
+
command: Mapping[str, ValueTypes],
|
|
65
|
+
*,
|
|
66
|
+
timeout: Optional[float] = None,
|
|
67
|
+
**kwargs,
|
|
68
|
+
) -> Mapping[str, ValueTypes]:
|
|
69
|
+
md = kwargs.get("metadata", self.Metadata()).proto
|
|
70
|
+
request = DoCommandRequest(name=self.name, command=dict_to_struct(command))
|
|
71
|
+
response: DoCommandResponse = await self.client.DoCommand(request, timeout=timeout, metadata=md)
|
|
72
|
+
return struct_to_dict(response.result)
|
|
73
|
+
|
|
74
|
+
async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> List[Geometry]:
|
|
75
|
+
md = kwargs.get("metadata", self.Metadata())
|
|
76
|
+
return await get_geometries(self.client, self.name, extra, timeout, md)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from grpclib.server import Stream
|
|
2
|
+
from h2.exceptions import StreamClosedError
|
|
3
|
+
|
|
4
|
+
from viam.logging import getLogger
|
|
5
|
+
from viam.proto.common import (
|
|
6
|
+
DoCommandRequest,
|
|
7
|
+
DoCommandResponse,
|
|
8
|
+
GetGeometriesRequest,
|
|
9
|
+
GetGeometriesResponse,
|
|
10
|
+
GetPropertiesRequest,
|
|
11
|
+
GetPropertiesResponse,
|
|
12
|
+
)
|
|
13
|
+
from viam.proto.component.audioin import AudioInServiceBase, GetAudioRequest, GetAudioResponse
|
|
14
|
+
from viam.resource.rpc_service_base import ResourceRPCServiceBase
|
|
15
|
+
from viam.utils import dict_to_struct, struct_to_dict
|
|
16
|
+
|
|
17
|
+
from .audio_in import AudioIn
|
|
18
|
+
|
|
19
|
+
LOGGER = getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AudioInRPCService(AudioInServiceBase, ResourceRPCServiceBase[AudioIn]):
|
|
23
|
+
"""
|
|
24
|
+
gRPC Service for a generic audio in.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
RESOURCE_TYPE = AudioIn
|
|
28
|
+
|
|
29
|
+
async def GetAudio(self, stream: Stream[GetAudioRequest, GetAudioResponse]) -> None:
|
|
30
|
+
request = await stream.recv_message()
|
|
31
|
+
assert request is not None
|
|
32
|
+
name = request.name
|
|
33
|
+
audio_in = self.get_resource(name)
|
|
34
|
+
audio_stream = await audio_in.get_audio(
|
|
35
|
+
codec=request.codec,
|
|
36
|
+
duration_seconds=request.duration_seconds,
|
|
37
|
+
previous_timestamp_ns=request.previous_timestamp_nanoseconds,
|
|
38
|
+
metadata=stream.metadata,
|
|
39
|
+
)
|
|
40
|
+
async for response in audio_stream:
|
|
41
|
+
try:
|
|
42
|
+
response.request_id = request.request_id
|
|
43
|
+
await stream.send_message(response)
|
|
44
|
+
except StreamClosedError:
|
|
45
|
+
return
|
|
46
|
+
except Exception as e:
|
|
47
|
+
LOGGER.error(e)
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
async def GetProperties(self, stream: Stream[GetPropertiesRequest, GetPropertiesResponse]) -> None:
|
|
51
|
+
request = await stream.recv_message()
|
|
52
|
+
assert request is not None
|
|
53
|
+
name = request.name
|
|
54
|
+
audio_in = self.get_resource(name)
|
|
55
|
+
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
56
|
+
properties = await audio_in.get_properties(
|
|
57
|
+
timeout=timeout,
|
|
58
|
+
metadata=stream.metadata,
|
|
59
|
+
)
|
|
60
|
+
await stream.send_message(properties)
|
|
61
|
+
|
|
62
|
+
async def DoCommand(self, stream: Stream[DoCommandRequest, DoCommandResponse]) -> None:
|
|
63
|
+
request = await stream.recv_message()
|
|
64
|
+
assert request is not None
|
|
65
|
+
name = request.name
|
|
66
|
+
audio_in = self.get_resource(name)
|
|
67
|
+
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
68
|
+
result = await audio_in.do_command(
|
|
69
|
+
command=struct_to_dict(request.command),
|
|
70
|
+
timeout=timeout,
|
|
71
|
+
metadata=stream.metadata,
|
|
72
|
+
)
|
|
73
|
+
response = DoCommandResponse(result=dict_to_struct(result))
|
|
74
|
+
await stream.send_message(response)
|
|
75
|
+
|
|
76
|
+
async def GetGeometries(self, stream: Stream[GetGeometriesRequest, GetGeometriesResponse]) -> None:
|
|
77
|
+
request = await stream.recv_message()
|
|
78
|
+
assert request is not None
|
|
79
|
+
arm = self.get_resource(request.name)
|
|
80
|
+
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
81
|
+
geometries = await arm.get_geometries(extra=struct_to_dict(request.extra), timeout=timeout)
|
|
82
|
+
response = GetGeometriesResponse(geometries=geometries)
|
|
83
|
+
await stream.send_message(response)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from viam.media.audio import AudioCodec
|
|
2
|
+
from viam.proto.common import AudioInfo
|
|
3
|
+
from viam.resource.registry import Registry, ResourceRegistration
|
|
4
|
+
|
|
5
|
+
from .audio_out import AudioOut
|
|
6
|
+
from .client import AudioOutClient
|
|
7
|
+
from .service import AudioOutRPCService
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"AudioOut",
|
|
11
|
+
"AudioInfo",
|
|
12
|
+
"AudioCodec",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
Registry.register_api(
|
|
16
|
+
ResourceRegistration(
|
|
17
|
+
AudioOut,
|
|
18
|
+
AudioOutRPCService,
|
|
19
|
+
lambda name, channel: AudioOutClient(name, channel),
|
|
20
|
+
)
|
|
21
|
+
)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import sys
|
|
3
|
+
from typing import Any, Dict, Final, Optional
|
|
4
|
+
|
|
5
|
+
from viam.proto.common import GetPropertiesResponse
|
|
6
|
+
from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT
|
|
7
|
+
|
|
8
|
+
from ..component_base import ComponentBase
|
|
9
|
+
from . import AudioInfo
|
|
10
|
+
|
|
11
|
+
if sys.version_info >= (3, 10):
|
|
12
|
+
from typing import TypeAlias
|
|
13
|
+
else:
|
|
14
|
+
from typing_extensions import TypeAlias
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class AudioOut(ComponentBase):
|
|
18
|
+
"""AudioOut represents a component that can play audio.
|
|
19
|
+
|
|
20
|
+
This acts as an abstract base class for any drivers representing specific
|
|
21
|
+
audio output implementations. This cannot be used on its own. If the ``__init__()`` function is
|
|
22
|
+
overridden, it must call the ``super().__init__()`` function.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
API: Final = API( # pyright: ignore [reportIncompatibleVariableOverride]
|
|
26
|
+
RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT, "audio_out"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
Properties: "TypeAlias" = GetPropertiesResponse
|
|
30
|
+
|
|
31
|
+
@abc.abstractmethod
|
|
32
|
+
async def play(
|
|
33
|
+
self,
|
|
34
|
+
data: bytes,
|
|
35
|
+
info: Optional[AudioInfo] = None,
|
|
36
|
+
*,
|
|
37
|
+
extra: Optional[Dict[str, Any]] = None,
|
|
38
|
+
timeout: Optional[float] = None,
|
|
39
|
+
**kwargs,
|
|
40
|
+
) -> None:
|
|
41
|
+
"""
|
|
42
|
+
Play the given audio data.
|
|
43
|
+
|
|
44
|
+
::
|
|
45
|
+
|
|
46
|
+
my_audio_out = AudioOut.from_robot(robot=machine, name="my_audio_out")
|
|
47
|
+
|
|
48
|
+
# With audio info
|
|
49
|
+
audio_info = AudioInfo(codec=AudioCodec.PCM16, sample_rate_hz=44100, num_channels=2)
|
|
50
|
+
await my_audio_out.play(audio_data, audio_info)
|
|
51
|
+
|
|
52
|
+
# Without audio info (when codec encodes information within audio_data)
|
|
53
|
+
await my_audio_out.play(audio_data)
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
data: audio bytes to play
|
|
57
|
+
info: (optional) information about the audio data such as codec, sample rate, and channel count
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
@abc.abstractmethod
|
|
61
|
+
async def get_properties(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> Properties:
|
|
62
|
+
"""
|
|
63
|
+
Get the audio output device's properties.
|
|
64
|
+
|
|
65
|
+
::
|
|
66
|
+
|
|
67
|
+
my_audio_out = AudioOut.from_robot(robot=machine, name="my_audio_out")
|
|
68
|
+
properties = await my_audio_out.get_properties()
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Properties: The properties of the audio output device
|
|
72
|
+
"""
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from typing import Any, Dict, List, Mapping, Optional
|
|
2
|
+
|
|
3
|
+
from grpclib.client import Channel
|
|
4
|
+
|
|
5
|
+
from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry, GetPropertiesRequest, GetPropertiesResponse
|
|
6
|
+
from viam.proto.component.audioout import AudioOutServiceStub, PlayRequest
|
|
7
|
+
from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase
|
|
8
|
+
from viam.utils import ValueTypes, dict_to_struct, get_geometries, struct_to_dict
|
|
9
|
+
|
|
10
|
+
from .audio_out import AudioInfo, AudioOut
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AudioOutClient(AudioOut, ReconfigurableResourceRPCClientBase):
|
|
14
|
+
"""gRPC client for AudioOut component."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, name: str, channel: Channel) -> None:
|
|
17
|
+
self.channel = channel
|
|
18
|
+
self.client = AudioOutServiceStub(channel)
|
|
19
|
+
super().__init__(name)
|
|
20
|
+
|
|
21
|
+
async def play(
|
|
22
|
+
self,
|
|
23
|
+
data: bytes,
|
|
24
|
+
info: Optional[AudioInfo] = None,
|
|
25
|
+
*,
|
|
26
|
+
extra: Optional[Dict[str, Any]] = None,
|
|
27
|
+
timeout: Optional[float] = None,
|
|
28
|
+
**kwargs,
|
|
29
|
+
) -> None:
|
|
30
|
+
if extra is None:
|
|
31
|
+
extra = {}
|
|
32
|
+
|
|
33
|
+
md = kwargs.get("metadata", self.Metadata()).proto
|
|
34
|
+
request = PlayRequest(
|
|
35
|
+
name=self.name,
|
|
36
|
+
audio_data=data,
|
|
37
|
+
audio_info=info,
|
|
38
|
+
extra=dict_to_struct(extra),
|
|
39
|
+
)
|
|
40
|
+
await self.client.Play(request, timeout=timeout, metadata=md)
|
|
41
|
+
|
|
42
|
+
async def get_properties(
|
|
43
|
+
self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs
|
|
44
|
+
) -> AudioOut.Properties:
|
|
45
|
+
if extra is None:
|
|
46
|
+
extra = {}
|
|
47
|
+
|
|
48
|
+
md = kwargs.get("metadata", self.Metadata()).proto
|
|
49
|
+
request = GetPropertiesRequest(name=self.name, extra=dict_to_struct(extra))
|
|
50
|
+
response: GetPropertiesResponse = await self.client.GetProperties(request, timeout=timeout, metadata=md)
|
|
51
|
+
return response
|
|
52
|
+
|
|
53
|
+
async def do_command(
|
|
54
|
+
self,
|
|
55
|
+
command: Mapping[str, ValueTypes],
|
|
56
|
+
*,
|
|
57
|
+
timeout: Optional[float] = None,
|
|
58
|
+
**kwargs,
|
|
59
|
+
) -> Mapping[str, ValueTypes]:
|
|
60
|
+
md = kwargs.get("metadata", self.Metadata()).proto
|
|
61
|
+
request = DoCommandRequest(name=self.name, command=dict_to_struct(command))
|
|
62
|
+
response: DoCommandResponse = await self.client.DoCommand(request, timeout=timeout, metadata=md)
|
|
63
|
+
return struct_to_dict(response.result)
|
|
64
|
+
|
|
65
|
+
async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> List[Geometry]:
|
|
66
|
+
md = kwargs.get("metadata", self.Metadata())
|
|
67
|
+
return await get_geometries(self.client, self.name, extra, timeout, md)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from grpclib.server import Stream
|
|
2
|
+
|
|
3
|
+
from viam.proto.common import (
|
|
4
|
+
DoCommandRequest,
|
|
5
|
+
DoCommandResponse,
|
|
6
|
+
GetGeometriesRequest,
|
|
7
|
+
GetGeometriesResponse,
|
|
8
|
+
GetPropertiesRequest,
|
|
9
|
+
GetPropertiesResponse,
|
|
10
|
+
)
|
|
11
|
+
from viam.proto.component.audioout import (
|
|
12
|
+
AudioOutServiceBase,
|
|
13
|
+
PlayRequest,
|
|
14
|
+
PlayResponse,
|
|
15
|
+
)
|
|
16
|
+
from viam.resource.rpc_service_base import ResourceRPCServiceBase
|
|
17
|
+
from viam.utils import dict_to_struct, struct_to_dict
|
|
18
|
+
|
|
19
|
+
from .audio_out import AudioOut
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AudioOutRPCService(AudioOutServiceBase, ResourceRPCServiceBase[AudioOut]):
|
|
23
|
+
"""gRPC service for AudioOut component."""
|
|
24
|
+
|
|
25
|
+
RESOURCE_TYPE = AudioOut
|
|
26
|
+
|
|
27
|
+
async def Play(self, stream: Stream[PlayRequest, PlayResponse]) -> None:
|
|
28
|
+
request = await stream.recv_message()
|
|
29
|
+
assert request is not None
|
|
30
|
+
name = request.name
|
|
31
|
+
audio_out = self.get_resource(name)
|
|
32
|
+
# Check if audio_info was provided in the request
|
|
33
|
+
audio_info = request.audio_info if request.HasField("audio_info") else None
|
|
34
|
+
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
35
|
+
await audio_out.play(request.audio_data, audio_info, extra=struct_to_dict(request.extra), timeout=timeout, metadata=stream.metadata)
|
|
36
|
+
await stream.send_message(PlayResponse())
|
|
37
|
+
|
|
38
|
+
async def GetProperties(self, stream: Stream[GetPropertiesRequest, GetPropertiesResponse]) -> None:
|
|
39
|
+
request = await stream.recv_message()
|
|
40
|
+
assert request is not None
|
|
41
|
+
name = request.name
|
|
42
|
+
audio_out = self.get_resource(name)
|
|
43
|
+
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
44
|
+
properties = await audio_out.get_properties(extra=struct_to_dict(request.extra), timeout=timeout, metadata=stream.metadata)
|
|
45
|
+
await stream.send_message(properties)
|
|
46
|
+
|
|
47
|
+
async def DoCommand(self, stream: Stream[DoCommandRequest, DoCommandResponse]) -> None:
|
|
48
|
+
request = await stream.recv_message()
|
|
49
|
+
assert request is not None
|
|
50
|
+
audio_out = self.get_resource(request.name)
|
|
51
|
+
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
52
|
+
result = await audio_out.do_command(command=struct_to_dict(request.command), timeout=timeout, metadata=stream.metadata)
|
|
53
|
+
response = DoCommandResponse(result=dict_to_struct(result))
|
|
54
|
+
await stream.send_message(response)
|
|
55
|
+
|
|
56
|
+
async def GetGeometries(self, stream: Stream[GetGeometriesRequest, GetGeometriesResponse]) -> None:
|
|
57
|
+
request = await stream.recv_message()
|
|
58
|
+
assert request is not None
|
|
59
|
+
audio_out = self.get_resource(request.name)
|
|
60
|
+
timeout = stream.deadline.time_remaining() if stream.deadline else None
|
|
61
|
+
geometries = await audio_out.get_geometries(extra=struct_to_dict(request.extra), timeout=timeout)
|
|
62
|
+
response = GetGeometriesResponse(geometries=geometries)
|
|
63
|
+
await stream.send_message(response)
|
viam/components/base/base.py
CHANGED
|
@@ -126,7 +126,7 @@ class Base(ComponentBase):
|
|
|
126
126
|
# Make your wheeled base move forward. Set linear power to 75%.
|
|
127
127
|
print("move forward")
|
|
128
128
|
await my_base.set_power(
|
|
129
|
-
linear=Vector3(x=0, y
|
|
129
|
+
linear=Vector3(x=0, y=.75, z=0),
|
|
130
130
|
angular=Vector3(x=0, y=0, z=0))
|
|
131
131
|
|
|
132
132
|
# Make your wheeled base move backward. Set linear power to -100%.
|