diff --git a/appdaemon/__main__.py b/appdaemon/__main__.py index b46fbae29..a85a96558 100644 --- a/appdaemon/__main__.py +++ b/appdaemon/__main__.py @@ -124,7 +124,7 @@ def run(self, ad_config_model: AppDaemonConfig, *args, http): self.logger.info("Running AD using uvloop") uvloop.install() - loop: asyncio.BaseEventLoop = asyncio.new_event_loop() + loop: asyncio.AbstractEventLoop = asyncio.new_event_loop() # Initialize AppDaemon diff --git a/appdaemon/app_management.py b/appdaemon/app_management.py index 6ef8716ea..e672f01f9 100644 --- a/appdaemon/app_management.py +++ b/appdaemon/app_management.py @@ -513,11 +513,10 @@ async def create_app_object(self, app_name: str) -> None: def get_managed_app_names(self, include_globals: bool = False) -> set[str]: apps = set(name for name, o in self.objects.items() if o.type == "app") if include_globals: - globals = set( + apps |= set( name for name, cfg in self.app_config.root.items() if isinstance(cfg, GlobalModule) - ) - apps |= globals + ) # fmt: skip return apps def add_plugin_object(self, name: str, object: "PluginBase", use_dictionary_unpacking: bool = False) -> None: diff --git a/appdaemon/appdaemon.py b/appdaemon/appdaemon.py index 9e1097f28..70450cf85 100755 --- a/appdaemon/appdaemon.py +++ b/appdaemon/appdaemon.py @@ -113,9 +113,6 @@ def __init__(self, logging: "Logging", loop: BaseEventLoop, ad_config_model: App self.global_vars: Any = {} self.main_thread_id = threading.current_thread().ident - if not self.apps: - self.logging.log("INFO", "Apps are disabled") - # Initialize subsystems self.callbacks = Callbacks(self) self.events = Events(self) @@ -125,7 +122,9 @@ def __init__(self, logging: "Logging", loop: BaseEventLoop, ad_config_model: App self.state = State(self) self.futures = Futures(self) - if self.apps is True: + if not self.apps: + self.logger.info("Apps are disabled, skipping app management initialization") + else: assert self.config_dir is not None, "Config_dir not set. This is a development problem" assert self.config_dir.exists(), f"{self.config_dir} does not exist" assert os.access( @@ -146,12 +145,13 @@ def __init__(self, logging: "Logging", loop: BaseEventLoop, ad_config_model: App self.logger.info(f"Using {self.app_dir} as app_dir") self.app_management = AppManagement(self) - self.threading = Threading(self) - # Create ThreadAsync loop - self.logger.debug("Starting thread_async loop") - self.thread_async = ThreadAsync(self) - loop.create_task(self.thread_async.loop()) + self.threading = Threading(self) + + # Create ThreadAsync loop + self.logger.debug("Starting thread_async loop") + self.thread_async = ThreadAsync(self) + loop.create_task(self.thread_async.loop()) self.executor = ThreadPoolExecutor(max_workers=self.threadpool_workers) diff --git a/appdaemon/logging.py b/appdaemon/logging.py index 567e850de..f8b75f16a 100644 --- a/appdaemon/logging.py +++ b/appdaemon/logging.py @@ -5,7 +5,7 @@ import traceback import uuid from collections import OrderedDict -from logging import Logger, StreamHandler +from logging import LogRecord, Logger, StreamHandler from logging.handlers import RotatingFileHandler from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union @@ -40,7 +40,7 @@ def __init__(self, logger: logging.Logger, threshold: float, delay: float, timeo self.timeout = timeout self.last_log_time = None - def filter(self, record: logging.LogRecord) -> bool: + def filter(self, record: logging.LogRecord) -> bool | LogRecord: if record.msg == "Previous message repeated %s times": return True if self.threshold == 0: @@ -48,15 +48,14 @@ def filter(self, record: logging.LogRecord) -> bool: current_log = (record.module, record.levelno, record.msg, record.args) if current_log != self.last_log: self.last_log = current_log + result = True if self.filtering is True: - self.logger.info( - "Previous message repeated %s times", - self.current_count - self.threshold + 1, - ) + record.msg = "Previous message repeated %s times" + record.args = (self.current_count - self.threshold + 1,) + result = record self.current_count = 0 self.filtering = False self.start_time = None - result = True self.first_time = True self.last_log_time = datetime.datetime.now() else: diff --git a/appdaemon/plugin_management.py b/appdaemon/plugin_management.py index 2a4d73985..943c0a238 100644 --- a/appdaemon/plugin_management.py +++ b/appdaemon/plugin_management.py @@ -302,7 +302,12 @@ def __init__(self, ad: "AppDaemon", config: Mapping[str, PluginConfig]): # # Create app entry for the plugin so we can listen_state/event # - self.AD.app_management.add_plugin_object(name, plugin, self.config[name].use_dictionary_unpacking) + if not self.AD.config.disable_apps: + self.AD.app_management.add_plugin_object( + name, + plugin, + self.config[name].use_dictionary_unpacking + ) self.AD.loop.create_task(plugin.get_updates()) except Exception: diff --git a/appdaemon/utility_loop.py b/appdaemon/utility_loop.py index abe075cbf..0745dbf67 100644 --- a/appdaemon/utility_loop.py +++ b/appdaemon/utility_loop.py @@ -74,10 +74,14 @@ async def loop(self): # # Setup # - # self.AD.threading = Threading(self) + await self.AD.threading.init_admin_stats() - await self.AD.threading.create_initial_threads() - await self.AD.app_management.init_admin_stats() + if not self.AD.config.disable_apps: + await self.AD.threading.create_initial_threads() + await self.AD.app_management.init_admin_stats() + else: + await self.AD.threading.add_thread(silent=True) + self.total_threads = 1 # # Start the web server @@ -246,7 +250,8 @@ async def loop(self): # # Stop apps # - if self.AD.app_management is not None: + if not self.AD.config.disable_apps and \ + self.AD.app_management is not None: # fmt: skip await self.AD.app_management.terminate() #