Skip to content

Commit 4f00a0c

Browse files
fix movement and power
1 parent 55064f5 commit 4f00a0c

File tree

9 files changed

+47
-140
lines changed

9 files changed

+47
-140
lines changed

src/viam/components/movement_sensor/client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
MovementSensorServiceStub,
2525
)
2626
from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase
27-
from viam.utils import ValueTypes, dict_to_struct, get_geometries, struct_to_dict, sensor_readings_value_to_native
27+
from viam.utils import ValueTypes, dict_to_struct, get_geometries, struct_to_dict
2828

2929
from . import GeoPoint, Orientation, Vector3
3030

@@ -98,7 +98,7 @@ async def get_readings(self, *, extra: Optional[Dict[str, Any]] = None, timeout:
9898
extra = {}
9999
request = GetReadingsRequest(name=self.name, extra=dict_to_struct(extra))
100100
response: GetReadingsResponse = await self.client.GetReadings(request, timeout=timeout)
101-
return sensor_readings_value_to_native(response.readings)
101+
return response.readings
102102

103103
async def do_command(self, command: Mapping[str, ValueTypes], *, timeout: Optional[float] = None) -> Mapping[str, ValueTypes]:
104104
request = DoCommandRequest(name=self.name, command=dict_to_struct(command))

src/viam/components/movement_sensor/movement_sensor.py

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
import abc
2-
import asyncio
32
from dataclasses import dataclass
4-
from typing import Any, Dict, Final, List, Mapping, Optional, Tuple
3+
from typing import Any, Dict, Final, Mapping, Optional, Tuple
54

6-
from grpclib import GRPCError
75
from typing_extensions import Self
86

9-
from viam.errors import MethodNotImplementedError, NotSupportedError
107
from viam.proto.component.movementsensor import GetPropertiesResponse
118
from viam.resource.types import RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT, Subtype
129

@@ -149,37 +146,4 @@ async def get_readings(self, *, extra: Optional[Dict[str, Any]] = None, timeout:
149146
}
150147
151148
"""
152-
(pos, lv, av, la, comp, orient) = await asyncio.gather(
153-
self.get_position(extra=extra, timeout=timeout),
154-
self.get_linear_velocity(extra=extra, timeout=timeout),
155-
self.get_angular_velocity(extra=extra, timeout=timeout),
156-
self.get_linear_acceleration(extra=extra, timeout=timeout),
157-
self.get_compass_heading(extra=extra, timeout=timeout),
158-
self.get_orientation(extra=extra, timeout=timeout),
159-
return_exceptions=True,
160-
)
161-
162-
readings = {}
163-
164-
# Add returned value to the readings dictionary if value is of expected type; omit if unimplemented.
165-
def add_reading(name: str, reading, returntype: List) -> None:
166-
possible_error_types = (NotImplementedError, MethodNotImplementedError, NotSupportedError)
167-
if type(reading) in returntype:
168-
if name == "position":
169-
readings["position"] = reading[0]
170-
readings["altitude"] = reading[1]
171-
else:
172-
readings[name] = reading
173-
return
174-
elif isinstance(reading, possible_error_types) or (isinstance(reading, GRPCError) and "Unimplemented" in str(reading.message)):
175-
return
176-
raise reading
177-
178-
add_reading("position", pos, [tuple])
179-
add_reading("linear_velocity", lv, [Vector3])
180-
add_reading("angular_velocity", av, [Vector3])
181-
add_reading("linear_acceleration", la, [Vector3])
182-
add_reading("compass", comp, [float, int])
183-
add_reading("orientation", orient, [Orientation])
184-
185-
return readings
149+
...

src/viam/components/movement_sensor/service.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
MovementSensorServiceBase,
3030
)
3131
from viam.resource.rpc_service_base import ResourceRPCServiceBase
32-
from viam.utils import dict_to_struct, struct_to_dict, sensor_readings_native_to_value
32+
from viam.utils import dict_to_struct, struct_to_dict
3333

3434

3535
class MovementSensorRPCService(MovementSensorServiceBase, ResourceRPCServiceBase):
@@ -143,5 +143,5 @@ async def GetReadings(self, stream: Stream[GetReadingsRequest, GetReadingsRespon
143143
sensor = self.get_resource(name)
144144
timeout = stream.deadline.time_remaining() if stream.deadline else None
145145
readings = await sensor.get_readings(extra=struct_to_dict(request.extra), timeout=timeout, metadata=stream.metadata)
146-
response = GetReadingsResponse(readings=sensor_readings_native_to_value(readings))
146+
response = GetReadingsResponse(readings=readings)
147147
await stream.send_message(response)

src/viam/components/power_sensor/client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
PowerSensorServiceStub,
1515
)
1616
from viam.resource.rpc_client_base import ReconfigurableResourceRPCClientBase
17-
from viam.utils import ValueTypes, dict_to_struct, struct_to_dict, sensor_readings_value_to_native
17+
from viam.utils import ValueTypes, dict_to_struct, struct_to_dict
1818

1919

2020
class PowerSensorClient(PowerSensor, ReconfigurableResourceRPCClientBase):
@@ -51,7 +51,7 @@ async def get_readings(self, *, extra: Optional[Dict[str, Any]] = None, timeout:
5151
extra = {}
5252
request = GetReadingsRequest(name=self.name, extra=dict_to_struct(extra))
5353
response: GetReadingsResponse = await self.client.GetReadings(request, timeout=timeout)
54-
return sensor_readings_value_to_native(response.readings)
54+
return response.readings
5555

5656
async def do_command(self, command: Mapping[str, ValueTypes], *, timeout: Optional[float] = None) -> Mapping[str, ValueTypes]:
5757
request = DoCommandRequest(name=self.name, command=dict_to_struct(command))

src/viam/components/power_sensor/power_sensor.py

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import abc
2-
import asyncio
3-
from typing import Any, Dict, Final, List, Mapping, Optional, Tuple
4-
5-
from grpclib import GRPCError
2+
from typing import Any, Dict, Final, Mapping, Optional, Tuple
63

74
from viam.components.component_base import ComponentBase
8-
from viam.errors import MethodNotImplementedError, NotSupportedError
95
from viam.resource.types import RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT, Subtype
106

117

@@ -59,34 +55,4 @@ async def get_readings(self, *, extra: Optional[Dict[str, Any]] = None, timeout:
5955
}
6056
6157
"""
62-
(vol, cur, pow) = await asyncio.gather(
63-
self.get_voltage(extra=extra, timeout=timeout),
64-
self.get_current(extra=extra, timeout=timeout),
65-
self.get_power(extra=extra, timeout=timeout),
66-
return_exceptions=True,
67-
)
68-
69-
readings = {}
70-
71-
# Add returned value to the readings dictionary if value is of expected type; omit if unimplemented.
72-
def add_reading(name: str, reading, returntype: List) -> None:
73-
possible_error_types = (NotImplementedError, MethodNotImplementedError, NotSupportedError)
74-
if type(reading) in returntype:
75-
if name == "voltage":
76-
readings["voltage"] = reading[0]
77-
readings["is_ac"] = reading[1]
78-
elif name == "current":
79-
readings["current"] = reading[0]
80-
readings["is_ac"] = reading[1]
81-
else:
82-
readings[name] = reading
83-
return
84-
elif isinstance(reading, possible_error_types) or (isinstance(reading, GRPCError) and "Unimplemented" in str(reading.message)):
85-
return
86-
raise reading
87-
88-
add_reading("voltage", vol, [tuple])
89-
add_reading("current", cur, [tuple])
90-
add_reading("power", pow, [float])
91-
92-
return readings
58+
...

src/viam/components/power_sensor/service.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
PowerSensorServiceBase,
1313
)
1414
from viam.resource.rpc_service_base import ResourceRPCServiceBase
15-
from viam.utils import dict_to_struct, struct_to_dict, sensor_readings_native_to_value
15+
from viam.utils import dict_to_struct, struct_to_dict
1616

1717

1818
class PowerSensorRPCService(PowerSensorServiceBase, ResourceRPCServiceBase):
@@ -29,7 +29,7 @@ async def GetReadings(self, stream: Stream[GetReadingsRequest, GetReadingsRespon
2929
sensor = self.get_resource(name)
3030
timeout = stream.deadline.time_remaining() if stream.deadline else None
3131
readings = await sensor.get_readings(extra=struct_to_dict(request.extra), timeout=timeout, metadata=stream.metadata)
32-
response = GetReadingsResponse(readings=sensor_readings_native_to_value(readings))
32+
response = GetReadingsResponse(readings=readings)
3333
await stream.send_message(response)
3434

3535
async def GetVoltage(self, stream: Stream[GetVoltageRequest, GetVoltageResponse]) -> None:

tests/mocks/components.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,12 +962,13 @@ async def do_command(self, command: Mapping[str, ValueTypes], *, timeout: Option
962962

963963

964964
class MockPowerSensor(PowerSensor):
965-
def __init__(self, name: str, voltage: float, current: float, is_ac: bool, power: float):
965+
def __init__(self, name: str, voltage: float, current: float, is_ac: bool, power: float, readings: Mapping[str, float]):
966966
super().__init__(name)
967967
self.voltage = voltage
968968
self.current = current
969969
self.is_ac = is_ac
970970
self.power = power
971+
self.readings = readings
971972
self.geometries = GEOMETRIES
972973
self.extra: Optional[Dict[str, Any]] = None
973974
self.timeout: Optional[float] = None

tests/test_movement_sensor.py

Lines changed: 16 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
from typing import Any, Dict, Optional
2-
31
import pytest
4-
from grpclib import GRPCError, Status
52
from grpclib.testing import ChannelFor
63

74
from viam.components.generic.service import GenericRPCService
@@ -37,7 +34,7 @@
3734
MovementSensorServiceStub,
3835
)
3936
from viam.resource.manager import ResourceManager
40-
from viam.utils import dict_to_struct, struct_to_dict, primitive_to_value
37+
from viam.utils import dict_to_struct, struct_to_dict
4138

4239
from . import loose_approx
4340
from .mocks.components import GEOMETRIES, MockMovementSensor
@@ -152,38 +149,9 @@ async def test_get_accuracy(self, movement_sensor: MockMovementSensor):
152149
@pytest.mark.asyncio
153150
async def test_get_readings(self, movement_sensor: MockMovementSensor):
154151
assert movement_sensor.extra is None
155-
readings = await movement_sensor.get_readings(extra=EXTRA_PARAMS, timeout=1.23)
152+
readings = await movement_sensor.get_readings(extra=EXTRA_PARAMS)
156153
assert readings == READINGS
157154
assert movement_sensor.extra == EXTRA_PARAMS
158-
assert movement_sensor.timeout == loose_approx(1.23)
159-
160-
# A mock method to replace some get functions just for testing that should result in omitted entries in the dictionary
161-
async def get_reading(*, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> Vector3:
162-
raise GRPCError(Status(2), "Unimplemented")
163-
164-
async def get_compass_heading(*, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> float:
165-
raise GRPCError(Status(2), "Unimplemented")
166-
167-
movement_sensor.get_linear_velocity = get_reading
168-
movement_sensor.get_linear_acceleration = get_reading
169-
movement_sensor.get_angular_velocity = get_reading
170-
movement_sensor.get_compass_heading = get_compass_heading
171-
172-
value = await movement_sensor.get_readings(extra=EXTRA_PARAMS)
173-
assert value == {
174-
"position": COORDINATE,
175-
"altitude": ALTITUDE,
176-
"orientation": ORIENTATION,
177-
}
178-
179-
# A mock method to replace some get functions just for testing that should result in a raised error
180-
async def get_orientation(*, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> Orientation:
181-
raise GRPCError(Status(2), "not implemented")
182-
183-
movement_sensor.get_orientation = get_orientation
184-
185-
with pytest.raises(GRPCError):
186-
await movement_sensor.get_readings(extra=EXTRA_PARAMS)
187155

188156
@pytest.mark.asyncio
189157
async def test_timeout(self, movement_sensor: MockMovementSensor):
@@ -316,6 +284,17 @@ async def test_get_accuracy(self, movement_sensor: MockMovementSensor, service:
316284
assert movement_sensor.extra == EXTRA_PARAMS
317285
assert movement_sensor.timeout == loose_approx(7.89)
318286

287+
@pytest.mark.asyncio
288+
async def test_get_readings(self, movement_sensor: MockMovementSensor, service: MovementSensorRPCService):
289+
async with ChannelFor([service]) as channel:
290+
client = MovementSensorServiceStub(channel)
291+
request = GetReadingsRequest(name=movement_sensor.name, extra=dict_to_struct(EXTRA_PARAMS))
292+
assert movement_sensor.extra is None
293+
response: GetReadingsResponse = await client.GetReadings(request, timeout=8.90)
294+
assert response.readings == pytest.approx(READINGS)
295+
assert movement_sensor.extra == EXTRA_PARAMS
296+
assert movement_sensor.timeout == loose_approx(8.90)
297+
319298
@pytest.mark.asyncio
320299
async def test_do(self, movement_sensor: MockMovementSensor, service: MovementSensorRPCService):
321300
async with ChannelFor([service]) as channel:
@@ -420,11 +399,10 @@ async def test_get_accuracy(self, movement_sensor: MockMovementSensor, service:
420399
@pytest.mark.asyncio
421400
async def test_get_readings(self, movement_sensor: MockMovementSensor, service: MovementSensorRPCService):
422401
async with ChannelFor([service]) as channel:
423-
client = MovementSensorServiceStub(channel)
424-
request = GetReadingsRequest(name=movement_sensor.name, extra=dict_to_struct(EXTRA_PARAMS))
402+
client = MovementSensorClient(movement_sensor.name, channel)
425403
assert movement_sensor.extra is None
426-
result: GetReadingsResponse = await client.GetReadings(request, timeout=2.34)
427-
assert result.readings == {key: primitive_to_value(value) for (key, value) in READINGS.items()}
404+
value = await client.get_readings(extra=EXTRA_PARAMS, timeout=2.34)
405+
assert value == pytest.approx(READINGS)
428406
assert movement_sensor.extra == EXTRA_PARAMS
429407
assert movement_sensor.timeout == loose_approx(2.34)
430408

tests/test_power_sensor.py

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
from typing import Any, Dict, Optional
2-
31
import pytest
4-
from grpclib import GRPCError, Status
52
from grpclib.testing import ChannelFor
63

74
from viam.components.generic.service import GenericRPCService
@@ -18,7 +15,7 @@
1815
)
1916

2017
from viam.resource.manager import ResourceManager
21-
from viam.utils import dict_to_struct, struct_to_dict, primitive_to_value
18+
from viam.utils import dict_to_struct, struct_to_dict
2219

2320
from . import loose_approx
2421
from .mocks.components import MockPowerSensor
@@ -33,7 +30,7 @@
3330

3431
@pytest.fixture(scope="function")
3532
def power_sensor() -> PowerSensor:
36-
return MockPowerSensor("power_sensor", VOLTS, AMPERES, IS_AC, WATTS)
33+
return MockPowerSensor("power_sensor", VOLTS, AMPERES, IS_AC, WATTS, READINGS)
3734

3835

3936
@pytest.fixture(scope="function")
@@ -73,18 +70,9 @@ async def test_get_power(self, power_sensor: MockPowerSensor):
7370
async def test_get_readings(self, power_sensor: MockPowerSensor):
7471
assert power_sensor.extra is None
7572
value = await power_sensor.get_readings(extra=EXTRA_PARAMS)
76-
assert value == {"voltage": VOLTS, "current": AMPERES, "is_ac": IS_AC, "power": WATTS, "readings": READINGS}
73+
assert value == READINGS
7774
assert power_sensor.extra == EXTRA_PARAMS
7875

79-
# A mock method to replace some get functions just for testing that should result in omitted entries in the dictionary
80-
async def get_reading(*, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> float:
81-
raise GRPCError(Status(2), "Unimplemented")
82-
83-
power_sensor.get_power = get_reading
84-
85-
value = await power_sensor.get_readings(extra=EXTRA_PARAMS)
86-
assert value == {"voltage": VOLTS, "current": AMPERES, "is_ac": IS_AC}
87-
8876
@pytest.mark.asyncio
8977
async def test_timeout(self, power_sensor: MockPowerSensor):
9078
assert power_sensor.timeout is None
@@ -144,6 +132,17 @@ async def test_get_power(self, power_sensor: MockPowerSensor, service: PowerSens
144132
assert power_sensor.extra == EXTRA_PARAMS
145133
assert power_sensor.timeout == loose_approx(1.23)
146134

135+
@pytest.mark.asyncio
136+
async def test_get_readings(self, power_sensor: MockPowerSensor, service: PowerSensorRPCService):
137+
async with ChannelFor([service]) as channel:
138+
client = PowerSensorServiceStub(channel)
139+
request = GetReadingsRequest(name=power_sensor.name, extra=dict_to_struct(EXTRA_PARAMS))
140+
assert power_sensor.extra is None
141+
response: GetReadingsResponse = await client.GetReadings(request, timeout=8.90)
142+
assert response.readings == pytest.approx(READINGS)
143+
assert power_sensor.extra == EXTRA_PARAMS
144+
assert power_sensor.timeout == loose_approx(8.90)
145+
147146
@pytest.mark.asyncio
148147
async def test_do(self, power_sensor: MockPowerSensor, service: PowerSensorRPCService):
149148
async with ChannelFor([service]) as channel:
@@ -191,11 +190,10 @@ async def test_get_power(self, power_sensor: MockPowerSensor, service: PowerSens
191190
@pytest.mark.asyncio
192191
async def test_get_readings(self, power_sensor: MockPowerSensor, service: PowerSensorRPCService):
193192
async with ChannelFor([service]) as channel:
194-
client = PowerSensorServiceStub(channel)
195-
request = GetReadingsRequest(name=power_sensor.name, extra=dict_to_struct(EXTRA_PARAMS))
193+
client = PowerSensorClient(power_sensor.name, channel)
196194
assert power_sensor.extra is None
197-
result: GetReadingsResponse = await client.GetReadings(request, timeout=2.34)
198-
assert result.readings == {key: primitive_to_value(value) for (key, value) in READINGS.items()}
195+
value = await client.get_readings(extra=EXTRA_PARAMS, timeout=2.34)
196+
assert value == pytest.approx(READINGS)
199197
assert power_sensor.extra == EXTRA_PARAMS
200198
assert power_sensor.timeout == loose_approx(2.34)
201199

0 commit comments

Comments
 (0)