mirror of
https://github.com/Manuel83/craftbeerpi3
synced 2026-09-19 07:49:08 +02:00
- Refactoring
- Action Button with Parameter - Actor Action with Parameter - Sensor Action with Parameter
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
from modules.core.core import CraftBeerPI, Addon
|
||||||
|
|
||||||
|
cbpi = CraftBeerPI()
|
||||||
|
cbpi.addon = Addon(cbpi)
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
|
from flask import request
|
||||||
from flask_classy import FlaskView, route
|
from flask_classy import FlaskView, route
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
|
|
||||||
class ActionView(FlaskView):
|
class ActionView(FlaskView):
|
||||||
|
|
||||||
@@ -15,9 +17,10 @@ class ActionView(FlaskView):
|
|||||||
200:
|
200:
|
||||||
description: action invoked
|
description: action invoked
|
||||||
"""
|
"""
|
||||||
|
data = request.json
|
||||||
|
|
||||||
self.cbpi.cache["actions"][action]["function"](self.cbpi)
|
obj = self.cbpi.cache["actions"][action]["class"](self.cbpi)
|
||||||
|
obj.execute(**data)
|
||||||
return ('',204)
|
return ('',204)
|
||||||
|
|
||||||
@cbpi.addon.core.initializer()
|
@cbpi.addon.core.initializer()
|
||||||
@@ -28,4 +31,4 @@ def init(cbpi):
|
|||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
ActionView.cbpi = cbpi
|
ActionView.cbpi = cbpi
|
||||||
ActionView.register(cbpi._app, route_base='/api/action')
|
ActionView.register(cbpi.web, route_base='/api/action')
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
|
from flask import request
|
||||||
from flask_classy import route
|
from flask_classy import route
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
from modules.core.db import DBModel
|
from modules.core.db import DBModel
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from modules.core.baseview import BaseView
|
from modules.core.baseview import RestApi
|
||||||
from modules.database.dbmodel import Actor
|
from modules.database.dbmodel import Actor
|
||||||
|
|
||||||
|
|
||||||
class ActorView(BaseView):
|
class ActorView(RestApi):
|
||||||
model = Actor
|
model = Actor
|
||||||
cache_key = "actors"
|
cache_key = "actors"
|
||||||
|
|
||||||
@@ -121,7 +123,7 @@ class ActorView(BaseView):
|
|||||||
def toggleTimeJob(self, id, t):
|
def toggleTimeJob(self, id, t):
|
||||||
self.api.cache.get("actors").get(int(id)).timer = int(time.time()) + int(t)
|
self.api.cache.get("actors").get(int(id)).timer = int(time.time()) + int(t)
|
||||||
self.toggle(int(id))
|
self.toggle(int(id))
|
||||||
self.api._socketio.sleep(t)
|
self.api.sleep(t)
|
||||||
self.api.cache.get("actors").get(int(id)).timer = None
|
self.api.cache.get("actors").get(int(id)).timer = None
|
||||||
self.toggle(int(id))
|
self.toggle(int(id))
|
||||||
|
|
||||||
@@ -179,13 +181,18 @@ class ActorView(BaseView):
|
|||||||
200:
|
200:
|
||||||
description: Actor Action called
|
description: Actor Action called
|
||||||
"""
|
"""
|
||||||
|
data = request.json
|
||||||
self.api.actor.action(id, method)
|
if data:
|
||||||
|
cbpi.actor.action(id, method, **data)
|
||||||
|
else:
|
||||||
|
cbpi.actor.action(id, method)
|
||||||
return ('', 204)
|
return ('', 204)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@cbpi.addon.core.initializer(order=1000)
|
@cbpi.addon.core.initializer(order=1000)
|
||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
ActorView.register(cbpi._app, route_base='/api/actor')
|
ActorView.register(cbpi.web, route_base='/api/actor')
|
||||||
ActorView.init_cache()
|
ActorView.init_cache()
|
||||||
#cbpi.init_actors()
|
#cbpi.init_actors()
|
||||||
|
|||||||
@@ -1,15 +1,37 @@
|
|||||||
from modules.core.baseapi import Buzzer
|
from modules.core.baseapi import Buzzer
|
||||||
from modules.core.basetypes import Actor, KettleController, FermenterController
|
from modules.core.basetypes import Actor, KettleController, FermenterController
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
|
from modules.core.proptypes import Property
|
||||||
|
|
||||||
@cbpi.addon.actor.type("Dummy Actor")
|
@cbpi.addon.actor.type("Dummy Actor")
|
||||||
class Dummy(Actor):
|
class Dummy(Actor):
|
||||||
|
|
||||||
|
|
||||||
@cbpi.addon.actor.action("WOHOO")
|
# Decorator to create a parameter based action
|
||||||
def myaction(self):
|
@cbpi.addon.actor.action("Run until Temp reached", parameters={"t": Property.Text(label="Target Temp")})
|
||||||
print "WOOHOO"
|
def check_sensor_value(self, t=1):
|
||||||
pass
|
|
||||||
|
def check(api, id, value):
|
||||||
|
'''
|
||||||
|
Background Prozess which checks the sensor value every second
|
||||||
|
:param api:
|
||||||
|
:param id:
|
||||||
|
:param value:
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
|
while api.sensor.get_value(1) < value:
|
||||||
|
api.sleep(1)
|
||||||
|
api.actor.off(id)
|
||||||
|
|
||||||
|
target_value = int(t)
|
||||||
|
|
||||||
|
# Create notificaiton
|
||||||
|
self.api.notify(headline="Waiting", message="Waiting for temp %s" % target_value)
|
||||||
|
# Switch actor on
|
||||||
|
self.api.actor.on(self.id, 100)
|
||||||
|
# Start Background task
|
||||||
|
self.api.start_background_task(check, self.api, id=self.id, value=target_value)
|
||||||
|
|
||||||
|
|
||||||
def on(self, power=100):
|
def on(self, power=100):
|
||||||
'''
|
'''
|
||||||
@@ -17,11 +39,10 @@ class Dummy(Actor):
|
|||||||
:param power: int value between 0 - 100
|
:param power: int value between 0 - 100
|
||||||
:return:
|
:return:
|
||||||
'''
|
'''
|
||||||
print "ON"
|
print "ID %s ON" % self.id
|
||||||
|
|
||||||
def off(self):
|
def off(self):
|
||||||
print "OFF"
|
print "ID %s OFF" % self.id
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@cbpi.addon.kettle.controller()
|
@cbpi.addon.kettle.controller()
|
||||||
@@ -29,7 +50,7 @@ class MyController(KettleController):
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while self.is_running():
|
while self.is_running():
|
||||||
|
print "HALLO"
|
||||||
|
|
||||||
self.sleep(1)
|
self.sleep(1)
|
||||||
|
|
||||||
@@ -49,6 +70,7 @@ def init(cbpi):
|
|||||||
|
|
||||||
class MyBuzzer(Buzzer):
|
class MyBuzzer(Buzzer):
|
||||||
def beep(self):
|
def beep(self):
|
||||||
|
print "BEEEEEP"
|
||||||
pass
|
pass
|
||||||
|
|
||||||
cbpi.buzzer = MyBuzzer()
|
cbpi.buzzer = MyBuzzer()
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ import os
|
|||||||
|
|
||||||
from os.path import join
|
from os.path import join
|
||||||
|
|
||||||
from modules.core.basetypes import Actor, Sensor
|
from modules.core.basetypes import Actor, Sensor, Action
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from modules.core.proptypes import Property
|
from modules.core.proptypes import Property
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|
||||||
@cbpi.addon.sensor.type("Dummy Sensor")
|
@cbpi.addon.sensor.type("Dummy Sensor")
|
||||||
class Dummy(Sensor):
|
class Dummy(Sensor):
|
||||||
|
|
||||||
@@ -21,10 +22,15 @@ class Dummy(Sensor):
|
|||||||
else:
|
else:
|
||||||
self.unit = "°F"
|
self.unit = "°F"
|
||||||
|
|
||||||
@cbpi.addon.sensor.action("WOHOO")
|
@cbpi.addon.sensor.action(label="Set Dummy Temp", parameters={
|
||||||
def myaction(self):
|
"p1":Property.Select(label="Temp",options=[1,2,3]),
|
||||||
|
|
||||||
|
})
|
||||||
|
def myaction(self, p1):
|
||||||
|
self.text = p1
|
||||||
|
self.update_value(int(p1))
|
||||||
|
|
||||||
|
|
||||||
self.api.notify(headline="WOHOO", message="HALLO")
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
while True:
|
while True:
|
||||||
@@ -34,14 +40,28 @@ class Dummy(Sensor):
|
|||||||
pass
|
pass
|
||||||
self.api.sleep(5)
|
self.api.sleep(5)
|
||||||
|
|
||||||
@cbpi.addon.core.action(key="clear", label="Clear all Logs")
|
|
||||||
def woohoo(cbpi):
|
|
||||||
|
|
||||||
dir = "./logs"
|
@cbpi.addon.core.action(name="Delete All Logs")
|
||||||
test = os.listdir(dir)
|
class ParameterAction(Action):
|
||||||
|
|
||||||
for item in test:
|
p1 = Property.Number("P1", configurable=True, description="Target Temperature of Mash Step", unit="C")
|
||||||
|
p2 = Property.Number("P2", configurable=True, description="Target Temperature of Mash Step", unit="C")
|
||||||
|
|
||||||
if item.endswith(".log"):
|
|
||||||
os.remove(join(dir, item))
|
def execute(self, p1, p2, **kwargs):
|
||||||
cbpi.notify(headline="Logs Deleted",message="All Logs Cleared")
|
for i in range(5):
|
||||||
|
cbpi.sleep(1)
|
||||||
|
cbpi.notify(headline="Woohoo", message="%s %s" % (p1, p2))
|
||||||
|
|
||||||
|
|
||||||
|
@cbpi.addon.core.action(name="Delete All Logs")
|
||||||
|
class DeleteAllLogs(Action):
|
||||||
|
def execute(self, **kwargs):
|
||||||
|
dir = "./logs"
|
||||||
|
test = os.listdir(dir)
|
||||||
|
|
||||||
|
for item in test:
|
||||||
|
|
||||||
|
if item.endswith(".log"):
|
||||||
|
os.remove(join(dir, item))
|
||||||
|
cbpi.notify(headline="Logs Deleted", message="All Logs Cleared")
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
from modules.core.basetypes import Step
|
from modules.core.basetypes import Step
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from modules.core.proptypes import Property
|
from modules.core.proptypes import Property
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ class Dummy(Step):
|
|||||||
time = Property.Text(label="Text", configurable=True, description="WOHOOO")
|
time = Property.Text(label="Text", configurable=True, description="WOHOOO")
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
#print self.text
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
@@ -36,8 +36,8 @@ class MashStep(Step):
|
|||||||
Just put the decorator @cbpi.step on top of a method
|
Just put the decorator @cbpi.step on top of a method
|
||||||
'''
|
'''
|
||||||
# Properties
|
# Properties
|
||||||
temp = Property.Number("Temperature", configurable=True, description="Target Temperature of Mash Step")
|
temp = Property.Number("Temperature", configurable=True, description="Target Temperature of Mash Step", unit="C")
|
||||||
kettle = Property.Kettle("Kettle", description="Kettle in which the mashing takes place")
|
kettle = Property.Kettle("Kettle", description="Kettle in which the mashing takes place" )
|
||||||
timer = Property.Number("Timer in Minutes", configurable=True, description="Timer is started when the target temperature is reached")
|
timer = Property.Number("Timer in Minutes", configurable=True, description="Timer is started when the target temperature is reached")
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
@@ -79,6 +79,7 @@ class MashStep(Step):
|
|||||||
|
|
||||||
# Check if timer finished and go to next step
|
# Check if timer finished and go to next step
|
||||||
if self.is_timer_finished() == True:
|
if self.is_timer_finished() == True:
|
||||||
|
self.api.beep()
|
||||||
self.notify("Mash Step Completed!", "Starting the next step", timeout=None)
|
self.notify("Mash Step Completed!", "Starting the next step", timeout=None)
|
||||||
self.next()
|
self.next()
|
||||||
|
|
||||||
@@ -243,3 +244,5 @@ class BoilStep(Step):
|
|||||||
if self.is_timer_finished() == True:
|
if self.is_timer_finished() == True:
|
||||||
self.notify("Boil Step Completed!", "Starting the next step", timeout=None)
|
self.notify("Boil Step Completed!", "Starting the next step", timeout=None)
|
||||||
self.next()
|
self.next()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import time
|
|||||||
from thread import start_new_thread
|
from thread import start_new_thread
|
||||||
|
|
||||||
from modules.core.baseapi import Buzzer
|
from modules.core.baseapi import Buzzer
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import RPi.GPIO as GPIO
|
import RPi.GPIO as GPIO
|
||||||
@@ -16,19 +16,19 @@ class GPIOBuzzer(Buzzer):
|
|||||||
|
|
||||||
def __init__(self, gpio):
|
def __init__(self, gpio):
|
||||||
try:
|
try:
|
||||||
cbpi._app.logger.info("INIT BUZZER NOW GPIO%s" % gpio)
|
cbpi.web.logger.info("INIT BUZZER NOW GPIO%s" % gpio)
|
||||||
self.gpio = int(gpio)
|
self.gpio = int(gpio)
|
||||||
GPIO.setmode(GPIO.BCM)
|
GPIO.setmode(GPIO.BCM)
|
||||||
GPIO.setup(self.gpio, GPIO.OUT)
|
GPIO.setup(self.gpio, GPIO.OUT)
|
||||||
self.state = True
|
self.state = True
|
||||||
cbpi._app.logger.info("BUZZER SETUP OK")
|
cbpi.web.logger.info("BUZZER SETUP OK")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
cbpi._app.logger.info("BUZZER EXCEPTION %s" % str(e))
|
cbpi.web.logger.info("BUZZER EXCEPTION %s" % str(e))
|
||||||
self.state = False
|
self.state = False
|
||||||
|
|
||||||
def beep(self):
|
def beep(self):
|
||||||
if self.state is False:
|
if self.state is False:
|
||||||
cbpi._app.logger.error("BUZZER not working")
|
cbpi.web.logger.error("BUZZER not working")
|
||||||
return
|
return
|
||||||
|
|
||||||
def play(sound):
|
def play(sound):
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import time
|
|||||||
|
|
||||||
from flask import json, request
|
from flask import json, request
|
||||||
from flask_classy import route
|
from flask_classy import route
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from modules.core.db import DBModel
|
from modules.core.db import DBModel
|
||||||
from modules.core.baseview import BaseView
|
from modules.core.baseview import RestApi
|
||||||
from modules.database.dbmodel import Config
|
from modules.database.dbmodel import Config
|
||||||
|
|
||||||
|
|
||||||
class ConfigView(BaseView):
|
class ConfigView(RestApi):
|
||||||
model = Config
|
model = Config
|
||||||
cache_key = "config"
|
cache_key = "config"
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ class ConfigView(BaseView):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def init_cache(cls):
|
def init_cache(cls):
|
||||||
|
|
||||||
with cls.api._app.app_context():
|
with cls.api.web.app_context():
|
||||||
cls.api.cache[cls.cache_key] = {}
|
cls.api.cache[cls.cache_key] = {}
|
||||||
for key, value in cls.model.get_all().iteritems():
|
for key, value in cls.model.get_all().iteritems():
|
||||||
cls.post_init_callback(value)
|
cls.post_init_callback(value)
|
||||||
@@ -85,5 +85,5 @@ class ConfigView(BaseView):
|
|||||||
|
|
||||||
@cbpi.addon.core.initializer(order=0)
|
@cbpi.addon.core.initializer(order=0)
|
||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
ConfigView.register(cbpi._app, route_base='/api/config')
|
ConfigView.register(cbpi.web, route_base='/api/config')
|
||||||
ConfigView.init_cache()
|
ConfigView.init_cache()
|
||||||
|
|||||||
+62
-26
@@ -22,6 +22,9 @@ class BaseAPI(object):
|
|||||||
except:
|
except:
|
||||||
doc = ""
|
doc = ""
|
||||||
|
|
||||||
|
if self.cbpi.cache.get(key) is None:
|
||||||
|
self.cbpi.cache[key] = {}
|
||||||
|
self.cbpi.logger.debug(name)
|
||||||
self.cbpi.cache.get(key)[name] = {"name": name, "class": cls, "description":doc, "properties": [], "actions": []}
|
self.cbpi.cache.get(key)[name] = {"name": name, "class": cls, "description":doc, "properties": [], "actions": []}
|
||||||
self.cbpi.cache.get(key)[name].update(options)
|
self.cbpi.cache.get(key)[name].update(options)
|
||||||
members = [attr for attr in dir(tmpObj) if not callable(getattr(tmpObj, attr)) and not attr.startswith("__")]
|
members = [attr for attr in dir(tmpObj) if not callable(getattr(tmpObj, attr)) and not attr.startswith("__")]
|
||||||
@@ -29,23 +32,39 @@ class BaseAPI(object):
|
|||||||
t = tmpObj.__getattribute__(m)
|
t = tmpObj.__getattribute__(m)
|
||||||
|
|
||||||
if isinstance(t, Property.Number):
|
if isinstance(t, Property.Number):
|
||||||
self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "number", "configurable": t.configurable, "description": t.description, "default_value": t.default_value})
|
self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "number", "configurable": t.configurable, "description": t.description, "default_value": t.default_value, "unit": t.unit})
|
||||||
elif isinstance(t, Property.Text):
|
elif isinstance(t, Property.Text):
|
||||||
self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "text", "required": t.required, "configurable": t.configurable, "description": t.description, "default_value": t.default_value})
|
self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "text", "required": t.required, "configurable": t.configurable, "description": t.description, "default_value": t.default_value})
|
||||||
elif isinstance(tmpObj.__getattribute__(m), Property.Select):
|
elif isinstance(t, Property.Select):
|
||||||
self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "select", "configurable": True, "options": t.options, "description": t.description})
|
self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "select", "configurable": True, "options": t.options, "description": t.description})
|
||||||
elif isinstance(tmpObj.__getattribute__(m), Property.Actor):
|
elif isinstance(t, Property.Actor):
|
||||||
self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "actor", "configurable": True, "description": t.description})
|
self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "actor", "configurable": True, "description": t.description})
|
||||||
elif isinstance(tmpObj.__getattribute__(m), Property.Sensor):
|
elif isinstance(t, Property.Sensor):
|
||||||
self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "sensor", "configurable": True, "description": t.description})
|
self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "sensor", "configurable": True, "description": t.description})
|
||||||
elif isinstance(tmpObj.__getattribute__(m), Property.Kettle):
|
elif isinstance(t, Property.Kettle):
|
||||||
self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "kettle", "configurable": True, "description": t.description})
|
self.cbpi.cache.get(key)[name]["properties"].append({"name": m, "label": t.label, "type": "kettle", "configurable": True, "description": t.description})
|
||||||
|
|
||||||
for method_name, method in cls.__dict__.iteritems():
|
for method_name, method in cls.__dict__.iteritems():
|
||||||
if hasattr(method, "action"):
|
if hasattr(method, "action"):
|
||||||
label = method.__getattribute__("label")
|
label = method.__getattribute__("label")
|
||||||
self.cbpi.cache.get(key)[name]["actions"].append({"method": method_name, "label": label})
|
parameters = method.__getattribute__("parameters")
|
||||||
|
props = []
|
||||||
|
if parameters is not None:
|
||||||
|
for k, t in parameters.iteritems():
|
||||||
|
if isinstance(t, Property.Number):
|
||||||
|
props.append({"name": k, "label": t.label, "type": "number", "configurable": t.configurable, "description": t.description, "default_value": t.default_value, "unit": t.unit})
|
||||||
|
elif isinstance(t, Property.Text):
|
||||||
|
props.append({"name": k, "label": t.label, "type": "text", "required": t.required, "configurable": t.configurable, "description": t.description, "default_value": t.default_value})
|
||||||
|
elif isinstance(t, Property.Select):
|
||||||
|
props.append({"name": k, "label": t.label, "type": "select", "configurable": True, "options": t.options, "description": t.description})
|
||||||
|
elif isinstance(t, Property.Actor):
|
||||||
|
props.append({"name": k, "label": t.label, "type": "actor", "configurable": True, "description": t.description})
|
||||||
|
elif isinstance(t, Property.Sensor):
|
||||||
|
props.append({"name": k, "label": t.label, "type": "sensor", "configurable": True, "description": t.description})
|
||||||
|
elif isinstance(t, Property.Kettle):
|
||||||
|
props.append({"name": k, "label": t.label, "type": "kettle", "configurable": True, "description": t.description})
|
||||||
|
|
||||||
|
self.cbpi.cache.get(key)[name]["actions"].append({"method": method_name, "label": label, "properties":props })
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
|
||||||
@@ -59,9 +78,11 @@ class SensorAPI(BaseAPI):
|
|||||||
return f
|
return f
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def action(self, label):
|
def action(self, label, parameters=None):
|
||||||
|
|
||||||
def real_decorator(func):
|
def real_decorator(func):
|
||||||
func.action = True
|
func.action = True
|
||||||
|
func.parameters = parameters
|
||||||
func.label = label
|
func.label = label
|
||||||
return func
|
return func
|
||||||
return real_decorator
|
return real_decorator
|
||||||
@@ -80,10 +101,11 @@ class StepAPI(BaseAPI):
|
|||||||
return f
|
return f
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def action(self, label):
|
def action(self, label, parameters=None):
|
||||||
def real_decorator(func):
|
def real_decorator(func):
|
||||||
func.action = True
|
func.action = True
|
||||||
func.label = label
|
func.label = label
|
||||||
|
func.parameters = parameters
|
||||||
return func
|
return func
|
||||||
return real_decorator
|
return real_decorator
|
||||||
|
|
||||||
@@ -100,10 +122,11 @@ class ActorAPI(BaseAPI):
|
|||||||
return f
|
return f
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def action(self, label):
|
def action(self, label, parameters=None):
|
||||||
def real_decorator(func):
|
def real_decorator(func):
|
||||||
func.action = True
|
func.action = True
|
||||||
func.label = label
|
func.label = label
|
||||||
|
func.parameters = parameters
|
||||||
return func
|
return func
|
||||||
return real_decorator
|
return real_decorator
|
||||||
|
|
||||||
@@ -119,10 +142,11 @@ class KettleAPI(BaseAPI):
|
|||||||
return f
|
return f
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def action(self, label):
|
def action(self, label, parameters=None):
|
||||||
def real_decorator(func):
|
def real_decorator(func):
|
||||||
func.action = True
|
func.action = True
|
||||||
func.label = label
|
func.label = label
|
||||||
|
func.parameters = parameters
|
||||||
return func
|
return func
|
||||||
return real_decorator
|
return real_decorator
|
||||||
|
|
||||||
@@ -136,10 +160,11 @@ class FermenterAPI(BaseAPI):
|
|||||||
return f
|
return f
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def action(self, label):
|
def action(self, label, parameters=None):
|
||||||
def real_decorator(func):
|
def real_decorator(func):
|
||||||
func.action = True
|
func.action = True
|
||||||
func.label = label
|
func.label = label
|
||||||
|
func.parameters = parameters
|
||||||
return func
|
return func
|
||||||
return real_decorator
|
return real_decorator
|
||||||
|
|
||||||
@@ -156,7 +181,6 @@ class CoreAPI(BaseAPI):
|
|||||||
self.cbpi.cache["web_menu"] =[]
|
self.cbpi.cache["web_menu"] =[]
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
|
|
||||||
self.cbpi.cache["init"] = sorted(self.cbpi.cache["init"], key=lambda k: k['order'])
|
self.cbpi.cache["init"] = sorted(self.cbpi.cache["init"], key=lambda k: k['order'])
|
||||||
for value in self.cbpi.cache.get("init"):
|
for value in self.cbpi.cache.get("init"):
|
||||||
|
|
||||||
@@ -168,12 +192,17 @@ class CoreAPI(BaseAPI):
|
|||||||
try:
|
try:
|
||||||
method(self.cbpi)
|
method(self.cbpi)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print e
|
self.cbpi.logger.error(e)
|
||||||
self.cbpi._socketio.sleep(interval)
|
self.cbpi.sleep(interval)
|
||||||
|
|
||||||
for value in self.cbpi.cache.get("background"):
|
for value in self.cbpi.cache.get("background"):
|
||||||
t = self.cbpi._socketio.start_background_task(target=job, interval=value.get("interval"), method=value.get("function"))
|
t = self.cbpi.start_background_task(target=job, interval=value.get("interval"), method=value.get("function"))
|
||||||
|
|
||||||
|
def action(self, **options):
|
||||||
|
def decorator(f):
|
||||||
|
BaseAPI.parseProps(self, "actions", f)
|
||||||
|
return f
|
||||||
|
return decorator
|
||||||
|
|
||||||
def add_js(self, name, file):
|
def add_js(self, name, file):
|
||||||
self.cbpi.cache["js"][name] = file
|
self.cbpi.cache["js"][name] = file
|
||||||
@@ -187,15 +216,7 @@ class CoreAPI(BaseAPI):
|
|||||||
return f
|
return f
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
def backgroundtask(self, key, interval, **options):
|
||||||
def action(self, key, label, **options):
|
|
||||||
def decorator(f):
|
|
||||||
self.cbpi.cache.get("actions")[key] = {"label": label, "function": f}
|
|
||||||
return f
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
def backgroundjob(self, key, interval, **options):
|
|
||||||
def decorator(f):
|
def decorator(f):
|
||||||
self.cbpi.cache.get("background").append({"function": f, "key": key, "interval": interval})
|
self.cbpi.cache.get("background").append({"function": f, "key": key, "interval": interval})
|
||||||
return f
|
return f
|
||||||
@@ -220,5 +241,20 @@ class CoreAPI(BaseAPI):
|
|||||||
|
|
||||||
class Buzzer(object):
|
class Buzzer(object):
|
||||||
|
|
||||||
def beep():
|
def beep(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class Addon(object):
|
||||||
|
def __init__(self, cbpi):
|
||||||
|
self.step = StepAPI(cbpi)
|
||||||
|
self.actor = ActorAPI(cbpi)
|
||||||
|
self.sensor = SensorAPI(cbpi)
|
||||||
|
self.kettle = KettleAPI(cbpi)
|
||||||
|
self.fermenter = FermenterAPI(cbpi)
|
||||||
|
self.core = CoreAPI(cbpi)
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
self.core.init()
|
||||||
|
self.step.init()
|
||||||
|
self.actor.init()
|
||||||
|
self.sensor.init()
|
||||||
@@ -12,11 +12,15 @@ class Base(object):
|
|||||||
self.value = None
|
self.value = None
|
||||||
self.__dirty = False
|
self.__dirty = False
|
||||||
|
|
||||||
|
class Action(Base):
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
pass
|
||||||
|
|
||||||
class Actor(Base):
|
class Actor(Base):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def init_global(cls):
|
def init_global(cls):
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
@@ -68,9 +72,6 @@ class Sensor(Base):
|
|||||||
print "EXECUTE"
|
print "EXECUTE"
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ControllerBase(object):
|
class ControllerBase(object):
|
||||||
__dirty = False
|
__dirty = False
|
||||||
__running = False
|
__running = False
|
||||||
@@ -271,7 +272,6 @@ class Step(Base, Timer):
|
|||||||
|
|
||||||
def set_target_temp(self, temp, id=None):
|
def set_target_temp(self, temp, id=None):
|
||||||
temp = float(temp)
|
temp = float(temp)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if id is None:
|
if id is None:
|
||||||
self.api.emit("SET_TARGET_TEMP", id=self.kettle_id, temp=temp)
|
self.api.emit("SET_TARGET_TEMP", id=self.kettle_id, temp=temp)
|
||||||
@@ -281,7 +281,6 @@ class Step(Base, Timer):
|
|||||||
|
|
||||||
self.api.notify("Faild to set Target Temp", "", type="warning")
|
self.api.notify("Faild to set Target Temp", "", type="warning")
|
||||||
|
|
||||||
|
|
||||||
def get_kettle_temp(self, id=None):
|
def get_kettle_temp(self, id=None):
|
||||||
id = int(id)
|
id = int(id)
|
||||||
if id is None:
|
if id is None:
|
||||||
@@ -294,6 +293,8 @@ class Step(Base, Timer):
|
|||||||
def reset_dirty(self):
|
def reset_dirty(self):
|
||||||
self.__dirty = False
|
self.__dirty = False
|
||||||
|
|
||||||
|
def notify(self, headline, messsage, timeout=None):
|
||||||
|
self.api.notify(headline, messsage, timeout)
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
|
|
||||||
if name != "_StepBase__dirty" and name in self.managed_fields:
|
if name != "_StepBase__dirty" and name in self.managed_fields:
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ from flask import request, json
|
|||||||
from flask_classy import route, FlaskView
|
from flask_classy import route, FlaskView
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
|
|
||||||
|
|
||||||
class BaseView(FlaskView):
|
class RestApi(FlaskView):
|
||||||
|
|
||||||
as_array = False
|
as_array = False
|
||||||
cache_key = None
|
cache_key = None
|
||||||
@@ -39,7 +39,7 @@ class BaseView(FlaskView):
|
|||||||
def post(self):
|
def post(self):
|
||||||
|
|
||||||
data = request.json
|
data = request.json
|
||||||
self.api._app.logger.info("INSERT Model %s", self.model.__name__)
|
self.api.web.logger.info("INSERT Model %s", self.model.__name__)
|
||||||
self._pre_post_callback(data)
|
self._pre_post_callback(data)
|
||||||
m = self.model.insert(**data)
|
m = self.model.insert(**data)
|
||||||
if self.api.cache.get(self.cache_key) is not None:
|
if self.api.cache.get(self.cache_key) is not None:
|
||||||
@@ -101,7 +101,7 @@ class BaseView(FlaskView):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def init_cache(cls):
|
def init_cache(cls):
|
||||||
with cls.api._app.app_context():
|
with cls.api.web.app_context():
|
||||||
|
|
||||||
if cls.model.__as_array__ is True:
|
if cls.model.__as_array__ is True:
|
||||||
cls.api.cache[cls.cache_key] = []
|
cls.api.cache[cls.cache_key] = []
|
||||||
|
|||||||
+53
-53
@@ -22,7 +22,6 @@ from modules.database.dbmodel import Kettle
|
|||||||
class ComplexEncoder(json.JSONEncoder):
|
class ComplexEncoder(json.JSONEncoder):
|
||||||
def default(self, obj):
|
def default(self, obj):
|
||||||
try:
|
try:
|
||||||
|
|
||||||
if isinstance(obj, DBModel):
|
if isinstance(obj, DBModel):
|
||||||
return obj.__dict__
|
return obj.__dict__
|
||||||
elif isinstance(obj, Actor):
|
elif isinstance(obj, Actor):
|
||||||
@@ -33,31 +32,11 @@ class ComplexEncoder(json.JSONEncoder):
|
|||||||
return obj()
|
return obj()
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return None
|
return None
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
pass
|
pass
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class Addon(object):
|
|
||||||
def __init__(self, cbpi):
|
|
||||||
self.step = StepAPI(cbpi)
|
|
||||||
self.actor = ActorAPI(cbpi)
|
|
||||||
self.sensor = SensorAPI(cbpi)
|
|
||||||
self.kettle = KettleAPI(cbpi)
|
|
||||||
self.fermenter = FermenterAPI(cbpi)
|
|
||||||
self.core = CoreAPI(cbpi)
|
|
||||||
|
|
||||||
def init(self):
|
|
||||||
self.core.init()
|
|
||||||
self.step.init()
|
|
||||||
self.actor.init()
|
|
||||||
self.sensor.init()
|
|
||||||
# self.kettle.init()
|
|
||||||
# self.fermenter.init()
|
|
||||||
|
|
||||||
|
|
||||||
class ActorCore(object):
|
class ActorCore(object):
|
||||||
key = "actor_types"
|
key = "actor_types"
|
||||||
|
|
||||||
@@ -82,8 +61,7 @@ class ActorCore(object):
|
|||||||
actor.power = 100
|
actor.power = 100
|
||||||
self.cbpi.emit("INIT_ACTOR", id=id)
|
self.cbpi.emit("INIT_ACTOR", id=id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print e
|
self.cbpi.web.logger.error(e)
|
||||||
self.cbpi._app.logger.error(e)
|
|
||||||
|
|
||||||
def stop_one(self, id):
|
def stop_one(self, id):
|
||||||
self.cbpi.cache["actors"][id]["instance"].stop()
|
self.cbpi.cache["actors"][id]["instance"].stop()
|
||||||
@@ -99,7 +77,7 @@ class ActorCore(object):
|
|||||||
self.cbpi.emit("SWITCH_ACTOR_ON", id=id, power=power)
|
self.cbpi.emit("SWITCH_ACTOR_ON", id=id, power=power)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print e
|
self.cbpi.logger.error(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def off(self, id):
|
def off(self, id):
|
||||||
@@ -111,7 +89,7 @@ class ActorCore(object):
|
|||||||
self.cbpi.emit("SWITCH_ACTOR_OFF", id=id)
|
self.cbpi.emit("SWITCH_ACTOR_OFF", id=id)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print e
|
self.cbpi.logger.error(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def toggle(self, id):
|
def toggle(self, id):
|
||||||
@@ -129,11 +107,11 @@ class ActorCore(object):
|
|||||||
self.cbpi.emit("SWITCH_ACTOR_POWER_CHANGE", id=id, power=power)
|
self.cbpi.emit("SWITCH_ACTOR_POWER_CHANGE", id=id, power=power)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print e
|
self.cbpi.logger.error(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def action(self, id, method):
|
def action(self, id, method, **data):
|
||||||
self.cbpi.cache.get("actors").get(id).instance.__getattribute__(method)()
|
self.cbpi.cache.get("actors").get(id).instance.__getattribute__(method)(**data)
|
||||||
|
|
||||||
|
|
||||||
def toggle_timeout(self, id, seconds):
|
def toggle_timeout(self, id, seconds):
|
||||||
@@ -182,7 +160,7 @@ class SensorCore(object):
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print "ERROR"
|
print "ERROR"
|
||||||
self.cbpi._app.logger.error(e)
|
self.cbpi.web.logger.error(e)
|
||||||
|
|
||||||
def stop_one(self, id):
|
def stop_one(self, id):
|
||||||
|
|
||||||
@@ -206,12 +184,12 @@ class SensorCore(object):
|
|||||||
with open(filename, "a") as file:
|
with open(filename, "a") as file:
|
||||||
file.write(msg)
|
file.write(msg)
|
||||||
|
|
||||||
def action(self, id, method):
|
def action(self, id, method, **data):
|
||||||
self.cbpi.cache.get("sensors").get(id).instance.__getattribute__(method)()
|
self.cbpi.cache.get("sensors").get(id).instance.__getattribute__(method)(**data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BrewingCore(object):
|
class BrewingCore(object):
|
||||||
|
|
||||||
def __init__(self, cbpi):
|
def __init__(self, cbpi):
|
||||||
self.cbpi = cbpi
|
self.cbpi = cbpi
|
||||||
self.cbpi.cache["step_types"] = {}
|
self.cbpi.cache["step_types"] = {}
|
||||||
@@ -240,7 +218,7 @@ class BrewingCore(object):
|
|||||||
# Start controller
|
# Start controller
|
||||||
if kettle.logic is not None:
|
if kettle.logic is not None:
|
||||||
cfg = kettle.config.copy()
|
cfg = kettle.config.copy()
|
||||||
cfg.update(dict(api=cbpi, kettle_id=kettle.id, heater=kettle.heater, sensor=kettle.sensor))
|
cfg.update(dict(api=self.cbpi, kettle_id=kettle.id, heater=kettle.heater, sensor=kettle.sensor))
|
||||||
instance = self.get_controller(kettle.logic).get("class")(**cfg)
|
instance = self.get_controller(kettle.logic).get("class")(**cfg)
|
||||||
instance.init()
|
instance.init()
|
||||||
kettle.instance = instance
|
kettle.instance = instance
|
||||||
@@ -250,13 +228,13 @@ class BrewingCore(object):
|
|||||||
|
|
||||||
t = self.cbpi._socketio.start_background_task(target=run, instance=instance)
|
t = self.cbpi._socketio.start_background_task(target=run, instance=instance)
|
||||||
kettle.state = not kettle.state
|
kettle.state = not kettle.state
|
||||||
self.cbpi.ws_emit("UPDATE_KETTLE", cbpi.cache.get("kettle").get(id))
|
self.cbpi.ws_emit("UPDATE_KETTLE", self.cbpi.cache.get("kettle").get(id))
|
||||||
self.cbpi.emit("KETTLE_CONTROLLER_STARTED", id=id)
|
self.cbpi.emit("KETTLE_CONTROLLER_STARTED", id=id)
|
||||||
else:
|
else:
|
||||||
# Stop controller
|
# Stop controller
|
||||||
kettle.instance.stop()
|
kettle.instance.stop()
|
||||||
kettle.state = not kettle.state
|
kettle.state = not kettle.state
|
||||||
self.cbpi.ws_emit("UPDATE_KETTLE", cbpi.cache.get("kettle").get(id))
|
self.cbpi.ws_emit("UPDATE_KETTLE", self.cbpi.cache.get("kettle").get(id))
|
||||||
self.cbpi.emit("KETTLE_CONTROLLER_STOPPED", id=id)
|
self.cbpi.emit("KETTLE_CONTROLLER_STOPPED", id=id)
|
||||||
|
|
||||||
|
|
||||||
@@ -270,28 +248,50 @@ class FermentationCore(object):
|
|||||||
return self.cbpi.cache["fermentation_controller_types"].get(name)
|
return self.cbpi.cache["fermentation_controller_types"].get(name)
|
||||||
|
|
||||||
|
|
||||||
|
class Logger(object):
|
||||||
|
def __init__(self, cbpi):
|
||||||
|
self.cbpi = cbpi
|
||||||
|
|
||||||
|
def error(self, msg, *args, **kwargs):
|
||||||
|
self.cbpi.web.logger.error(msg, *args, **kwargs)
|
||||||
|
|
||||||
|
def info(self, msg, *args, **kwargs):
|
||||||
|
self.cbpi.web.logger.info(msg, *args, **kwargs)
|
||||||
|
|
||||||
|
def debug(self, msg, *args, **kwargs):
|
||||||
|
self.cbpi.web.logger.debug(msg, *args, **kwargs)
|
||||||
|
|
||||||
|
def warning(self, msg, *args, **kwargs):
|
||||||
|
self.cbpi.web.logger.warning(msg, *args, **kwargs)
|
||||||
|
|
||||||
class CraftBeerPI(object):
|
class CraftBeerPI(object):
|
||||||
cache = {}
|
cache = {}
|
||||||
eventbus = {}
|
eventbus = {}
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
FORMAT = '%(asctime)-15s - %(levelname)s - %(message)s'
|
|
||||||
logging.basicConfig(filename='./logs/app.log', level=logging.INFO, format=FORMAT)
|
|
||||||
self.cache["messages"] = []
|
self.cache["messages"] = []
|
||||||
self.cache["version"] = "3.1"
|
self.cache["version"] = "3.1"
|
||||||
self.modules = {}
|
FORMAT = '%(asctime)-15s - %(levelname)s - %(message)s'
|
||||||
|
logging.basicConfig(filename='./logs/app.log', level=logging.INFO, format=FORMAT)
|
||||||
|
logging.getLogger('socketio').setLevel(logging.ERROR)
|
||||||
|
logging.getLogger('engineio').setLevel(logging.ERROR)
|
||||||
|
self.web = Flask(__name__)
|
||||||
|
self.logger = Logger(self)
|
||||||
|
|
||||||
|
self.logger.info("###Startup CraftBeerPi %s ###" % self.cache.get("version"))
|
||||||
|
self.web.secret_key = 'Cr4ftB33rP1'
|
||||||
|
self.web.json_encoder = ComplexEncoder
|
||||||
|
self._socketio = SocketIO(self.web, json=json, logging=False)
|
||||||
|
|
||||||
|
|
||||||
|
self.modules = {}
|
||||||
self.addon = Addon(self)
|
self.addon = Addon(self)
|
||||||
self.actor = ActorCore(self)
|
self.actor = ActorCore(self)
|
||||||
self.sensor = SensorCore(self)
|
self.sensor = SensorCore(self)
|
||||||
self.brewing = BrewingCore(self)
|
self.brewing = BrewingCore(self)
|
||||||
self.fermentation = FermentationCore(self)
|
self.fermentation = FermentationCore(self)
|
||||||
self._app = Flask(__name__)
|
|
||||||
self._app.secret_key = 'Cr4ftB33rP1'
|
|
||||||
self._app.json_encoder = ComplexEncoder
|
|
||||||
self._socketio = SocketIO(self._app, json=json, logging=False)
|
|
||||||
|
|
||||||
@self._app.route('/')
|
@self.web.route('/')
|
||||||
def index():
|
def index():
|
||||||
return redirect('ui')
|
return redirect('ui')
|
||||||
|
|
||||||
@@ -303,11 +303,11 @@ class CraftBeerPI(object):
|
|||||||
self.actor.init()
|
self.actor.init()
|
||||||
self.beep()
|
self.beep()
|
||||||
try:
|
try:
|
||||||
port = int(cbpi.get_config_parameter('port', '5000'))
|
port = int(self.get_config_parameter('port', '5000'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
port = 5000
|
port = 5000
|
||||||
print port
|
|
||||||
self._socketio.run(self._app, host='0.0.0.0', port=port)
|
self._socketio.run(self.web, host='0.0.0.0', port=port)
|
||||||
|
|
||||||
def beep(self):
|
def beep(self):
|
||||||
self.buzzer.beep()
|
self.buzzer.beep()
|
||||||
@@ -315,6 +315,10 @@ class CraftBeerPI(object):
|
|||||||
def sleep(self, seconds):
|
def sleep(self, seconds):
|
||||||
self._socketio.sleep(seconds)
|
self._socketio.sleep(seconds)
|
||||||
|
|
||||||
|
def start_background_task(self, target, *args, **kwargs):
|
||||||
|
|
||||||
|
self._socketio.start_background_task(target, *args, **kwargs)
|
||||||
|
|
||||||
def notify(self, headline, message, type="success", timeout=5000):
|
def notify(self, headline, message, type="success", timeout=5000):
|
||||||
msg = {"id": str(uuid.uuid1()), "type": type, "headline": headline, "message": message, "timeout": timeout}
|
msg = {"id": str(uuid.uuid1()), "type": type, "headline": headline, "message": message, "timeout": timeout}
|
||||||
self.ws_emit("NOTIFY", msg)
|
self.ws_emit("NOTIFY", msg)
|
||||||
@@ -324,10 +328,10 @@ class CraftBeerPI(object):
|
|||||||
|
|
||||||
def __init_db(self, ):
|
def __init_db(self, ):
|
||||||
|
|
||||||
with self._app.app_context():
|
with self.web.app_context():
|
||||||
db = self.get_db()
|
db = self.get_db()
|
||||||
try:
|
try:
|
||||||
with self._app.open_resource('../../config/schema.sql', mode='r') as f:
|
with self.web.open_resource('../../config/schema.sql', mode='r') as f:
|
||||||
db.cursor().executescript(f.read())
|
db.cursor().executescript(f.read())
|
||||||
db.commit()
|
db.commit()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -373,7 +377,7 @@ class CraftBeerPI(object):
|
|||||||
|
|
||||||
def set_config_parameter(self, name, value):
|
def set_config_parameter(self, name, value):
|
||||||
from modules.config import Config
|
from modules.config import Config
|
||||||
with self._app.app_context():
|
with self.web.app_context():
|
||||||
update_data = {"name": name, "value": value}
|
update_data = {"name": name, "value": value}
|
||||||
self.cache.get("config")[name].__dict__.update(**update_data)
|
self.cache.get("config")[name].__dict__.update(**update_data)
|
||||||
c = Config.update(**update_data)
|
c = Config.update(**update_data)
|
||||||
@@ -381,7 +385,6 @@ class CraftBeerPI(object):
|
|||||||
|
|
||||||
|
|
||||||
def emit(self, key, **kwargs):
|
def emit(self, key, **kwargs):
|
||||||
|
|
||||||
if self.eventbus.get(key) is not None:
|
if self.eventbus.get(key) is not None:
|
||||||
for value in self.eventbus[key]:
|
for value in self.eventbus[key]:
|
||||||
if value["async"] is False:
|
if value["async"] is False:
|
||||||
@@ -400,6 +403,3 @@ class CraftBeerPI(object):
|
|||||||
|
|
||||||
self.notify("Failed to load plugin %s " % filename, str(e), type="danger", timeout=None)
|
self.notify("Failed to load plugin %s " % filename, str(e), type="danger", timeout=None)
|
||||||
|
|
||||||
|
|
||||||
cbpi = CraftBeerPI()
|
|
||||||
addon = cbpi.addon
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
import os
|
import os
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from modules.core.db import get_db
|
from modules.core.db import get_db
|
||||||
|
|
||||||
def execute_file(curernt_version, data):
|
def execute_file(curernt_version, data):
|
||||||
if curernt_version >= data["version"]:
|
if curernt_version >= data["version"]:
|
||||||
cbpi._app.logger.info("SKIP DB FILE: %s" % data["file"])
|
cbpi.web.logger.info("SKIP DB FILE: %s" % data["file"])
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
with sqlite3.connect("craftbeerpi.db") as conn:
|
with sqlite3.connect("craftbeerpi.db") as conn:
|
||||||
@@ -18,14 +18,13 @@ def execute_file(curernt_version, data):
|
|||||||
cur.execute("INSERT INTO schema_info (version,filename) values (?,?)", (data["version"], data["file"]))
|
cur.execute("INSERT INTO schema_info (version,filename) values (?,?)", (data["version"], data["file"]))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
except sqlite3.OperationalError as err:
|
except sqlite3.OperationalError as e:
|
||||||
|
cbpi.logger.error(e)
|
||||||
print err
|
|
||||||
|
|
||||||
@cbpi.addon.core.initializer(order=-9999)
|
@cbpi.addon.core.initializer(order=-9999)
|
||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
|
|
||||||
with cbpi._app.app_context():
|
with cbpi.web.app_context():
|
||||||
conn = get_db()
|
conn = get_db()
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
current_version = None
|
current_version = None
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class Property(object):
|
|||||||
self.configurable = configurable
|
self.configurable = configurable
|
||||||
self.default_value = default_value
|
self.default_value = default_value
|
||||||
self.description = description
|
self.description = description
|
||||||
|
self.unit = unit
|
||||||
|
|
||||||
class Text(PropertyType):
|
class Text(PropertyType):
|
||||||
def __init__(self, label, configurable=False, required=False, default_value="", description=""):
|
def __init__(self, label, configurable=False, required=False, default_value="", description=""):
|
||||||
@@ -44,5 +45,6 @@ class Property(object):
|
|||||||
def __init__(self, label, description=""):
|
def __init__(self, label, description=""):
|
||||||
PropertyType.__init__(self)
|
PropertyType.__init__(self)
|
||||||
self.label = label
|
self.label = label
|
||||||
|
self.unit = ""
|
||||||
self.configurable = True
|
self.configurable = True
|
||||||
self.description = description
|
self.description = description
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
|
|
||||||
from modules.core.core import cbpi, addon
|
from modules import cbpi
|
||||||
from flask_swagger import swagger
|
from flask_swagger import swagger
|
||||||
from flask import json
|
from flask import json
|
||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
|
|
||||||
@addon.core.initializer(order=22)
|
@cbpi.addon.core.initializer(order=22)
|
||||||
def web(cbpi):
|
def web(cbpi):
|
||||||
|
|
||||||
s = Blueprint('web_view', __name__, template_folder='templates', static_folder='static')
|
s = Blueprint('web_view', __name__, template_folder='templates', static_folder='static')
|
||||||
@@ -16,4 +16,4 @@ def web(cbpi):
|
|||||||
|
|
||||||
|
|
||||||
cbpi.addon.core.add_menu_link("JQuery View", "/web_view")
|
cbpi.addon.core.add_menu_link("JQuery View", "/web_view")
|
||||||
cbpi._app.register_blueprint(s, url_prefix='/web_view')
|
cbpi.web.register_blueprint(s, url_prefix='/web_view')
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
|
|
||||||
from modules.core.core import cbpi, addon
|
from modules import cbpi
|
||||||
from flask_swagger import swagger
|
from flask_swagger import swagger
|
||||||
from flask import json
|
from flask import json
|
||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
|
|
||||||
@addon.core.initializer(order=22)
|
@cbpi.addon.core.initializer(order=22)
|
||||||
def web(cbpi):
|
def web(cbpi):
|
||||||
|
|
||||||
s = Blueprint('webviewreact', __name__, template_folder='templates', static_folder='static')
|
s = Blueprint('webviewreact', __name__, template_folder='templates', static_folder='static')
|
||||||
@@ -16,4 +16,4 @@ def web(cbpi):
|
|||||||
|
|
||||||
|
|
||||||
cbpi.addon.core.add_menu_link("ReactJS View", "/webviewreact")
|
cbpi.addon.core.add_menu_link("ReactJS View", "/webviewreact")
|
||||||
cbpi._app.register_blueprint(s, url_prefix='/webviewreact')
|
cbpi.web.register_blueprint(s, url_prefix='/webviewreact')
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
from modules.core.core import cbpi, addon
|
from modules import cbpi
|
||||||
from flask_swagger import swagger
|
from flask_swagger import swagger
|
||||||
from flask import json
|
from flask import json
|
||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
|
|
||||||
@addon.core.initializer(order=22)
|
@cbpi.addon.core.initializer(order=22)
|
||||||
def hello(cbpi):
|
def hello(cbpi):
|
||||||
|
|
||||||
s = Blueprint('react', __name__, template_folder='templates', static_folder='static')
|
s = Blueprint('react', __name__, template_folder='templates', static_folder='static')
|
||||||
@@ -14,10 +14,10 @@ def hello(cbpi):
|
|||||||
|
|
||||||
@s.route('/swagger.json', methods=["GET"])
|
@s.route('/swagger.json', methods=["GET"])
|
||||||
def spec():
|
def spec():
|
||||||
swag = swagger(cbpi._app)
|
swag = swagger(cbpi.web)
|
||||||
swag['info']['version'] = "3.0"
|
swag['info']['version'] = "3.0"
|
||||||
swag['info']['title'] = "CraftBeerPi"
|
swag['info']['title'] = "CraftBeerPi"
|
||||||
return json.dumps(swag)
|
return json.dumps(swag)
|
||||||
|
|
||||||
cbpi.addon.core.add_menu_link("Swagger API", "/swagger")
|
cbpi.addon.core.add_menu_link("Swagger API", "/swagger")
|
||||||
cbpi._app.register_blueprint(s, url_prefix='/swagger')
|
cbpi.web.register_blueprint(s, url_prefix='/swagger')
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import time
|
|||||||
from flask import request
|
from flask import request
|
||||||
from flask_classy import route
|
from flask_classy import route
|
||||||
|
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from modules.core.db import get_db, DBModel
|
from modules.core.db import get_db, DBModel
|
||||||
from modules.core.baseview import BaseView
|
from modules.core.baseview import RestApi
|
||||||
from modules.database.dbmodel import Fermenter, FermenterStep
|
from modules.database.dbmodel import Fermenter, FermenterStep
|
||||||
|
|
||||||
|
|
||||||
class FermenterView(BaseView):
|
class FermenterView(RestApi):
|
||||||
model = Fermenter
|
model = Fermenter
|
||||||
cache_key = "fermenter"
|
cache_key = "fermenter"
|
||||||
|
|
||||||
@@ -212,10 +212,9 @@ class FermenterView(BaseView):
|
|||||||
cbpi.ws_emit("UPDATE_FERMENTER", cbpi.cache.get(self.cache_key)[id])
|
cbpi.ws_emit("UPDATE_FERMENTER", cbpi.cache.get(self.cache_key)[id])
|
||||||
|
|
||||||
def check_step(self):
|
def check_step(self):
|
||||||
print "CHECK STEP"
|
|
||||||
print cbpi.cache["fermenter_task"]
|
|
||||||
for key, value in cbpi.cache["fermenter_task"].iteritems():
|
for key, value in cbpi.cache["fermenter_task"].iteritems():
|
||||||
print value
|
|
||||||
try:
|
try:
|
||||||
fermenter = self.get_fermenter(key)
|
fermenter = self.get_fermenter(key)
|
||||||
current_temp = current_temp = cbpi.sensor.get_value(int(fermenter.sensor))
|
current_temp = current_temp = cbpi.sensor.get_value(int(fermenter.sensor))
|
||||||
@@ -236,11 +235,11 @@ class FermenterView(BaseView):
|
|||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print e
|
self.api.looger.error(e)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@cbpi.addon.core.backgroundjob(key="read_target_temps_fermenter", interval=5)
|
@cbpi.addon.core.backgroundtask(key="read_target_temps_fermenter", interval=5)
|
||||||
def read_target_temps(cbpi):
|
def read_target_temps(cbpi):
|
||||||
"""
|
"""
|
||||||
background process that reads all passive sensors in interval of 1 second
|
background process that reads all passive sensors in interval of 1 second
|
||||||
@@ -253,9 +252,9 @@ def read_target_temps(cbpi):
|
|||||||
|
|
||||||
instance = FermenterView()
|
instance = FermenterView()
|
||||||
|
|
||||||
@cbpi.addon.core.backgroundjob(key="fermentation_task", interval=1)
|
@cbpi.addon.core.backgroundtask(key="fermentation_task", interval=1)
|
||||||
def execute_fermentation_step(cbpi):
|
def execute_fermentation_step(cbpi):
|
||||||
with cbpi._app.app_context():
|
with cbpi.web.app_context():
|
||||||
instance.check_step()
|
instance.check_step()
|
||||||
|
|
||||||
|
|
||||||
@@ -268,5 +267,5 @@ def init_active_steps():
|
|||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
|
|
||||||
cbpi.cache["fermenter_task"] = {}
|
cbpi.cache["fermenter_task"] = {}
|
||||||
FermenterView.register(cbpi._app, route_base='/api/fermenter')
|
FermenterView.register(cbpi.web, route_base='/api/fermenter')
|
||||||
FermenterView.init_cache()
|
FermenterView.init_cache()
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
from flask import request
|
from flask import request
|
||||||
from flask_classy import FlaskView, route
|
from flask_classy import FlaskView, route
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from modules.core.baseview import BaseView
|
from modules.core.baseview import RestApi
|
||||||
from modules.core.db import DBModel
|
from modules.core.db import DBModel
|
||||||
from modules.database.dbmodel import Kettle
|
from modules.database.dbmodel import Kettle
|
||||||
|
|
||||||
class KettleView(BaseView):
|
class KettleView(RestApi):
|
||||||
model = Kettle
|
model = Kettle
|
||||||
cache_key = "kettle"
|
cache_key = "kettle"
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ def set_target_temp(id, temp):
|
|||||||
'''
|
'''
|
||||||
KettleView().postTargetTemp(id,temp)
|
KettleView().postTargetTemp(id,temp)
|
||||||
|
|
||||||
@cbpi.addon.core.backgroundjob(key="read_target_temps", interval=5)
|
@cbpi.addon.core.backgroundtask(key="read_target_temps", interval=5)
|
||||||
def read_target_temps(api):
|
def read_target_temps(api):
|
||||||
"""
|
"""
|
||||||
background process that reads all passive sensors in interval of 1 second
|
background process that reads all passive sensors in interval of 1 second
|
||||||
@@ -241,5 +241,5 @@ def read_target_temps(api):
|
|||||||
@cbpi.addon.core.initializer()
|
@cbpi.addon.core.initializer()
|
||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
KettleView.api = cbpi
|
KettleView.api = cbpi
|
||||||
KettleView.register(cbpi._app, route_base='/api/kettle')
|
KettleView.register(cbpi.web, route_base='/api/kettle')
|
||||||
KettleView.init_cache()
|
KettleView.init_cache()
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
import flask_login
|
import flask_login
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
from modules.core.core import cbpi, addon
|
from modules import cbpi
|
||||||
|
|
||||||
class User(flask_login.UserMixin):
|
class User(flask_login.UserMixin):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@addon.core.initializer(order=0)
|
@cbpi.addon.core.initializer(order=0)
|
||||||
def log(cbpi):
|
def log(cbpi):
|
||||||
|
|
||||||
|
|
||||||
cbpi._login_manager = flask_login.LoginManager()
|
cbpi._login_manager = flask_login.LoginManager()
|
||||||
cbpi._login_manager.init_app(cbpi._app)
|
cbpi._login_manager.init_app(cbpi.web)
|
||||||
@cbpi._app.route('/login', methods=['POST'])
|
|
||||||
|
@cbpi.web.route('/login', methods=['POST'])
|
||||||
def login():
|
def login():
|
||||||
|
|
||||||
data = request.json
|
data = request.json
|
||||||
@@ -30,16 +31,30 @@ def log(cbpi):
|
|||||||
return ('',401)
|
return ('',401)
|
||||||
|
|
||||||
|
|
||||||
@cbpi._app.route('/logout', methods=['POST'])
|
@cbpi.web.route('/logout', methods=['POST'])
|
||||||
def logout():
|
def logout():
|
||||||
flask_login.logout_user()
|
flask_login.logout_user()
|
||||||
return 'Logged out'
|
return 'Logged out'
|
||||||
|
|
||||||
|
@cbpi._login_manager.request_loader
|
||||||
|
def load_user_from_request(request):
|
||||||
|
|
||||||
|
|
||||||
|
api_key = request.args.get('api_key')
|
||||||
|
|
||||||
|
if cbpi.get_config_parameter("password_security", "NO") == "NO":
|
||||||
|
user = User()
|
||||||
|
user.id = "craftbeerpi"
|
||||||
|
return user
|
||||||
|
elif api_key == "123":
|
||||||
|
user = User()
|
||||||
|
user.id = "craftbeerpi"
|
||||||
|
return user
|
||||||
|
return None
|
||||||
|
|
||||||
@cbpi._login_manager.user_loader
|
@cbpi._login_manager.user_loader
|
||||||
def user_loader(user):
|
def user_loader(user):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if cbpi.get_config_parameter("password_security", "NO") == "YES":
|
if cbpi.get_config_parameter("password_security", "NO") == "YES":
|
||||||
if user != "craftbeerpi":
|
if user != "craftbeerpi":
|
||||||
return
|
return
|
||||||
@@ -53,4 +68,6 @@ def log(cbpi):
|
|||||||
|
|
||||||
@cbpi._login_manager.unauthorized_handler
|
@cbpi._login_manager.unauthorized_handler
|
||||||
def unauthorized_handler():
|
def unauthorized_handler():
|
||||||
|
|
||||||
|
|
||||||
return ('Please login',401)
|
return ('Please login',401)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import datetime
|
|||||||
import os
|
import os
|
||||||
from flask import Blueprint, request, send_from_directory, json
|
from flask import Blueprint, request, send_from_directory, json
|
||||||
from flask_classy import FlaskView, route
|
from flask_classy import FlaskView, route
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
|
|
||||||
|
|
||||||
class LogView(FlaskView):
|
class LogView(FlaskView):
|
||||||
@@ -172,4 +172,4 @@ def init(cbpi):
|
|||||||
:param app: the flask app
|
:param app: the flask app
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
LogView.register(cbpi._app, route_base='/api/logs')
|
LogView.register(cbpi.web, route_base='/api/logs')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
from flask_classy import FlaskView, route
|
from flask_classy import FlaskView, route
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
|
|
||||||
class NotificationView(FlaskView):
|
class NotificationView(FlaskView):
|
||||||
|
|
||||||
@@ -63,4 +63,4 @@ def init(cbpi):
|
|||||||
msg = {"id": len(cbpi.cache["messages"]), "type": "info", "headline": "Support CraftBeerPi with your donation", "message": "You will find the PayPay Donation button in the system menu" , "read": False}
|
msg = {"id": len(cbpi.cache["messages"]), "type": "info", "headline": "Support CraftBeerPi with your donation", "message": "You will find the PayPay Donation button in the system menu" , "read": False}
|
||||||
cbpi.cache["messages"].append(msg)
|
cbpi.cache["messages"].append(msg)
|
||||||
|
|
||||||
NotificationView.register(cbpi._app, route_base='/api/notification')
|
NotificationView.register(cbpi.web, route_base='/api/notification')
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import sys
|
import sys
|
||||||
from flask import request, send_from_directory, json
|
from flask import request, send_from_directory, json
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from git import Repo
|
from git import Repo
|
||||||
import os
|
import os
|
||||||
import requests
|
import requests
|
||||||
@@ -46,7 +46,7 @@ class PluginView(FlaskView):
|
|||||||
response = requests.get("https://raw.githubusercontent.com/Manuel83/craftbeerpi-plugins/master/plugins.yaml")
|
response = requests.get("https://raw.githubusercontent.com/Manuel83/craftbeerpi-plugins/master/plugins.yaml")
|
||||||
self.api.cache["plugins"] = self.merge(yaml.load(response.text), self.api.cache["plugins"])
|
self.api.cache["plugins"] = self.merge(yaml.load(response.text), self.api.cache["plugins"])
|
||||||
for key, value in cbpi.cache["plugins"].iteritems():
|
for key, value in cbpi.cache["plugins"].iteritems():
|
||||||
print key
|
|
||||||
value["installed"] = os.path.isdir("./plugins/%s/" % (key))
|
value["installed"] = os.path.isdir("./plugins/%s/" % (key))
|
||||||
return json.dumps(cbpi.cache["plugins"])
|
return json.dumps(cbpi.cache["plugins"])
|
||||||
|
|
||||||
@@ -136,4 +136,4 @@ class PluginView(FlaskView):
|
|||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
cbpi.cache["plugins"] = {}
|
cbpi.cache["plugins"] = {}
|
||||||
PluginView.api = cbpi
|
PluginView.api = cbpi
|
||||||
PluginView.register(cbpi._app, route_base='/api/plugin')
|
PluginView.register(cbpi.web, route_base='/api/plugin')
|
||||||
@@ -7,8 +7,8 @@ from flask import json, request, send_from_directory
|
|||||||
from flask_classy import route, FlaskView
|
from flask_classy import route, FlaskView
|
||||||
|
|
||||||
from modules.core.db import DBModel
|
from modules.core.db import DBModel
|
||||||
from modules.core.baseview import BaseView
|
from modules.core.baseview import RestApi
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from modules.database.dbmodel import Step
|
from modules.database.dbmodel import Step
|
||||||
from yaml import Loader, Dumper
|
from yaml import Loader, Dumper
|
||||||
from yaml import load, dump
|
from yaml import load, dump
|
||||||
@@ -59,7 +59,7 @@ class RecipeBook(FlaskView):
|
|||||||
description: Log file downloaded
|
description: Log file downloaded
|
||||||
"""
|
"""
|
||||||
file = "%s.json" % name
|
file = "%s.json" % name
|
||||||
print file
|
|
||||||
if not self.check_filename(file):
|
if not self.check_filename(file):
|
||||||
return ('File Not Found111', 404)
|
return ('File Not Found111', 404)
|
||||||
return send_from_directory('../../recipes', file, as_attachment=True, attachment_filename=file)
|
return send_from_directory('../../recipes', file, as_attachment=True, attachment_filename=file)
|
||||||
@@ -143,4 +143,4 @@ class RecipeBook(FlaskView):
|
|||||||
@cbpi.addon.core.initializer(order=2000)
|
@cbpi.addon.core.initializer(order=2000)
|
||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
RecipeBook.api = cbpi
|
RecipeBook.api = cbpi
|
||||||
RecipeBook.register(cbpi._app, route_base='/api/recipebook')
|
RecipeBook.register(cbpi.web, route_base='/api/recipebook')
|
||||||
@@ -2,7 +2,7 @@ from flask import json, request
|
|||||||
from flask_classy import FlaskView, route
|
from flask_classy import FlaskView, route
|
||||||
from git import Repo, Git
|
from git import Repo, Git
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
import pprint
|
import pprint
|
||||||
import time
|
import time
|
||||||
@@ -60,7 +60,7 @@ class BeerXMLImport(FlaskView):
|
|||||||
return ('', 204)
|
return ('', 204)
|
||||||
return ('', 404)
|
return ('', 404)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print e
|
self.api.logger.error(e)
|
||||||
self.api.notify(headline="Upload Failed", message="Failed to upload Beer xml", type="danger")
|
self.api.notify(headline="Upload Failed", message="Failed to upload Beer xml", type="danger")
|
||||||
return ('', 500)
|
return ('', 500)
|
||||||
|
|
||||||
@@ -143,4 +143,4 @@ class BeerXMLImport(FlaskView):
|
|||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
|
|
||||||
BeerXMLImport.api = cbpi
|
BeerXMLImport.api = cbpi
|
||||||
BeerXMLImport.register(cbpi._app, route_base='/api/beerxml')
|
BeerXMLImport.register(cbpi.web, route_base='/api/beerxml')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from flask import json, request
|
|||||||
from flask_classy import FlaskView, route
|
from flask_classy import FlaskView, route
|
||||||
from git import Repo, Git
|
from git import Repo, Git
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
import pprint
|
import pprint
|
||||||
import time
|
import time
|
||||||
@@ -39,7 +39,7 @@ class KBH(FlaskView):
|
|||||||
result.append({"id": row[0], "name": row[1], "brewed": row[2]})
|
result.append({"id": row[0], "name": row[1], "brewed": row[2]})
|
||||||
return json.dumps(result)
|
return json.dumps(result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print e
|
self.api.logger.error(e)
|
||||||
self.api.notify(headline="Failed to load KHB database", message="ERROR", type="danger")
|
self.api.notify(headline="Failed to load KHB database", message="ERROR", type="danger")
|
||||||
return ('', 500)
|
return ('', 500)
|
||||||
finally:
|
finally:
|
||||||
@@ -143,4 +143,4 @@ class KBH(FlaskView):
|
|||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
|
|
||||||
KBH.api = cbpi
|
KBH.api = cbpi
|
||||||
KBH.register(cbpi._app, route_base='/api/kbh')
|
KBH.register(cbpi.web, route_base='/api/kbh')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from flask import json, request
|
|||||||
from flask_classy import FlaskView, route
|
from flask_classy import FlaskView, route
|
||||||
from git import Repo, Git
|
from git import Repo, Git
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
import pprint
|
import pprint
|
||||||
import time
|
import time
|
||||||
@@ -59,4 +59,4 @@ class RESTImport(FlaskView):
|
|||||||
@cbpi.addon.core.initializer()
|
@cbpi.addon.core.initializer()
|
||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
RESTImport.api = cbpi
|
RESTImport.api = cbpi
|
||||||
RESTImport.register(cbpi._app, route_base='/api/recipe/import/v1')
|
RESTImport.register(cbpi.web, route_base='/api/recipe/import/v1')
|
||||||
|
|||||||
+16
-10
@@ -1,12 +1,12 @@
|
|||||||
import time
|
import time
|
||||||
from flask_classy import route
|
from flask_classy import route
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from modules.core.db import DBModel
|
from modules.core.db import DBModel
|
||||||
from modules.core.baseview import BaseView
|
from modules.core.baseview import RestApi
|
||||||
from modules.database.dbmodel import Sensor
|
from modules.database.dbmodel import Sensor
|
||||||
|
from flask import request
|
||||||
|
|
||||||
|
class SensorView(RestApi):
|
||||||
class SensorView(BaseView):
|
|
||||||
model = Sensor
|
model = Sensor
|
||||||
cache_key = "sensors"
|
cache_key = "sensors"
|
||||||
|
|
||||||
@@ -34,7 +34,11 @@ class SensorView(BaseView):
|
|||||||
200:
|
200:
|
||||||
description: Sensor Action called
|
description: Sensor Action called
|
||||||
"""
|
"""
|
||||||
cbpi.sensor.action(id, method)
|
data = request.json
|
||||||
|
if data:
|
||||||
|
cbpi.sensor.action(id, method, **data)
|
||||||
|
else:
|
||||||
|
cbpi.sensor.action(id, method)
|
||||||
return ('', 204)
|
return ('', 204)
|
||||||
|
|
||||||
def _post_post_callback(self, m):
|
def _post_post_callback(self, m):
|
||||||
@@ -51,17 +55,19 @@ class SensorView(BaseView):
|
|||||||
@cbpi.addon.core.initializer(order=1000)
|
@cbpi.addon.core.initializer(order=1000)
|
||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
|
|
||||||
SensorView.register(cbpi._app, route_base='/api/sensor')
|
SensorView.register(cbpi.web, route_base='/api/sensor')
|
||||||
SensorView.init_cache()
|
SensorView.init_cache()
|
||||||
|
|
||||||
|
|
||||||
#@cbpi.backgroundtask(key="read_passiv_sensor", interval=5)
|
#@cbpi.addon.core.backgroundtask(key="read_passiv_sensor", interval=5)
|
||||||
def read_passive_sensor(api):
|
def read_passive_sensor(api):
|
||||||
"""
|
"""
|
||||||
background process that reads all passive sensors in interval of 1 second
|
background process that reads all passive sensors in interval of 1 second
|
||||||
:return: None
|
:return: None
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for key, value in cbpi.cache.get("sensors").iteritems():
|
|
||||||
if value.mode == "P":
|
|
||||||
value.instance.read()
|
#for key, value in cbpi.cache.get("sensors").iteritems():
|
||||||
|
# if value.mode == "P":
|
||||||
|
# value.instance.read()
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ from flask import json, request
|
|||||||
from flask_classy import route
|
from flask_classy import route
|
||||||
|
|
||||||
from modules.core.db import DBModel
|
from modules.core.db import DBModel
|
||||||
from modules.core.baseview import BaseView
|
from modules.core.baseview import RestApi
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
from modules.database.dbmodel import Step
|
from modules.database.dbmodel import Step
|
||||||
|
|
||||||
|
|
||||||
class StepView(BaseView):
|
class StepView(RestApi):
|
||||||
model = Step
|
model = Step
|
||||||
def _pre_post_callback(self, data):
|
def _pre_post_callback(self, data):
|
||||||
order = self.model.get_max_order()
|
order = self.model.get_max_order()
|
||||||
@@ -207,24 +207,25 @@ def init_after_startup():
|
|||||||
@cbpi.addon.core.initializer(order=2000)
|
@cbpi.addon.core.initializer(order=2000)
|
||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
|
|
||||||
StepView.register(cbpi._app, route_base='/api/step')
|
StepView.register(cbpi.web, route_base='/api/step')
|
||||||
|
|
||||||
def get_all():
|
def get_all():
|
||||||
with cbpi._app.app_context():
|
with cbpi.web.app_context():
|
||||||
return Step.get_all()
|
return Step.get_all()
|
||||||
|
|
||||||
with cbpi._app.app_context():
|
with cbpi.web.app_context():
|
||||||
init_after_startup()
|
init_after_startup()
|
||||||
|
|
||||||
cbpi.add_cache_callback("steps", get_all)
|
cbpi.add_cache_callback("steps", get_all)
|
||||||
|
|
||||||
@cbpi.addon.core.backgroundjob(key="step_task", interval=0.1)
|
@cbpi.addon.core.backgroundtask(key="step_task", interval=0.1)
|
||||||
def execute_step(api):
|
def execute_step(api):
|
||||||
'''
|
'''
|
||||||
Background job which executes the step
|
Background job which executes the step
|
||||||
:return:
|
:return:
|
||||||
'''
|
'''
|
||||||
with cbpi._app.app_context():
|
with cbpi.web.app_context():
|
||||||
|
|
||||||
step = cbpi.cache.get("active_step")
|
step = cbpi.cache.get("active_step")
|
||||||
if step is not None:
|
if step is not None:
|
||||||
step.execute()
|
step.execute()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from flask import json, url_for, Response, request
|
|||||||
from flask_classy import FlaskView, route
|
from flask_classy import FlaskView, route
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from git import Repo, Git
|
from git import Repo, Git
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
import pprint
|
import pprint
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@@ -190,4 +190,4 @@ class SystemView(FlaskView):
|
|||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
|
|
||||||
SystemView.api = cbpi
|
SystemView.api = cbpi
|
||||||
SystemView.register(cbpi._app, route_base='/api/system')
|
SystemView.register(cbpi.web, route_base='/api/system')
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
from flask import Blueprint,render_template
|
from flask import Blueprint,render_template
|
||||||
|
|
||||||
from modules.core.core import cbpi
|
from modules import cbpi
|
||||||
|
|
||||||
react = Blueprint('ui', __name__, template_folder='templates', static_folder='static')
|
react = Blueprint('ui', __name__, template_folder='templates', static_folder='static')
|
||||||
|
|
||||||
@cbpi.addon.core.initializer(order=10)
|
@cbpi.addon.core.initializer(order=10)
|
||||||
def init(cbpi):
|
def init(cbpi):
|
||||||
cbpi._app.register_blueprint(react, url_prefix='/ui')
|
cbpi.web.register_blueprint(react, url_prefix='/ui')
|
||||||
|
|
||||||
|
|
||||||
@react.route('/', methods=["GET"])
|
@react.route('/', methods=["GET"])
|
||||||
@@ -22,7 +22,7 @@ def index():
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
@cbpi._app.errorhandler(404)
|
@cbpi.web.errorhandler(404)
|
||||||
def page_not_found(e):
|
def page_not_found(e):
|
||||||
return render_template('404.html'), 404
|
return render_template('404.html'), 404
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 149 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 941 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 313 KiB |
Vendored
+7713
-2
File diff suppressed because one or more lines are too long
+37
-36
File diff suppressed because one or more lines are too long
@@ -10,11 +10,17 @@
|
|||||||
<link rel="stylesheet" href="static/bootstrap.dark.css">
|
<link rel="stylesheet" href="static/bootstrap.dark.css">
|
||||||
|
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
html {
|
||||||
|
background-image: url('static/bg.png');
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<title>CraftBeerPi 3.0</title>
|
<title>CraftBeerPi 3.0</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root" ></div>
|
<div id="root" ></div>
|
||||||
|
HALLO
|
||||||
<script src="static/bundle.js" type="text/javascript"></script>
|
<script src="static/bundle.js" type="text/javascript"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,18 +7,13 @@
|
|||||||
|
|
||||||
<link rel="stylesheet" href="static/bootstrap.min.css">
|
<link rel="stylesheet" href="static/bootstrap.min.css">
|
||||||
<link rel="stylesheet" href="static/css/font-awesome.min.css">
|
<link rel="stylesheet" href="static/css/font-awesome.min.css">
|
||||||
<link rel="stylesheet" href="static/bootstrap.dark.css">
|
<link rel="stylesheet" href="static/theme.css">
|
||||||
<link href="https://fonts.googleapis.com/css?family=Dosis:200,500" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css?family=Dosis:200,500" rel="stylesheet"/>
|
||||||
<style>
|
|
||||||
|
|
||||||
body, h1, h2, h3, h4, h5, h6 {
|
|
||||||
font-family: 'Dosis', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
<title>CraftBeerPi 3.1</title>
|
<title>CraftBeerPi 3.1</title>
|
||||||
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root" ></div>
|
<div id="root" ></div>
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
import re
|
|
||||||
|
|
||||||
recipe_name = "Manuel 8881881 18181 "
|
|
||||||
print re.match("^[\sA-Za-z0-9_-]*$", recipe_name)
|
|
||||||
Reference in New Issue
Block a user