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

Replace abodepy library with jaraco.abode to enable new Abode devices #85474

Merged
merged 3 commits into from Jan 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 21 additions & 18 deletions homeassistant/components/abode/__init__.py
Expand Up @@ -3,10 +3,14 @@

from functools import partial

from abodepy import Abode, AbodeAutomation as AbodeAuto
from abodepy.devices import AbodeDevice as AbodeDev
from abodepy.exceptions import AbodeAuthenticationException, AbodeException
import abodepy.helpers.timeline as TIMELINE
from jaraco.abode.automation import Automation as AbodeAuto
from jaraco.abode.client import Client as Abode
from jaraco.abode.devices.base import Device as AbodeDev
from jaraco.abode.exceptions import (
AuthenticationException as AbodeAuthenticationException,
Exception as AbodeException,
)
from jaraco.abode.helpers.timeline import Groups as GROUPS
from requests.exceptions import ConnectTimeout, HTTPError
import voluptuous as vol

Expand All @@ -26,7 +30,7 @@
from homeassistant.helpers import config_validation as cv, entity
from homeassistant.helpers.dispatcher import dispatcher_send

from .const import ATTRIBUTION, CONF_POLLING, DEFAULT_CACHEDB, DOMAIN, LOGGER
from .const import ATTRIBUTION, CONF_POLLING, DOMAIN, LOGGER

SERVICE_SETTINGS = "change_setting"
SERVICE_CAPTURE_IMAGE = "capture_image"
Expand Down Expand Up @@ -82,7 +86,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
username = entry.data[CONF_USERNAME]
password = entry.data[CONF_PASSWORD]
polling = entry.data[CONF_POLLING]
cache = hass.config.path(DEFAULT_CACHEDB)

# For previous config entries where unique_id is None
if entry.unique_id is None:
Expand All @@ -92,7 +95,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:

try:
abode = await hass.async_add_executor_job(
Abode, username, password, True, True, True, cache
Abode, username, password, True, True, True
)

except AbodeAuthenticationException as ex:
Expand Down Expand Up @@ -225,17 +228,17 @@ def event_callback(event: str, event_json: dict[str, str]) -> None:
hass.bus.fire(event, data)

events = [
TIMELINE.ALARM_GROUP,
TIMELINE.ALARM_END_GROUP,
TIMELINE.PANEL_FAULT_GROUP,
TIMELINE.PANEL_RESTORE_GROUP,
TIMELINE.AUTOMATION_GROUP,
TIMELINE.DISARM_GROUP,
TIMELINE.ARM_GROUP,
TIMELINE.ARM_FAULT_GROUP,
TIMELINE.TEST_GROUP,
TIMELINE.CAPTURE_GROUP,
TIMELINE.DEVICE_GROUP,
GROUPS.ALARM,
GROUPS.ALARM_END,
GROUPS.PANEL_FAULT,
GROUPS.PANEL_RESTORE,
GROUPS.AUTOMATION,
GROUPS.DISARM,
GROUPS.ARM,
GROUPS.ARM_FAULT,
GROUPS.TEST,
GROUPS.CAPTURE,
GROUPS.DEVICE,
]

for event in events:
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/abode/alarm_control_panel.py
@@ -1,7 +1,7 @@
"""Support for Abode Security System alarm control panels."""
from __future__ import annotations

from abodepy.devices.alarm import AbodeAlarm as AbodeAl
from jaraco.abode.devices.alarm import Alarm as AbodeAl

import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarm_control_panel import AlarmControlPanelEntityFeature
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/abode/binary_sensor.py
Expand Up @@ -4,8 +4,8 @@
from contextlib import suppress
from typing import cast

from abodepy.devices.binary_sensor import AbodeBinarySensor as ABBinarySensor
import abodepy.helpers.constants as CONST
from jaraco.abode.devices.sensor import BinarySensor as ABBinarySensor
from jaraco.abode.helpers import constants as CONST

from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
Expand Down
8 changes: 4 additions & 4 deletions homeassistant/components/abode/camera.py
Expand Up @@ -4,9 +4,9 @@
from datetime import timedelta
from typing import Any, cast

from abodepy.devices import CONST, AbodeDevice as AbodeDev
from abodepy.devices.camera import AbodeCamera as AbodeCam
import abodepy.helpers.timeline as TIMELINE
from jaraco.abode.devices.base import Device as AbodeDev
from jaraco.abode.devices.camera import Camera as AbodeCam
from jaraco.abode.helpers import constants as CONST, timeline as TIMELINE
import requests
from requests.models import Response

Expand All @@ -30,7 +30,7 @@ async def async_setup_entry(
data: AbodeSystem = hass.data[DOMAIN]

async_add_entities(
AbodeCamera(data, device, TIMELINE.CAPTURE_IMAGE)
AbodeCamera(data, device, TIMELINE.CAPTURE_IMAGE) # pylint: disable=no-member
tradel marked this conversation as resolved.
Show resolved Hide resolved
for device in data.abode.get_devices(generic_type=CONST.TYPE_CAMERA)
)

Expand Down
22 changes: 9 additions & 13 deletions homeassistant/components/abode/config_flow.py
Expand Up @@ -5,17 +5,20 @@
from http import HTTPStatus
from typing import Any, cast

from abodepy import Abode
from abodepy.exceptions import AbodeAuthenticationException, AbodeException
from abodepy.helpers.errors import MFA_CODE_REQUIRED
from jaraco.abode.client import Client as Abode
from jaraco.abode.exceptions import (
AuthenticationException as AbodeAuthenticationException,
Exception as AbodeException,
)
from jaraco.abode.helpers.errors import MFA_CODE_REQUIRED
from requests.exceptions import ConnectTimeout, HTTPError
import voluptuous as vol

from homeassistant import config_entries
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.data_entry_flow import FlowResult

from .const import CONF_POLLING, DEFAULT_CACHEDB, DOMAIN, LOGGER
from .const import CONF_POLLING, DOMAIN, LOGGER

CONF_MFA = "mfa_code"

Expand All @@ -35,20 +38,18 @@ def __init__(self) -> None:
vol.Required(CONF_MFA): str,
}

self._cache: str | None = None
self._mfa_code: str | None = None
self._password: str | None = None
self._polling: bool = False
self._username: str | None = None

async def _async_abode_login(self, step_id: str) -> FlowResult:
"""Handle login with Abode."""
self._cache = self.hass.config.path(DEFAULT_CACHEDB)
errors = {}

try:
await self.hass.async_add_executor_job(
Abode, self._username, self._password, True, False, False, self._cache
Abode, self._username, self._password, True, False, False
)

except AbodeException as ex:
Expand Down Expand Up @@ -77,12 +78,7 @@ async def _async_abode_mfa_login(self) -> FlowResult:
"""Handle multi-factor authentication (MFA) login with Abode."""
try:
# Create instance to access login method for passing MFA code
abode = Abode(
auto_login=False,
get_devices=False,
get_automations=False,
cache_path=self._cache,
)
abode = Abode(auto_login=False, get_devices=False, get_automations=False)
await self.hass.async_add_executor_job(
abode.login, self._username, self._password, self._mfa_code
)
Expand Down
1 change: 0 additions & 1 deletion homeassistant/components/abode/const.py
Expand Up @@ -6,5 +6,4 @@
DOMAIN = "abode"
ATTRIBUTION = "Data provided by goabode.com"

DEFAULT_CACHEDB = "abodepy_cache.pickle"
tradel marked this conversation as resolved.
Show resolved Hide resolved
CONF_POLLING = "polling"
4 changes: 2 additions & 2 deletions homeassistant/components/abode/cover.py
@@ -1,8 +1,8 @@
"""Support for Abode Security System covers."""
from typing import Any

from abodepy.devices.cover import AbodeCover as AbodeCV
import abodepy.helpers.constants as CONST
from jaraco.abode.devices.cover import Cover as AbodeCV
from jaraco.abode.helpers import constants as CONST

from homeassistant.components.cover import CoverEntity
from homeassistant.config_entries import ConfigEntry
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/abode/light.py
Expand Up @@ -4,8 +4,8 @@
from math import ceil
from typing import Any

from abodepy.devices.light import AbodeLight as AbodeLT
import abodepy.helpers.constants as CONST
from jaraco.abode.devices.light import Light as AbodeLT
from jaraco.abode.helpers import constants as CONST

from homeassistant.components.light import (
ATTR_BRIGHTNESS,
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/abode/lock.py
@@ -1,8 +1,8 @@
"""Support for the Abode Security System locks."""
from typing import Any

from abodepy.devices.lock import AbodeLock as AbodeLK
import abodepy.helpers.constants as CONST
from jaraco.abode.devices.lock import Lock as AbodeLK
from jaraco.abode.helpers import constants as CONST

from homeassistant.components.lock import LockEntity
from homeassistant.config_entries import ConfigEntry
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/abode/manifest.json
Expand Up @@ -3,11 +3,11 @@
"name": "Abode",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/abode",
"requirements": ["abodepy==1.2.0"],
"requirements": ["jaraco.abode==3.2.1"],
"codeowners": ["@shred86"],
"homekit": {
"models": ["Abode", "Iota"]
},
"iot_class": "cloud_push",
"loggers": ["abodepy", "lomond"]
"loggers": ["jaraco.abode", "lomond"]
}
3 changes: 2 additions & 1 deletion homeassistant/components/abode/sensor.py
Expand Up @@ -3,7 +3,8 @@

from typing import cast

from abodepy.devices.sensor import CONST, AbodeSensor as AbodeSense
from jaraco.abode.devices.sensor import Sensor as AbodeSense
from jaraco.abode.helpers import constants as CONST

from homeassistant.components.sensor import (
SensorDeviceClass,
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/abode/switch.py
Expand Up @@ -3,7 +3,8 @@

from typing import Any, cast

from abodepy.devices.switch import CONST, AbodeSwitch as AbodeSW
from jaraco.abode.devices.switch import Switch as AbodeSW
from jaraco.abode.helpers import constants as CONST

from homeassistant.components.switch import SwitchEntity
from homeassistant.config_entries import ConfigEntry
Expand Down
6 changes: 3 additions & 3 deletions requirements_all.txt
Expand Up @@ -70,9 +70,6 @@ WSDiscovery==2.0.0
# homeassistant.components.waze_travel_time
WazeRouteCalculator==0.14

# homeassistant.components.abode
abodepy==1.2.0

# homeassistant.components.accuweather
accuweather==0.5.0

Expand Down Expand Up @@ -990,6 +987,9 @@ ismartgate==4.0.4
# homeassistant.components.file_upload
janus==1.0.0

# homeassistant.components.abode
jaraco.abode==3.2.1

# homeassistant.components.jellyfin
jellyfin-apiclient-python==1.9.2

Expand Down
6 changes: 3 additions & 3 deletions requirements_test_all.txt
Expand Up @@ -60,9 +60,6 @@ WSDiscovery==2.0.0
# homeassistant.components.waze_travel_time
WazeRouteCalculator==0.14

# homeassistant.components.abode
abodepy==1.2.0

# homeassistant.components.accuweather
accuweather==0.5.0

Expand Down Expand Up @@ -743,6 +740,9 @@ ismartgate==4.0.4
# homeassistant.components.file_upload
janus==1.0.0

# homeassistant.components.abode
jaraco.abode==3.2.1

# homeassistant.components.jellyfin
jellyfin-apiclient-python==1.9.2

Expand Down
4 changes: 2 additions & 2 deletions tests/components/abode/common.py
Expand Up @@ -23,8 +23,8 @@ async def setup_platform(hass: HomeAssistant, platform: str) -> MockConfigEntry:
mock_entry.add_to_hass(hass)

with patch("homeassistant.components.abode.PLATFORMS", [platform]), patch(
"abodepy.event_controller.sio"
), patch("abodepy.utils.save_cache"):
"jaraco.abode.event_controller.sio"
):
assert await async_setup_component(hass, ABODE_DOMAIN, {})
await hass.async_block_till_done()

Expand Down
18 changes: 7 additions & 11 deletions tests/components/abode/conftest.py
@@ -1,5 +1,5 @@
"""Configuration for Abode tests."""
import abodepy.helpers.constants as CONST
from jaraco.abode.helpers import urls as URL
import pytest

from tests.common import load_fixture
Expand All @@ -10,18 +10,14 @@
def requests_mock_fixture(requests_mock) -> None:
"""Fixture to provide a requests mocker."""
# Mocks the login response for abodepy.
requests_mock.post(CONST.LOGIN_URL, text=load_fixture("login.json", "abode"))
requests_mock.post(URL.LOGIN, text=load_fixture("login.json", "abode"))
# Mocks the logout response for abodepy.
requests_mock.post(CONST.LOGOUT_URL, text=load_fixture("logout.json", "abode"))
requests_mock.post(URL.LOGOUT, text=load_fixture("logout.json", "abode"))
# Mocks the oauth claims response for abodepy.
requests_mock.get(
CONST.OAUTH_TOKEN_URL, text=load_fixture("oauth_claims.json", "abode")
)
requests_mock.get(URL.OAUTH_TOKEN, text=load_fixture("oauth_claims.json", "abode"))
# Mocks the panel response for abodepy.
requests_mock.get(CONST.PANEL_URL, text=load_fixture("panel.json", "abode"))
requests_mock.get(URL.PANEL, text=load_fixture("panel.json", "abode"))
# Mocks the automations response for abodepy.
requests_mock.get(
CONST.AUTOMATION_URL, text=load_fixture("automation.json", "abode")
)
requests_mock.get(URL.AUTOMATION, text=load_fixture("automation.json", "abode"))
# Mocks the devices response for abodepy.
requests_mock.get(CONST.DEVICES_URL, text=load_fixture("devices.json", "abode"))
requests_mock.get(URL.DEVICES, text=load_fixture("devices.json", "abode"))