| @@ -3,7 +3,7 @@ import pprint | |||||
| import sys, os | import sys, os | ||||
| from flask import Flask, render_template, redirect | from flask import Flask, render_template, redirect | ||||
| from flask_socketio import SocketIO, emit | from flask_socketio import SocketIO, emit | ||||
| from flask_sqlalchemy import SQLAlchemy | |||||
| import logging | import logging | ||||
| # Define the WSGI application object | # Define the WSGI application object | ||||
| @@ -5,10 +5,10 @@ from flask import Flask, render_template, redirect, json, g | |||||
| from flask_socketio import SocketIO, emit | from flask_socketio import SocketIO, emit | ||||
| from flask_sqlalchemy import SQLAlchemy | |||||
| import logging | import logging | ||||
| from sqlalchemy.ext.declarative import DeclarativeMeta | |||||
| from modules.core.core import CraftBeerPi, ActorBase, SensorBase | from modules.core.core import CraftBeerPi, ActorBase, SensorBase | ||||
| from modules.core.db import DBModel | from modules.core.db import DBModel | ||||
| @@ -16,13 +16,9 @@ from modules.core.db import DBModel | |||||
| app = Flask(__name__) | app = Flask(__name__) | ||||
| logging.basicConfig(filename='./logs/app.log',level=logging.INFO) | logging.basicConfig(filename='./logs/app.log',level=logging.INFO) | ||||
| app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///../craftbeerpi.db' | |||||
| #app.config['SQLALCHEMY_ECHO'] = False | |||||
| app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False | |||||
| app.config['SECRET_KEY'] = 'craftbeerpi' | app.config['SECRET_KEY'] = 'craftbeerpi' | ||||
| app.config['UPLOAD_FOLDER'] = './upload' | app.config['UPLOAD_FOLDER'] = './upload' | ||||
| db = SQLAlchemy(app) | |||||
| @app.teardown_appcontext | @app.teardown_appcontext | ||||
| def close_connection(exception): | def close_connection(exception): | ||||
| @@ -6,22 +6,33 @@ from modules.core.props import Property | |||||
| @cbpi.fermentation_controller | @cbpi.fermentation_controller | ||||
| class Hysteresis(FermenterController): | class Hysteresis(FermenterController): | ||||
| on = Property.Number("Offset On", True, 0) | |||||
| off = Property.Number("Offset Off", True, 0) | |||||
| heater_offset_min = Property.Number("Heater Offset min", True, 0) | |||||
| heater_offset_max = Property.Number("Heater Offset max", True, 0) | |||||
| cooler_offset_min = Property.Number("Cooler Offset min", True, 0) | |||||
| cooler_offset_max = Property.Number("Cooler Offset max", True, 0) | |||||
| def stop(self): | def stop(self): | ||||
| super(FermenterController, self).stop() | super(FermenterController, self).stop() | ||||
| self.heater_off() | self.heater_off() | ||||
| self.cooler_off() | |||||
| def run(self): | def run(self): | ||||
| while self.is_running(): | while self.is_running(): | ||||
| print "Temp %s" % self.get_temp() | |||||
| if self.get_temp() < self.get_target_temp() - int(self.on): | |||||
| target_temp = self.get_target_temp() | |||||
| temp = self.get_temp() | |||||
| if temp + int(self.heater_offset_min) < target_temp: | |||||
| self.heater_on(100) | self.heater_on(100) | ||||
| elif self.get_temp() >= self.get_target_temp() - int(self.off): | |||||
| self.heater_off() | |||||
| else: | |||||
| if temp + int(self.heater_offset_max) > target_temp: | |||||
| self.heater_off() | self.heater_off() | ||||
| self.sleep(1) | |||||
| if temp > target_temp + int(self.cooler_offset_min): | |||||
| self.cooler_on(100) | |||||
| if temp < target_temp + int(self.cooler_offset_max): | |||||
| self.cooler_off() | |||||
| self.sleep(1) | |||||
| @@ -106,9 +106,10 @@ class FermenterController(ControllerBase, ActorController, SensorController): | |||||
| self.fermenter_id = kwds.get("fermenter_id") | self.fermenter_id = kwds.get("fermenter_id") | ||||
| self.cooler = kwds.get("cooler") | self.cooler = kwds.get("cooler") | ||||
| @cbpi.try_catch(None) | @cbpi.try_catch(None) | ||||
| def get_target_temp(self, id=None): | def get_target_temp(self, id=None): | ||||
| if id is None: | if id is None: | ||||
| id = self.fermenter_id | id = self.fermenter_id | ||||
| return self.api.cache.get("fermenter").get(id).target_temp | return self.api.cache.get("fermenter").get(id).target_temp | ||||
| @@ -116,15 +117,27 @@ class FermenterController(ControllerBase, ActorController, SensorController): | |||||
| @cbpi.try_catch(None) | @cbpi.try_catch(None) | ||||
| def heater_on(self, power=100): | def heater_on(self, power=100): | ||||
| f = self.api.cache.get("fermenter").get(self.fermenter_id) | f = self.api.cache.get("fermenter").get(self.fermenter_id) | ||||
| if k.heater is not None: | |||||
| self.actor_on(int(f.heater)) | |||||
| if f.heater is not None: | |||||
| self.actor_on(power, int(f.heater)) | |||||
| @cbpi.try_catch(None) | @cbpi.try_catch(None) | ||||
| def heater_off(self): | def heater_off(self): | ||||
| f = self.api.cache.get("fermenter").get(self.fermenter_id) | f = self.api.cache.get("fermenter").get(self.fermenter_id) | ||||
| if k.heater is not None: | |||||
| if f.heater is not None: | |||||
| self.actor_off(int(f.heater)) | self.actor_off(int(f.heater)) | ||||
| @cbpi.try_catch(None) | |||||
| def cooler_on(self, power=100): | |||||
| f = self.api.cache.get("fermenter").get(self.fermenter_id) | |||||
| if f.heater is not None: | |||||
| self.actor_on(power, int(f.cooler)) | |||||
| @cbpi.try_catch(None) | |||||
| def cooler_off(self): | |||||
| f = self.api.cache.get("fermenter").get(self.fermenter_id) | |||||
| if f.heater is not None: | |||||
| self.actor_off(int(f.cooler)) | |||||
| @cbpi.try_catch(None) | @cbpi.try_catch(None) | ||||
| def get_temp(self, id=None): | def get_temp(self, id=None): | ||||
| @@ -6,7 +6,7 @@ import datetime | |||||
| from datetime import datetime | from datetime import datetime | ||||
| from flask.views import MethodView | from flask.views import MethodView | ||||
| from flask_classy import FlaskView, route | from flask_classy import FlaskView, route | ||||
| from flask_sqlalchemy import SQLAlchemy | |||||
| from time import localtime, strftime | from time import localtime, strftime | ||||
| from functools import wraps, update_wrapper | from functools import wraps, update_wrapper | ||||
| from props import * | from props import * | ||||
| @@ -67,6 +67,15 @@ class FermenterView(BaseView): | |||||
| m.state = False | m.state = False | ||||
| m.steps = [] | m.steps = [] | ||||
| def pre_put_callback(self, m): | |||||
| m.state = False | |||||
| try: | |||||
| m.instance.stop() | |||||
| except: | |||||
| pass | |||||
| def post_put_callback(self, m): | |||||
| m.state = False | |||||
| @route('/<int:id>/targettemp/<temp>', methods=['POST']) | @route('/<int:id>/targettemp/<temp>', methods=['POST']) | ||||
| def postTargetTemp(self, id, temp): | def postTargetTemp(self, id, temp): | ||||
| @@ -199,7 +208,7 @@ class FermenterView(BaseView): | |||||
| def toggle(self, id): | def toggle(self, id): | ||||
| fermenter = cbpi.cache.get(self.cache_key)[id] | fermenter = cbpi.cache.get(self.cache_key)[id] | ||||
| try: | try: | ||||
| print fermenter.state | |||||
| if fermenter.state is False: | if fermenter.state is False: | ||||
| # Start controller | # Start controller | ||||
| if fermenter.logic is not None: | if fermenter.logic is not None: | ||||
| @@ -208,7 +217,7 @@ class FermenterView(BaseView): | |||||
| dict(api=cbpi, fermenter_id=fermenter.id, heater=fermenter.heater, sensor=fermenter.sensor)) | dict(api=cbpi, fermenter_id=fermenter.id, heater=fermenter.heater, sensor=fermenter.sensor)) | ||||
| instance = cbpi.get_fermentation_controller(fermenter.logic).get("class")(**cfg) | instance = cbpi.get_fermentation_controller(fermenter.logic).get("class")(**cfg) | ||||
| instance.init() | instance.init() | ||||
| fermenter.controller_instance = instance | |||||
| fermenter.instance = instance | |||||
| def run(instance): | def run(instance): | ||||
| instance.run() | instance.run() | ||||
| @@ -218,12 +227,12 @@ class FermenterView(BaseView): | |||||
| cbpi.emit("UPDATE_FERMENTER", cbpi.cache.get(self.cache_key).get(id)) | cbpi.emit("UPDATE_FERMENTER", cbpi.cache.get(self.cache_key).get(id)) | ||||
| else: | else: | ||||
| # Stop controller | # Stop controller | ||||
| fermenter.controller_instance.stop() | |||||
| fermenter.instance.stop() | |||||
| fermenter.state = not fermenter.state | fermenter.state = not fermenter.state | ||||
| cbpi.emit("UPDATE_FERMENTER", cbpi.cache.get(self.cache_key).get(id)) | cbpi.emit("UPDATE_FERMENTER", cbpi.cache.get(self.cache_key).get(id)) | ||||
| except Exception as e: | except Exception as e: | ||||
| print e | |||||
| cbpi.notify("Toogle Fementer Controller failed", "Pleae check the %s configuration" % fermenter.name, | cbpi.notify("Toogle Fementer Controller failed", "Pleae check the %s configuration" % fermenter.name, | ||||
| type="danger", timeout=None) | type="danger", timeout=None) | ||||
| return ('', 500) | return ('', 500) | ||||
| @@ -26,6 +26,14 @@ class Kettle2View(BaseView): | |||||
| def post_post_callback(self, m): | def post_post_callback(self, m): | ||||
| m.state = False | m.state = False | ||||
| def pre_put_callback(self, m): | |||||
| try: | |||||
| m.instance.stop() | |||||
| except: | |||||
| pass | |||||
| def post_put_callback(self, m): | |||||
| m.state = False | |||||
| @route('/<int:id>/targettemp/<temp>', methods=['POST']) | @route('/<int:id>/targettemp/<temp>', methods=['POST']) | ||||
| def postTargetTemp(self, id, temp): | def postTargetTemp(self, id, temp): | ||||
| @@ -47,7 +55,7 @@ class Kettle2View(BaseView): | |||||
| cfg.update(dict(api=cbpi, kettle_id=kettle.id, heater=kettle.heater, sensor=kettle.sensor)) | cfg.update(dict(api=cbpi, kettle_id=kettle.id, heater=kettle.heater, sensor=kettle.sensor)) | ||||
| instance = cbpi.get_controller(kettle.logic).get("class")(**cfg) | instance = cbpi.get_controller(kettle.logic).get("class")(**cfg) | ||||
| instance.init() | instance.init() | ||||
| kettle.controller_instance = instance | |||||
| kettle.instance = instance | |||||
| def run(instance): | def run(instance): | ||||
| instance.run() | instance.run() | ||||
| t = self.api.socketio.start_background_task(target=run, instance=instance) | t = self.api.socketio.start_background_task(target=run, instance=instance) | ||||
| @@ -55,7 +63,7 @@ class Kettle2View(BaseView): | |||||
| cbpi.emit("UPDATE_KETTLE", cbpi.cache.get("kettle").get(id)) | cbpi.emit("UPDATE_KETTLE", cbpi.cache.get("kettle").get(id)) | ||||
| else: | else: | ||||
| # Stop controller | # Stop controller | ||||
| kettle.controller_instance.stop() | |||||
| kettle.instance.stop() | |||||
| kettle.state = not kettle.state | kettle.state = not kettle.state | ||||
| cbpi.emit("UPDATE_KETTLE", cbpi.cache.get("kettle").get(id)) | cbpi.emit("UPDATE_KETTLE", cbpi.cache.get("kettle").get(id)) | ||||
| return ('', 204) | return ('', 204) | ||||