Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix niko_home_control integration #23093

Merged
merged 1 commit into from
Apr 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 84 additions & 20 deletions homeassistant/components/niko_home_control/light.py
Original file line number Diff line number Diff line change
@@ -1,53 +1,81 @@
"""Support for Niko Home Control."""
from datetime import timedelta
awarecan marked this conversation as resolved.
Show resolved Hide resolved
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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already part of the base platform schema.

})


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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We try to avoid side effects in init method. Move the logging out of init.


@property
def unique_id(self):
"""Return unique ID for light."""
return self._unique_id

@property
def device_info(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

device_info property is only read if the platform is loaded via config entry.

https://developers.home-assistant.io/docs/en/device_registry_index.html#defining-devices

"""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):
Expand All @@ -64,16 +92,52 @@ def is_on(self):
"""Return true if light is on."""
return self._state

def turn_on(self, **kwargs):
async def async_turn_on(self, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change to async api? The device library doesn't support asyncio.

"""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)

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)


def update(self):
"""Fetch new state data for this light."""
self._light.update()
self._state = self._light.is_on
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use filter + lambda. Use a generator expression.


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']
2 changes: 1 addition & 1 deletion homeassistant/components/niko_home_control/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": []
Expand Down
2 changes: 1 addition & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down