diff --git a/homeassistant/components/niko_home_control/light.py b/homeassistant/components/niko_home_control/light.py index b7ba5d33eb8..aabee41694c 100644 --- a/homeassistant/components/niko_home_control/light.py +++ b/homeassistant/components/niko_home_control/light.py @@ -1,53 +1,81 @@ """Support for Niko Home Control.""" +from datetime import timedelta import logging import voluptuous as vol +# Import the device class from the component that you want to support from homeassistant.components.light import ( ATTR_BRIGHTNESS, PLATFORM_SCHEMA, Light) -from homeassistant.const import CONF_HOST +from homeassistant.const import CONF_HOST, CONF_SCAN_INTERVAL from homeassistant.exceptions import PlatformNotReady import homeassistant.helpers.config_validation as cv +from homeassistant.util import Throttle _LOGGER = logging.getLogger(__name__) +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=1) +SCAN_INTERVAL = timedelta(seconds=30) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_HOST): cv.string, + vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period, }) -def setup_platform(hass, config, add_entities, discovery_info=None): +async def async_setup_platform( + hass, config, async_add_entities, discovery_info=None): """Set up the Niko Home Control light platform.""" import nikohomecontrol - host = config[CONF_HOST] try: - hub = nikohomecontrol.Hub({ + nhc = nikohomecontrol.NikoHomeControl({ 'ip': host, 'port': 8000, - 'timeout': 20000, - 'events': True + 'timeout': 20000 }) + niko_data = NikoHomeControlData(hass, nhc) + await niko_data.async_update() except OSError as err: _LOGGER.error("Unable to access %s (%s)", host, err) raise PlatformNotReady - add_entities( - [NikoHomeControlLight(light, hub) for light in hub.list_actions()], - True) + async_add_entities([ + NikoHomeControlLight(light, niko_data) for light in nhc.list_actions() + ], True) class NikoHomeControlLight(Light): """Representation of an Niko Light.""" - def __init__(self, light, nhc): + def __init__(self, light, data): """Set up the Niko Home Control light platform.""" - self._nhc = nhc + self._data = data self._light = light + self._unique_id = "light-{}".format(light.id) self._name = light.name - self._state = None + self._state = light.is_on self._brightness = None + _LOGGER.debug("Init new light: %s", light.name) + + @property + def unique_id(self): + """Return unique ID for light.""" + return self._unique_id + + @property + def device_info(self): + """Return device info for light.""" + return { + 'identifiers': { + ('niko_home_control', self.unique_id) + }, + 'name': self.name, + 'manufacturer': 'Niko group nv', + 'model': 'Niko connected controller', + 'sw_version': self._data.info_swversion(self._light), + 'via_hub': ('niko_home_control'), + } @property def name(self): @@ -64,16 +92,52 @@ class NikoHomeControlLight(Light): """Return true if light is on.""" return self._state - def turn_on(self, **kwargs): + async def async_turn_on(self, **kwargs): """Instruct the light to turn on.""" self._light.brightness = kwargs.get(ATTR_BRIGHTNESS, 255) - self._light.turn_on() + _LOGGER.debug('Turn on: %s', self.name) + await self._data.hass.async_add_executor_job(self._light.turn_on) - def turn_off(self, **kwargs): + async def async_turn_off(self, **kwargs): """Instruct the light to turn off.""" - self._light.turn_off() + _LOGGER.debug('Turn off: %s', self.name) + await self._data.hass.async_add_executor_job(self._light.turn_off) - def update(self): - """Fetch new state data for this light.""" - self._light.update() - self._state = self._light.is_on + async def async_update(self): + """Get the latest data from NikoHomeControl API.""" + await self._data.async_update() + self._state = self._data.get_state(self._light.id) + + +class NikoHomeControlData: + """The class for handling data retrieval.""" + + def __init__(self, hass, nhc): + """Set up Niko Home Control Data object.""" + self._nhc = nhc + self.hass = hass + self.available = True + self.data = {} + self._system_info = None + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + async def async_update(self): + """Get the latest data from the NikoHomeControl API.""" + _LOGGER.debug('Fetching async state in bulk') + try: + self.data = await self.hass.async_add_executor_job( + self._nhc.list_actions_raw) + self.available = True + except OSError as ex: + _LOGGER.error("Unable to retrieve data from Niko, %s", str(ex)) + self.available = False + + def get_state(self, aid): + """Find and filter state based on action id.""" + return next(filter(lambda a: a['id'] == aid, self.data))['value1'] != 0 + + def info_swversion(self, light): + """Return software version information.""" + if self._system_info is None: + self._system_info = self._nhc.system_info() + return self._system_info['swversion'] diff --git a/homeassistant/components/niko_home_control/manifest.json b/homeassistant/components/niko_home_control/manifest.json index 6f5ce87d8e1..c1c095f989a 100644 --- a/homeassistant/components/niko_home_control/manifest.json +++ b/homeassistant/components/niko_home_control/manifest.json @@ -3,7 +3,7 @@ "name": "Niko home control", "documentation": "https://www.home-assistant.io/components/niko_home_control", "requirements": [ - "niko-home-control==0.1.8" + "niko-home-control==0.2.0" ], "dependencies": [], "codeowners": [] diff --git a/requirements_all.txt b/requirements_all.txt index 92627b444f7..1e280eb69dd 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -740,7 +740,7 @@ netdisco==2.6.0 neurio==0.3.1 # homeassistant.components.niko_home_control -niko-home-control==0.1.8 +niko-home-control==0.2.0 # homeassistant.components.nilu niluclient==0.1.2