浏览代码

Merge 933096624e into 6253cb9976

pull/147/merge
isarvalley GitHub 8 年前
父节点
当前提交
27df35dc5c
共有 24 个文件被更改,包括 162 次插入47 次删除
  1. +1
    -0
      .codebeatignore
  2. +13
    -0
      .travis.yml
  3. +8
    -0
      README.md
  4. +19
    -0
      config/logger.yaml
  5. +4
    -0
      modules/action/__init__.py
  6. +9
    -5
      modules/base_plugins/actor.py
  7. +9
    -4
      modules/base_plugins/sensor.py
  8. +6
    -2
      modules/core/baseapi.py
  9. +18
    -9
      modules/core/basetypes.py
  10. +28
    -17
      modules/core/core.py
  11. +1
    -2
      modules/core/db_migrate.py
  12. +4
    -0
      modules/example_plugins/WebViewJquery/__init__.py
  13. +3
    -0
      modules/example_plugins/WebViewReactJs/__init__.py
  14. +3
    -0
      modules/fermenter/__init__.py
  15. +2
    -0
      modules/login/__init__.py
  16. +3
    -1
      modules/logs/__init__.py
  17. +5
    -1
      modules/recipe_import/kbh.py
  18. +0
    -6
      run.py
  19. +0
    -0
      tests/__init__.py
  20. +0
    -0
      tests/logs/__init__.py
  21. +13
    -0
      tests/logs/test_log_view.py
  22. +0
    -0
      tests/testlib/__init__.py
  23. +13
    -0
      tests/testlib/utils.py
  24. +0
    -0
      update/5_kairosdb_config.sql

+ 1
- 0
.codebeatignore 查看文件

@@ -0,0 +1 @@
modules/ui/static/**

+ 13
- 0
.travis.yml 查看文件

@@ -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

+ 8
- 0
README.md 查看文件

@@ -1,3 +1,11 @@
[![Build Status](https://travis-ci.org/isarvalley/craftbeerpi3.svg?branch=core_refactoring)](https://travis-ci.org/isarvalley/craftbeerpi3)

[![codebeat badge](https://codebeat.co/badges/72fa1981-c82a-488f-9a53-9e21ed9de4cc)](https://codebeat.co/projects/github-com-isarvalley-craftbeerpi3-core_refactoring)

[![Codacy Badge](https://api.codacy.com/project/badge/Grade/0a970c7873f84953bd772c36d5ffc05c)](https://www.codacy.com/app/isar_valley/craftbeerpi3?utm_source=github.com&utm_medium=referral&utm_content=isarvalley/craftbeerpi3&utm_campaign=Badge_Grade)

[![BCH compliance](https://bettercodehub.com/edge/badge/isarvalley/craftbeerpi3?branch=core_refactoring)](https://bettercodehub.com/)

# CraftBeerPi V3.0

This is CraftBeerPi version 3.0. It's currently in beta status.


+ 19
- 0
config/logger.yaml 查看文件

@@ -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]

+ 4
- 0
modules/action/__init__.py 查看文件

@@ -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):


+ 9
- 5
modules/base_plugins/actor.py 查看文件

@@ -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)


+ 9
- 4
modules/base_plugins/sensor.py 查看文件

@@ -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:


+ 6
- 2
modules/core/baseapi.py 查看文件

@@ -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

+ 18
- 9
modules/core/basetypes.py 查看文件

@@ -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))


+ 28
- 17
modules/core/core.py 查看文件

@@ -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

+ 1
- 2
modules/core/db_migrate.py 查看文件

@@ -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):


+ 4
- 0
modules/example_plugins/WebViewJquery/__init__.py 查看文件

@@ -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"])


+ 3
- 0
modules/example_plugins/WebViewReactJs/__init__.py 查看文件

@@ -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')



+ 3
- 0
modules/fermenter/__init__.py 查看文件

@@ -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


+ 2
- 0
modules/login/__init__.py 查看文件

@@ -3,6 +3,8 @@ from flask import request

from modules.core.core import cbpi, addon

import logging

class User(flask_login.UserMixin):
pass



+ 3
- 1
modules/logs/__init__.py 查看文件

@@ -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)


+ 5
- 1
modules/recipe_import/kbh.py 查看文件

@@ -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:


+ 0
- 6
run.py 查看文件

@@ -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
tests/__init__.py 查看文件


+ 0
- 0
tests/logs/__init__.py 查看文件


+ 13
- 0
tests/logs/test_log_view.py 查看文件

@@ -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
tests/testlib/__init__.py 查看文件


+ 13
- 0
tests/testlib/utils.py 查看文件

@@ -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))

+ 0
- 0
update/5_kairosdb_config.sql 查看文件


正在加载...
取消
保存