diff --git a/.coveragerc b/.coveragerc
index 8608d30236d66aaa97912971a6fda2eb0aa4ecc0..e4d5bca95d36a3c46da89726d4a0ad5230bed290 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -97,6 +97,9 @@ omit =
     homeassistant/components/homematic/__init__.py
     homeassistant/components/*/homematic.py
 
+    homeassistant/components/ihc/*
+    homeassistant/components/*/ihc.py
+
     homeassistant/components/insteon_local.py
     homeassistant/components/*/insteon_local.py
 
diff --git a/homeassistant/components/binary_sensor/ihc.py b/homeassistant/components/binary_sensor/ihc.py
new file mode 100644
index 0000000000000000000000000000000000000000..14e45f88cf1fb0d1d1ad337a5c5a79d9d63741ba
--- /dev/null
+++ b/homeassistant/components/binary_sensor/ihc.py
@@ -0,0 +1,95 @@
+"""IHC binary sensor platform.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/binary_sensor.ihc/
+"""
+from xml.etree.ElementTree import Element
+
+import voluptuous as vol
+
+from homeassistant.components.binary_sensor import (
+    BinarySensorDevice, PLATFORM_SCHEMA, DEVICE_CLASSES_SCHEMA)
+from homeassistant.components.ihc import (
+    validate_name, IHC_DATA, IHC_CONTROLLER, IHC_INFO)
+from homeassistant.components.ihc.const import CONF_INVERTING
+from homeassistant.components.ihc.ihcdevice import IHCDevice
+from homeassistant.const import (
+    CONF_NAME, CONF_TYPE, CONF_ID, CONF_BINARY_SENSORS)
+import homeassistant.helpers.config_validation as cv
+
+DEPENDENCIES = ['ihc']
+
+PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
+    vol.Optional(CONF_BINARY_SENSORS, default=[]):
+        vol.All(cv.ensure_list, [
+            vol.All({
+                vol.Required(CONF_ID): cv.positive_int,
+                vol.Optional(CONF_NAME): cv.string,
+                vol.Optional(CONF_TYPE, default=None): DEVICE_CLASSES_SCHEMA,
+                vol.Optional(CONF_INVERTING, default=False): cv.boolean,
+            }, validate_name)
+        ])
+})
+
+
+def setup_platform(hass, config, add_devices, discovery_info=None):
+    """Set up the IHC binary sensor platform."""
+    ihc_controller = hass.data[IHC_DATA][IHC_CONTROLLER]
+    info = hass.data[IHC_DATA][IHC_INFO]
+    devices = []
+    if discovery_info:
+        for name, device in discovery_info.items():
+            ihc_id = device['ihc_id']
+            product_cfg = device['product_cfg']
+            product = device['product']
+            sensor = IHCBinarySensor(ihc_controller, name, ihc_id, info,
+                                     product_cfg[CONF_TYPE],
+                                     product_cfg[CONF_INVERTING],
+                                     product)
+            devices.append(sensor)
+    else:
+        binary_sensors = config[CONF_BINARY_SENSORS]
+        for sensor_cfg in binary_sensors:
+            ihc_id = sensor_cfg[CONF_ID]
+            name = sensor_cfg[CONF_NAME]
+            sensor_type = sensor_cfg[CONF_TYPE]
+            inverting = sensor_cfg[CONF_INVERTING]
+            sensor = IHCBinarySensor(ihc_controller, name, ihc_id, info,
+                                     sensor_type, inverting)
+            devices.append(sensor)
+
+    add_devices(devices)
+
+
+class IHCBinarySensor(IHCDevice, BinarySensorDevice):
+    """IHC Binary Sensor.
+
+    The associated IHC resource can be any in or output from a IHC product
+    or function block, but it must be a boolean ON/OFF resources.
+    """
+
+    def __init__(self, ihc_controller, name, ihc_id: int, info: bool,
+                 sensor_type: str, inverting: bool, product: Element=None):
+        """Initialize the IHC binary sensor."""
+        super().__init__(ihc_controller, name, ihc_id, info, product)
+        self._state = None
+        self._sensor_type = sensor_type
+        self.inverting = inverting
+
+    @property
+    def device_class(self):
+        """Return the class of this sensor."""
+        return self._sensor_type
+
+    @property
+    def is_on(self):
+        """Return true if the binary sensor is on/open."""
+        return self._state
+
+    def on_ihc_change(self, ihc_id, value):
+        """IHC resource has changed."""
+        if self.inverting:
+            self._state = not value
+        else:
+            self._state = value
+        self.schedule_update_ha_state()
diff --git a/homeassistant/components/ihc/__init__.py b/homeassistant/components/ihc/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..f3cd9d790466a5dbfb2ecb2d3841780b8b0bb3a2
--- /dev/null
+++ b/homeassistant/components/ihc/__init__.py
@@ -0,0 +1,213 @@
+"""IHC component.
+
+For more details about this component, please refer to the documentation at
+https://home-assistant.io/components/ihc/
+"""
+import logging
+import os.path
+import xml.etree.ElementTree
+import voluptuous as vol
+
+from homeassistant.components.ihc.const import (
+    ATTR_IHC_ID, ATTR_VALUE, CONF_INFO, CONF_AUTOSETUP,
+    CONF_BINARY_SENSOR, CONF_LIGHT, CONF_SENSOR, CONF_SWITCH,
+    CONF_XPATH, CONF_NODE, CONF_DIMMABLE, CONF_INVERTING,
+    SERVICE_SET_RUNTIME_VALUE_BOOL, SERVICE_SET_RUNTIME_VALUE_INT,
+    SERVICE_SET_RUNTIME_VALUE_FLOAT)
+from homeassistant.config import load_yaml_config_file
+from homeassistant.const import (
+    CONF_URL, CONF_USERNAME, CONF_PASSWORD, CONF_ID, CONF_NAME,
+    CONF_UNIT_OF_MEASUREMENT, CONF_TYPE, TEMP_CELSIUS)
+from homeassistant.helpers import discovery
+import homeassistant.helpers.config_validation as cv
+from homeassistant.helpers.typing import HomeAssistantType
+
+REQUIREMENTS = ['ihcsdk==2.1.1']
+
+DOMAIN = 'ihc'
+IHC_DATA = 'ihc'
+IHC_CONTROLLER = 'controller'
+IHC_INFO = 'info'
+AUTO_SETUP_YAML = 'ihc_auto_setup.yaml'
+
+CONFIG_SCHEMA = vol.Schema({
+    DOMAIN: vol.Schema({
+        vol.Required(CONF_URL): cv.string,
+        vol.Required(CONF_USERNAME): cv.string,
+        vol.Required(CONF_PASSWORD): cv.string,
+        vol.Optional(CONF_AUTOSETUP, default=True): cv.boolean,
+        vol.Optional(CONF_INFO, default=True): cv.boolean
+    }),
+}, extra=vol.ALLOW_EXTRA)
+
+AUTO_SETUP_SCHEMA = vol.Schema({
+    vol.Optional(CONF_BINARY_SENSOR, default=[]):
+        vol.All(cv.ensure_list, [
+            vol.All({
+                vol.Required(CONF_XPATH): cv.string,
+                vol.Required(CONF_NODE): cv.string,
+                vol.Optional(CONF_TYPE, default=None): cv.string,
+                vol.Optional(CONF_INVERTING, default=False): cv.boolean,
+            })
+        ]),
+    vol.Optional(CONF_LIGHT, default=[]):
+        vol.All(cv.ensure_list, [
+            vol.All({
+                vol.Required(CONF_XPATH): cv.string,
+                vol.Required(CONF_NODE): cv.string,
+                vol.Optional(CONF_DIMMABLE, default=False): cv.boolean,
+            })
+        ]),
+    vol.Optional(CONF_SENSOR, default=[]):
+        vol.All(cv.ensure_list, [
+            vol.All({
+                vol.Required(CONF_XPATH): cv.string,
+                vol.Required(CONF_NODE): cv.string,
+                vol.Optional(CONF_UNIT_OF_MEASUREMENT,
+                             default=TEMP_CELSIUS): cv.string,
+            })
+        ]),
+    vol.Optional(CONF_SWITCH, default=[]):
+        vol.All(cv.ensure_list, [
+            vol.All({
+                vol.Required(CONF_XPATH): cv.string,
+                vol.Required(CONF_NODE): cv.string,
+            })
+        ]),
+})
+
+SET_RUNTIME_VALUE_BOOL_SCHEMA = vol.Schema({
+    vol.Required(ATTR_IHC_ID): cv.positive_int,
+    vol.Required(ATTR_VALUE): cv.boolean
+})
+
+SET_RUNTIME_VALUE_INT_SCHEMA = vol.Schema({
+    vol.Required(ATTR_IHC_ID): cv.positive_int,
+    vol.Required(ATTR_VALUE): int
+})
+
+SET_RUNTIME_VALUE_FLOAT_SCHEMA = vol.Schema({
+    vol.Required(ATTR_IHC_ID): cv.positive_int,
+    vol.Required(ATTR_VALUE): vol.Coerce(float)
+})
+
+_LOGGER = logging.getLogger(__name__)
+
+IHC_PLATFORMS = ('binary_sensor', 'light', 'sensor', 'switch')
+
+
+def setup(hass, config):
+    """Setup the IHC component."""
+    from ihcsdk.ihccontroller import IHCController
+    conf = config[DOMAIN]
+    url = conf[CONF_URL]
+    username = conf[CONF_USERNAME]
+    password = conf[CONF_PASSWORD]
+    ihc_controller = IHCController(url, username, password)
+
+    if not ihc_controller.authenticate():
+        _LOGGER.error("Unable to authenticate on ihc controller.")
+        return False
+
+    if (conf[CONF_AUTOSETUP] and
+            not autosetup_ihc_products(hass, config, ihc_controller)):
+        return False
+
+    hass.data[IHC_DATA] = {
+        IHC_CONTROLLER: ihc_controller,
+        IHC_INFO: conf[CONF_INFO]}
+
+    setup_service_functions(hass, ihc_controller)
+    return True
+
+
+def autosetup_ihc_products(hass: HomeAssistantType, config, ihc_controller):
+    """Auto setup of IHC products from the ihc project file."""
+    project_xml = ihc_controller.get_project()
+    if not project_xml:
+        _LOGGER.error("Unable to read project from ihc controller.")
+        return False
+    project = xml.etree.ElementTree.fromstring(project_xml)
+
+    # if an auto setup file exist in the configuration it will override
+    yaml_path = hass.config.path(AUTO_SETUP_YAML)
+    if not os.path.isfile(yaml_path):
+        yaml_path = os.path.join(os.path.dirname(__file__), AUTO_SETUP_YAML)
+    yaml = load_yaml_config_file(yaml_path)
+    try:
+        auto_setup_conf = AUTO_SETUP_SCHEMA(yaml)
+    except vol.Invalid as exception:
+        _LOGGER.error("Invalid IHC auto setup data: %s", exception)
+        return False
+    groups = project.findall('.//group')
+    for component in IHC_PLATFORMS:
+        component_setup = auto_setup_conf[component]
+        discovery_info = get_discovery_info(component_setup, groups)
+        if discovery_info:
+            discovery.load_platform(hass, component, DOMAIN, discovery_info,
+                                    config)
+    return True
+
+
+def get_discovery_info(component_setup, groups):
+    """Get discovery info for specified component."""
+    discovery_data = {}
+    for group in groups:
+        groupname = group.attrib['name']
+        for product_cfg in component_setup:
+            products = group.findall(product_cfg[CONF_XPATH])
+            for product in products:
+                nodes = product.findall(product_cfg[CONF_NODE])
+                for node in nodes:
+                    if ('setting' in node.attrib
+                            and node.attrib['setting'] == 'yes'):
+                        continue
+                    ihc_id = int(node.attrib['id'].strip('_'), 0)
+                    name = '{}_{}'.format(groupname, ihc_id)
+                    device = {
+                        'ihc_id': ihc_id,
+                        'product': product,
+                        'product_cfg': product_cfg}
+                    discovery_data[name] = device
+    return discovery_data
+
+
+def setup_service_functions(hass: HomeAssistantType, ihc_controller):
+    """Setup the ihc service functions."""
+    def set_runtime_value_bool(call):
+        """Set a IHC runtime bool value service function."""
+        ihc_id = call.data[ATTR_IHC_ID]
+        value = call.data[ATTR_VALUE]
+        ihc_controller.set_runtime_value_bool(ihc_id, value)
+
+    def set_runtime_value_int(call):
+        """Set a IHC runtime integer value service function."""
+        ihc_id = call.data[ATTR_IHC_ID]
+        value = call.data[ATTR_VALUE]
+        ihc_controller.set_runtime_value_int(ihc_id, value)
+
+    def set_runtime_value_float(call):
+        """Set a IHC runtime float value service function."""
+        ihc_id = call.data[ATTR_IHC_ID]
+        value = call.data[ATTR_VALUE]
+        ihc_controller.set_runtime_value_float(ihc_id, value)
+
+    hass.services.register(DOMAIN, SERVICE_SET_RUNTIME_VALUE_BOOL,
+                           set_runtime_value_bool,
+                           schema=SET_RUNTIME_VALUE_BOOL_SCHEMA)
+    hass.services.register(DOMAIN, SERVICE_SET_RUNTIME_VALUE_INT,
+                           set_runtime_value_int,
+                           schema=SET_RUNTIME_VALUE_INT_SCHEMA)
+    hass.services.register(DOMAIN, SERVICE_SET_RUNTIME_VALUE_FLOAT,
+                           set_runtime_value_float,
+                           schema=SET_RUNTIME_VALUE_FLOAT_SCHEMA)
+
+
+def validate_name(config):
+    """Validate device name."""
+    if CONF_NAME in config:
+        return config
+    ihcid = config[CONF_ID]
+    name = 'ihc_{}'.format(ihcid)
+    config[CONF_NAME] = name
+    return config
diff --git a/homeassistant/components/ihc/const.py b/homeassistant/components/ihc/const.py
new file mode 100644
index 0000000000000000000000000000000000000000..b06746c8e7aef1c0676edf482bf26f8ffc9e042c
--- /dev/null
+++ b/homeassistant/components/ihc/const.py
@@ -0,0 +1,19 @@
+"""IHC component constants."""
+
+CONF_AUTOSETUP = 'auto_setup'
+CONF_INFO = 'info'
+CONF_XPATH = 'xpath'
+CONF_NODE = 'node'
+CONF_INVERTING = 'inverting'
+CONF_DIMMABLE = 'dimmable'
+CONF_BINARY_SENSOR = 'binary_sensor'
+CONF_LIGHT = 'light'
+CONF_SENSOR = 'sensor'
+CONF_SWITCH = 'switch'
+
+ATTR_IHC_ID = 'ihc_id'
+ATTR_VALUE = 'value'
+
+SERVICE_SET_RUNTIME_VALUE_BOOL = "set_runtime_value_bool"
+SERVICE_SET_RUNTIME_VALUE_INT = "set_runtime_value_int"
+SERVICE_SET_RUNTIME_VALUE_FLOAT = "set_runtime_value_float"
diff --git a/homeassistant/components/ihc/ihc_auto_setup.yaml b/homeassistant/components/ihc/ihc_auto_setup.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..81d5bf37977dffba2ffec7ec6045860ef60b033d
--- /dev/null
+++ b/homeassistant/components/ihc/ihc_auto_setup.yaml
@@ -0,0 +1,98 @@
+# IHC auto setup configuration.
+# To customize this, copy this file to the home assistant configuration
+# folder and make your changes. 
+
+binary_sensor:
+    # Magnet contact
+    - xpath: './/product_dataline[@product_identifier="_0x2109"]'
+      node: 'dataline_input'
+      type: 'opening'
+      inverting: True
+    # Pir sensors
+    - xpath: './/product_dataline[@product_identifier="_0x210e"]'
+      node: 'dataline_input[1]'
+      type: 'motion'
+    # Pir sensors twilight sensor
+    - xpath: './/product_dataline[@product_identifier="_0x0"]'
+      node: 'dataline_input[1]'
+      type: 'motion'
+    # Pir sensors alarm
+    - xpath: './/product_dataline[@product_identifier="_0x210f"]'
+      node: 'dataline_input'
+      type: 'motion'
+    # Smoke detector
+    - xpath: './/product_dataline[@product_identifier="_0x210a"]'
+      node: 'dataline_input'
+      type: 'smoke'
+    # leak detector
+    - xpath: './/product_dataline[@product_identifier="_0x210c"]'
+      node: 'dataline_input'
+      type: 'moisture'
+    # light detector
+    - xpath: './/product_dataline[@product_identifier="_0x2110"]'
+      node: 'dataline_input'
+      type: 'light'
+
+light:
+    # Wireless Combi dimmer 4 buttons
+    - xpath: './/product_airlink[@product_identifier="_0x4406"]'
+      node: 'airlink_dimming'
+      dimmable: True
+    # Wireless Lamp outlet dimmer
+    - xpath: './/product_airlink[@product_identifier="_0x4304"]'
+      node: 'airlink_dimming'
+      dimmable: True
+    # Wireless universal dimmer
+    - xpath: './/product_airlink[@product_identifier="_0x4306"]'
+      node: 'airlink_dimming'
+      dimmable: True
+    # Wireless Lamp outlet relay
+    - xpath: './/product_airlink[@product_identifier="_0x4202"]'
+      node: 'airlink_relay'
+    # Wireless Combi relay 4 buttons
+    - xpath: './/product_airlink[@product_identifier="_0x4404"]'
+      node: 'airlink_relay'
+    # Dataline Lamp outlet
+    - xpath: './/product_dataline[@product_identifier="_0x2202"]'
+      node: 'dataline_output'
+    # Mobile Wireless dimmer
+    - xpath: './/product_airlink[@product_identifier="_0x4303"]'
+      node: 'airlink_dimming'
+      dimmable: True
+
+sensor:
+    # Temperature sensor
+    - xpath: './/product_dataline[@product_identifier="_0x2124"]'
+      node: 'resource_temperature'
+      unit_of_measurement: '°C'
+    # Humidity/temperature
+    - xpath: './/product_dataline[@product_identifier="_0x2135"]'
+      node: 'resource_humidity_level'
+      unit_of_measurement: '%'
+    # Humidity/temperature
+    - xpath: './/product_dataline[@product_identifier="_0x2135"]'
+      node: 'resource_temperature'
+      unit_of_measurement: '°C'
+    # Lux/temperature
+    - xpath: './/product_dataline[@product_identifier="_0x2136"]'
+      node: 'resource_light'
+      unit_of_measurement: 'Lux'
+    # Lux/temperature
+    - xpath: './/product_dataline[@product_identifier="_0x2136"]'
+      node: 'resource_temperature'
+      unit_of_measurement: '°C'
+
+switch:
+    # Wireless Plug outlet
+    - xpath: './/product_airlink[@product_identifier="_0x4201"]'
+      node: 'airlink_relay'
+    # Dataline universal relay
+    - xpath: './/product_airlink[@product_identifier="_0x4203"]'
+      node: 'airlink_relay'
+    # Dataline plug outlet
+    - xpath: './/product_dataline[@product_identifier="_0x2201"]'
+      node: 'dataline_output'
+    # Wireless mobile relay
+    - xpath: './/product_airlink[@product_identifier="_0x4204"]'
+      node: 'airlink_relay'
+
diff --git a/homeassistant/components/ihc/ihcdevice.py b/homeassistant/components/ihc/ihcdevice.py
new file mode 100644
index 0000000000000000000000000000000000000000..48827851f92a0080bb4c789c8bee1b9e9f046f41
--- /dev/null
+++ b/homeassistant/components/ihc/ihcdevice.py
@@ -0,0 +1,65 @@
+"""Implements a base class for all IHC devices."""
+import asyncio
+from xml.etree.ElementTree import Element
+
+from homeassistant.helpers.entity import Entity
+
+
+class IHCDevice(Entity):
+    """Base class for all ihc devices.
+
+    All IHC devices have an associated IHC resource. IHCDevice handled the
+    registration of the IHC controller callback when the IHC resource changes.
+    Derived classes must implement the on_ihc_change method
+    """
+
+    def __init__(self, ihc_controller, name, ihc_id: int, info: bool,
+                 product: Element=None):
+        """Initialize IHC attributes."""
+        self.ihc_controller = ihc_controller
+        self._name = name
+        self.ihc_id = ihc_id
+        self.info = info
+        if product:
+            self.ihc_name = product.attrib['name']
+            self.ihc_note = product.attrib['note']
+            self.ihc_position = product.attrib['position']
+        else:
+            self.ihc_name = ''
+            self.ihc_note = ''
+            self.ihc_position = ''
+
+    @asyncio.coroutine
+    def async_added_to_hass(self):
+        """Add callback for ihc changes."""
+        self.ihc_controller.add_notify_event(
+            self.ihc_id, self.on_ihc_change, True)
+
+    @property
+    def should_poll(self) -> bool:
+        """No polling needed for ihc devices."""
+        return False
+
+    @property
+    def name(self):
+        """Return the device name."""
+        return self._name
+
+    @property
+    def device_state_attributes(self):
+        """Return the state attributes."""
+        if not self.info:
+            return {}
+        return {
+            'ihc_id': self.ihc_id,
+            'ihc_name': self.ihc_name,
+            'ihc_note': self.ihc_note,
+            'ihc_position': self.ihc_position
+        }
+
+    def on_ihc_change(self, ihc_id, value):
+        """Callback when ihc resource changes.
+
+        Derived classes must overwrite this to do device specific stuff.
+        """
+        raise NotImplementedError
diff --git a/homeassistant/components/ihc/services.yaml b/homeassistant/components/ihc/services.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7b6053eff898aee19135e8e0db4cd69ffcadccb5
--- /dev/null
+++ b/homeassistant/components/ihc/services.yaml
@@ -0,0 +1,26 @@
+# Describes the format for available ihc services
+
+set_runtime_value_bool:
+  description: Set a boolean runtime value on the ihc controller
+  fields:
+    ihc_id:
+      description: The integer ihc resource id
+    value:
+      description: The boolean value to set
+
+set_runtime_value_int:
+  description: Set an integer runtime value on the ihc controller
+  fields:
+    ihc_id:
+      description: The integer ihc resource id
+    value:
+      description: The integer value to set
+
+set_runtime_value_float:
+  description: Set a float runtime value on the ihc controller
+  fields:
+    ihc_id:
+      description: The integer ihc resource id
+    value:
+      description: The float value to set
+
diff --git a/homeassistant/components/light/ihc.py b/homeassistant/components/light/ihc.py
new file mode 100644
index 0000000000000000000000000000000000000000..f23ae77c8b2f87c445b2c57c2c6b1605cb39d5cb
--- /dev/null
+++ b/homeassistant/components/light/ihc.py
@@ -0,0 +1,123 @@
+"""IHC light platform.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/light.ihc/
+"""
+from xml.etree.ElementTree import Element
+
+import voluptuous as vol
+
+from homeassistant.components.ihc import (
+    validate_name, IHC_DATA, IHC_CONTROLLER, IHC_INFO)
+from homeassistant.components.ihc.const import CONF_DIMMABLE
+from homeassistant.components.ihc.ihcdevice import IHCDevice
+from homeassistant.components.light import (
+    ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, PLATFORM_SCHEMA, Light)
+from homeassistant.const import CONF_ID, CONF_NAME, CONF_LIGHTS
+import homeassistant.helpers.config_validation as cv
+
+DEPENDENCIES = ['ihc']
+
+PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
+    vol.Optional(CONF_LIGHTS, default=[]):
+        vol.All(cv.ensure_list, [
+            vol.All({
+                vol.Required(CONF_ID): cv.positive_int,
+                vol.Optional(CONF_NAME): cv.string,
+                vol.Optional(CONF_DIMMABLE, default=False): cv.boolean,
+            }, validate_name)
+        ])
+})
+
+
+def setup_platform(hass, config, add_devices, discovery_info=None):
+    """Setup the ihc lights platform."""
+    ihc_controller = hass.data[IHC_DATA][IHC_CONTROLLER]
+    info = hass.data[IHC_DATA][IHC_INFO]
+    devices = []
+    if discovery_info:
+        for name, device in discovery_info.items():
+            ihc_id = device['ihc_id']
+            product_cfg = device['product_cfg']
+            product = device['product']
+            light = IhcLight(ihc_controller, name, ihc_id, info,
+                             product_cfg[CONF_DIMMABLE], product)
+            devices.append(light)
+    else:
+        lights = config[CONF_LIGHTS]
+        for light in lights:
+            ihc_id = light[CONF_ID]
+            name = light[CONF_NAME]
+            dimmable = light[CONF_DIMMABLE]
+            device = IhcLight(ihc_controller, name, ihc_id, info, dimmable)
+            devices.append(device)
+
+    add_devices(devices)
+
+
+class IhcLight(IHCDevice, Light):
+    """Representation of a IHC light.
+
+    For dimmable lights, the associated IHC resource should be a light
+    level (integer). For non dimmable light the IHC resource should be
+    an on/off (boolean) resource
+    """
+
+    def __init__(self, ihc_controller, name, ihc_id: int, info: bool,
+                 dimmable=False, product: Element=None):
+        """Initialize the light."""
+        super().__init__(ihc_controller, name, ihc_id, info, product)
+        self._brightness = 0
+        self._dimmable = dimmable
+        self._state = None
+
+    @property
+    def brightness(self) -> int:
+        """Return the brightness of this light between 0..255."""
+        return self._brightness
+
+    @property
+    def is_on(self) -> bool:
+        """Return true if light is on."""
+        return self._state
+
+    @property
+    def supported_features(self):
+        """Flag supported features."""
+        if self._dimmable:
+            return SUPPORT_BRIGHTNESS
+        return 0
+
+    def turn_on(self, **kwargs) -> None:
+        """Turn the light on."""
+        if ATTR_BRIGHTNESS in kwargs:
+            brightness = kwargs[ATTR_BRIGHTNESS]
+        else:
+            brightness = self._brightness
+            if brightness == 0:
+                brightness = 255
+
+        if self._dimmable:
+            self.ihc_controller.set_runtime_value_int(
+                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:
+        """Turn the light off."""
+        if self._dimmable:
+            self.ihc_controller.set_runtime_value_int(self.ihc_id, 0)
+        else:
+            self.ihc_controller.set_runtime_value_bool(self.ihc_id, False)
+
+    def on_ihc_change(self, ihc_id, value):
+        """Callback from Ihc notifications."""
+        if isinstance(value, bool):
+            self._dimmable = False
+            self._state = value != 0
+        else:
+            self._dimmable = True
+            self._state = value > 0
+            if self._state:
+                self._brightness = int(value * 255 / 100)
+        self.schedule_update_ha_state()
diff --git a/homeassistant/components/sensor/ihc.py b/homeassistant/components/sensor/ihc.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ad86e51f9730be75a84ebf5901626a67021e8f0
--- /dev/null
+++ b/homeassistant/components/sensor/ihc.py
@@ -0,0 +1,84 @@
+"""IHC sensor platform.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/sensor.ihc/
+"""
+from xml.etree.ElementTree import Element
+
+import voluptuous as vol
+
+from homeassistant.components.ihc import (
+    validate_name, IHC_DATA, IHC_CONTROLLER, IHC_INFO)
+from homeassistant.components.ihc.ihcdevice import IHCDevice
+from homeassistant.components.sensor import PLATFORM_SCHEMA
+from homeassistant.const import (
+    CONF_ID, CONF_NAME, CONF_UNIT_OF_MEASUREMENT, CONF_SENSORS,
+    TEMP_CELSIUS)
+import homeassistant.helpers.config_validation as cv
+from homeassistant.helpers.entity import Entity
+
+DEPENDENCIES = ['ihc']
+
+PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
+    vol.Optional(CONF_SENSORS, default=[]):
+        vol.All(cv.ensure_list, [
+            vol.All({
+                vol.Required(CONF_ID): cv.positive_int,
+                vol.Optional(CONF_NAME): cv.string,
+                vol.Optional(CONF_UNIT_OF_MEASUREMENT,
+                             default=TEMP_CELSIUS): cv.string
+            }, validate_name)
+        ])
+})
+
+
+def setup_platform(hass, config, add_devices, discovery_info=None):
+    """Setup the ihc sensor platform."""
+    ihc_controller = hass.data[IHC_DATA][IHC_CONTROLLER]
+    info = hass.data[IHC_DATA][IHC_INFO]
+    devices = []
+    if discovery_info:
+        for name, device in discovery_info.items():
+            ihc_id = device['ihc_id']
+            product_cfg = device['product_cfg']
+            product = device['product']
+            sensor = IHCSensor(ihc_controller, name, ihc_id, info,
+                               product_cfg[CONF_UNIT_OF_MEASUREMENT],
+                               product)
+            devices.append(sensor)
+    else:
+        sensors = config[CONF_SENSORS]
+        for sensor_cfg in sensors:
+            ihc_id = sensor_cfg[CONF_ID]
+            name = sensor_cfg[CONF_NAME]
+            unit = sensor_cfg[CONF_UNIT_OF_MEASUREMENT]
+            sensor = IHCSensor(ihc_controller, name, ihc_id, info, unit)
+            devices.append(sensor)
+
+    add_devices(devices)
+
+
+class IHCSensor(IHCDevice, Entity):
+    """Implementation of the IHC sensor."""
+
+    def __init__(self, ihc_controller, name, ihc_id: int, info: bool,
+                 unit, product: Element=None):
+        """Initialize the IHC sensor."""
+        super().__init__(ihc_controller, name, ihc_id, info, product)
+        self._state = None
+        self._unit_of_measurement = unit
+
+    @property
+    def state(self):
+        """Return the state of the sensor."""
+        return self._state
+
+    @property
+    def unit_of_measurement(self):
+        """Return the unit of measurement of this entity, if any."""
+        return self._unit_of_measurement
+
+    def on_ihc_change(self, ihc_id, value):
+        """Callback when ihc resource changes."""
+        self._state = value
+        self.schedule_update_ha_state()
diff --git a/homeassistant/components/switch/ihc.py b/homeassistant/components/switch/ihc.py
new file mode 100644
index 0000000000000000000000000000000000000000..4bab1378acd16c77efdd9953c029f8105a65c602
--- /dev/null
+++ b/homeassistant/components/switch/ihc.py
@@ -0,0 +1,77 @@
+"""IHC switch platform.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/switch.ihc/
+"""
+from xml.etree.ElementTree import Element
+
+import voluptuous as vol
+
+from homeassistant.components.ihc import (
+    validate_name, IHC_DATA, IHC_CONTROLLER, IHC_INFO)
+from homeassistant.components.ihc.ihcdevice import IHCDevice
+from homeassistant.components.switch import SwitchDevice, PLATFORM_SCHEMA
+from homeassistant.const import CONF_ID, CONF_NAME, CONF_SWITCHES
+import homeassistant.helpers.config_validation as cv
+
+DEPENDENCIES = ['ihc']
+
+PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
+    vol.Optional(CONF_SWITCHES, default=[]):
+        vol.All(cv.ensure_list, [
+            vol.All({
+                vol.Required(CONF_ID): cv.positive_int,
+                vol.Optional(CONF_NAME): cv.string,
+            }, validate_name)
+        ])
+})
+
+
+def setup_platform(hass, config, add_devices, discovery_info=None):
+    """Setup the ihc switch platform."""
+    ihc_controller = hass.data[IHC_DATA][IHC_CONTROLLER]
+    info = hass.data[IHC_DATA][IHC_INFO]
+    devices = []
+    if discovery_info:
+        for name, device in discovery_info.items():
+            ihc_id = device['ihc_id']
+            product = device['product']
+            switch = IHCSwitch(ihc_controller, name, ihc_id, info, product)
+            devices.append(switch)
+    else:
+        switches = config[CONF_SWITCHES]
+        for switch in switches:
+            ihc_id = switch[CONF_ID]
+            name = switch[CONF_NAME]
+            sensor = IHCSwitch(ihc_controller, name, ihc_id, info)
+            devices.append(sensor)
+
+    add_devices(devices)
+
+
+class IHCSwitch(IHCDevice, SwitchDevice):
+    """IHC Switch."""
+
+    def __init__(self, ihc_controller, name: str, ihc_id: int,
+                 info: bool, product: Element=None):
+        """Initialize the IHC switch."""
+        super().__init__(ihc_controller, name, ihc_id, product)
+        self._state = False
+
+    @property
+    def is_on(self):
+        """Return true if switch is on."""
+        return self._state
+
+    def turn_on(self, **kwargs):
+        """Turn the switch on."""
+        self.ihc_controller.set_runtime_value_bool(self.ihc_id, True)
+
+    def turn_off(self, **kwargs):
+        """Turn the device off."""
+        self.ihc_controller.set_runtime_value_bool(self.ihc_id, False)
+
+    def on_ihc_change(self, ihc_id, value):
+        """Callback when the ihc resource changes."""
+        self._state = value
+        self.schedule_update_ha_state()
diff --git a/requirements_all.txt b/requirements_all.txt
index ffa7c4e1cbd7811b687c0bd29787e7ef27cdf0c5..1bee68301d6233e751859747aadd67bfe3ee2609 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -398,6 +398,9 @@ https://github.com/wokar/pylgnetcast/archive/v0.2.0.zip#pylgnetcast==0.2.0
 # homeassistant.components.light.iglo
 iglo==1.1.3
 
+# homeassistant.components.ihc
+ihcsdk==2.1.1
+
 # homeassistant.components.influxdb
 # homeassistant.components.sensor.influxdb
 influxdb==4.1.1