bell mqtt

This commit is contained in:
Lynn Ochs 2022-11-21 18:10:54 +01:00
parent 9dbed1a51e
commit 0e95c8ec8a
2 changed files with 34 additions and 20 deletions

View File

@ -51,7 +51,7 @@ def main():
logger().info("Starting bell") logger().info("Starting bell")
def door_is_open(): def door_is_open():
return control.state() == control.target() == door.constants.state.OPEN return control.state() == control.target() == door.constants.state.OPEN
bell_control = bell.Control(config.bell_port, door_is_open) bell_control = bell.Control(config.bell_port, mqttc, door_is_open)
bell_control.start() bell_control.start()
logger().info("Starting socket") logger().info("Starting socket")

View File

@ -20,11 +20,12 @@ msgs = {
} }
class Reader(util.Loggable): class Reader(util.Loggable):
def __init__(self, should_open_immediately_cb = None): def __init__(self, should_open_immediately_cb = None, mqttc = None):
super().__init__("bell") super().__init__("bell")
self.tmp = bytes() self.tmp = bytes()
self.data = [] self.data = []
self.lock = threading.RLock() self.lock = threading.RLock()
self.cv = threading.Condition(self.lock) self.cv = threading.Condition(self.lock)
self.times = [] self.times = []
@ -36,6 +37,9 @@ class Reader(util.Loggable):
self.closed = False self.closed = False
self.open_now_cb = should_open_immediately_cb self.open_now_cb = should_open_immediately_cb
self._events = mqtt.Value(mqttc, "door/bell/event")
self._last_ring = datetime.datetime.now() - datetime.timedelta(days=1)
def connection_lost(self, exc): def connection_lost(self, exc):
if exc: if exc:
print(exc) print(exc)
@ -93,30 +97,37 @@ class Reader(util.Loggable):
if dt >= 3: if dt >= 3:
self.doing_light = not self.doing_light self.doing_light = not self.doing_light
elif msgs['ring_hs'] == msg: elif msgs['ring_hs'] == msg:
open_now = self.open_now_cb and self.open_now_cb() if not self.start:
if open_now:
self._logger().info("Opening after a single button press")
self.open_door()
elif not self.start:
self.start = datetime.datetime.now() self.start = datetime.datetime.now()
if self.last_symbol_timestamp and (self.start - self.last_symbol_timestamp).total_seconds() > 5: if self.last_symbol_timestamp and (self.start - self.last_symbol_timestamp).total_seconds() > 5:
self.times = [] self.times = []
elif msgs['release'] == msg and self.start: elif msgs['release'] == msg and self.start:
t = datetime.datetime.now() open_now = self.open_now_cb and self.open_now_cb()
self.last_symbol_timestamp = t if open_now:
dt = (t - self.start).total_seconds() self._logger().info("Opening after a single button press")
self.start = None
self.times = self.times[-3:] + [dt]
avg = sum(self.times) / len(self.times)
morse = [x>avg for x in self.times]
if len(self.times) == 4:
self._logger().info(", ".join([{True: "dah", False: "dit"}[x > avg] for x in self.times]))
if morse == [False, False, True, False]:
self.open_door() self.open_door()
else:
t = datetime.datetime.now()
self.last_symbol_timestamp = t
dt = (t - self.start).total_seconds()
self.start = None
self.times = self.times[-3:] + [dt]
avg = sum(self.times) / len(self.times)
morse = [x>avg for x in self.times]
if len(self.times) == 4:
self._logger().info(", ".join([{True: "dah", False: "dit"}[x > avg] for x in self.times]))
if (t - self._last_ring).total_seconds() > 30:
self._events("ring", force=True)
self._last_ring = t
if morse == [False, False, True, False]:
self._events("morse", force=True)
self.open_door()
data = data[7:] data = data[7:]
self.tmp = data self.tmp = data
self._events("")
def alternate_msgs(self, names, times = 3, *, dt = 0.04): def alternate_msgs(self, names, times = 3, *, dt = 0.04):
for _ in range(times): for _ in range(times):
@ -139,6 +150,8 @@ class Reader(util.Loggable):
def open_door(self): def open_door(self):
self._logger().info("Opening") self._logger().info("Opening")
self._events("open", force=True)
self._events("")
self.alternate_msgs(['light_push', 'open_push'], dt = 0.04) self.alternate_msgs(['light_push', 'open_push'], dt = 0.04)
time.sleep(0.3) time.sleep(0.3)
self.alternate_msgs(['light_release', 'open_release'], dt = 0.04); self.alternate_msgs(['light_release', 'open_release'], dt = 0.04);
@ -155,11 +168,12 @@ class Reader(util.Loggable):
return rv return rv
class Control(util.Loggable): class Control(util.Loggable):
def __init__(self, port, open_immediately_cb = None): def __init__(self, port, mqttc = None, open_immediately_cb = None):
super().__init__("bell") super().__init__("bell")
self._port = port self._port = port
self._task = None self._task = None
self._cb = open_immediately_cb self._cb = open_immediately_cb
self._mqttc = mqttc
def start(self): def start(self):
if not self._task: if not self._task:
self._task = threading.Thread(target = self.run, daemon=True) self._task = threading.Thread(target = self.run, daemon=True)
@ -171,7 +185,7 @@ class Control(util.Loggable):
if port is None or self._protocol.closed: if port is None or self._protocol.closed:
try: try:
port = serial.Serial(self._port, 9600) port = serial.Serial(self._port, 9600)
self._protocol = serial.threaded.ReaderThread(port, lambda: Reader(self._cb)) self._protocol = serial.threaded.ReaderThread(port, lambda: Reader(self._cb, self._mqttc))
self._protocol.start() self._protocol.start()
self._protocol = self._protocol.protocol self._protocol = self._protocol.protocol
except Exception as e: except Exception as e: