From 7dd3309158790d3e8385527fef0366e688c123eb Mon Sep 17 00:00:00 2001 From: Zoe Moore Date: Sun, 27 Dec 2020 22:41:06 -0800 Subject: [PATCH] Initial commit --- .gitignore | 1 + gate.py | 54 ++++++++++++++++++++++++++++ secrets-example.json | 4 +++ wiegand.py | 83 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+) create mode 100644 .gitignore create mode 100644 gate.py create mode 100644 secrets-example.json create mode 100644 wiegand.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..63fb2a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +secrets.json \ No newline at end of file diff --git a/gate.py b/gate.py new file mode 100644 index 0000000..7a3ecb7 --- /dev/null +++ b/gate.py @@ -0,0 +1,54 @@ +import pigpio +import time +import logging +import json + +from wiegand import decoder + +class gate: + def __init__(self, pi, relay_pin): + self.pi = pi + self.relay_pin = relay_pin + + # set the pin to high to keep the gate locked + pi.write(relay_pin, 1) + + # unlocks the gate for a number of seconds defined by timeout + def unlock_gate(self, timeout): + self.pi.write(self.relay_pin, 0) + time.sleep(timeout) + self.pi.write(self.relay_pin, 1) + +def load_secrets(): + with open("./secrets.json") as secrets: + return json.loads(secrets.read()) + +if __name__ == "__main__": + secrets = load_secrets() + pi = pigpio.pi() + gate = gate(pi, 4) + + current_code = "" + def callback(bits, value): + global current_code + # indicates keypad press + if bits == 4: + current_code = current_code[-3:] + str(value) + if len(current_code) == 4: + # check if we have a valid code + if current_code in secrets['codes']: + gate.unlock_gate(5) + current_code = "" + # indicates a card swipe + elif bits == 37: + current_code = "" + str_value = str(value) + if str_value in secrets['cards']: + gate.unlock_gate(5) + + logging.info("bits={} value={}".format(bits, value)) + + w = decoder(pi, 2, 3, callback) + time.sleep(1000) + w.cancel() + pi.stop() diff --git a/secrets-example.json b/secrets-example.json new file mode 100644 index 0000000..80bf754 --- /dev/null +++ b/secrets-example.json @@ -0,0 +1,4 @@ +{ + "cards": ["0000000000"], + "codes": ["0000"] +} \ No newline at end of file diff --git a/wiegand.py b/wiegand.py new file mode 100644 index 0000000..2eef700 --- /dev/null +++ b/wiegand.py @@ -0,0 +1,83 @@ +import pigpio + +# Original code from https://github.com/alxsmora1/raspberrypi_wiegand +class decoder: + """ + A class to read Wiegand codes of an arbitrary length. + + The code length and value are returned. + """ + + def __init__(self, pi, gpio_0, gpio_1, callback, bit_timeout=6): + + """ + Instantiate with the pi, gpio for 0 (green wire), the gpio for 1 + (white wire), the callback function, and the bit timeout in + milliseconds which indicates the end of a code. + + The callback is passed the code length in bits and the value. + """ + + self.pi = pi + self.gpio_0 = gpio_0 + self.gpio_1 = gpio_1 + + self.callback = callback + + self.bit_timeout = bit_timeout + + self.in_code = False + + self.pi.set_mode(gpio_0, pigpio.INPUT) + self.pi.set_mode(gpio_1, pigpio.INPUT) + + self.pi.set_pull_up_down(gpio_0, pigpio.PUD_UP) + self.pi.set_pull_up_down(gpio_1, pigpio.PUD_UP) + + self.cb_0 = self.pi.callback(gpio_0, pigpio.FALLING_EDGE, self._cb) + self.cb_1 = self.pi.callback(gpio_1, pigpio.FALLING_EDGE, self._cb) + + def _cb(self, gpio, level, tick): + + """ + Accumulate bits until both gpios 0 and 1 timeout. + """ + + if level < pigpio.TIMEOUT: + if self.in_code == False: + self.bits = 1 + self.num = 0 + + self.in_code = True + self.code_timeout = 0 + self.pi.set_watchdog(self.gpio_0, self.bit_timeout) + self.pi.set_watchdog(self.gpio_1, self.bit_timeout) + else: + self.bits += 1 + self.num = self.num << 1 + + if gpio == self.gpio_0: + self.code_timeout = self.code_timeout & 2 # clear gpio 0 timeout + else: + self.code_timeout = self.code_timeout & 1 # clear gpio 1 timeout + self.num = self.num | 1 + + else: + if self.in_code: + if gpio == self.gpio_0: + self.code_timeout = self.code_timeout | 1 # timeout gpio 0 + else: + self.code_timeout = self.code_timeout | 2 # timeout gpio 1 + + if self.code_timeout == 3: # both gpios timed out + self.pi.set_watchdog(self.gpio_0, 0) + self.pi.set_watchdog(self.gpio_1, 0) + self.in_code = False + self.callback(self.bits, self.num) + + def cancel(self): + """ + Cancel the Wiegand decoder. + """ + self.cb_0.cancel() + self.cb_1.cancel()