From 88ec6110c68a6b798abc388a991e8d8b0f2a3516 Mon Sep 17 00:00:00 2001 From: vitrinekast Date: Mon, 28 Oct 2024 17:45:30 +0100 Subject: [PATCH] setup first bit of rule based stuff --- .gitignore | 4 +- rule-listener/script.py | 93 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 rule-listener/script.py diff --git a/.gitignore b/.gitignore index f069a75..cfca2eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ secrets.h arduino/MQTT/secret.h -arduino/MQTT/secrets.h \ No newline at end of file +arduino/MQTT/secrets.h +venv +rule-listener/secrets.py \ No newline at end of file diff --git a/rule-listener/script.py b/rule-listener/script.py new file mode 100644 index 0000000..bde0b78 --- /dev/null +++ b/rule-listener/script.py @@ -0,0 +1,93 @@ +import paho.mqtt.client as mqtt +import sched, time +import secrets + +s = sched.scheduler(time.time, time.sleep) + +state = {} + +rules = { + "main/fan/1": [ + { # after the fan has been on 2 times, another fan should be turned on + "count": 2, # the amount of times + "state": "on", # it has had this state + "doTopic": "main/fan/2", # i will send to topic + "doMessage": "on", # this message + "delay": 3, # after this amount of seconds + "reset": True # and i should reset my count afterwards + }, + { # 30 seconds after the fan has been turned on, turn it off again. + "count": 1, # the amount of times + "state": "on", # it has had this state + "doTopic": "main/fan/11", # i will send to topic + "doMessage": "off", # this message + "delay": 30, # after this amount of seconds + "reset": False # and i should reset my count afterwards + }, + ] +} + +def on_connect(client, userdata, flags, reason_code, properties): + print(f"Connected with result code {reason_code}") + client.subscribe("main/#") + +def publish_later(topic, msg, delay): + print(f"TODO: make this run {delay} seconds later") + # s.enter(delay, 1, publish, kwargs={'topic': topic, 'msg': msg}) + # s.run() + publish(topic, msg) + +def publish(topic, msg): + result = mqttc.publish(topic, msg) + + status = result[0] + + if not status == 0: + print(f"Failed to send message to topic {topic}") + +def check_against_rules(msg): + if msg.topic in rules: + print(f"Found {len(rules[msg.topic])} rules on this topic") + for rule in rules[msg.topic]: + print(f"Rule is met when the count is above {rule['count']}. Current count is {state[msg.topic]['count']}") + + if state[msg.topic]['count'] > rule['count']: + print(f"i matched a rule") + if(rule['reset']): + state[msg.topic]['count'] = 0 + + if rule['delay']: + publish_later(rule['doMessage'], rule['doMessage'], rule['delay']) + else: + publish(rule['doTopic'], rule['doMessage']) + else: + print("i have no rules for this topic") + + print("finished rule checking") + +# The callback for when a PUBLISH message is received from the server. +def on_message(client, userdata, msg): + if msg.retain: + return False + + if msg.topic in state: + print("i already exist") + state[msg.topic]["count"] += 1 + else: + print("i do not") + state[msg.topic] = {} + state[msg.topic]["count"] = 0 + + check_against_rules(msg) + + + +mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) +mqttc.on_connect = on_connect +mqttc.on_message = on_message + +mqttc.username_pw_set(secrets.mqtt_username, secrets.mqtt_password) + +mqttc.connect("mqtt.klank.school", 7000, 60) + +mqttc.loop_forever() \ No newline at end of file