LCN cover control via output ports (#25511)
* LCN motor control via oputput ports * Remove default value from cover validator
This commit is contained in:
parent
dc722adbb5
commit
c4f673c894
5 changed files with 100 additions and 17 deletions
|
@ -4,23 +4,23 @@ import logging
|
|||
import pypck
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.components.climate import DEFAULT_MAX_TEMP, DEFAULT_MIN_TEMP
|
||||
from homeassistant.const import (
|
||||
CONF_ADDRESS, CONF_BINARY_SENSORS, CONF_COVERS, CONF_HOST, CONF_LIGHTS,
|
||||
CONF_NAME, CONF_PASSWORD, CONF_PORT, CONF_SENSORS, CONF_SWITCHES,
|
||||
CONF_UNIT_OF_MEASUREMENT, CONF_USERNAME, TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.discovery import async_load_platform
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from .const import (
|
||||
BINSENSOR_PORTS, CONF_CLIMATES, CONF_CONNECTIONS, CONF_DIM_MODE,
|
||||
CONF_DIMMABLE, CONF_LOCKABLE, CONF_MAX_TEMP, CONF_MIN_TEMP, CONF_MOTOR,
|
||||
CONF_OUTPUT, CONF_OUTPUTS, CONF_REGISTER, CONF_SCENE, CONF_SCENES,
|
||||
CONF_SETPOINT, CONF_SK_NUM_TRIES, CONF_SOURCE, CONF_TRANSITION, DATA_LCN,
|
||||
DIM_MODES, DOMAIN, KEYS, LED_PORTS, LOGICOP_PORTS, MOTOR_PORTS,
|
||||
OUTPUT_PORTS, RELAY_PORTS, S0_INPUTS, SETPOINTS, THRESHOLDS, VAR_UNITS,
|
||||
VARIABLES)
|
||||
CONF_OUTPUT, CONF_OUTPUTS, CONF_REGISTER, CONF_REVERSE_TIME, CONF_SCENE,
|
||||
CONF_SCENES, CONF_SETPOINT, CONF_SK_NUM_TRIES, CONF_SOURCE,
|
||||
CONF_TRANSITION, DATA_LCN, DIM_MODES, DOMAIN, KEYS, LED_PORTS,
|
||||
LOGICOP_PORTS, MOTOR_PORTS, MOTOR_REVERSE_TIME, OUTPUT_PORTS, RELAY_PORTS,
|
||||
S0_INPUTS, SETPOINTS, THRESHOLDS, VAR_UNITS, VARIABLES)
|
||||
from .helpers import has_unique_connection_names, is_address
|
||||
from .services import (
|
||||
DynText, Led, LockKeys, LockRegulator, OutputAbs, OutputRel, OutputToggle,
|
||||
|
@ -51,7 +51,9 @@ CLIMATES_SCHEMA = vol.Schema({
|
|||
COVERS_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_NAME): cv.string,
|
||||
vol.Required(CONF_ADDRESS): is_address,
|
||||
vol.Required(CONF_MOTOR): vol.All(vol.Upper, vol.In(MOTOR_PORTS))
|
||||
vol.Required(CONF_MOTOR): vol.All(vol.Upper, vol.In(MOTOR_PORTS)),
|
||||
vol.Optional(CONF_REVERSE_TIME): vol.All(vol.Upper,
|
||||
vol.In(MOTOR_REVERSE_TIME))
|
||||
})
|
||||
|
||||
LIGHTS_SCHEMA = vol.Schema({
|
||||
|
|
|
@ -36,6 +36,7 @@ CONF_SCENES = 'scenes'
|
|||
CONF_REGISTER = 'register'
|
||||
CONF_SCENE = 'scene'
|
||||
CONF_OUTPUTS = 'outputs'
|
||||
CONF_REVERSE_TIME = 'reverse_time'
|
||||
|
||||
DIM_MODES = ['STEPS50', 'STEPS200']
|
||||
|
||||
|
@ -46,7 +47,7 @@ RELAY_PORTS = ['RELAY1', 'RELAY2', 'RELAY3', 'RELAY4',
|
|||
'MOTORONOFF1', 'MOTORUPDOWN1', 'MOTORONOFF2', 'MOTORUPDOWN2',
|
||||
'MOTORONOFF3', 'MOTORUPDOWN3', 'MOTORONOFF4', 'MOTORUPDOWN4']
|
||||
|
||||
MOTOR_PORTS = ['MOTOR1', 'MOTOR2', 'MOTOR3', 'MOTOR4']
|
||||
MOTOR_PORTS = ['MOTOR1', 'MOTOR2', 'MOTOR3', 'MOTOR4', 'OUTPUTS']
|
||||
|
||||
LED_PORTS = ['LED1', 'LED2', 'LED3', 'LED4', 'LED5', 'LED6',
|
||||
'LED7', 'LED8', 'LED9', 'LED10', 'LED11', 'LED12']
|
||||
|
@ -96,3 +97,5 @@ TIME_UNITS = ['SECONDS', 'SECOND', 'SEC', 'S',
|
|||
'MINUTES', 'MINUTE', 'MIN', 'M',
|
||||
'HOURS', 'HOUR', 'H',
|
||||
'DAYS', 'DAY', 'D']
|
||||
|
||||
MOTOR_REVERSE_TIME = ['RT70', 'RT600', 'RT1200']
|
||||
|
|
|
@ -5,7 +5,7 @@ from homeassistant.components.cover import CoverDevice
|
|||
from homeassistant.const import CONF_ADDRESS
|
||||
|
||||
from . import LcnDevice
|
||||
from .const import CONF_CONNECTIONS, CONF_MOTOR, DATA_LCN
|
||||
from .const import CONF_CONNECTIONS, CONF_MOTOR, CONF_REVERSE_TIME, DATA_LCN
|
||||
from .helpers import get_connection
|
||||
|
||||
|
||||
|
@ -23,13 +23,91 @@ 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(LcnCover(config, address_connection))
|
||||
if config[CONF_MOTOR] == 'OUTPUTS':
|
||||
devices.append(LcnOutputsCover(config, address_connection))
|
||||
else: # RELAYS
|
||||
devices.append(LcnRelayCover(config, address_connection))
|
||||
|
||||
async_add_entities(devices)
|
||||
|
||||
|
||||
class LcnCover(LcnDevice, CoverDevice):
|
||||
"""Representation of a LCN cover."""
|
||||
class LcnOutputsCover(LcnDevice, CoverDevice):
|
||||
"""Representation of a LCN cover connected to output ports."""
|
||||
|
||||
def __init__(self, config, address_connection):
|
||||
"""Initialize the LCN cover."""
|
||||
super().__init__(config, address_connection)
|
||||
|
||||
self.output_ids = [pypck.lcn_defs.OutputPort['OUTPUTUP'].value,
|
||||
pypck.lcn_defs.OutputPort['OUTPUTDOWN'].value]
|
||||
if CONF_REVERSE_TIME in config:
|
||||
self.reverse_time = pypck.lcn_defs.MotorReverseTime[
|
||||
config[CONF_REVERSE_TIME]]
|
||||
else:
|
||||
self.reverse_time = None
|
||||
self._closed = None
|
||||
self.state_up = False
|
||||
self.state_down = False
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Run when entity about to be added to hass."""
|
||||
await super().async_added_to_hass()
|
||||
await self.address_connection.activate_status_request_handler(
|
||||
pypck.lcn_defs.OutputPort['OUTPUTUP'])
|
||||
await self.address_connection.activate_status_request_handler(
|
||||
pypck.lcn_defs.OutputPort['OUTPUTDOWN'])
|
||||
|
||||
@property
|
||||
def is_closed(self):
|
||||
"""Return if the cover is closed."""
|
||||
return self._closed
|
||||
|
||||
async def async_close_cover(self, **kwargs):
|
||||
"""Close the cover."""
|
||||
self._closed = True
|
||||
|
||||
state = pypck.lcn_defs.MotorStateModifier.DOWN
|
||||
self.address_connection.control_motors_outputs(
|
||||
state)
|
||||
await self.async_update_ha_state()
|
||||
|
||||
async def async_open_cover(self, **kwargs):
|
||||
"""Open the cover."""
|
||||
self._closed = False
|
||||
state = pypck.lcn_defs.MotorStateModifier.UP
|
||||
self.address_connection.control_motors_outputs(
|
||||
state, self.reverse_time)
|
||||
await self.async_update_ha_state()
|
||||
|
||||
async def async_stop_cover(self, **kwargs):
|
||||
"""Stop the cover."""
|
||||
self._closed = None
|
||||
state = pypck.lcn_defs.MotorStateModifier.STOP
|
||||
self.address_connection.control_motors_outputs(
|
||||
state, self.reverse_time)
|
||||
await self.async_update_ha_state()
|
||||
|
||||
def input_received(self, input_obj):
|
||||
"""Set cover states when LCN input object (command) is received."""
|
||||
if not isinstance(input_obj, pypck.inputs.ModStatusOutput) or \
|
||||
input_obj.get_output_id() not in self.output_ids:
|
||||
return
|
||||
|
||||
if input_obj.get_output_id() == self.output_ids[0]:
|
||||
self.state_up = (input_obj.get_percent() > 0)
|
||||
else: # self.output_ids[1]
|
||||
self.state_down = (input_obj.get_percent() > 0)
|
||||
|
||||
if self.state_up and not self.state_down:
|
||||
self._closed = False # Cover open
|
||||
elif self.state_down and not self.state_up:
|
||||
self._closed = True # Cover closed
|
||||
|
||||
self.async_schedule_update_ha_state()
|
||||
|
||||
|
||||
class LcnRelayCover(LcnDevice, CoverDevice):
|
||||
"""Representation of a LCN cover connected to relays."""
|
||||
|
||||
def __init__(self, config, address_connection):
|
||||
"""Initialize the LCN cover."""
|
||||
|
@ -57,7 +135,7 @@ class LcnCover(LcnDevice, CoverDevice):
|
|||
self._closed = True
|
||||
states = [pypck.lcn_defs.MotorStateModifier.NOCHANGE] * 4
|
||||
states[self.motor.value] = pypck.lcn_defs.MotorStateModifier.DOWN
|
||||
self.address_connection.control_motors(states)
|
||||
self.address_connection.control_motors_relays(states)
|
||||
await self.async_update_ha_state()
|
||||
|
||||
async def async_open_cover(self, **kwargs):
|
||||
|
@ -65,7 +143,7 @@ class LcnCover(LcnDevice, CoverDevice):
|
|||
self._closed = False
|
||||
states = [pypck.lcn_defs.MotorStateModifier.NOCHANGE] * 4
|
||||
states[self.motor.value] = pypck.lcn_defs.MotorStateModifier.UP
|
||||
self.address_connection.control_motors(states)
|
||||
self.address_connection.control_motors_relays(states)
|
||||
await self.async_update_ha_state()
|
||||
|
||||
async def async_stop_cover(self, **kwargs):
|
||||
|
@ -73,7 +151,7 @@ class LcnCover(LcnDevice, CoverDevice):
|
|||
self._closed = None
|
||||
states = [pypck.lcn_defs.MotorStateModifier.NOCHANGE] * 4
|
||||
states[self.motor.value] = pypck.lcn_defs.MotorStateModifier.STOP
|
||||
self.address_connection.control_motors(states)
|
||||
self.address_connection.control_motors_relays(states)
|
||||
await self.async_update_ha_state()
|
||||
|
||||
def input_received(self, input_obj):
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Lcn",
|
||||
"documentation": "https://www.home-assistant.io/components/lcn",
|
||||
"requirements": [
|
||||
"pypck==0.6.2"
|
||||
"pypck==0.6.3"
|
||||
],
|
||||
"dependencies": [],
|
||||
"codeowners": [
|
||||
|
|
|
@ -1330,7 +1330,7 @@ pyowm==2.10.0
|
|||
pypca==0.0.4
|
||||
|
||||
# homeassistant.components.lcn
|
||||
pypck==0.6.2
|
||||
pypck==0.6.3
|
||||
|
||||
# homeassistant.components.pjlink
|
||||
pypjlink2==1.2.0
|
||||
|
|
Loading…
Add table
Reference in a new issue