mirror of
https://github.com/binary-kitchen/doorlockd
synced 2024-12-22 18:34:25 +01:00
Remove socket.io dependency and use http server sent events instead
Signed-off-by: Thomas Schmid <tom@binary-kitchen.de>
This commit is contained in:
parent
f1c267dc94
commit
7676f957c5
@ -16,7 +16,6 @@ depends=('python3'
|
|||||||
'mosquitto'
|
'mosquitto'
|
||||||
'mpg123'
|
'mpg123'
|
||||||
'python-flask-wtf'
|
'python-flask-wtf'
|
||||||
'python-flask-socketio'
|
|
||||||
'python-paho-mqtt'
|
'python-paho-mqtt'
|
||||||
'chromium'
|
'chromium'
|
||||||
'xf86-video-fbdev'
|
'xf86-video-fbdev'
|
||||||
|
@ -24,7 +24,7 @@ from serial import Serial
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from os.path import join
|
from os.path import join
|
||||||
|
import gevent
|
||||||
from .Door import DoorState
|
from .Door import DoorState
|
||||||
from .Protocol import Protocol
|
from .Protocol import Protocol
|
||||||
|
|
||||||
|
34
pydoorlock/EventClient.py
Normal file
34
pydoorlock/EventClient.py
Normal file
@ -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']))
|
||||||
|
|
@ -16,9 +16,11 @@ details.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import json
|
||||||
|
import gevent
|
||||||
|
import threading
|
||||||
|
|
||||||
from flask import abort, Flask, jsonify, render_template, request
|
from flask import abort, Flask, jsonify, render_template, request, Response
|
||||||
from flask_socketio import SocketIO
|
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import PasswordField, StringField, SubmitField
|
from wtforms import PasswordField, StringField, SubmitField
|
||||||
from wtforms.validators import DataRequired, Length
|
from wtforms.validators import DataRequired, Length
|
||||||
@ -28,19 +30,46 @@ from .Doorlock import DoorlockResponse
|
|||||||
from .Authenticator import AuthMethod
|
from .Authenticator import AuthMethod
|
||||||
|
|
||||||
log = logging.getLogger()
|
log = logging.getLogger()
|
||||||
|
|
||||||
webapp = Flask(__name__)
|
webapp = Flask(__name__)
|
||||||
socketio = SocketIO(webapp, async_mode='threading')
|
evt = threading.Event()
|
||||||
|
json_push_state = ""
|
||||||
|
|
||||||
|
|
||||||
def emit_doorstate(response=None):
|
def emit_doorstate(response=None):
|
||||||
state = logic.state
|
global json_push_state
|
||||||
|
json_dict = dict()
|
||||||
|
|
||||||
if response:
|
if response:
|
||||||
message = str(response)
|
message = str(response)
|
||||||
else:
|
else:
|
||||||
message = str(state)
|
message = str(logic.state)
|
||||||
socketio.emit('status', {'led': state.to_img(), 'message': message})
|
|
||||||
|
|
||||||
|
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):
|
class AuthenticationForm(FlaskForm):
|
||||||
username = StringField('Username', [Length(min=3, max=25)])
|
username = StringField('Username', [Length(min=3, max=25)])
|
||||||
@ -64,13 +93,6 @@ class AuthenticationForm(FlaskForm):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@socketio.on('request_status')
|
|
||||||
@socketio.on('connect')
|
|
||||||
def on_connect():
|
|
||||||
emit_doorstate()
|
|
||||||
|
|
||||||
|
|
||||||
@webapp.route('/display')
|
@webapp.route('/display')
|
||||||
def display():
|
def display():
|
||||||
return render_template('display.html',
|
return render_template('display.html',
|
||||||
@ -78,19 +100,25 @@ def display():
|
|||||||
title=title,
|
title=title,
|
||||||
welcome=welcome)
|
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'])
|
@webapp.route('/api', methods=['POST'])
|
||||||
def api():
|
def api():
|
||||||
def json_response(response, msg=None):
|
def json_response(response, msg=None):
|
||||||
json = dict()
|
json_dict = dict()
|
||||||
json['err'] = response.value
|
json_dict['err'] = response.value
|
||||||
json['msg'] = str(response) if msg is None else msg
|
json_dict['msg'] = str(response) if msg is None else msg
|
||||||
if response == DoorlockResponse.Success or \
|
if response == DoorlockResponse.Success or \
|
||||||
response == DoorlockResponse.AlreadyActive:
|
response == DoorlockResponse.AlreadyActive:
|
||||||
# TBD: Remove 'open'. No more users. Still used in App Version 2.1.1!
|
# TBD: Remove 'open'. No more users. Still used in App Version 2.1.1!
|
||||||
json['open'] = logic.state.is_open()
|
json_dict['open'] = logic.state.is_open()
|
||||||
json['status'] = logic.state.value
|
json_dict['status'] = logic.state.value
|
||||||
return jsonify(json)
|
return jsonify(json_dict)
|
||||||
|
|
||||||
user = request.form.get('user')
|
user = request.form.get('user')
|
||||||
password = request.form.get('pass')
|
password = request.form.get('pass')
|
||||||
@ -137,6 +165,7 @@ def home():
|
|||||||
desired_state = authentication_form.desired_state
|
desired_state = authentication_form.desired_state
|
||||||
log.info(' desired state: %s' % desired_state)
|
log.info(' desired state: %s' % desired_state)
|
||||||
log.info(' current state: %s' % logic.state)
|
log.info(' current state: %s' % logic.state)
|
||||||
|
|
||||||
response = logic.request(desired_state, credentials)
|
response = logic.request(desired_state, credentials)
|
||||||
log.info(' response: %s' % response)
|
log.info(' response: %s' % response)
|
||||||
|
|
||||||
@ -154,6 +183,7 @@ def home():
|
|||||||
def webapp_run(cfg, my_logic, status, version, template_folder, static_folder):
|
def webapp_run(cfg, my_logic, status, version, template_folder, static_folder):
|
||||||
global logic
|
global logic
|
||||||
logic = my_logic
|
logic = my_logic
|
||||||
|
state = logic.state
|
||||||
|
|
||||||
debug = cfg.boolean('DEBUG')
|
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.config['SECRET_KEY'] = cfg.str('SECRET_KEY')
|
||||||
webapp.template_folder = template_folder
|
webapp.template_folder = template_folder
|
||||||
webapp.static_folder = static_folder
|
webapp.static_folder = static_folder
|
||||||
socketio.run(webapp, host=host, port=8080, use_reloader=False, debug=debug)
|
webapp.debug = debug
|
||||||
|
webapp.run()
|
||||||
|
@ -13,23 +13,27 @@
|
|||||||
<script type="text/javascript" src="static/socket.io.slim.js"></script>
|
<script type="text/javascript" src="static/socket.io.slim.js"></script>
|
||||||
<script type="text/javascript" charset="utf-8">
|
<script type="text/javascript" charset="utf-8">
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
function request_status() {
|
var source = new EventSource('{{ url_for('push')}}');
|
||||||
socket.emit('request_status');
|
source.onmessage = function(event){
|
||||||
}
|
console.log("event:" + event.data);
|
||||||
|
try{
|
||||||
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);
|
var data = JSON.parse(event.data);
|
||||||
var timer = setInterval(request_status, 120000);
|
$('#message').html(data.message);
|
||||||
|
led = $('#led');
|
||||||
socket.on('connect', function() {
|
switch(data.status){
|
||||||
socket.emit('connected');
|
case 0:
|
||||||
|
led.attr('src','static/led-green.png');
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
led.attr('src','static/led-yellow.png');
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
led.attr('src','static/led-red.png');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
} catch(e){console.log(e);}}
|
||||||
});
|
});
|
||||||
socket.on('status', function(status) {
|
|
||||||
$('#led').attr('src', status.led);
|
|
||||||
$('#message').html(status.message);
|
|
||||||
clearInterval(timer);
|
|
||||||
timer = setInterval(request_status, 120000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user