diff --git a/door_pi_control/__init__.py b/door_pi_control/__init__.py index 7aa1645..7f2f423 100644 --- a/door_pi_control/__init__.py +++ b/door_pi_control/__init__.py @@ -51,7 +51,7 @@ def main(): logger().info("Starting bell") def door_is_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() logger().info("Starting socket") diff --git a/door_pi_control/bell.py b/door_pi_control/bell.py index 46b0640..85cfda4 100644 --- a/door_pi_control/bell.py +++ b/door_pi_control/bell.py @@ -20,11 +20,12 @@ msgs = { } 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") self.tmp = bytes() self.data = [] self.lock = threading.RLock() + self.cv = threading.Condition(self.lock) self.times = [] @@ -36,6 +37,9 @@ class Reader(util.Loggable): self.closed = False 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): if exc: print(exc) @@ -93,30 +97,37 @@ class Reader(util.Loggable): if dt >= 3: self.doing_light = not self.doing_light elif msgs['ring_hs'] == msg: - open_now = self.open_now_cb and self.open_now_cb() - if open_now: - self._logger().info("Opening after a single button press") - self.open_door() - elif not self.start: + if not self.start: self.start = datetime.datetime.now() if self.last_symbol_timestamp and (self.start - self.last_symbol_timestamp).total_seconds() > 5: self.times = [] elif msgs['release'] == msg and self.start: - 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 morse == [False, False, True, False]: + open_now = self.open_now_cb and self.open_now_cb() + if open_now: + self._logger().info("Opening after a single button press") 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:] self.tmp = data + self._events("") def alternate_msgs(self, names, times = 3, *, dt = 0.04): for _ in range(times): @@ -139,6 +150,8 @@ class Reader(util.Loggable): def open_door(self): self._logger().info("Opening") + self._events("open", force=True) + self._events("") self.alternate_msgs(['light_push', 'open_push'], dt = 0.04) time.sleep(0.3) self.alternate_msgs(['light_release', 'open_release'], dt = 0.04); @@ -155,11 +168,12 @@ class Reader(util.Loggable): return rv 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") self._port = port self._task = None self._cb = open_immediately_cb + self._mqttc = mqttc def start(self): if not self._task: 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: try: 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 = self._protocol.protocol except Exception as e: