diff --git a/arch/PKGBUILD b/arch/PKGBUILD
index f6b40f7..4b94ae9 100644
--- a/arch/PKGBUILD
+++ b/arch/PKGBUILD
@@ -16,7 +16,6 @@ depends=('python3'
'mosquitto'
'mpg123'
'python-flask-wtf'
- 'python-flask-socketio'
'python-paho-mqtt'
'chromium'
'xf86-video-fbdev'
diff --git a/pydoorlock/Doorlock.py b/pydoorlock/Doorlock.py
index 17be03f..3f2a8ad 100644
--- a/pydoorlock/Doorlock.py
+++ b/pydoorlock/Doorlock.py
@@ -24,7 +24,7 @@ from serial import Serial
from threading import Thread
from time import sleep
from os.path import join
-
+import gevent
from .Door import DoorState
from .Protocol import Protocol
diff --git a/pydoorlock/EventClient.py b/pydoorlock/EventClient.py
new file mode 100644
index 0000000..5ad257d
--- /dev/null
+++ b/pydoorlock/EventClient.py
@@ -0,0 +1,34 @@
+import requests
+import threading
+import json
+
+class EventClient:
+ def __init__(self,url):
+ self.r = requests.get(url,stream=True)
+ print("connected")
+ if self.r.encoding is None:
+ self.r.encoding = 'utf8'
+
+ def parseEvent(self,line_buf):
+ ret = dict()
+ for line in line_buf:
+ if line:
+ k,v = line.decode().split(':',1)
+ ret[k] = v
+ return ret
+
+ def events(self):
+ lines = self.r.iter_lines()
+ line_buf = []
+ while True:
+ line_buf.append(next(lines))
+ if line_buf:
+ if not line_buf[-1].decode():
+ yield self.parseEvent(line_buf)
+ line_buf = []
+
+if __name__ == "__main__":
+ e = EventClient("http://localhost:8080/push")
+ for evt in e.events():
+ print(json.loads(evt['data']))
+
diff --git a/pydoorlock/WebApp.py b/pydoorlock/WebApp.py
index b1c3046..c5748c0 100644
--- a/pydoorlock/WebApp.py
+++ b/pydoorlock/WebApp.py
@@ -16,9 +16,11 @@ details.
"""
import logging
+import json
+import gevent
+import threading
-from flask import abort, Flask, jsonify, render_template, request
-from flask_socketio import SocketIO
+from flask import abort, Flask, jsonify, render_template, request, Response
from flask_wtf import FlaskForm
from wtforms import PasswordField, StringField, SubmitField
from wtforms.validators import DataRequired, Length
@@ -28,19 +30,46 @@ from .Doorlock import DoorlockResponse
from .Authenticator import AuthMethod
log = logging.getLogger()
-
webapp = Flask(__name__)
-socketio = SocketIO(webapp, async_mode='threading')
+evt = threading.Event()
+json_push_state = ""
def emit_doorstate(response=None):
- state = logic.state
+ global json_push_state
+ json_dict = dict()
+
if response:
message = str(response)
else:
- message = str(state)
- socketio.emit('status', {'led': state.to_img(), 'message': message})
+ message = str(logic.state)
+ json_dict['message'] = message
+ json_dict['status'] = logic.state.value
+ json_push_state = json.dumps(json_dict)
+
+ #Notify push clients
+ evt.set()
+ evt.clear()
+
+def event_str():
+ return "data: {}\n\n".format(json_push_state)
+
+def push_state():
+ try:
+ yield event_str()
+ while True:
+ evt.wait()
+ yield event_str()
+ except GeneratorExit:
+ return
+
+def push_refresh():
+ while True:
+ sleep(10)
+ emit_doorstate()
+ evt.set()
+ evt.clear()
class AuthenticationForm(FlaskForm):
username = StringField('Username', [Length(min=3, max=25)])
@@ -64,13 +93,6 @@ class AuthenticationForm(FlaskForm):
return True
-
-@socketio.on('request_status')
-@socketio.on('connect')
-def on_connect():
- emit_doorstate()
-
-
@webapp.route('/display')
def display():
return render_template('display.html',
@@ -78,19 +100,25 @@ def display():
title=title,
welcome=welcome)
+@webapp.route('/push')
+def push():
+ if not json_push_state:
+ emit_doorstate()
+ return Response(push_state(),mimetype="text/event-stream")
+
@webapp.route('/api', methods=['POST'])
def api():
def json_response(response, msg=None):
- json = dict()
- json['err'] = response.value
- json['msg'] = str(response) if msg is None else msg
+ json_dict = dict()
+ json_dict['err'] = response.value
+ json_dict['msg'] = str(response) if msg is None else msg
if response == DoorlockResponse.Success or \
response == DoorlockResponse.AlreadyActive:
# TBD: Remove 'open'. No more users. Still used in App Version 2.1.1!
- json['open'] = logic.state.is_open()
- json['status'] = logic.state.value
- return jsonify(json)
+ json_dict['open'] = logic.state.is_open()
+ json_dict['status'] = logic.state.value
+ return jsonify(json_dict)
user = request.form.get('user')
password = request.form.get('pass')
@@ -137,6 +165,7 @@ def home():
desired_state = authentication_form.desired_state
log.info(' desired state: %s' % desired_state)
log.info(' current state: %s' % logic.state)
+
response = logic.request(desired_state, credentials)
log.info(' response: %s' % response)
@@ -154,6 +183,7 @@ def home():
def webapp_run(cfg, my_logic, status, version, template_folder, static_folder):
global logic
logic = my_logic
+ state = logic.state
debug = cfg.boolean('DEBUG')
@@ -176,4 +206,5 @@ def webapp_run(cfg, my_logic, status, version, template_folder, static_folder):
webapp.config['SECRET_KEY'] = cfg.str('SECRET_KEY')
webapp.template_folder = template_folder
webapp.static_folder = static_folder
- socketio.run(webapp, host=host, port=8080, use_reloader=False, debug=debug)
+ webapp.debug = debug
+ webapp.run()
diff --git a/share/doorlockd/templates/display.html b/share/doorlockd/templates/display.html
index cfb34f7..f1d12a6 100644
--- a/share/doorlockd/templates/display.html
+++ b/share/doorlockd/templates/display.html
@@ -13,23 +13,27 @@
{% endblock %}