Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] redesign #13

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions Kod/DoorIO.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
class Base:
def __init__(self):
# Lock the door on system startup.
self.lock()

def unlock(self):
self.unlocked = True
self.stateChanged()

def lock(self):
self.unlocked = False
self.stateChanged()

def stateChanged(self):
pass

def isUnlocked(self):
return self.unlocked

def needsCleanup(self):
return False

def stop(self):
pass


class Debug(Base):
def stateChanged(self):
print("doors unlocked = %s" % self.unlocked)


try:
import RPi.GPIO as GPIO

class RPi(Base):
LOCK_PIN = 18

def __init__(self):
GPIO.setmode(GPIO.BCM)
GPIO.setup(RPi.LOCK_PIN, GPIO.OUT)
super().__init__()

def stateChanged(self):
if self.unlocked:
GPIO.output(RPi.LOCK_PIN, GPIO.LOW)
else:
GPIO.output(RPi.LOCK_PIN, GPIO.HIGH)

def needsCleanup(self):
return True

def stop(self):
GPIO.cleanup()

class Auto(RPi):
pass

except Exception:
# Not running on RPi, so DoorIO.RPi is unavailable
class Auto(Debug):
pass
42 changes: 42 additions & 0 deletions Kod/DoorManager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from threading import Thread, Event
import time
import DoorIO


class DoorManager(Thread):
"""This thread will manage the door lock state"""

def __init__(self, io=DoorIO.Auto, unlockTime=8.0):
self.io = io()
self.waitForChild = self.io.needsCleanup()
name = "%s for %s.%s" % (
type(self).__name__,
io.__module__, io.__name__
)
super().__init__(
name=name,
target=self,
daemon=not self.waitForChild
)
self.running = True
self.lastUnlockRequestTime = None
self.unlockTime = unlockTime

def run(self):
"""Don't run this directly, use start() instead"""
while self.running:
if self.lastUnlockRequestTime is not None:
if time.time() - self.lastUnlockRequestTime > self.unlockTime:
self.io.lock()
else:
self.io.unlock()
time.sleep(0.1)

def unlock(self):
self.lastUnlockRequestTime = time.time()

def stop(self):
self.running = False

def isUnlocked(self):
return self.io.isUnlocked()
108 changes: 108 additions & 0 deletions Kod/Repository.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import sqlite3
import os
import subprocess


class Repository:
def __init__(self, path):
self.path = path
if not os.path.exists(path) or os.path.getsize(path) == 0:
here = os.path.dirname(__file__)
sql1 = here + "/SQL/1-create_basic_table.sql"
sql2 = here + "/SQL/2-create_log_table.sql"
subprocess.run(["sh", "-c", "sqlite3 %s < %s" % (path, sql1)])
subprocess.run(["sh", "-c", "sqlite3 %s < %s" % (path, sql2)])
self.db = sqlite3.connect(path)

def add_card(self, name, serial):
query = '''
INSERT INTO registeredCards(name, serial)
VALUES (:name,:serial)
'''
params = {
'name': name,
'serial': serial,
}
try:
with self.db as con:
con.execute(query, params)
return True
except sqlite3.IntegrityError:
return False

def is_authorized(self, serial):
query = '''
SELECT count(*)
FROM registeredCards
WHERE serial=:serial
'''
params = {
'serial': serial,
}
cursor = self.db.execute(query, params)
count_of_serials = cursor.fetchone()
return count_of_serials[0] > 0

def update_last_used(self, serial):
query = '''
UPDATE registeredCards
SET last_used = datetime('now','localtime')
WHERE serial=:serial
'''
params = {
'serial': serial,
}
with self.db as con:
con.execute(query, params)

def log_message(self, msg_type, message):
types = ['add', 'open', 'reject', 'error']

query = '''
INSERT INTO logs(type, message)
VALUES (:type,:message)
'''
params = {
'type': msg_type if msg_type in types else 'unknown',
'message': message,
}
with self.db as con:
con.execute(query, params)

def get_name(self, serial):
query = '''
SELECT name
FROM registeredCards
WHERE serial=:serial
'''
params = {
'serial': serial,
}
cursor = self.db.execute(query, params)
name = cursor.fetchone()
return name[0]

def disconnect(self):
self.db.close()


class TerminalOutput:
def log_message(self, msg_type, message):
print("%s: %s" % (msg_type, message))


class Logger:
def __init__(self, output):
self.output = output

def add(self, message):
self.output.log_message('add', message)

def open(self, message):
self.output.log_message('open', message)

def reject(self, message):
self.output.log_message('reject', message)

def error(self, message):
self.output.log_message('error', message)
26 changes: 0 additions & 26 deletions Kod/door_lock.py

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
12 changes: 0 additions & 12 deletions Kod/messenger.py

This file was deleted.

17 changes: 0 additions & 17 deletions Kod/open_the_door.py

This file was deleted.

122 changes: 0 additions & 122 deletions Kod/repository.py

This file was deleted.

Loading