Skip to content

Commit 2b18d80

Browse files
nanomadedenhaus
andauthored
Do not assume every PositionsEvent has a PositionType.DEEBOT inside (#955)
Co-authored-by: Robert Resch <robert@resch.dev>
1 parent e9c66b6 commit 2b18d80

2 files changed

Lines changed: 100 additions & 13 deletions

File tree

deebot_client/device.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,20 @@ async def on_pos(event: PositionsEvent) -> None:
7777
if self._state == StateEvent(State.DOCKED):
7878
return
7979

80-
deebot = next(p for p in event.positions if p.type == PositionType.DEEBOT)
81-
82-
if deebot:
83-
on_charger = filter(
84-
lambda p: p.type == PositionType.CHARGER
85-
and p.x == deebot.x
86-
and p.y == deebot.y,
87-
event.positions,
88-
)
89-
if on_charger:
90-
# deebot on charger so the status should be docked... Checking
91-
self.events.request_refresh(StateEvent)
80+
deebot = next(
81+
(p for p in event.positions if p.type == PositionType.DEEBOT), None
82+
)
83+
84+
if deebot and any(
85+
p
86+
for p in event.positions
87+
if p.type == PositionType.CHARGER
88+
and p.x == deebot.x
89+
and p.y == deebot.y
90+
):
91+
# Deebot is on charger and the status is not docked
92+
# Request refresh for the state
93+
self.events.request_refresh(StateEvent)
9294

9395
self.events.subscribe(PositionsEvent, on_pos)
9496

tests/test_device.py

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,21 @@
1313
from deebot_client.commands.xml import GetBatteryInfo
1414
from deebot_client.const import DataType
1515
from deebot_client.device import Device
16-
from deebot_client.events import AvailabilityEvent
16+
from deebot_client.events import AvailabilityEvent, StateEvent
17+
from deebot_client.events.map import Position, PositionsEvent
1718
from deebot_client.events.network import NetworkInfoEvent
1819
from deebot_client.hardware import get_static_device_info
1920
from deebot_client.messages.json import OnBattery
2021
from deebot_client.messages.xml import BatteryInfo
2122
from deebot_client.models import DeviceInfo, StaticDeviceInfo
2223
from deebot_client.mqtt_client import MqttClient, SubscriberInfo
24+
from deebot_client.rs.map import PositionType
2325
from tests.helpers import mock_static_device_info
2426
from tests.helpers.tasks import block_till_done
2527

2628
if TYPE_CHECKING:
2729
from deebot_client.authentication import Authenticator
30+
from deebot_client.event_bus import EventBus
2831
from deebot_client.message import Message
2932
from deebot_client.models import ApiDeviceInfo
3033

@@ -277,3 +280,85 @@ async def on_status(event: AvailabilityEvent) -> None:
277280

278281
# teardown bot
279282
await bot.teardown()
283+
284+
285+
@pytest.mark.parametrize(
286+
("pos_event", "expected_call"),
287+
[
288+
(PositionsEvent([]), False),
289+
(PositionsEvent([Position(PositionType.CHARGER, 0, 0, 0)]), False),
290+
(PositionsEvent([Position(PositionType.DEEBOT, 0, 0, 0)]), False),
291+
(
292+
PositionsEvent(
293+
[
294+
Position(PositionType.DEEBOT, 0, 0, 0),
295+
Position(PositionType.CHARGER, 0, 0, 0),
296+
]
297+
),
298+
True,
299+
),
300+
(
301+
PositionsEvent(
302+
[
303+
Position(PositionType.CHARGER, 0, 0, 0),
304+
Position(PositionType.DEEBOT, 0, 0, 0),
305+
]
306+
),
307+
True,
308+
),
309+
(
310+
PositionsEvent(
311+
[
312+
Position(PositionType.CHARGER, 1, 0, 0),
313+
Position(PositionType.DEEBOT, 0, 0, 0),
314+
]
315+
),
316+
False,
317+
),
318+
(
319+
PositionsEvent(
320+
[
321+
Position(PositionType.DEEBOT, 0, 0, 0),
322+
Position(PositionType.CHARGER, 1, 0, 0),
323+
]
324+
),
325+
False,
326+
),
327+
(
328+
PositionsEvent(
329+
[
330+
Position(PositionType.DEEBOT, 0, 0, 0),
331+
Position(PositionType.CHARGER, 1, 0, 0),
332+
Position(PositionType.CHARGER, 0, 0, 0),
333+
]
334+
),
335+
True,
336+
),
337+
],
338+
)
339+
async def test_onPos_device_handling(
340+
authenticator: Authenticator,
341+
device_info: DeviceInfo,
342+
event_bus_mock: Mock,
343+
event_bus: EventBus,
344+
pos_event: PositionsEvent,
345+
expected_call: bool,
346+
) -> None:
347+
"""Test the available check including if the status Event is fired correctly."""
348+
with patch("deebot_client.device.EventBus", return_value=event_bus_mock):
349+
bot = Device(device_info, authenticator)
350+
mqtt_client = Mock(spec=MqttClient)
351+
unsubscribe_mock = Mock(spec=Callable[[], None])
352+
mqtt_client.subscribe.return_value = unsubscribe_mock
353+
await bot.initialize(mqtt_client)
354+
355+
bot.events.notify(pos_event)
356+
await block_till_done(event_bus._tasks)
357+
358+
if expected_call:
359+
event_bus_mock.request_refresh.assert_called_once_with(StateEvent)
360+
else:
361+
event_bus_mock.request_refresh.assert_not_called()
362+
363+
# teardown bot
364+
await bot.teardown()

0 commit comments

Comments
 (0)