mirror of
https://github.com/Manuel83/craftbeerpi3
synced 2026-08-10 02:55:27 +02:00
- Login Added. Default Password is „beer“
- Several UI Adjustments - still work in progress - New API Method to add custom JavaScript to CraftBeerPi - Global Action Buttons added - Register new Web Modules for complete custom UI
This commit is contained in:
@@ -87,6 +87,9 @@ class StepAPI(BaseAPI):
|
||||
return func
|
||||
return real_decorator
|
||||
|
||||
|
||||
|
||||
|
||||
class ActorAPI(BaseAPI):
|
||||
|
||||
key = "actor_types"
|
||||
@@ -150,6 +153,8 @@ class CoreAPI(BaseAPI):
|
||||
self.cbpi.cache["init"] = []
|
||||
self.cbpi.cache["js"] = {}
|
||||
self.cbpi.cache["background"] = []
|
||||
self.cbpi.cache["web_menu"] =[]
|
||||
|
||||
def init(self):
|
||||
|
||||
self.cbpi.cache["init"] = sorted(self.cbpi.cache["init"], key=lambda k: k['order'])
|
||||
@@ -173,6 +178,9 @@ class CoreAPI(BaseAPI):
|
||||
def add_js(self, name, file):
|
||||
self.cbpi.cache["js"][name] = file
|
||||
|
||||
def add_menu_link(self, name, path):
|
||||
self.cbpi.cache["web_menu"].append(dict(name=name, path=path))
|
||||
|
||||
def initializer(self, order=0, **options):
|
||||
def decorator(f):
|
||||
self.cbpi.cache.get("init").append({"function": f, "order": order})
|
||||
|
||||
@@ -246,4 +246,5 @@ class Step(Base):
|
||||
self.__dirty = True
|
||||
super(Step, self).__setattr__(name, value)
|
||||
else:
|
||||
super(Step, self).__setattr__(name, value)
|
||||
super(Step, self).__setattr__(name, value)
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from flask import request, json
|
||||
from flask_classy import route, FlaskView
|
||||
from flask_login import login_required
|
||||
|
||||
from modules.core.core import cbpi
|
||||
|
||||
|
||||
@@ -9,6 +11,7 @@ class BaseView(FlaskView):
|
||||
cache_key = None
|
||||
api = cbpi
|
||||
|
||||
@login_required
|
||||
@route('/<int:id>', methods=["GET"])
|
||||
def getOne(self, id):
|
||||
if self.api.cache.get(self.cache_key) is not None:
|
||||
@@ -16,6 +19,7 @@ class BaseView(FlaskView):
|
||||
else:
|
||||
return json.dumps(self.model.get_one(id))
|
||||
|
||||
@login_required
|
||||
@route('/', methods=["GET"])
|
||||
def getAll(self):
|
||||
if self.api.cache.get(self.cache_key) is not None:
|
||||
@@ -30,6 +34,7 @@ class BaseView(FlaskView):
|
||||
def _post_post_callback(self, m):
|
||||
pass
|
||||
|
||||
@login_required
|
||||
@route('/', methods=["POST"])
|
||||
def post(self):
|
||||
|
||||
@@ -50,7 +55,7 @@ class BaseView(FlaskView):
|
||||
def _post_put_callback(self, m):
|
||||
pass
|
||||
|
||||
|
||||
@login_required
|
||||
@route('/<int:id>', methods=["PUT"])
|
||||
def put(self, id):
|
||||
data = request.json
|
||||
@@ -78,6 +83,7 @@ class BaseView(FlaskView):
|
||||
def _post_delete_callback(self, id):
|
||||
pass
|
||||
|
||||
@login_required
|
||||
@route('/<int:id>', methods=["DELETE"])
|
||||
def delete(self, id):
|
||||
if self.api.cache.get(self.cache_key) is not None:
|
||||
|
||||
+53
-1
@@ -7,6 +7,7 @@ from datetime import datetime
|
||||
from functools import wraps, update_wrapper
|
||||
from importlib import import_module
|
||||
from time import localtime, strftime
|
||||
import time
|
||||
|
||||
from flask import Flask, redirect, json, g, make_response
|
||||
from flask_socketio import SocketIO
|
||||
@@ -17,6 +18,7 @@ from modules.core.basetypes import Sensor, Actor
|
||||
from modules.database.dbmodel import Kettle
|
||||
|
||||
|
||||
|
||||
class ComplexEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
try:
|
||||
@@ -109,6 +111,12 @@ class ActorCore(object):
|
||||
print e
|
||||
return False
|
||||
|
||||
def toggle(self, id):
|
||||
if self.cbpi.cache.get("actors").get(id).state == 0:
|
||||
self.on(id)
|
||||
else:
|
||||
self.off(id)
|
||||
|
||||
def power(self, id, power):
|
||||
try:
|
||||
actor = self.cbpi.cache["actors"].get(int(id))
|
||||
@@ -121,6 +129,20 @@ class ActorCore(object):
|
||||
print e
|
||||
return False
|
||||
|
||||
def action(self, id, method):
|
||||
self.cbpi.cache.get("actors").get(id).instance.__getattribute__(method)()
|
||||
|
||||
|
||||
def toggle_timeout(self, id, seconds):
|
||||
|
||||
def toggle( id, seconds):
|
||||
self.cbpi.cache.get("actors").get(int(id)).timer = int(time.time()) + int(seconds)
|
||||
self.toggle(int(id))
|
||||
self.cbpi.sleep(seconds)
|
||||
self.cbpi.cache.get("actors").get(int(id)).timer = None
|
||||
self.toggle(int(id))
|
||||
job = self.cbpi._socketio.start_background_task(target=toggle, id=id, seconds=seconds)
|
||||
|
||||
def get_state(self, actor_id):
|
||||
print actor_id
|
||||
print self.cbpi
|
||||
@@ -183,6 +205,10 @@ class SensorCore(object):
|
||||
with open(filename, "a") as file:
|
||||
file.write(msg)
|
||||
|
||||
def action(self, id, method):
|
||||
self.cbpi.cache.get("sensors").get(id).instance.__getattribute__(method)()
|
||||
|
||||
|
||||
|
||||
class BrewingCore(object):
|
||||
def __init__(self, cbpi):
|
||||
@@ -207,6 +233,32 @@ class BrewingCore(object):
|
||||
self.cbpi.emit("SET_KETTLE_TARGET_TEMP", id=id, temp=temp)
|
||||
|
||||
|
||||
def toggle_automatic(self, id):
|
||||
kettle = self.cbpi.cache.get("kettle")[id]
|
||||
if kettle.state is False:
|
||||
# Start controller
|
||||
if kettle.logic is not None:
|
||||
cfg = kettle.config.copy()
|
||||
cfg.update(dict(api=cbpi, kettle_id=kettle.id, heater=kettle.heater, sensor=kettle.sensor))
|
||||
instance = self.get_controller(kettle.logic).get("class")(**cfg)
|
||||
instance.init()
|
||||
kettle.instance = instance
|
||||
|
||||
def run(instance):
|
||||
instance.run()
|
||||
|
||||
t = self.cbpi._socketio.start_background_task(target=run, instance=instance)
|
||||
kettle.state = not kettle.state
|
||||
self.cbpi.ws_emit("UPDATE_KETTLE", cbpi.cache.get("kettle").get(id))
|
||||
self.cbpi.emit("KETTLE_CONTROLLER_STARTED", id=id)
|
||||
else:
|
||||
# Stop controller
|
||||
kettle.instance.stop()
|
||||
kettle.state = not kettle.state
|
||||
self.cbpi.ws_emit("UPDATE_KETTLE", cbpi.cache.get("kettle").get(id))
|
||||
self.cbpi.emit("KETTLE_CONTROLLER_STOPPED", id=id)
|
||||
|
||||
|
||||
class FermentationCore(object):
|
||||
def __init__(self, cbpi):
|
||||
self.cbpi = cbpi
|
||||
@@ -313,7 +365,7 @@ class CraftBeerPI(object):
|
||||
return cfg.value
|
||||
|
||||
def emit(self, key, **kwargs):
|
||||
print key, kwargs
|
||||
|
||||
if self.eventbus.get(key) is not None:
|
||||
for value in self.eventbus[key]:
|
||||
if value["async"] is False:
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import sqlite3
|
||||
import os
|
||||
from modules.core.core import cbpi
|
||||
from modules.core.db import get_db
|
||||
|
||||
def execute_file(curernt_version, data):
|
||||
if curernt_version >= data["version"]:
|
||||
cbpi._app.logger.info("SKIP DB FILE: %s" % data["file"])
|
||||
return
|
||||
try:
|
||||
with sqlite3.connect("craftbeerpi.db") as conn:
|
||||
with open('./update/%s' % data["file"], 'r') as f:
|
||||
d = f.read()
|
||||
sqlCommands = d.split(";")
|
||||
cur = conn.cursor()
|
||||
for s in sqlCommands:
|
||||
cur.execute(s)
|
||||
cur.execute("INSERT INTO schema_info (version,filename) values (?,?)", (data["version"], data["file"]))
|
||||
conn.commit()
|
||||
|
||||
except sqlite3.OperationalError as err:
|
||||
print "EXCEPT"
|
||||
print err
|
||||
|
||||
@cbpi.addon.core.initializer(order=-9999)
|
||||
def init(cbpi):
|
||||
|
||||
with cbpi._app.app_context():
|
||||
conn = get_db()
|
||||
cur = conn.cursor()
|
||||
current_version = None
|
||||
try:
|
||||
cur.execute("SELECT max(version) as m FROM schema_info")
|
||||
m = cur.fetchone()
|
||||
current_version = m["m"]
|
||||
except:
|
||||
pass
|
||||
result = []
|
||||
for filename in os.listdir("./update"):
|
||||
print filename
|
||||
if filename.endswith(".sql"):
|
||||
d = {"version": int(filename[:filename.index('_')]), "file": filename}
|
||||
result.append(d)
|
||||
execute_file(current_version, d)
|
||||
@@ -1,36 +0,0 @@
|
||||
import flask_login
|
||||
from modules.core.core import cbpi, addon
|
||||
|
||||
class User(flask_login.UserMixin):
|
||||
pass
|
||||
|
||||
@addon.core.initializer(order=0)
|
||||
def log(cbpi):
|
||||
|
||||
|
||||
cbpi._login_manager = flask_login.LoginManager()
|
||||
cbpi._login_manager.init_app(cbpi._app)
|
||||
@cbpi._app.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
user = User()
|
||||
user.id = "manuel"
|
||||
flask_login.login_user(user)
|
||||
return "OK"
|
||||
|
||||
@cbpi._app.route('/logout')
|
||||
def logout():
|
||||
flask_login.logout_user()
|
||||
return 'Logged out'
|
||||
|
||||
@cbpi._login_manager.user_loader
|
||||
def user_loader(email):
|
||||
if email not in cbpi.cache["users"]:
|
||||
return
|
||||
|
||||
user = User()
|
||||
user.id = email
|
||||
return user
|
||||
|
||||
@cbpi._login_manager.unauthorized_handler
|
||||
def unauthorized_handler():
|
||||
return 'Unauthorized :-('
|
||||
Reference in New Issue
Block a user