mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Add separate on/off ids on manual configured IHC lights (#20253)
* Add support for separate on/off ids on manual configured IHC lights. This makes it easier to support IHC code units thats relies on being turned on and off through specific inputs. Also adds a pulse service (ihc.pulse) that supports sending a short on/off pulse to an IHC input. * Fix * Lint fix * Add on/off id support in switch * Make pulse async * Code review fixes
This commit is contained in:
parent
ee4be13bda
commit
0aba49adce
@ -7,9 +7,11 @@ import voluptuous as vol
|
||||
from homeassistant.components.binary_sensor import DEVICE_CLASSES_SCHEMA
|
||||
from homeassistant.components.ihc.const import (
|
||||
ATTR_IHC_ID, ATTR_VALUE, CONF_AUTOSETUP, CONF_BINARY_SENSOR, CONF_DIMMABLE,
|
||||
CONF_INFO, CONF_INVERTING, CONF_LIGHT, CONF_NODE, CONF_NOTE, CONF_POSITION,
|
||||
CONF_SENSOR, CONF_SWITCH, CONF_XPATH, SERVICE_SET_RUNTIME_VALUE_BOOL,
|
||||
SERVICE_SET_RUNTIME_VALUE_FLOAT, SERVICE_SET_RUNTIME_VALUE_INT)
|
||||
CONF_INFO, CONF_INVERTING, CONF_LIGHT, CONF_NODE, CONF_NOTE, CONF_OFF_ID,
|
||||
CONF_ON_ID, CONF_POSITION, CONF_SENSOR, CONF_SWITCH, CONF_XPATH,
|
||||
SERVICE_SET_RUNTIME_VALUE_BOOL, SERVICE_SET_RUNTIME_VALUE_FLOAT,
|
||||
SERVICE_SET_RUNTIME_VALUE_INT, SERVICE_PULSE)
|
||||
from homeassistant.components.ihc.util import async_pulse
|
||||
from homeassistant.config import load_yaml_config_file
|
||||
from homeassistant.const import (
|
||||
CONF_ID, CONF_NAME, CONF_PASSWORD, CONF_TYPE, CONF_UNIT_OF_MEASUREMENT,
|
||||
@ -50,7 +52,10 @@ DEVICE_SCHEMA = vol.Schema({
|
||||
})
|
||||
|
||||
|
||||
SWITCH_SCHEMA = DEVICE_SCHEMA.extend({})
|
||||
SWITCH_SCHEMA = DEVICE_SCHEMA.extend({
|
||||
vol.Optional(CONF_OFF_ID, default=0): cv.positive_int,
|
||||
vol.Optional(CONF_ON_ID, default=0): cv.positive_int,
|
||||
})
|
||||
|
||||
BINARY_SENSOR_SCHEMA = DEVICE_SCHEMA.extend({
|
||||
vol.Optional(CONF_INVERTING, default=False): cv.boolean,
|
||||
@ -59,6 +64,8 @@ BINARY_SENSOR_SCHEMA = DEVICE_SCHEMA.extend({
|
||||
|
||||
LIGHT_SCHEMA = DEVICE_SCHEMA.extend({
|
||||
vol.Optional(CONF_DIMMABLE, default=False): cv.boolean,
|
||||
vol.Optional(CONF_OFF_ID, default=0): cv.positive_int,
|
||||
vol.Optional(CONF_ON_ID, default=0): cv.positive_int,
|
||||
})
|
||||
|
||||
SENSOR_SCHEMA = DEVICE_SCHEMA.extend({
|
||||
@ -138,6 +145,10 @@ SET_RUNTIME_VALUE_FLOAT_SCHEMA = vol.Schema({
|
||||
vol.Required(ATTR_VALUE): vol.Coerce(float),
|
||||
})
|
||||
|
||||
PULSE_SCHEMA = vol.Schema({
|
||||
vol.Required(ATTR_IHC_ID): cv.positive_int,
|
||||
})
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
"""Set up the IHC platform."""
|
||||
@ -197,6 +208,8 @@ def get_manual_configuration(
|
||||
'product_cfg': {
|
||||
'type': sensor_cfg.get(CONF_TYPE),
|
||||
'inverting': sensor_cfg.get(CONF_INVERTING),
|
||||
'off_id': sensor_cfg.get(CONF_OFF_ID),
|
||||
'on_id': sensor_cfg.get(CONF_ON_ID),
|
||||
'dimmable': sensor_cfg.get(CONF_DIMMABLE),
|
||||
'unit_of_measurement': sensor_cfg.get(
|
||||
CONF_UNIT_OF_MEASUREMENT)
|
||||
@ -287,6 +300,11 @@ def setup_service_functions(hass: HomeAssistantType, ihc_controller):
|
||||
value = call.data[ATTR_VALUE]
|
||||
ihc_controller.set_runtime_value_float(ihc_id, value)
|
||||
|
||||
async def async_pulse_runtime_input(call):
|
||||
"""Pulse a IHC controller input function."""
|
||||
ihc_id = call.data[ATTR_IHC_ID]
|
||||
await async_pulse(hass, ihc_controller, ihc_id)
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_SET_RUNTIME_VALUE_BOOL,
|
||||
set_runtime_value_bool,
|
||||
schema=SET_RUNTIME_VALUE_BOOL_SCHEMA)
|
||||
@ -296,3 +314,6 @@ def setup_service_functions(hass: HomeAssistantType, ihc_controller):
|
||||
hass.services.register(DOMAIN, SERVICE_SET_RUNTIME_VALUE_FLOAT,
|
||||
set_runtime_value_float,
|
||||
schema=SET_RUNTIME_VALUE_FLOAT_SCHEMA)
|
||||
hass.services.register(DOMAIN, SERVICE_PULSE,
|
||||
async_pulse_runtime_input,
|
||||
schema=PULSE_SCHEMA)
|
||||
|
@ -9,6 +9,8 @@ CONF_LIGHT = 'light'
|
||||
CONF_NAME = 'name'
|
||||
CONF_NODE = 'node'
|
||||
CONF_NOTE = 'note'
|
||||
CONF_OFF_ID = 'off_id'
|
||||
CONF_ON_ID = 'on_id'
|
||||
CONF_POSITION = 'position'
|
||||
CONF_SENSOR = 'sensor'
|
||||
CONF_SWITCH = 'switch'
|
||||
@ -20,3 +22,4 @@ ATTR_VALUE = 'value'
|
||||
SERVICE_SET_RUNTIME_VALUE_BOOL = 'set_runtime_value_bool'
|
||||
SERVICE_SET_RUNTIME_VALUE_FLOAT = 'set_runtime_value_float'
|
||||
SERVICE_SET_RUNTIME_VALUE_INT = 'set_runtime_value_int'
|
||||
SERVICE_PULSE = 'pulse'
|
||||
|
@ -2,7 +2,10 @@
|
||||
import logging
|
||||
|
||||
from homeassistant.components.ihc import IHC_CONTROLLER, IHC_DATA, IHC_INFO
|
||||
from homeassistant.components.ihc.const import CONF_DIMMABLE
|
||||
from homeassistant.components.ihc.const import (
|
||||
CONF_DIMMABLE, CONF_OFF_ID, CONF_ON_ID)
|
||||
from homeassistant.components.ihc.util import (
|
||||
async_pulse, async_set_bool, async_set_int)
|
||||
from homeassistant.components.ihc.ihcdevice import IHCDevice
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, Light)
|
||||
@ -26,9 +29,11 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
ihc_key = IHC_DATA.format(ctrl_id)
|
||||
info = hass.data[ihc_key][IHC_INFO]
|
||||
ihc_controller = hass.data[ihc_key][IHC_CONTROLLER]
|
||||
ihc_off_id = product_cfg.get(CONF_OFF_ID)
|
||||
ihc_on_id = product_cfg.get(CONF_ON_ID)
|
||||
dimmable = product_cfg[CONF_DIMMABLE]
|
||||
light = IhcLight(ihc_controller, name, ihc_id, info,
|
||||
dimmable, product)
|
||||
light = IhcLight(ihc_controller, name, ihc_id, ihc_off_id, ihc_on_id,
|
||||
info, dimmable, product)
|
||||
devices.append(light)
|
||||
add_entities(devices)
|
||||
|
||||
@ -41,10 +46,13 @@ class IhcLight(IHCDevice, Light):
|
||||
an on/off (boolean) resource
|
||||
"""
|
||||
|
||||
def __init__(self, ihc_controller, name, ihc_id: int, info: bool,
|
||||
dimmable=False, product=None) -> None:
|
||||
def __init__(self, ihc_controller, name, ihc_id: int, ihc_off_id: int,
|
||||
ihc_on_id: int, info: bool, dimmable=False,
|
||||
product=None) -> None:
|
||||
"""Initialize the light."""
|
||||
super().__init__(ihc_controller, name, ihc_id, info, product)
|
||||
self._ihc_off_id = ihc_off_id
|
||||
self._ihc_on_id = ihc_on_id
|
||||
self._brightness = 0
|
||||
self._dimmable = dimmable
|
||||
self._state = None
|
||||
@ -66,7 +74,7 @@ class IhcLight(IHCDevice, Light):
|
||||
return SUPPORT_BRIGHTNESS
|
||||
return 0
|
||||
|
||||
def turn_on(self, **kwargs) -> None:
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Turn the light on."""
|
||||
if ATTR_BRIGHTNESS in kwargs:
|
||||
brightness = kwargs[ATTR_BRIGHTNESS]
|
||||
@ -76,17 +84,28 @@ class IhcLight(IHCDevice, Light):
|
||||
brightness = 255
|
||||
|
||||
if self._dimmable:
|
||||
self.ihc_controller.set_runtime_value_int(
|
||||
self.ihc_id, int(brightness * 100 / 255))
|
||||
await async_set_int(self.hass, self.ihc_controller,
|
||||
self.ihc_id, int(brightness * 100 / 255))
|
||||
else:
|
||||
self.ihc_controller.set_runtime_value_bool(self.ihc_id, True)
|
||||
if self._ihc_on_id:
|
||||
await async_pulse(self.hass, self.ihc_controller,
|
||||
self._ihc_on_id)
|
||||
else:
|
||||
await async_set_bool(self.hass, self.ihc_controller,
|
||||
self.ihc_id, True)
|
||||
|
||||
def turn_off(self, **kwargs) -> None:
|
||||
async def async_turn_off(self, **kwargs):
|
||||
"""Turn the light off."""
|
||||
if self._dimmable:
|
||||
self.ihc_controller.set_runtime_value_int(self.ihc_id, 0)
|
||||
await async_set_int(self.hass, self.ihc_controller,
|
||||
self.ihc_id, 0)
|
||||
else:
|
||||
self.ihc_controller.set_runtime_value_bool(self.ihc_id, False)
|
||||
if self._ihc_off_id:
|
||||
await async_pulse(self.hass, self.ihc_controller,
|
||||
self._ihc_off_id)
|
||||
else:
|
||||
await async_set_bool(self.hass, self.ihc_controller,
|
||||
self.ihc_id, False)
|
||||
|
||||
def on_ihc_change(self, ihc_id, value):
|
||||
"""Handle IHC notifications."""
|
||||
|
@ -24,3 +24,8 @@ set_runtime_value_float:
|
||||
value:
|
||||
description: The float value to set.
|
||||
|
||||
pulse:
|
||||
description: Pulses an input on the IHC controller.
|
||||
fields:
|
||||
ihc_id:
|
||||
description: The integer IHC resource ID.
|
@ -1,5 +1,7 @@
|
||||
"""Support for IHC switches."""
|
||||
from homeassistant.components.ihc import IHC_CONTROLLER, IHC_DATA, IHC_INFO
|
||||
from homeassistant.components.ihc.const import CONF_OFF_ID, CONF_ON_ID
|
||||
from homeassistant.components.ihc.util import async_pulse, async_set_bool
|
||||
from homeassistant.components.ihc.ihcdevice import IHCDevice
|
||||
from homeassistant.components.switch import SwitchDevice
|
||||
|
||||
@ -13,14 +15,18 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
devices = []
|
||||
for name, device in discovery_info.items():
|
||||
ihc_id = device['ihc_id']
|
||||
product_cfg = device['product_cfg']
|
||||
product = device['product']
|
||||
# Find controller that corresponds with device id
|
||||
ctrl_id = device['ctrl_id']
|
||||
ihc_key = IHC_DATA.format(ctrl_id)
|
||||
info = hass.data[ihc_key][IHC_INFO]
|
||||
ihc_controller = hass.data[ihc_key][IHC_CONTROLLER]
|
||||
ihc_off_id = product_cfg.get(CONF_OFF_ID)
|
||||
ihc_on_id = product_cfg.get(CONF_ON_ID)
|
||||
|
||||
switch = IHCSwitch(ihc_controller, name, ihc_id, info, product)
|
||||
switch = IHCSwitch(ihc_controller, name, ihc_id, ihc_off_id, ihc_on_id,
|
||||
info, product)
|
||||
devices.append(switch)
|
||||
add_entities(devices)
|
||||
|
||||
@ -28,10 +34,12 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
class IHCSwitch(IHCDevice, SwitchDevice):
|
||||
"""Representation of an IHC switch."""
|
||||
|
||||
def __init__(self, ihc_controller, name: str, ihc_id: int,
|
||||
info: bool, product=None) -> None:
|
||||
def __init__(self, ihc_controller, name: str, ihc_id: int, ihc_off_id: int,
|
||||
ihc_on_id: int, info: bool, product=None) -> None:
|
||||
"""Initialize the IHC switch."""
|
||||
super().__init__(ihc_controller, name, ihc_id, product)
|
||||
self._ihc_off_id = ihc_off_id
|
||||
self._ihc_on_id = ihc_on_id
|
||||
self._state = False
|
||||
|
||||
@property
|
||||
@ -39,13 +47,21 @@ class IHCSwitch(IHCDevice, SwitchDevice):
|
||||
"""Return true if switch is on."""
|
||||
return self._state
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Turn the switch on."""
|
||||
self.ihc_controller.set_runtime_value_bool(self.ihc_id, True)
|
||||
if self._ihc_on_id:
|
||||
await async_pulse(self.hass, self.ihc_controller, self._ihc_on_id)
|
||||
else:
|
||||
await async_set_bool(self.hass, self.ihc_controller,
|
||||
self.ihc_id, True)
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
async def async_turn_off(self, **kwargs):
|
||||
"""Turn the device off."""
|
||||
self.ihc_controller.set_runtime_value_bool(self.ihc_id, False)
|
||||
if self._ihc_off_id:
|
||||
await async_pulse(self.hass, self.ihc_controller, self._ihc_off_id)
|
||||
else:
|
||||
await async_set_bool(self.hass, self.ihc_controller,
|
||||
self.ihc_id, False)
|
||||
|
||||
def on_ihc_change(self, ihc_id, value):
|
||||
"""Handle IHC resource change."""
|
||||
|
22
homeassistant/components/ihc/util.py
Normal file
22
homeassistant/components/ihc/util.py
Normal file
@ -0,0 +1,22 @@
|
||||
"""Useful functions for the IHC component."""
|
||||
|
||||
import asyncio
|
||||
|
||||
|
||||
async def async_pulse(hass, ihc_controller, ihc_id: int):
|
||||
"""Send a short on/off pulse to an IHC controller resource."""
|
||||
await async_set_bool(hass, ihc_controller, ihc_id, True)
|
||||
await asyncio.sleep(0.1)
|
||||
await async_set_bool(hass, ihc_controller, ihc_id, False)
|
||||
|
||||
|
||||
def async_set_bool(hass, ihc_controller, ihc_id: int, value: bool):
|
||||
"""Set a bool value on an IHC controller resource."""
|
||||
return hass.async_add_executor_job(ihc_controller.set_runtime_value_bool,
|
||||
ihc_id, value)
|
||||
|
||||
|
||||
def async_set_int(hass, ihc_controller, ihc_id: int, value: int):
|
||||
"""Set a int value on an IHC controller resource."""
|
||||
return hass.async_add_executor_job(ihc_controller.set_runtime_value_int,
|
||||
ihc_id, value)
|
Loading…
x
Reference in New Issue
Block a user