diff --git a/homeassistant/components/homekit/__init__.py b/homeassistant/components/homekit/__init__.py
index 63013bd8fc9a22e3d76ba248ecf5a7fde38775fd..b74171b08f7a17e164e8bb297aac695c0d444cbf 100644
--- a/homeassistant/components/homekit/__init__.py
+++ b/homeassistant/components/homekit/__init__.py
@@ -73,7 +73,8 @@ async def async_setup(hass, config):
 
 def get_accessory(hass, state, aid, config):
     """Take state and return an accessory object if supported."""
-    _LOGGER.debug('%s: <aid=%d config=%s>')
+    _LOGGER.debug('<entity_id=%s aid=%d config=%s>',
+                  state.entity_id, aid, config)
     if not aid:
         _LOGGER.warning('The entitiy "%s" is not supported, since it '
                         'generates an invalid aid, please change it.',
@@ -87,6 +88,11 @@ def get_accessory(hass, state, aid, config):
                           state.entity_id, 'TemperatureSensor')
             return TYPES['TemperatureSensor'](hass, state.entity_id,
                                               state.name, aid=aid)
+        elif unit == '%':
+            _LOGGER.debug('Add "%s" as %s"',
+                          state.entity_id, 'HumiditySensor')
+            return TYPES['HumiditySensor'](hass, state.entity_id, state.name,
+                                           aid=aid)
 
     elif state.domain == 'cover':
         # Only add covers that support set_cover_position
@@ -114,8 +120,11 @@ def get_accessory(hass, state, aid, config):
         return TYPES['Thermostat'](hass, state.entity_id,
                                    state.name, support_auto, aid=aid)
 
+    elif state.domain == 'light':
+        return TYPES['Light'](hass, state.entity_id, state.name, aid=aid)
+
     elif state.domain == 'switch' or state.domain == 'remote' \
-            or state.domain == 'input_boolean':
+            or state.domain == 'input_boolean' or state.domain == 'script':
         _LOGGER.debug('Add "%s" as "%s"', state.entity_id, 'Switch')
         return TYPES['Switch'](hass, state.entity_id, state.name, aid=aid)
 
@@ -175,7 +184,7 @@ class HomeKit():
 
         # pylint: disable=unused-variable
         from . import (  # noqa F401
-            type_covers, type_security_systems, type_sensors,
+            type_covers, type_lights, type_security_systems, type_sensors,
             type_switches, type_thermostats)
 
         for state in self._hass.states.all():
diff --git a/homeassistant/components/homekit/accessories.py b/homeassistant/components/homekit/accessories.py
index 0af25bc44538362f7659dee6b0fe64afca7be024..4c4409e6dfc79831bc71837756770a37f8318883 100644
--- a/homeassistant/components/homekit/accessories.py
+++ b/homeassistant/components/homekit/accessories.py
@@ -4,6 +4,8 @@ import logging
 from pyhap.accessory import Accessory, Bridge, Category
 from pyhap.accessory_driver import AccessoryDriver
 
+from homeassistant.helpers.event import async_track_state_change
+
 from .const import (
     ACCESSORY_MODEL, ACCESSORY_NAME, BRIDGE_MODEL, BRIDGE_NAME,
     MANUFACTURER, SERV_ACCESSORY_INFO, SERV_BRIDGING_STATE,
@@ -49,6 +51,8 @@ def override_properties(char, properties=None, valid_values=None):
 class HomeAccessory(Accessory):
     """Adapter class for Accessory."""
 
+    # pylint: disable=no-member
+
     def __init__(self, name=ACCESSORY_NAME, model=ACCESSORY_MODEL,
                  category='OTHER', **kwargs):
         """Initialize a Accessory object."""
@@ -59,6 +63,13 @@ class HomeAccessory(Accessory):
     def _set_services(self):
         add_preload_service(self, SERV_ACCESSORY_INFO)
 
+    def run(self):
+        """Method called by accessory after driver is started."""
+        state = self._hass.states.get(self._entity_id)
+        self.update_state(new_state=state)
+        async_track_state_change(
+            self._hass, self._entity_id, self.update_state)
+
 
 class HomeBridge(Bridge):
     """Adapter class for Bridge."""
diff --git a/homeassistant/components/homekit/const.py b/homeassistant/components/homekit/const.py
index d2b1caffe5326d4a910820e080bf2401e89543d3..a45c8298b78a7bbc19e198ff588ffb7408aed97b 100644
--- a/homeassistant/components/homekit/const.py
+++ b/homeassistant/components/homekit/const.py
@@ -23,10 +23,18 @@ BRIDGE_MODEL = 'homekit.bridge'
 BRIDGE_NAME = 'Home Assistant'
 MANUFACTURER = 'HomeAssistant'
 
+# #### Categories ####
+CATEGORY_LIGHT = 'LIGHTBULB'
+CATEGORY_SENSOR = 'SENSOR'
+
 
 # #### Services ####
 SERV_ACCESSORY_INFO = 'AccessoryInformation'
 SERV_BRIDGING_STATE = 'BridgingState'
+SERV_HUMIDITY_SENSOR = 'HumiditySensor'
+# CurrentRelativeHumidity | StatusActive, StatusFault, StatusTampered,
+# StatusLowBattery, Name
+SERV_LIGHTBULB = 'Lightbulb'  # On | Brightness, Hue, Saturation, Name
 SERV_SECURITY_SYSTEM = 'SecuritySystem'
 SERV_SWITCH = 'Switch'
 SERV_TEMPERATURE_SENSOR = 'TemperatureSensor'
@@ -36,20 +44,24 @@ SERV_WINDOW_COVERING = 'WindowCovering'
 
 # #### Characteristics ####
 CHAR_ACC_IDENTIFIER = 'AccessoryIdentifier'
+CHAR_BRIGHTNESS = 'Brightness'  # Int | [0, 100]
 CHAR_CATEGORY = 'Category'
 CHAR_COOLING_THRESHOLD_TEMPERATURE = 'CoolingThresholdTemperature'
 CHAR_CURRENT_HEATING_COOLING = 'CurrentHeatingCoolingState'
 CHAR_CURRENT_POSITION = 'CurrentPosition'
+CHAR_CURRENT_HUMIDITY = 'CurrentRelativeHumidity'  # percent
 CHAR_CURRENT_SECURITY_STATE = 'SecuritySystemCurrentState'
 CHAR_CURRENT_TEMPERATURE = 'CurrentTemperature'
 CHAR_HEATING_THRESHOLD_TEMPERATURE = 'HeatingThresholdTemperature'
+CHAR_HUE = 'Hue'  # arcdegress | [0, 360]
 CHAR_LINK_QUALITY = 'LinkQuality'
 CHAR_MANUFACTURER = 'Manufacturer'
 CHAR_MODEL = 'Model'
 CHAR_NAME = 'Name'
-CHAR_ON = 'On'
+CHAR_ON = 'On'  # boolean
 CHAR_POSITION_STATE = 'PositionState'
 CHAR_REACHABLE = 'Reachable'
+CHAR_SATURATION = 'Saturation'  # percent
 CHAR_SERIAL_NUMBER = 'SerialNumber'
 CHAR_TARGET_HEATING_COOLING = 'TargetHeatingCoolingState'
 CHAR_TARGET_POSITION = 'TargetPosition'
diff --git a/homeassistant/components/homekit/type_covers.py b/homeassistant/components/homekit/type_covers.py
index 0110bff318558dc2d37f2c98dcf1c7d11c2b73ac..36cfa4d635af7e314a1f95441b2ce86e6375f468 100644
--- a/homeassistant/components/homekit/type_covers.py
+++ b/homeassistant/components/homekit/type_covers.py
@@ -2,7 +2,6 @@
 import logging
 
 from homeassistant.components.cover import ATTR_CURRENT_POSITION
-from homeassistant.helpers.event import async_track_state_change
 
 from . import TYPES
 from .accessories import HomeAccessory, add_preload_service
@@ -22,7 +21,7 @@ class WindowCovering(HomeAccessory):
     """
 
     def __init__(self, hass, entity_id, display_name, *args, **kwargs):
-        """Initialize a Window accessory object."""
+        """Initialize a WindowCovering accessory object."""
         super().__init__(display_name, entity_id, 'WINDOW_COVERING',
                          *args, **kwargs)
 
@@ -45,14 +44,6 @@ class WindowCovering(HomeAccessory):
 
         self.char_target_position.setter_callback = self.move_cover
 
-    def run(self):
-        """Method called be object after driver is started."""
-        state = self._hass.states.get(self._entity_id)
-        self.update_cover_position(new_state=state)
-
-        async_track_state_change(
-            self._hass, self._entity_id, self.update_cover_position)
-
     def move_cover(self, value):
         """Move cover to value if call came from HomeKit."""
         if value != self.current_position:
@@ -65,8 +56,7 @@ class WindowCovering(HomeAccessory):
             self._hass.components.cover.set_cover_position(
                 value, self._entity_id)
 
-    def update_cover_position(self, entity_id=None, old_state=None,
-                              new_state=None):
+    def update_state(self, entity_id=None, old_state=None, new_state=None):
         """Update cover position after state changed."""
         if new_state is None:
             return
diff --git a/homeassistant/components/homekit/type_lights.py b/homeassistant/components/homekit/type_lights.py
new file mode 100644
index 0000000000000000000000000000000000000000..107ad1db1e4ab5953dec7ab2e970890a935ac276
--- /dev/null
+++ b/homeassistant/components/homekit/type_lights.py
@@ -0,0 +1,209 @@
+"""Class to hold all light accessories."""
+import logging
+
+from homeassistant.components.light import (
+    ATTR_RGB_COLOR, ATTR_BRIGHTNESS,
+    SUPPORT_BRIGHTNESS, SUPPORT_RGB_COLOR)
+from homeassistant.const import ATTR_SUPPORTED_FEATURES, STATE_ON, STATE_OFF
+
+from . import TYPES
+from .accessories import HomeAccessory, add_preload_service
+from .const import (
+    CATEGORY_LIGHT, SERV_LIGHTBULB,
+    CHAR_BRIGHTNESS, CHAR_HUE, CHAR_ON, CHAR_SATURATION)
+
+_LOGGER = logging.getLogger(__name__)
+
+RGB_COLOR = 'rgb_color'
+
+
+class Color:
+    """Class to handle color conversions."""
+
+    # pylint: disable=invalid-name
+
+    def __init__(self, hue=None, saturation=None):
+        """Initialize a new Color object."""
+        self.hue = hue                # [0, 360]
+        self.saturation = saturation  # [0, 1]
+
+    def calc_hsv_to_rgb(self):
+        """Convert hsv_color value to rgb_color."""
+        if not self.hue or not self.saturation:
+            return [None] * 3
+
+        i = int(self.hue / 60)
+        f = self.hue / 60 - i
+        v = 1
+        p = 1 - self.saturation
+        q = 1 - self.saturation * f
+        t = 1 - self.saturation * (1 - f)
+
+        rgb = []
+        if i in [0, 6]:
+            rgb = [v, t, p]
+        elif i == 1:
+            rgb = [q, v, p]
+        elif i == 2:
+            rgb = [p, v, t]
+        elif i == 3:
+            rgb = [p, q, v]
+        elif i == 4:
+            rgb = [t, p, v]
+        elif i == 5:
+            rgb = [v, p, q]
+
+        return [round(c * 255) for c in rgb]
+
+    @classmethod
+    def calc_rgb_to_hsv(cls, rgb_color):
+        """Convert a give rgb_color back to a hsv_color."""
+        rgb_color = [c / 255 for c in rgb_color]
+        c_max = max(rgb_color)
+        c_min = min(rgb_color)
+        c_diff = c_max - c_min
+        r, g, b = rgb_color
+
+        hue, saturation = 0, 0
+        if c_max == r:
+            hue = 60 * (0 + (g - b) / c_diff)
+        elif c_max == g:
+            hue = 60 * (2 + (b - r) / c_diff)
+        elif c_max == b:
+            hue = 60 * (4 + (r - g) / c_diff)
+
+        hue = round(hue + 360) if hue < 0 else round(hue)
+
+        if c_max != 0:
+            saturation = round((c_max - c_min) / c_max * 100)
+
+        return (hue, saturation)
+
+
+@TYPES.register('Light')
+class Light(HomeAccessory):
+    """Generate a Light accessory for a light entity.
+
+    Currently supports: state, brightness, rgb_color.
+    """
+
+    def __init__(self, hass, entity_id, name, *args, **kwargs):
+        """Initialize a new Light accessory object."""
+        super().__init__(name, entity_id, CATEGORY_LIGHT, *args, **kwargs)
+
+        self._hass = hass
+        self._entity_id = entity_id
+        self._flag = {CHAR_ON: False, CHAR_BRIGHTNESS: False,
+                      CHAR_HUE: False, CHAR_SATURATION: False,
+                      RGB_COLOR: False}
+
+        self.color = Color()
+
+        self.chars = []
+        self._features = self._hass.states.get(self._entity_id) \
+            .attributes.get(ATTR_SUPPORTED_FEATURES)
+        if self._features & SUPPORT_BRIGHTNESS:
+            self.chars.append(CHAR_BRIGHTNESS)
+        if self._features & SUPPORT_RGB_COLOR:
+            self.chars.append(CHAR_HUE)
+            self.chars.append(CHAR_SATURATION)
+
+        serv_light = add_preload_service(self, SERV_LIGHTBULB, self.chars)
+        self.char_on = serv_light.get_characteristic(CHAR_ON)
+        self.char_on.setter_callback = self.set_state
+        self.char_on.value = 0
+
+        if CHAR_BRIGHTNESS in self.chars:
+            self.char_brightness = serv_light \
+                .get_characteristic(CHAR_BRIGHTNESS)
+            self.char_brightness.setter_callback = self.set_brightness
+            self.char_brightness.value = 0
+        if CHAR_HUE in self.chars:
+            self.char_hue = serv_light.get_characteristic(CHAR_HUE)
+            self.char_hue.setter_callback = self.set_hue
+            self.char_hue.value = 0
+        if CHAR_SATURATION in self.chars:
+            self.char_saturation = serv_light \
+                .get_characteristic(CHAR_SATURATION)
+            self.char_saturation.setter_callback = self.set_saturation
+            self.char_saturation.value = 75
+
+    def set_state(self, value):
+        """Set state if call came from HomeKit."""
+        if self._flag[CHAR_BRIGHTNESS]:
+            return
+
+        _LOGGER.debug('%s: Set state to %d', self._entity_id, value)
+        self._flag[CHAR_ON] = True
+
+        if value == 1:
+            self._hass.components.light.turn_on(self._entity_id)
+        elif value == 0:
+            self._hass.components.light.turn_off(self._entity_id)
+
+    def set_brightness(self, value):
+        """Set brightness if call came from HomeKit."""
+        _LOGGER.debug('%s: Set brightness to %d', self._entity_id, value)
+        self._flag[CHAR_BRIGHTNESS] = True
+        self._hass.components.light.turn_on(
+            self._entity_id, brightness_pct=value)
+
+    def set_saturation(self, value):
+        """Set saturation if call came from HomeKit."""
+        _LOGGER.debug('%s: Set saturation to %d', self._entity_id, value)
+        self._flag[CHAR_SATURATION] = True
+        self.color.saturation = value / 100
+        self.set_color()
+
+    def set_hue(self, value):
+        """Set hue if call came from HomeKit."""
+        _LOGGER.debug('%s: Set hue to %d', self._entity_id, value)
+        self._flag[CHAR_HUE] = True
+        self.color.hue = value
+        self.set_color()
+
+    def set_color(self):
+        """Set color if call came from HomeKit."""
+        # Handle RGB Color
+        if self._features & SUPPORT_RGB_COLOR and self._flag[CHAR_HUE] and \
+                self._flag[CHAR_SATURATION]:
+            color = self.color.calc_hsv_to_rgb()
+            _LOGGER.debug('%s: Set rgb_color to %s', self._entity_id, color)
+            self._flag.update({
+                CHAR_HUE: False, CHAR_SATURATION: False, RGB_COLOR: True})
+            self._hass.components.light.turn_on(
+                self._entity_id, rgb_color=color)
+
+    def update_state(self, entity_id=None, old_state=None, new_state=None):
+        """Update light after state change."""
+        if not new_state:
+            return
+
+        # Handle State
+        state = new_state.state
+        if not self._flag[CHAR_ON] and state in [STATE_ON, STATE_OFF] and \
+                self.char_on.value != (state == STATE_ON):
+            self.char_on.set_value(state == STATE_ON, should_callback=False)
+        self._flag[CHAR_ON] = False
+
+        # Handle Brightness
+        if CHAR_BRIGHTNESS in self.chars:
+            brightness = new_state.attributes.get(ATTR_BRIGHTNESS)
+            if not self._flag[CHAR_BRIGHTNESS] and isinstance(brightness, int):
+                brightness = round(brightness / 255 * 100, 0)
+                if self.char_brightness.value != brightness:
+                    self.char_brightness.set_value(brightness,
+                                                   should_callback=False)
+            self._flag[CHAR_BRIGHTNESS] = False
+
+        # Handle RGB Color
+        if CHAR_SATURATION in self.chars and CHAR_HUE in self.chars:
+            rgb_color = new_state.attributes.get(ATTR_RGB_COLOR)
+            if not self._flag[RGB_COLOR] and \
+                isinstance(rgb_color, (list, tuple)) and \
+                    list(rgb_color) != self.color.calc_hsv_to_rgb():
+                hue, saturation = Color.calc_rgb_to_hsv(rgb_color)
+                self.char_hue.set_value(hue, should_callback=False)
+                self.char_saturation.set_value(saturation,
+                                               should_callback=False)
+            self._flag[RGB_COLOR] = False
diff --git a/homeassistant/components/homekit/type_security_systems.py b/homeassistant/components/homekit/type_security_systems.py
index 02742acb75d83edb7e497e7fd8a7000bf1bf1440..1d47160f9d246573d973c8c18f9c488cc8f07692 100644
--- a/homeassistant/components/homekit/type_security_systems.py
+++ b/homeassistant/components/homekit/type_security_systems.py
@@ -5,7 +5,6 @@ from homeassistant.const import (
     STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
     STATE_ALARM_ARMED_NIGHT, STATE_ALARM_DISARMED,
     ATTR_ENTITY_ID, ATTR_CODE)
-from homeassistant.helpers.event import async_track_state_change
 
 from . import TYPES
 from .accessories import HomeAccessory, add_preload_service
@@ -50,14 +49,6 @@ class SecuritySystem(HomeAccessory):
 
         self.char_target_state.setter_callback = self.set_security_state
 
-    def run(self):
-        """Method called be object after driver is started."""
-        state = self._hass.states.get(self._entity_id)
-        self.update_security_state(new_state=state)
-
-        async_track_state_change(self._hass, self._entity_id,
-                                 self.update_security_state)
-
     def set_security_state(self, value):
         """Move security state to value if call came from HomeKit."""
         _LOGGER.debug('%s: Set security state to %d',
@@ -69,8 +60,7 @@ class SecuritySystem(HomeAccessory):
         params = {ATTR_ENTITY_ID: self._entity_id, ATTR_CODE: self._alarm_code}
         self._hass.services.call('alarm_control_panel', service, params)
 
-    def update_security_state(self, entity_id=None,
-                              old_state=None, new_state=None):
+    def update_state(self, entity_id=None, old_state=None, new_state=None):
         """Update security state after state changed."""
         if new_state is None:
             return
diff --git a/homeassistant/components/homekit/type_sensors.py b/homeassistant/components/homekit/type_sensors.py
index 286862343f4d69b37928c9567e540e8100977904..759fda08a02a6db25d83234b30bf6cb2605f901d 100644
--- a/homeassistant/components/homekit/type_sensors.py
+++ b/homeassistant/components/homekit/type_sensors.py
@@ -3,13 +3,13 @@ import logging
 
 from homeassistant.const import (
     ATTR_UNIT_OF_MEASUREMENT, TEMP_FAHRENHEIT, TEMP_CELSIUS)
-from homeassistant.helpers.event import async_track_state_change
 
 from . import TYPES
 from .accessories import (
     HomeAccessory, add_preload_service, override_properties)
 from .const import (
-    SERV_TEMPERATURE_SENSOR, CHAR_CURRENT_TEMPERATURE, PROP_CELSIUS)
+    CATEGORY_SENSOR, SERV_HUMIDITY_SENSOR, SERV_TEMPERATURE_SENSOR,
+    CHAR_CURRENT_HUMIDITY, CHAR_CURRENT_TEMPERATURE, PROP_CELSIUS)
 
 
 _LOGGER = logging.getLogger(__name__)
@@ -29,6 +29,14 @@ def calc_temperature(state, unit=TEMP_CELSIUS):
     return round((value - 32) / 1.8, 2) if unit == TEMP_FAHRENHEIT else value
 
 
+def calc_humidity(state):
+    """Calculate humidity from state."""
+    try:
+        return float(state)
+    except ValueError:
+        return None
+
+
 @TYPES.register('TemperatureSensor')
 class TemperatureSensor(HomeAccessory):
     """Generate a TemperatureSensor accessory for a temperature sensor.
@@ -36,9 +44,9 @@ class TemperatureSensor(HomeAccessory):
     Sensor entity must return temperature in °C, °F.
     """
 
-    def __init__(self, hass, entity_id, display_name, *args, **kwargs):
+    def __init__(self, hass, entity_id, name, *args, **kwargs):
         """Initialize a TemperatureSensor accessory object."""
-        super().__init__(display_name, entity_id, 'SENSOR', *args, **kwargs)
+        super().__init__(name, entity_id, CATEGORY_SENSOR, *args, **kwargs)
 
         self._hass = hass
         self._entity_id = entity_id
@@ -49,23 +57,42 @@ class TemperatureSensor(HomeAccessory):
         self.char_temp.value = 0
         self.unit = None
 
-    def run(self):
-        """Method called be object after driver is started."""
-        state = self._hass.states.get(self._entity_id)
-        self.update_temperature(new_state=state)
-
-        async_track_state_change(
-            self._hass, self._entity_id, self.update_temperature)
-
-    def update_temperature(self, entity_id=None, old_state=None,
-                           new_state=None):
+    def update_state(self, entity_id=None, old_state=None, new_state=None):
         """Update temperature after state changed."""
         if new_state is None:
             return
 
         unit = new_state.attributes[ATTR_UNIT_OF_MEASUREMENT]
         temperature = calc_temperature(new_state.state, unit)
-        if temperature is not None:
-            self.char_temp.set_value(temperature)
+        if temperature:
+            self.char_temp.set_value(temperature, should_callback=False)
             _LOGGER.debug('%s: Current temperature set to %d°C',
                           self._entity_id, temperature)
+
+
+@TYPES.register('HumiditySensor')
+class HumiditySensor(HomeAccessory):
+    """Generate a HumiditySensor accessory as humidity sensor."""
+
+    def __init__(self, hass, entity_id, name, *args, **kwargs):
+        """Initialize a HumiditySensor accessory object."""
+        super().__init__(name, entity_id, CATEGORY_SENSOR, *args, **kwargs)
+
+        self._hass = hass
+        self._entity_id = entity_id
+
+        serv_humidity = add_preload_service(self, SERV_HUMIDITY_SENSOR)
+        self.char_humidity = serv_humidity \
+            .get_characteristic(CHAR_CURRENT_HUMIDITY)
+        self.char_humidity.value = 0
+
+    def update_state(self, entity_id=None, old_state=None, new_state=None):
+        """Update accessory after state change."""
+        if new_state is None:
+            return
+
+        humidity = calc_humidity(new_state.state)
+        if humidity:
+            self.char_humidity.set_value(humidity, should_callback=False)
+            _LOGGER.debug('%s: Current humidity set to %d%%',
+                          self._entity_id, humidity)
diff --git a/homeassistant/components/homekit/type_switches.py b/homeassistant/components/homekit/type_switches.py
index 989bf4e19f51b269ed783446bb95ef2f496ab6b5..fd3291ffe23e3434cce245b9e837ac0fa76d0ef4 100644
--- a/homeassistant/components/homekit/type_switches.py
+++ b/homeassistant/components/homekit/type_switches.py
@@ -4,7 +4,6 @@ import logging
 from homeassistant.const import (
     ATTR_ENTITY_ID, SERVICE_TURN_ON, SERVICE_TURN_OFF, STATE_ON)
 from homeassistant.core import split_entity_id
-from homeassistant.helpers.event import async_track_state_change
 
 from . import TYPES
 from .accessories import HomeAccessory, add_preload_service
@@ -32,14 +31,6 @@ class Switch(HomeAccessory):
         self.char_on.value = False
         self.char_on.setter_callback = self.set_state
 
-    def run(self):
-        """Method called be object after driver is started."""
-        state = self._hass.states.get(self._entity_id)
-        self.update_state(new_state=state)
-
-        async_track_state_change(self._hass, self._entity_id,
-                                 self.update_state)
-
     def set_state(self, value):
         """Move switch state to value if call came from HomeKit."""
         _LOGGER.debug('%s: Set switch state to %s',
diff --git a/homeassistant/components/homekit/type_thermostats.py b/homeassistant/components/homekit/type_thermostats.py
index 6e720c2214e397ff88a5c0b0fef3d0ca3edcf6b0..b73b492ba74d193e2b35f67e4c922bd0d240cca8 100644
--- a/homeassistant/components/homekit/type_thermostats.py
+++ b/homeassistant/components/homekit/type_thermostats.py
@@ -8,7 +8,6 @@ from homeassistant.components.climate import (
     STATE_HEAT, STATE_COOL, STATE_AUTO)
 from homeassistant.const import (
     ATTR_UNIT_OF_MEASUREMENT, TEMP_CELSIUS, TEMP_FAHRENHEIT)
-from homeassistant.helpers.event import async_track_state_change
 
 from . import TYPES
 from .accessories import HomeAccessory, add_preload_service
@@ -96,14 +95,6 @@ class Thermostat(HomeAccessory):
             self.char_cooling_thresh_temp = None
             self.char_heating_thresh_temp = None
 
-    def run(self):
-        """Method called be object after driver is started."""
-        state = self._hass.states.get(self._entity_id)
-        self.update_thermostat(new_state=state)
-
-        async_track_state_change(self._hass, self._entity_id,
-                                 self.update_thermostat)
-
     def set_heat_cool(self, value):
         """Move operation mode to value if call came from HomeKit."""
         if value in HC_HOMEKIT_TO_HASS:
@@ -142,8 +133,7 @@ class Thermostat(HomeAccessory):
         self._hass.components.climate.set_temperature(
             temperature=value, entity_id=self._entity_id)
 
-    def update_thermostat(self, entity_id=None,
-                          old_state=None, new_state=None):
+    def update_state(self, entity_id=None, old_state=None, new_state=None):
         """Update security state after state changed."""
         if new_state is None:
             return
diff --git a/tests/components/homekit/test_get_accessories.py b/tests/components/homekit/test_get_accessories.py
index 6e1c67cf2823f71aa930232734c2c1cdfec56454..e6dbe1ff729e5d6d8166aeacfcb691332d7c7004 100644
--- a/tests/components/homekit/test_get_accessories.py
+++ b/tests/components/homekit/test_get_accessories.py
@@ -53,6 +53,13 @@ class TestGetAccessories(unittest.TestCase):
                           {ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT})
             get_accessory(None, state, 2, {})
 
+    def test_sensor_humidity(self):
+        """Test humidity sensor with % as unit."""
+        with patch.dict(TYPES, {'HumiditySensor': self.mock_type}):
+            state = State('sensor.humidity', '20',
+                          {ATTR_UNIT_OF_MEASUREMENT: '%'})
+            get_accessory(None, state, 2, {})
+
     def test_cover_set_position(self):
         """Test cover with support for set_cover_position."""
         with patch.dict(TYPES, {'WindowCovering': self.mock_type}):
@@ -81,6 +88,12 @@ class TestGetAccessories(unittest.TestCase):
         self.assertEqual(
             self.mock_type.call_args[0][-1], False)  # support_auto
 
+    def test_light(self):
+        """Test light devices."""
+        with patch.dict(TYPES, {'Light': self.mock_type}):
+            state = State('light.test', 'on')
+            get_accessory(None, state, 2, {})
+
     def test_climate_support_auto(self):
         """Test climate devices with support for auto mode."""
         with patch.dict(TYPES, {'Thermostat': self.mock_type}):
diff --git a/tests/components/homekit/test_type_lights.py b/tests/components/homekit/test_type_lights.py
new file mode 100644
index 0000000000000000000000000000000000000000..0e102c53860fe96465414260dc0bb317668c4ad2
--- /dev/null
+++ b/tests/components/homekit/test_type_lights.py
@@ -0,0 +1,160 @@
+"""Test different accessory types: Lights."""
+import unittest
+
+from homeassistant.core import callback
+from homeassistant.components.homekit.type_lights import Light, Color
+from homeassistant.components.light import (
+    DOMAIN, ATTR_BRIGHTNESS, ATTR_BRIGHTNESS_PCT, ATTR_RGB_COLOR,
+    SUPPORT_BRIGHTNESS, SUPPORT_RGB_COLOR)
+from homeassistant.const import (
+    ATTR_DOMAIN, ATTR_ENTITY_ID, ATTR_SERVICE, ATTR_SERVICE_DATA,
+    ATTR_SUPPORTED_FEATURES, EVENT_CALL_SERVICE, SERVICE_TURN_ON,
+    SERVICE_TURN_OFF, STATE_ON, STATE_OFF, STATE_UNKNOWN)
+
+from tests.common import get_test_home_assistant
+
+
+def test_calc_hsv_to_rgb():
+    """Test conversion hsv to rgb."""
+    color = Color(43, 23 / 100)
+    assert color.calc_hsv_to_rgb() == [255, 238, 196]
+
+    color.hue, color.saturation = (79, 12 / 100)
+    assert color.calc_hsv_to_rgb() == [245, 255, 224]
+
+    color.hue, color.saturation = (177, 2 / 100)
+    assert color.calc_hsv_to_rgb() == [250, 255, 255]
+
+    color.hue, color.saturation = (212, 26 / 100)
+    assert color.calc_hsv_to_rgb() == [189, 220, 255]
+
+    color.hue, color.saturation = (271, 93 / 100)
+    assert color.calc_hsv_to_rgb() == [140, 18, 255]
+
+    color.hue, color.saturation = (355, 100 / 100)
+    assert color.calc_hsv_to_rgb() == [255, 0, 21]
+
+
+def test_calc_rgb_to_hsv():
+    """Test conversion rgb to hsv."""
+    assert Color.calc_rgb_to_hsv([255, 0, 21]) == (355, 100)
+    assert Color.calc_rgb_to_hsv([245, 255, 224]) == (79, 12)
+    assert Color.calc_rgb_to_hsv([189, 220, 255]) == (212, 26)
+
+
+class TestHomekitLights(unittest.TestCase):
+    """Test class for all accessory types regarding lights."""
+
+    def setUp(self):
+        """Setup things to be run when tests are started."""
+        self.hass = get_test_home_assistant()
+        self.events = []
+
+        @callback
+        def record_event(event):
+            """Track called event."""
+            self.events.append(event)
+
+        self.hass.bus.listen(EVENT_CALL_SERVICE, record_event)
+
+    def tearDown(self):
+        """Stop down everything that was started."""
+        self.hass.stop()
+
+    def test_light_basic(self):
+        """Test light with char state."""
+        entity_id = 'light.demo'
+        self.hass.states.set(entity_id, STATE_ON,
+                             {ATTR_SUPPORTED_FEATURES: 0})
+        acc = Light(self.hass, entity_id, 'Light', aid=2)
+        self.assertEqual(acc.aid, 2)
+        self.assertEqual(acc.category, 5)  # Lightbulb
+        self.assertEqual(acc.char_on.value, 0)
+
+        acc.run()
+        self.hass.block_till_done()
+        self.assertEqual(acc.char_on.value, 1)
+
+        self.hass.states.set(entity_id, STATE_OFF,
+                             {ATTR_SUPPORTED_FEATURES: 0})
+        self.hass.block_till_done()
+        self.assertEqual(acc.char_on.value, 0)
+
+        self.hass.states.set(entity_id, STATE_UNKNOWN)
+        self.hass.block_till_done()
+        self.assertEqual(acc.char_on.value, 0)
+
+        # Set from HomeKit
+        acc.char_on.set_value(True)
+        self.hass.block_till_done()
+        self.assertEqual(
+            self.events[0].data[ATTR_DOMAIN], DOMAIN)
+        self.assertEqual(
+            self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON)
+
+        acc.char_on.set_value(False)
+        self.hass.block_till_done()
+        self.assertEqual(
+            self.events[1].data[ATTR_DOMAIN], DOMAIN)
+        self.assertEqual(
+            self.events[1].data[ATTR_SERVICE], SERVICE_TURN_OFF)
+
+        # Remove entity
+        self.hass.states.remove(entity_id)
+        self.hass.block_till_done()
+
+    def test_light_brightness(self):
+        """Test light with brightness."""
+        entity_id = 'light.demo'
+        self.hass.states.set(entity_id, STATE_ON, {
+            ATTR_SUPPORTED_FEATURES: SUPPORT_BRIGHTNESS, ATTR_BRIGHTNESS: 255})
+        acc = Light(self.hass, entity_id, 'Light', aid=2)
+        self.assertEqual(acc.char_brightness.value, 0)
+
+        acc.run()
+        self.hass.block_till_done()
+        self.assertEqual(acc.char_brightness.value, 100)
+
+        self.hass.states.set(entity_id, STATE_ON, {ATTR_BRIGHTNESS: 102})
+        self.hass.block_till_done()
+        self.assertEqual(acc.char_brightness.value, 40)
+
+        # Set from HomeKit
+        acc.char_brightness.set_value(20)
+        acc.char_on.set_value(1)
+        self.hass.block_till_done()
+        self.assertEqual(
+            self.events[0].data[ATTR_DOMAIN], DOMAIN)
+        self.assertEqual(
+            self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON)
+        print(self.events[0].data)
+        self.assertEqual(
+            self.events[0].data[ATTR_SERVICE_DATA], {
+                ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS_PCT: 20})
+
+    def test_light_rgb_color(self):
+        """Test light with rgb_color."""
+        entity_id = 'light.demo'
+        self.hass.states.set(entity_id, STATE_ON, {
+            ATTR_SUPPORTED_FEATURES: SUPPORT_RGB_COLOR,
+            ATTR_RGB_COLOR: (120, 20, 300)})
+        acc = Light(self.hass, entity_id, 'Light', aid=2)
+        self.assertEqual(acc.char_hue.value, 0)
+        self.assertEqual(acc.char_saturation.value, 75)
+
+        acc.run()
+        self.hass.block_till_done()
+        self.assertEqual(acc.char_hue.value, 261)
+        self.assertEqual(acc.char_saturation.value, 93)
+
+        # Set from HomeKit
+        acc.char_hue.set_value(145)
+        acc.char_saturation.set_value(75)
+        self.hass.block_till_done()
+        self.assertEqual(
+            self.events[0].data[ATTR_DOMAIN], DOMAIN)
+        self.assertEqual(
+            self.events[0].data[ATTR_SERVICE], SERVICE_TURN_ON)
+        self.assertEqual(
+            self.events[0].data[ATTR_SERVICE_DATA], {
+                ATTR_ENTITY_ID: entity_id, ATTR_RGB_COLOR: [64, 255, 143]})
diff --git a/tests/components/homekit/test_type_sensors.py b/tests/components/homekit/test_type_sensors.py
index f9a14f6b8cf13959e0f8fc42c256223dbf3cccf8..b533c896019beb5e2fc0ea863c377801647b3510 100644
--- a/tests/components/homekit/test_type_sensors.py
+++ b/tests/components/homekit/test_type_sensors.py
@@ -3,7 +3,7 @@ import unittest
 
 from homeassistant.components.homekit.const import PROP_CELSIUS
 from homeassistant.components.homekit.type_sensors import (
-    TemperatureSensor, calc_temperature)
+    TemperatureSensor, HumiditySensor, calc_temperature, calc_humidity)
 from homeassistant.const import (
     ATTR_UNIT_OF_MEASUREMENT, STATE_UNKNOWN, TEMP_CELSIUS, TEMP_FAHRENHEIT)
 
@@ -22,6 +22,15 @@ def test_calc_temperature():
     assert calc_temperature('-20.6', TEMP_FAHRENHEIT) == -29.22
 
 
+def test_calc_humidity():
+    """Test if humidity is a integer."""
+    assert calc_humidity(STATE_UNKNOWN) is None
+    assert calc_humidity('test') is None
+
+    assert calc_humidity('20') == 20
+    assert calc_humidity('75.2') == 75.2
+
+
 class TestHomekitSensors(unittest.TestCase):
     """Test class for all accessory types regarding sensors."""
 
@@ -60,3 +69,23 @@ class TestHomekitSensors(unittest.TestCase):
                              {ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT})
         self.hass.block_till_done()
         self.assertEqual(acc.char_temp.value, 24)
+
+    def test_humidity(self):
+        """Test if accessory is updated after state change."""
+        entity_id = 'sensor.humidity'
+
+        acc = HumiditySensor(self.hass, entity_id, 'Humidity', aid=2)
+        acc.run()
+
+        self.assertEqual(acc.aid, 2)
+        self.assertEqual(acc.category, 10)  # Sensor
+
+        self.assertEqual(acc.char_humidity.value, 0)
+
+        self.hass.states.set(entity_id, STATE_UNKNOWN,
+                             {ATTR_UNIT_OF_MEASUREMENT: "%"})
+        self.hass.block_till_done()
+
+        self.hass.states.set(entity_id, '20', {ATTR_UNIT_OF_MEASUREMENT: "%"})
+        self.hass.block_till_done()
+        self.assertEqual(acc.char_humidity.value, 20)