Added Philips Hue lights backend to monitor status changes to the lights
This commit is contained in:
parent
7c02c70663
commit
d50d92e99e
4 changed files with 150 additions and 0 deletions
|
@ -15,6 +15,7 @@ Backends
|
|||
platypush/backend/http.rst
|
||||
platypush/backend/inotify.rst
|
||||
platypush/backend/kafka.rst
|
||||
platypush/backend/light.hue.rst
|
||||
platypush/backend/midi.rst
|
||||
platypush/backend/mqtt.rst
|
||||
platypush/backend/music.mpd.rst
|
||||
|
|
|
@ -13,6 +13,7 @@ Events
|
|||
platypush/events/http.rst
|
||||
platypush/events/joystick.rst
|
||||
platypush/events/kafka.rst
|
||||
platypush/events/light.rst
|
||||
platypush/events/midi.rst
|
||||
platypush/events/music.rst
|
||||
platypush/events/music.snapcast.rst
|
||||
|
|
93
platypush/backend/light/hue.py
Normal file
93
platypush/backend/light/hue.py
Normal file
|
@ -0,0 +1,93 @@
|
|||
import json
|
||||
import time
|
||||
|
||||
from threading import Thread
|
||||
|
||||
from platypush.backend import Backend
|
||||
from platypush.context import get_plugin
|
||||
from platypush.message.event.light import LightStatusChangeEvent
|
||||
|
||||
|
||||
class LightHueBackend(Backend):
|
||||
"""
|
||||
This backend will periodically check for the status of your configured
|
||||
Philips Hue light devices and trigger events when the status of a device
|
||||
(power, saturation, brightness or hue) changes.
|
||||
|
||||
Triggers:
|
||||
|
||||
* :class:`platypush.message.event.light.LightStatusChangeEvent` when the
|
||||
status of a lightbulb changes
|
||||
|
||||
Requires:
|
||||
|
||||
* The :class:`platypush.plugins.light.hue.LightHuePlugin` plugin to be
|
||||
active and configured.
|
||||
"""
|
||||
|
||||
_DEFAULT_POLL_SECONDS = 10
|
||||
|
||||
def __init__(self, poll_seconds=_DEFAULT_POLL_SECONDS, *args, **kwargs):
|
||||
"""
|
||||
:param poll_seconds: How often the backend will poll the Hue plugin for
|
||||
status updates. Default: 10 seconds
|
||||
:type poll_seconds: float
|
||||
"""
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
self.poll_seconds = poll_seconds
|
||||
|
||||
|
||||
def _get_lights(self):
|
||||
return get_plugin('light.hue').get_lights().output
|
||||
|
||||
def _listener(self):
|
||||
def _thread():
|
||||
lights = self._get_lights()
|
||||
|
||||
while not self.should_stop():
|
||||
try:
|
||||
lights_new = self._get_lights()
|
||||
|
||||
for light_id, light in lights_new.items():
|
||||
event_args = {}
|
||||
state = light.get('state')
|
||||
prev_state = lights.get(light_id, {}).get('state', {})
|
||||
|
||||
if 'on' in state and state.get('on') != prev_state.get('on'):
|
||||
event_args['on'] = state.get('on')
|
||||
if 'bri' in state and state.get('bri') != prev_state.get('bri'):
|
||||
event_args['bri'] = state.get('bri')
|
||||
if 'sat' in state and state.get('sat') != prev_state.get('sat'):
|
||||
event_args['sat'] = state.get('sat')
|
||||
if 'hue' in state and state.get('hue') != prev_state.get('hue'):
|
||||
event_args['hue'] = state.get('hue')
|
||||
if 'ct' in state and state.get('ct') != prev_state.get('ct'):
|
||||
event_args['ct'] = state.get('ct')
|
||||
|
||||
if event_args:
|
||||
event_args['light_id'] = light_id
|
||||
event_args['light_name'] = light.get('name')
|
||||
self.bus.post(LightStatusChangeEvent(**event_args))
|
||||
|
||||
lights = lights_new
|
||||
except Exception as e:
|
||||
self.logger.exception(e)
|
||||
finally:
|
||||
time.sleep(self.poll_seconds)
|
||||
|
||||
return _thread
|
||||
|
||||
def run(self):
|
||||
super().run()
|
||||
|
||||
while not self.should_stop():
|
||||
try:
|
||||
poll_thread = Thread(target=self._listener())
|
||||
poll_thread.start()
|
||||
poll_thread.join()
|
||||
except Exception as e:
|
||||
self.logger.exception(e)
|
||||
time.sleep(self.poll_seconds)
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
55
platypush/message/event/light.py
Normal file
55
platypush/message/event/light.py
Normal file
|
@ -0,0 +1,55 @@
|
|||
from platypush.message.event import Event
|
||||
|
||||
|
||||
class LightStatusChangeEvent(Event):
|
||||
"""
|
||||
Event triggered when the state of a lightbulb changes
|
||||
"""
|
||||
|
||||
def __init__(self, light_id=None, light_name=None, on=None, bri=None,
|
||||
sat=None, hue=None, ct=None, *args, **kwargs):
|
||||
"""
|
||||
:param light_id: Light ID that triggered the event
|
||||
:type light_id: int
|
||||
|
||||
:param light_name: Light name that triggered the event
|
||||
:type light_name: str
|
||||
|
||||
:param on: Set if the power state of the bulb changed
|
||||
:type on: bool
|
||||
|
||||
:param bri: Set if the brightness state of the bulb changed
|
||||
:type bri: int
|
||||
|
||||
:param sat: Set if the saturation state of the bulb changed
|
||||
:type sat: int
|
||||
|
||||
:param hue: Set if the hue state of the bulb changed
|
||||
:type hue: int
|
||||
|
||||
:param ct: Set if the color temperature state of the bulb changed
|
||||
:type ct: int
|
||||
"""
|
||||
|
||||
attrs = {}
|
||||
|
||||
if light_id is not None:
|
||||
attrs['light_id'] = light_id
|
||||
if light_name is not None:
|
||||
attrs['light_name'] = light_name
|
||||
if on is not None:
|
||||
attrs['on'] = on
|
||||
if bri is not None:
|
||||
attrs['bri'] = bri
|
||||
if sat is not None:
|
||||
attrs['sat'] = sat
|
||||
if hue is not None:
|
||||
attrs['hue'] = hue
|
||||
if ct is not None:
|
||||
attrs['ct'] = ct
|
||||
|
||||
super().__init__(*args, **attrs, **kwargs)
|
||||
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
||||
|
Loading…
Reference in a new issue