diff --git a/.coveragerc b/.coveragerc
index 938f42fe222527989d8807cc992f8f4e2546f539..2f1bcf735613bf85d2b4ee6c985517ddded488c5 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -203,6 +203,7 @@ omit =
     homeassistant/components/notify/twilio_sms.py
     homeassistant/components/notify/twitter.py
     homeassistant/components/notify/xmpp.py
+    homeassistant/components/nuimo_controller.py
     homeassistant/components/scene/hunterdouglas_powerview.py
     homeassistant/components/sensor/arest.py
     homeassistant/components/sensor/bitcoin.py
diff --git a/homeassistant/components/nuimo_controller.py b/homeassistant/components/nuimo_controller.py
new file mode 100644
index 0000000000000000000000000000000000000000..b383b4f45fcf0b705c3f1c0bc9f4b7037e2a6bcd
--- /dev/null
+++ b/homeassistant/components/nuimo_controller.py
@@ -0,0 +1,185 @@
+"""
+Component that connects to a Nuimo device over Bluetooth LE.
+
+For more details about this component, please refer to the documentation at
+https://home-assistant.io/components/nuimo_controller/
+"""
+import logging
+import threading
+import time
+import voluptuous as vol
+import homeassistant.helpers.config_validation as cv
+from homeassistant.const import (CONF_MAC, CONF_NAME, EVENT_HOMEASSISTANT_STOP)
+
+REQUIREMENTS = [
+    '--only-binary=all '  # avoid compilation of gattlib
+    'git+https://github.com/getSenic/nuimo-linux-python'
+    '#nuimo==1.0.0']
+
+_LOGGER = logging.getLogger(__name__)
+
+DOMAIN = 'nuimo_controller'
+EVENT_NUIMO = 'nuimo_input'
+
+DEFAULT_NAME = 'None'
+
+CONFIG_SCHEMA = vol.Schema({
+    DOMAIN: vol.Schema({
+        vol.Optional(CONF_MAC): cv.string,
+        vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string
+    }),
+}, extra=vol.ALLOW_EXTRA)
+
+SERVICE_NUIMO = 'led_matrix'
+DEFAULT_INTERVAL = 2.0
+
+SERVICE_NUIMO_SCHEMA = vol.Schema({
+    vol.Required('matrix'): cv.string,
+    vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
+    vol.Optional('interval', default=DEFAULT_INTERVAL): float
+})
+
+DEFAULT_ADAPTER = 'hci0'
+
+
+def setup(hass, config):
+    """Setup the Nuimo component."""
+    conf = config[DOMAIN]
+    mac = conf.get(CONF_MAC)
+    name = conf.get(CONF_NAME)
+    NuimoThread(hass, mac, name).start()
+    return True
+
+
+class NuimoLogger(object):  # pylint: disable=too-few-public-methods
+    """Handle Nuimo Controller event callbacks."""
+
+    def __init__(self, hass, name):
+        """Initialize Logger object."""
+        self._hass = hass
+        self._name = name
+
+    def received_gesture_event(self, event):
+        """Input Event received."""
+        _LOGGER.debug("received event: name=%s, gesture_id=%s,value=%s",
+                      event.name, event.gesture, event.value)
+        self._hass.bus.fire(EVENT_NUIMO,
+                            {'type': event.name, 'value': event.value,
+                             'name': self._name})
+
+
+class NuimoThread(threading.Thread):
+    """Manage one Nuimo controller."""
+
+    def __init__(self, hass, mac, name):
+        """Initialize thread object."""
+        super(NuimoThread, self).__init__()
+        self._hass = hass
+        self._mac = mac
+        self._name = name
+        self._hass_is_running = True
+        self._nuimo = None
+        self._listener = hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP,
+                                              self.stop)
+
+    def run(self):
+        """Setup connection or be idle."""
+        while self._hass_is_running:
+            if not self._nuimo or not self._nuimo.is_connected():
+                self._attach()
+                self._connect()
+            else:
+                time.sleep(1)
+
+        if self._nuimo:
+            self._nuimo.disconnect()
+            self._nuimo = None
+
+    def stop(self, event):  # pylint: disable=unused-argument
+        """Terminate Thread by unsetting flag."""
+        _LOGGER.debug('Stopping thread for Nuimo %s', self._mac)
+        self._hass_is_running = False
+        self._hass.bus.remove_listener(EVENT_HOMEASSISTANT_STOP,
+                                       self._listener)
+
+    def _attach(self):
+        """Create a nuimo object from mac address or discovery."""
+        # pylint: disable=import-error
+        from nuimo import NuimoController, NuimoDiscoveryManager
+
+        if self._nuimo:
+            self._nuimo.disconnect()
+            self._nuimo = None
+
+        if self._mac:
+            self._nuimo = NuimoController(self._mac)
+        else:
+            nuimo_manager = NuimoDiscoveryManager(
+                bluetooth_adapter=DEFAULT_ADAPTER, delegate=DiscoveryLogger())
+            nuimo_manager.start_discovery()
+            # Were any Nuimos found?
+            if not nuimo_manager.nuimos:
+                _LOGGER.debug('No Nuimos detected')
+                return
+            # Take the first Nuimo found.
+            self._nuimo = nuimo_manager.nuimos[0]
+            self._mac = self._nuimo.addr
+
+    def _connect(self):
+        """Build up connection and set event delegator and service."""
+        if not self._nuimo:
+            return
+
+        try:
+            self._nuimo.connect()
+            _LOGGER.debug('connected to %s', self._mac)
+        except RuntimeError as error:
+            _LOGGER.error('could not connect to %s: %s', self._mac, error)
+            time.sleep(1)
+            return
+
+        nuimo_event_delegate = NuimoLogger(self._hass, self._name)
+        self._nuimo.set_delegate(nuimo_event_delegate)
+
+        def handle_write_matrix(call):
+            """Handle led matrix service."""
+            matrix = call.data.get('matrix', None)
+            name = call.data.get(CONF_NAME, DEFAULT_NAME)
+            interval = call.data.get('interval', DEFAULT_INTERVAL)
+            if self._name == name and matrix:
+                self._nuimo.write_matrix(matrix, interval)
+
+        self._hass.services.register(DOMAIN, SERVICE_NUIMO,
+                                     handle_write_matrix,
+                                     schema=SERVICE_NUIMO_SCHEMA)
+
+        self._nuimo.write_matrix(HOMEASSIST_LOGO, 2.0)
+
+
+# must be 9x9 matrix
+HOMEASSIST_LOGO = (
+    "    .    " +
+    "   ...   " +
+    "  .....  " +
+    " ....... " +
+    "..... ..." +
+    " ....... " +
+    " .. .... " +
+    " .. .... " +
+    ".........")
+
+
+class DiscoveryLogger(object):
+    """Handle Nuimo Discovery callbacks."""
+
+    def discovery_started(self):  # pylint: disable=no-self-use
+        """Discovery startet."""
+        _LOGGER.info("started discovery")
+
+    def discovery_finished(self):  # pylint: disable=no-self-use
+        """Discovery finished."""
+        _LOGGER.info("finished discovery")
+
+    def controller_added(self, nuimo):  # pylint: disable=no-self-use
+        """Controller found."""
+        _LOGGER.info("added Nuimo: %s", nuimo)
diff --git a/requirements_all.txt b/requirements_all.txt
index 400ee949c7f9b3d0fa290fcd43cec8720dd3d1c3..1ecf40624630a96fe20d2eeb927db2f868fc1f59 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -7,6 +7,9 @@ jinja2>=2.8
 voluptuous==0.9.2
 typing>=3,<4
 
+# homeassistant.components.nuimo_controller
+--only-binary=all git+https://github.com/getSenic/nuimo-linux-python#nuimo==1.0.0
+
 # homeassistant.components.isy994
 PyISY==1.0.7