| @@ -0,0 +1 @@ | |||
| modules/ui/static/** | |||
| @@ -0,0 +1,13 @@ | |||
| language: python | |||
| python: | |||
| - "2.7" | |||
| #before_install: | |||
| # - pip install pytest pytest-cov | |||
| # command to install dependencies | |||
| install: | |||
| - pip install -r requirements.txt | |||
| script: | |||
| - py.test | |||
| @@ -1,3 +1,11 @@ | |||
| [](https://travis-ci.org/isarvalley/craftbeerpi3) | |||
| [](https://codebeat.co/projects/github-com-isarvalley-craftbeerpi3-core_refactoring) | |||
| [](https://www.codacy.com/app/isar_valley/craftbeerpi3?utm_source=github.com&utm_medium=referral&utm_content=isarvalley/craftbeerpi3&utm_campaign=Badge_Grade) | |||
| [](https://bettercodehub.com/) | |||
| # CraftBeerPi V3.0 | |||
| This is CraftBeerPi version 3.0. It's currently in beta status. | |||
| @@ -0,0 +1,19 @@ | |||
| version: 1 | |||
| formatters: | |||
| simple: | |||
| format: '%(asctime)s - %(levelname)-8s - %(name)s - %(message)s' | |||
| handlers: | |||
| console: | |||
| class: logging.StreamHandler | |||
| level: DEBUG | |||
| formatter: simple | |||
| stream: ext://sys.stdout | |||
| file: | |||
| class : logging.handlers.RotatingFileHandler | |||
| formatter: simple | |||
| filename: ./logs/app.log | |||
| maxBytes: 10000000 | |||
| backupCount: 3 | |||
| root: | |||
| level: DEBUG | |||
| handlers: [console, file] | |||
| @@ -1,8 +1,12 @@ | |||
| import json | |||
| import logging | |||
| from flask_classy import FlaskView, route | |||
| from modules.core.core import cbpi | |||
| class ActionView(FlaskView): | |||
| def __init__(self): | |||
| self.logger = logging.getLogger(__name__) | |||
| @route('/<action>', methods=['POST']) | |||
| def action(self, action): | |||
| @@ -1,10 +1,13 @@ | |||
| import logging | |||
| from modules.core.baseapi import Buzzer | |||
| from modules.core.basetypes import Actor, KettleController, FermenterController | |||
| from modules.core.core import cbpi | |||
| @cbpi.addon.actor.type("Dummy Actor") | |||
| class Dummy(Actor): | |||
| def __init__(self): | |||
| self.logger = logging.getLogger(__name__) | |||
| @cbpi.addon.actor.action("WOHOO") | |||
| def myaction(self): | |||
| @@ -16,10 +19,10 @@ class Dummy(Actor): | |||
| :param power: int value between 0 - 100 | |||
| :return: | |||
| ''' | |||
| print "ON" | |||
| self.logger.info("ON") | |||
| def off(self): | |||
| print "OFF" | |||
| self.logger.info("OFF") | |||
| @@ -33,11 +36,12 @@ class MyController(KettleController): | |||
| @cbpi.addon.fermenter.controller() | |||
| class MyController2(FermenterController): | |||
| def __init__(self): | |||
| self.logger = logging.getLogger(__name__) | |||
| def run(self): | |||
| while self.is_running(): | |||
| print "HALLO" | |||
| self.logger.debug("HALLO") | |||
| self.sleep(1) | |||
| @cbpi.addon.core.initializer(order=200) | |||
| @@ -3,10 +3,12 @@ import os | |||
| from os.path import join | |||
| from modules.core.basetypes import Actor, Sensor | |||
| from modules.core.basetypes import Sensor | |||
| from modules.core.core import cbpi | |||
| from modules.core.proptypes import Property | |||
| import random | |||
| import logging | |||
| @cbpi.addon.sensor.type("Dummy Sensor") | |||
| class Dummy(Sensor): | |||
| @@ -14,6 +16,10 @@ class Dummy(Sensor): | |||
| text = Property.Text(label="Text", required=True, description="This is a parameter", configurable=True) | |||
| p = Property.Select(label="hallo",options=[1,2,3]) | |||
| def __init__(self): | |||
| self.logger = logging.getLogger(__name__) | |||
| self.logger.info("INIT SENSOR") | |||
| def init(self): | |||
| if self.api.get_config_parameter("unit","C") == "C": | |||
| @@ -23,8 +29,7 @@ class Dummy(Sensor): | |||
| @cbpi.addon.sensor.action("WOHOO") | |||
| def myaction(self): | |||
| print "SENSOR ACTION HALLO!!!" | |||
| self.logger.debug("SENSOR ACTION HALLO!!!") | |||
| def execute(self): | |||
| while True: | |||
| @@ -1,3 +1,5 @@ | |||
| import logging | |||
| from proptypes import * | |||
| class BaseAPI(object): | |||
| @@ -148,6 +150,8 @@ class CoreAPI(BaseAPI): | |||
| key = "core" | |||
| def __init__(self, cbpi): | |||
| self.logger = logging.getLogger(__name__) | |||
| self.cbpi = cbpi | |||
| self.cbpi.cache["actions"] = {} | |||
| self.cbpi.cache["init"] = [] | |||
| @@ -168,7 +172,7 @@ class CoreAPI(BaseAPI): | |||
| try: | |||
| method(self.cbpi) | |||
| except Exception as e: | |||
| print e | |||
| self.logger.debug(e) | |||
| self.cbpi._socketio.sleep(interval) | |||
| for value in self.cbpi.cache.get("background"): | |||
| @@ -220,5 +224,5 @@ class CoreAPI(BaseAPI): | |||
| class Buzzer(object): | |||
| def beep(): | |||
| def beep(self): | |||
| pass | |||
| @@ -1,3 +1,5 @@ | |||
| import logging | |||
| from modules.core.proptypes import Property | |||
| import time | |||
| @@ -12,7 +14,9 @@ class Base(object): | |||
| self.value = None | |||
| self.__dirty = False | |||
| class Actor(Base): | |||
| __logger = logging.getLogger(__name__) | |||
| @classmethod | |||
| def init_global(cls): | |||
| @@ -26,15 +30,15 @@ class Actor(Base): | |||
| pass | |||
| def on(self, power=100): | |||
| print "SWITCH ON" | |||
| self._logger.info("SWITCH ON") | |||
| pass | |||
| def off(self): | |||
| print "SWITCH OFF" | |||
| self._logger.info("SWITCH OFF") | |||
| pass | |||
| def power(self, power): | |||
| print "SET POWER", power | |||
| self._logger.info("SET POWER TO [%s]", power) | |||
| pass | |||
| def state(self): | |||
| @@ -42,6 +46,7 @@ class Actor(Base): | |||
| class Sensor(Base): | |||
| __logger = logging.getLogger(__name__) | |||
| unit = "" | |||
| @@ -60,12 +65,13 @@ class Sensor(Base): | |||
| def update_value(self, value): | |||
| self.value = value | |||
| self.__logger.info("Updated value for sensor [%s] with value [%s].", self.id, value) | |||
| self.cbpi.sensor.write_log(self.id, value) | |||
| self.cbpi.emit("SENSOR_UPDATE", id=self.id, value=value) | |||
| self.cbpi.ws_emit("SENSOR_UPDATE", self.cbpi.cache["sensors"][self.id]) | |||
| def execute(self): | |||
| print "EXECUTE" | |||
| self.__logger.info("EXECUTE") | |||
| pass | |||
| @@ -75,9 +81,11 @@ class ControllerBase(object): | |||
| __dirty = False | |||
| __running = False | |||
| __logger = logging.getLogger(__name__) | |||
| @staticmethod | |||
| def init_global(): | |||
| print "GLOBAL CONTROLLER INIT" | |||
| ControllerBase.__logger.info("GLOBAL CONTROLLER INIT") | |||
| def notify(self, headline, message, type="success", timeout=5000): | |||
| self.api.notify(headline, message, type, timeout) | |||
| @@ -251,12 +259,13 @@ class Step(Base, Timer): | |||
| pass | |||
| def execute(self): | |||
| print "Step Info" | |||
| print "Kettle ID: %s" % self.kettle_id | |||
| print "ID: %s" % self.id | |||
| self.logger.info("-------------") | |||
| self.logger.info("Step Info") | |||
| self.logger.info("Kettle ID: %s" % self.kettle_id) | |||
| self.logger.info("ID: %s" % self.id) | |||
| def __init__(self, *args, **kwds): | |||
| self.logger = logging.getLogger(__name__) | |||
| for a in kwds: | |||
| super(Step, self).__setattr__(a, kwds.get(a)) | |||
| @@ -1,13 +1,16 @@ | |||
| import json | |||
| import logging | |||
| import logging.config | |||
| import os | |||
| import sqlite3 | |||
| import uuid | |||
| import yaml | |||
| from datetime import datetime | |||
| from functools import wraps, update_wrapper | |||
| from importlib import import_module | |||
| from time import localtime, strftime | |||
| import time | |||
| import os.path | |||
| from flask import Flask, redirect, json, g, make_response | |||
| from flask_socketio import SocketIO | |||
| @@ -62,6 +65,8 @@ class ActorCore(object): | |||
| key = "actor_types" | |||
| def __init__(self, cbpi): | |||
| self.logger = logging.getLogger(__name__) | |||
| self.cbpi = cbpi | |||
| self.cbpi.cache["actors"] = {} | |||
| self.cbpi.cache[self.key] = {} | |||
| @@ -82,8 +87,7 @@ class ActorCore(object): | |||
| actor.power = 100 | |||
| self.cbpi.emit("INIT_ACTOR", id=id) | |||
| except Exception as e: | |||
| print e | |||
| self.cbpi._app.logger.error(e) | |||
| self.logger.error(e) | |||
| def stop_one(self, id): | |||
| self.cbpi.cache["actors"][id]["instance"].stop() | |||
| @@ -99,7 +103,7 @@ class ActorCore(object): | |||
| self.cbpi.emit("SWITCH_ACTOR_ON", id=id, power=power) | |||
| return True | |||
| except Exception as e: | |||
| print e | |||
| self.logger.error(e) | |||
| return False | |||
| def off(self, id): | |||
| @@ -111,7 +115,7 @@ class ActorCore(object): | |||
| self.cbpi.emit("SWITCH_ACTOR_OFF", id=id) | |||
| return True | |||
| except Exception as e: | |||
| print e | |||
| self.logger.error(e) | |||
| return False | |||
| def toggle(self, id): | |||
| @@ -129,7 +133,7 @@ class ActorCore(object): | |||
| self.cbpi.emit("SWITCH_ACTOR_POWER_CHANGE", id=id, power=power) | |||
| return True | |||
| except Exception as e: | |||
| print e | |||
| self.logger.error(e) | |||
| return False | |||
| def action(self, id, method): | |||
| @@ -154,6 +158,8 @@ class SensorCore(object): | |||
| key = "sensor_types" | |||
| def __init__(self, cbpi): | |||
| self.logger = logging.getLogger(__name__) | |||
| self.cbpi = cbpi | |||
| self.cbpi.cache["sensors"] = {} | |||
| self.cbpi.cache["sensor_instances"] = {} | |||
| @@ -181,8 +187,7 @@ class SensorCore(object): | |||
| self.cbpi.emit("INIT_SENSOR", id=id) | |||
| except Exception as e: | |||
| print "ERROR" | |||
| self.cbpi._app.logger.error(e) | |||
| self.logger.error(e) | |||
| def stop_one(self, id): | |||
| @@ -240,7 +245,7 @@ class BrewingCore(object): | |||
| # 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)) | |||
| 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.init() | |||
| kettle.instance = instance | |||
| @@ -250,13 +255,13 @@ class BrewingCore(object): | |||
| 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.ws_emit("UPDATE_KETTLE", self.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.ws_emit("UPDATE_KETTLE", self.cbpi.cache.get("kettle").get(id)) | |||
| self.cbpi.emit("KETTLE_CONTROLLER_STOPPED", id=id) | |||
| @@ -271,12 +276,19 @@ class FermentationCore(object): | |||
| class CraftBeerPI(object): | |||
| _logger_configuration_file = './config/logger.yaml' | |||
| cache = {} | |||
| eventbus = {} | |||
| def __init__(self): | |||
| FORMAT = '%(asctime)-15s - %(levelname)s - %(message)s' | |||
| logging.basicConfig(filename='./logs/app.log', level=logging.INFO, format=FORMAT) | |||
| if os.path.isfile(self._logger_configuration_file): | |||
| logging.config.dictConfig(yaml.load(open(self._logger_configuration_file, 'r'))) | |||
| self.logger = logging.getLogger(__name__) | |||
| self.logger.info("Logger got initialized.") | |||
| self.cache["messages"] = [] | |||
| self.cache["version"] = "3.1" | |||
| self.modules = {} | |||
| @@ -306,7 +318,7 @@ class CraftBeerPI(object): | |||
| port = int(cbpi.get_config_parameter('port', '5000')) | |||
| except ValueError: | |||
| port = 5000 | |||
| print port | |||
| self.logger.info("port [%s]", port) | |||
| self._socketio.run(self._app, host='0.0.0.0', port=port) | |||
| def beep(self): | |||
| @@ -331,7 +343,7 @@ class CraftBeerPI(object): | |||
| db.cursor().executescript(f.read()) | |||
| db.commit() | |||
| except Exception as e: | |||
| self.logger.error(e) | |||
| pass | |||
| def nocache(self, view): | |||
| @@ -388,9 +400,8 @@ class CraftBeerPI(object): | |||
| try: | |||
| self.modules[filename] = import_module("modules.plugins.%s" % (filename)) | |||
| except Exception as e: | |||
| self.logger.error(e) | |||
| self.notify("Failed to load plugin %s " % filename, str(e), type="danger", timeout=None) | |||
| cbpi = CraftBeerPI() | |||
| addon = cbpi.addon | |||
| addon = cbpi.addon | |||
| @@ -19,8 +19,7 @@ def execute_file(curernt_version, data): | |||
| conn.commit() | |||
| except sqlite3.OperationalError as err: | |||
| print err | |||
| cbpi._app.logger.error(err) | |||
| @cbpi.addon.core.initializer(order=-9999) | |||
| def init(cbpi): | |||
| @@ -5,9 +5,13 @@ from flask_swagger import swagger | |||
| from flask import json | |||
| from flask import Blueprint | |||
| import logging | |||
| @addon.core.initializer(order=22) | |||
| def web(cbpi): | |||
| logger = logging.getLogger(__name__) | |||
| s = Blueprint('web_view', __name__, template_folder='templates', static_folder='static') | |||
| @s.route('/', methods=["GET"]) | |||
| @@ -5,8 +5,11 @@ from flask_swagger import swagger | |||
| from flask import json | |||
| from flask import Blueprint | |||
| import logging | |||
| @addon.core.initializer(order=22) | |||
| def web(cbpi): | |||
| logger = logging.getLogger(__name__) | |||
| s = Blueprint('webviewreact', __name__, template_folder='templates', static_folder='static') | |||
| @@ -1,3 +1,4 @@ | |||
| import logging | |||
| import time | |||
| from flask import request | |||
| from flask_classy import route | |||
| @@ -12,6 +13,8 @@ class FermenterView(BaseView): | |||
| model = Fermenter | |||
| cache_key = "fermenter" | |||
| def __init__(self): | |||
| self.logger = logging.getLogger(__name__) | |||
| def _post_post_callback(self, m): | |||
| m.state = False | |||
| @@ -3,6 +3,8 @@ from flask import request | |||
| from modules.core.core import cbpi, addon | |||
| import logging | |||
| class User(flask_login.UserMixin): | |||
| pass | |||
| @@ -7,6 +7,8 @@ from modules.core.core import cbpi | |||
| class LogView(FlaskView): | |||
| _log_directory = "./logs" | |||
| @route('/', methods=['GET']) | |||
| def get_all_logfiles(self): | |||
| """ | |||
| @@ -19,7 +21,7 @@ class LogView(FlaskView): | |||
| description: List of all log files | |||
| """ | |||
| result = [] | |||
| for filename in os.listdir("./logs"): | |||
| for filename in os.listdir(self._log_directory): | |||
| if filename.endswith(".log"): | |||
| result.append(filename) | |||
| return json.dumps(result) | |||
| @@ -1,3 +1,5 @@ | |||
| import logging | |||
| from flask import json, request | |||
| from flask_classy import FlaskView, route | |||
| from git import Repo, Git | |||
| @@ -11,6 +13,8 @@ from modules.step import Step, StepView | |||
| class KBH(FlaskView): | |||
| def __init__(self): | |||
| self.logger = logging.getLogger(__name__) | |||
| @route('/', methods=['GET']) | |||
| def get(self): | |||
| @@ -39,7 +43,7 @@ class KBH(FlaskView): | |||
| result.append({"id": row[0], "name": row[1], "brewed": row[2]}) | |||
| return json.dumps(result) | |||
| except Exception as e: | |||
| print e | |||
| self.logger.error(e) | |||
| self.api.notify(headline="Failed to load KHB database", message="ERROR", type="danger") | |||
| return ('', 500) | |||
| finally: | |||
| @@ -1,12 +1,6 @@ | |||
| #!/usr/bin/env python | |||
| from modules.core.core import * | |||
| cbpi = CraftBeerPI() | |||
| addon = cbpi.addon | |||
| from modules.core.db_migrate import * | |||
| from modules.buzzer import * | |||
| from modules.config import * | |||
| @@ -0,0 +1,13 @@ | |||
| from modules.logs import LogView | |||
| from tests.testlib import utils | |||
| class TestLogView(object): | |||
| def test_get_all_logfiles(self): | |||
| LogView._log_directory = utils.get_base_path() + "/logs" | |||
| logfiles = LogView().get_all_logfiles() | |||
| # if no log file is found then two square brackets "[]" are returned and string length is 2 | |||
| assert (len(logfiles) > 2) | |||
| @@ -0,0 +1,13 @@ | |||
| import os | |||
| def get_base_path(): | |||
| marker_file = "run.py" | |||
| current_path = os.getcwd() | |||
| while current_path != 0: | |||
| if marker_file in os.listdir(current_path): | |||
| return current_path | |||
| current_path = os.path.dirname(os.path.normpath(current_path)) | |||