Nuimo controller component based on SDK (#3039)
This commit is contained in:
parent
b58976bc36
commit
c693db49b3
3 changed files with 189 additions and 0 deletions
|
@ -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
|
||||
|
|
185
homeassistant/components/nuimo_controller.py
Normal file
185
homeassistant/components/nuimo_controller.py
Normal file
|
@ -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)
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue