--- /dev/null
+#!/usr/bin/python
+
+import getopt
+import paho.mqtt.client as mqtt
+import sys
+import time
+
+debug_mode = False
+
+def debug(msg):
+ if debug_mode:
+ print msg
+
+class State:
+ def __init__(self):
+ self.attrs = {}
+
+ def update(self):
+ self.now = time.time()
+ tm = time.localtime(self.now)
+ self.year = tm.tm_year
+ self.month = tm.tm_mon
+ self.day = tm.tm_mday
+ self.hour = tm.tm_hour
+ self.min = tm.tm_min
+ self.wday = tm.tm_wday
+
+ def get_sensor(self, key):
+ topic = "burrow/" + key
+ if topic in self.attrs:
+ s = self.attrs[topic].split(" ")
+ if len(s) >= 2 and s[1] < self.now - 120:
+ return None
+ return float(s[0])
+ else:
+ return None
+
+ def set(self, key, val):
+ global mq
+ topic = "burrow/" + key
+ debug("Setting {} to {}".format(topic, val))
+ mq.publish(topic, val, qos=1, retain=True)
+
+st = State()
+
+def on_connect(mq, userdata, flags, rc):
+ mq.subscribe("burrow/#")
+
+def on_message(mq, userdata, msg):
+ global st
+ debug("Message {}: {}".format(msg.topic, msg.payload))
+ st.attrs[msg.topic] = msg.payload
+
+def auto_loft_fan():
+ global st
+ lt = st.get_sensor("temp/loft")
+ if lt is not None and lt >= 30:
+ fs = 3
+ elif st.hour in range(10, 20):
+ fs = 2
+ else:
+ fs = 1
+ st.set("loft/fan", fs)
+
+def auto_circ():
+ global st
+ if st.hour in range(19, 23):
+ c = 1
+ else:
+ c = 0;
+ st.set("loft/circulation", c)
+
+opts, args = getopt.gnu_getopt(sys.argv[1:], "", ["debug"])
+for opt in opts:
+ o, arg = opt
+ if o == "--debug":
+ debug_mode = True
+
+mq = mqtt.Client()
+mq.on_connect = on_connect
+mq.on_message = on_message
+mq.will_set("status/auto", "failed", retain=True)
+mq.connect("127.0.0.1")
+mq.publish("status/auto", "ok", retain=True)
+mq.loop_start()
+
+while True:
+ st.update()
+ auto_loft_fan()
+ auto_circ()
+ time.sleep(10)