From 7536e825fa8e717366ccadd91da30a81859bda2b Mon Sep 17 00:00:00 2001 From: Open Home Automation Date: Fri, 7 Jul 2017 08:21:06 +0200 Subject: [PATCH] LaMetric platform and notify module (#8230) * First version of a LaMetrci platform with a Notify module * Cleanup, fix formatting bugs * More formatting * Formatting * Updated requirements * formatting * Formatting * More formatting * Dummy commit for new Travis CI run * Refactoring class methods to instance methods * Cleanup unused classed * Removed Eddystone_weatherurl that had nothing to do with this component * Cleanup class methods * Cleanup requirements * Removed broad excepts Removed storage of LaMetric devices * Removed unused import --- .coveragerc | 3 + homeassistant/components/lametric.py | 83 +++++++++++++++++++ homeassistant/components/notify/lametric.py | 91 +++++++++++++++++++++ requirements_all.txt | 4 + 4 files changed, 181 insertions(+) create mode 100644 homeassistant/components/lametric.py create mode 100644 homeassistant/components/notify/lametric.py diff --git a/.coveragerc b/.coveragerc index f1150512225..67b1225797d 100644 --- a/.coveragerc +++ b/.coveragerc @@ -92,6 +92,9 @@ omit = homeassistant/components/knx.py homeassistant/components/*/knx.py + homeassistant/components/lametric.py + homeassistant/components/*/lametric.py + homeassistant/components/lutron.py homeassistant/components/*/lutron.py diff --git a/homeassistant/components/lametric.py b/homeassistant/components/lametric.py new file mode 100644 index 00000000000..b11d874127f --- /dev/null +++ b/homeassistant/components/lametric.py @@ -0,0 +1,83 @@ +""" +Support for LaMetric time. + +This is the base platform to support LaMetric components: +Notify, Light, Mediaplayer + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/lametric/ +""" +import logging + +import voluptuous as vol + +import homeassistant.helpers.config_validation as cv + +REQUIREMENTS = ['lmnotify==0.0.4'] + +_LOGGER = logging.getLogger(__name__) + +CONF_CLIENT_ID = 'client_id' +CONF_CLIENT_SECRET = 'client_secret' + +DOMAIN = 'lametric' +LAMETRIC_DEVICES = 'LAMETRIC_DEVICES' + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({ + vol.Required(CONF_CLIENT_ID): cv.string, + vol.Required(CONF_CLIENT_SECRET): cv.string, + }), +}, extra=vol.ALLOW_EXTRA) + + +# pylint: disable=broad-except +def setup(hass, config): + """Set up the LaMetricManager.""" + _LOGGER.debug("Setting up LaMetric platform") + conf = config[DOMAIN] + hlmn = HassLaMetricManager(client_id=conf[CONF_CLIENT_ID], + client_secret=conf[CONF_CLIENT_SECRET]) + devices = hlmn.manager().get_devices() + + found = False + hass.data[DOMAIN] = hlmn + for dev in devices: + _LOGGER.debug("Discovered LaMetric device: %s", dev) + found = True + + return found + + +class HassLaMetricManager(): + """ + A class that encapsulated requests to the LaMetric manager. + + As the original class does not have a re-connect feature that is needed + for applications running for a long time as the OAuth tokens expire. This + class implements this reconnect() feature. + """ + + def __init__(self, client_id, client_secret): + """Initialize HassLaMetricManager and connect to LaMetric.""" + from lmnotify import LaMetricManager + + _LOGGER.debug("Connecting to LaMetric") + self.lmn = LaMetricManager(client_id, client_secret) + self._client_id = client_id + self._client_secret = client_secret + + def reconnect(self): + """ + Reconnect to LaMetric. + + This is usually necessary when the OAuth token is expired. + """ + from lmnotify import LaMetricManager + _LOGGER.debug("Reconnecting to LaMetric") + self.lmn = LaMetricManager(self._client_id, + self._client_secret) + + def manager(self): + """Return the global LaMetricManager instance.""" + return self.lmn diff --git a/homeassistant/components/notify/lametric.py b/homeassistant/components/notify/lametric.py new file mode 100644 index 00000000000..a3af1eb1914 --- /dev/null +++ b/homeassistant/components/notify/lametric.py @@ -0,0 +1,91 @@ +""" +Notifier for LaMetric time. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/notify.lametric/ +""" +import logging + +import voluptuous as vol + +from homeassistant.components.notify import ( + ATTR_TARGET, ATTR_DATA, PLATFORM_SCHEMA, BaseNotificationService) +from homeassistant.const import CONF_ICON +import homeassistant.helpers.config_validation as cv + +from homeassistant.components.lametric import DOMAIN + +REQUIREMENTS = ['lmnotify==0.0.4'] + +_LOGGER = logging.getLogger(__name__) + +CONF_DISPLAY_TIME = "display_time" + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Optional(CONF_ICON, default="i555"): cv.string, + vol.Optional(CONF_DISPLAY_TIME, default=10): cv.positive_int, +}) + + +# pylint: disable=unused-variable +def get_service(hass, config, discovery_info=None): + """Get the Slack notification service.""" + hlmn = hass.data.get(DOMAIN) + return LaMetricNotificationService(hlmn, + config[CONF_ICON], + config[CONF_DISPLAY_TIME] * 1000) + + +class LaMetricNotificationService(BaseNotificationService): + """Implement the notification service for LaMetric.""" + + def __init__(self, hasslametricmanager, icon, display_time): + """Initialize the service.""" + self.hasslametricmanager = hasslametricmanager + self._icon = icon + self._display_time = display_time + + # pylint: disable=broad-except + def send_message(self, message="", **kwargs): + """Send a message to some LaMetric deviced.""" + from lmnotify import SimpleFrame, Sound, Model + + targets = kwargs.get(ATTR_TARGET) + data = kwargs.get(ATTR_DATA) + _LOGGER.debug("Targets/Data: %s/%s", targets, data) + icon = self._icon + sound = None + + # User-defined icon? + if data is not None: + if "icon" in data: + icon = data["icon"] + if "sound" in data: + try: + sound = Sound(category="notifications", + sound_id=data["sound"]) + _LOGGER.debug("Adding notification sound %s", + data["sound"]) + except AssertionError: + _LOGGER.error("Sound ID %s unknown, ignoring", + data["sound"]) + + text_frame = SimpleFrame(icon, message) + _LOGGER.debug("Icon/Message/Duration: %s, %s, %d", + icon, message, self._display_time) + + frames = [text_frame] + + if sound is not None: + frames.append(sound) + + _LOGGER.debug(frames) + + model = Model(frames=frames) + lmn = self.hasslametricmanager.manager() + devices = lmn.get_devices() + for dev in devices: + if (targets is None) or (dev["name"] in targets): + lmn.set_device(dev) + lmn.send_notification(model, lifetime=self._display_time) + _LOGGER.debug("Sent notification to LaMetric %s", dev["name"]) diff --git a/requirements_all.txt b/requirements_all.txt index d00629c6a64..a459c65689d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -365,6 +365,10 @@ limitlessled==1.0.8 # homeassistant.components.media_player.liveboxplaytv liveboxplaytv==1.4.9 +# homeassistant.components.lametric +# homeassistant.components.notify.lametric +lmnotify==0.0.4 + # homeassistant.components.sensor.lyft lyft_rides==0.1.0b0