diff --git a/.coveragerc b/.coveragerc
index 6526b2b1e3d252ca921db4e6744859ec4135c7e7..51d6d81179f8f5d516d0ea48f4b8cc5a9f2470b8 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -84,6 +84,9 @@ omit =
     homeassistant/components/netatmo.py
     homeassistant/components/*/netatmo.py
 
+    homeassistant/components/homematic.py
+    homeassistant/components/*/homematic.py
+
     homeassistant/components/alarm_control_panel/alarmdotcom.py
     homeassistant/components/alarm_control_panel/nx584.py
     homeassistant/components/binary_sensor/arest.py
diff --git a/homeassistant/components/binary_sensor/homematic.py b/homeassistant/components/binary_sensor/homematic.py
new file mode 100644
index 0000000000000000000000000000000000000000..08ea209944548ff172a0473ad751156fa78a8e8e
--- /dev/null
+++ b/homeassistant/components/binary_sensor/homematic.py
@@ -0,0 +1,169 @@
+"""
+The homematic binary sensor platform.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/binary_sensor.homematic/
+
+Important: For this platform to work the homematic component has to be
+properly configured.
+
+Configuration (single channel, simple device):
+
+binary_sensor:
+  - platform: homematic
+    address: "<Homematic address for device>" # e.g. "JEQ0XXXXXXX"
+    name: "<User defined name>" (optional)
+
+
+Configuration (multiple channels, like motion detector with buttons):
+
+binary_sensor:
+  - platform: homematic
+    address: "<Homematic address for device>" # e.g. "JEQ0XXXXXXX"
+    param: <MOTION|PRESS_SHORT...> (device-dependent) (optional)
+    button: n (integer of channel to map, device-dependent) (optional)
+    name: "<User defined name>" (optional)
+binary_sensor:
+  - platform: homematic
+  ...
+"""
+
+import logging
+from homeassistant.const import STATE_UNKNOWN
+from homeassistant.components.binary_sensor import BinarySensorDevice
+import homeassistant.components.homematic as homematic
+
+_LOGGER = logging.getLogger(__name__)
+
+DEPENDENCIES = ['homematic']
+
+SENSOR_TYPES_CLASS = {
+    "Remote": None,
+    "ShutterContact": "opening",
+    "Smoke": "smoke",
+    "SmokeV2": "smoke",
+    "Motion": "motion",
+    "MotionV2": "motion",
+    "RemoteMotion": None
+}
+
+SUPPORT_HM_EVENT_AS_BINMOD = [
+    "PRESS_LONG",
+    "PRESS_SHORT"
+]
+
+
+def setup_platform(hass, config, add_callback_devices, discovery_info=None):
+    """Setup the platform."""
+    if discovery_info:
+        return homematic.setup_hmdevice_discovery_helper(HMBinarySensor,
+                                                         discovery_info,
+                                                         add_callback_devices)
+    # Manual
+    return homematic.setup_hmdevice_entity_helper(HMBinarySensor,
+                                                  config,
+                                                  add_callback_devices)
+
+
+class HMBinarySensor(homematic.HMDevice, BinarySensorDevice):
+    """Represents diverse binary Homematic units in Home Assistant."""
+
+    @property
+    def is_on(self):
+        """Return True if switch is on."""
+        if not self.available:
+            return False
+        # no binary is defined, check all!
+        if self._state is None:
+            available_bin = self._create_binary_list_from_hm()
+            for binary in available_bin:
+                try:
+                    if binary in self._data and self._data[binary] == 1:
+                        return True
+                except (ValueError, TypeError):
+                    _LOGGER.warning("%s datatype error!", self._name)
+            return False
+
+        # single binary
+        return bool(self._hm_get_state())
+
+    @property
+    def sensor_class(self):
+        """Return the class of this sensor, from SENSOR_CLASSES."""
+        if not self.available:
+            return None
+
+        # If state is MOTION (RemoteMotion works only)
+        if self._state == "MOTION":
+            return "motion"
+        return SENSOR_TYPES_CLASS.get(self._hmdevice.__class__.__name__, None)
+
+    def _check_hm_to_ha_object(self):
+        """Check if possible to use the HM Object as this HA type."""
+        from pyhomematic.devicetypes.sensors import HMBinarySensor\
+            as pyHMBinarySensor
+
+        # Check compatibility from HMDevice
+        if not super()._check_hm_to_ha_object():
+            return False
+
+        # check if the homematic device correct for this HA device
+        if not isinstance(self._hmdevice, pyHMBinarySensor):
+            _LOGGER.critical("This %s can't be use as binary!", self._name)
+            return False
+
+        # load possible binary sensor
+        available_bin = self._create_binary_list_from_hm()
+
+        # if exists user value?
+        if self._state and self._state not in available_bin:
+            _LOGGER.critical("This %s have no binary with %s!", self._name,
+                             self._state)
+            return False
+
+        # only check and give a warining to User
+        if self._state is None and len(available_bin) > 1:
+            _LOGGER.warning("%s have multible binary params. It use all " +
+                            "binary nodes as one. Possible param values: %s",
+                            self._name, str(available_bin))
+
+        return True
+
+    def _init_data_struct(self):
+        """Generate a data struct (self._data) from hm metadata."""
+        super()._init_data_struct()
+
+        # load possible binary sensor
+        available_bin = self._create_binary_list_from_hm()
+
+        # object have 1 binary
+        if self._state is None and len(available_bin) == 1:
+            for value in available_bin:
+                self._state = value
+
+        # no binary is definit, use all binary for state
+        if self._state is None and len(available_bin) > 1:
+            for node in available_bin:
+                self._data.update({node: STATE_UNKNOWN})
+
+        # add state to data struct
+        if self._state:
+            _LOGGER.debug("%s init datastruct with main node '%s'", self._name,
+                          self._state)
+            self._data.update({self._state: STATE_UNKNOWN})
+
+    def _create_binary_list_from_hm(self):
+        """Generate a own metadata for binary_sensors."""
+        bin_data = {}
+        if not self._hmdevice:
+            return bin_data
+
+        # copy all data from BINARYNODE
+        bin_data.update(self._hmdevice.BINARYNODE)
+
+        # copy all hm event they are supportet by this object
+        for event, channel in self._hmdevice.EVENTNODE.items():
+            if event in SUPPORT_HM_EVENT_AS_BINMOD:
+                bin_data.update({event: channel})
+
+        return bin_data
diff --git a/homeassistant/components/homematic.py b/homeassistant/components/homematic.py
new file mode 100644
index 0000000000000000000000000000000000000000..c2c6c000fa262a4fd23843b5e0b6f49c835825de
--- /dev/null
+++ b/homeassistant/components/homematic.py
@@ -0,0 +1,521 @@
+"""
+Support for Homematic Devices.
+
+For more details about this component, please refer to the documentation at
+https://home-assistant.io/components/homematic/
+
+Configuration:
+
+homematic:
+  local_ip: "<IP of device running Home Assistant>"
+  local_port: <Port for connection with Home Assistant>
+  remote_ip: "<IP of Homegear / CCU>"
+  remote_port: <Port of Homegear / CCU XML-RPC Server>
+  autodetect: "<True/False>" (optional, experimental, detect all devices)
+"""
+import time
+import logging
+from functools import partial
+from homeassistant.const import EVENT_HOMEASSISTANT_STOP, STATE_UNKNOWN
+from homeassistant.helpers import discovery
+from homeassistant.helpers.entity import Entity
+
+DOMAIN = 'homematic'
+REQUIREMENTS = ['pyhomematic==0.1.6']
+
+HOMEMATIC = None
+HOMEMATIC_DEVICES = {}
+
+DISCOVER_SWITCHES = "homematic.switch"
+DISCOVER_LIGHTS = "homematic.light"
+DISCOVER_SENSORS = "homematic.sensor"
+DISCOVER_BINARY_SENSORS = "homematic.binary_sensor"
+DISCOVER_ROLLERSHUTTER = "homematic.rollershutter"
+DISCOVER_THERMOSTATS = "homematic.thermostat"
+
+ATTR_DISCOVER_DEVICES = "devices"
+ATTR_DISCOVER_CONFIG = "config"
+
+HM_DEVICE_TYPES = {
+    DISCOVER_SWITCHES: ["Switch", "SwitchPowermeter"],
+    DISCOVER_LIGHTS: ["Dimmer"],
+    DISCOVER_SENSORS: ["SwitchPowermeter", "Motion", "MotionV2",
+                       "RemoteMotion", "ThermostatWall", "AreaThermostat",
+                       "RotaryHandleSensor"],
+    DISCOVER_THERMOSTATS: ["Thermostat", "ThermostatWall", "MAXThermostat"],
+    DISCOVER_BINARY_SENSORS: ["Remote", "ShutterContact", "Smoke", "SmokeV2",
+                              "Motion", "MotionV2", "RemoteMotion",
+                              "GongSensor"],
+    DISCOVER_ROLLERSHUTTER: ["Blind"]
+}
+
+HM_IGNORE_DISCOVERY_NODE = [
+    "ACTUAL_TEMPERATURE"
+]
+
+HM_ATTRIBUTE_SUPPORT = {
+    "LOWBAT": ["Battery", {0: "High", 1: "Low"}],
+    "ERROR": ["Sabotage", {0: "No", 1: "Yes"}],
+    "RSSI_DEVICE": ["RSSI", {}],
+    "VALVE_STATE": ["Valve", {}],
+    "BATTERY_STATE": ["Battery", {}],
+    "CONTROL_MODE": ["Mode", {0: "Auto", 1: "Manual", 2: "Away", 3: "Boost"}],
+    "POWER": ["Power", {}],
+    "CURRENT": ["Current", {}],
+    "VOLTAGE": ["Voltage", {}]
+}
+
+_LOGGER = logging.getLogger(__name__)
+
+
+# pylint: disable=unused-argument
+def setup(hass, config):
+    """Setup the Homematic component."""
+    global HOMEMATIC
+
+    from pyhomematic import HMConnection
+
+    local_ip = config[DOMAIN].get("local_ip", None)
+    local_port = config[DOMAIN].get("local_port", 8943)
+    remote_ip = config[DOMAIN].get("remote_ip", None)
+    remote_port = config[DOMAIN].get("remote_port", 2001)
+    resolvenames = config[DOMAIN].get("resolvenames", False)
+
+    if remote_ip is None or local_ip is None:
+        _LOGGER.error("Missing remote CCU/Homegear or local address")
+        return False
+
+    # Create server thread
+    bound_system_callback = partial(system_callback_handler, hass, config)
+    HOMEMATIC = HMConnection(local=local_ip,
+                             localport=local_port,
+                             remote=remote_ip,
+                             remoteport=remote_port,
+                             systemcallback=bound_system_callback,
+                             resolvenames=resolvenames,
+                             interface_id="homeassistant")
+
+    # Start server thread, connect to peer, initialize to receive events
+    HOMEMATIC.start()
+
+    # Stops server when Homeassistant is shutting down
+    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, HOMEMATIC.stop)
+    hass.config.components.append(DOMAIN)
+
+    return True
+
+
+# pylint: disable=too-many-branches
+def system_callback_handler(hass, config, src, *args):
+    """Callback handler."""
+    delay = config[DOMAIN].get("delay", 0.5)
+    if src == 'newDevices':
+        # pylint: disable=unused-variable
+        (interface_id, dev_descriptions) = args
+        key_dict = {}
+        # Get list of all keys of the devices (ignoring channels)
+        for dev in dev_descriptions:
+            key_dict[dev['ADDRESS'].split(':')[0]] = True
+        # Connect devices already created in HA to pyhomematic and
+        # add remaining devices to list
+        devices_not_created = []
+        for dev in key_dict:
+            if dev in HOMEMATIC_DEVICES:
+                for hm_element in HOMEMATIC_DEVICES[dev]:
+                    hm_element.link_homematic(delay=delay)
+            else:
+                devices_not_created.append(dev)
+
+        # If configuration allows autodetection of devices,
+        # all devices not configured are added.
+        autodetect = config[DOMAIN].get("autodetect", False)
+        if autodetect and devices_not_created:
+            for component_name, discovery_type in (
+                    ('switch', DISCOVER_SWITCHES),
+                    ('light', DISCOVER_LIGHTS),
+                    ('rollershutter', DISCOVER_ROLLERSHUTTER),
+                    ('binary_sensor', DISCOVER_BINARY_SENSORS),
+                    ('sensor', DISCOVER_SENSORS),
+                    ('thermostat', DISCOVER_THERMOSTATS)):
+                # Get all devices of a specific type
+                found_devices = _get_devices(discovery_type,
+                                             devices_not_created)
+
+                # When devices of this type are found
+                # they are setup in HA and an event is fired
+                if found_devices:
+                    # Fire discovery event
+                    discovery.load_platform(hass, component_name, DOMAIN, {
+                        ATTR_DISCOVER_DEVICES: found_devices
+                    }, config)
+
+            for dev in devices_not_created:
+                if dev in HOMEMATIC_DEVICES:
+                    for hm_element in HOMEMATIC_DEVICES[dev]:
+                        hm_element.link_homematic(delay=delay)
+
+
+def _get_devices(device_type, keys):
+    """Get devices."""
+    from homeassistant.components.binary_sensor.homematic import \
+        SUPPORT_HM_EVENT_AS_BINMOD
+
+    # run
+    device_arr = []
+    if not keys:
+        keys = HOMEMATIC.devices
+    for key in keys:
+        device = HOMEMATIC.devices[key]
+        if device.__class__.__name__ not in HM_DEVICE_TYPES[device_type]:
+            continue
+        metadata = {}
+
+        # Load metadata if needed to generate a param list
+        if device_type == DISCOVER_SENSORS:
+            metadata.update(device.SENSORNODE)
+        elif device_type == DISCOVER_BINARY_SENSORS:
+            metadata.update(device.BINARYNODE)
+
+            # Also add supported events as binary type
+            for event, channel in device.EVENTNODE.items():
+                if event in SUPPORT_HM_EVENT_AS_BINMOD:
+                    metadata.update({event: channel})
+
+        params = _create_params_list(device, metadata)
+        if params:
+            # Generate options for 1...n elements with 1...n params
+            for channel in range(1, device.ELEMENT + 1):
+                _LOGGER.debug("Handling %s:%i", key, channel)
+                if channel in params:
+                    for param in params[channel]:
+                        name = _create_ha_name(name=device.NAME,
+                                               channel=channel,
+                                               param=param)
+                        device_dict = dict(platform="homematic",
+                                           address=key,
+                                           name=name,
+                                           button=channel)
+                        if param is not None:
+                            device_dict["param"] = param
+
+                        # Add new device
+                        device_arr.append(device_dict)
+                else:
+                    _LOGGER.debug("Channel %i not in params", channel)
+        else:
+            _LOGGER.debug("Got no params for %s", key)
+    _LOGGER.debug("%s autodiscovery: %s",
+                  device_type, str(device_arr))
+    return device_arr
+
+
+def _create_params_list(hmdevice, metadata):
+    """Create a list from HMDevice with all possible parameters in config."""
+    params = {}
+
+    # Search in sensor and binary metadata per elements
+    for channel in range(1, hmdevice.ELEMENT + 1):
+        param_chan = []
+        try:
+            for node, meta_chan in metadata.items():
+                # Is this attribute ignored?
+                if node in HM_IGNORE_DISCOVERY_NODE:
+                    continue
+                if meta_chan == 'c' or meta_chan is None:
+                    # Only channel linked data
+                    param_chan.append(node)
+                elif channel == 1:
+                    # First channel can have other data channel
+                    param_chan.append(node)
+        # pylint: disable=broad-except
+        except Exception as err:
+            _LOGGER.error("Exception generating %s (%s): %s",
+                          hmdevice.ADDRESS, str(metadata), str(err))
+        # Default parameter
+        if not param_chan:
+            param_chan.append(None)
+        # Add to channel
+        params.update({channel: param_chan})
+
+    _LOGGER.debug("Create param list for %s with: %s", hmdevice.ADDRESS,
+                  str(params))
+    return params
+
+
+def _create_ha_name(name, channel, param):
+    """Generate a unique object name."""
+    # HMDevice is a simple device
+    if channel == 1 and param is None:
+        return name
+
+    # Has multiple elements/channels
+    if channel > 1 and param is None:
+        return "{} {}".format(name, channel)
+
+    # With multiple param first elements
+    if channel == 1 and param is not None:
+        return "{} {}".format(name, param)
+
+    # Multiple param on object with multiple elements
+    if channel > 1 and param is not None:
+        return "{} {} {}".format(name, channel, param)
+
+
+def setup_hmdevice_discovery_helper(hmdevicetype, discovery_info,
+                                    add_callback_devices):
+    """Helper to setup Homematic devices with discovery info."""
+    for config in discovery_info["devices"]:
+        ret = setup_hmdevice_entity_helper(hmdevicetype, config,
+                                           add_callback_devices)
+        if not ret:
+            _LOGGER.error("Setup discovery error with config %s", str(config))
+    return True
+
+
+def setup_hmdevice_entity_helper(hmdevicetype, config, add_callback_devices):
+    """Helper to setup Homematic devices."""
+    if HOMEMATIC is None:
+        _LOGGER.error('Error setting up HMDevice: Server not configured.')
+        return False
+
+    address = config.get('address', None)
+    if address is None:
+        _LOGGER.error("Error setting up device '%s': " +
+                      "'address' missing in configuration.", address)
+        return False
+
+    # Create a new HA homematic object
+    new_device = hmdevicetype(config)
+    if address not in HOMEMATIC_DEVICES:
+        HOMEMATIC_DEVICES[address] = []
+    HOMEMATIC_DEVICES[address].append(new_device)
+
+    # Add to HA
+    add_callback_devices([new_device])
+    return True
+
+
+class HMDevice(Entity):
+    """Homematic device base object."""
+
+    # pylint: disable=too-many-instance-attributes
+    def __init__(self, config):
+        """Initialize generic HM device."""
+        self._name = config.get("name", None)
+        self._address = config.get("address", None)
+        self._channel = config.get("button", 1)
+        self._state = config.get("param", None)
+        self._hidden = config.get("hidden", False)
+        self._data = {}
+        self._hmdevice = None
+        self._connected = False
+        self._available = False
+
+        # Set param to uppercase
+        if self._state:
+            self._state = self._state.upper()
+
+        # Generate name
+        if not self._name:
+            self._name = _create_ha_name(name=self._address,
+                                         channel=self._channel,
+                                         param=self._state)
+
+    @property
+    def should_poll(self):
+        """Return False. Homematic states are pushed by the XML RPC Server."""
+        return False
+
+    @property
+    def name(self):
+        """Return the name of the device."""
+        return self._name
+
+    @property
+    def assumed_state(self):
+        """Return True if unable to access real state of the device."""
+        return not self._available
+
+    @property
+    def available(self):
+        """Return True if device is available."""
+        return self._available
+
+    @property
+    def hidden(self):
+        """Return True if the entity should be hidden from UIs."""
+        return self._hidden
+
+    @property
+    def device_state_attributes(self):
+        """Return device specific state attributes."""
+        attr = {}
+
+        # Generate an attributes list
+        for node, data in HM_ATTRIBUTE_SUPPORT.items():
+            # Is an attributes and exists for this object
+            if node in self._data:
+                value = data[1].get(self._data[node], self._data[node])
+                attr[data[0]] = value
+
+        return attr
+
+    def link_homematic(self, delay=0.5):
+        """Connect to homematic."""
+        # Does a HMDevice from pyhomematic exist?
+        if self._address in HOMEMATIC.devices:
+            # Init
+            self._hmdevice = HOMEMATIC.devices[self._address]
+            self._connected = True
+
+            # Check if HM class is okay for HA class
+            _LOGGER.info("Start linking %s to %s", self._address, self._name)
+            if self._check_hm_to_ha_object():
+                try:
+                    # Init datapoints of this object
+                    self._init_data_struct()
+                    if delay:
+                        # We delay / pause loading of data to avoid overloading
+                        # of CCU / Homegear when doing auto detection
+                        time.sleep(delay)
+                    self._load_init_data_from_hm()
+                    _LOGGER.debug("%s datastruct: %s",
+                                  self._name, str(self._data))
+
+                    # Link events from pyhomatic
+                    self._subscribe_homematic_events()
+                    self._available = not self._hmdevice.UNREACH
+                # pylint: disable=broad-except
+                except Exception as err:
+                    self._connected = False
+                    self._available = False
+                    _LOGGER.error("Exception while linking %s: %s",
+                                  self._address, str(err))
+            else:
+                _LOGGER.critical("Delink %s object from HM!", self._name)
+                self._connected = False
+                self._available = False
+
+            # Update HA
+            _LOGGER.debug("%s linking down, send update_ha_state", self._name)
+            self.update_ha_state()
+        else:
+            _LOGGER.debug("%s not found in HOMEMATIC.devices", self._address)
+
+    def _hm_event_callback(self, device, caller, attribute, value):
+        """Handle all pyhomematic device events."""
+        _LOGGER.debug("%s receive event '%s' value: %s", self._name,
+                      attribute, value)
+        have_change = False
+
+        # Is data needed for this instance?
+        if attribute in self._data:
+            # Did data change?
+            if self._data[attribute] != value:
+                self._data[attribute] = value
+                have_change = True
+
+        # If available it has changed
+        if attribute is "UNREACH":
+            self._available = bool(value)
+            have_change = True
+
+        # If it has changed, update HA
+        if have_change:
+            _LOGGER.debug("%s update_ha_state after '%s'", self._name,
+                          attribute)
+            self.update_ha_state()
+
+            # Reset events
+            if attribute in self._hmdevice.EVENTNODE:
+                _LOGGER.debug("%s reset event", self._name)
+                self._data[attribute] = False
+                self.update_ha_state()
+
+    def _subscribe_homematic_events(self):
+        """Subscribe all required events to handle job."""
+        channels_to_sub = {}
+
+        # Push data to channels_to_sub from hmdevice metadata
+        for metadata in (self._hmdevice.SENSORNODE, self._hmdevice.BINARYNODE,
+                         self._hmdevice.ATTRIBUTENODE,
+                         self._hmdevice.WRITENODE, self._hmdevice.EVENTNODE,
+                         self._hmdevice.ACTIONNODE):
+            for node, channel in metadata.items():
+                # Data is needed for this instance
+                if node in self._data:
+                    # chan is current channel
+                    if channel == 'c' or channel is None:
+                        channel = self._channel
+                    # Prepare for subscription
+                    try:
+                        if int(channel) > 0:
+                            channels_to_sub.update({int(channel): True})
+                    except (ValueError, TypeError):
+                        _LOGGER("Invalid channel in metadata from %s",
+                                self._name)
+
+        # Set callbacks
+        for channel in channels_to_sub:
+            _LOGGER.debug("Subscribe channel %s from %s",
+                          str(channel), self._name)
+            self._hmdevice.setEventCallback(callback=self._hm_event_callback,
+                                            bequeath=False,
+                                            channel=channel)
+
+    def _load_init_data_from_hm(self):
+        """Load first value from pyhomematic."""
+        if not self._connected:
+            return False
+
+        # Read data from pyhomematic
+        for metadata, funct in (
+                (self._hmdevice.ATTRIBUTENODE,
+                 self._hmdevice.getAttributeData),
+                (self._hmdevice.WRITENODE, self._hmdevice.getWriteData),
+                (self._hmdevice.SENSORNODE, self._hmdevice.getSensorData),
+                (self._hmdevice.BINARYNODE, self._hmdevice.getBinaryData)):
+            for node in metadata:
+                if node in self._data:
+                    self._data[node] = funct(name=node, channel=self._channel)
+
+        # Set events to False
+        for node in self._hmdevice.EVENTNODE:
+            if node in self._data:
+                self._data[node] = False
+
+        return True
+
+    def _hm_set_state(self, value):
+        if self._state in self._data:
+            self._data[self._state] = value
+
+    def _hm_get_state(self):
+        if self._state in self._data:
+            return self._data[self._state]
+        return None
+
+    def _check_hm_to_ha_object(self):
+        """Check if it is possible to use the HM Object as this HA type.
+
+        NEEDS overwrite by inherit!
+        """
+        if not self._connected or self._hmdevice is None:
+            _LOGGER.error("HA object is not linked to homematic.")
+            return False
+
+        # Check if button option is correctly set for this object
+        if self._channel > self._hmdevice.ELEMENT:
+            _LOGGER.critical("Button option is not correct for this object!")
+            return False
+
+        return True
+
+    def _init_data_struct(self):
+        """Generate a data dict (self._data) from hm metadata.
+
+        NEEDS overwrite by inherit!
+        """
+        # Add all attributes to data dict
+        for data_note in self._hmdevice.ATTRIBUTENODE:
+            self._data.update({data_note: STATE_UNKNOWN})
diff --git a/homeassistant/components/light/homematic.py b/homeassistant/components/light/homematic.py
new file mode 100644
index 0000000000000000000000000000000000000000..159f3e4dbdcd2bd48ff640e891c1beb42ab9fa86
--- /dev/null
+++ b/homeassistant/components/light/homematic.py
@@ -0,0 +1,117 @@
+"""
+The homematic light platform.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/light.homematic/
+
+Important: For this platform to work the homematic component has to be
+properly configured.
+
+Configuration:
+
+light:
+  - platform: homematic
+    addresss: <Homematic addresss for device> # e.g. "JEQ0XXXXXXX"
+    name: <User defined name> (optional)
+    button: n (integer of channel to map, device-dependent)
+"""
+
+import logging
+from homeassistant.components.light import (ATTR_BRIGHTNESS, Light)
+from homeassistant.const import STATE_UNKNOWN
+import homeassistant.components.homematic as homematic
+
+_LOGGER = logging.getLogger(__name__)
+
+# List of component names (string) your component depends upon.
+DEPENDENCIES = ['homematic']
+
+
+def setup_platform(hass, config, add_callback_devices, discovery_info=None):
+    """Setup the platform."""
+    if discovery_info:
+        return homematic.setup_hmdevice_discovery_helper(HMLight,
+                                                         discovery_info,
+                                                         add_callback_devices)
+    # Manual
+    return homematic.setup_hmdevice_entity_helper(HMLight,
+                                                  config,
+                                                  add_callback_devices)
+
+
+class HMLight(homematic.HMDevice, Light):
+    """Represents a Homematic Light in Home Assistant."""
+
+    @property
+    def brightness(self):
+        """Return the brightness of this light between 0..255."""
+        if not self.available:
+            return None
+        # Is dimmer?
+        if self._state is "LEVEL":
+            return int(self._hm_get_state() * 255)
+        else:
+            return None
+
+    @property
+    def is_on(self):
+        """Return True if light is on."""
+        try:
+            return self._hm_get_state() > 0
+        except TypeError:
+            return False
+
+    def turn_on(self, **kwargs):
+        """Turn the light on."""
+        if not self.available:
+            return
+
+        if ATTR_BRIGHTNESS in kwargs and self._state is "LEVEL":
+            percent_bright = float(kwargs[ATTR_BRIGHTNESS]) / 255
+            self._hmdevice.set_level(percent_bright, self._channel)
+        else:
+            self._hmdevice.on(self._channel)
+
+    def turn_off(self, **kwargs):
+        """Turn the light off."""
+        if self.available:
+            self._hmdevice.off(self._channel)
+
+    def _check_hm_to_ha_object(self):
+        """Check if possible to use the HM Object as this HA type."""
+        from pyhomematic.devicetypes.actors import Dimmer, Switch
+
+        # Check compatibility from HMDevice
+        if not super()._check_hm_to_ha_object():
+            return False
+
+        # Check if the homematic device is correct for this HA device
+        if isinstance(self._hmdevice, Switch):
+            return True
+        if isinstance(self._hmdevice, Dimmer):
+            return True
+
+        _LOGGER.critical("This %s can't be use as light!", self._name)
+        return False
+
+    def _init_data_struct(self):
+        """Generate a data dict (self._data) from hm metadata."""
+        from pyhomematic.devicetypes.actors import Dimmer, Switch
+
+        super()._init_data_struct()
+
+        # Use STATE
+        if isinstance(self._hmdevice, Switch):
+            self._state = "STATE"
+
+        # Use LEVEL
+        if isinstance(self._hmdevice, Dimmer):
+            self._state = "LEVEL"
+
+        # Add state to data dict
+        if self._state:
+            _LOGGER.debug("%s init datadict with main node '%s'", self._name,
+                          self._state)
+            self._data.update({self._state: STATE_UNKNOWN})
+        else:
+            _LOGGER.critical("Can't correctly init light %s.", self._name)
diff --git a/homeassistant/components/rollershutter/homematic.py b/homeassistant/components/rollershutter/homematic.py
new file mode 100644
index 0000000000000000000000000000000000000000..737a7eb017ddc0dc309effd8bca3aee7e11b3857
--- /dev/null
+++ b/homeassistant/components/rollershutter/homematic.py
@@ -0,0 +1,110 @@
+"""
+The homematic rollershutter platform.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/rollershutter.homematic/
+
+Important: For this platform to work the homematic component has to be
+properly configured.
+
+Configuration:
+
+rollershutter:
+  - platform: homematic
+    address: "<Homematic address for device>" # e.g. "JEQ0XXXXXXX"
+    name: "<User defined name>" (optional)
+"""
+
+import logging
+from homeassistant.const import (STATE_OPEN, STATE_CLOSED, STATE_UNKNOWN)
+from homeassistant.components.rollershutter import RollershutterDevice,\
+    ATTR_CURRENT_POSITION
+import homeassistant.components.homematic as homematic
+
+
+_LOGGER = logging.getLogger(__name__)
+
+DEPENDENCIES = ['homematic']
+
+
+def setup_platform(hass, config, add_callback_devices, discovery_info=None):
+    """Setup the platform."""
+    if discovery_info:
+        return homematic.setup_hmdevice_discovery_helper(HMRollershutter,
+                                                         discovery_info,
+                                                         add_callback_devices)
+    # Manual
+    return homematic.setup_hmdevice_entity_helper(HMRollershutter,
+                                                  config,
+                                                  add_callback_devices)
+
+
+class HMRollershutter(homematic.HMDevice, RollershutterDevice):
+    """Represents a Homematic Rollershutter in Home Assistant."""
+
+    @property
+    def current_position(self):
+        """
+        Return current position of rollershutter.
+
+        None is unknown, 0 is closed, 100 is fully open.
+        """
+        if self.available:
+            return int((1 - self._hm_get_state()) * 100)
+        return None
+
+    def position(self, **kwargs):
+        """Move to a defined position: 0 (closed) and 100 (open)."""
+        if self.available:
+            if ATTR_CURRENT_POSITION in kwargs:
+                position = float(kwargs[ATTR_CURRENT_POSITION])
+                position = min(100, max(0, position))
+                level = (100 - position) / 100.0
+                self._hmdevice.set_level(level, self._channel)
+
+    @property
+    def state(self):
+        """Return the state of the rollershutter."""
+        current = self.current_position
+        if current is None:
+            return STATE_UNKNOWN
+
+        return STATE_CLOSED if current == 100 else STATE_OPEN
+
+    def move_up(self, **kwargs):
+        """Move the rollershutter up."""
+        if self.available:
+            self._hmdevice.move_up(self._channel)
+
+    def move_down(self, **kwargs):
+        """Move the rollershutter down."""
+        if self.available:
+            self._hmdevice.move_down(self._channel)
+
+    def stop(self, **kwargs):
+        """Stop the device if in motion."""
+        if self.available:
+            self._hmdevice.stop(self._channel)
+
+    def _check_hm_to_ha_object(self):
+        """Check if possible to use the HM Object as this HA type."""
+        from pyhomematic.devicetypes.actors import Blind
+
+        # Check compatibility from HMDevice
+        if not super()._check_hm_to_ha_object():
+            return False
+
+        # Check if the homematic device is correct for this HA device
+        if isinstance(self._hmdevice, Blind):
+            return True
+
+        _LOGGER.critical("This %s can't be use as rollershutter!", self._name)
+        return False
+
+    def _init_data_struct(self):
+        """Generate a data dict (self._data) from hm metadata."""
+        super()._init_data_struct()
+
+        # Add state to data dict
+        self._state = "LEVEL"
+        self._data.update({self._state: STATE_UNKNOWN})
diff --git a/homeassistant/components/sensor/homematic.py b/homeassistant/components/sensor/homematic.py
new file mode 100644
index 0000000000000000000000000000000000000000..f6f3825199b687ace3e77a1f9a0c55367a107ef8
--- /dev/null
+++ b/homeassistant/components/sensor/homematic.py
@@ -0,0 +1,124 @@
+"""
+The homematic sensor platform.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/sensor.homematic/
+
+Important: For this platform to work the homematic component has to be
+properly configured.
+
+Configuration:
+
+sensor:
+  - platform: homematic
+    address: <Homematic address for device> # e.g. "JEQ0XXXXXXX"
+    name: <User defined name> (optional)
+    param: <Name of datapoint to us as sensor> (optional)
+"""
+
+import logging
+from homeassistant.const import STATE_UNKNOWN
+import homeassistant.components.homematic as homematic
+
+_LOGGER = logging.getLogger(__name__)
+
+DEPENDENCIES = ['homematic']
+
+HM_STATE_HA_CAST = {
+    "RotaryHandleSensor": {0: "closed", 1: "tilted", 2: "open"}
+}
+
+HM_UNIT_HA_CAST = {
+    "HUMIDITY": "%",
+    "TEMPERATURE": "°C",
+    "BRIGHTNESS": "#",
+    "POWER": "W",
+    "CURRENT": "mA",
+    "VOLTAGE": "V",
+    "ENERGY_COUNTER": "Wh"
+}
+
+
+def setup_platform(hass, config, add_callback_devices, discovery_info=None):
+    """Setup the platform."""
+    if discovery_info:
+        return homematic.setup_hmdevice_discovery_helper(HMSensor,
+                                                         discovery_info,
+                                                         add_callback_devices)
+    # Manual
+    return homematic.setup_hmdevice_entity_helper(HMSensor,
+                                                  config,
+                                                  add_callback_devices)
+
+
+class HMSensor(homematic.HMDevice):
+    """Represents various Homematic sensors in Home Assistant."""
+
+    @property
+    def state(self):
+        """Return the state of the sensor."""
+        if not self.available:
+            return STATE_UNKNOWN
+
+        # Does a cast exist for this class?
+        name = self._hmdevice.__class__.__name__
+        if name in HM_STATE_HA_CAST:
+            return HM_STATE_HA_CAST[name].get(self._hm_get_state(), None)
+
+        # No cast, return original value
+        return self._hm_get_state()
+
+    @property
+    def unit_of_measurement(self):
+        """Return the unit of measurement of this entity, if any."""
+        if not self.available:
+            return None
+
+        return HM_UNIT_HA_CAST.get(self._state, None)
+
+    def _check_hm_to_ha_object(self):
+        """Check if possible to use the HM Object as this HA type."""
+        from pyhomematic.devicetypes.sensors import HMSensor as pyHMSensor
+
+        # Check compatibility from HMDevice
+        if not super()._check_hm_to_ha_object():
+            return False
+
+        # Check if the homematic device is correct for this HA device
+        if not isinstance(self._hmdevice, pyHMSensor):
+            _LOGGER.critical("This %s can't be use as sensor!", self._name)
+            return False
+
+        # Does user defined value exist?
+        if self._state and self._state not in self._hmdevice.SENSORNODE:
+            # pylint: disable=logging-too-many-args
+            _LOGGER.critical("This %s have no sensor with %s! Values are",
+                             self._name, self._state,
+                             str(self._hmdevice.SENSORNODE.keys()))
+            return False
+
+        # No param is set and more than 1 sensor nodes are present
+        if self._state is None and len(self._hmdevice.SENSORNODE) > 1:
+            _LOGGER.critical("This %s has multiple sensor nodes. " +
+                             "Please us param. Values are: %s", self._name,
+                             str(self._hmdevice.SENSORNODE.keys()))
+            return False
+
+        _LOGGER.debug("%s is okay for linking", self._name)
+        return True
+
+    def _init_data_struct(self):
+        """Generate a data dict (self._data) from hm metadata."""
+        super()._init_data_struct()
+
+        if self._state is None and len(self._hmdevice.SENSORNODE) == 1:
+            for value in self._hmdevice.SENSORNODE:
+                self._state = value
+
+        # Add state to data dict
+        if self._state:
+            _LOGGER.debug("%s init datadict with main node '%s'", self._name,
+                          self._state)
+            self._data.update({self._state: STATE_UNKNOWN})
+        else:
+            _LOGGER.critical("Can't correctly init sensor %s.", self._name)
diff --git a/homeassistant/components/switch/homematic.py b/homeassistant/components/switch/homematic.py
new file mode 100644
index 0000000000000000000000000000000000000000..16cc63a6708ad93bbefb6e2888f98784a691d9a9
--- /dev/null
+++ b/homeassistant/components/switch/homematic.py
@@ -0,0 +1,116 @@
+"""
+The homematic switch platform.
+
+For more details about this platform, please refer to the documentation at
+https://home-assistant.io/components/switch.homematic/
+
+Important: For this platform to work the homematic component has to be
+properly configured.
+
+Configuration:
+
+switch:
+  - platform: homematic
+    address: <Homematic address for device> # e.g. "JEQ0XXXXXXX"
+    name: <User defined name> (optional)
+    button: n (integer of channel to map, device-dependent) (optional)
+"""
+
+import logging
+from homeassistant.components.switch import SwitchDevice
+from homeassistant.const import STATE_UNKNOWN
+import homeassistant.components.homematic as homematic
+
+_LOGGER = logging.getLogger(__name__)
+
+DEPENDENCIES = ['homematic']
+
+
+def setup_platform(hass, config, add_callback_devices, discovery_info=None):
+    """Setup the platform."""
+    if discovery_info:
+        return homematic.setup_hmdevice_discovery_helper(HMSwitch,
+                                                         discovery_info,
+                                                         add_callback_devices)
+    # Manual
+    return homematic.setup_hmdevice_entity_helper(HMSwitch,
+                                                  config,
+                                                  add_callback_devices)
+
+
+class HMSwitch(homematic.HMDevice, SwitchDevice):
+    """Represents a Homematic Switch in Home Assistant."""
+
+    @property
+    def is_on(self):
+        """Return True if switch is on."""
+        try:
+            return self._hm_get_state() > 0
+        except TypeError:
+            return False
+
+    @property
+    def current_power_mwh(self):
+        """Return the current power usage in mWh."""
+        if "ENERGY_COUNTER" in self._data:
+            try:
+                return self._data["ENERGY_COUNTER"] / 1000
+            except ZeroDivisionError:
+                return 0
+
+        return None
+
+    def turn_on(self, **kwargs):
+        """Turn the switch on."""
+        if self.available:
+            self._hmdevice.on(self._channel)
+
+    def turn_off(self, **kwargs):
+        """Turn the switch off."""
+        if self.available:
+            self._hmdevice.off(self._channel)
+
+    def _check_hm_to_ha_object(self):
+        """Check if possible to use the HM Object as this HA type."""
+        from pyhomematic.devicetypes.actors import Dimmer, Switch
+
+        # Check compatibility from HMDevice
+        if not super()._check_hm_to_ha_object():
+            return False
+
+        # Check if the homematic device is correct for this HA device
+        if isinstance(self._hmdevice, Switch):
+            return True
+        if isinstance(self._hmdevice, Dimmer):
+            return True
+
+        _LOGGER.critical("This %s can't be use as switch!", self._name)
+        return False
+
+    def _init_data_struct(self):
+        """Generate a data dict (self._data) from hm metadata."""
+        from pyhomematic.devicetypes.actors import Dimmer,\
+            Switch, SwitchPowermeter
+
+        super()._init_data_struct()
+
+        # Use STATE
+        if isinstance(self._hmdevice, Switch):
+            self._state = "STATE"
+
+        # Use LEVEL
+        if isinstance(self._hmdevice, Dimmer):
+            self._state = "LEVEL"
+
+        # Need sensor values for SwitchPowermeter
+        if isinstance(self._hmdevice, SwitchPowermeter):
+            for node in self._hmdevice.SENSORNODE:
+                self._data.update({node: STATE_UNKNOWN})
+
+        # Add state to data dict
+        if self._state:
+            _LOGGER.debug("%s init data dict with main node '%s'", self._name,
+                          self._state)
+            self._data.update({self._state: STATE_UNKNOWN})
+        else:
+            _LOGGER.critical("Can't correctly init light %s.", self._name)
diff --git a/homeassistant/components/thermostat/homematic.py b/homeassistant/components/thermostat/homematic.py
index 6f1ff29c16c5c020233959d261cec13a00b10fee..d7675a5cd472c319b9c1942137e3a2f939d54b6b 100644
--- a/homeassistant/components/thermostat/homematic.py
+++ b/homeassistant/components/thermostat/homematic.py
@@ -1,121 +1,46 @@
 """
-Support for Homematic (HM-TC-IT-WM-W-EU, HM-CC-RT-DN) thermostats.
+The Homematic thermostat platform.
 
 For more details about this platform, please refer to the documentation at
 https://home-assistant.io/components/thermostat.homematic/
+
+Important: For this platform to work the homematic component has to be
+properly configured.
+
+Configuration:
+
+thermostat:
+  - platform: homematic
+    address: "<Homematic address for device>" # e.g. "JEQ0XXXXXXX"
+    name: "<User defined name>" (optional)
 """
-import logging
-import socket
-from xmlrpc.client import ServerProxy
-from xmlrpc.client import Error
-from collections import namedtuple
 
+import logging
+import homeassistant.components.homematic as homematic
 from homeassistant.components.thermostat import ThermostatDevice
-from homeassistant.const import TEMP_CELSIUS
 from homeassistant.helpers.temperature import convert
+from homeassistant.const import TEMP_CELSIUS, STATE_UNKNOWN
 
-REQUIREMENTS = []
+DEPENDENCIES = ['homematic']
 
 _LOGGER = logging.getLogger(__name__)
 
-CONF_ADDRESS = 'address'
-CONF_DEVICES = 'devices'
-CONF_ID = 'id'
-PROPERTY_SET_TEMPERATURE = 'SET_TEMPERATURE'
-PROPERTY_VALVE_STATE = 'VALVE_STATE'
-PROPERTY_ACTUAL_TEMPERATURE = 'ACTUAL_TEMPERATURE'
-PROPERTY_BATTERY_STATE = 'BATTERY_STATE'
-PROPERTY_LOWBAT = 'LOWBAT'
-PROPERTY_CONTROL_MODE = 'CONTROL_MODE'
-PROPERTY_BURST_MODE = 'BURST_RX'
-TYPE_HM_THERMOSTAT = 'HOMEMATIC_THERMOSTAT'
-TYPE_HM_WALLTHERMOSTAT = 'HOMEMATIC_WALLTHERMOSTAT'
-TYPE_MAX_THERMOSTAT = 'MAX_THERMOSTAT'
-
-HomematicConfig = namedtuple('HomematicConfig',
-                             ['device_type',
-                              'platform_type',
-                              'channel',
-                              'maint_channel'])
-
-HM_TYPE_MAPPING = {
-    'HM-CC-RT-DN': HomematicConfig('HM-CC-RT-DN',
-                                   TYPE_HM_THERMOSTAT,
-                                   4, 4),
-    'HM-CC-RT-DN-BoM': HomematicConfig('HM-CC-RT-DN-BoM',
-                                       TYPE_HM_THERMOSTAT,
-                                       4, 4),
-    'HM-TC-IT-WM-W-EU': HomematicConfig('HM-TC-IT-WM-W-EU',
-                                        TYPE_HM_WALLTHERMOSTAT,
-                                        2, 2),
-    'BC-RT-TRX-CyG': HomematicConfig('BC-RT-TRX-CyG',
-                                     TYPE_MAX_THERMOSTAT,
-                                     1, 0),
-    'BC-RT-TRX-CyG-2': HomematicConfig('BC-RT-TRX-CyG-2',
-                                       TYPE_MAX_THERMOSTAT,
-                                       1, 0),
-    'BC-RT-TRX-CyG-3': HomematicConfig('BC-RT-TRX-CyG-3',
-                                       TYPE_MAX_THERMOSTAT,
-                                       1, 0)
-}
-
-
-def setup_platform(hass, config, add_devices, discovery_info=None):
-    """Setup the Homematic thermostat."""
-    devices = []
-    try:
-        address = config[CONF_ADDRESS]
-        homegear = ServerProxy(address)
-
-        for name, device_cfg in config[CONF_DEVICES].items():
-            # get device description to detect the type
-            device_type = homegear.getDeviceDescription(
-                device_cfg[CONF_ID] + ':-1')['TYPE']
-
-            if device_type in HM_TYPE_MAPPING.keys():
-                devices.append(HomematicThermostat(
-                    HM_TYPE_MAPPING[device_type],
-                    address,
-                    device_cfg[CONF_ID],
-                    name))
-            else:
-                raise ValueError(
-                    "Device Type '{}' currently not supported".format(
-                        device_type))
-    except socket.error:
-        _LOGGER.exception("Connection error to homematic web service")
-        return False
-
-    add_devices(devices)
-
-    return True
-
 
-# pylint: disable=too-many-instance-attributes, abstract-method
-class HomematicThermostat(ThermostatDevice):
-    """Representation of a Homematic thermostat."""
+def setup_platform(hass, config, add_callback_devices, discovery_info=None):
+    """Setup the platform."""
+    if discovery_info:
+        return homematic.setup_hmdevice_discovery_helper(HMThermostat,
+                                                         discovery_info,
+                                                         add_callback_devices)
+    # Manual
+    return homematic.setup_hmdevice_entity_helper(HMThermostat,
+                                                  config,
+                                                  add_callback_devices)
 
-    def __init__(self, hm_config, address, _id, name):
-        """Initialize the thermostat."""
-        self._hm_config = hm_config
-        self.address = address
-        self._id = _id
-        self._name = name
-        self._full_device_name = '{}:{}'.format(self._id,
-                                                self._hm_config.channel)
-        self._maint_device_name = '{}:{}'.format(self._id,
-                                                 self._hm_config.maint_channel)
-        self._current_temperature = None
-        self._target_temperature = None
-        self._valve = None
-        self._battery = None
-        self._mode = None
-        self.update()
 
-    @property
-    def name(self):
-        """Return the name of the Homematic device."""
-        return self._name
+# pylint: disable=abstract-method
+class HMThermostat(homematic.HMDevice, ThermostatDevice):
+    """Represents a Homematic Thermostat in Home Assistant."""
 
     @property
     def unit_of_measurement(self):
@@ -125,26 +50,22 @@ class HomematicThermostat(ThermostatDevice):
     @property
     def current_temperature(self):
         """Return the current temperature."""
-        return self._current_temperature
+        if not self.available:
+            return None
+        return self._data["ACTUAL_TEMPERATURE"]
 
     @property
     def target_temperature(self):
-        """Return the temperature we try to reach."""
-        return self._target_temperature
+        """Return the target temperature."""
+        if not self.available:
+            return None
+        return self._data["SET_TEMPERATURE"]
 
     def set_temperature(self, temperature):
         """Set new target temperature."""
-        device = ServerProxy(self.address)
-        device.setValue(self._full_device_name,
-                        PROPERTY_SET_TEMPERATURE,
-                        temperature)
-
-    @property
-    def device_state_attributes(self):
-        """Return the device specific state attributes."""
-        return {"valve": self._valve,
-                "battery": self._battery,
-                "mode": self._mode}
+        if not self.available:
+            return None
+        self._hmdevice.set_temperature(temperature)
 
     @property
     def min_temp(self):
@@ -156,39 +77,27 @@ class HomematicThermostat(ThermostatDevice):
         """Return the maximum temperature - 30.5 means on."""
         return convert(30.5, TEMP_CELSIUS, self.unit_of_measurement)
 
-    def update(self):
-        """Update the data from the thermostat."""
-        try:
-            device = ServerProxy(self.address)
-            self._current_temperature = device.getValue(
-                self._full_device_name,
-                PROPERTY_ACTUAL_TEMPERATURE)
-            self._target_temperature = device.getValue(
-                self._full_device_name,
-                PROPERTY_SET_TEMPERATURE)
-            self._valve = device.getValue(
-                self._full_device_name,
-                PROPERTY_VALVE_STATE)
-            self._mode = device.getValue(
-                self._full_device_name,
-                PROPERTY_CONTROL_MODE)
-
-            if self._hm_config.platform_type in [TYPE_HM_THERMOSTAT,
-                                                 TYPE_HM_WALLTHERMOSTAT]:
-                self._battery = device.getValue(self._maint_device_name,
-                                                PROPERTY_BATTERY_STATE)
-            elif self._hm_config.platform_type == TYPE_MAX_THERMOSTAT:
-                # emulate homematic battery voltage,
-                # max reports lowbat if voltage < 2.2V
-                # while homematic battery_state should
-                # be between 1.5V and 4.6V
-                lowbat = device.getValue(self._maint_device_name,
-                                         PROPERTY_LOWBAT)
-                if lowbat:
-                    self._battery = 1.5
-                else:
-                    self._battery = 4.6
-
-        except Error:
-            _LOGGER.exception("Did not receive any temperature data from the "
-                              "homematic API.")
+    def _check_hm_to_ha_object(self):
+        """Check if possible to use the HM Object as this HA type."""
+        from pyhomematic.devicetypes.thermostats import HMThermostat\
+            as pyHMThermostat
+
+        # Check compatibility from HMDevice
+        if not super()._check_hm_to_ha_object():
+            return False
+
+        # Check if the homematic device correct for this HA device
+        if isinstance(self._hmdevice, pyHMThermostat):
+            return True
+
+        _LOGGER.critical("This %s can't be use as thermostat", self._name)
+        return False
+
+    def _init_data_struct(self):
+        """Generate a data dict (self._data) from hm metadata."""
+        super()._init_data_struct()
+
+        # Add state to data dict
+        self._data.update({"CONTROL_MODE": STATE_UNKNOWN,
+                           "SET_TEMPERATURE": STATE_UNKNOWN,
+                           "ACTUAL_TEMPERATURE": STATE_UNKNOWN})
diff --git a/requirements_all.txt b/requirements_all.txt
index 7360074d8ab60e863de0ebc48458c781c985626a..62a87fcc368f610f113ff8c0e1d979ed5438f9e9 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -260,6 +260,9 @@ pyenvisalink==1.0
 # homeassistant.components.ifttt
 pyfttt==0.3
 
+# homeassistant.components.homematic
+pyhomematic==0.1.6
+
 # homeassistant.components.device_tracker.icloud
 pyicloud==0.8.3