setuptools added

This commit is contained in:
manuel83 2019-01-05 20:43:48 +01:00
parent 00c7a465d7
commit 7ab75f0b01
104 changed files with 1446 additions and 1208 deletions

7
.gitignore vendored
View file

@ -1,4 +1,7 @@
*.pyc *.pyc
docs_src/build/ docs_src/build/
build
dist
.idea
*.log
cbpi.egg-info

View file

@ -2,13 +2,14 @@
<module type="PYTHON_MODULE" version="4"> <module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/core" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/cbpi" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/test_env2" />
</content> </content>
<orderEntry type="jdk" jdkName="Python 3.7.1 virtualenv at ~/cbp42" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.7.1 virtualenv at ~/cbp42" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
<component name="TestRunnerService"> <component name="TestRunnerService">
<option name="projectConfiguration" value="py.test" /> <option name="projectConfiguration" value="pytest" />
<option name="PROJECT_TEST_RUNNER" value="py.test" /> <option name="PROJECT_TEST_RUNNER" value="py.test" />
</component> </component>
</module> </module>

View file

@ -14,5 +14,23 @@
<auth-required>false</auth-required> <auth-required>false</auth-required>
<introspection-schemas>*:@</introspection-schemas> <introspection-schemas>*:@</introspection-schemas>
</data-source> </data-source>
<data-source name="craftbeerpi [3]" uuid="633d3113-4e25-4945-a8ff-56edb8af9fa9">
<database-info product="SQLite" version="3.16.1" jdbc-version="2.1" driver-name="SQLiteJDBC" driver-version="native" dbms="SQLITE" exact-version="3.16.1" />
<case-sensitivity plain-identifiers="mixed" quoted-identifiers="mixed" />
<auth-required>false</auth-required>
<introspection-schemas>*:@</introspection-schemas>
</data-source>
<data-source name="craftbeerpi [4]" uuid="6a479d72-eae8-4efb-a6f4-370f17be2a85">
<database-info product="SQLite" version="3.16.1" jdbc-version="2.1" driver-name="SQLiteJDBC" driver-version="native" dbms="SQLITE" exact-version="3.16.1" />
<case-sensitivity plain-identifiers="mixed" quoted-identifiers="mixed" />
<auth-required>false</auth-required>
<introspection-schemas>*:@</introspection-schemas>
</data-source>
<data-source name="craftbeerpi [2]" uuid="e7e939c3-e1f6-46db-8ea3-75b5f26d7b73">
<database-info product="SQLite" version="3.16.1" jdbc-version="2.1" driver-name="SQLiteJDBC" driver-version="native" dbms="SQLITE" exact-version="3.16.1" />
<case-sensitivity plain-identifiers="mixed" quoted-identifiers="mixed" />
<auth-required>false</auth-required>
<introspection-schemas>*:@</introspection-schemas>
</data-source>
</component> </component>
</project> </project>

View file

@ -27,5 +27,56 @@
</library> </library>
</libraries> </libraries>
</data-source> </data-source>
<data-source source="LOCAL" name="craftbeerpi [3]" uuid="633d3113-4e25-4945-a8ff-56edb8af9fa9">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/test/craftbeerpi.db</jdbc-url>
<driver-properties>
<property name="enable_load_extension" value="true" />
</driver-properties>
<libraries>
<library>
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.16.1/xerial-sqlite-license.txt</url>
</library>
<library>
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.16.1/sqlite-jdbc-3.16.1.jar</url>
</library>
</libraries>
</data-source>
<data-source source="LOCAL" name="craftbeerpi [4]" uuid="6a479d72-eae8-4efb-a6f4-370f17be2a85">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/test22/craftbeerpi.db</jdbc-url>
<driver-properties>
<property name="enable_load_extension" value="true" />
</driver-properties>
<libraries>
<library>
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.16.1/xerial-sqlite-license.txt</url>
</library>
<library>
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.16.1/sqlite-jdbc-3.16.1.jar</url>
</library>
</libraries>
</data-source>
<data-source source="LOCAL" name="craftbeerpi [2]" uuid="e7e939c3-e1f6-46db-8ea3-75b5f26d7b73">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/cbpi/craftbeerpi.db</jdbc-url>
<driver-properties>
<property name="enable_load_extension" value="true" />
</driver-properties>
<libraries>
<library>
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.16.1/xerial-sqlite-license.txt</url>
</library>
<library>
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.16.1/sqlite-jdbc-3.16.1.jar</url>
</library>
</libraries>
</data-source>
</component> </component>
</project> </project>

File diff suppressed because it is too large Load diff

View file

@ -1,14 +1,14 @@
FROM python:3 FROM python:3.5.6-stretch
WORKDIR /usr/src/app WORKDIR /usr/src/app
COPY requirements.txt ./ COPY dist/cbpi-0.0.1.tar.gz ./
RUN pip install --no-cache-dir -r requirements.txt RUN pip install cbpi-0.0.1.tar.gz --no-cache-dir
COPY . . COPY . .
EXPOSE 8080 EXPOSE 8080
CMD [ "python", "./run.py" ] CMD [ "cbpi" ]

2
MANIFEST.in Normal file
View file

@ -0,0 +1,2 @@
recursive-include cbpi/config *
recursive-include cbpi/extension *

27
cbpi/api/__init__.py Normal file
View file

@ -0,0 +1,27 @@
__all__ = ["CBPiActor",
"CBPiExtension",
"Property",
"PropertyType",
"on_websocket_message",
"on_mqtt_message",
"on_event",
"on_startup",
"request_mapping",
"action",
"background_task",
"CBPiKettleLogic",
"CBPiSimpleStep",
"CBPiException",
"KettleException",
"SensorException",
"ActorException",
"CBPiSensor"]
from cbpi.api.actor import *
from cbpi.api.sensor import *
from cbpi.api.extension import *
from cbpi.api.property import *
from cbpi.api.decorator import *
from cbpi.api.kettle_logic import *
from cbpi.api.step import *
from cbpi.api.exceptions import *

49
cbpi/api/actor.py Normal file
View file

@ -0,0 +1,49 @@
from abc import ABCMeta
from cbpi.api.extension import CBPiExtension
__all__ = ["CBPiActor"]
import logging
logger = logging.getLogger(__file__)
class CBPiActor(CBPiExtension, metaclass=ABCMeta):
def init(self):
pass
def stop(self):
pass
def on(self, power):
'''
Code to switch the actor on. Power is provided as integer value
:param power: power value between 0 and 100
:return: None
'''
pass
def off(self):
'''
Code to switch the actor off
:return: None
'''
pass
def state(self):
'''
Return the current actor state
:return:
'''
pass
def reprJSON(self):
return dict(state=True)

8
cbpi/api/config.py Normal file
View file

@ -0,0 +1,8 @@
from enum import Enum
class ConfigType(Enum):
STRING = "string"
NUMBER = "number"
SELECT = "select"

96
cbpi/api/decorator.py Normal file
View file

@ -0,0 +1,96 @@
__all__ = ["request_mapping", "on_startup", "on_event", "on_mqtt_message", "on_websocket_message", "action", "background_task"]
from aiohttp_auth import auth
def composed(*decs):
def deco(f):
for dec in reversed(decs):
f = dec(f)
return f
return deco
def request_mapping(path, name=None, method="GET", auth_required=True):
def on_http_request(path, name=None):
def real_decorator(func):
func.route = True
func.path = path
func.name = name
func.method = method
return func
return real_decorator
if auth_required is True:
return composed(
on_http_request(path, name),
auth.auth_required
)
else:
return composed(
on_http_request(path, name)
)
def on_websocket_message(path, name=None):
def real_decorator(func):
func.ws = True
func.key = path
func.name = name
return func
return real_decorator
def on_event(topic):
def real_decorator(func):
func.eventbus = True
func.topic = topic
func.c = None
return func
return real_decorator
def action(key, parameters):
def real_decorator(func):
func.action = True
func.key = key
func.parameters = parameters
return func
return real_decorator
def on_mqtt_message(topic):
def real_decorator(func):
func.mqtt = True
func.topic = topic
return func
return real_decorator
def background_task(name, interval):
def real_decorator(func):
func.background_task = True
func.name = name
func.interval = interval
return func
return real_decorator
def on_startup(name, order=0):
def real_decorator(func):
func.on_startup = True
func.name = name
func.order = order
return func
return real_decorator
def entry_exit(f):
def new_f():
f()
return new_f

14
cbpi/api/exceptions.py Normal file
View file

@ -0,0 +1,14 @@
__all__ = ["CBPiException","KettleException","SensorException","ActorException"]
class CBPiException(Exception):
pass
class KettleException(CBPiException):
pass
class SensorException(CBPiException):
pass
class ActorException(CBPiException):
pass

54
cbpi/api/extension.py Normal file
View file

@ -0,0 +1,54 @@
import logging
import os
import sys
import yaml
__all__ = ["CBPiExtension"]
logger = logging.getLogger(__file__)
class CBPiExtension():
def init(self):
pass
def stop(self):
pass
def __init__(self, *args, **kwds):
for a in kwds:
logger.debug("Parameter: %s Value: %s" % ( a, kwds.get(a)))
super(CBPiExtension, self).__setattr__(a, kwds.get(a))
self.cbpi = kwds.get("cbpi")
self.id = kwds.get("id")
self.value = None
self.__dirty = False
def __setattr__(self, name, value):
if name != "_CBPiExtension__dirty":
self.__dirty = True
super(CBPiExtension, self).__setattr__(name, value)
else:
super(CBPiExtension, self).__setattr__(name, value)
def load_config(self):
path = os.path.dirname(sys.modules[self.__class__.__module__].__file__)
try:
with open("%s/config.yaml" % path, 'rt') as f:
data = yaml.load(f)
return data
except:
logger.warning("Faild to load config %s/config.yaml" % path)

38
cbpi/api/kettle_logic.py Normal file
View file

@ -0,0 +1,38 @@
from cbpi.api.extension import CBPiExtension
class CBPiKettleLogic(CBPiExtension):
'''
Base Class for a Kettle logic.
'''
def init(self):
'''
Code which will be executed when the logic is initialised. Needs to be overwritten by the implementing logic
:return: None
'''
pass
def stop(self):
'''
Code which will be executed when the logic is stopped. Needs to be overwritten by the implementing logic
:return: None
'''
pass
def run(self):
'''
This method is running as background process when logic is started.
Typically a while loop responsible that the method keeps running
while self.running:
await asyncio.sleep(1)
:return: None
'''
pass

113
cbpi/api/property.py Normal file
View file

@ -0,0 +1,113 @@
__all__ = ["PropertyType", "Property"]
class PropertyType(object):
pass
class Property(object):
class Select(PropertyType):
'''
Select Property. The user can select value from list set as options parameter
'''
def __init__(self, label, options, description=""):
'''
:param label:
:param options:
:param description:
'''
PropertyType.__init__(self)
self.label = label
self.options = options
self.description = description
class Number(PropertyType):
'''
The user can set a number value
'''
def __init__(self, label, configurable=False, default_value=None, unit="", description=""):
'''
Test
:param label:
:param configurable:
:param default_value:
:param unit:
:param description:
'''
PropertyType.__init__(self)
self.label = label
self.configurable = configurable
self.default_value = default_value
self.description = description
class Text(PropertyType):
'''
The user can set a text value
'''
def __init__(self, label, configurable=False, default_value="", description=""):
'''
:param label:
:param configurable:
:param default_value:
:param description:
'''
PropertyType.__init__(self)
self.label = label
self.configurable = configurable
self.default_value = default_value
self.description = description
class Actor(PropertyType):
'''
The user select an actor which is available in the system. The value of this variable will be the actor id
'''
def __init__(self, label, description=""):
'''
:param label:
:param description:
'''
PropertyType.__init__(self)
self.label = label
self.configurable = True
self.description = description
class Sensor(PropertyType):
'''
The user select a sensor which is available in the system. The value of this variable will be the sensor id
'''
def __init__(self, label, description=""):
'''
:param label:
:param description:
'''
PropertyType.__init__(self)
self.label = label
self.configurable = True
self.description = description
class Kettle(PropertyType):
'''
The user select a kettle which is available in the system. The value of this variable will be the kettle id
'''
def __init__(self, label, description=""):
'''
:param label:
:param description:
'''
PropertyType.__init__(self)
self.label = label
self.configurable = True
self.description = description

38
cbpi/api/sensor.py Normal file
View file

@ -0,0 +1,38 @@
from logging.handlers import RotatingFileHandler
from time import localtime, strftime
from cbpi.api.extension import CBPiExtension
import logging
class CBPiSensor(CBPiExtension):
def __init__(self, *args, **kwds):
CBPiExtension.__init__(self, *args, **kwds)
self.logger = logging.getLogger(__file__)
self.data_logger = None
def log_data(self, value):
formatted_time = strftime("%Y-%m-%d %H:%M:%S", localtime())
self.data_logger.debug("%s,%s" % (formatted_time, value))
def init(self):
self.data_logger = logging.getLogger('cbpi.sensor.%s' % self.id)
self.data_logger.propagate = False
self.data_logger.setLevel(logging.DEBUG)
handler = RotatingFileHandler('./logs/sensors/sensor_%s.log' % self.id, maxBytes=2000, backupCount=10)
self.data_logger.addHandler(handler)
pass
async def run(self, cbpi):
self.logger.warning("Sensor Init not implemented")
def state(self):
pass

134
cbpi/api/step.py Normal file
View file

@ -0,0 +1,134 @@
import time
import asyncio
import logging
from abc import abstractmethod,ABCMeta
class CBPiSimpleStep(metaclass=ABCMeta):
__dirty = False
managed_fields = []
_interval = 0.1
_max_exceptions = 2
_exception_count = 0
def __init__(self, *args, **kwargs):
self.logger = logging.getLogger(__name__)
for a in kwargs:
super(CBPiSimpleStep, self).__setattr__(a, kwargs.get(a))
self.id = kwargs.get("id")
self.is_stopped = False
self.is_next = False
self.start = time.time()
def running(self):
'''
Method checks if the step should continue running.
The method will return False if the step is requested to stop or the next step should start
:return: True if the step is running. Otherwise False.
'''
if self.is_next is True:
return False
if self.is_stopped is True:
return False
return True
async def run(self):
'''
This method in running in the background. It invokes the run_cycle method in the configured interval
It checks if a managed variable was modified in the last exection cycle. If yes, the method will persisit the new value of the
managed property
:return: None
'''
while self.running():
try:
await self.run_cycle()
except Exception as e:
logging.exception("CBPiSimpleStep Error")
self._exception_count = self._exception_count + 1
if self._exception_count == self._max_exceptions:
self.logger.error("Step Exception limit exceeded. Stopping Step")
self.stop()
await asyncio.sleep(self._interval)
if self.is_dirty():
# Now we have to store the managed props
state = {}
for field in self.managed_fields:
state[field] = self.__getattribute__(field)
#step_controller.model.update_step_state(step_controller.current_step.id, state)
await self.cbpi.step.model.update_step_state(self.id, state)
self.reset_dirty()
@abstractmethod
async def run_cycle(self):
'''
This method is executed in the defined interval.
That the place to put your step logic.
The method need to be overwritten in the Ccstom step implementaion
:return: None
'''
print("NOTING IMPLEMENTED")
pass
def next(self):
'''
Request to stop the the step
:return: None
'''
self.is_next = True
def stop(self):
'''
Request to stop the step
:return: None
'''
self.is_stopped = True
def reset(self):
'''
Reset the step. This method needs to be overwritten by the custom step implementation
:return: None
'''
pass
def is_dirty(self):
'''
Check if a managed variable has a new value
:return: True if at least one managed variable has a new value assigend. Otherwise False
'''
return self.__dirty
def reset_dirty(self):
'''
Reset the dirty flag
:return:
'''
self.__dirty = False
def __setattr__(self, name, value):
if name != "_Step__dirty" and name in self.managed_fields:
self.__dirty = True
super(CBPiSimpleStep, self).__setattr__(name, value)
else:
super(CBPiSimpleStep, self).__setattr__(name, value)

42
cbpi/cli.py Normal file
View file

@ -0,0 +1,42 @@
import logging
from cbpi.craftbeerpi import CraftBeerPi
import os
import pathlib
import shutil
logging.basicConfig(level=logging.INFO,filename='./logs/app.log', filemode='a', format='%(asctime)s - %(levelname)s - %(name)s - %(message)s')
def create_plugin_file():
import os.path
if os.path.exists(os.path.join(".", 'config', "plugin_list.txt")) is False:
srcfile = os.path.join(os.path.dirname(__file__), "config", "plugin_list.txt")
destfile = os.path.join(".", 'config')
shutil.copy(srcfile, destfile)
def create_config_file():
import os.path
if os.path.exists(os.path.join(".", 'config', "config.yaml")) is False:
srcfile = os.path.join(os.path.dirname(__file__), "config", "config.yaml")
destfile = os.path.join(".", 'config')
shutil.copy(srcfile, destfile)
def create_home_folder_structure():
pathlib.Path(os.path.join(".", 'logs/sensors')).mkdir(parents=True, exist_ok=True)
pathlib.Path(os.path.join(".", 'config')).mkdir(parents=True, exist_ok=True)
def main():
#import sys
#arg1, arg2 = sys.argv[1], sys.argv[2]
create_home_folder_structure()
create_plugin_file()
create_config_file()
cbpi = CraftBeerPi()
cbpi.start()

11
cbpi/config/config.yaml Normal file
View file

@ -0,0 +1,11 @@
name: CraftBeerPi
version: 4.1
#index_url: /myext
port: 8080
username: cbpi
password: 123

View file

@ -0,0 +1 @@
cbpi-actor

View file

@ -1,11 +1,11 @@
import logging import logging
from asyncio import Future from asyncio import Future
from cbpi_api import * from cbpi.api import *
from voluptuous import Schema from voluptuous import Schema
from core.controller.crud_controller import CRUDController from cbpi.controller.crud_controller import CRUDController
from core.database.model import ActorModel from cbpi.database.model import ActorModel
class ActorController(CRUDController): class ActorController(CRUDController):

View file

@ -1,10 +1,9 @@
import logging import logging
import os import os
from cbpi_api.config import ConfigType from cbpi.api.config import ConfigType
from cbpi.database.model import ConfigModel
from core.database.model import ConfigModel from cbpi.utils import load_config
from utils import load_config
class ConfigController(): class ConfigController():
@ -21,7 +20,8 @@ class ConfigController():
async def init(self): async def init(self):
this_directory = os.path.dirname(__file__) this_directory = os.path.dirname(__file__)
self.static = load_config(os.path.join(this_directory, '../../config/config.yaml'))
self.static = load_config("./config/config.yaml")
items = await self.model.get_all() items = await self.model.get_all()
for key, value in items.items(): for key, value in items.items():
self.cache[value.name] = value self.cache[value.name] = value

View file

@ -1,7 +1,7 @@
import pprint import pprint
from abc import ABCMeta from abc import ABCMeta
from cbpi_api.exceptions import CBPiException from cbpi.api import *
class CRUDController(metaclass=ABCMeta): class CRUDController(metaclass=ABCMeta):

View file

@ -2,8 +2,8 @@ import logging
from voluptuous import Schema, MultipleInvalid from voluptuous import Schema, MultipleInvalid
from core.controller.crud_controller import CRUDController from cbpi.controller.crud_controller import CRUDController
from core.database.model import DashboardModel, DashboardContentModel from cbpi.database.model import DashboardModel, DashboardContentModel
class DashboardController(CRUDController): class DashboardController(CRUDController):

View file

@ -1,7 +1,7 @@
import asyncio import asyncio
import logging import logging
from job.aiohttp import setup, get_scheduler_from_app from cbpi.job.aiohttp import setup, get_scheduler_from_app
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class JobController(object): class JobController(object):

View file

@ -1,13 +1,8 @@
import re import re
from cbpi.api import *
from cbpi.controller.crud_controller import CRUDController
from cbpi_api import * from cbpi.database.model import KettleModel
from cbpi_api.exceptions import KettleException, ActorException, SensorException from cbpi.job.aiohttp import get_scheduler_from_app
from core.controller.crud_controller import CRUDController
from core.database.model import KettleModel
from core.job.aiohttp import get_scheduler_from_app
class KettleController(CRUDController): class KettleController(CRUDController):

View file

@ -1,4 +1,4 @@
from cbpi_api import * from cbpi.api import *
class NotificationController(object): class NotificationController(object):

View file

@ -5,9 +5,9 @@ from importlib import import_module
import aiohttp import aiohttp
import yaml import yaml
from aiohttp import web from aiohttp import web
from cbpi_api import * from cbpi.api import *
from core.utils.utils import load_config, json_dumps from cbpi.utils.utils import load_config, json_dumps
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -33,17 +33,20 @@ class PluginController():
def load_plugins(self): def load_plugins(self):
for filename in os.listdir("./core/extension"): this_directory = os.path.dirname(__file__)
if os.path.isdir("./core/extension/" + filename) is False or filename == "__pycache__": for filename in os.listdir(os.path.join(this_directory, "../extension")):
if os.path.isdir(os.path.join(this_directory, "../extension/") + filename) is False or filename == "__pycache__":
continue continue
try: try:
logger.info("Trying to load plugin %s" % filename) logger.info("Trying to load plugin %s" % filename)
data = load_config("./core/extension/%s/config.yaml" % filename)
data = load_config(os.path.join(this_directory, "../extension/%s/config.yaml" % filename))
if(data.get("version") == 4): if(data.get("version") == 4):
self.modules[filename] = import_module("core.extension.%s" % (filename)) self.modules[filename] = import_module("cbpi.extension.%s" % (filename))
self.modules[filename].setup(self.cbpi) self.modules[filename].setup(self.cbpi)
logger.info("Plugin %s loaded successful" % filename) logger.info("Plugin %s loaded successful" % filename)
@ -57,8 +60,8 @@ class PluginController():
def load_plugins_from_evn(self): def load_plugins_from_evn(self):
plugins = [] plugins = []
this_directory = os.path.dirname(__file__)
with open('./config/plugin_list.txt') as f: with open(os.path.join(this_directory, "../config/plugin_list.txt")) as f:
plugins = f.read().splitlines() plugins = f.read().splitlines()
plugins = list(set(plugins)) plugins = list(set(plugins))

View file

@ -1,12 +1,9 @@
import json
import logging import logging
from cbpi.controller.crud_controller import CRUDController
from cbpi.database.model import SensorModel
from cbpi.job.aiohttp import get_scheduler_from_app
from cbpi_api import request_mapping
from core.controller.crud_controller import CRUDController
from core.database.model import SensorModel
from core.job.aiohttp import get_scheduler_from_app
from core.utils.encoder import ComplexEncoder
class SensorController(CRUDController): class SensorController(CRUDController):

View file

@ -1,11 +1,9 @@
import asyncio
import logging import logging
import time import time
from cbpi_api import * from cbpi.api import *
from cbpi.controller.crud_controller import CRUDController
from core.controller.crud_controller import CRUDController from cbpi.database.model import StepModel
from core.database.model import StepModel
class StepController(CRUDController): class StepController(CRUDController):

View file

@ -2,9 +2,9 @@ import datetime
from aiohttp import web from aiohttp import web
from aiojobs.aiohttp import get_scheduler_from_app from aiojobs.aiohttp import get_scheduler_from_app
from cbpi_api import * from cbpi.api import *
from utils import json_dumps from cbpi.utils import json_dumps
class SystemController(): class SystemController():

View file

@ -1,5 +1,4 @@
import logging import logging
import os
from os import urandom from os import urandom
from aiohttp import web from aiohttp import web
@ -7,33 +6,36 @@ from aiohttp_auth import auth
from aiohttp_session import session_middleware from aiohttp_session import session_middleware
from aiohttp_session.cookie_storage import EncryptedCookieStorage from aiohttp_session.cookie_storage import EncryptedCookieStorage
from aiohttp_swagger import setup_swagger from aiohttp_swagger import setup_swagger
from cbpi_api.exceptions import CBPiException from cbpi.api.exceptions import CBPiException
from voluptuous import MultipleInvalid from voluptuous import MultipleInvalid
from controller.dashboard_controller import DashboardController from cbpi.controller.dashboard_controller import DashboardController
from controller.job_controller import JobController from cbpi.controller.job_controller import JobController
from core.controller.actor_controller import ActorController from cbpi.controller.actor_controller import ActorController
from core.controller.config_controller import ConfigController from cbpi.controller.config_controller import ConfigController
from core.controller.kettle_controller import KettleController from cbpi.controller.kettle_controller import KettleController
from core.controller.notification_controller import NotificationController from cbpi.controller.notification_controller import NotificationController
from core.controller.plugin_controller import PluginController from cbpi.controller.plugin_controller import PluginController
from core.controller.sensor_controller import SensorController from cbpi.controller.sensor_controller import SensorController
from core.controller.step_controller import StepController from cbpi.controller.step_controller import StepController
from core.controller.system_controller import SystemController from cbpi.controller.system_controller import SystemController
from core.database.model import DBModel from cbpi.database.model import DBModel
from core.eventbus import CBPiEventBus from cbpi.eventbus import CBPiEventBus
from core.http_endpoints.http_login import Login from cbpi.http_endpoints.http_login import Login
from core.utils import * from cbpi.utils import *
from core.websocket import CBPiWebSocket from cbpi.websocket import CBPiWebSocket
from http_endpoints.http_actor import ActorHttpEndpoints from cbpi.http_endpoints.http_actor import ActorHttpEndpoints
from http_endpoints.http_config import ConfigHttpEndpoints from cbpi.http_endpoints.http_config import ConfigHttpEndpoints
from http_endpoints.http_dashboard import DashBoardHttpEndpoints from cbpi.http_endpoints.http_dashboard import DashBoardHttpEndpoints
from http_endpoints.http_kettle import KettleHttpEndpoints from cbpi.http_endpoints.http_kettle import KettleHttpEndpoints
from http_endpoints.http_sensor import SensorHttpEndpoints from cbpi.http_endpoints.http_sensor import SensorHttpEndpoints
from http_endpoints.http_step import StepHttpEndpoints from cbpi.http_endpoints.http_step import StepHttpEndpoints
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
@web.middleware @web.middleware
async def error_middleware(request, handler): async def error_middleware(request, handler):
@ -56,7 +58,9 @@ async def error_middleware(request, handler):
class CraftBeerPi(): class CraftBeerPi():
def __init__(self): def __init__(self):
self.static_config = load_config(os.path.join(os.path.dirname(__file__), '../config/config.yaml'))
self.static_config = load_config("./config/config.yaml")
self.database_file = "./craftbeerpi.db" self.database_file = "./craftbeerpi.db"
logger.info("Init CraftBeerPI") logger.info("Init CraftBeerPI")

View file

@ -1,10 +1,9 @@
import json import json
import aiosqlite import aiosqlite
from cbpi_api.exceptions import CBPiException
from voluptuous import Schema, MultipleInvalid
from core.database.orm_framework import DBModel
from cbpi.database.orm_framework import DBModel
DATABASE_FILE = "./craftbeerpi.db" DATABASE_FILE = "./craftbeerpi.db"

View file

@ -2,7 +2,7 @@ import json
import aiosqlite import aiosqlite
import os import os
from cbpi_api.exceptions import CBPiException from cbpi.api import *
from voluptuous import MultipleInvalid, Schema from voluptuous import MultipleInvalid, Schema
DATABASE_FILE = "./craftbeerpi.db" DATABASE_FILE = "./craftbeerpi.db"
@ -38,7 +38,7 @@ class DBModel(object):
async with aiosqlite.connect(DATABASE_FILE) as db: async with aiosqlite.connect(DATABASE_FILE) as db:
assert isinstance(db, aiosqlite.Connection) assert isinstance(db, aiosqlite.Connection)
this_directory = os.path.dirname(__file__) this_directory = os.path.dirname(__file__)
qry = open(os.path.join(this_directory, '../../config/create_database.sql'), 'r').read() qry = open(os.path.join(this_directory, "../config/create_database.sql"), 'r').read()
cursor = await db.executescript(qry) cursor = await db.executescript(qry)
@classmethod @classmethod

View file

@ -2,10 +2,12 @@ import asyncio
import inspect import inspect
import logging import logging
from cbpi_api.exceptions import CBPiException from cbpi.api import *
class CBPiEventBus(object): class CBPiEventBus(object):
class Node(object): class Node(object):
__slots__ = '_children', '_content' __slots__ = '_children', '_content'
@ -22,17 +24,18 @@ class CBPiEventBus(object):
self.topic = topic self.topic = topic
self.supports_future = supports_future self.supports_future = supports_future
class Result(): class Result:
def __init__(self, result, timeout): def __init__(self, result, timeout):
self.result = result self.result = result
self.timeout = timeout self.timeout = timeout
class ResultContainer(): class ResultContainer:
def __init__(self, results, timeout=False): def __init__(self, results, timeout=False):
self.results = {} self.results = {}
self.timeout = timeout self.timeout = timeout
self._jobs = set()
for key, value in results.items(): for key, value in results.items():
if value.done() is True: if value.done() is True:
self.results[key] = CBPiEventBus.Result(value.result(), True) self.results[key] = CBPiEventBus.Result(value.result(), True)
@ -108,7 +111,7 @@ class CBPiEventBus(object):
def sync_fire(self,topic: str,timeout=1, **kwargs): def sync_fire(self,topic: str,timeout=1, **kwargs):
self.loop.create_task(self.fire(topic=topic, timeout=timeout, **kwargs)) self.loop.create_task(self.fire(topic=topic, timeout=timeout, **kwargs))
async def fire(self, topic: str, timeout=1, **kwargs): async def fire(self, topic: str, timeout=0.5, **kwargs):
futures = {} futures = {}

View file

@ -1,9 +1,11 @@
import os
from aiohttp import web from aiohttp import web
from cbpi_api import * from cbpi.api import *
from core.controller.crud_controller import CRUDController from cbpi.controller.crud_controller import CRUDController
from core.database.orm_framework import DBModel from cbpi.database.orm_framework import DBModel
from core.http_endpoints.http_api import HttpAPI from cbpi.http_endpoints.http_curd_endpoints import HttpCrudEndpoints
class DummyModel(DBModel): class DummyModel(DBModel):
@ -14,7 +16,7 @@ class DummyModel(DBModel):
__table_name__ = "dummy" __table_name__ = "dummy"
class MyComp(CBPiExtension, CRUDController, HttpAPI): class MyComp(CBPiExtension, CRUDController, HttpCrudEndpoints):
model = DummyModel model = DummyModel
def __init__(self, cbpi): def __init__(self, cbpi):
@ -23,10 +25,12 @@ class MyComp(CBPiExtension, CRUDController, HttpAPI):
:param cbpi: :param cbpi:
''' '''
self.cbpi = cbpi self.cbpi = cbpi
# register component for http, events # register component for http, events
# In addtion the sub folder static is exposed to access static content via http # In addtion the sub folder static is exposed to access static content via http
self.cbpi.register(self, "/dummy", static="./core/extension/comp/static") self.cbpi.register(self, "/dummy", static=os.path.join(os.path.dirname(__file__), "static"))
@on_event(topic="actor/#") @on_event(topic="actor/#")

View file

@ -1,8 +1,8 @@
import logging import logging
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from cbpi_api import * from cbpi.api import *
from cbpi_api.exceptions import CBPiException
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View file

@ -1,6 +1,6 @@
import asyncio import asyncio
from cbpi_api import * from cbpi.api import *
class CustomLogic(CBPiKettleLogic): class CustomLogic(CBPiKettleLogic):

View file

@ -2,7 +2,7 @@ import asyncio
import logging import logging
import random import random
from cbpi_api import * from cbpi.api import *
class CustomSensor(CBPiSensor): class CustomSensor(CBPiSensor):

View file

@ -1,6 +1,6 @@
import asyncio import asyncio
from cbpi_api import * from cbpi.api import *
class CustomStepCBPi(CBPiSimpleStep): class CustomStepCBPi(CBPiSimpleStep):

View file

@ -1,8 +1,8 @@
from aiohttp import web from aiohttp import web
from cbpi_api import request_mapping from cbpi.api import *
from cbpi_api.exceptions import CBPiException
from cbpi.http_endpoints.http_curd_endpoints import HttpCrudEndpoints
from http_endpoints.http_curd_endpoints import HttpCrudEndpoints
auth = False auth = False
class ActorHttpEndpoints(HttpCrudEndpoints): class ActorHttpEndpoints(HttpCrudEndpoints):

View file

@ -1,9 +1,8 @@
from aiohttp import web from aiohttp import web
from cbpi_api import request_mapping from cbpi.api import *
from cbpi_api.exceptions import CBPiException
from http_endpoints.http_curd_endpoints import HttpCrudEndpoints from cbpi.utils import json_dumps
from utils import json_dumps from cbpi.http_endpoints.http_curd_endpoints import HttpCrudEndpoints
class ConfigHttpEndpoints(HttpCrudEndpoints): class ConfigHttpEndpoints(HttpCrudEndpoints):

View file

@ -1,9 +1,9 @@
import logging import logging
from aiohttp import web from aiohttp import web
from cbpi_api import * from cbpi.api import *
from core.utils.utils import json_dumps from cbpi.utils.utils import json_dumps
class HttpCrudEndpoints(): class HttpCrudEndpoints():

View file

@ -1,10 +1,9 @@
from aiohttp import web from aiohttp import web
from cbpi_api import request_mapping from cbpi.api import *
from voluptuous import Schema from voluptuous import Schema
from database.model import DashboardContentModel from cbpi.http_endpoints.http_curd_endpoints import HttpCrudEndpoints
from http_endpoints.http_curd_endpoints import HttpCrudEndpoints from cbpi.utils import json_dumps
from utils import json_dumps
class DashBoardHttpEndpoints(HttpCrudEndpoints): class DashBoardHttpEndpoints(HttpCrudEndpoints):

View file

@ -1,8 +1,8 @@
from aiohttp import web from aiohttp import web
from cbpi_api import request_mapping from cbpi.api import *
from http_endpoints.http_curd_endpoints import HttpCrudEndpoints from cbpi.http_endpoints.http_curd_endpoints import HttpCrudEndpoints
auth = False auth = False

View file

@ -1,7 +1,7 @@
from aiohttp import web from aiohttp import web
from aiohttp_auth import auth from aiohttp_auth import auth
from cbpi_api import * from cbpi.api import *
class Login(): class Login():

View file

@ -1,8 +1,6 @@
from aiohttp import web from cbpi.api import request_mapping
from cbpi_api import request_mapping
from cbpi_api.exceptions import CBPiException
from http_endpoints.http_curd_endpoints import HttpCrudEndpoints from cbpi.http_endpoints.http_curd_endpoints import HttpCrudEndpoints
class SensorHttpEndpoints(HttpCrudEndpoints): class SensorHttpEndpoints(HttpCrudEndpoints):

View file

@ -1,8 +1,8 @@
from aiohttp import web from aiohttp import web
from cbpi_api import request_mapping from cbpi.api import *
from cbpi_api.exceptions import CBPiException
from http_endpoints.http_curd_endpoints import HttpCrudEndpoints
from cbpi.http_endpoints.http_curd_endpoints import HttpCrudEndpoints
class StepHttpEndpoints(HttpCrudEndpoints): class StepHttpEndpoints(HttpCrudEndpoints):

View file

@ -1,5 +1,5 @@
from aiojobs.aiohttp import get_scheduler_from_app from aiojobs.aiohttp import get_scheduler_from_app
from core.mqtt_matcher import MQTTMatcher from cbpi.mqtt_matcher import MQTTMatcher
from hbmqtt.broker import Broker from hbmqtt.broker import Broker
from hbmqtt.client import MQTTClient from hbmqtt.client import MQTTClient
from hbmqtt.mqtt.constants import QOS_1, QOS_0 from hbmqtt.mqtt.constants import QOS_1, QOS_0

1
cbpi/utils/__init__.py Normal file
View file

@ -0,0 +1 @@
from cbpi.utils.utils import *

View file

@ -4,7 +4,7 @@ class ComplexEncoder(JSONEncoder):
def default(self, obj): def default(self, obj):
from core.database.orm_framework import DBModel from cbpi.database.orm_framework import DBModel
try: try:
if isinstance(obj, DBModel): if isinstance(obj, DBModel):

View file

@ -1,4 +1,4 @@
from core.utils.encoder import ComplexEncoder from cbpi.utils.encoder import ComplexEncoder
__all__ = ['load_config',"json_dumps"] __all__ = ['load_config',"json_dumps"]

View file

@ -4,10 +4,10 @@ from collections import defaultdict
import aiohttp import aiohttp
from aiohttp import web from aiohttp import web
from cbpi_api import * from cbpi.api import *
from voluptuous import Schema from voluptuous import Schema
from utils import json_dumps from cbpi.utils import json_dumps
class CBPiWebSocket: class CBPiWebSocket:
@ -22,7 +22,7 @@ class CBPiWebSocket:
@on_event(topic="#") @on_event(topic="#")
async def listen(self, topic, **kwargs): async def listen(self, topic, **kwargs):
data = dict(topic=topic, data=dict(**kwargs)) data = dict(topic=topic, data=dict(**kwargs))
self.logger.info("PUSH %s " % data) self.logger.debug("PUSH %s " % data)
self.send(data) self.send(data)
def send(self, data): def send(self, data):

View file

@ -1,3 +1 @@
cbpi-actor
cbpi-actor
cbpi-actor cbpi-actor

View file

@ -1 +0,0 @@
from core.utils.utils import *

Binary file not shown.

View file

@ -1,34 +0,0 @@
2019-01-04 00:44:35,10
2019-01-04 00:44:40,10
2019-01-04 00:44:45,10
2019-01-04 00:44:50,10
2019-01-04 00:44:55,10
2019-01-04 00:45:00,10
2019-01-04 00:45:05,10
2019-01-04 00:45:10,10
2019-01-04 00:45:15,10
2019-01-04 00:45:20,10
2019-01-04 00:45:25,10
2019-01-04 00:45:30,10
2019-01-04 00:45:35,10
2019-01-04 00:45:40,10
2019-01-04 00:45:45,10
2019-01-04 00:45:50,10
2019-01-04 00:45:55,10
2019-01-04 00:46:00,10
2019-01-04 00:46:05,10
2019-01-04 00:46:10,10
2019-01-04 00:46:15,10
2019-01-04 00:46:20,10
2019-01-04 00:46:31,10
2019-01-04 00:46:36,10
2019-01-04 00:46:41,10
2019-01-04 00:46:46,10
2019-01-04 00:46:51,10
2019-01-04 00:46:56,10
2019-01-04 00:47:01,10
2019-01-04 00:47:06,10
2019-01-04 00:47:11,10
2019-01-04 00:47:16,10
2019-01-04 00:47:21,10
2019-01-04 00:47:26,10

View file

@ -1,86 +0,0 @@
2019-01-04 00:19:10,10
2019-01-04 00:19:15,10
2019-01-04 00:19:20,10
2019-01-04 00:19:25,10
2019-01-04 00:19:30,10
2019-01-04 00:19:48,10
2019-01-04 00:19:53,10
2019-01-04 00:20:04,10
2019-01-04 00:20:09,10
2019-01-04 00:20:14,10
2019-01-04 00:20:19,10
2019-01-04 00:20:24,10
2019-01-04 00:20:29,10
2019-01-04 00:20:34,10
2019-01-04 00:20:39,10
2019-01-04 00:20:44,10
2019-01-04 00:20:49,10
2019-01-04 00:20:54,10
2019-01-04 00:20:59,10
2019-01-04 00:38:43,10
2019-01-04 00:38:48,10
2019-01-04 00:38:53,10
2019-01-04 00:38:58,10
2019-01-04 00:39:03,10
2019-01-04 00:39:08,10
2019-01-04 00:39:13,10
2019-01-04 00:39:18,10
2019-01-04 00:39:23,10
2019-01-04 00:39:28,10
2019-01-04 00:39:33,10
2019-01-04 00:39:38,10
2019-01-04 00:39:45,10
2019-01-04 00:39:54,10
2019-01-04 00:39:59,10
2019-01-04 00:40:04,10
2019-01-04 00:40:09,10
2019-01-04 00:40:14,10
2019-01-04 00:40:21,10
2019-01-04 00:40:31,10
2019-01-04 00:40:36,10
2019-01-04 00:40:41,10
2019-01-04 00:40:46,10
2019-01-04 00:40:51,10
2019-01-04 00:40:56,10
2019-01-04 00:41:01,10
2019-01-04 00:41:06,10
2019-01-04 00:41:11,10
2019-01-04 00:41:16,10
2019-01-04 00:41:21,10
2019-01-04 00:41:26,10
2019-01-04 00:41:31,10
2019-01-04 00:41:36,10
2019-01-04 00:41:41,10
2019-01-04 00:41:46,10
2019-01-04 00:41:51,10
2019-01-04 00:41:56,10
2019-01-04 00:42:01,10
2019-01-04 00:42:06,10
2019-01-04 00:42:11,10
2019-01-04 00:42:16,10
2019-01-04 00:42:21,10
2019-01-04 00:42:26,10
2019-01-04 00:42:31,10
2019-01-04 00:42:36,10
2019-01-04 00:42:41,10
2019-01-04 00:42:46,10
2019-01-04 00:42:51,10
2019-01-04 00:42:56,10
2019-01-04 00:43:05,10
2019-01-04 00:43:10,10
2019-01-04 00:43:15,10
2019-01-04 00:43:20,10
2019-01-04 00:43:25,10
2019-01-04 00:43:30,10
2019-01-04 00:43:35,10
2019-01-04 00:43:40,10
2019-01-04 00:43:45,10
2019-01-04 00:43:50,10
2019-01-04 00:43:55,10
2019-01-04 00:44:00,10
2019-01-04 00:44:05,10
2019-01-04 00:44:10,10
2019-01-04 00:44:15,10
2019-01-04 00:44:20,10
2019-01-04 00:44:25,10
2019-01-04 00:44:30,10

View file

@ -1,5 +0,0 @@
2019-01-04 00:19:10,10
2019-01-04 00:19:15,10
2019-01-04 00:19:20,10
2019-01-04 00:19:25,10
2019-01-04 00:19:30,10

View file

@ -1,5 +0,0 @@
2019-01-04 00:19:10,10
2019-01-04 00:19:15,10
2019-01-04 00:19:20,10
2019-01-04 00:19:25,10
2019-01-04 00:19:30,10

View file

@ -1,5 +0,0 @@
2019-01-04 00:19:10,10
2019-01-04 00:19:15,10
2019-01-04 00:19:20,10
2019-01-04 00:19:25,10
2019-01-04 00:19:30,10

View file

@ -1,5 +0,0 @@
2019-01-04 00:19:10,10
2019-01-04 00:19:15,10
2019-01-04 00:19:20,10
2019-01-04 00:19:25,10
2019-01-04 00:19:30,10

View file

@ -1,5 +0,0 @@
2019-01-04 00:19:10,10
2019-01-04 00:19:15,10
2019-01-04 00:19:20,10
2019-01-04 00:19:25,10
2019-01-04 00:19:30,10

View file

@ -1,5 +0,0 @@
2019-01-04 00:19:10,10
2019-01-04 00:19:15,10
2019-01-04 00:19:20,10
2019-01-04 00:19:25,10
2019-01-04 00:19:30,10

View file

@ -1,5 +0,0 @@
2019-01-04 00:19:10,10
2019-01-04 00:19:15,10
2019-01-04 00:19:20,10
2019-01-04 00:19:25,10
2019-01-04 00:19:30,10

View file

@ -1,5 +0,0 @@
2019-01-04 00:19:10,10
2019-01-04 00:19:15,10
2019-01-04 00:19:20,10
2019-01-04 00:19:25,10
2019-01-04 00:19:30,10

View file

@ -1,5 +0,0 @@
2019-01-04 00:19:10,10
2019-01-04 00:19:15,10
2019-01-04 00:19:20,10
2019-01-04 00:19:25,10
2019-01-04 00:19:30,10

View file

@ -1,23 +0,0 @@
2019-01-02 18:49:55,10
2019-01-02 18:49:56,10
2019-01-02 18:49:57,10
2019-01-02 18:51:25,10
2019-01-02 18:51:26,10
2019-01-02 18:51:27,10
2019-01-02 18:51:28,10
2019-01-02 18:51:40,10
2019-01-02 18:51:41,10
2019-01-02 18:51:42,10
2019-01-02 18:51:43,10
2019-01-02 18:51:49,10
2019-01-02 18:51:50,10
2019-01-02 18:51:51,10
2019-01-02 18:51:52,10
2019-01-02 18:53:09,10
2019-01-02 18:53:10,10
2019-01-02 18:53:11,10
2019-01-02 18:53:12,10
2019-01-02 19:03:29,10
2019-01-02 19:03:30,10
2019-01-02 19:03:31,10
2019-01-02 19:03:32,10

View file

@ -1,86 +0,0 @@
2019-01-02 17:05:13,10
2019-01-02 17:05:14,10
2019-01-02 17:05:15,10
2019-01-02 18:02:23,10
2019-01-02 18:02:24,10
2019-01-02 18:02:25,10
2019-01-02 18:02:26,10
2019-01-02 18:21:31,10
2019-01-02 18:21:32,10
2019-01-02 18:21:33,10
2019-01-02 18:21:34,10
2019-01-02 18:21:47,10
2019-01-02 18:21:48,10
2019-01-02 18:21:49,10
2019-01-02 18:21:50,10
2019-01-02 18:21:51,10
2019-01-02 18:29:16,10
2019-01-02 18:29:17,10
2019-01-02 18:29:18,10
2019-01-02 18:29:19,10
2019-01-02 18:31:37,10
2019-01-02 18:31:38,10
2019-01-02 18:31:39,10
2019-01-02 18:31:40,10
2019-01-02 18:32:06,10
2019-01-02 18:32:07,10
2019-01-02 18:32:08,10
2019-01-02 18:32:09,10
2019-01-02 18:32:59,10
2019-01-02 18:33:00,10
2019-01-02 18:33:01,10
2019-01-02 18:33:02,10
2019-01-02 18:33:33,10
2019-01-02 18:33:34,10
2019-01-02 18:33:35,10
2019-01-02 18:33:36,10
2019-01-02 18:33:37,10
2019-01-02 18:34:07,10
2019-01-02 18:34:08,10
2019-01-02 18:34:09,10
2019-01-02 18:34:10,10
2019-01-02 18:37:59,10
2019-01-02 18:38:00,10
2019-01-02 18:38:01,10
2019-01-02 18:38:02,10
2019-01-02 18:38:48,10
2019-01-02 18:38:49,10
2019-01-02 18:38:50,10
2019-01-02 18:38:51,10
2019-01-02 18:38:52,10
2019-01-02 18:40:45,10
2019-01-02 18:40:46,10
2019-01-02 18:40:47,10
2019-01-02 18:40:48,10
2019-01-02 18:40:56,10
2019-01-02 18:40:57,10
2019-01-02 18:40:58,10
2019-01-02 18:40:59,10
2019-01-02 18:41:00,10
2019-01-02 18:41:50,10
2019-01-02 18:41:51,10
2019-01-02 18:41:52,10
2019-01-02 18:41:53,10
2019-01-02 18:43:39,10
2019-01-02 18:43:40,10
2019-01-02 18:43:41,10
2019-01-02 18:43:42,10
2019-01-02 18:44:37,10
2019-01-02 18:44:38,10
2019-01-02 18:44:39,10
2019-01-02 18:44:40,10
2019-01-02 18:44:41,10
2019-01-02 18:45:17,10
2019-01-02 18:45:18,10
2019-01-02 18:45:19,10
2019-01-02 18:45:20,10
2019-01-02 18:47:19,10
2019-01-02 18:47:20,10
2019-01-02 18:47:21,10
2019-01-02 18:47:22,10
2019-01-02 18:47:23,10
2019-01-02 18:49:03,10
2019-01-02 18:49:05,10
2019-01-02 18:49:06,10
2019-01-02 18:49:07,10
2019-01-02 18:49:54,10

View file

@ -1,86 +0,0 @@
2019-01-02 11:15:04,10
2019-01-02 11:16:21,10
2019-01-02 11:16:22,10
2019-01-02 11:16:23,10
2019-01-02 11:16:24,10
2019-01-02 11:16:25,10
2019-01-02 11:18:51,10
2019-01-02 11:18:52,10
2019-01-02 11:18:53,10
2019-01-02 11:18:54,10
2019-01-02 16:19:57,10
2019-01-02 16:19:58,10
2019-01-02 16:19:59,10
2019-01-02 16:20:00,10
2019-01-02 16:20:01,10
2019-01-02 16:21:08,10
2019-01-02 16:21:09,10
2019-01-02 16:21:10,10
2019-01-02 16:21:11,10
2019-01-02 16:21:25,10
2019-01-02 16:21:26,10
2019-01-02 16:21:27,10
2019-01-02 16:21:28,10
2019-01-02 16:22:24,10
2019-01-02 16:22:25,10
2019-01-02 16:22:26,10
2019-01-02 16:22:27,10
2019-01-02 16:23:42,10
2019-01-02 16:23:43,10
2019-01-02 16:23:44,10
2019-01-02 16:23:45,10
2019-01-02 16:23:46,10
2019-01-02 16:24:55,10
2019-01-02 16:24:56,10
2019-01-02 16:24:57,10
2019-01-02 16:24:58,10
2019-01-02 16:24:59,10
2019-01-02 16:25:20,10
2019-01-02 16:25:21,10
2019-01-02 16:25:22,10
2019-01-02 16:25:23,10
2019-01-02 16:25:24,10
2019-01-02 16:26:25,10
2019-01-02 16:26:26,10
2019-01-02 16:26:27,10
2019-01-02 16:26:28,10
2019-01-02 16:52:03,10
2019-01-02 16:52:04,10
2019-01-02 16:52:05,10
2019-01-02 16:52:06,10
2019-01-02 16:52:07,10
2019-01-02 16:52:47,10
2019-01-02 16:52:48,10
2019-01-02 16:52:49,10
2019-01-02 16:52:50,10
2019-01-02 16:53:19,10
2019-01-02 16:53:20,10
2019-01-02 16:53:22,10
2019-01-02 16:53:23,10
2019-01-02 16:53:46,10
2019-01-02 16:53:47,10
2019-01-02 16:53:48,10
2019-01-02 16:53:49,10
2019-01-02 17:00:57,10
2019-01-02 17:00:58,10
2019-01-02 17:00:59,10
2019-01-02 17:01:00,10
2019-01-02 17:01:06,10
2019-01-02 17:01:07,10
2019-01-02 17:01:08,10
2019-01-02 17:01:09,10
2019-01-02 17:02:14,10
2019-01-02 17:02:15,10
2019-01-02 17:02:16,10
2019-01-02 17:02:17,10
2019-01-02 17:02:18,10
2019-01-02 17:02:34,10
2019-01-02 17:02:35,10
2019-01-02 17:02:36,10
2019-01-02 17:02:37,10
2019-01-02 17:02:38,10
2019-01-02 17:02:48,10
2019-01-02 17:02:49,10
2019-01-02 17:02:50,10
2019-01-02 17:02:51,10
2019-01-02 17:05:12,10

View file

@ -1,86 +0,0 @@
2019-01-01 16:29:39,10
2019-01-01 16:29:40,10
2019-01-01 16:29:41,10
2019-01-01 16:29:42,10
2019-01-01 16:31:21,10
2019-01-01 16:31:22,10
2019-01-01 16:31:23,10
2019-01-01 16:31:24,10
2019-01-01 16:49:40,10
2019-01-01 16:49:41,10
2019-01-01 16:49:42,10
2019-01-01 16:49:43,10
2019-01-01 16:51:23,10
2019-01-01 16:51:24,10
2019-01-01 16:51:25,10
2019-01-01 16:51:26,10
2019-01-02 10:46:44,10
2019-01-02 10:46:45,10
2019-01-02 10:46:46,10
2019-01-02 10:46:47,10
2019-01-02 10:46:48,10
2019-01-02 10:48:16,10
2019-01-02 10:48:17,10
2019-01-02 10:48:18,10
2019-01-02 10:48:19,10
2019-01-02 10:48:41,10
2019-01-02 10:48:42,10
2019-01-02 10:48:43,10
2019-01-02 10:48:44,10
2019-01-02 10:48:45,10
2019-01-02 10:49:30,10
2019-01-02 10:49:31,10
2019-01-02 10:49:32,10
2019-01-02 10:49:33,10
2019-01-02 10:49:51,10
2019-01-02 10:49:52,10
2019-01-02 10:49:53,10
2019-01-02 10:49:54,10
2019-01-02 10:56:09,10
2019-01-02 10:56:10,10
2019-01-02 10:56:11,10
2019-01-02 10:56:12,10
2019-01-02 10:56:35,10
2019-01-02 10:56:36,10
2019-01-02 10:56:37,10
2019-01-02 10:56:38,10
2019-01-02 11:01:55,10
2019-01-02 11:01:56,10
2019-01-02 11:01:57,10
2019-01-02 11:01:58,10
2019-01-02 11:03:23,10
2019-01-02 11:03:24,10
2019-01-02 11:03:25,10
2019-01-02 11:03:26,10
2019-01-02 11:04:47,10
2019-01-02 11:04:48,10
2019-01-02 11:04:49,10
2019-01-02 11:04:50,10
2019-01-02 11:05:22,10
2019-01-02 11:05:23,10
2019-01-02 11:05:24,10
2019-01-02 11:05:25,10
2019-01-02 11:06:54,10
2019-01-02 11:06:55,10
2019-01-02 11:06:56,10
2019-01-02 11:06:57,10
2019-01-02 11:08:16,10
2019-01-02 11:08:17,10
2019-01-02 11:08:18,10
2019-01-02 11:08:19,10
2019-01-02 11:09:04,10
2019-01-02 11:09:05,10
2019-01-02 11:09:06,10
2019-01-02 11:09:07,10
2019-01-02 11:10:59,10
2019-01-02 11:11:00,10
2019-01-02 11:11:01,10
2019-01-02 11:11:02,10
2019-01-02 11:11:03,10
2019-01-02 11:14:02,10
2019-01-02 11:14:03,10
2019-01-02 11:14:04,10
2019-01-02 11:14:05,10
2019-01-02 11:15:01,10
2019-01-02 11:15:02,10
2019-01-02 11:15:03,10

View file

@ -6,66 +6,6 @@ aiohttp-session==2.7.0
aiohttp-swagger==1.0.5 aiohttp-swagger==1.0.5
aiojobs==0.2.2 aiojobs==0.2.2
aiosqlite==0.7.0 aiosqlite==0.7.0
alabaster==0.7.12
asn1crypto==0.24.0
async-timeout==3.0.1
asynctest==0.12.2
atomicwrites==1.2.1
attrs==18.2.0
Babel==2.6.0
beautifulsoup4==4.6.3
bleach==3.0.2
bs4==0.0.1
cbpi-api==4.0.1
CBPiActor1==4.0.3
certifi==2018.10.15
cffi==1.11.5
chardet==3.0.4
Click==7.0
coverage==4.5.2
cryptography==2.3.1 cryptography==2.3.1
docopt==0.6.2
docutils==0.14
gTTS==2.0.1
gTTS-token==1.1.3
hbmqtt==0.9.4
idna==2.7
idna-ssl==1.1.0
imagesize==1.1.0
Jinja2==2.10
MarkupSafe==1.0
more-itertools==4.3.0
multidict==4.4.2
packaging==18.0
passlib==1.7.1
pkginfo==1.4.2
pluggy==0.7.1
py==1.7.0
pycparser==2.19
pyfiglet==0.7.6
pygame==1.9.4
Pygments==2.2.0
pync==2.0.3
pyparsing==2.3.0
pytest==3.8.2
pytest-aiohttp==0.3.0
python-dateutil==2.7.5
pytz==2018.7
PyYAML==3.13
readme-renderer==24.0
requests==2.20.1
requests-toolbelt==0.8.0
six==1.11.0
snowballstemmer==1.2.1
Sphinx==1.8.2
sphinx-rtd-theme==0.4.2
sphinxcontrib-websupport==1.1.0
ticket-auth==0.1.4
tqdm==4.28.1
transitions==0.6.8
twine==1.12.1
urllib3==1.24.1
voluptuous==0.11.5 voluptuous==0.11.5
webencodings==0.5.1 pyfigle==0.7.6
websockets==6.0
yarl==1.2.6

5
run.py
View file

@ -1,4 +1,3 @@
from core.craftbeerpi import CraftBeerPi from cbpi.cli import main
cbpi = CraftBeerPi() main()
cbpi.start()

37
setup.py Normal file
View file

@ -0,0 +1,37 @@
from setuptools import setup, find_packages
setup(name='cbpi',
version='0.0.1',
description='CraftBeerPi API',
author='Manuel Fritsch',
author_email='manuel@craftbeerpi.com',
url='http://web.craftbeerpi.com',
packages=find_packages(),
include_package_data=True,
package_data={
# If any package contains *.txt or *.rst files, include them:
'': ['*.txt', '*.rst', '*.yaml'],
'cbpi': ['*','*.txt', '*.rst', '*.yaml']},
install_requires=[
"aiohttp==3.4.4",
"aiohttp-auth==0.1.1",
"aiohttp-route-decorator==0.1.4",
"aiohttp-security==0.4.0",
"aiohttp-session==2.7.0",
"aiohttp-swagger==1.0.5",
"aiojobs==0.2.2",
"aiosqlite==0.7.0",
"cryptography==2.3.1",
"voluptuous==0.11.5",
"pyfiglet==0.7.6"
],
dependency_links=[
'https://testpypi.python.org/pypi'
],
entry_points = {
"console_scripts": [
"cbpi=cbpi.cli:main",
]
}
)

View file

@ -2,7 +2,7 @@ from unittest import mock
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
from core.craftbeerpi import CraftBeerPi from cbpi.craftbeerpi import CraftBeerPi
class ActorTestCase(AioHTTPTestCase): class ActorTestCase(AioHTTPTestCase):

View file

@ -2,9 +2,9 @@ import time
import aiosqlite import aiosqlite
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
from cbpi_api.config import ConfigType from cbpi.api.config import ConfigType
from core.craftbeerpi import CraftBeerPi from cbpi.craftbeerpi import CraftBeerPi
class ConfigTestCase(AioHTTPTestCase): class ConfigTestCase(AioHTTPTestCase):

View file

@ -1,7 +1,7 @@
import aiohttp import aiohttp
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
from core.craftbeerpi import CraftBeerPi from cbpi.craftbeerpi import CraftBeerPi
class DashboardTestCase(AioHTTPTestCase): class DashboardTestCase(AioHTTPTestCase):

View file

@ -1,6 +1,6 @@
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
from core.craftbeerpi import CraftBeerPi from cbpi.craftbeerpi import CraftBeerPi
class IndexTestCase(AioHTTPTestCase): class IndexTestCase(AioHTTPTestCase):

View file

@ -1,6 +1,6 @@
import asyncio import asyncio
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
from core.craftbeerpi import CraftBeerPi from cbpi.craftbeerpi import CraftBeerPi
class KettleTestCase(AioHTTPTestCase): class KettleTestCase(AioHTTPTestCase):

View file

@ -1,7 +1,7 @@
import aiohttp import aiohttp
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
from core.craftbeerpi import CraftBeerPi from cbpi.craftbeerpi import CraftBeerPi
class NotificationTestCase(AioHTTPTestCase): class NotificationTestCase(AioHTTPTestCase):

View file

@ -1,6 +1,6 @@
import asyncio import asyncio
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
from core.craftbeerpi import CraftBeerPi from cbpi.craftbeerpi import CraftBeerPi
class SensorTestCase(AioHTTPTestCase): class SensorTestCase(AioHTTPTestCase):

Some files were not shown because too many files have changed in this diff Show more