craftbeerpi4-pione/cbpi/controller/plugin_controller.py

200 lines
8.6 KiB
Python
Raw Normal View History

2018-11-04 00:47:26 +01:00
import logging
import os
from importlib import import_module
2021-10-16 14:22:04 +02:00
from importlib_metadata import version, metadata
2019-07-31 07:58:54 +02:00
import datetime
2018-11-04 00:47:26 +01:00
import aiohttp
2021-10-16 14:22:04 +02:00
import asyncio
2018-11-04 00:47:26 +01:00
import yaml
2019-07-27 21:08:19 +02:00
import subprocess
import sys
2019-07-31 07:58:54 +02:00
from cbpi.api import *
from cbpi.utils.utils import load_config
2018-12-29 00:27:19 +01:00
2019-07-31 07:58:54 +02:00
logger = logging.getLogger(__name__)
2018-11-04 00:47:26 +01:00
2021-01-17 22:49:18 +01:00
2018-11-04 00:47:26 +01:00
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
2019-07-31 07:58:54 +02:00
2018-12-07 00:18:35 +01:00
def load_plugins(self):
2018-11-04 00:47:26 +01:00
2021-02-01 01:38:04 +01:00
this_directory = os.sep.join(os.path.abspath(__file__).split(os.sep)[:-1])
2019-01-05 20:43:48 +01:00
for filename in os.listdir(os.path.join(this_directory, "../extension")):
2021-02-01 01:38:04 +01:00
if os.path.isdir(
os.path.join(this_directory, "../extension/") + filename) is False or filename == "__pycache__":
2018-11-04 00:47:26 +01:00
continue
try:
logger.info("Trying to load plugin %s" % filename)
2021-01-17 22:49:18 +01:00
data = load_config(os.path.join(
this_directory, "../extension/%s/config.yaml" % filename))
2019-08-05 20:51:20 +02:00
if (data.get("active") is True and data.get("version") == 4):
2021-01-17 22:49:18 +01:00
self.modules[filename] = import_module(
"cbpi.extension.%s" % (filename))
2018-11-16 20:35:59 +01:00
self.modules[filename].setup(self.cbpi)
2021-02-01 01:38:04 +01:00
# logger.info("Plugin %s loaded successful" % filename)
2018-11-04 00:47:26 +01:00
else:
2021-01-17 22:49:18 +01:00
logger.warning(
"Plugin %s is not supporting version 4" % filename)
2018-11-04 00:47:26 +01:00
except Exception as e:
2021-02-16 20:37:51 +01:00
2018-11-04 00:47:26 +01:00
logger.error(e)
2018-12-29 00:27:19 +01:00
def load_plugins_from_evn(self):
2021-02-01 01:38:04 +01:00
for p in self.cbpi.static_config.get("plugins", []):
try:
logger.info("Try to load plugin: %s " % p)
self.modules[p] = import_module(p)
self.modules[p].setup(self.cbpi)
2021-01-30 22:29:33 +01:00
logger.info("Plugin %s loaded successfully" % p)
except Exception as e:
logger.error("FAILED to load plugin %s " % p)
logger.error(e)
2018-12-29 00:27:19 +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
'''
2021-01-22 23:25:20 +01:00
logger.debug("Register %s Class %s" % (name, clazz.__name__))
2021-02-01 01:38:04 +01:00
2021-01-23 14:41:26 +01:00
if issubclass(clazz, CBPiActor):
2021-02-01 01:38:04 +01:00
self.cbpi.actor.types[name] = self._parse_step_props(clazz, name)
2018-11-18 15:40:10 +01:00
2021-01-23 14:41:26 +01:00
if issubclass(clazz, CBPiKettleLogic):
2021-02-01 01:38:04 +01:00
self.cbpi.kettle.types[name] = self._parse_step_props(clazz, name)
2021-01-23 14:41:26 +01:00
if issubclass(clazz, CBPiSensor):
2021-02-01 01:38:04 +01:00
self.cbpi.sensor.types[name] = self._parse_step_props(clazz, name)
2018-12-29 00:27:19 +01:00
2021-01-17 22:49:18 +01:00
if issubclass(clazz, CBPiStep):
2021-02-01 01:38:04 +01:00
self.cbpi.step.types[name] = self._parse_step_props(clazz, name)
2021-01-17 22:49:18 +01:00
if issubclass(clazz, CBPiExtension):
2019-07-27 21:08:19 +02:00
self.c = clazz(self.cbpi)
2018-11-01 19:50:04 +01:00
2021-01-17 22:49:18 +01:00
def _parse_property_object(self, p):
if isinstance(p, Property.Number):
2021-02-01 01:38:04 +01:00
return {"label": p.label, "type": "number", "configurable": p.configurable, "description": p.description,
"default_value": p.default_value}
2021-01-17 22:49:18 +01:00
elif isinstance(p, Property.Text):
2021-02-01 01:38:04 +01:00
return {"label": p.label, "type": "text", "configurable": p.configurable, "default_value": p.default_value,
"description": p.description}
2021-01-17 22:49:18 +01:00
elif isinstance(p, Property.Select):
2021-02-01 01:38:04 +01:00
return {"label": p.label, "type": "select", "configurable": True, "options": p.options,
"description": p.description}
2021-01-17 22:49:18 +01:00
elif isinstance(p, Property.Actor):
return {"label": p.label, "type": "actor", "configurable": p.configurable, "description": p.description}
elif isinstance(p, Property.Sensor):
return {"label": p.label, "type": "sensor", "configurable": p.configurable, "description": p.description}
elif isinstance(p, Property.Kettle):
return {"label": p.label, "type": "kettle", "configurable": p.configurable, "description": p.description}
def _parse_step_props(self, cls, name):
2021-01-22 23:25:20 +01:00
result = {"name": name, "class": cls, "properties": [], "actions": []}
2021-01-17 22:49:18 +01:00
if hasattr(cls, "cbpi_parameters"):
parameters = []
for p in cls.cbpi_parameters:
parameters.append(self._parse_property_object(p))
result["properties"] = parameters
for method_name, method in cls.__dict__.items():
if hasattr(method, "action"):
key = method.__getattribute__("key")
parameters = []
2021-02-01 01:38:04 +01:00
for p in method.__getattribute__("parameters"):
2021-01-17 22:49:18 +01:00
parameters.append(self._parse_property_object(p))
result["actions"].append({"method": method_name, "label": key, "parameters": parameters})
return result
2018-11-01 19:50:04 +01:00
def _parse_props(self, cls):
2018-12-29 00:27:19 +01:00
2018-11-01 19:50:04 +01:00
name = cls.__name__
result = {"name": name, "class": cls, "properties": [], "actions": []}
2019-07-27 21:08:19 +02:00
tmpObj = cls(cbpi=None, managed_fields=None)
2021-01-17 22:49:18 +01:00
members = [attr for attr in dir(tmpObj) if not callable(
getattr(tmpObj, attr)) and not attr.startswith("__")]
2018-11-01 19:50:04 +01:00
for m in members:
if isinstance(tmpObj.__getattribute__(m), Property.Number):
t = tmpObj.__getattribute__(m)
result["properties"].append(
2021-02-01 01:38:04 +01:00
{"name": m, "label": t.label, "type": "number", "configurable": t.configurable,
"description": t.description, "default_value": t.default_value})
2018-11-01 19:50:04 +01:00
elif isinstance(tmpObj.__getattribute__(m), Property.Text):
t = tmpObj.__getattribute__(m)
result["properties"].append(
2021-02-01 01:38:04 +01:00
{"name": m, "label": t.label, "type": "text", "configurable": t.configurable,
"default_value": t.default_value, "description": t.description})
2018-11-01 19:50:04 +01:00
elif isinstance(tmpObj.__getattribute__(m), Property.Select):
t = tmpObj.__getattribute__(m)
result["properties"].append(
2021-02-01 01:38:04 +01:00
{"name": m, "label": t.label, "type": "select", "configurable": True, "options": t.options,
"description": t.description})
2018-11-01 19:50:04 +01:00
elif isinstance(tmpObj.__getattribute__(m), Property.Actor):
t = tmpObj.__getattribute__(m)
2021-01-17 22:49:18 +01:00
result["properties"].append(
2021-02-01 01:38:04 +01:00
{"name": m, "label": t.label, "type": "actor", "configurable": t.configurable,
"description": t.description})
2018-11-01 19:50:04 +01:00
elif isinstance(tmpObj.__getattribute__(m), Property.Sensor):
t = tmpObj.__getattribute__(m)
2021-01-17 22:49:18 +01:00
result["properties"].append(
2021-02-01 01:38:04 +01:00
{"name": m, "label": t.label, "type": "sensor", "configurable": t.configurable,
"description": t.description})
2018-11-01 19:50:04 +01:00
elif isinstance(tmpObj.__getattribute__(m), Property.Kettle):
t = tmpObj.__getattribute__(m)
2021-01-17 22:49:18 +01:00
result["properties"].append(
2021-02-01 01:38:04 +01:00
{"name": m, "label": t.label, "type": "kettle", "configurable": t.configurable,
"description": t.description})
2018-11-01 19:50:04 +01:00
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")
2021-01-17 22:49:18 +01:00
result["actions"].append(
{"method": method_name, "label": key, "parameters": parameters})
2018-12-29 00:27:19 +01:00
2019-07-27 21:08:19 +02:00
return result
2021-10-16 14:22:04 +02:00
async def load_plugin_list(self):
result = []
try:
with open(os.path.join(".", 'config', "config.yaml"), 'rt') as f:
data = yaml.load(f, Loader=yaml.FullLoader)
for p in data["plugins"]:
try:
p_metadata= metadata(p)
p_name = p_metadata['name']
p_version = p_metadata['Version']
p_summary = p_metadata['Summary']
p_homepage= p_metadata['Home-page']
p_author = p_metadata['Author']
p_author_email = p_metadata['Author-email']
p_license = p_metadata['License']
p_description = p_metadata['Description']
plugin_data = {'Name': p_name,'Version': p_version,'Summary': p_summary,'Homepage':p_homepage,'Author':p_author,'Email': p_author_email,'License': p_license,'Description': p_description}
result.append(plugin_data)
except:
pass
# print("- ({})\t{}".format(p_version,p))
except Exception as e:
print(e)
return []
pass
return result