diff --git a/homeassistant/components/googlehome/__init__.py b/homeassistant/components/googlehome/__init__.py index 78bd2d7df3f..f2d5ad09350 100644 --- a/homeassistant/components/googlehome/__init__.py +++ b/homeassistant/components/googlehome/__init__.py @@ -24,6 +24,7 @@ NAME = 'GoogleHome' CONF_DEVICE_TYPES = 'device_types' CONF_RSSI_THRESHOLD = 'rssi_threshold' +CONF_TRACK_ALARMS = 'track_alarms' DEVICE_TYPES = [1, 2, 3] DEFAULT_RSSI_THRESHOLD = -70 @@ -35,6 +36,7 @@ DEVICE_CONFIG = vol.Schema({ [vol.In(DEVICE_TYPES)]), vol.Optional(CONF_RSSI_THRESHOLD, default=DEFAULT_RSSI_THRESHOLD): vol.Coerce(int), + vol.Optional(CONF_TRACK_ALARMS, default=False): cv.boolean, }) @@ -56,6 +58,11 @@ async def async_setup(hass, config): discovery.async_load_platform( hass, 'device_tracker', DOMAIN, device, config)) + if device[CONF_TRACK_ALARMS]: + hass.async_create_task( + discovery.async_load_platform( + hass, 'sensor', DOMAIN, device, config)) + return True @@ -67,20 +74,38 @@ class GoogleHomeClient: self.hass = hass self._connected = None - async def update_data(self, host): + async def update_info(self, host): """Update data from Google Home.""" from googledevices.api.connect import Cast - _LOGGER.debug("Updating Google Home data for %s", host) + _LOGGER.debug("Updating Google Home info for %s", host) session = async_get_clientsession(self.hass) device_info = await Cast(host, self.hass.loop, session).info() device_info_data = await device_info.get_device_info() self._connected = bool(device_info_data) + self.hass.data[DOMAIN][host]['info'] = device_info_data + + async def update_bluetooth(self, host): + """Update bluetooth from Google Home.""" + from googledevices.api.connect import Cast + _LOGGER.debug("Updating Google Home bluetooth for %s", host) + session = async_get_clientsession(self.hass) + bluetooth = await Cast(host, self.hass.loop, session).bluetooth() await bluetooth.scan_for_devices() await asyncio.sleep(5) bluetooth_data = await bluetooth.get_scan_result() - self.hass.data[DOMAIN][host]['info'] = device_info_data self.hass.data[DOMAIN][host]['bluetooth'] = bluetooth_data + + async def update_alarms(self, host): + """Update alarms from Google Home.""" + from googledevices.api.connect import Cast + _LOGGER.debug("Updating Google Home bluetooth for %s", host) + session = async_get_clientsession(self.hass) + + assistant = await Cast(host, self.hass.loop, session).assistant() + alarms_data = await assistant.get_alarms() + + self.hass.data[DOMAIN][host]['alarms'] = alarms_data diff --git a/homeassistant/components/googlehome/device_tracker.py b/homeassistant/components/googlehome/device_tracker.py index ba6d708295a..c4b490ab316 100644 --- a/homeassistant/components/googlehome/device_tracker.py +++ b/homeassistant/components/googlehome/device_tracker.py @@ -45,7 +45,7 @@ class GoogleHomeDeviceScanner(DeviceScanner): async def async_init(self): """Further initialize connection to Google Home.""" - await self.client.update_data(self.host) + await self.client.update_info(self.host) data = self.hass.data[GOOGLEHOME_DOMAIN][self.host] info = data.get('info', {}) connected = bool(info) @@ -59,7 +59,7 @@ class GoogleHomeDeviceScanner(DeviceScanner): async def async_update(self, now=None): """Ensure the information from Google Home is up to date.""" _LOGGER.debug('Checking Devices on %s', self.host) - await self.client.update_data(self.host) + await self.client.update_bluetooth(self.host) data = self.hass.data[GOOGLEHOME_DOMAIN][self.host] info = data.get('info') bluetooth = data.get('bluetooth') diff --git a/homeassistant/components/googlehome/sensor.py b/homeassistant/components/googlehome/sensor.py new file mode 100644 index 00000000000..f2a0f822dbf --- /dev/null +++ b/homeassistant/components/googlehome/sensor.py @@ -0,0 +1,110 @@ +""" +Support for Google Home alarm sensor. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/sensor.googlehome/ +""" +import logging +from datetime import timedelta + +from homeassistant.components.sensor import ENTITY_ID_FORMAT +from homeassistant.components.googlehome import ( + CLIENT, DOMAIN as GOOGLEHOME_DOMAIN, NAME) +from homeassistant.const import DEVICE_CLASS_TIMESTAMP +from homeassistant.helpers.entity import Entity, async_generate_entity_id +import homeassistant.util.dt as dt_util + + +DEPENDENCIES = ['googlehome'] + +SCAN_INTERVAL = timedelta(seconds=10) + +_LOGGER = logging.getLogger(__name__) + +ICON = 'mdi:alarm' + +SENSOR_TYPES = { + 'timer': "Timer", + 'alarm': "Alarm", +} + + +async def async_setup_platform(hass, config, + async_add_entities, discovery_info=None): + """Set up the googlehome sensor platform.""" + if discovery_info is None: + _LOGGER.warning( + "To use this you need to configure the 'googlehome' component") + + devices = [] + for condition in SENSOR_TYPES: + device = GoogleHomeAlarm(hass.data[CLIENT], condition, + discovery_info) + devices.append(device) + + async_add_entities(devices, True) + + +class GoogleHomeAlarm(Entity): + """Representation of a GoogleHomeAlarm.""" + + def __init__(self, client, condition, config): + """Initialize the GoogleHomeAlarm sensor.""" + self._host = config['host'] + self._client = client + self._condition = condition + self._name = None + self._state = None + self._available = True + + async def async_added_to_hass(self): + """Subscribe GoogleHome events.""" + await self._client.update_info(self._host) + data = self.hass.data[GOOGLEHOME_DOMAIN][self._host] + info = data.get('info', {}) + if info is None: + return + self._name = "{} {}".format(info.get('name', NAME), + SENSOR_TYPES[self._condition]) + self.entity_id = async_generate_entity_id( + ENTITY_ID_FORMAT, self._name, hass=self.hass) + + async def async_update(self): + """Update the data.""" + await self._client.update_alarms(self._host) + data = self.hass.data[GOOGLEHOME_DOMAIN][self._host] + + alarms = data.get('alarms')[self._condition] + if not alarms: + self._available = False + return + self._available = True + time_date = dt_util.utc_from_timestamp(min(element['fire_time'] + for element in alarms) + / 1000) + self._state = time_date.isoformat() + + @property + def state(self): + """Return the state.""" + return self._state + + @property + def name(self): + """Return the name.""" + return self._name + + @property + def device_class(self): + """Return the device class.""" + return DEVICE_CLASS_TIMESTAMP + + @property + def available(self): + """Return the availability state.""" + return self._available + + @property + def icon(self): + """Return the icon.""" + return ICON