mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-28 09:44:20 +01:00
refactoring job controller
This commit is contained in:
parent
ce2d942771
commit
e0bec43960
28 changed files with 636 additions and 688 deletions
File diff suppressed because it is too large
Load diff
|
@ -8,21 +8,20 @@ from typing import Iterable, Callable
|
||||||
from cbpi_api import *
|
from cbpi_api import *
|
||||||
|
|
||||||
|
|
||||||
class WebSocket:
|
class CBPiWebSocket:
|
||||||
def __init__(self, cbpi) -> None:
|
def __init__(self, cbpi) -> None:
|
||||||
self.cbpi = cbpi
|
self.cbpi = cbpi
|
||||||
self._callbacks = defaultdict(set)
|
self._callbacks = defaultdict(set)
|
||||||
self._clients = weakref.WeakSet()
|
self._clients = weakref.WeakSet()
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
self.cbpi.app.add_routes([web.get('/ws', self.websocket_handler)])
|
self.cbpi.app.add_routes([web.get('/ws', self.websocket_handler)])
|
||||||
|
self.cbpi.bus.register_object(self)
|
||||||
|
|
||||||
@on_event(topic="#")
|
@on_event(topic="#")
|
||||||
async def listen(self, topic, **kwargs):
|
async def listen(self, topic, **kwargs):
|
||||||
from core.utils.encoder import ComplexEncoder
|
from core.utils.encoder import ComplexEncoder
|
||||||
data = json.dumps(dict(topic=topic, data=dict(**kwargs)),skipkeys=True, check_circular=True, cls=ComplexEncoder)
|
data = json.dumps(dict(topic=topic, data=dict(**kwargs)),skipkeys=True, check_circular=True, cls=ComplexEncoder)
|
||||||
self.logger.info("PUSH %s " % data)
|
self.logger.info("PUSH %s " % data)
|
||||||
|
|
||||||
|
|
||||||
self.send(data)
|
self.send(data)
|
||||||
|
|
||||||
def send(self, data):
|
def send(self, data):
|
||||||
|
@ -33,10 +32,13 @@ class WebSocket:
|
||||||
await ws.send_str(data)
|
await ws.send_str(data)
|
||||||
self.cbpi.app.loop.create_task(send_data(ws, data))
|
self.cbpi.app.loop.create_task(send_data(ws, data))
|
||||||
|
|
||||||
|
|
||||||
def add_callback(self, func: Callable, event: str) -> None:
|
def add_callback(self, func: Callable, event: str) -> None:
|
||||||
self._callbacks[event].add(func)
|
self._callbacks[event].add(func)
|
||||||
|
|
||||||
|
def register_object(self, obj):
|
||||||
|
for method in [getattr(obj, f) for f in dir(obj) if callable(getattr(obj, f)) and hasattr(getattr(obj, f), "ws")]:
|
||||||
|
self.add_callback(method, method.__getattribute__("key"))
|
||||||
|
|
||||||
async def emit(self, event: str, *args, **kwargs) -> None:
|
async def emit(self, event: str, *args, **kwargs) -> None:
|
||||||
for func in self._event_funcs(event):
|
for func in self._event_funcs(event):
|
||||||
await func(*args, **kwargs)
|
await func(*args, **kwargs)
|
|
@ -83,7 +83,9 @@ class ActorController(ActorHttp, CRUDController):
|
||||||
await self._init_actor(value)
|
await self._init_actor(value)
|
||||||
|
|
||||||
async def _init_actor(self, actor):
|
async def _init_actor(self, actor):
|
||||||
|
print("INIT ACXTOR")
|
||||||
if actor.type in self.types:
|
if actor.type in self.types:
|
||||||
|
print("INIT ONE ACTOT")
|
||||||
cfg = actor.config.copy()
|
cfg = actor.config.copy()
|
||||||
cfg.update(dict(cbpi=self.cbpi, id=id, name=actor.name))
|
cfg.update(dict(cbpi=self.cbpi, id=id, name=actor.name))
|
||||||
clazz = self.types[actor.type]["class"];
|
clazz = self.types[actor.type]["class"];
|
||||||
|
@ -91,7 +93,7 @@ class ActorController(ActorHttp, CRUDController):
|
||||||
self.cache[actor.id].instance.init()
|
self.cache[actor.id].instance.init()
|
||||||
await self.cbpi.bus.fire(topic="actor/%s/initialized" % actor.id, id=actor.id)
|
await self.cbpi.bus.fire(topic="actor/%s/initialized" % actor.id, id=actor.id)
|
||||||
else:
|
else:
|
||||||
|
print("NOT FOUND")
|
||||||
self.logger.error("Actor type '%s' not found (Available Actor Types: %s)" % (actor.type, ', '.join(self.types.keys())))
|
self.logger.error("Actor type '%s' not found (Available Actor Types: %s)" % (actor.type, ', '.join(self.types.keys())))
|
||||||
|
|
||||||
|
|
||||||
|
|
42
core/controller/job_controller.py
Normal file
42
core/controller/job_controller.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import asyncio
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from job.aiohttp import setup, get_scheduler_from_app
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
class JobController(object):
|
||||||
|
|
||||||
|
def __init__(self, cbpi):
|
||||||
|
self.cbpi = cbpi
|
||||||
|
|
||||||
|
async def init(self):
|
||||||
|
await setup(self.cbpi.app, self.cbpi)
|
||||||
|
|
||||||
|
def register_background_task(self, obj):
|
||||||
|
'''
|
||||||
|
This method parses all method for the @background_task decorator and registers the background job
|
||||||
|
which will be launched during start up of the server
|
||||||
|
|
||||||
|
:param obj: the object to parse
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
|
|
||||||
|
async def job_loop(app, name, interval, method):
|
||||||
|
logger.info("Start Background Task %s Interval %s Method %s" % (name, interval, method))
|
||||||
|
while True:
|
||||||
|
logger.debug("Execute Task %s - interval(%s second(s)" % (name, interval))
|
||||||
|
await asyncio.sleep(interval)
|
||||||
|
await method()
|
||||||
|
|
||||||
|
async def spawn_job(app):
|
||||||
|
scheduler = get_scheduler_from_app(self.cbpi.app)
|
||||||
|
for method in [getattr(obj, f) for f in dir(obj) if callable(getattr(obj, f)) and hasattr(getattr(obj, f), "background_task")]:
|
||||||
|
name = method.__getattribute__("name")
|
||||||
|
interval = method.__getattribute__("interval")
|
||||||
|
job = await scheduler.spawn(job_loop(self.app, name, interval, method), name, "background")
|
||||||
|
|
||||||
|
self.cbpi.app.on_startup.append(spawn_job)
|
||||||
|
|
||||||
|
async def start_job(self, method, name, type):
|
||||||
|
scheduler = get_scheduler_from_app(self.cbpi.app)
|
||||||
|
return await scheduler.spawn(method, name, type)
|
|
@ -35,7 +35,7 @@ class KettleHttp(HttpAPI):
|
||||||
else:
|
else:
|
||||||
return web.Response(status=404, text=result[1])
|
return web.Response(status=404, text=result[1])
|
||||||
|
|
||||||
class KettleController(CRUDController):
|
class KettleController(CRUDController, KettleHttp):
|
||||||
'''
|
'''
|
||||||
The main kettle controller
|
The main kettle controller
|
||||||
'''
|
'''
|
||||||
|
@ -45,9 +45,8 @@ class KettleController(CRUDController):
|
||||||
super(KettleController, self).__init__(cbpi)
|
super(KettleController, self).__init__(cbpi)
|
||||||
self.cbpi = cbpi
|
self.cbpi = cbpi
|
||||||
self.types = {}
|
self.types = {}
|
||||||
self.cbpi.register(self, None)
|
self.cbpi.register(self, "/kettle")
|
||||||
self.http = KettleHttp(cbpi)
|
|
||||||
self.cbpi.register(self.http, "/kettle")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,7 +112,7 @@ class KettleController(CRUDController):
|
||||||
cfg.update(dict(cbpi=self.cbpi))
|
cfg.update(dict(cbpi=self.cbpi))
|
||||||
kettle.instance = clazz(**cfg)
|
kettle.instance = clazz(**cfg)
|
||||||
|
|
||||||
await self.cbpi.start_job(kettle.instance.run(), "Kettle_logic_%s" % kettle.id, "kettle_logic%s"%id)
|
await self.cbpi.job.start_job(kettle.instance.run(), "Kettle_logic_%s" % kettle.id, "kettle_logic%s"%id)
|
||||||
else:
|
else:
|
||||||
kettle.instance.running = False
|
kettle.instance.running = False
|
||||||
kettle.instance = None
|
kettle.instance = None
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
from logging.handlers import TimedRotatingFileHandler
|
|
||||||
from core.utils.encoder import ComplexEncoder
|
|
||||||
from core.job.aiohttp import get_scheduler_from_app
|
|
||||||
from cbpi_api import *
|
|
||||||
from core.controller.crud_controller import CRUDController
|
from core.controller.crud_controller import CRUDController
|
||||||
from core.database.model import SensorModel
|
from core.database.model import SensorModel
|
||||||
from core.http_endpoints.http_api import HttpAPI
|
from core.http_endpoints.http_api import HttpAPI
|
||||||
|
from core.job.aiohttp import get_scheduler_from_app
|
||||||
|
from core.utils.encoder import ComplexEncoder
|
||||||
|
|
||||||
|
|
||||||
class SensorController(CRUDController, HttpAPI):
|
class SensorController(CRUDController, HttpAPI):
|
||||||
|
@ -19,7 +17,7 @@ class SensorController(CRUDController, HttpAPI):
|
||||||
self.cbpi.register(self, "/sensor")
|
self.cbpi.register(self, "/sensor")
|
||||||
self.service = self
|
self.service = self
|
||||||
self.types = {}
|
self.types = {}
|
||||||
|
self.logger = logging.getLogger(__name__)
|
||||||
self.sensors = {}
|
self.sensors = {}
|
||||||
|
|
||||||
def info(self):
|
def info(self):
|
||||||
|
@ -34,8 +32,7 @@ class SensorController(CRUDController, HttpAPI):
|
||||||
'''
|
'''
|
||||||
await super(SensorController, self).init()
|
await super(SensorController, self).init()
|
||||||
|
|
||||||
for name, clazz in self.types.items():
|
|
||||||
pass
|
|
||||||
|
|
||||||
for id, value in self.cache.items():
|
for id, value in self.cache.items():
|
||||||
if value.type in self.types:
|
if value.type in self.types:
|
||||||
|
@ -45,7 +42,8 @@ class SensorController(CRUDController, HttpAPI):
|
||||||
self.cache[id].instance = clazz(**cfg)
|
self.cache[id].instance = clazz(**cfg)
|
||||||
scheduler = get_scheduler_from_app(self.cbpi.app)
|
scheduler = get_scheduler_from_app(self.cbpi.app)
|
||||||
self.cache[id].instance.job = await scheduler.spawn(self.cache[id].instance.run(self.cbpi), value.name, "sensor")
|
self.cache[id].instance.job = await scheduler.spawn(self.cache[id].instance.run(self.cbpi), value.name, "sensor")
|
||||||
|
else:
|
||||||
|
self.logger.error("Sensor type '%s' not found (Available Sensor Types: %s)" % (value.type, ', '.join(self.types.keys())))
|
||||||
|
|
||||||
async def get_value(self, id):
|
async def get_value(self, id):
|
||||||
return self.cache[id].instance.value
|
return self.cache[id].instance.value
|
|
@ -62,7 +62,7 @@ class StepController(HttpAPI, CRUDController):
|
||||||
cfg.update(dict(cbpi=self.cbpi, id=step.id, managed_fields=self._get_manged_fields_as_array(step_type)))
|
cfg.update(dict(cbpi=self.cbpi, id=step.id, managed_fields=self._get_manged_fields_as_array(step_type)))
|
||||||
|
|
||||||
self.current_step = step_type["class"](**cfg)
|
self.current_step = step_type["class"](**cfg)
|
||||||
self.current_job = await self.cbpi.start_job(self.current_step.run(), step.name, "step")
|
self.current_job = await self.cbpi.job.start_job(self.current_step.run(), step.name, "step")
|
||||||
|
|
||||||
@request_mapping(path="/action", auth_required=False)
|
@request_mapping(path="/action", auth_required=False)
|
||||||
async def http_action(self, request):
|
async def http_action(self, request):
|
||||||
|
@ -255,7 +255,7 @@ class StepController(HttpAPI, CRUDController):
|
||||||
inactive.stepstate = inactive.config
|
inactive.stepstate = inactive.config
|
||||||
inactive.start = int(time.time())
|
inactive.start = int(time.time())
|
||||||
await self.model.update(**inactive.__dict__)
|
await self.model.update(**inactive.__dict__)
|
||||||
self.current_job = await self.cbpi.start_job(self.current_step.run(), inactive.name, "step")
|
self.current_job = await self.cbpi.job.start_job(self.current_step.run(), inactive.name, "step")
|
||||||
else:
|
else:
|
||||||
await self.cbpi.bus.fire("step/berwing/finished")
|
await self.cbpi.bus.fire("step/berwing/finished")
|
||||||
|
|
||||||
|
|
|
@ -1,142 +1,74 @@
|
||||||
import asyncio
|
|
||||||
import logging
|
import logging
|
||||||
from os import urandom
|
|
||||||
import os
|
import os
|
||||||
|
from os import urandom
|
||||||
|
|
||||||
import yaml
|
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
from aiohttp_auth import auth
|
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 controller.job_controller import JobController
|
||||||
|
from core.cbpiwebsocket import CBPiWebSocket
|
||||||
|
from core.controller.actor_controller import ActorController
|
||||||
from core.controller.config_controller import ConfigController
|
from core.controller.config_controller import ConfigController
|
||||||
from core.controller.kettle_controller import KettleController
|
from core.controller.kettle_controller import KettleController
|
||||||
from core.controller.step_controller import StepController
|
|
||||||
from core.extension.comp import MyComp
|
|
||||||
from core.job.aiohttp import setup, get_scheduler_from_app
|
|
||||||
|
|
||||||
from core.controller.actor_controller import ActorController
|
|
||||||
from core.controller.notification_controller import NotificationController
|
from core.controller.notification_controller import NotificationController
|
||||||
from core.controller.plugin_controller import PluginController
|
from core.controller.plugin_controller import PluginController
|
||||||
from core.controller.sensor_controller import SensorController
|
from core.controller.sensor_controller import SensorController
|
||||||
|
from core.controller.step_controller import StepController
|
||||||
from core.controller.system_controller import SystemController
|
from core.controller.system_controller import SystemController
|
||||||
from core.database.model import DBModel
|
from core.database.model import DBModel
|
||||||
from core.eventbus import CBPiEventBus
|
from core.eventbus import CBPiEventBus
|
||||||
from core.http_endpoints.http_login import Login
|
from core.http_endpoints.http_login import Login
|
||||||
from core.utils import *
|
from core.utils import *
|
||||||
from core.websocket import WebSocket
|
|
||||||
from core.utils.encoder import ComplexEncoder
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
This is a module docstring
|
|
||||||
"""
|
|
||||||
|
|
||||||
class CraftBeerPi():
|
class CraftBeerPi():
|
||||||
"""
|
|
||||||
This is a Hello class docstring
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
this_directory = os.path.dirname(__file__)
|
self.static_config = load_config(os.path.join(os.path.dirname(__file__), '../config/config.yaml'))
|
||||||
|
|
||||||
self.config = load_config(os.path.join(this_directory, '../config/config.yaml'))
|
|
||||||
|
|
||||||
logger.info("Init CraftBeerPI")
|
logger.info("Init CraftBeerPI")
|
||||||
|
|
||||||
policy = auth.SessionTktAuthentication(urandom(32), 60, include_ip=True)
|
policy = auth.SessionTktAuthentication(urandom(32), 60, include_ip=True)
|
||||||
middlewares = [web.normalize_path_middleware(), session_middleware(EncryptedCookieStorage(urandom(32))), auth.auth_middleware(policy)]
|
middlewares = [web.normalize_path_middleware(), session_middleware(EncryptedCookieStorage(urandom(32))), auth.auth_middleware(policy)]
|
||||||
self.app = web.Application(middlewares=middlewares)
|
self.app = web.Application(middlewares=middlewares)
|
||||||
|
|
||||||
|
|
||||||
|
self._setup_shutdownhook()
|
||||||
self.initializer = []
|
self.initializer = []
|
||||||
self.shutdown = False
|
|
||||||
|
|
||||||
async def on_cleanup(app):
|
|
||||||
self.shutdown = True
|
|
||||||
|
|
||||||
|
|
||||||
self.app.on_cleanup.append(on_cleanup)
|
|
||||||
|
|
||||||
|
|
||||||
setup(self.app, self)
|
|
||||||
|
|
||||||
|
|
||||||
self.bus = CBPiEventBus(self.app.loop, self)
|
self.bus = CBPiEventBus(self.app.loop, self)
|
||||||
self.ws = WebSocket(self)
|
self.ws = CBPiWebSocket(self)
|
||||||
|
self.job = JobController(self)
|
||||||
self.actor = ActorController(self)
|
self.actor = ActorController(self)
|
||||||
self.sensor = SensorController(self)
|
self.sensor = SensorController(self)
|
||||||
self.plugin = PluginController(self)
|
self.plugin = PluginController(self)
|
||||||
self.system = SystemController(self)
|
self.system = SystemController(self)
|
||||||
self.config2 = ConfigController(self)
|
self.config = ConfigController(self)
|
||||||
self.kettle = KettleController(self)
|
self.kettle = KettleController(self)
|
||||||
self.step = StepController(self)
|
self.step = StepController(self)
|
||||||
self.notification = NotificationController(self)
|
self.notification = NotificationController(self)
|
||||||
self.login = Login(self)
|
self.login = Login(self)
|
||||||
self.register_events(self.ws)
|
|
||||||
|
|
||||||
|
def _setup_shutdownhook(self):
|
||||||
|
self.shutdown = False
|
||||||
|
async def on_cleanup(app):
|
||||||
|
self.shutdown = True
|
||||||
|
|
||||||
def register_events(self, obj):
|
self.app.on_cleanup.append(on_cleanup)
|
||||||
|
|
||||||
for method in [getattr(obj, f) for f in dir(obj) if callable(getattr(obj, f)) and hasattr(getattr(obj, f), "eventbus")]:
|
|
||||||
|
|
||||||
doc = None
|
|
||||||
if method.__doc__ is not None:
|
|
||||||
try:
|
|
||||||
doc = yaml.load(method.__doc__)
|
|
||||||
doc["topic"] = method.__getattribute__("topic")
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self.bus.register(method.__getattribute__("topic"), method)
|
|
||||||
|
|
||||||
def register_background_task(self, obj):
|
|
||||||
'''
|
|
||||||
This method parses all method for the @background_task decorator and registers the background job
|
|
||||||
which will be launched during start up of the server
|
|
||||||
|
|
||||||
:param obj: the object to parse
|
|
||||||
:return:
|
|
||||||
'''
|
|
||||||
|
|
||||||
async def job_loop(app, name, interval, method):
|
|
||||||
logger.info("Start Background Task %s Interval %s Method %s" % (name, interval, method))
|
|
||||||
while True:
|
|
||||||
logger.debug("Execute Task %s - interval(%s second(s)" % (name, interval))
|
|
||||||
await asyncio.sleep(interval)
|
|
||||||
await method()
|
|
||||||
|
|
||||||
async def spawn_job(app):
|
|
||||||
scheduler = get_scheduler_from_app(self.app)
|
|
||||||
for method in [getattr(obj, f) for f in dir(obj) if callable(getattr(obj, f)) and hasattr(getattr(obj, f), "background_task")]:
|
|
||||||
name = method.__getattribute__("name")
|
|
||||||
interval = method.__getattribute__("interval")
|
|
||||||
job = await scheduler.spawn(job_loop(self.app, name, interval, method),name, "background")
|
|
||||||
|
|
||||||
|
|
||||||
self.app.on_startup.append(spawn_job)
|
|
||||||
|
|
||||||
|
|
||||||
def register_on_startup(self, obj):
|
def register_on_startup(self, obj):
|
||||||
|
|
||||||
for method in [getattr(obj, f) for f in dir(obj) if callable(getattr(obj, f)) and hasattr(getattr(obj, f), "on_startup")]:
|
for method in [getattr(obj, f) for f in dir(obj) if callable(getattr(obj, f)) and hasattr(getattr(obj, f), "on_startup")]:
|
||||||
|
|
||||||
name = method.__getattribute__("name")
|
name = method.__getattribute__("name")
|
||||||
order = method.__getattribute__("order")
|
order = method.__getattribute__("order")
|
||||||
|
|
||||||
self.initializer.append(dict(name=name, method=method, order=order))
|
self.initializer.append(dict(name=name, method=method, order=order))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def register_ws(self, obj):
|
|
||||||
if self.ws is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
for method in [getattr(obj, f) for f in dir(obj) if callable(getattr(obj, f)) and hasattr(getattr(obj, f), "ws")]:
|
|
||||||
self.ws.add_callback(method, method.__getattribute__("key"))
|
|
||||||
|
|
||||||
def register(self, obj, url_prefix=None, static=None):
|
def register(self, obj, url_prefix=None, static=None):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@ -147,19 +79,13 @@ class CraftBeerPi():
|
||||||
:return: None
|
:return: None
|
||||||
'''
|
'''
|
||||||
self.register_http_endpoints(obj, url_prefix, static)
|
self.register_http_endpoints(obj, url_prefix, static)
|
||||||
self.register_events(obj)
|
self.bus.register_object(obj)
|
||||||
self.register_ws(obj)
|
self.ws.register_object(obj)
|
||||||
self.register_background_task(obj)
|
self.job.register_background_task(obj)
|
||||||
self.register_on_startup(obj)
|
self.register_on_startup(obj)
|
||||||
|
|
||||||
def register_http_endpoints(self, obj, url_prefix=None, static=None):
|
def register_http_endpoints(self, obj, url_prefix=None, static=None):
|
||||||
'''
|
|
||||||
This method parses the provided object for @request_mapping decorator
|
|
||||||
|
|
||||||
:param obj: the object which will be analyzed
|
|
||||||
:param url_prefix: the prefix which will be used for the all http endpoints of the object
|
|
||||||
:return:
|
|
||||||
'''
|
|
||||||
routes = []
|
routes = []
|
||||||
for method in [getattr(obj, f) for f in dir(obj) if callable(getattr(obj, f)) and hasattr(getattr(obj, f), "route")]:
|
for method in [getattr(obj, f) for f in dir(obj) if callable(getattr(obj, f)) and hasattr(getattr(obj, f), "route")]:
|
||||||
http_method = method.__getattribute__("method")
|
http_method = method.__getattribute__("method")
|
||||||
|
@ -185,11 +111,8 @@ class CraftBeerPi():
|
||||||
"DELETE": add_delete,
|
"DELETE": add_delete,
|
||||||
"PUT": add_put
|
"PUT": add_put
|
||||||
}
|
}
|
||||||
|
|
||||||
switcher[http_method]()
|
switcher[http_method]()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if url_prefix is not None:
|
if url_prefix is not None:
|
||||||
logger.debug("URL Prefix: %s " % (url_prefix,))
|
logger.debug("URL Prefix: %s " % (url_prefix,))
|
||||||
sub = web.Application()
|
sub = web.Application()
|
||||||
|
@ -198,15 +121,8 @@ class CraftBeerPi():
|
||||||
sub.add_routes([web.static('/static', static, show_index=False)])
|
sub.add_routes([web.static('/static', static, show_index=False)])
|
||||||
self.app.add_subapp(url_prefix, sub)
|
self.app.add_subapp(url_prefix, sub)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
|
||||||
self.app.add_routes(routes)
|
self.app.add_routes(routes)
|
||||||
|
|
||||||
|
|
||||||
async def start_job(self, method, name, type):
|
|
||||||
scheduler = get_scheduler_from_app(self.app)
|
|
||||||
return await scheduler.spawn(method, name, type)
|
|
||||||
|
|
||||||
def _swagger_setup(self):
|
def _swagger_setup(self):
|
||||||
'''
|
'''
|
||||||
Internatl method to expose REST API documentation by swagger
|
Internatl method to expose REST API documentation by swagger
|
||||||
|
@ -219,8 +135,8 @@ class CraftBeerPi():
|
||||||
|
|
||||||
setup_swagger(self.app,
|
setup_swagger(self.app,
|
||||||
description=long_description,
|
description=long_description,
|
||||||
title=self.config.get("name", "CraftBeerPi"),
|
title=self.static_config.get("name", "CraftBeerPi"),
|
||||||
api_version=self.config.get("version", ""),
|
api_version=self.static_config.get("version", ""),
|
||||||
contact="info@craftbeerpi.com")
|
contact="info@craftbeerpi.com")
|
||||||
|
|
||||||
def notify(self, key, message, type="info"):
|
def notify(self, key, message, type="info"):
|
||||||
|
@ -234,23 +150,6 @@ class CraftBeerPi():
|
||||||
'''
|
'''
|
||||||
self.bus.sync_fire(topic="notification/%s" % key, key=key, message=message, type=type)
|
self.bus.sync_fire(topic="notification/%s" % key, key=key, message=message, type=type)
|
||||||
|
|
||||||
|
|
||||||
def setup(self):
|
|
||||||
'''
|
|
||||||
This method will start the server
|
|
||||||
|
|
||||||
:return:
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#async def init_database(app):
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#self.app.on_startup.append(call_initializer)
|
|
||||||
|
|
||||||
async def call_initializer(self, app):
|
async def call_initializer(self, app):
|
||||||
self.initializer = sorted(self.initializer, key=lambda k: k['order'])
|
self.initializer = sorted(self.initializer, key=lambda k: k['order'])
|
||||||
for i in self.initializer:
|
for i in self.initializer:
|
||||||
|
@ -260,13 +159,15 @@ class CraftBeerPi():
|
||||||
def _print_logo(self):
|
def _print_logo(self):
|
||||||
from pyfiglet import Figlet
|
from pyfiglet import Figlet
|
||||||
f = Figlet(font='big')
|
f = Figlet(font='big')
|
||||||
logger.info("\n%s" % f.renderText("%s %s" % (self.config.get("name"), self.config.get("version"))))
|
logger.info("\n%s" % f.renderText("%s %s" % (self.static_config.get("name"), self.static_config.get("version"))))
|
||||||
|
|
||||||
async def init_serivces(self):
|
async def init_serivces(self):
|
||||||
|
|
||||||
self._print_logo()
|
self._print_logo()
|
||||||
await DBModel.test_connection()
|
|
||||||
await self.config2.init()
|
await self.job.init()
|
||||||
|
await DBModel.setup()
|
||||||
|
await self.config.init()
|
||||||
self.plugin.load_plugins()
|
self.plugin.load_plugins()
|
||||||
self.plugin.load_plugins_from_evn()
|
self.plugin.load_plugins_from_evn()
|
||||||
await self.sensor.init()
|
await self.sensor.init()
|
||||||
|
@ -274,13 +175,10 @@ class CraftBeerPi():
|
||||||
await self.actor.init()
|
await self.actor.init()
|
||||||
await self.kettle.init()
|
await self.kettle.init()
|
||||||
await self.call_initializer(self.app)
|
await self.call_initializer(self.app)
|
||||||
|
|
||||||
logger.info(self.sensor.info())
|
|
||||||
logger.info(self.actor.info())
|
|
||||||
|
|
||||||
self._swagger_setup()
|
self._swagger_setup()
|
||||||
|
|
||||||
return self.app
|
return self.app
|
||||||
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
web.run_app(self.init_serivces(), port=self.config.get("port", 8080))
|
web.run_app(self.init_serivces(), port=self.static_config.get("port", 8080))
|
||||||
|
|
|
@ -12,9 +12,6 @@ class DBModel(object):
|
||||||
__json_fields__ = []
|
__json_fields__ = []
|
||||||
|
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self.__setattr__(self.__priamry_key__, args[self.__priamry_key__])
|
self.__setattr__(self.__priamry_key__, args[self.__priamry_key__])
|
||||||
for f in self.__fields__:
|
for f in self.__fields__:
|
||||||
|
|
||||||
|
@ -32,7 +29,7 @@ class DBModel(object):
|
||||||
self.__setattr__(f, args.get(f))
|
self.__setattr__(f, args.get(f))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def test_connection(self):
|
async def setup(self):
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -185,3 +185,15 @@ class CBPiEventBus(object):
|
||||||
yield content
|
yield content
|
||||||
|
|
||||||
return rec(self._root)
|
return rec(self._root)
|
||||||
|
|
||||||
|
def register_object(self, obj):
|
||||||
|
|
||||||
|
for method in [getattr(obj, f) for f in dir(obj) if callable(getattr(obj, f)) and hasattr(getattr(obj, f), "eventbus")]:
|
||||||
|
doc = None
|
||||||
|
if method.__doc__ is not None:
|
||||||
|
try:
|
||||||
|
doc = yaml.load(method.__doc__)
|
||||||
|
doc["topic"] = method.__getattribute__("topic")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
self.register(method.__getattribute__("topic"), method)
|
|
@ -11,7 +11,7 @@ class Login():
|
||||||
self.cbpi.register(self)
|
self.cbpi.register(self)
|
||||||
|
|
||||||
|
|
||||||
self.db = {cbpi.config.get("username", "cbpi"): cbpi.config.get("password", "cbpi")}
|
self.db = {cbpi.static_config.get("username", "cbpi"): cbpi.static_config.get("password", "cbpi")}
|
||||||
|
|
||||||
@request_mapping(path="/logout", name="Logout", method="GET", auth_required=True)
|
@request_mapping(path="/logout", name="Logout", method="GET", auth_required=True)
|
||||||
async def logout_view(self, request):
|
async def logout_view(self, request):
|
||||||
|
|
|
@ -40,12 +40,14 @@ def atomic(coro):
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def setup(app, cbpi, **kwargs):
|
|
||||||
async def on_startup(app):
|
async def setup(app, cbpi, **kwargs):
|
||||||
|
|
||||||
app['AIOJOBS_SCHEDULER'] = await create_scheduler(cbpi, **kwargs)
|
app['AIOJOBS_SCHEDULER'] = await create_scheduler(cbpi, **kwargs)
|
||||||
|
|
||||||
async def on_cleanup(app):
|
async def on_cleanup(app):
|
||||||
await app['AIOJOBS_SCHEDULER'].close()
|
await app['AIOJOBS_SCHEDULER'].close()
|
||||||
|
|
||||||
app.on_startup.append(on_startup)
|
|
||||||
app.on_cleanup.append(on_cleanup)
|
app.on_cleanup.append(on_cleanup)
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
craftbeerpi.db
BIN
craftbeerpi.db
Binary file not shown.
|
@ -53,16 +53,16 @@ Typically you perform just some basing parameter validation and fire an event so
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The Events are process in an async way. Results will be pushed to the client via WebSocket Event.
|
The Events are process in an async way. Results will be pushed to the client via CBPiWebSocket Event.
|
||||||
|
|
||||||
|
|
||||||
WebSocket
|
CBPiWebSocket
|
||||||
---------
|
---------
|
||||||
|
|
||||||
The WebSocket is listening on `http://<IP_ADDRESS>:<PORT>/ws`
|
The CBPiWebSocket is listening on `http://<IP_ADDRESS>:<PORT>/ws`
|
||||||
All events are forwarded to all connected web socket clients.
|
All events are forwarded to all connected web socket clients.
|
||||||
|
|
||||||
The WebSocket Event is having the following structure.
|
The CBPiWebSocket Event is having the following structure.
|
||||||
|
|
||||||
* topic -> is the bus topic
|
* topic -> is the bus topic
|
||||||
* data -> the event data
|
* data -> the event data
|
||||||
|
|
2
docs/_static/doctools.js
vendored
2
docs/_static/doctools.js
vendored
|
@ -237,7 +237,7 @@ var Documentation = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init the domain index toggle buttons
|
* setup the domain index toggle buttons
|
||||||
*/
|
*/
|
||||||
initIndexTable : function() {
|
initIndexTable : function() {
|
||||||
var togglers = $('img.toggler').click(function() {
|
var togglers = $('img.toggler').click(function() {
|
||||||
|
|
8
docs/_static/jquery-3.2.1.js
vendored
8
docs/_static/jquery-3.2.1.js
vendored
|
@ -93,8 +93,8 @@ var
|
||||||
// Define a local copy of jQuery
|
// Define a local copy of jQuery
|
||||||
jQuery = function( selector, context ) {
|
jQuery = function( selector, context ) {
|
||||||
|
|
||||||
// The jQuery object is actually just the init constructor 'enhanced'
|
// The jQuery object is actually just the setup constructor 'enhanced'
|
||||||
// Need init if jQuery is called (just allow error to be thrown if not included)
|
// Need setup if jQuery is called (just allow error to be thrown if not included)
|
||||||
return new jQuery.fn.init( selector, context );
|
return new jQuery.fn.init( selector, context );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2965,7 +2965,7 @@ var rootjQuery,
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method init() accepts an alternate rootjQuery
|
// Method setup() accepts an alternate rootjQuery
|
||||||
// so migrate can support jQuery.sub (gh-2101)
|
// so migrate can support jQuery.sub (gh-2101)
|
||||||
root = root || rootjQuery;
|
root = root || rootjQuery;
|
||||||
|
|
||||||
|
@ -3056,7 +3056,7 @@ var rootjQuery,
|
||||||
return jQuery.makeArray( selector, this );
|
return jQuery.makeArray( selector, this );
|
||||||
};
|
};
|
||||||
|
|
||||||
// Give the init function the jQuery prototype for later instantiation
|
// Give the setup function the jQuery prototype for later instantiation
|
||||||
init.prototype = jQuery.fn;
|
init.prototype = jQuery.fn;
|
||||||
|
|
||||||
// Initialize central reference
|
// Initialize central reference
|
||||||
|
|
|
@ -171,7 +171,7 @@
|
||||||
<p>The main actor controller</p>
|
<p>The main actor controller</p>
|
||||||
<dl class="method">
|
<dl class="method">
|
||||||
<dt id="core.controller.actor_controller.ActorController.init">
|
<dt id="core.controller.actor_controller.ActorController.init">
|
||||||
<code class="descname">init</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#core.controller.actor_controller.ActorController.init" title="Permalink to this definition">¶</a></dt>
|
<code class="descname">setup</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#core.controller.actor_controller.ActorController.init" title="Permalink to this definition">¶</a></dt>
|
||||||
<dd><p>This method initializes all actors during startup. It creates actor instances</p>
|
<dd><p>This method initializes all actors during startup. It creates actor instances</p>
|
||||||
<table class="docutils field-list" frame="void" rules="none">
|
<table class="docutils field-list" frame="void" rules="none">
|
||||||
<col class="field-name" />
|
<col class="field-name" />
|
||||||
|
|
|
@ -258,7 +258,7 @@
|
||||||
<h2 id="I">I</h2>
|
<h2 id="I">I</h2>
|
||||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||||
<td style="width: 33%; vertical-align: top;"><ul>
|
<td style="width: 33%; vertical-align: top;"><ul>
|
||||||
<li><a href="kettle_controller.html#core.api.kettle_logic.CBPiKettleLogic.init">init() (core.api.kettle_logic.CBPiKettleLogic method)</a>
|
<li><a href="kettle_controller.html#core.api.kettle_logic.CBPiKettleLogic.init">setup() (core.api.kettle_logic.CBPiKettleLogic method)</a>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="actor.html#core.controller.actor_controller.ActorController.init">(core.controller.actor_controller.ActorController method)</a>
|
<li><a href="actor.html#core.controller.actor_controller.ActorController.init">(core.controller.actor_controller.ActorController method)</a>
|
||||||
|
|
|
@ -189,7 +189,7 @@
|
||||||
<li class="toctree-l2"><a class="reference internal" href="standards.html#python">Python</a><ul>
|
<li class="toctree-l2"><a class="reference internal" href="standards.html#python">Python</a><ul>
|
||||||
<li class="toctree-l3"><a class="reference internal" href="standards.html#eventbus">CBPiEventBus</a></li>
|
<li class="toctree-l3"><a class="reference internal" href="standards.html#eventbus">CBPiEventBus</a></li>
|
||||||
<li class="toctree-l3"><a class="reference internal" href="standards.html#http-endpoints">HTTP Endpoints</a></li>
|
<li class="toctree-l3"><a class="reference internal" href="standards.html#http-endpoints">HTTP Endpoints</a></li>
|
||||||
<li class="toctree-l3"><a class="reference internal" href="standards.html#websocket">WebSocket</a></li>
|
<li class="toctree-l3"><a class="reference internal" href="standards.html#websocket">CBPiWebSocket</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="standards.html#web-user-interface">Web User Interface</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="standards.html#web-user-interface">Web User Interface</a></li>
|
||||||
|
|
|
@ -244,7 +244,7 @@
|
||||||
|
|
||||||
<dl class="method">
|
<dl class="method">
|
||||||
<dt id="core.controller.kettle_controller.KettleController.init">
|
<dt id="core.controller.kettle_controller.KettleController.init">
|
||||||
<code class="descname">init</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#core.controller.kettle_controller.KettleController.init" title="Permalink to this definition">¶</a></dt>
|
<code class="descname">setup</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#core.controller.kettle_controller.KettleController.init" title="Permalink to this definition">¶</a></dt>
|
||||||
<dd><p>This method initializes all actors during startup. It creates actor instances</p>
|
<dd><p>This method initializes all actors during startup. It creates actor instances</p>
|
||||||
<table class="docutils field-list" frame="void" rules="none">
|
<table class="docutils field-list" frame="void" rules="none">
|
||||||
<col class="field-name" />
|
<col class="field-name" />
|
||||||
|
@ -295,7 +295,7 @@
|
||||||
<p>Base Class for a Kettle logic.</p>
|
<p>Base Class for a Kettle logic.</p>
|
||||||
<dl class="method">
|
<dl class="method">
|
||||||
<dt id="core.api.kettle_logic.CBPiKettleLogic.init">
|
<dt id="core.api.kettle_logic.CBPiKettleLogic.init">
|
||||||
<code class="descname">init</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#core.api.kettle_logic.CBPiKettleLogic.init" title="Permalink to this definition">¶</a></dt>
|
<code class="descname">setup</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#core.api.kettle_logic.CBPiKettleLogic.init" title="Permalink to this definition">¶</a></dt>
|
||||||
<dd><p>Code which will be executed when the logic is initialised. Needs to be overwritten by the implementing logic</p>
|
<dd><p>Code which will be executed when the logic is initialised. Needs to be overwritten by the implementing logic</p>
|
||||||
<table class="docutils field-list" frame="void" rules="none">
|
<table class="docutils field-list" frame="void" rules="none">
|
||||||
<col class="field-name" />
|
<col class="field-name" />
|
||||||
|
|
|
@ -170,7 +170,7 @@
|
||||||
|
|
||||||
<dl class="method">
|
<dl class="method">
|
||||||
<dt id="core.controller.sensor_controller.SensorController.init">
|
<dt id="core.controller.sensor_controller.SensorController.init">
|
||||||
<code class="descname">init</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#core.controller.sensor_controller.SensorController.init" title="Permalink to this definition">¶</a></dt>
|
<code class="descname">setup</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#core.controller.sensor_controller.SensorController.init" title="Permalink to this definition">¶</a></dt>
|
||||||
<dd><p>This method initializes all actors during startup. It creates actor instances</p>
|
<dd><p>This method initializes all actors during startup. It creates actor instances</p>
|
||||||
<table class="docutils field-list" frame="void" rules="none">
|
<table class="docutils field-list" frame="void" rules="none">
|
||||||
<col class="field-name" />
|
<col class="field-name" />
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
<li class="toctree-l2"><a class="reference internal" href="#python">Python</a><ul>
|
<li class="toctree-l2"><a class="reference internal" href="#python">Python</a><ul>
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#eventbus">CBPiEventBus</a></li>
|
<li class="toctree-l3"><a class="reference internal" href="#eventbus">CBPiEventBus</a></li>
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#http-endpoints">HTTP Endpoints</a></li>
|
<li class="toctree-l3"><a class="reference internal" href="#http-endpoints">HTTP Endpoints</a></li>
|
||||||
<li class="toctree-l3"><a class="reference internal" href="#websocket">WebSocket</a></li>
|
<li class="toctree-l3"><a class="reference internal" href="#websocket">CBPiWebSocket</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="#web-user-interface">Web User Interface</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="#web-user-interface">Web User Interface</a></li>
|
||||||
|
@ -202,14 +202,14 @@ Typically you perform just some basing parameter validation and fire an event so
|
||||||
</div>
|
</div>
|
||||||
<div class="admonition note">
|
<div class="admonition note">
|
||||||
<p class="first admonition-title">Note</p>
|
<p class="first admonition-title">Note</p>
|
||||||
<p class="last">The Events are process in an async way. Results will be pushed to the client via WebSocket Event.</p>
|
<p class="last">The Events are process in an async way. Results will be pushed to the client via CBPiWebSocket Event.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="websocket">
|
<div class="section" id="websocket">
|
||||||
<h3>WebSocket<a class="headerlink" href="#websocket" title="Permalink to this headline">¶</a></h3>
|
<h3>CBPiWebSocket<a class="headerlink" href="#websocket" title="Permalink to this headline">¶</a></h3>
|
||||||
<p>The WebSocket is listening on <cite>http://<IP_ADDRESS>:<PORT>/ws</cite>
|
<p>The CBPiWebSocket is listening on <cite>http://<IP_ADDRESS>:<PORT>/ws</cite>
|
||||||
All events are forwarded to all connected web socket clients.</p>
|
All events are forwarded to all connected web socket clients.</p>
|
||||||
<p>The WebSocket Event is having the following structure.</p>
|
<p>The CBPiWebSocket Event is having the following structure.</p>
|
||||||
<ul class="simple">
|
<ul class="simple">
|
||||||
<li>topic -> is the bus topic</li>
|
<li>topic -> is the bus topic</li>
|
||||||
<li>data -> the event data</li>
|
<li>data -> the event data</li>
|
||||||
|
|
|
@ -352,7 +352,7 @@ Stops the current step</p>
|
||||||
|
|
||||||
<dl class="method">
|
<dl class="method">
|
||||||
<dt id="core.controller.step_controller.StepController.init">
|
<dt id="core.controller.step_controller.StepController.init">
|
||||||
<code class="descname">init</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#core.controller.step_controller.StepController.init" title="Permalink to this definition">¶</a></dt>
|
<code class="descname">setup</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#core.controller.step_controller.StepController.init" title="Permalink to this definition">¶</a></dt>
|
||||||
<dd><p>Initializer of the the Step Controller.
|
<dd><p>Initializer of the the Step Controller.
|
||||||
:return:</p>
|
:return:</p>
|
||||||
</dd></dl>
|
</dd></dl>
|
||||||
|
|
|
@ -55,16 +55,16 @@ Typically you perform just some basing parameter validation and fire an event so
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The Events are process in an async way. Results will be pushed to the client via WebSocket Event.
|
The Events are process in an async way. Results will be pushed to the client via CBPiWebSocket Event.
|
||||||
|
|
||||||
|
|
||||||
WebSocket
|
CBPiWebSocket
|
||||||
---------
|
---------
|
||||||
|
|
||||||
The WebSocket is listening on `http://<IP_ADDRESS>:<PORT>/ws`
|
The CBPiWebSocket is listening on `http://<IP_ADDRESS>:<PORT>/ws`
|
||||||
All events are forwarded to all connected web socket clients.
|
All events are forwarded to all connected web socket clients.
|
||||||
|
|
||||||
The WebSocket Event is having the following structure.
|
The CBPiWebSocket Event is having the following structure.
|
||||||
|
|
||||||
* topic -> is the bus topic
|
* topic -> is the bus topic
|
||||||
* data -> the event data
|
* data -> the event data
|
||||||
|
|
2
main.py
2
main.py
|
@ -7,7 +7,7 @@ from hbmqtt.broker import Broker
|
||||||
from hbmqtt.client import MQTTClient
|
from hbmqtt.client import MQTTClient
|
||||||
from hbmqtt.mqtt.constants import QOS_1
|
from hbmqtt.mqtt.constants import QOS_1
|
||||||
|
|
||||||
from core.websocket import websocket_handler
|
from core.cbpiwebsocket import websocket_handler
|
||||||
|
|
||||||
TEST_DB = "test.db"
|
TEST_DB = "test.db"
|
||||||
c = MQTTClient()
|
c = MQTTClient()
|
||||||
|
|
|
@ -11,8 +11,6 @@ class MyAppTestCase(AioHTTPTestCase):
|
||||||
|
|
||||||
async def get_application(self):
|
async def get_application(self):
|
||||||
self.cbpi = CraftBeerPi()
|
self.cbpi = CraftBeerPi()
|
||||||
self.cbpi.setup()
|
|
||||||
|
|
||||||
await self.cbpi.init_serivces()
|
await self.cbpi.init_serivces()
|
||||||
return self.cbpi.app
|
return self.cbpi.app
|
||||||
|
|
||||||
|
@ -21,11 +19,9 @@ class MyAppTestCase(AioHTTPTestCase):
|
||||||
async def test_example(self):
|
async def test_example(self):
|
||||||
|
|
||||||
resp = await self.client.post(path="/login", data={"username": "cbpi", "password": "123"})
|
resp = await self.client.post(path="/login", data={"username": "cbpi", "password": "123"})
|
||||||
print("resp.status",resp.status)
|
|
||||||
assert resp.status == 200
|
assert resp.status == 200
|
||||||
|
|
||||||
resp = await self.client.request("GET", "/actor/1/on")
|
resp = await self.client.request("GET", "/actor/1/on")
|
||||||
print("resp.status", resp.status)
|
|
||||||
assert resp.status == 204
|
assert resp.status == 204
|
||||||
i = await self.cbpi.actor.get_one(1)
|
i = await self.cbpi.actor.get_one(1)
|
||||||
assert i.instance.state is True
|
assert i.instance.state is True
|
||||||
|
@ -46,33 +42,5 @@ class MyAppTestCase(AioHTTPTestCase):
|
||||||
i = await self.cbpi.actor.get_one(1)
|
i = await self.cbpi.actor.get_one(1)
|
||||||
assert i.instance.state is False
|
assert i.instance.state is False
|
||||||
|
|
||||||
i = await self.cbpi.actor.get_all()
|
|
||||||
assert len(i) == 2
|
|
||||||
#ws = await self.client.ws_connect("/ws");
|
|
||||||
#await ws.send_str(json.dumps({"key": "test"}))
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_example2(self):
|
|
||||||
print("TEST2222")
|
|
||||||
|
|
||||||
print("CLIENT ###### ", self.client)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ws = await self.client.ws_connect("/ws");
|
|
||||||
await ws.send_str(json.dumps({"topic": "test"}))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#resp = await ws.receive()
|
|
||||||
|
|
||||||
#print("##### REPSONE", resp)
|
|
||||||
assert "Manuel" in await self.cbpi.actor.get_name(), "OH NOW"
|
|
||||||
|
|
||||||
await self.client.close()
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
|
@ -1,32 +1,33 @@
|
||||||
import asyncio
|
|
||||||
import time
|
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 core.craftbeerpi import CraftBeerPi
|
|
||||||
from cbpi_api.config import ConfigType
|
from cbpi_api.config import ConfigType
|
||||||
|
|
||||||
|
from core.craftbeerpi import CraftBeerPi
|
||||||
|
|
||||||
|
|
||||||
class ConfigTestCase(AioHTTPTestCase):
|
class ConfigTestCase(AioHTTPTestCase):
|
||||||
|
|
||||||
|
|
||||||
async def get_application(self):
|
async def get_application(self):
|
||||||
self.cbpi = CraftBeerPi()
|
self.cbpi = CraftBeerPi()
|
||||||
self.cbpi.setup()
|
await self.cbpi.init_serivces()
|
||||||
return self.cbpi.app
|
return self.cbpi.app
|
||||||
|
|
||||||
|
|
||||||
@unittest_run_loop
|
@unittest_run_loop
|
||||||
async def test_get(self):
|
async def test_get(self):
|
||||||
|
|
||||||
assert await self.cbpi.config2.get("CBPI_TEST_1", 1) == "22"
|
assert self.cbpi.config.get("CBPI_TEST_1", 1) == "22"
|
||||||
|
|
||||||
@unittest_run_loop
|
@unittest_run_loop
|
||||||
async def test_set_get(self):
|
async def test_set_get(self):
|
||||||
value = str(time.time())
|
value = str(time.time())
|
||||||
|
|
||||||
await self.cbpi.config2.set("CBPI_TEST_2", value)
|
await self.cbpi.config.set("CBPI_TEST_2", value)
|
||||||
|
|
||||||
assert await self.cbpi.config2.get("CBPI_TEST_2", 1) == value
|
assert self.cbpi.config.get("CBPI_TEST_2", 1) == value
|
||||||
|
|
||||||
@unittest_run_loop
|
@unittest_run_loop
|
||||||
async def test_add(self):
|
async def test_add(self):
|
||||||
|
@ -36,18 +37,18 @@ class ConfigTestCase(AioHTTPTestCase):
|
||||||
await db.execute("DELETE FROM config WHERE name = ? ", (key,))
|
await db.execute("DELETE FROM config WHERE name = ? ", (key,))
|
||||||
await db.commit()
|
await db.commit()
|
||||||
|
|
||||||
await self.cbpi.config2.add(key, value, type=ConfigType.STRING, description="test")
|
await self.cbpi.config.add(key, value, type=ConfigType.STRING, description="test")
|
||||||
|
|
||||||
@unittest_run_loop
|
@unittest_run_loop
|
||||||
async def test_http_set(self):
|
async def test_http_set(self):
|
||||||
value = str(time.time())
|
value = str(time.time())
|
||||||
key = "CBPI_TEST_3"
|
key = "CBPI_TEST_3"
|
||||||
await self.cbpi.config2.set(key, value)
|
await self.cbpi.config.set(key, value)
|
||||||
assert await self.cbpi.config2.get(key, 1) == value
|
assert self.cbpi.config.get(key, 1) == value
|
||||||
|
|
||||||
resp = await self.client.request("POST", "/config/%s/" % key, json={'value': '1'})
|
resp = await self.client.request("POST", "/config/%s/" % key, json={'value': '1'})
|
||||||
assert resp.status == 204
|
assert resp.status == 204
|
||||||
assert await self.cbpi.config2.get(key, -1) == "1"
|
assert self.cbpi.config.get(key, -1) == "1"
|
||||||
|
|
||||||
@unittest_run_loop
|
@unittest_run_loop
|
||||||
async def test_http_get(self):
|
async def test_http_get(self):
|
||||||
|
|
|
@ -8,19 +8,33 @@ class KettleTestCase(AioHTTPTestCase):
|
||||||
|
|
||||||
async def get_application(self):
|
async def get_application(self):
|
||||||
self.cbpi = CraftBeerPi()
|
self.cbpi = CraftBeerPi()
|
||||||
self.cbpi.setup()
|
await self.cbpi.init_serivces()
|
||||||
return self.cbpi.app
|
return self.cbpi.app
|
||||||
|
|
||||||
|
@unittest_run_loop
|
||||||
|
async def test_get(self):
|
||||||
|
|
||||||
|
resp = await self.client.request("GET", "/kettle")
|
||||||
|
assert resp.status == 200
|
||||||
|
print(await resp.json())
|
||||||
|
|
||||||
@unittest_run_loop
|
@unittest_run_loop
|
||||||
async def test_example(self):
|
async def test_add(self):
|
||||||
await asyncio.sleep(10)
|
data = {
|
||||||
for i in range(100):
|
"name": "Test",
|
||||||
resp = await self.client.request("GET", "/actor/")
|
"sensor": None,
|
||||||
print(resp)
|
"heater": "1",
|
||||||
resp = await self.client.post(path="/actor/", json={ "name": "Test", "type": "CustomActor", "config": {"gpio": 22 }})
|
"automatic": None,
|
||||||
print(resp)
|
"logic": "CustomKettleLogic",
|
||||||
|
"config": {
|
||||||
|
"test": "WOOHO"
|
||||||
|
},
|
||||||
|
"agitator": None,
|
||||||
|
"target_temp": None
|
||||||
|
}
|
||||||
|
|
||||||
|
resp = await self.client.post(path="/kettle/", json=data)
|
||||||
|
assert resp.status == 200
|
||||||
|
|
||||||
'''
|
'''
|
||||||
result = await self.cbpi.kettle.toggle_automtic(1)
|
result = await self.cbpi.kettle.toggle_automtic(1)
|
||||||
|
|
Loading…
Reference in a new issue