Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove websocket V1 #551

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 3 additions & 75 deletions src/aioautomower/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,71 +401,6 @@
await self.get_status()
self.rest_task = asyncio.create_task(self._rest_task())

def add_settigs_tree(self, msg_dict: dict) -> dict:
"""Add settings key and ignore empty calendar tasks.

Needed, because when polling the API `headlight` and `cuttingHeight` are
nested under the `settings` key. But when receiving a websocket message,
the `settings` key is missing.
"""
copy_msg_dict = dict(msg_dict)
current_data = self._data
if current_data is None:
raise NoDataAvailableException
dater_iter = current_data["data"]
for _, current_data_mower in enumerate(dater_iter):
if current_data_mower["id"] == copy_msg_dict["id"]:
current_attributes = current_data_mower["attributes"]
formated_msg = {
"id": current_data_mower["id"],
"type": "settings-event",
"attributes": {
"calendar": {"tasks": current_attributes["calendar"]["tasks"]},
"settings": {
"cuttingHeight": current_attributes["settings"][
"cuttingHeight"
],
"headlight": {
"mode": current_attributes["settings"]["headlight"][
"mode"
]
},
},
},
}
new_attributes = copy_msg_dict["attributes"]
if len(new_attributes["calendar"]["tasks"]) > 0:
formated_msg["attributes"]["calendar"]["tasks"] = copy_msg_dict[
"attributes"
]["calendar"]["tasks"]
if "cuttingHeight" in new_attributes:
formated_msg["attributes"]["settings"]["cuttingHeight"] = (
copy_msg_dict["attributes"]["cuttingHeight"]
)
if "headlight" in new_attributes:
formated_msg["attributes"]["settings"]["headlight"]["mode"] = (
copy_msg_dict["attributes"]["headlight"]["mode"]
)
return formated_msg
return copy_msg_dict

def filter_work_area_id(self, msg_dict: dict) -> dict:
"""Filter empty work_area_id."""
if not self._data:
raise NoDataAvailableException
mower_id = msg_dict["id"]
new_attributes = msg_dict["attributes"]
for mower in self._data["data"]:
if (
mower["id"] == mower_id
and mower["attributes"]["capabilities"]["workAreas"]
):
new_attributes["mower"]["workAreaId"] = mower["attributes"]["mower"][
"workAreaId"
]
break
return msg_dict

def _handle_text_message(self, msg: WSMessage) -> None:
"""Process a text message to data."""
if not msg.data:
Expand All @@ -475,16 +410,9 @@
if msg.data:
msg_dict = msg.json()
if "type" in msg_dict:
if msg_dict["type"] in set(EVENT_TYPES) | {
event.value for event in EventTypesV2
}:
if msg_dict["type"] == "settings-event":
copy = dict(msg_dict)
msg_dict = self.add_settigs_tree(copy)
if msg_dict["type"] == "status-event":
copy = dict(msg_dict)
msg_dict = self.filter_work_area_id(copy)
_LOGGER.debug("Got %s, data: %s", msg_dict["type"], msg_dict)
if msg_dict["type"] in set(EVENT_TYPES):
_LOGGER.debug("Received websocket V1 type %s", msg_dict["type"])

Check warning on line 414 in src/aioautomower/session.py

View check run for this annotation

Codecov / codecov/patch

src/aioautomower/session.py#L414

Added line #L414 was not covered by tests
if msg_dict["type"] in {event.value for event in EventTypesV2}:
self._update_data(msg_dict)
else:
_LOGGER.warning("Received unknown ws type %s", msg_dict["type"])
Expand Down
8 changes: 4 additions & 4 deletions tests/fixtures/events/calendar_event.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
"calendar": {
"tasks": [
{
"start": 420,
"duration": 780,
"start": 720,
"duration": 300,
"monday": true,
"tuesday": true,
"wednesday": true,
"thursday": true,
"friday": true,
"saturday": false,
"sunday": false
"saturday": true,
"sunday": true
}
]
}
Expand Down
7 changes: 0 additions & 7 deletions tests/fixtures/positions_event.json

This file was deleted.

9 changes: 0 additions & 9 deletions tests/fixtures/settings_event.json

This file was deleted.

21 changes: 0 additions & 21 deletions tests/fixtures/settings_event_with_tasks.json

This file was deleted.

21 changes: 0 additions & 21 deletions tests/fixtures/status_event.json

This file was deleted.

21 changes: 0 additions & 21 deletions tests/fixtures/status_event_battery_50.json

This file was deleted.

21 changes: 0 additions & 21 deletions tests/fixtures/status_event_mower2.json

This file was deleted.

57 changes: 0 additions & 57 deletions tests/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from aioautomower.auth import AbstractAuth
from aioautomower.exceptions import (
FeatureNotSupportedException,
NoDataAvailableException,
WorkAreasDifferentException,
)
from aioautomower.model import (
Expand Down Expand Up @@ -319,62 +318,6 @@ async def test_patch_commands(mock_automower_client_two_mowers: AbstractAuth):
assert automower_api.rest_task.cancelled()


async def test_update_data(mock_automower_client: AbstractAuth):
"""Test automower session patch commands."""
automower_api = AutomowerSession(mock_automower_client, poll=True)
await automower_api.connect()

# Test empty tasks. doesn't delete the tasks
calendar = automower_api.data[MOWER_ID].calendar.tasks
msg = WSMessage(WSMsgType.TEXT, load_fixture("settings_event.json"), None)
automower_api._handle_text_message(msg) # noqa: SLF001
assert automower_api.data[MOWER_ID].calendar.tasks == calendar
assert (
automower_api.data[MOWER_ID].settings.headlight.mode
== HeadlightModes.EVENING_AND_NIGHT
)

# Test new tasks arrive
msg = WSMessage(
WSMsgType.TEXT, load_fixture("settings_event_with_tasks.json"), None
)
automower_api._handle_text_message(msg) # noqa: SLF001
assert automower_api.data[MOWER_ID].calendar.tasks == [
Calendar(
start=time(hour=12),
duration=timedelta(minutes=300),
monday=True,
tuesday=True,
wednesday=True,
thursday=True,
friday=True,
saturday=True,
sunday=True,
work_area_id=None,
)
]

# Test new positions arrive
msg = WSMessage(WSMsgType.TEXT, load_fixture("positions_event.json"), None)
automower_api._handle_text_message(msg) # noqa: SLF001
assert automower_api.data[MOWER_ID].positions[0].latitude == 1 # type: ignore[index]
assert automower_api.data[MOWER_ID].positions[0].longitude == 2 # type: ignore[index]

msg = WSMessage(WSMsgType.TEXT, load_fixture("status_event.json"), None)
automower_api._handle_text_message(msg) # noqa: SLF001
assert automower_api.data[MOWER_ID].mower.work_area_id == 123456

# Test NoDataAvailableException is risen, if there is no data
automower_api._data = None # noqa: SLF001
with pytest.raises(NoDataAvailableException):
automower_api._handle_text_message(msg) # noqa: SLF001

await automower_api.close()
if TYPE_CHECKING:
assert automower_api.rest_task is not None
assert automower_api.rest_task.cancelled()


async def test_battery_event(mock_automower_client: AbstractAuth):
"""Test automower websocket V2 battery update."""
automower_api = AutomowerSession(mock_automower_client, poll=True)
Expand Down
6 changes: 2 additions & 4 deletions tests/test_timeliney.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""Test automower session."""

import zoneinfo
from datetime import datetime
from typing import TYPE_CHECKING

import zoneinfo
from aiohttp import WSMessage, WSMsgType
from freezegun import freeze_time
from freezegun.api import FakeDatetime
Expand Down Expand Up @@ -94,9 +94,7 @@ async def test_daily_schedule(
)
await automower_api.connect()
# Test event of other mower doesn't overwrite the data
msg = WSMessage(
WSMsgType.TEXT, load_fixture("settings_event_with_tasks.json"), None
)
msg = WSMessage(WSMsgType.TEXT, load_fixture("events/calendar_event.json"), None)
automower_api._handle_text_message(msg) # noqa: SLF001

mower_timeline = automower_api.data["1234"].calendar.timeline
Expand Down
13 changes: 10 additions & 3 deletions tests/test_two_mower.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from aioautomower.auth import AbstractAuth
from aioautomower.session import AutomowerSession
from tests import load_fixture

MOWER1_ID = "c7233734-b219-4287-a173-08e3643f89f0"
MOWER2_ID = "1234"
Expand All @@ -19,11 +18,19 @@ async def test_two_mower(mock_automower_client_two_mowers: AbstractAuth) -> None
assert automower_api.data[MOWER1_ID].battery.battery_percent == 100
assert automower_api.data[MOWER2_ID].battery.battery_percent == 50
# Test event of other mower doesn't overwrite the data
msg2 = WSMessage(WSMsgType.TEXT, load_fixture("status_event_mower2.json"), None)
msg2 = WSMessage(
WSMsgType.TEXT,
b'{"id": "1234", "type": "battery-event-v2", "attributes": {"battery": {"batteryPercent": "99"}}}',
None,
)
automower_api._handle_text_message(msg2) # noqa: SLF001
assert automower_api.data[MOWER1_ID].battery.battery_percent == 100
assert automower_api.data[MOWER2_ID].battery.battery_percent == 99
msg1 = WSMessage(WSMsgType.TEXT, load_fixture("status_event_battery_50.json"), None)
msg1 = WSMessage(
WSMsgType.TEXT,
b'{"id": "c7233734-b219-4287-a173-08e3643f89f0", "type": "battery-event-v2", "attributes": {"battery": {"batteryPercent": "50"}}}',
None,
)
automower_api._handle_text_message(msg1) # noqa: SLF001
assert automower_api.data[MOWER1_ID].battery.battery_percent == 50
assert automower_api.data[MOWER2_ID].battery.battery_percent == 99
Expand Down
Loading