craftbeerpi4-pione/core/controller/plugin_controller.py

149 lines
5.8 KiB
Python
Raw Normal View History

2018-11-04 00:47:26 +01:00
import logging
import os
from importlib import import_module
2018-11-01 19:50:04 +01:00
from pprint import pprint
2018-11-04 00:47:26 +01:00
import aiohttp
import yaml
from aiohttp import web
2018-11-16 20:35:59 +01:00
from core.api.actor import CBPiActor
2018-11-04 00:47:26 +01:00
from core.api.decorator import request_mapping
2018-11-16 20:35:59 +01:00
from core.api.extension import CBPiExtension
2018-11-18 15:40:10 +01:00
from core.api.kettle_logic import CBPiKettleLogic
2018-11-01 19:50:04 +01:00
from core.api.property import Property
2018-11-18 15:40:10 +01:00
from core.api.sensor import CBPiSensor
2018-12-03 22:16:03 +01:00
from core.api.step import Step
2018-11-04 00:47:26 +01:00
from core.utils.utils import load_config, json_dumps
logger = logging.getLogger(__file__)
logging.basicConfig(level=logging.INFO)
class PluginController():
modules = {}
2018-11-16 20:35:59 +01:00
types = {}
2018-11-04 00:47:26 +01:00
def __init__(self, cbpi):
self.cbpi = cbpi
self.cbpi.register(self, "/plugin")
@classmethod
async def load_plugin_list(self):
async with aiohttp.ClientSession() as session:
async with session.get('https://raw.githubusercontent.com/Manuel83/craftbeerpi-plugins/master/plugins.yaml') as resp:
if(resp.status == 200):
data = yaml.load(await resp.text())
return data
async def load_plugins(self):
for filename in os.listdir("./core/extension"):
if os.path.isdir("./core/extension/" + filename) is False or filename == "__pycache__":
continue
try:
logger.info("Trying to load plugin %s" % filename)
data = load_config("./core/extension/%s/config.yaml" % filename)
if(data.get("version") == 4):
self.modules[filename] = import_module("core.extension.%s" % (filename))
2018-11-16 20:35:59 +01:00
self.modules[filename].setup(self.cbpi)
2018-11-04 00:47:26 +01:00
logger.info("Plugin %s loaded successful" % filename)
else:
logger.warning("Plguin %s is not supporting version 4" % filename)
except Exception as e:
logger.error(e)
2018-11-04 01:55:54 +01:00
@request_mapping(path="/plugins", method="GET", auth_required=False)
2018-11-04 00:47:26 +01:00
async def get_plugins(self, request):
"""
---
2018-11-16 20:35:59 +01:00
description: Get a list of avialable plugins
2018-11-04 00:47:26 +01:00
tags:
2018-11-16 20:35:59 +01:00
- Plugin
2018-11-04 00:47:26 +01:00
produces:
2018-11-16 20:35:59 +01:00
- application/json
2018-11-04 00:47:26 +01:00
responses:
"200":
description: successful operation. Return "pong" text
"405":
description: invalid HTTP Method
"""
return web.json_response(await self.load_plugin_list(), dumps=json_dumps)
2018-11-01 19:50:04 +01:00
2018-11-01 21:25:42 +01:00
def register(self, name, clazz) -> None:
'''
Register a new actor type
:param name: actor name
:param clazz: actor class
:return: None
'''
2018-11-18 15:40:10 +01:00
print("REGISTER", name, clazz)
2018-11-16 20:35:59 +01:00
if issubclass(clazz, CBPiActor):
self.cbpi.actor.types[name] = {"class": clazz, "config": self._parse_props(clazz)}
2018-11-18 15:40:10 +01:00
if issubclass(clazz, CBPiSensor):
self.cbpi.sensor.types[name] = {"class": clazz, "config": self._parse_props(clazz)}
if issubclass(clazz, CBPiKettleLogic):
self.cbpi.kettle.types[name] = {"class": clazz, "config": self._parse_props(clazz)}
2018-12-03 22:16:03 +01:00
if issubclass(clazz, Step):
2018-12-05 07:31:12 +01:00
self.cbpi.step.types[name] = self._parse_props(clazz)
print(self.cbpi.step.types)
#if issubclass(clazz, CBPiExtension):
# self.c = clazz(self.cbpi)
2018-11-16 20:35:59 +01:00
2018-11-01 19:50:04 +01:00
def _parse_props(self, cls):
2018-12-03 22:16:03 +01:00
print("PARSE", cls)
2018-11-01 19:50:04 +01:00
name = cls.__name__
result = {"name": name, "class": cls, "properties": [], "actions": []}
tmpObj = cls()
members = [attr for attr in dir(tmpObj) if not callable(getattr(tmpObj, attr)) and not attr.startswith("__")]
for m in members:
if isinstance(tmpObj.__getattribute__(m), Property.Number):
t = tmpObj.__getattribute__(m)
result["properties"].append(
{"name": m, "label": t.label, "type": "number", "configurable": t.configurable, "description": t.description, "default_value": t.default_value})
elif isinstance(tmpObj.__getattribute__(m), Property.Text):
t = tmpObj.__getattribute__(m)
result["properties"].append(
{"name": m, "label": t.label, "type": "text", "configurable": t.configurable, "default_value": t.default_value, "description": t.description})
elif isinstance(tmpObj.__getattribute__(m), Property.Select):
t = tmpObj.__getattribute__(m)
result["properties"].append(
{"name": m, "label": t.label, "type": "select", "configurable": True, "options": t.options, "description": t.description})
elif isinstance(tmpObj.__getattribute__(m), Property.Actor):
t = tmpObj.__getattribute__(m)
result["properties"].append({"name": m, "label": t.label, "type": "actor", "configurable": t.configurable, "description": t.description})
elif isinstance(tmpObj.__getattribute__(m), Property.Sensor):
t = tmpObj.__getattribute__(m)
result["properties"].append({"name": m, "label": t.label, "type": "sensor", "configurable": t.configurable, "description": t.description})
elif isinstance(tmpObj.__getattribute__(m), Property.Kettle):
t = tmpObj.__getattribute__(m)
result["properties"].append({"name": m, "label": t.label, "type": "kettle", "configurable": t.configurable, "description": t.description})
for method_name, method in cls.__dict__.items():
2018-11-01 21:25:42 +01:00
if hasattr(method, "action"):
key = method.__getattribute__("key")
parameters = method.__getattribute__("parameters")
result["actions"].append({"method": method_name, "label": key, "parameters": parameters})
2018-12-05 07:31:12 +01:00
pprint(result)
return result