From a99b4472a8bfa63edf774765db3f1d1aecd57cdf Mon Sep 17 00:00:00 2001 From: Juha Niemi <juha.niemi@wunder.io> Date: Fri, 27 Jul 2018 12:11:32 +0300 Subject: [PATCH] Add support for P5 FutureNow light platform (#15662) * Added support for FutureNow light platform and relay/dimmer units * Pinned specific version for requirement * Added support for FutureNow light platform and relay/dimmer units * Added futurenow.py to .coveragerc. * Minor fixes and enhancements as requested in the code review. * Minor fixes and enhancements as requested in the code review. * Use device_config's value directly as it's validated as boolean. * Simplify state check. * Fixed brightness update that was broken in previous commit. --- .coveragerc | 1 + homeassistant/components/light/futurenow.py | 135 ++++++++++++++++++++ requirements_all.txt | 3 + 3 files changed, 139 insertions(+) create mode 100644 homeassistant/components/light/futurenow.py diff --git a/.coveragerc b/.coveragerc index 7e10830d876..84f4da0e371 100644 --- a/.coveragerc +++ b/.coveragerc @@ -465,6 +465,7 @@ omit = homeassistant/components/light/decora_wifi.py homeassistant/components/light/decora.py homeassistant/components/light/flux_led.py + homeassistant/components/light/futurenow.py homeassistant/components/light/greenwave.py homeassistant/components/light/hue.py homeassistant/components/light/hyperion.py diff --git a/homeassistant/components/light/futurenow.py b/homeassistant/components/light/futurenow.py new file mode 100644 index 00000000000..56ecaa7b2ca --- /dev/null +++ b/homeassistant/components/light/futurenow.py @@ -0,0 +1,135 @@ +""" +Support for FutureNow Ethernet unit outputs as Lights. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/light.futurenow/ +""" + +import logging + +import voluptuous as vol + +from homeassistant.const import ( + CONF_NAME, CONF_HOST, CONF_PORT, CONF_DEVICES) +from homeassistant.components.light import ( + ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, Light, + PLATFORM_SCHEMA) +import homeassistant.helpers.config_validation as cv + +REQUIREMENTS = ['pyfnip==0.1'] + +_LOGGER = logging.getLogger(__name__) + +CONF_DRIVER = 'driver' +CONF_DRIVER_FNIP6X10AD = 'FNIP6x10ad' +CONF_DRIVER_FNIP8X10A = 'FNIP8x10a' +CONF_DRIVER_TYPES = [CONF_DRIVER_FNIP6X10AD, CONF_DRIVER_FNIP8X10A] + +DEVICE_SCHEMA = vol.Schema({ + vol.Required(CONF_NAME): cv.string, + vol.Optional('dimmable', default=False): cv.boolean, +}) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_DRIVER): vol.In(CONF_DRIVER_TYPES), + vol.Required(CONF_HOST): cv.string, + vol.Required(CONF_PORT): cv.port, + vol.Required(CONF_DEVICES): {cv.string: DEVICE_SCHEMA}, +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up the light platform for each FutureNow unit.""" + lights = [] + for channel, device_config in config[CONF_DEVICES].items(): + device = {} + device['name'] = device_config[CONF_NAME] + device['dimmable'] = device_config['dimmable'] + device['channel'] = channel + device['driver'] = config[CONF_DRIVER] + device['host'] = config[CONF_HOST] + device['port'] = config[CONF_PORT] + lights.append(FutureNowLight(device)) + + add_devices(lights, True) + + +def to_futurenow_level(level): + """Convert the given HASS light level (0-255) to FutureNow (0-100).""" + return int((level * 100) / 255) + + +def to_hass_level(level): + """Convert the given FutureNow (0-100) light level to HASS (0-255).""" + return int((level * 255) / 100) + + +class FutureNowLight(Light): + """Representation of an FutureNow light.""" + + def __init__(self, device): + """Initialize the light.""" + import pyfnip + + self._name = device['name'] + self._dimmable = device['dimmable'] + self._channel = device['channel'] + self._brightness = None + self._state = None + self._skip_update = False + + if device['driver'] == CONF_DRIVER_FNIP6X10AD: + self._light = pyfnip.FNIP6x2adOutput(device['host'], + device['port'], + self._channel) + if device['driver'] == CONF_DRIVER_FNIP8X10A: + self._light = pyfnip.FNIP8x10aOutput(device['host'], + device['port'], + self._channel) + + @property + def name(self): + """Return the name of the device if any.""" + return self._name + + @property + def is_on(self): + """Return true if device is on.""" + return self._state + + @property + def brightness(self): + """Return the brightness of this light between 0..255.""" + return self._brightness + + @property + def supported_features(self): + """Flag supported features.""" + if self._dimmable: + return SUPPORT_BRIGHTNESS + return 0 + + def turn_on(self, **kwargs): + """Turn the light on.""" + level = kwargs.get(ATTR_BRIGHTNESS, 255) if self._dimmable else 255 + self._light.turn_on(to_futurenow_level(level)) + self._brightness = level + self._state = True + self._skip_update = True + + def turn_off(self, **kwargs): + """Turn the light off.""" + self._light.turn_off() + self._brightness = 0 + self._state = False + self._skip_update = True + + def update(self): + """Fetch new state data for this light.""" + if self._skip_update: + self._skip_update = False + return + + state = int(self._light.is_on()) + self._state = bool(state) + self._brightness = to_hass_level(state) diff --git a/requirements_all.txt b/requirements_all.txt index 3b89719651f..51ab8100372 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -825,6 +825,9 @@ pyflexit==0.3 # homeassistant.components.binary_sensor.flic pyflic-homeassistant==0.4.dev0 +# homeassistant.components.light.futurenow +pyfnip==0.1 + # homeassistant.components.fritzbox pyfritzhome==0.3.7 -- GitLab