From a51ac1e29eacbfcf7ff13d0d56528100f9cc28f1 Mon Sep 17 00:00:00 2001 From: makefu Date: Thu, 11 May 2017 15:39:06 +0200 Subject: init --- __init__.py | 0 ampel.py | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fade.py | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ times.json | 33 ++++++++++++++++++++++++ 4 files changed, 194 insertions(+) create mode 100644 __init__.py create mode 100755 ampel.py create mode 100755 fade.py create mode 100644 times.json diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ampel.py b/ampel.py new file mode 100755 index 0000000..5b1391f --- /dev/null +++ b/ampel.py @@ -0,0 +1,83 @@ +#! /usr/bin/env nix-shell +#! nix-shell -i python3 -p python3 python35Packages.docopt python35Packages.paho-mqtt +""" usage: ampel [options] NUMLEDS TIMEFILE + + --mqtt-server=HOST path to mqtt server [Default: 192.168.8.11] + +NUMLEDS is the number of leds to output data for (--add-empty does not count in here) +TIMEFILE refers to a json file which contains all the dates where the bus +drives + +13 22 24 26 28 +|-----------|----|----|----| +BLUE GR YEL RED BLUE + EEN LOW +""" +from docopt import docopt +from fade import calc_chain +import time +from time import sleep +import json +import sys +from datetime import datetime, timedelta + +import paho.mqtt.client as mqtt + +red = timedelta(minutes=2) +orange = timedelta(minutes=3) +yellow = timedelta(minutes=4) +green = timedelta(minutes=6) +maxtime = timedelta(minutes=15) +def next_date(now,times): + # now = datetime.now() + for time in times: #times are sorted + h,m = [ int(i) for i in time.split(":") ] + t = datetime.now().replace(hour=h,minute=m,second=0,microsecond=0) + if (t - maxtime) < now < t: + return t + raise ValueError("Unable to find date for today") + + +def main(): + args = docopt(__doc__) + numleds = int(args['NUMLEDS']) + times = json.load(open(args['TIMEFILE'])) + mqtt_server = args["--mqtt-server"] + last = [] + mq = mqtt.Client() + mq.connect(mqtt_server,1883,60) + mq.loop_start() + val = 0.0 + step = 0.01 + while True: + try: + now = datetime.now() + t = next_date(now,times) + sys.stdout.write("{}:{} -> {}:{} ".format(now.hour,now.minute,t.hour,t.minute)) + ret = [] + if (t-red) < now < t: + print("Red alert") + ret = [[255,0,0]] * 4 + elif (t-orange) < now < t: + print("orange") + ret = [[255,128,0]] * 4 + elif (t-yellow) < now < t: + print("yellow") + ret = [[255,255,0]] * 4 + elif (t-green) < now < t: + print("green") + ret = [[0,255,0]] * 4 + else: + print("blue") + ret = [[0,0,255]] * 4 + mq.publish("/leds/nodemcu-switcher/set",json.dumps(ret)) + except ValueError: + print("No bus for now, you will have to walk!") + ret = calc_chain(3,val) + ret.insert(0,[0,0,0]) + mq.publish("/leds/nodemcu-switcher/set",json.dumps(ret)) + val += step % 1 + sleep(1) + +if __name__ == "__main__": + main() diff --git a/fade.py b/fade.py new file mode 100755 index 0000000..8178ad6 --- /dev/null +++ b/fade.py @@ -0,0 +1,78 @@ +#! /usr/bin/env nix-shell +#! nix-shell -i python3 -p python3 python35Packages.docopt +""" usage: run [options] NUMLEDS (loop [--skip-unchanged] [STEP] [DELAY]|single STARTVAL) + + --add-empty essentially add a single empty led in front, does not count into NUMLEDS + + --mode=TYPE mode of fading (Default: chain) + --output=TYPE output type, either json or raw (Default: json) + --skip-unchanged if the value in the loop is unchanged, skip the output + +running with loop this script essentially becomes a generator which outputs the +next value each "DELAY" +single returns a single output with STARTVAL as starting point for the first led + +NUMLEDS is the number of leds to output data for (--add-empty does not count in here) +STEP defaults to 0.01 +DELAY defaults to 1 second + +""" +from docopt import docopt +import time +from colorsys import hsv_to_rgb +import json +import sys + +def calc_chain(numleds,val): + divisor = 1.0 / numleds + ret = [] + for i in range(numleds): + v = float(divisor * i + val) % 1 + r,g,b = hsv_to_rgb(v,0.9,1) + ret.append([int(r*255), + int(g*255), + int(b*255)]) + return ret + +def calc_single(numleds,val): + ret = [] + for i in range(numleds): + r,g,b = hsv_to_rgb(val,1,1) + ret.append([int(r*255), + int(g*255), + int(b*255)]) + return ret + +def main(): + args = docopt(__doc__) + numleds = int(args['NUMLEDS']) + mode = args['--mode'] + step = float(args['STEP'] or 0.01) + delay = float(args['DELAY'] or 1) + val = float(args['STARTVAL'] or 0) + last = [] + while True: + if mode == "chain": + ret = calc_chain(numleds,val) + elif mode == "single": + ret = calc_single(numleds,val) + + if args['--add-empty']: + ret.insert(0,[0,0,0]) + + # early serialization makes comparsion easy + ret = json.dumps(ret) + if not (args['--skip-unchanged'] and last == ret): + last = ret + print(ret) + sys.stdout.flush() + if args['single']: + break + else: + val += step % 1 + time.sleep(delay) + + + +if __name__ == "__main__": + main() diff --git a/times.json b/times.json new file mode 100644 index 0000000..bb3ffce --- /dev/null +++ b/times.json @@ -0,0 +1,33 @@ +[ + + "13:10", + "13:25", + "13:40", + + "15:13", + "15:28", + "15:43", + "15:58", + + "16:13", + "16:28", + "16:43", + "16:58", + + "17:13", + "17:28", + "17:43", + "17:58", + + "18:10", + "18:25", + "18:40", + "18:55", + + "19:10", + "19:25", + "19:40", + "19:55", + + "20:10" +] -- cgit v1.2.3