diff --git a/homeassistant/components/ihc/__init__.py b/homeassistant/components/ihc/__init__.py index bd45a52944cc8287f8dac18f07db7796d214f23d..daaf471e3182d9e2a5dd3a87ab0f79265b0bd0c5 100644 --- a/homeassistant/components/ihc/__init__.py +++ b/homeassistant/components/ihc/__init__.py @@ -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) diff --git a/homeassistant/components/ihc/const.py b/homeassistant/components/ihc/const.py index 69342c944ba7ad23f80a9025f697e87e76c5c0ea..2199a8a156e31508efe0371139f30ac55bd1f719 100644 --- a/homeassistant/components/ihc/const.py +++ b/homeassistant/components/ihc/const.py @@ -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' diff --git a/homeassistant/components/ihc/light.py b/homeassistant/components/ihc/light.py index 2590ea832221e0616c882821924bec3b6d3b00bc..646be7597d057c4af3c69de59eaee89e803c74d8 100644 --- a/homeassistant/components/ihc/light.py +++ b/homeassistant/components/ihc/light.py @@ -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) - - def turn_off(self, **kwargs) -> None: + 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) + + 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.""" diff --git a/homeassistant/components/ihc/services.yaml b/homeassistant/components/ihc/services.yaml index 0c63b32a618f7a9ea9f05c337257488e86ae86a8..0a78c45d7b23a3767cdd53eca42107c5c08b1f2c 100644 --- a/homeassistant/components/ihc/services.yaml +++ b/homeassistant/components/ihc/services.yaml @@ -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. \ No newline at end of file diff --git a/homeassistant/components/ihc/switch.py b/homeassistant/components/ihc/switch.py index bbab9d3e68c0cb6428f5a7504c37017176d1f736..d25b343446dd05f63af653d1b10ee97001312419 100644 --- a/homeassistant/components/ihc/switch.py +++ b/homeassistant/components/ihc/switch.py @@ -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.""" diff --git a/homeassistant/components/ihc/util.py b/homeassistant/components/ihc/util.py new file mode 100644 index 0000000000000000000000000000000000000000..a6780262f5eac0e9038c6953b9cee8eb07d92c5a --- /dev/null +++ b/homeassistant/components/ihc/util.py @@ -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)