Compare commits

..

2 Commits

Author SHA1 Message Date
2efc2343b6 mqtt 2021-03-10 17:17:12 +01:00
b2d7c5a4cc Variable thresholds 2021-03-10 17:16:40 +01:00

50
door.py
View File

@ -1,7 +1,12 @@
#!/usr/bin/python
import os, serial, socket, subprocess, select, datetime, sys
import paho.mqtt.client as mqcl
import argparse
OPEN_THRESHOLD = 35
CLOSED_THRESHOLD = 60
CLOSED_WANT = 135
parser = argparse.ArgumentParser()
parser.add_argument("--serial_port", default="/dev/serial/by-id/usb-Imaginaerraum.de_DoorControl_43363220195053573A002C0-if01")
parser.add_argument("--nfc_fifo", default="/tmp/nfc_fifo")
@ -10,16 +15,25 @@ parser.add_argument("--valid_tokens", default="/etc/door_tokens")
parser.add_argument("--log_file", default="/tmp/nfc.log")
parser.add_argument("--state_timeout", type=float, default=10)
parser.add_argument("--repeat_time", type=float, default=5)
parser.add_argument("--mqtt_host", default="10.10.21.2")
config = parser.parse_args()
mqttc = mqcl.Client()
def timestamp():
return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Log data to stdout and the log file
def log(*args):
data = "%s %s" % (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), " ".join(str(i) for i in args))
data = "%s %s" % (timestamp(), " ".join(str(i) for i in args))
lgf.write(data + "\n")
lgf.flush()
print(data)
def mqtt(topic, msg, persistent = True):
mqttc.publish("door/" + topic, msg, qos=2, retain=persistent)
# Opens the socket that can control the daemon
# Commands are TBD
def open_control_socket():
@ -118,14 +132,18 @@ def poll_door_state():
data = serial_port.readline().strip().split()
if data[0] == b'pos:':
data = int(data[1])
if state_pos != data:
mqtt("position/value", data, True)
state_pos = data
changed = False
if data < 80 and state != OPEN:
if data < OPEN_THRESHOLD and state != OPEN:
state = OPEN
changed = True
elif data > 100 and state != CLOSE:
mqtt("state/value", "open", True)
elif data > CLOSED_THRESHOLD and state != CLOSE:
state = CLOSE
changed = True
mqtt("state/value", "closed", True)
return state
# Check the door state and send commands through a state machine
@ -154,6 +172,12 @@ def handle_door_state():
if action == IDLE:
if state != old_state:
log("Door changed unexpectedly:", state_names[state])
start_time = datetime.datetime.now()
if start_time and (datetime.datetime.now() - start_time).total_seconds() >= config.state_timeout:
start_time = None
if state_pos >= CLOSED_THRESHOLD and state_pos < CLOSED_WANT:
log("Closing door a bit more")
serial_port.write(target_state_cmd[CLOSE])
return
# Target state, next action, timeout action
@ -199,6 +223,7 @@ def open_door():
log("Opening the door")
action = OPEN
start_time = None
mqtt("state/target", "open", True)
handle_door_state()
def close_door():
@ -207,6 +232,7 @@ def close_door():
log("Closing the door")
action = CLOSE
start_time = None
mqtt("state/target", "closed", True)
handle_door_state()
def toggle_door_state():
@ -235,12 +261,7 @@ def handle_nfc_token(token = None):
toggle_door_state()
else:
log("Invalid token:", token)
open_logfile()
read_valid_tokens()
open_nfc_fifo()
open_serial_port()
open_control_socket()
mqtt("token/last_invalid", "%s;%s" % (timestamp(), token))
class LineBuffer(object):
def __init__(self, f, handler):
@ -259,7 +280,6 @@ class LineBuffer(object):
self.handler(self.f, i)
return True
def handle_cmd(comm, data):
cmd = data.decode('utf8').split()
cmd, args = cmd[0], cmd[1:]
@ -290,6 +310,16 @@ def handle_cmd(comm, data):
action_names[action],
(datetime.datetime.now() - start_time).total_seconds()))
open_logfile()
read_valid_tokens()
open_nfc_fifo()
open_serial_port()
open_control_socket()
mqttc.on_connect = lambda client, userdata, flags, rc: log("Connected to mqtt host with result %s" % (str(rc), ))
mqttc.connect_async(config.mqtt_host, keepalive = 60)
mqttc.loop_start()
buffers = {}
while True:
readable = select.select([ nfc_fifo, control_socket ] + comm_channels, [], [], 1)[0]