Binary Sensor for Remote UI & Fix timezone (#22076)
* Binary Sensor for Remote UI * Fix lint * Revert make hass public * Add tests
This commit is contained in:
parent
9520d38288
commit
17ba33004c
7 changed files with 124 additions and 6 deletions
|
@ -24,7 +24,7 @@ from .const import (
|
|||
CONF_USER_POOL_ID, DOMAIN, MODE_DEV, MODE_PROD)
|
||||
from .prefs import CloudPreferences
|
||||
|
||||
REQUIREMENTS = ['hass-nabucasa==0.5']
|
||||
REQUIREMENTS = ['hass-nabucasa==0.7']
|
||||
DEPENDENCIES = ['http']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -193,4 +193,6 @@ async def async_setup(hass, config):
|
|||
DOMAIN, SERVICE_REMOTE_DISCONNECT, _service_handler)
|
||||
|
||||
await http_api.async_setup(hass)
|
||||
hass.async_create_task(hass.helpers.discovery.async_load_platform(
|
||||
'binary_sensor', DOMAIN, {}, config))
|
||||
return True
|
||||
|
|
73
homeassistant/components/cloud/binary_sensor.py
Normal file
73
homeassistant/components/cloud/binary_sensor.py
Normal file
|
@ -0,0 +1,73 @@
|
|||
"""Support for Home Assistant Cloud binary sensors."""
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
from .const import DISPATCHER_REMOTE_UPDATE, DOMAIN
|
||||
|
||||
DEPENDENCIES = ['cloud']
|
||||
|
||||
|
||||
async def async_setup_platform(
|
||||
hass, config, async_add_entities, discovery_info=None):
|
||||
"""Set up the cloud binary sensors."""
|
||||
if discovery_info is None:
|
||||
return
|
||||
cloud = hass.data[DOMAIN]
|
||||
|
||||
async_add_entities([CloudRemoteBinary(cloud)])
|
||||
|
||||
|
||||
class CloudRemoteBinary(BinarySensorDevice):
|
||||
"""Representation of an Cloud Remote UI Connection binary sensor."""
|
||||
|
||||
def __init__(self, cloud):
|
||||
"""Initialize the binary sensor."""
|
||||
self.cloud = cloud
|
||||
self._unsub_dispatcher = None
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Return the name of the binary sensor, if any."""
|
||||
return "Remote UI"
|
||||
|
||||
@property
|
||||
def unique_id(self) -> str:
|
||||
"""Return a unique ID."""
|
||||
return "cloud-remote-ui-connectivity"
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if the binary sensor is on."""
|
||||
return self.cloud.remote.is_connected
|
||||
|
||||
@property
|
||||
def device_class(self) -> str:
|
||||
"""Return the class of this device, from component DEVICE_CLASSES."""
|
||||
return 'connectivity'
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return True if entity is available."""
|
||||
return self.cloud.remote.certificate is not None
|
||||
|
||||
@property
|
||||
def should_poll(self) -> bool:
|
||||
"""Return True if entity has to be polled for state."""
|
||||
return False
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Register update dispatcher."""
|
||||
@callback
|
||||
def async_state_update(data):
|
||||
"""Update callback."""
|
||||
self.async_write_ha_state()
|
||||
|
||||
self._unsub_dispatcher = async_dispatcher_connect(
|
||||
self.hass, DISPATCHER_REMOTE_UPDATE, async_state_update)
|
||||
|
||||
async def async_will_remove_from_hass(self):
|
||||
"""Register update dispatcher."""
|
||||
if self._unsub_dispatcher is not None:
|
||||
self._unsub_dispatcher()
|
||||
self._unsub_dispatcher = None
|
|
@ -6,15 +6,18 @@ from typing import Any, Dict
|
|||
import aiohttp
|
||||
from hass_nabucasa.client import CloudClient as Interface
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.components.alexa import smart_home as alexa_sh
|
||||
from homeassistant.components.google_assistant import (
|
||||
helpers as ga_h, smart_home as ga)
|
||||
from homeassistant.const import CLOUD_NEVER_EXPOSED_ENTITIES
|
||||
from homeassistant.helpers.typing import HomeAssistantType
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
from homeassistant.util.aiohttp import MockRequest
|
||||
|
||||
from . import utils
|
||||
from .const import CONF_ENTITY_CONFIG, CONF_FILTER, DOMAIN
|
||||
from .const import (
|
||||
CONF_ENTITY_CONFIG, CONF_FILTER, DOMAIN, DISPATCHER_REMOTE_UPDATE)
|
||||
from .prefs import CloudPreferences
|
||||
|
||||
|
||||
|
@ -115,13 +118,19 @@ class CloudClient(Interface):
|
|||
self._alexa_config = None
|
||||
self._google_config = None
|
||||
|
||||
async def async_user_message(
|
||||
self, identifier: str, title: str, message: str) -> None:
|
||||
@callback
|
||||
def user_message(self, identifier: str, title: str, message: str) -> None:
|
||||
"""Create a message for user to UI."""
|
||||
self._hass.components.persistent_notification.async_create(
|
||||
message, title, identifier
|
||||
)
|
||||
|
||||
@callback
|
||||
def dispatcher_message(self, identifier: str, data: Any = None) -> None:
|
||||
"""Match cloud notification to dispatcher."""
|
||||
if identifier.startwith("remote_"):
|
||||
async_dispatcher_send(self._hass, DISPATCHER_REMOTE_UPDATE, data)
|
||||
|
||||
async def async_alexa_message(
|
||||
self, payload: Dict[Any, Any]) -> Dict[Any, Any]:
|
||||
"""Process cloud alexa message to client."""
|
||||
|
|
|
@ -25,3 +25,5 @@ CONF_ACME_DIRECTORY_SERVER = 'acme_directory_server'
|
|||
|
||||
MODE_DEV = "development"
|
||||
MODE_PROD = "production"
|
||||
|
||||
DISPATCHER_REMOTE_UPDATE = 'cloud_remote_update'
|
||||
|
|
|
@ -524,7 +524,7 @@ habitipy==0.2.0
|
|||
hangups==0.4.6
|
||||
|
||||
# homeassistant.components.cloud
|
||||
hass-nabucasa==0.5
|
||||
hass-nabucasa==0.7
|
||||
|
||||
# homeassistant.components.mqtt.server
|
||||
hbmqtt==0.9.4
|
||||
|
|
|
@ -114,7 +114,7 @@ ha-ffmpeg==1.11
|
|||
hangups==0.4.6
|
||||
|
||||
# homeassistant.components.cloud
|
||||
hass-nabucasa==0.5
|
||||
hass-nabucasa==0.7
|
||||
|
||||
# homeassistant.components.mqtt.server
|
||||
hbmqtt==0.9.4
|
||||
|
|
32
tests/components/cloud/test_binary_sensor.py
Normal file
32
tests/components/cloud/test_binary_sensor.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
"""Tests for the cloud binary sensor."""
|
||||
from unittest.mock import Mock
|
||||
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.components.cloud.const import DISPATCHER_REMOTE_UPDATE
|
||||
|
||||
|
||||
async def test_remote_connection_sensor(hass):
|
||||
"""Test the remote connection sensor."""
|
||||
assert await async_setup_component(hass, 'cloud', {'cloud': {}})
|
||||
cloud = hass.data['cloud'] = Mock()
|
||||
cloud.remote.certificate = None
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get('binary_sensor.remote_ui')
|
||||
assert state is not None
|
||||
assert state.state == 'unavailable'
|
||||
|
||||
cloud.remote.is_connected = False
|
||||
cloud.remote.certificate = object()
|
||||
hass.helpers.dispatcher.async_dispatcher_send(DISPATCHER_REMOTE_UPDATE, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get('binary_sensor.remote_ui')
|
||||
assert state.state == 'off'
|
||||
|
||||
cloud.remote.is_connected = True
|
||||
hass.helpers.dispatcher.async_dispatcher_send(DISPATCHER_REMOTE_UPDATE, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get('binary_sensor.remote_ui')
|
||||
assert state.state == 'on'
|
Loading…
Add table
Reference in a new issue