From 780060e582a44763128d9a8d52455279e426960d Mon Sep 17 00:00:00 2001 From: mischa Date: Sun, 3 Nov 2019 14:10:45 +0100 Subject: [PATCH] added bright|relax|dimmed|nightlight as option for daylight-trigger --- daylight-trigger.py | 47 +++++++++++++++++++++++++++++-------- get-sensors.py | 2 -- lightctl.py | 14 +++++------ wrapper-daylight-trigger.sh | 2 +- 4 files changed, 45 insertions(+), 20 deletions(-) diff --git a/daylight-trigger.py b/daylight-trigger.py index bc3005e..96502fa 100755 --- a/daylight-trigger.py +++ b/daylight-trigger.py @@ -25,6 +25,7 @@ parser.add_argument("bridge", type=str, help="Hue Bridge IP") parser.add_argument("token", type=str, help="Hue API Token") parser.add_argument("-s", "--sensor", type=int, required=True, help="sensor id#") parser.add_argument("-l", "--light", type=int, required=True, help="light id#") +parser.add_argument("-a", "--action", type=str, default='on', help="on|off|relax|bright|dimmed|nightlight") parser.add_argument("-v", "--verbose", action='store_true', help="verbose") parser.add_argument("-d", "--debug", action='store_true', help="debug") @@ -34,6 +35,7 @@ try: token = args.token sensor = args.sensor light = args.light + action = args.action verbose = args.verbose debug = args.debug @@ -44,6 +46,20 @@ no_cert_check = ssl.create_default_context() no_cert_check.check_hostname=False no_cert_check.verify_mode=ssl.CERT_NONE +scenes = {'br': {}, 'ct': {}, 'xt': {}} +scenes['br']['bright'] = b'{"on": true, "bri": 254, "alert": "none"}' +scenes['br']['relax'] = b'{"on": true, "bri": 144, "alert": "none"}' +scenes['br']['dimmed'] = b'{"on": true, "bri": 77, "alert": "none"}' +scenes['br']['nightlight'] = b'{"on": true, "bri": 1, "alert": "none"}' +scenes['ct']['bright'] = b'{"on": true, "bri": 254, "ct": 367, "alert": "none", "colormode": "ct"}' +scenes['ct']['relax'] = b'{"on": true, "bri": 144, "ct": 447, "alert": "none", "colormode": "ct"}' +scenes['ct']['dimmed'] = b'{"on": true, "bri": 77, "ct": 367, "alert": "none", "colormode": "ct"}' +scenes['ct']['nightlight'] = b'{"on": true, "bri": 1, "ct": 447, "alert": "none", "colormode": "ct"}' +scenes['xt']['bright'] = b'{"on": true, "bri": 254, "hue": 8402, "sat": 140, "effect": "none", "xy": [0.4578, 0.41], "ct": 367, "alert": "none", "colormode": "xy"}' +scenes['xt']['relax'] = b'{"on": true, "bri": 144, "hue": 8402, "sat": 140, "effect": "none", "xy": [0.5019, 0.4152], "ct": 447, "alert": "none", "colormode": "xy"}' +scenes['xt']['dimmed'] = b'{"on": true, "bri": 77, "hue": 8402, "sat": 140, "effect": "none", "xy": [0.4578, 0.41], "ct": 367, "alert": "none", "colormode": "xy"}' +scenes['xt']['nightlight'] = b'{"on": true, "bri": 1, "hue": 8402, "sat": 140, "effect": "none", "xy": [0.561, 0.4042], "ct": 367, "alert": "none", "colormode": "xy"}' + def get_state(type, id): url = f"https://{bridge}/api/{token}/{type}/{id}" req = urllib.request.Request(url) @@ -53,13 +69,26 @@ def get_state(type, id): if debug: print (f"State for {type[:-1]} id {id}:\n{json_data['state']}") return (json_data['state']) -def put_state(type, id, action): - if action == "on": - data = b'{"on": true, "bri": 77, "hue": 8402, "sat": 254, "effect": "none", "xy": [0.4578, 0.41], "ct": 367, "alert": "none", "colormode": "xy"}' - if action == "off": - data = b'{"on":false}' +def put_state(id, state, action): + if not 'colormode' in state: + if debug: print("state[colormode] not found, colormode set to: br") + colormode = "br" + else: + if debug: print(f"state[colormode] found, colormode set to: {state['colormode']}") + colormode = state['colormode'] - url = f"https://{bridge}/api/{token}/{type}/{id}/state" + if action == 'off': + if verbose or debug: print(f"Light {action}!") + data = b'{"on": false}' + elif action == 'on': + if verbose or debug: print(f"Light {action}!") + data = b'{"on": true}' + elif action in scenes[colormode]: + if verbose or debug: print(f"Light {action}!") + if debug: print(f"Light set to: {scenes[colormode][action]}") + data = scenes[colormode][action] + + url = f"https://{bridge}/api/{token}/lights/{id}/state" req = urllib.request.Request(url=url, data=data, method='PUT') res = urllib.request.urlopen(req, context=no_cert_check) if debug: print (f"PUT response: {res.status} {res.reason}") @@ -71,9 +100,7 @@ light_state = get_state("lights", light) if debug: print (f"Dark: {sensor_state['dark']}, Daylight: {sensor_state['daylight']}, Light On: {sensor_state['daylight']}") if sensor_state['dark'] and not light_state['on']: - if verbose or debug: print ("Light ON!") - put_state("lights", light, "on") + put_state(light, light_state, action) if not sensor_state['dark'] and light_state['on']: - if verbose or debug: print ("Light OFF!") - put_state("lights", light, "off") + put_state(light, light_state, "off") diff --git a/get-sensors.py b/get-sensors.py index ab5f50f..2da7ef4 100755 --- a/get-sensors.py +++ b/get-sensors.py @@ -56,7 +56,6 @@ for key in json_data: sensors[json_data[key]['uniqueid'][:-8]].append(key) for key in sensors: - #print(f"sens: {key} {sensors[key]}") for i in sensors[key]: if json_data.get(i)['type'] == 'ZLLPresence': print(json_data.get(i)['name']) @@ -65,4 +64,3 @@ for key in sensors: print(f"\t{i}: {json_data.get(i)['productname']}") if json_data.get(i)['type'] == 'ZLLTemperature': print(f"\t{i}: {json_data.get(i)['productname']}") - diff --git a/lightctl.py b/lightctl.py index bd6550c..82bf24a 100755 --- a/lightctl.py +++ b/lightctl.py @@ -22,7 +22,7 @@ import json parser = argparse.ArgumentParser(description="Control light") parser.add_argument("bridge", type=str, help="Hue Bridge IP") parser.add_argument("token", type=str, help="Hue API Token") -parser.add_argument("-i", "--id", type=int, required=True, help="light id#") +parser.add_argument("-l", "--light", type=int, required=True, help="light id#") parser.add_argument("-a", "--action", type=str, default='on', help="on|off|relax|bright|dimmed|nightlight") parser.add_argument("-v", "--verbose", action='store_true', help="verbose") parser.add_argument("-d", "--debug", action='store_true', help="debug") @@ -31,7 +31,7 @@ try: args = parser.parse_args() bridge = args.bridge token = args.token - light_id = args.id + light = args.light action = args.action verbose = args.verbose debug = args.debug @@ -76,13 +76,13 @@ def put_state(id, state): colormode = state['colormode'] if action == 'off': - if verbose or debug: print("Light {action}!") + if verbose or debug: print(f"Light {action}!") data = b'{"on": false}' elif action == 'on': - if verbose or debug: print("Light {action}!") + if verbose or debug: print(f"Light {action}!") data = b'{"on": true}' elif action in scenes[colormode]: - if verbose or debug: print("Light {action}!") + if verbose or debug: print(f"Light {action}!") if debug: print(f"Light set to: {scenes[colormode][action]}") data = scenes[colormode][action] @@ -93,5 +93,5 @@ def put_state(id, state): if verbose or debug: print (f"{res.status} {res.reason}") return(res) -light_state = get_state(light_id) -put_state(light_id, light_state) +light_state = get_state(light) +put_state(light, light_state) diff --git a/wrapper-daylight-trigger.sh b/wrapper-daylight-trigger.sh index 497e8c7..de09d64 100755 --- a/wrapper-daylight-trigger.sh +++ b/wrapper-daylight-trigger.sh @@ -7,4 +7,4 @@ PATH=$PATH:/usr/local/bin # # Sensor 50 to check # Light 24 to control -/home/mischa/hue/daylight-trigger.py 10.0.0.174 $(cat /home/mischa/hue-token) -s 50 -l 24 -v +/home/mischa/hue/daylight-trigger.py 10.0.0.174 $(cat /home/mischa/hue-token) -s 50 -l 24 -a dimmed -v