Skip to content
This repository has been archived by the owner on Feb 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #522 from Thomas55555/revert-514-split-up-session-…
Browse files Browse the repository at this point in the history
…and-rest

Revert "split up session and rest"
  • Loading branch information
Thomas55555 authored Jul 25, 2023
2 parents 9a4f5e2 + 95ab914 commit 4850b47
Show file tree
Hide file tree
Showing 20 changed files with 950 additions and 670 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,4 @@ deps/
custom_components/husqvarna_automower/tests/output/*.png
*.lock
coverage.xml
.gitmodules
core/
.gitmodules
45 changes: 13 additions & 32 deletions custom_components/husqvarna_automower/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import logging
import os
from asyncio.exceptions import TimeoutError as AsyncioTimeoutError
from datetime import timedelta

import aioautomower
from homeassistant.components.application_credentials import DATA_STORAGE
Expand Down Expand Up @@ -41,15 +40,14 @@ def __init__(self, hass: HomeAssistant, *, entry: ConfigEntry) -> None:
hass,
_LOGGER,
name=DOMAIN,
update_interval=timedelta(seconds=300),
)
self.api_key = None
api_key = None
ap_storage = hass.data.get("application_credentials")[DATA_STORAGE]
ap_storage_data = ap_storage.__dict__["data"]
for k in ap_storage_data:
self.api_key = ap_storage_data[k]["client_id"]
self.access_token = entry.data.get(CONF_TOKEN)
if not "amc:api" in self.access_token["scope"]:
api_key = ap_storage_data[k]["client_id"]
access_token = entry.data.get(CONF_TOKEN)
if not "amc:api" in access_token["scope"]:
async_create_issue(
hass,
DOMAIN,
Expand All @@ -59,9 +57,7 @@ def __init__(self, hass: HomeAssistant, *, entry: ConfigEntry) -> None:
translation_key="wrong_scope",
)
low_energy = False
self.session = aioautomower.AutomowerSession(
self.api_key, self.access_token, low_energy
)
self.session = aioautomower.AutomowerSession(api_key, access_token, low_energy)
self.session.register_token_callback(
lambda token: hass.config_entries.async_update_entry(
entry,
Expand All @@ -71,16 +67,15 @@ def __init__(self, hass: HomeAssistant, *, entry: ConfigEntry) -> None:

async def _async_update_data(self) -> None:
"""Fetch data from Husqvarna."""
provider = self.access_token["provider"]
token_type = self.access_token["token_type"]
access_token = self.access_token["access_token"]
rest = aioautomower.GetMowerData(
self.api_key, access_token, provider, token_type
)
try:
return await rest.async_mower_state()
except aioautomower.MowerApiConnectionsError as error:
_LOGGER.debug("Exception in updating Rest data: %s", error)
await self.session.connect()
except AsyncioTimeoutError as error:
_LOGGER.debug("Asyncio timeout: %s", error)
raise ConfigEntryNotReady from error
except Exception as error:
_LOGGER.debug("Exception in async_setup_entry: %s", error)
# If we haven't used the refresh_token (ie. been offline) for 10 days,
# we need to login using username and password in the config flow again.
raise ConfigEntryAuthFailed from Exception


Expand All @@ -93,20 +88,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass,
entry=entry,
)

try:
coordinator.async_set_updated_data(
await coordinator.session.ws_and_token_session()
)
except AsyncioTimeoutError as error:
_LOGGER.debug("Asyncio timeout: %s", error)
raise ConfigEntryNotReady from error
except Exception as error:
_LOGGER.debug("Exception in async_setup_entry: %s", error)
# If we haven't used the refresh_token (ie. been offline) for 10 days,
# we need to login using username and password in the config flow again.
raise ConfigEntryAuthFailed from Exception

await coordinator.async_config_entry_first_refresh()

hass.data.setdefault(DOMAIN, {})
Expand Down
4 changes: 2 additions & 2 deletions custom_components/husqvarna_automower/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import voluptuous as vol
from homeassistant import config_entries, data_entry_flow
from homeassistant.const import CONF_TOKEN
from homeassistant.core import async_get_hass, callback, HomeAssistant
from homeassistant.core import async_get_hass, callback
from homeassistant.helpers import config_entry_oauth2_flow
from homeassistant.helpers import selector
import homeassistant.helpers.config_validation as cv
Expand Down Expand Up @@ -122,7 +122,7 @@ def __init__(self, config_entry: config_entries.ConfigEntry) -> None:
super().__init__()
self.base_path = os.path.dirname(__file__)
self.config_entry = config_entry
self.hass: HomeAssistant # pylint throws no member errors if we don't hint

self.hass = async_get_hass()
self.mower_idx = []
for entity in self.hass.data[DOMAIN].keys():
Expand Down
5 changes: 1 addition & 4 deletions custom_components/husqvarna_automower/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,7 @@ async def async_added_to_hass(self) -> None:
"""Call when entity about to be added to Home Assistant."""
await super().async_added_to_hass()
self.coordinator.session.register_data_callback(
lambda _: self.coordinator.async_set_updated_data(
self.coordinator.session.data
),
schedule_immediately=True,
lambda _: self.async_write_ha_state(), schedule_immediately=True
)

async def async_will_remove_from_hass(self) -> None:
Expand Down
11 changes: 3 additions & 8 deletions custom_components/husqvarna_automower/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,13 @@
"integration_type": "hub",
"iot_class": "cloud_push",
"issue_tracker": "https://github.com/Thomas55555/husqvarna_automower/issues",
"loggers": [
"aioautomower",
"geopy",
"numpy",
"Pillow"
],
"loggers": ["aioautomower", "geopy", "numpy", "Pillow"],
"requirements": [
"aioautomower==2023.7.1",
"aioautomower==2023.4.5",
"geopy>=2.1.0",
"numpy>=1.21.6",
"Pillow>=9.1.1",
"Shapely>=1.8.2"
],
"version": "0.0.0"
}
}
37 changes: 2 additions & 35 deletions custom_components/husqvarna_automower/tests/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,46 +34,13 @@

# Single Mower Options
AUTOMER_SM_CONFIG = {
"configured_zones": '{"front_garden": {"zone_coordinates": [[35.5408367, -82.5524521],'
" [35.5403893, -82.552613], [35.5399462, -82.5506738], [35.5403827, -82.5505236],"
' [35.5408367, -82.5524521]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"],'
' "color": [255, 0, 0], "name": "Front Garden", "display": true}, "west_italian_garden":'
' {"zone_coordinates": [[35.5402452, -82.552951], [35.540075, -82.5530073],'
" [35.5399943, -82.5526425], [35.5401536, -82.5525835], [35.5402452, -82.552951]],"
' "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"], "color": [0, 255, 0],'
' "name": "West Italian Garden", "display": true}, "east_italian_garden":'
' {"zone_coordinates": [[35.5398415, -82.5512532], [35.5396822, -82.5513122],'
" [35.5395927, -82.550942], [35.5397498, -82.5508803], [35.5398415, -82.5512532]],"
' "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"], "color": [0, 0, 255],'
' "name": "East Italian Garden", "display": true}, "shrub_garden": {"zone_coordinates":'
" [[35.5397978, -82.5531334], [35.539357, -82.553289], [35.5393198, -82.553128],"
" [35.5394028, -82.5530529], [35.5394443, -82.5529751], [35.5394639, -82.5528866],"
" [35.5394901, -82.5528303], [35.539645, -82.5529242], [35.5397629, -82.5529698],"
' [35.5397978, -82.5531334]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"],'
' "color": [100, 100, 0], "name": "Shrub Garden", "display": true}}',
"configured_zones": '{"front_garden": {"zone_coordinates": [[35.5408367, -82.5524521], [35.5403893, -82.552613], [35.5399462, -82.5506738], [35.5403827, -82.5505236], [35.5408367, -82.5524521]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"], "color": [255, 0, 0], "name": "Front Garden", "display": true}, "west_italian_garden": {"zone_coordinates": [[35.5402452, -82.552951], [35.540075, -82.5530073], [35.5399943, -82.5526425], [35.5401536, -82.5525835], [35.5402452, -82.552951]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"], "color": [0, 255, 0], "name": "West Italian Garden", "display": true}, "east_italian_garden": {"zone_coordinates": [[35.5398415, -82.5512532], [35.5396822, -82.5513122], [35.5395927, -82.550942], [35.5397498, -82.5508803], [35.5398415, -82.5512532]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"], "color": [0, 0, 255], "name": "East Italian Garden", "display": true}, "shrub_garden": {"zone_coordinates": [[35.5397978, -82.5531334], [35.539357, -82.553289], [35.5393198, -82.553128], [35.5394028, -82.5530529], [35.5394443, -82.5529751], [35.5394639, -82.5528866], [35.5394901, -82.5528303], [35.539645, -82.5529242], [35.5397629, -82.5529698], [35.5397978, -82.5531334]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"], "color": [100, 100, 0], "name": "Shrub Garden", "display": true}}',
MWR_ONE_ID: MWR_ONE_CONFIG,
}

# Dual Mower Options
AUTOMER_DM_CONFIG = {
"configured_zones": '{"front_garden": {"zone_coordinates": [[35.5408367, -82.5524521],'
" [35.5403893, -82.552613], [35.5399462, -82.5506738], [35.5403827, -82.5505236], "
'[35.5408367, -82.5524521]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0",'
' "1c7aec7b-06ff-462e-b307-7c6ae4469047"], "color": [255, 0, 0], "name": "Front Garden",'
' "display": true}, "west_italian_garden": {"zone_coordinates": [[35.5402452, -82.552951],'
" [35.540075, -82.5530073], [35.5399943, -82.5526425], [35.5401536, -82.5525835], "
'[35.5402452, -82.552951]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"], '
'"color": [0, 255, 0], "name": "West Italian Garden", "display": true}, '
'"east_italian_garden": {"zone_coordinates": [[35.5398415, -82.5512532], '
"[35.5396822, -82.5513122], [35.5395927, -82.550942], [35.5397498, -82.5508803],"
' [35.5398415, -82.5512532]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"],'
' "color": [0, 0, 255], "name": "East Italian Garden", "display": true}, "shrub_garden":'
' {"zone_coordinates": [[35.5397978, -82.5531334], [35.539357, -82.553289],'
" [35.5393198, -82.553128], [35.5394028, -82.5530529], [35.5394443, -82.5529751],"
" [35.5394639, -82.5528866], [35.5394901, -82.5528303], [35.539645, -82.5529242],"
' [35.5397629, -82.5529698], [35.5397978, -82.5531334]], "sel_mowers": '
'["c7233734-b219-4287-a173-08e3643f89f0"], "color": [100, 100, 0], "name":'
' "Shrub Garden", "display": true}}',
"configured_zones": '{"front_garden": {"zone_coordinates": [[35.5408367, -82.5524521], [35.5403893, -82.552613], [35.5399462, -82.5506738], [35.5403827, -82.5505236], [35.5408367, -82.5524521]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0", "1c7aec7b-06ff-462e-b307-7c6ae4469047"], "color": [255, 0, 0], "name": "Front Garden", "display": true}, "west_italian_garden": {"zone_coordinates": [[35.5402452, -82.552951], [35.540075, -82.5530073], [35.5399943, -82.5526425], [35.5401536, -82.5525835], [35.5402452, -82.552951]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"], "color": [0, 255, 0], "name": "West Italian Garden", "display": true}, "east_italian_garden": {"zone_coordinates": [[35.5398415, -82.5512532], [35.5396822, -82.5513122], [35.5395927, -82.550942], [35.5397498, -82.5508803], [35.5398415, -82.5512532]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"], "color": [0, 0, 255], "name": "East Italian Garden", "display": true}, "shrub_garden": {"zone_coordinates": [[35.5397978, -82.5531334], [35.539357, -82.553289], [35.5393198, -82.553128], [35.5394028, -82.5530529], [35.5394443, -82.5529751], [35.5394639, -82.5528866], [35.5394901, -82.5528303], [35.539645, -82.5529242], [35.5397629, -82.5529698], [35.5397978, -82.5531334]], "sel_mowers": ["c7233734-b219-4287-a173-08e3643f89f0"], "color": [100, 100, 0], "name": "Shrub Garden", "display": true}}',
MWR_ONE_ID: MWR_ONE_CONFIG,
MWR_TWO_ID: MWR_TWO_CONFIG,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,63 @@
"""Tests for application credentials module."""
from unittest.mock import MagicMock, patch
from copy import deepcopy
from unittest.mock import AsyncMock, MagicMock, patch

import pytest
from aioautomower import AutomowerSession
from homeassistant.components.application_credentials import AuthorizationServer
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from pytest_homeassistant_custom_component.common import MockConfigEntry

from ..application_credentials import (
async_get_authorization_server,
async_get_description_placeholders,
)
from ..const import HUSQVARNA_URL
from ..const import DOMAIN, HUSQVARNA_URL
from .const import AUTOMER_DM_CONFIG, AUTOMOWER_CONFIG_DATA, AUTOMOWER_SM_SESSION_DATA

from .test_common import setup_entity

@pytest.mark.asyncio
async def setup_entity(hass: HomeAssistant):
"""Set up entity and config entry"""

options = deepcopy(AUTOMER_DM_CONFIG)

config_entry = MockConfigEntry(
domain=DOMAIN,
data=AUTOMOWER_CONFIG_DATA,
options=options,
entry_id="automower_test",
title="Automower Test",
)

config_entry.add_to_hass(hass)

session = deepcopy(AUTOMOWER_SM_SESSION_DATA)

with patch(
"aioautomower.AutomowerSession",
return_value=AsyncMock(
name="AutomowerMockSession",
model=AutomowerSession,
data=session,
register_data_callback=MagicMock(),
unregister_data_callback=MagicMock(),
register_token_callback=MagicMock(),
connect=AsyncMock(),
action=AsyncMock(),
),
) as automower_session_mock:
automower_coordinator_mock = MagicMock(
name="MockCoordinator", session=automower_session_mock()
)

await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert config_entry.state == ConfigEntryState.LOADED
assert len(hass.config_entries.async_entries(DOMAIN)) == 1

return config_entry


@pytest.mark.asyncio
Expand Down
Loading

0 comments on commit 4850b47

Please sign in to comment.