diff --git a/homeassistant/components/lcn.py b/homeassistant/components/lcn.py index 597acb3bb02..f9ff9e64c3d 100644 --- a/homeassistant/components/lcn.py +++ b/homeassistant/components/lcn.py @@ -32,8 +32,10 @@ CONF_TRANSITION = 'transition' CONF_DIMMABLE = 'dimmable' CONF_CONNECTIONS = 'connections' -DIM_MODES = ['steps50', 'steps200'] -OUTPUT_PORTS = ['output1', 'output2', 'output3', 'output4'] +DIM_MODES = ['STEPS50', 'STEPS200'] +OUTPUT_PORTS = ['OUTPUT1', 'OUTPUT2', 'OUTPUT3', 'OUTPUT4'] +RELAY_PORTS = ['RELAY1', 'RELAY2', 'RELAY3', 'RELAY4', + 'RELAY5', 'RELAY6', 'RELAY7', 'RELAY8'] # Regex for address validation PATTERN_ADDRESS = re.compile('^((?P\\w+)\\.)?s?(?P\\d+)' @@ -85,7 +87,8 @@ def is_address(value): LIGHTS_SCHEMA = vol.Schema({ vol.Required(CONF_NAME): cv.string, vol.Required(CONF_ADDRESS): is_address, - vol.Required(CONF_OUTPUT): vol.All(vol.In(OUTPUT_PORTS), vol.Upper), + vol.Required(CONF_OUTPUT): vol.All(vol.Upper, + vol.In(OUTPUT_PORTS + RELAY_PORTS)), vol.Optional(CONF_DIMMABLE, default=False): vol.Coerce(bool), vol.Optional(CONF_TRANSITION, default=0): vol.All(vol.Coerce(float), vol.Range(min=0., max=486.), @@ -98,8 +101,8 @@ CONNECTION_SCHEMA = vol.Schema({ vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_PASSWORD): cv.string, vol.Optional(CONF_SK_NUM_TRIES, default=3): cv.positive_int, - vol.Optional(CONF_DIM_MODE, default='steps50'): vol.All(vol.In(DIM_MODES), - vol.Upper), + vol.Optional(CONF_DIM_MODE, default='steps50'): vol.All(vol.Upper, + vol.In(DIM_MODES)), vol.Optional(CONF_NAME): cv.string }) @@ -180,11 +183,11 @@ class LcnDevice(Entity): self._name = config[CONF_NAME] @property - def should_poll(self) -> bool: + def should_poll(self): """Lcn device entity pushes its state to HA.""" return False - async def async_added_to_hass(self) -> None: + async def async_added_to_hass(self): """Run when entity about to be added to hass.""" self.address_connection.register_for_inputs( self.input_received) diff --git a/homeassistant/components/light/lcn.py b/homeassistant/components/light/lcn.py index 3f00d305a14..f64eadaca5d 100644 --- a/homeassistant/components/light/lcn.py +++ b/homeassistant/components/light/lcn.py @@ -7,7 +7,7 @@ https://home-assistant.io/components/light.lcn/ from homeassistant.components.lcn import ( CONF_CONNECTIONS, CONF_DIMMABLE, CONF_OUTPUT, CONF_TRANSITION, DATA_LCN, - LcnDevice, get_connection) + OUTPUT_PORTS, LcnDevice, get_connection) from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_TRANSITION, SUPPORT_BRIGHTNESS, SUPPORT_TRANSITION, Light) @@ -29,7 +29,13 @@ async def async_setup_platform(hass, hass_config, async_add_entities, connection = get_connection(connections, connection_id) address_connection = connection.get_address_conn(addr) - devices.append(LcnOutputLight(config, address_connection)) + if config[CONF_OUTPUT] in OUTPUT_PORTS: + device = LcnOutputLight(config, address_connection) + else: # in RELAY_PORTS + device = LcnRelayLight(config, address_connection) + + devices.append(device) + async_add_entities(devices) @@ -50,7 +56,7 @@ class LcnOutputLight(LcnDevice, Light): self._is_on = None self._is_dimming_to_zero = False - async def async_added_to_hass(self) -> None: + async def async_added_to_hass(self): """Run when entity about to be added to hass.""" await super().async_added_to_hass() self.hass.async_create_task( @@ -119,3 +125,55 @@ class LcnOutputLight(LcnDevice, Light): if not self._is_dimming_to_zero: self._is_on = self.brightness > 0 self.async_schedule_update_ha_state() + + +class LcnRelayLight(LcnDevice, Light): + """Representation of a LCN light for relay ports.""" + + def __init__(self, config, address_connection): + """Initialize the LCN light.""" + super().__init__(config, address_connection) + + self.output = self.pypck.lcn_defs.RelayPort[config[CONF_OUTPUT]] + + self._is_on = None + + async def async_added_to_hass(self): + """Run when entity about to be added to hass.""" + await super().async_added_to_hass() + self.hass.async_create_task( + self.address_connection.activate_status_request_handler( + self.output)) + + @property + def is_on(self): + """Return True if entity is on.""" + return self._is_on + + async def async_turn_on(self, **kwargs): + """Turn the entity on.""" + self._is_on = True + + states = [self.pypck.lcn_defs.RelayStateModifier.NOCHANGE] * 8 + states[self.output.value] = self.pypck.lcn_defs.RelayStateModifier.ON + self.address_connection.control_relays(states) + + await self.async_update_ha_state() + + async def async_turn_off(self, **kwargs): + """Turn the entity off.""" + self._is_on = False + + states = [self.pypck.lcn_defs.RelayStateModifier.NOCHANGE] * 8 + states[self.output.value] = self.pypck.lcn_defs.RelayStateModifier.OFF + self.address_connection.control_relays(states) + + await self.async_update_ha_state() + + def input_received(self, input_obj): + """Set light state when LCN input object (command) is received.""" + if not isinstance(input_obj, self.pypck.inputs.ModStatusRelays): + return + + self._is_on = input_obj.get_state(self.output.value) + self.async_schedule_update_ha_state()