From eaf3620fe7658a0ca195fa72ac7c16d288689e3b Mon Sep 17 00:00:00 2001 From: Tobias Haase Date: Thu, 1 Aug 2019 21:25:28 +0200 Subject: [PATCH] Add binary sensor --- homeassistant/components/updater/__init__.py | 30 ++++----- .../components/updater/binary_sensor.py | 62 +++++++++++++++++++ 2 files changed, 78 insertions(+), 14 deletions(-) create mode 100644 homeassistant/components/updater/binary_sensor.py diff --git a/homeassistant/components/updater/__init__.py b/homeassistant/components/updater/__init__.py index 1b134e0f2a3..cafdfb13e08 100644 --- a/homeassistant/components/updater/__init__.py +++ b/homeassistant/components/updater/__init__.py @@ -28,8 +28,6 @@ CONF_COMPONENT_REPORTING = "include_used_components" DOMAIN = "updater" -ENTITY_ID = "updater.updater" - UPDATER_URL = "https://updater.home-assistant.io/" UPDATER_UUID_FILE = ".uuid" @@ -48,6 +46,14 @@ RESPONSE_SCHEMA = vol.Schema( ) +class Updater: + """Updater class.""" + + update_available = None + release_notes = None + newest_version = None + + def _create_uuid(hass, filename=UPDATER_UUID_FILE): """Create UUID and save it in a file.""" with open(hass.config.path(filename), "w") as fptr: @@ -82,6 +88,8 @@ async def async_setup(hass, config): include_components = config.get(CONF_COMPONENT_REPORTING) + updater = hass.data[DOMAIN] = Updater() + async def check_new_version(now): """Check if a new version is available and report if one is.""" result = await get_newest_version(hass, huuid, include_components) @@ -89,7 +97,7 @@ async def async_setup(hass, config): if result is None: return - newest, releasenotes = result + newest, release_notes = result # Skip on dev if newest is None or "dev" in current_version: @@ -109,15 +117,9 @@ async def async_setup(hass, config): elif StrictVersion(newest) < StrictVersion(current_version): _LOGGER.debug("Local version is newer than the latest version (%s)", newest) - hass.states.async_set( - ENTITY_ID, - "on" if update_available else "off", - { - ATTR_FRIENDLY_NAME: "Update Available", - ATTR_RELEASE_NOTES: releasenotes, - ATTR_NEWEST_VERSION: newest, - }, - ) + updater.update_available = update_available + updater.release_notes = release_notes + updater.newest_version = newest # Update daily, start 1 hour after startup _dt = dt_util.utcnow() + timedelta(hours=1) @@ -152,13 +154,13 @@ async def get_newest_version(hass, huuid, include_components): req = await session.post(UPDATER_URL, json=info_object) _LOGGER.info( ( - "Submitted analytics to Home Assistant servers. " + "Submitted analytics to Home Assistant servers." "Information submitted includes %s" ), info_object, ) except (asyncio.TimeoutError, aiohttp.ClientError): - _LOGGER.error("Could not contact Home Assistant Update to check " "for updates") + _LOGGER.error("Could not contact Home Assistant Update to check for updates") return None try: diff --git a/homeassistant/components/updater/binary_sensor.py b/homeassistant/components/updater/binary_sensor.py new file mode 100644 index 00000000000..c80d0e682f0 --- /dev/null +++ b/homeassistant/components/updater/binary_sensor.py @@ -0,0 +1,62 @@ +"""Support for Home Assistant Updater binary sensors.""" + +from homeassistant.components.binary_sensor import BinarySensorDevice + +from . import ATTR_NEWEST_VERSION, ATTR_RELEASE_NOTES, DOMAIN + + +async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): + """Set up the updater binary sensors.""" + updater = hass.data[DOMAIN] + + async_add_entities([UpdaterBinary(updater)]) + + +class UpdaterBinary(BinarySensorDevice): + """Representation of an updater binary sensor.""" + + def __init__(self, updater): + """Initialize the binary sensor.""" + self._updater = updater + + @property + def name(self) -> str: + """Return the name of the binary sensor, if any.""" + return "Updater" + + @property + def unique_id(self) -> str: + """Return a unique ID.""" + return "updater" + + @property + def is_on(self) -> bool: + """Return true if the binary sensor is on.""" + return "on" if self._updater.update_available else "off" + + @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 True if self._updater.update_available is not None else False + + @property + def should_poll(self) -> bool: + """Return True if entity has to be polled for state.""" + return True + + @property + def device_state_attributes(self) -> dict: + """Return the optional state attributes.""" + data = super().device_state_attributes + if data is None: + data = {} + if self._updater.release_notes: + data[ATTR_RELEASE_NOTES] = self._updater.release_notes + if self._updater.newest_version: + data[ATTR_NEWEST_VERSION] = self._updater.newest_version + return data