Skip to content

Commit

Permalink
refactor battery messages (#70)
Browse files Browse the repository at this point in the history
* add onBattery

* add battery tests

* decrease target to 80%
  • Loading branch information
edenhaus authored Jan 28, 2022
1 parent 5c76973 commit 44b9fb6
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ coverage:
status:
patch:
default:
target: 100%
target: 80%
20 changes: 3 additions & 17 deletions deebot_client/commands/battery.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,9 @@
"""Battery commands."""
from typing import Any
from ..messages import OnBattery
from .common import _NoArgsCommand

from ..events import BatteryEvent
from ..message import HandlingResult
from .common import EventBus, _NoArgsCommand


class GetBattery(_NoArgsCommand):
class GetBattery(OnBattery, _NoArgsCommand):
"""Get battery command."""

name = "getBattery"

@classmethod
def _handle_body_data_dict(
cls, event_bus: EventBus, data: dict[str, Any]
) -> HandlingResult:
"""Handle message->body->data and notify the correct event subscribers.
:return: A message response
"""
event_bus.notify(BatteryEvent(data["value"]))
return HandlingResult.success()
14 changes: 4 additions & 10 deletions deebot_client/messages/__init__.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
"""Messages module."""


from typing import Dict, Type

from ..commands import COMMANDS_WITH_HANDLING
from ..message import Message
from ..messages.stats import ReportStats
from .battery import OnBattery

# fmt: off
# ordered by file asc
_MESSAGES: list[type[Message]] = [
OnBattery,

ReportStats
]
# fmt: on

MESSAGES: dict[str, type[Message]] = {
message.name: message
for message in (
_MESSAGES
+ [cmd for cmd in COMMANDS_WITH_HANDLING.values() if issubclass(cmd, Message)]
)
}
MESSAGES: dict[str, type[Message]] = {message.name: message for message in _MESSAGES}
23 changes: 23 additions & 0 deletions deebot_client/messages/battery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Battery messages."""
from typing import Any

from ..events import BatteryEvent
from ..events.event_bus import EventBus
from ..message import HandlingResult, Message


class OnBattery(Message):
"""On battery message."""

name = "onBattery"

@classmethod
def _handle_body_data_dict(
cls, event_bus: EventBus, data: dict[str, Any]
) -> HandlingResult:
"""Handle message->body->data and notify the correct event subscribers.
:return: A message response
"""
event_bus.notify(BatteryEvent(data["value"]))
return HandlingResult.success()
12 changes: 5 additions & 7 deletions deebot_client/vacuum_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
import re
from typing import Any, Final, Optional, Union

import aiohttp

from .api_client import ApiClient
from .command import Command
from .commands import Clean, CommandWithHandling
from .commands import COMMANDS_WITH_HANDLING, Clean, CommandWithHandling
from .commands.clean import CleanAction
from .commands.custom import CustomCommand
from .events import (
Expand Down Expand Up @@ -38,11 +36,9 @@ class VacuumBot:

def __init__(
self,
session: aiohttp.ClientSession,
device_info: DeviceInfo,
api_client: ApiClient,
):
self._session = session
self.device_info: Final[DeviceInfo] = device_info
self._api_client = api_client

Expand Down Expand Up @@ -154,7 +150,7 @@ async def handle_message(
message_type.handle(self.events, message_data)
return

_LOGGER.debug("Falling back to old handling way...")
_LOGGER.debug("Falling back to old handling way for %s", message_name)
# Handle message starting with "on","off","report" the same as "get" commands
message_name = re.sub(
_COMMAND_REPLACE_PATTERN,
Expand All @@ -166,7 +162,9 @@ async def handle_message(
if message_name.endswith("_V2"):
message_name = message_name[:-3]

found_command = MESSAGES.get(message_name, None)
found_command = MESSAGES.get(
message_name, COMMANDS_WITH_HANDLING.get(message_name, None)
)
if found_command:
found_command.handle(self.events, message_data)
else:
Expand Down
18 changes: 18 additions & 0 deletions tests/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from typing import Any
from unittest.mock import Mock

from deebot_client.commands import CommandWithHandling
from deebot_client.events import Event
from deebot_client.events.event_bus import EventBus
from deebot_client.message import HandlingState


def assert_command_requested(
command: CommandWithHandling, data: dict[str, Any], expected_event: Event
):
event_bus = Mock(spec_set=EventBus)

result = command.handle_requested(event_bus, data)

assert result.state == HandlingState.SUCCESS
event_bus.notify.assert_called_once_with(expected_event)
29 changes: 29 additions & 0 deletions tests/commands/test_battery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import pytest

from deebot_client.commands import GetBattery
from deebot_client.events import BatteryEvent
from tests.commands import assert_command_requested


@pytest.mark.parametrize("percentage", [0, 49, 100])
def test_get_battery_requested(percentage: int):
data = {
"id": "ALZf",
"ret": "ok",
"resp": {
"header": {
"pri": 1,
"tzm": 480,
"ts": "1304623069888",
"ver": "0.0.1",
"fwVer": "1.8.2",
"hwVer": "0.1.1",
},
"body": {
"code": 0,
"msg": "ok",
"data": {"value": percentage, "isLow": 1 if percentage < 20 else 0},
},
},
}
assert_command_requested(GetBattery(), data, BatteryEvent(percentage))
15 changes: 15 additions & 0 deletions tests/messages/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from typing import Any
from unittest.mock import Mock

from deebot_client.events import Event
from deebot_client.events.event_bus import EventBus
from deebot_client.message import HandlingState, Message


def assert_message(message: type[Message], data: dict[str, Any], expected_event: Event):
event_bus = Mock(spec_set=EventBus)

result = message.handle(event_bus, data)

assert result.state == HandlingState.SUCCESS
event_bus.notify.assert_called_once_with(expected_event)
22 changes: 22 additions & 0 deletions tests/messages/test_battery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import pytest

from deebot_client.events import BatteryEvent
from deebot_client.messages import OnBattery
from tests.messages import assert_message


@pytest.mark.parametrize("percentage", [0, 49, 100])
def test_getBattery(percentage: int):
data = {
"header": {
"pri": 1,
"tzm": 480,
"ts": "1304637391896",
"ver": "0.0.1",
"fwVer": "1.8.2",
"hwVer": "0.1.1",
},
"body": {"data": {"value": percentage, "isLow": 1 if percentage < 20 else 0}},
}

assert_message(OnBattery, data, BatteryEvent(percentage))

0 comments on commit 44b9fb6

Please sign in to comment.