From cff53e746a1cc8d4d8f749c5b8388814527094c2 Mon Sep 17 00:00:00 2001 From: Bob Carroll Date: Sat, 3 Sep 2022 15:10:35 -0500 Subject: [PATCH] add topics for light attributes --- cherry/light/__init__.py | 22 ++++++++++++++++++---- cherry/light/hue.py | 32 ++++++++++++++++++++++++++++++++ setup.py | 2 +- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/cherry/light/__init__.py b/cherry/light/__init__.py index 3f7642e..cbec223 100644 --- a/cherry/light/__init__.py +++ b/cherry/light/__init__.py @@ -38,14 +38,23 @@ async def on_light_set(client, mappings, messages): """ async for m in messages: try: - platform, name, event = m.topic.split('/') - state = umsgpack.unpackb(m.payload) + # TODO + # platform, name, event = m.topic.split('/') + paths = m.topic.split('/') + if len(paths) == 4: + platform, name, event, _ = paths + else: + platform, name, event = paths + light = mappings.get(name) if light is None: logging.error(f'Light {name} is not defined in configuration') - elif light.get('platform') == 'hue': + elif light.get('platform') == 'hue' and event in ['state', 'set']: # TODO + state = umsgpack.unpackb(m.payload) await hue.set_state(client, light, state) + elif light.get('platform') == 'hue': + await hue.set_attr(client, light, event, m.payload) else: logging.error(f'Light {name} platform is not implemented') except Exception as ex: @@ -82,7 +91,12 @@ async def init(config): logging.info('Connected to mqtt broker') topics = { - 'light/+/set': on_light_set, + 'light/+/brightness/set': on_light_set, + 'light/+/mode/set': on_light_set, + 'light/+/on/set': on_light_set, + 'light/+/set': on_light_set, # TODO + 'light/+/state/set': on_light_set, + 'light/+/temperature/set': on_light_set, 'hue/group/+/state': hue.receive_state, 'hue/light/+/state': hue.receive_state} diff --git a/cherry/light/hue.py b/cherry/light/hue.py index db3584d..fd3a447 100644 --- a/cherry/light/hue.py +++ b/cherry/light/hue.py @@ -107,6 +107,27 @@ async def set_state(client, light, state): await client.publish(f'hue/{dc}/{id_}/state/set', payload) +async def set_attr(client, light, attr, value): + """ + Updates single state attribute of a Hue device. + + :param client: mqtt client + :param light: light configuration + :param attr: state dictionary key + :param value: new value + """ + if attr == 'mode': + state = {'mode': value} + elif attr == 'brightness': + state = {'mode': 'dim', 'brightness': value} + elif attr == 'on': + state = {'mode': 'on' if int(value) else 'off'} + elif attr == 'temperature': + state = {'mode': 'on', 'effect': {'type': 'temperature', 'value': value}} + + await set_state(client, light, state) + + async def pivot_map(m): """ Inverts the light configuration mapping for fast device look-ups. @@ -153,17 +174,28 @@ async def receive_state(client, mappings, messages): if is_on and 'bri' in state: bri = round((state['bri'] / 255) * 100) payload.update({'mode': 'dim', 'brightness': int(bri)}) + await client.publish(f'light/{name}/mode', 'dim', retain=True) + await client.publish(f'light/{name}/brightness', int(bri), retain=True) elif is_on: payload['mode'] = 'on' + await client.publish(f'light/{name}/mode', 'on', retain=True) + await client.publish(f'light/{name}/brightness', 100, retain=True) else: payload['mode'] = 'off' + await client.publish(f'light/{name}/mode', 'off', retain=True) + await client.publish(f'light/{name}/brightness', 0, retain=True) if is_on and state.get('colormode') == 'ct': payload['effect'] = {'type': 'temperature', 'value': state['ct']} + await client.publish(f'light/{name}/temperature', state['ct'], retain=True) elif is_on and state.get('colormode') == 'hue': payload['effect'] = {'type': 'color', 'value': {'hue': state['hue'], 'saturation': state['saturation']}} + await client.publish(f'light/{name}/hue', state['hue'], retain=True) + await client.publish(f'light/{name}/saturation', state['saturation'], retain=True) + + await client.publish(f'light/{name}/on', int(is_on), retain=True) logging.debug(f'Announcing light state for {name}: {payload}') payload = umsgpack.packb(payload) diff --git a/setup.py b/setup.py index 5d224aa..a80785d 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_namespace_packages setup(name='cherry-light', - version='0.1', + version='0.2', description='Provides an abstraction for lighting protocols', author='Bob Carroll', author_email='bob.carroll@alum.rit.edu',