1
0
mirror of https://github.com/binary-kitchen/doorlockd synced 2024-12-22 10:24:26 +01:00

Prepare doorlock for new states

Signed-off-by: Ralf Ramsauer <ralf@binary-kitchen.de>
This commit is contained in:
Ralf Ramsauer 2018-09-02 02:11:15 +00:00
parent bd63a57d31
commit 9a29f02449
3 changed files with 72 additions and 37 deletions

View File

@ -134,18 +134,28 @@ class AuthMethod(Enum):
class DoorState(Enum): class DoorState(Enum):
Close = 1 Open = 1
Open = 2 Present = 2
Closed = 3
def is_open(self):
if self != DoorState.Closed:
return True
return False
def to_img(self): def to_img(self):
led = 'red' led = 'red'
if self == DoorState.Open: if self == DoorState.Present:
led = 'green' led = 'yellow'
elif self == DoorState.Open:
led = 'green'
return 'static/led-%s.png' % led return 'static/led-%s.png' % led
def to_html(self): def to_html(self):
if self == DoorState.Open: if self == DoorState.Open:
return 'Offen' return 'Offen'
elif self == DoorState.Present:
return 'Jemand da'
return 'Geschlossen' return 'Geschlossen'
@ -160,6 +170,7 @@ class LogicResponse(Enum):
EmergencyUnlock = 10, EmergencyUnlock = 10,
ButtonLock = 11, ButtonLock = 11,
ButtonUnlock = 12, ButtonUnlock = 12,
ButtonPresent = 13,
def to_html(self): def to_html(self):
if self == LogicResponse.Success: if self == LogicResponse.Success:
@ -177,23 +188,28 @@ class LogicResponse(Enum):
elif self == LogicResponse.EmergencyUnlock: elif self == LogicResponse.EmergencyUnlock:
return '!!! Emergency Unlock !!!' return '!!! Emergency Unlock !!!'
elif self == LogicResponse.ButtonLock: elif self == LogicResponse.ButtonLock:
return 'Closed by lock button' return 'Closed by button'
elif self == LogicResponse.ButtonUnlock: elif self == LogicResponse.ButtonUnlock:
return 'Temporary unlock by unlock button' return 'Opened by button'
elif self == LogicResponse.ButtonPresent:
return 'Present by button'
return 'Bitte spezifizieren Sie.' return 'Bitte spezifizieren Sie.'
class DoorHandler: class DoorHandler:
state = DoorState.Close state = DoorState.Closed
do_schnapper = False do_close = False
CMD_UNLOCK = b'u' CMD_PRESENT = b'y'
CMD_LOCK = b'l' CMD_OPEN = b'g'
CMD_SCHNAPPER = b's' CMD_CLOSE = b'r'
BUTTON_LOCK_PRESS = b'L'
BUTTON_UNLOCK_PRESS = b'U' BUTTON_PRESENT = b'Y'
BUTTON_EMERGENCY_PRESS = b'E' BUTTON_OPEN = b'G'
BUTTON_CLOSE = b'R'
# TBD EMERGENCY OPEN
# TBD DOOR NOT CLOSED
def __init__(self, device): def __init__(self, device):
if simulate_serial: if simulate_serial:
@ -205,18 +221,23 @@ class DoorHandler:
self.thread.start() self.thread.start()
def handle_input(self, recv, expect=None): def handle_input(self, recv, expect=None):
if recv == DoorHandler.BUTTON_LOCK_PRESS: if recv == DoorHandler.BUTTON_CLOSE:
playsound(wave_lock_button) playsound(wave_lock_button)
if self.state == DoorState.Open: if self.state.is_open():
run_lock() run_lock()
self.state = DoorState.Close self.state = DoorState.Closed
logic.emit_status(LogicResponse.ButtonLock) logic.emit_status(LogicResponse.ButtonLock)
elif recv == DoorHandler.BUTTON_UNLOCK_PRESS: elif recv == DoorHandler.BUTTON_OPEN:
playsound(wave_unlock_button) playsound(wave_unlock_button)
self.state = DoorState.Open
logic.emit_status(LogicResponse.ButtonUnlock) logic.emit_status(LogicResponse.ButtonUnlock)
elif recv == DoorHandler.BUTTON_EMERGENCY_PRESS: elif recv == DoorHandler.BUTTON_PRESENT:
playsound(wave_emergency) # playsound...
logic.emit_status(LogicResponse.EmergencyUnlock) self.state = DoorState.Present
logic.emit_status(LogicResponse.ButtonPresent)
# elif recv == DoorHandler.BUTTON_EMERGENCY_PRESS:
# playsound(wave_emergency)
# logic.emit_status(LogicResponse.EmergencyUnlock)
if expect is None: if expect is None:
return True return True
@ -239,16 +260,16 @@ class DoorHandler:
break break
self.handle_input(char) self.handle_input(char)
if self.state == DoorState.Open: if self.do_close:
self.send_command(DoorHandler.CMD_UNLOCK) self.send_command(DoorHandler.CMD_CLOSE)
if self.do_schnapper: self.do_close = False
self.send_command(DoorHandler.CMD_SCHNAPPER) elif self.state.is_open():
self.do_schnapper = False if self.state == DoorState.Present:
elif self.state == DoorState.Close: self.send_command(DoorHandler.CMD_PRESENT)
self.send_command(DoorHandler.CMD_LOCK) else:
self.send_command(DoorHandler.CMD_OPEN)
def open(self): def open(self):
self.do_schnapper = True
if self.state == DoorState.Open: if self.state == DoorState.Open:
return LogicResponse.AlreadyOpen return LogicResponse.AlreadyOpen
@ -257,16 +278,27 @@ class DoorHandler:
return LogicResponse.Success return LogicResponse.Success
def close(self): def close(self):
if self.state == DoorState.Close: if self.state == DoorState.Closed:
return LogicResponse.AlreadyLocked return LogicResponse.AlreadyLocked
self.state = DoorState.Close self.do_close = True
self.state = DoorState.Closed
run_lock() run_lock()
return LogicResponse.Success return LogicResponse.Success
def present(self):
if self.state == DoorState.Present:
return LogicResponse.AlreadyOpen
self.state = DoorState.Present
# new hook?
return LogicResponse.Success
def request(self, state): def request(self, state):
if state == DoorState.Close: if state == DoorState.Closed:
return self.close() return self.close()
elif state == DoorState.Present:
return self.present()
elif state == DoorState.Open: elif state == DoorState.Open:
return self.open() return self.open()
@ -312,7 +344,7 @@ class Logic:
if err == LogicResponse.Success: if err == LogicResponse.Success:
if self.door_handler.state == DoorState.Open: if self.door_handler.state == DoorState.Open:
playsound(wave_unlock) playsound(wave_unlock)
if self.door_handler.state == DoorState.Close: if self.door_handler.state == DoorState.Closed:
playsound(wave_lock) playsound(wave_lock)
elif err == LogicResponse.AlreadyLocked or err == LogicResponse.AlreadyOpen: elif err == LogicResponse.AlreadyLocked or err == LogicResponse.AlreadyOpen:
playsound(wave_zonk) playsound(wave_zonk)
@ -337,11 +369,12 @@ class AuthenticationForm(FlaskForm):
username = StringField('Username', [Length(min=3, max=25)]) username = StringField('Username', [Length(min=3, max=25)])
password = PasswordField('Password', [DataRequired()]) password = PasswordField('Password', [DataRequired()])
open = SubmitField('Open') open = SubmitField('Open')
present = SubmitField('Present')
close = SubmitField('Close') close = SubmitField('Close')
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
FlaskForm.__init__(self, *args, **kwargs) FlaskForm.__init__(self, *args, **kwargs)
self.desired_state = DoorState.Close self.desired_state = DoorState.Closed
def validate(self): def validate(self):
if not FlaskForm.validate(self): if not FlaskForm.validate(self):
@ -349,6 +382,8 @@ class AuthenticationForm(FlaskForm):
if self.open.data: if self.open.data:
self.desired_state = DoorState.Open self.desired_state = DoorState.Open
elif self.present.data:
self.desired_state = DoorState.Present
return True return True
@ -377,7 +412,7 @@ def api():
response == LogicResponse.AlreadyOpen: response == LogicResponse.AlreadyOpen:
# TBD: Remove 'status'. No more users. Still used in App Version 2.0! # TBD: Remove 'status'. No more users. Still used in App Version 2.0!
json['status'] = str(logic.state.to_html()) json['status'] = str(logic.state.to_html())
json['open'] = logic.state == DoorState.Open json['open'] = logic.state.is_open()
return jsonify(json) return jsonify(json)
user = request.form.get('user') user = request.form.get('user')
@ -399,7 +434,7 @@ def api():
if command == 'status': if command == 'status':
return json_response(logic.try_auth(credentials)) return json_response(logic.try_auth(credentials))
elif command == 'lock': elif command == 'lock':
desired_state = DoorState.Close desired_state = DoorState.Closed
elif command == 'unlock': elif command == 'unlock':
desired_state = DoorState.Open desired_state = DoorState.Open

BIN
static/led-yellow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -13,7 +13,7 @@
<img src="{{ led }}"> <img src="{{ led }}">
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
{{ wtf.quick_form(authentication_form, button_map={'open': 'success btn-lg btn-block', 'close': 'danger btn-lg btn-block'}) }} {{ wtf.quick_form(authentication_form, button_map={'open': 'success btn-lg btn-block', 'present': 'warning btn-lg btn-block', 'close': 'danger btn-lg btn-block'}) }}
{% if response %} {% if response %}
<hr/> <hr/>
<h1>{{ response.to_html() }}</h1> <h1>{{ response.to_html() }}</h1>