Upgrade Ring to new version (#30666)
* Upgrade Ring to new version * Move legacy cleanup down * Fix testpull/30803/head
parent
86bdba2ea2
commit
718f3438ea
|
@ -5,8 +5,7 @@ from functools import partial
|
|||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from requests.exceptions import ConnectTimeout, HTTPError
|
||||
from ring_doorbell import Ring
|
||||
from ring_doorbell import Auth, Ring
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
|
@ -14,6 +13,7 @@ from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
|||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.dispatcher import dispatcher_send
|
||||
from homeassistant.helpers.event import track_time_interval
|
||||
from homeassistant.util.async_ import run_callback_threadsafe
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -28,7 +28,6 @@ DATA_RING_CHIMES = "ring_chimes"
|
|||
DATA_TRACK_INTERVAL = "ring_track_interval"
|
||||
|
||||
DOMAIN = "ring"
|
||||
DEFAULT_CACHEDB = ".ring_cache.pickle"
|
||||
DEFAULT_ENTITY_NAMESPACE = "ring"
|
||||
SIGNAL_UPDATE_RING = "ring_update"
|
||||
|
||||
|
@ -54,6 +53,14 @@ async def async_setup(hass, config):
|
|||
if DOMAIN not in config:
|
||||
return True
|
||||
|
||||
def legacy_cleanup():
|
||||
"""Clean up old tokens."""
|
||||
old_cache = Path(hass.config.path(".ring_cache.pickle"))
|
||||
if old_cache.is_file():
|
||||
old_cache.unlink()
|
||||
|
||||
await hass.async_add_executor_job(legacy_cleanup)
|
||||
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
|
@ -69,30 +76,20 @@ async def async_setup(hass, config):
|
|||
|
||||
async def async_setup_entry(hass, entry):
|
||||
"""Set up a config entry."""
|
||||
cache = hass.config.path(DEFAULT_CACHEDB)
|
||||
try:
|
||||
ring = await hass.async_add_executor_job(
|
||||
partial(
|
||||
Ring,
|
||||
username=entry.data["username"],
|
||||
password="invalid-password",
|
||||
cache_file=cache,
|
||||
)
|
||||
)
|
||||
except (ConnectTimeout, HTTPError) as ex:
|
||||
_LOGGER.error("Unable to connect to Ring service: %s", str(ex))
|
||||
hass.components.persistent_notification.async_create(
|
||||
"Error: {}<br />"
|
||||
"You will need to restart hass after fixing."
|
||||
"".format(ex),
|
||||
title=NOTIFICATION_TITLE,
|
||||
notification_id=NOTIFICATION_ID,
|
||||
)
|
||||
return False
|
||||
|
||||
if not ring.is_connected:
|
||||
_LOGGER.error("Unable to connect to Ring service")
|
||||
return False
|
||||
def token_updater(token):
|
||||
"""Handle from sync context when token is updated."""
|
||||
run_callback_threadsafe(
|
||||
hass.loop,
|
||||
partial(
|
||||
hass.config_entries.async_update_entry,
|
||||
entry,
|
||||
data={**entry.data, "token": token},
|
||||
),
|
||||
).result()
|
||||
|
||||
auth = Auth(entry.data["token"], token_updater)
|
||||
ring = Ring(auth)
|
||||
|
||||
await hass.async_add_executor_job(finish_setup_entry, hass, ring)
|
||||
|
||||
|
@ -106,9 +103,10 @@ async def async_setup_entry(hass, entry):
|
|||
|
||||
def finish_setup_entry(hass, ring):
|
||||
"""Finish setting up entry."""
|
||||
hass.data[DATA_RING_CHIMES] = chimes = ring.chimes
|
||||
hass.data[DATA_RING_DOORBELLS] = doorbells = ring.doorbells
|
||||
hass.data[DATA_RING_STICKUP_CAMS] = stickup_cams = ring.stickup_cams
|
||||
devices = ring.devices
|
||||
hass.data[DATA_RING_CHIMES] = chimes = devices["chimes"]
|
||||
hass.data[DATA_RING_DOORBELLS] = doorbells = devices["doorbells"]
|
||||
hass.data[DATA_RING_STICKUP_CAMS] = stickup_cams = devices["stickup_cams"]
|
||||
|
||||
ring_devices = chimes + doorbells + stickup_cams
|
||||
|
||||
|
@ -160,8 +158,3 @@ async def async_unload_entry(hass, entry):
|
|||
hass.data.pop(DATA_TRACK_INTERVAL)
|
||||
|
||||
return unload_ok
|
||||
|
||||
|
||||
async def async_remove_entry(hass, entry):
|
||||
"""Act when an entry is removed."""
|
||||
await hass.async_add_executor_job(Path(hass.config.path(DEFAULT_CACHEDB)).unlink)
|
||||
|
|
|
@ -5,7 +5,7 @@ import logging
|
|||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
from homeassistant.const import ATTR_ATTRIBUTION
|
||||
|
||||
from . import ATTRIBUTION, DATA_RING_DOORBELLS, DATA_RING_STICKUP_CAMS
|
||||
from . import ATTRIBUTION, DATA_RING_DOORBELLS, DATA_RING_STICKUP_CAMS, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -72,14 +72,23 @@ class RingBinarySensor(BinarySensorDevice):
|
|||
"""Return a unique ID."""
|
||||
return self._unique_id
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return device info."""
|
||||
return {
|
||||
"identifiers": {(DOMAIN, self._data.id)},
|
||||
"sw_version": self._data.firmware,
|
||||
"name": self._data.name,
|
||||
"model": self._data.kind,
|
||||
"manufacturer": "Ring",
|
||||
}
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the state attributes."""
|
||||
attrs = {}
|
||||
attrs[ATTR_ATTRIBUTION] = ATTRIBUTION
|
||||
|
||||
attrs["device_id"] = self._data.id
|
||||
attrs["firmware"] = self._data.firmware
|
||||
attrs["timezone"] = self._data.timezone
|
||||
|
||||
if self._data.alert and self._data.alert_expires_at:
|
||||
|
|
|
@ -18,6 +18,7 @@ from . import (
|
|||
ATTRIBUTION,
|
||||
DATA_RING_DOORBELLS,
|
||||
DATA_RING_STICKUP_CAMS,
|
||||
DOMAIN,
|
||||
SIGNAL_UPDATE_RING,
|
||||
)
|
||||
|
||||
|
@ -86,16 +87,23 @@ class RingCam(Camera):
|
|||
"""Return a unique ID."""
|
||||
return self._camera.id
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return device info."""
|
||||
return {
|
||||
"identifiers": {(DOMAIN, self._camera.id)},
|
||||
"sw_version": self._camera.firmware,
|
||||
"name": self._camera.name,
|
||||
"model": self._camera.kind,
|
||||
"manufacturer": "Ring",
|
||||
}
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the state attributes."""
|
||||
return {
|
||||
ATTR_ATTRIBUTION: ATTRIBUTION,
|
||||
"device_id": self._camera.id,
|
||||
"firmware": self._camera.firmware,
|
||||
"kind": self._camera.kind,
|
||||
"timezone": self._camera.timezone,
|
||||
"type": self._camera.family,
|
||||
"video_url": self._video_url,
|
||||
"last_video_id": self._last_video_id,
|
||||
}
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
"""Config flow for Ring integration."""
|
||||
from functools import partial
|
||||
import logging
|
||||
|
||||
from oauthlib.oauth2 import AccessDeniedError
|
||||
from ring_doorbell import Ring
|
||||
from ring_doorbell import Auth
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries, core, exceptions
|
||||
|
||||
from . import DEFAULT_CACHEDB, DOMAIN # pylint: disable=unused-import
|
||||
from . import DOMAIN # pylint: disable=unused-import
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def validate_input(hass: core.HomeAssistant, data):
|
||||
"""Validate the user input allows us to connect."""
|
||||
cache = hass.config.path(DEFAULT_CACHEDB)
|
||||
|
||||
def otp_callback():
|
||||
if "2fa" in data:
|
||||
|
@ -23,21 +21,16 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||
|
||||
raise Require2FA
|
||||
|
||||
auth = Auth()
|
||||
|
||||
try:
|
||||
ring = await hass.async_add_executor_job(
|
||||
partial(
|
||||
Ring,
|
||||
username=data["username"],
|
||||
password=data["password"],
|
||||
cache_file=cache,
|
||||
auth_callback=otp_callback,
|
||||
)
|
||||
token = await hass.async_add_executor_job(
|
||||
auth.fetch_token, data["username"], data["password"], otp_callback,
|
||||
)
|
||||
except AccessDeniedError:
|
||||
raise InvalidAuth
|
||||
|
||||
if not ring.is_connected:
|
||||
raise InvalidAuth
|
||||
return token
|
||||
|
||||
|
||||
class RingConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
|
@ -56,12 +49,12 @@ class RingConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
errors = {}
|
||||
if user_input is not None:
|
||||
try:
|
||||
await validate_input(self.hass, user_input)
|
||||
token = await validate_input(self.hass, user_input)
|
||||
await self.async_set_unique_id(user_input["username"])
|
||||
|
||||
return self.async_create_entry(
|
||||
title=user_input["username"],
|
||||
data={"username": user_input["username"]},
|
||||
data={"username": user_input["username"], "token": token},
|
||||
)
|
||||
except Require2FA:
|
||||
self.user_pass = user_input
|
||||
|
|
|
@ -7,7 +7,7 @@ from homeassistant.core import callback
|
|||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from . import DATA_RING_STICKUP_CAMS, SIGNAL_UPDATE_RING
|
||||
from . import DATA_RING_STICKUP_CAMS, DOMAIN, SIGNAL_UPDATE_RING
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -84,6 +84,17 @@ class RingLight(Light):
|
|||
"""If the switch is currently on or off."""
|
||||
return self._light_on
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return device info."""
|
||||
return {
|
||||
"identifiers": {(DOMAIN, self._device.id)},
|
||||
"sw_version": self._device.firmware,
|
||||
"name": self._device.name,
|
||||
"model": self._device.kind,
|
||||
"manufacturer": "Ring",
|
||||
}
|
||||
|
||||
def _set_light(self, new_state):
|
||||
"""Update light state, and causes Home Assistant to correctly update."""
|
||||
self._device.lights = new_state
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"domain": "ring",
|
||||
"name": "Ring",
|
||||
"documentation": "https://www.home-assistant.io/integrations/ring",
|
||||
"requirements": ["ring_doorbell==0.2.9"],
|
||||
"requirements": ["ring_doorbell==0.4.0"],
|
||||
"dependencies": ["ffmpeg"],
|
||||
"codeowners": [],
|
||||
"config_flow": true
|
||||
|
|
|
@ -12,6 +12,7 @@ from . import (
|
|||
DATA_RING_CHIMES,
|
||||
DATA_RING_DOORBELLS,
|
||||
DATA_RING_STICKUP_CAMS,
|
||||
DOMAIN,
|
||||
SIGNAL_UPDATE_RING,
|
||||
)
|
||||
|
||||
|
@ -108,6 +109,7 @@ class RingSensor(Entity):
|
|||
self._disp_disconnect = async_dispatcher_connect(
|
||||
self.hass, SIGNAL_UPDATE_RING, self._update_callback
|
||||
)
|
||||
await self.hass.async_add_executor_job(self._data.update)
|
||||
|
||||
async def async_will_remove_from_hass(self):
|
||||
"""Disconnect callbacks."""
|
||||
|
@ -140,17 +142,24 @@ class RingSensor(Entity):
|
|||
"""Return a unique ID."""
|
||||
return self._unique_id
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return device info."""
|
||||
return {
|
||||
"identifiers": {(DOMAIN, self._data.id)},
|
||||
"sw_version": self._data.firmware,
|
||||
"name": self._data.name,
|
||||
"model": self._data.kind,
|
||||
"manufacturer": "Ring",
|
||||
}
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the state attributes."""
|
||||
attrs = {}
|
||||
|
||||
attrs[ATTR_ATTRIBUTION] = ATTRIBUTION
|
||||
attrs["device_id"] = self._data.id
|
||||
attrs["firmware"] = self._data.firmware
|
||||
attrs["kind"] = self._data.kind
|
||||
attrs["timezone"] = self._data.timezone
|
||||
attrs["type"] = self._data.family
|
||||
attrs["wifi_name"] = self._data.wifi_name
|
||||
|
||||
if self._extra and self._sensor_type.startswith("last_"):
|
||||
|
|
|
@ -7,7 +7,7 @@ from homeassistant.core import callback
|
|||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from . import DATA_RING_STICKUP_CAMS, SIGNAL_UPDATE_RING
|
||||
from . import DATA_RING_STICKUP_CAMS, DOMAIN, SIGNAL_UPDATE_RING
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -76,6 +76,17 @@ class BaseRingSwitch(SwitchDevice):
|
|||
"""Update controlled via the hub."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return device info."""
|
||||
return {
|
||||
"identifiers": {(DOMAIN, self._device.id)},
|
||||
"sw_version": self._device.firmware,
|
||||
"name": self._device.name,
|
||||
"model": self._device.kind,
|
||||
"manufacturer": "Ring",
|
||||
}
|
||||
|
||||
|
||||
class SirenSwitch(BaseRingSwitch):
|
||||
"""Creates a switch to turn the ring cameras siren on and off."""
|
||||
|
|
|
@ -1753,7 +1753,7 @@ rfk101py==0.0.1
|
|||
rflink==0.0.50
|
||||
|
||||
# homeassistant.components.ring
|
||||
ring_doorbell==0.2.9
|
||||
ring_doorbell==0.4.0
|
||||
|
||||
# homeassistant.components.fleetgo
|
||||
ritassist==0.9.2
|
||||
|
|
|
@ -567,7 +567,7 @@ restrictedpython==5.0
|
|||
rflink==0.0.50
|
||||
|
||||
# homeassistant.components.ring
|
||||
ring_doorbell==0.2.9
|
||||
ring_doorbell==0.4.0
|
||||
|
||||
# homeassistant.components.yamaha
|
||||
rxv==0.6.0
|
||||
|
|
|
@ -9,7 +9,9 @@ from tests.common import MockConfigEntry
|
|||
|
||||
async def setup_platform(hass, platform):
|
||||
"""Set up the ring platform and prerequisites."""
|
||||
MockConfigEntry(domain=DOMAIN, data={"username": "foo"}).add_to_hass(hass)
|
||||
MockConfigEntry(domain=DOMAIN, data={"username": "foo", "token": {}}).add_to_hass(
|
||||
hass
|
||||
)
|
||||
with patch("homeassistant.components.ring.PLATFORMS", [platform]):
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
|
|
|
@ -1,21 +1,12 @@
|
|||
"""Configuration for Ring tests."""
|
||||
from asynctest import patch
|
||||
import pytest
|
||||
import requests_mock
|
||||
|
||||
from tests.common import load_fixture
|
||||
|
||||
|
||||
@pytest.fixture(name="ring_mock")
|
||||
def ring_save_mock():
|
||||
"""Fixture to mock a ring."""
|
||||
with patch("ring_doorbell._exists_cache", return_value=False):
|
||||
with patch("ring_doorbell._save_cache", return_value=True) as save_mock:
|
||||
yield save_mock
|
||||
|
||||
|
||||
@pytest.fixture(name="requests_mock")
|
||||
def requests_mock_fixture(ring_mock):
|
||||
def requests_mock_fixture():
|
||||
"""Fixture to provide a requests mocker."""
|
||||
with requests_mock.mock() as mock:
|
||||
# Note all devices have an id of 987652, but a different device_id.
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
"""The tests for the Ring binary sensor platform."""
|
||||
from asyncio import run_coroutine_threadsafe
|
||||
import os
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
|
@ -9,12 +8,7 @@ import requests_mock
|
|||
from homeassistant.components import ring as base_ring
|
||||
from homeassistant.components.ring import binary_sensor as ring
|
||||
|
||||
from tests.common import (
|
||||
get_test_config_dir,
|
||||
get_test_home_assistant,
|
||||
load_fixture,
|
||||
mock_storage,
|
||||
)
|
||||
from tests.common import get_test_home_assistant, load_fixture, mock_storage
|
||||
from tests.components.ring.test_init import ATTRIBUTION, VALID_CONFIG
|
||||
|
||||
|
||||
|
@ -28,15 +22,9 @@ class TestRingBinarySensorSetup(unittest.TestCase):
|
|||
for device in devices:
|
||||
self.DEVICES.append(device)
|
||||
|
||||
def cleanup(self):
|
||||
"""Cleanup any data created from the tests."""
|
||||
if os.path.isfile(self.cache):
|
||||
os.remove(self.cache)
|
||||
|
||||
def setUp(self):
|
||||
"""Initialize values for this testcase class."""
|
||||
self.hass = get_test_home_assistant()
|
||||
self.cache = get_test_config_dir(base_ring.DEFAULT_CACHEDB)
|
||||
self.config = {
|
||||
"username": "foo",
|
||||
"password": "bar",
|
||||
|
@ -46,7 +34,6 @@ class TestRingBinarySensorSetup(unittest.TestCase):
|
|||
def tearDown(self):
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
self.cleanup()
|
||||
|
||||
@requests_mock.Mocker()
|
||||
def test_binary_sensor(self, mock):
|
||||
|
|
|
@ -18,8 +18,10 @@ async def test_form(hass):
|
|||
assert result["errors"] == {}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.ring.config_flow.Ring",
|
||||
return_value=Mock(is_connected=True),
|
||||
"homeassistant.components.ring.config_flow.Auth",
|
||||
return_value=Mock(
|
||||
fetch_token=Mock(return_value={"access_token": "mock-token"})
|
||||
),
|
||||
), patch(
|
||||
"homeassistant.components.ring.async_setup", return_value=mock_coro(True)
|
||||
) as mock_setup, patch(
|
||||
|
@ -34,6 +36,7 @@ async def test_form(hass):
|
|||
assert result2["title"] == "hello@home-assistant.io"
|
||||
assert result2["data"] == {
|
||||
"username": "hello@home-assistant.io",
|
||||
"token": {"access_token": "mock-token"},
|
||||
}
|
||||
await hass.async_block_till_done()
|
||||
assert len(mock_setup.mock_calls) == 1
|
||||
|
@ -47,7 +50,8 @@ async def test_form_invalid_auth(hass):
|
|||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.ring.config_flow.Ring", side_effect=InvalidAuth,
|
||||
"homeassistant.components.ring.config_flow.Auth.fetch_token",
|
||||
side_effect=InvalidAuth,
|
||||
):
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
from asyncio import run_coroutine_threadsafe
|
||||
from copy import deepcopy
|
||||
from datetime import timedelta
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import requests_mock
|
||||
|
@ -10,7 +9,7 @@ import requests_mock
|
|||
from homeassistant import setup
|
||||
import homeassistant.components.ring as ring
|
||||
|
||||
from tests.common import get_test_config_dir, get_test_home_assistant, load_fixture
|
||||
from tests.common import get_test_home_assistant, load_fixture
|
||||
|
||||
ATTRIBUTION = "Data provided by Ring.com"
|
||||
|
||||
|
@ -22,21 +21,14 @@ VALID_CONFIG = {
|
|||
class TestRing(unittest.TestCase):
|
||||
"""Tests the Ring component."""
|
||||
|
||||
def cleanup(self):
|
||||
"""Cleanup any data created from the tests."""
|
||||
if os.path.isfile(self.cache):
|
||||
os.remove(self.cache)
|
||||
|
||||
def setUp(self):
|
||||
"""Initialize values for this test case class."""
|
||||
self.hass = get_test_home_assistant()
|
||||
self.cache = get_test_config_dir(ring.DEFAULT_CACHEDB)
|
||||
self.config = VALID_CONFIG
|
||||
|
||||
def tearDown(self): # pylint: disable=invalid-name
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
self.cleanup()
|
||||
|
||||
@requests_mock.Mocker()
|
||||
def test_setup(self, mock):
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
"""The tests for the Ring sensor platform."""
|
||||
from asyncio import run_coroutine_threadsafe
|
||||
import os
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
|
@ -10,12 +9,7 @@ from homeassistant.components import ring as base_ring
|
|||
import homeassistant.components.ring.sensor as ring
|
||||
from homeassistant.helpers.icon import icon_for_battery_level
|
||||
|
||||
from tests.common import (
|
||||
get_test_config_dir,
|
||||
get_test_home_assistant,
|
||||
load_fixture,
|
||||
mock_storage,
|
||||
)
|
||||
from tests.common import get_test_home_assistant, load_fixture, mock_storage
|
||||
from tests.components.ring.test_init import ATTRIBUTION, VALID_CONFIG
|
||||
|
||||
|
||||
|
@ -29,15 +23,9 @@ class TestRingSensorSetup(unittest.TestCase):
|
|||
for device in devices:
|
||||
self.DEVICES.append(device)
|
||||
|
||||
def cleanup(self):
|
||||
"""Cleanup any data created from the tests."""
|
||||
if os.path.isfile(self.cache):
|
||||
os.remove(self.cache)
|
||||
|
||||
def setUp(self):
|
||||
"""Initialize values for this testcase class."""
|
||||
self.hass = get_test_home_assistant()
|
||||
self.cache = get_test_config_dir(base_ring.DEFAULT_CACHEDB)
|
||||
self.config = {
|
||||
"username": "foo",
|
||||
"password": "bar",
|
||||
|
@ -55,7 +43,6 @@ class TestRingSensorSetup(unittest.TestCase):
|
|||
def tearDown(self):
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
self.cleanup()
|
||||
|
||||
@requests_mock.Mocker()
|
||||
def test_sensor(self, mock):
|
||||
|
@ -97,6 +84,13 @@ class TestRingSensorSetup(unittest.TestCase):
|
|||
).result()
|
||||
|
||||
for device in self.DEVICES:
|
||||
# Mimick add to hass
|
||||
device.hass = self.hass
|
||||
run_coroutine_threadsafe(
|
||||
device.async_added_to_hass(), self.hass.loop,
|
||||
).result()
|
||||
|
||||
# Entity update data from ring data
|
||||
device.update()
|
||||
if device.name == "Front Battery":
|
||||
expected_icon = icon_for_battery_level(
|
||||
|
@ -104,18 +98,12 @@ class TestRingSensorSetup(unittest.TestCase):
|
|||
)
|
||||
assert device.icon == expected_icon
|
||||
assert 80 == device.state
|
||||
assert "hp_cam_v1" == device.device_state_attributes["kind"]
|
||||
assert "stickup_cams" == device.device_state_attributes["type"]
|
||||
if device.name == "Front Door Battery":
|
||||
assert 100 == device.state
|
||||
assert "lpd_v1" == device.device_state_attributes["kind"]
|
||||
assert "chimes" != device.device_state_attributes["type"]
|
||||
if device.name == "Downstairs Volume":
|
||||
assert 2 == device.state
|
||||
assert "1.2.3" == device.device_state_attributes["firmware"]
|
||||
assert "ring_mock_wifi" == device.device_state_attributes["wifi_name"]
|
||||
assert "mdi:bell-ring" == device.icon
|
||||
assert "chimes" == device.device_state_attributes["type"]
|
||||
if device.name == "Front Door Last Activity":
|
||||
assert not device.device_state_attributes["answered"]
|
||||
assert "America/New_York" == device.device_state_attributes["timezone"]
|
||||
|
|
Loading…
Reference in New Issue