"""Step 4: the door also opens on the reader's wired pulse.

The reader's GP28 pulse arrives on GP21. The door cannot tell who was
granted or why: a wire only says "open". The door keeps its own 5 seconds.
"""

from machine import Pin
import time

OPEN_MS = 5000

red = Pin(14, Pin.OUT, value=0)
green = Pin(15, Pin.OUT, value=0)
strike = Pin(25, Pin.OUT, value=0)
wired_input = Pin(21, Pin.IN, Pin.PULL_DOWN)


class Door:
    """Closed, or open until a given time. The strike follows it."""

    def __init__(self):
        self.open_until = time.ticks_ms()

    def open_for(self, milliseconds):
        self.open_until = time.ticks_add(time.ticks_ms(), milliseconds)

    def is_open(self):
        return time.ticks_diff(self.open_until, time.ticks_ms()) > 0


door = Door()
was_wired = False

while True:
    wired = wired_input.value() == 1
    if wired and not was_wired:
        door.open_for(OPEN_MS)
        print("Wired pulse: open for", OPEN_MS // 1000, "s")
    was_wired = wired

    strike.value(door.is_open())
    red.value(not door.is_open())
    green.value(door.is_open())
    time.sleep_ms(20)
