Skip to content

Commit 22718e5

Browse files
committed
Fixed get_plugin_api
1 parent b458b5b commit 22718e5

File tree

5 files changed

+50
-56
lines changed

5 files changed

+50
-56
lines changed

appdaemon/adapi.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def __init__(self, ad: AppDaemon, config_model: "AppConfig"):
7070
self.config_model = config_model
7171

7272
self.config = self.AD.config.model_dump(by_alias=True, exclude_unset=True)
73-
self.args = self.config_model.model_dump(by_alias=True, exclude_unset=True)
73+
self.args = config_model.model_dump(by_alias=True, exclude_unset=True)
7474

7575
self.dashboard_dir = None
7676

@@ -118,6 +118,11 @@ def _get_namespace(self, **kwargs):
118118
#
119119
# Properties
120120
#
121+
@property
122+
def app_config(self) -> dict:
123+
"""Full set of loaded app configurations."""
124+
return self.AD.app_management.app_config.model_dump(by_alias=True, exclude_unset=True)
125+
121126
@property
122127
def app_dir(self) -> Path:
123128
return self.AD.app_dir
@@ -127,7 +132,7 @@ def config_dir(self) -> Path:
127132
return self.AD.config_dir
128133

129134
@property
130-
def global_vars(self):
135+
def global_vars(self) -> dict:
131136
return self.AD.global_vars
132137

133138
@property

appdaemon/adbase.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -145,17 +145,10 @@ def name(self) -> str:
145145
def get_ad_api(self) -> adapi.ADAPI:
146146
return adapi.ADAPI(self.AD, self.config_model)
147147

148-
@utils.sync_decorator
149-
async def get_plugin_api(self, plugin_name: str) -> Callable:
150-
return await self.AD.plugins.get_plugin_api(
151-
plugin_name,
152-
self.name,
153-
self._logging,
154-
self.args,
155-
self.config_model,
156-
self.app_config,
157-
self.global_vars,
158-
)
148+
def get_plugin_api(self, plugin_name: str):
149+
app_cfg = self.app_config.root[self.name]
150+
plugin_api = self.AD.plugins.get_plugin_api(plugin_name, app_cfg)
151+
return plugin_api
159152

160153
#
161154
# Constraints

appdaemon/models/config/plugin.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@ class PluginConfig(BaseModel, extra="allow"):
2020
"""Delay between refreshes of the complete plugin state in the utility loop"""
2121
refresh_timeout: int = 30
2222
use_dictionary_unpacking: bool = True
23-
module_name: str = None
24-
class_name: str = None
23+
24+
# Used by the AppDaemon internals to import the plugins.
25+
plugin_module: str = None
26+
plugin_class: str = None
27+
api_module: str = None
28+
api_class: str = None
2529

2630
connect_timeout: int | float = 1.0
2731
reconnect_delay: int | float = 5.0
@@ -36,11 +40,17 @@ def lower(cls, v: str, info: ValidationInfo):
3640

3741
@model_validator(mode="after")
3842
def custom_validator(self):
39-
if "module_name" not in self.model_fields_set:
40-
self.module_name = f"appdaemon.plugins.{self.type}.{self.type}plugin"
43+
if "plugin_module" not in self.model_fields_set:
44+
self.plugin_module = f"appdaemon.plugins.{self.type}.{self.type}plugin"
45+
46+
if "plugin_class" not in self.model_fields_set:
47+
self.plugin_class = f"{self.type.capitalize()}Plugin"
48+
49+
if "api_module" not in self.model_fields_set:
50+
self.api_module = f"appdaemon.plugins.{self.type}.{self.type}api"
4151

42-
if "class_name" not in self.model_fields_set:
43-
self.class_name = f"{self.type.capitalize()}Plugin"
52+
if "api_classname" not in self.model_fields_set:
53+
self.api_class = f"{self.type.capitalize()}"
4454

4555
return self
4656

appdaemon/plugin_management.py

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
from . import utils
1313
from .app_management import UpdateMode
1414
from .models.config.plugin import PluginConfig
15+
from .models.config import AppConfig
1516

1617
if TYPE_CHECKING:
17-
from appdaemon.appdaemon import AppDaemon
18+
from .adapi import ADAPI
19+
from .appdaemon import AppDaemon
1820

1921

2022
class PluginBase(abc.ABC):
@@ -282,13 +284,13 @@ def __init__(self, ad: "AppDaemon", config: dict[str, PluginConfig]):
282284
self.logger.info(
283285
msg,
284286
name,
285-
cfg.class_name,
286-
cfg.module_name,
287+
cfg.plugin_class,
288+
cfg.plugin_module,
287289
)
288290

289291
try:
290-
module = importlib.import_module(cfg.module_name)
291-
plugin_class: Type[PluginBase] = getattr(module, cfg.class_name)
292+
module = importlib.import_module(cfg.plugin_module)
293+
plugin_class: Type[PluginBase] = getattr(module, cfg.plugin_class)
292294
plugin: PluginBase = plugin_class(self.AD, name, self.config[name])
293295
namespace = plugin.config.namespace
294296

@@ -486,19 +488,12 @@ def required_meta_check(self):
486488
OK = False
487489
return OK
488490

489-
async def get_plugin_api(self, plugin_name, name, _logging, args, config, app_config, global_vars):
490-
if plugin_name in self.config:
491-
plugin = self.config[plugin_name]
492-
module_name = "{}api".format(plugin["type"])
493-
mod = __import__(module_name, globals(), locals(), [module_name], 0)
494-
app_class = getattr(mod, plugin["type"].title())
495-
api = app_class(self.AD, name, _logging, args, config, app_config, global_vars)
496-
if "namespace" in plugin:
497-
api.set_namespace(plugin["namespace"])
498-
else:
499-
api.set_namespace("default")
491+
def get_plugin_api(self, plugin_name: str, app_cfg: AppConfig) -> "ADAPI":
492+
if plugin_cfg := self.config.get(plugin_name):
493+
module = importlib.import_module(plugin_cfg.api_module)
494+
api_class: Type["ADAPI"] = getattr(module, plugin_cfg.api_class)
495+
api = api_class(self.AD, app_cfg)
496+
api.set_namespace(plugin_cfg.namespace)
500497
return api
501-
502498
else:
503499
self.logger.warning("Unknown Plugin Configuration in get_plugin_api()")
504-
return None

appdaemon/plugins/mqtt/mqttapi.py

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
from typing import Any, Callable, Optional, Union
1+
from typing import TYPE_CHECKING, Any, Callable, Optional, Union
22

33
import appdaemon.adapi as adapi
44
import appdaemon.adbase as adbase
55
import appdaemon.utils as utils
6-
from appdaemon.appdaemon import AppDaemon
7-
from appdaemon.models.config.app import AppConfig
8-
from appdaemon.plugins.mqtt.mqttplugin import MqttPlugin
6+
7+
from ...appdaemon import AppDaemon
8+
9+
if TYPE_CHECKING:
10+
from ...models.config import AppConfig
11+
from .mqttplugin import MqttPlugin
912

1013

1114
class Mqtt(adbase.ADBase, adapi.ADAPI):
@@ -54,21 +57,9 @@ def initialize(self):
5457
an more readable. These are documented in the following section.
5558
"""
5659

57-
_plugin: MqttPlugin
58-
59-
def __init__(self, ad: AppDaemon, config_model: AppConfig):
60-
"""Constructor for the app.
60+
_plugin: "MqttPlugin"
6161

62-
Args:
63-
ad: AppDaemon object.
64-
name: name of the app.
65-
logging: reference to logging object.
66-
args: app arguments.
67-
config: AppDaemon config.
68-
app_config: config for all apps.
69-
global_vars: reference to global variables dict.
70-
71-
"""
62+
def __init__(self, ad: AppDaemon, config_model: "AppConfig"):
7263
# Call Super Classes
7364
adbase.ADBase.__init__(self, ad, config_model)
7465
adapi.ADAPI.__init__(self, ad, config_model)
@@ -154,7 +145,7 @@ async def listen_event(self, callback: Callable, event: str = None, **kwargs: Op
154145
"""
155146

156147
namespace = self._get_namespace(**kwargs)
157-
plugin: MqttPlugin = self.AD.plugins.get_plugin_object(namespace)
148+
plugin: "MqttPlugin" = self.AD.plugins.get_plugin_object(namespace)
158149
topic = kwargs.get("topic", kwargs.get("wildcard"))
159150

160151
if plugin is not None:

0 commit comments

Comments
 (0)