2019-04-03 15:40:03 +00:00
|
|
|
"""Support for FutureNow Ethernet unit outputs as Lights."""
|
2022-01-03 14:02:21 +00:00
|
|
|
from __future__ import annotations
|
|
|
|
|
2019-10-20 21:21:17 +00:00
|
|
|
import pyfnip
|
2018-07-27 09:11:32 +00:00
|
|
|
import voluptuous as vol
|
|
|
|
|
|
|
|
from homeassistant.components.light import (
|
2019-07-31 19:25:30 +00:00
|
|
|
ATTR_BRIGHTNESS,
|
2019-10-20 21:21:17 +00:00
|
|
|
PLATFORM_SCHEMA,
|
2019-07-31 19:25:30 +00:00
|
|
|
SUPPORT_BRIGHTNESS,
|
2020-04-26 16:49:41 +00:00
|
|
|
LightEntity,
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2019-10-20 21:21:17 +00:00
|
|
|
from homeassistant.const import CONF_DEVICES, CONF_HOST, CONF_NAME, CONF_PORT
|
2022-01-03 14:02:21 +00:00
|
|
|
from homeassistant.core import HomeAssistant
|
2018-07-27 09:11:32 +00:00
|
|
|
import homeassistant.helpers.config_validation as cv
|
2022-01-03 14:02:21 +00:00
|
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
|
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
2018-07-27 09:11:32 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
CONF_DRIVER = "driver"
|
|
|
|
CONF_DRIVER_FNIP6X10AD = "FNIP6x10ad"
|
|
|
|
CONF_DRIVER_FNIP8X10A = "FNIP8x10a"
|
2018-07-27 09:11:32 +00:00
|
|
|
CONF_DRIVER_TYPES = [CONF_DRIVER_FNIP6X10AD, CONF_DRIVER_FNIP8X10A]
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
DEVICE_SCHEMA = vol.Schema(
|
|
|
|
{
|
|
|
|
vol.Required(CONF_NAME): cv.string,
|
|
|
|
vol.Optional("dimmable", default=False): cv.boolean,
|
|
|
|
}
|
|
|
|
)
|
2018-07-27 09:11:32 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
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},
|
|
|
|
}
|
|
|
|
)
|
2018-07-27 09:11:32 +00:00
|
|
|
|
|
|
|
|
2022-01-03 14:02:21 +00:00
|
|
|
def setup_platform(
|
|
|
|
hass: HomeAssistant,
|
|
|
|
config: ConfigType,
|
|
|
|
add_entities: AddEntitiesCallback,
|
|
|
|
discovery_info: DiscoveryInfoType | None = None,
|
|
|
|
) -> None:
|
2018-07-27 09:11:32 +00:00
|
|
|
"""Set up the light platform for each FutureNow unit."""
|
|
|
|
lights = []
|
|
|
|
for channel, device_config in config[CONF_DEVICES].items():
|
|
|
|
device = {}
|
2019-07-31 19:25:30 +00:00
|
|
|
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]
|
2018-07-27 09:11:32 +00:00
|
|
|
lights.append(FutureNowLight(device))
|
|
|
|
|
2018-08-24 14:37:30 +00:00
|
|
|
add_entities(lights, True)
|
2018-07-27 09:11:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
def to_futurenow_level(level):
|
2020-01-05 12:09:17 +00:00
|
|
|
"""Convert the given Home Assistant light level (0-255) to FutureNow (0-100)."""
|
2021-02-15 11:33:13 +00:00
|
|
|
return round((level * 100) / 255)
|
2018-07-27 09:11:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
def to_hass_level(level):
|
2020-01-05 12:09:17 +00:00
|
|
|
"""Convert the given FutureNow (0-100) light level to Home Assistant (0-255)."""
|
2018-07-27 09:11:32 +00:00
|
|
|
return int((level * 255) / 100)
|
|
|
|
|
|
|
|
|
2020-04-26 16:49:41 +00:00
|
|
|
class FutureNowLight(LightEntity):
|
2018-07-27 09:11:32 +00:00
|
|
|
"""Representation of an FutureNow light."""
|
|
|
|
|
|
|
|
def __init__(self, device):
|
|
|
|
"""Initialize the light."""
|
2019-07-31 19:25:30 +00:00
|
|
|
self._name = device["name"]
|
|
|
|
self._dimmable = device["dimmable"]
|
|
|
|
self._channel = device["channel"]
|
2018-07-27 09:11:32 +00:00
|
|
|
self._brightness = None
|
2018-07-30 05:09:59 +00:00
|
|
|
self._last_brightness = 255
|
2018-07-27 09:11:32 +00:00
|
|
|
self._state = None
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
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
|
|
|
|
)
|
2018-07-27 09:11:32 +00:00
|
|
|
|
|
|
|
@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."""
|
2018-07-30 05:09:59 +00:00
|
|
|
if self._dimmable:
|
|
|
|
level = kwargs.get(ATTR_BRIGHTNESS, self._last_brightness)
|
|
|
|
else:
|
|
|
|
level = 255
|
2018-07-27 09:11:32 +00:00
|
|
|
self._light.turn_on(to_futurenow_level(level))
|
|
|
|
|
|
|
|
def turn_off(self, **kwargs):
|
|
|
|
"""Turn the light off."""
|
|
|
|
self._light.turn_off()
|
2018-07-30 05:09:59 +00:00
|
|
|
if self._brightness:
|
|
|
|
self._last_brightness = self._brightness
|
2018-07-27 09:11:32 +00:00
|
|
|
|
|
|
|
def update(self):
|
|
|
|
"""Fetch new state data for this light."""
|
|
|
|
state = int(self._light.is_on())
|
|
|
|
self._state = bool(state)
|
|
|
|
self._brightness = to_hass_level(state)
|