mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Add availability to Rflink entities. (#14977)
This commit is contained in:
parent
4bd7a7eee3
commit
2ec295a6f8
@ -20,6 +20,8 @@ from homeassistant.exceptions import HomeAssistantError
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.deprecation import get_deprecated
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.dispatcher import (
|
||||
async_dispatcher_send, async_dispatcher_connect)
|
||||
|
||||
|
||||
REQUIREMENTS = ['rflink==0.0.37']
|
||||
@ -65,6 +67,8 @@ DOMAIN = 'rflink'
|
||||
|
||||
SERVICE_SEND_COMMAND = 'send_command'
|
||||
|
||||
SIGNAL_AVAILABILITY = 'rflink_device_available'
|
||||
|
||||
DEVICE_DEFAULTS_SCHEMA = vol.Schema({
|
||||
vol.Optional(CONF_FIRE_EVENT, default=False): cv.boolean,
|
||||
vol.Optional(CONF_SIGNAL_REPETITIONS,
|
||||
@ -185,6 +189,8 @@ def async_setup(hass, config):
|
||||
# Reset protocol binding before starting reconnect
|
||||
RflinkCommand.set_rflink_protocol(None)
|
||||
|
||||
async_dispatcher_send(hass, SIGNAL_AVAILABILITY, False)
|
||||
|
||||
# If HA is not stopping, initiate new connection
|
||||
if hass.state != CoreState.stopping:
|
||||
_LOGGER.warning('disconnected from Rflink, reconnecting')
|
||||
@ -219,9 +225,16 @@ def async_setup(hass, config):
|
||||
_LOGGER.exception(
|
||||
"Error connecting to Rflink, reconnecting in %s",
|
||||
reconnect_interval)
|
||||
# Connection to Rflink device is lost, make entities unavailable
|
||||
async_dispatcher_send(hass, SIGNAL_AVAILABILITY, False)
|
||||
|
||||
hass.loop.call_later(reconnect_interval, reconnect, exc)
|
||||
return
|
||||
|
||||
# There is a valid connection to a Rflink device now so
|
||||
# mark entities as available
|
||||
async_dispatcher_send(hass, SIGNAL_AVAILABILITY, True)
|
||||
|
||||
# Bind protocol to command class to allow entities to send commands
|
||||
RflinkCommand.set_rflink_protocol(
|
||||
protocol, config[DOMAIN][CONF_WAIT_FOR_ACK])
|
||||
@ -244,6 +257,7 @@ class RflinkDevice(Entity):
|
||||
|
||||
platform = None
|
||||
_state = STATE_UNKNOWN
|
||||
_available = True
|
||||
|
||||
def __init__(self, device_id, hass, name=None, aliases=None, group=True,
|
||||
group_aliases=None, nogroup_aliases=None, fire_event=False,
|
||||
@ -305,6 +319,23 @@ class RflinkDevice(Entity):
|
||||
"""Assume device state until first device event sets state."""
|
||||
return self._state is STATE_UNKNOWN
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Return True if entity is available."""
|
||||
return self._available
|
||||
|
||||
@callback
|
||||
def set_availability(self, availability):
|
||||
"""Update availability state."""
|
||||
self._available = availability
|
||||
self.async_schedule_update_ha_state()
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_added_to_hass(self):
|
||||
"""Register update callback."""
|
||||
async_dispatcher_connect(self.hass, SIGNAL_AVAILABILITY,
|
||||
self.set_availability)
|
||||
|
||||
|
||||
class RflinkCommand(RflinkDevice):
|
||||
"""Singleton class to make Rflink command interface available to entities.
|
||||
|
@ -8,6 +8,9 @@ automatic sensor creation.
|
||||
import asyncio
|
||||
|
||||
from ..test_rflink import mock_rflink
|
||||
from homeassistant.components.rflink import (
|
||||
CONF_RECONNECT_INTERVAL)
|
||||
from homeassistant.const import STATE_UNKNOWN
|
||||
|
||||
DOMAIN = 'sensor'
|
||||
|
||||
@ -32,7 +35,7 @@ CONFIG = {
|
||||
def test_default_setup(hass, monkeypatch):
|
||||
"""Test all basic functionality of the rflink sensor component."""
|
||||
# setup mocking rflink module
|
||||
event_callback, create, _, _ = yield from mock_rflink(
|
||||
event_callback, create, _, disconnect_callback = yield from mock_rflink(
|
||||
hass, CONFIG, DOMAIN, monkeypatch)
|
||||
|
||||
# make sure arguments are passed
|
||||
@ -100,3 +103,38 @@ def test_disable_automatic_add(hass, monkeypatch):
|
||||
|
||||
# make sure new device is not added
|
||||
assert not hass.states.get('sensor.test2')
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_entity_availability(hass, monkeypatch):
|
||||
"""If Rflink device is disconnected, entities should become unavailable."""
|
||||
# Make sure Rflink mock does not 'recover' to quickly from the
|
||||
# disconnect or else the unavailability cannot be measured
|
||||
config = CONFIG
|
||||
failures = [True, True]
|
||||
config[CONF_RECONNECT_INTERVAL] = 60
|
||||
|
||||
# Create platform and entities
|
||||
event_callback, create, _, disconnect_callback = yield from mock_rflink(
|
||||
hass, config, DOMAIN, monkeypatch, failures=failures)
|
||||
|
||||
# Entities are available by default
|
||||
assert hass.states.get('sensor.test').state == STATE_UNKNOWN
|
||||
|
||||
# Mock a disconnect of the Rflink device
|
||||
disconnect_callback()
|
||||
|
||||
# Wait for dispatch events to propagate
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
# Entity should be unavailable
|
||||
assert hass.states.get('sensor.test').state == 'unavailable'
|
||||
|
||||
# Reconnect the Rflink device
|
||||
disconnect_callback()
|
||||
|
||||
# Wait for dispatch events to propagate
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
# Entities should be available again
|
||||
assert hass.states.get('sensor.test').state == STATE_UNKNOWN
|
||||
|
Loading…
x
Reference in New Issue
Block a user