diff --git a/hackeriet/cardreaderd/__init__.py b/hackeriet/cardreaderd/__init__.py index f0fc910..4ed06c4 100755 --- a/hackeriet/cardreaderd/__init__.py +++ b/hackeriet/cardreaderd/__init__.py @@ -1,37 +1,64 @@ #!/usr/bin/env python from hackeriet import mifare -from hackeriet.mqtt import MQTT from hackeriet.door import users import os, logging, time logging.basicConfig(level=logging.DEBUG) -door_name = os.getenv("DOOR_NAME", 'hackeriet') -door_topic = "hackeriet/door/%s/open" % door_name -door_timeout = int(os.getenv("DOOR_TIMEOUT", 2)) -mqtt = MQTT() +class MQTTSignaler: + def __init__(self): + from hackeriet.mqtt import MQTT + self.door_name = os.getenv("DOOR_NAME", 'hackeriet') + self.door_topic = "hackeriet/door/%s/open" % door_name + self.mqtt = MQTT() + def signal(self, user): + self.mqtt(door_topic, user) -def main(): - logging.debug('Starting main loop') +class HTTPSignaler: + def __init__(self): + # load config + self.host = "localhost" + self.port = 1234 + def signal(self, user): + import urllib + urllib.request.urlopen("http://%s:%d/open?%s" % (self.host, self.port, user)).read() + +def main_loop(signaler): + door_timeout = int(os.getenv("DOOR_TIMEOUT", 2)) while True: - users.load() - # Read data from card reader - logging.debug('mifare: waiting for data...') - data = mifare.try_read() - if data: - logging.debug('mifare: data read') - user = users.auth(data[0:16]) - if user: - ascii_user = user.encode('ascii', 'replace').decode('ascii') - logging.info('auth: card read for user %s' % ascii_user) - mqtt(door_topic, user) + users.load() + # Read data from card reader + logging.debug('mifare: waiting for data...') + data = mifare.try_read() + if data: + logging.debug('mifare: data read') + user = users.auth(data[0:16]) + if user: + ascii_user = user.encode('ascii', 'replace').decode('ascii') + logging.info('auth: card read for user %s' % ascii_user) + signaler.signal(user) + else: + logging.debug('auth: card data does not belong to a user: %s' % data[0:16]) + # Avoid spewing messages every single ms while a card is in front of the reader + time.sleep(door_timeout) else: - logging.debug('auth: card data does not belong to a user: %s' % data[0:16]) - # Avoid spewing messages every single ms while a card is in front of the reader - time.sleep(door_timeout) - else: - logging.debug('mifare: no data read in last attempt') + logging.debug('mifare: no data read in last attempt') + +def main(): + logging.debug('Starting main loop') + + parser = argparse.ArgumentParser() + parser.add_argument('--experiment-with-mqtt', action='store_true') + args = parser.parse_args() + + if args.experiment_with_mqtt: + signaler = MQTTSignaler() + else: + signaler = HTTPSignaler() + + main_loop(signaler) + if __name__ == "__main__": main() diff --git a/hackeriet/door/__init__.py b/hackeriet/door/__init__.py index e56bda2..16e5403 100644 --- a/hackeriet/door/__init__.py +++ b/hackeriet/door/__init__.py @@ -1,11 +1,11 @@ import time import atexit -import RPi.GPIO as GPIO - -GPIO.setmode(GPIO.BCM) # Broadcom PIN numbering +import logging class Doors(): def __init__(self, piface=False, pin=5, timeout=1): + import RPi.GPIO as GPIO + GPIO.setmode(GPIO.BCM) # Broadcom PIN numbering self.timeout = timeout if piface: import pifacedigitalio @@ -15,7 +15,7 @@ def __init__(self, piface=False, pin=5, timeout=1): self.pin = pin GPIO.setup(pin, GPIO.OUT, initial=GPIO.LOW) - @atexit.register + #@atexit.register def cleanup(self): if not self.piface: GPIO.cleanup() @@ -30,3 +30,8 @@ def open(self): time.sleep(self.timeout) GPIO.output(self.pin, GPIO.LOW) +class SimulatedDoor(): + def __init__(self): + logging.info("Using simulated door") + def open(self): + logging.info("Door opened") \ No newline at end of file diff --git a/hackeriet/doorcontrold/__init__.py b/hackeriet/doorcontrold/__init__.py index 67b9a57..f1cfee9 100755 --- a/hackeriet/doorcontrold/__init__.py +++ b/hackeriet/doorcontrold/__init__.py @@ -1,41 +1,72 @@ #!/usr/bin/env python -from hackeriet.mqtt import MQTT -from hackeriet.door import Doors import threading, os, logging +import argparse -logging.basicConfig(level=logging.DEBUG) +def connect_to_mqtt(door): + logging.warn("Using MQTT for signaling. Never do this in production; use local HTTP instead.") -piface = False + from hackeriet.mqtt import MQTT -# Determine if piface is used on the Pi -if "PIFACE" in os.environ: - piface = True - logging.info('Using piface configuration') + door_name = os.getenv("DOOR_NAME", 'hackeriet') + door_topic = "hackeriet/door/%s/open" % door_name -# Be backwards compatible with old env variable name -gpio_pin = int(os.getenv("DOOR_GPIO_PIN", os.getenv("DOOR_PIN", 0))) + def on_message(mosq, obj, msg): + door.open() + logging.info('Door opened: %s' % msg.payload) -# How many seconds should the door lock remain open -timeout = int(os.getenv("DOOR_TIMEOUT", 2)) + mqtt = MQTT(on_message) + mqtt.subscribe(door_topic, 0) -door = Doors(piface=piface,pin=gpio_pin,timeout=timeout) + for t in threading.enumerate(): + if t is threading.currentThread(): + continue + t.join() + +def listen_to_socket(door): + from flask import Flask + app = Flask(__name__) + + @app.route("/open") + def opendoor(): + door.open() + return "opened" + app.run(host='localhost', port=1234) + +def setup(use_simulated_door, use_mqtt): + from hackeriet.door import Doors, SimulatedDoor + + logging.basicConfig(level=logging.DEBUG) -def on_message(mosq, obj, msg): - door.open() - logging.info('Door opened: %s' % msg.payload) + piface = False -door_name = os.getenv("DOOR_NAME", 'hackeriet') -door_topic = "hackeriet/door/%s/open" % door_name + # Determine if piface is used on the Pi + if "PIFACE" in os.environ: + piface = True + logging.info('Using piface configuration') -mqtt = MQTT(on_message) -mqtt.subscribe(door_topic, 0) + # Be backwards compatible with old env variable name + gpio_pin = int(os.getenv("DOOR_GPIO_PIN", os.getenv("DOOR_PIN", 0))) + + # How many seconds should the door lock remain open + timeout = int(os.getenv("DOOR_TIMEOUT", 2)) + + if use_simulated_door: + door = SimulatedDoor() + else: + door = Doors(piface=piface,pin=gpio_pin,timeout=timeout) + + if use_mqtt: + connect_to_mqtt(door) + else: + listen_to_socket(door) -# Block forever def main(): - for t in threading.enumerate(): - if t is threading.currentThread(): - continue - t.join() + parser = argparse.ArgumentParser() + parser.add_argument('--simulated', action='store_true') + parser.add_argument('--experiment-with-mqtt', action='store_true') + args = parser.parse_args() + + setup(args.simulated, args.experiment_with_mqtt) if __name__ == "__main__": main()