From e68b4264513eb6daf2e1df66e1a52ce10365fd39 Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 22 Mar 2025 15:37:09 +0100 Subject: [PATCH] created roon_arc trigger --- cpu_governor_auto_adjust.xml | 24 +++++-- cpu_governor_auto_adjust/mapping.py | 5 +- cpu_governor_auto_adjust/schedule.py | 10 +-- cpu_governor_auto_adjust/triggers/__init__.py | 3 +- cpu_governor_auto_adjust/triggers/log.py | 65 +++++++++++++++++++ cpu_governor_auto_adjust/triggers/roon_arc.py | 7 ++ .../triggers/test_trigger1.py | 2 +- 7 files changed, 101 insertions(+), 15 deletions(-) create mode 100644 cpu_governor_auto_adjust/triggers/log.py create mode 100644 cpu_governor_auto_adjust/triggers/roon_arc.py diff --git a/cpu_governor_auto_adjust.xml b/cpu_governor_auto_adjust.xml index 0d1ba11..ad24570 100644 --- a/cpu_governor_auto_adjust.xml +++ b/cpu_governor_auto_adjust.xml @@ -7,21 +7,21 @@ test_trigger1 Info - run_once + sync 1 ondemand test_trigger2 Info - run_once + sync 3 conservative roon Info - callback + async 2 performance @@ -36,7 +36,7 @@ wakeup Info - run_once + sync 5 conservative @@ -46,8 +46,8 @@ cpu_load - Debug - run_once + Info + sync 5 performance @@ -57,5 +57,17 @@ 3 + + roon_arc + Debug + async + 5 + performance + + /home/martin/dev/roon_arc/RoonServer_log.txt + 1 + [Broker:Mobile] + + diff --git a/cpu_governor_auto_adjust/mapping.py b/cpu_governor_auto_adjust/mapping.py index 6359db1..382bfba 100644 --- a/cpu_governor_auto_adjust/mapping.py +++ b/cpu_governor_auto_adjust/mapping.py @@ -1,11 +1,12 @@ from types import MappingProxyType -from cpu_governor_auto_adjust.triggers import TestTrigger1, TestTrigger2, RoonTrigger, WakeupTrigger, CpuLoadTrigger +from cpu_governor_auto_adjust.triggers import TestTrigger1, TestTrigger2, RoonTrigger, WakeupTrigger, CpuLoadTrigger, RoonArcTrigger _trigger_mapping = { 'test_trigger1': TestTrigger1, 'test_trigger2': TestTrigger2, 'roon': RoonTrigger, 'wakeup': WakeupTrigger, - 'cpu_load': CpuLoadTrigger + 'cpu_load': CpuLoadTrigger, + 'roon_arc': RoonArcTrigger } trigger_mapping = MappingProxyType(_trigger_mapping) diff --git a/cpu_governor_auto_adjust/schedule.py b/cpu_governor_auto_adjust/schedule.py index 486d48d..c3607f3 100644 --- a/cpu_governor_auto_adjust/schedule.py +++ b/cpu_governor_auto_adjust/schedule.py @@ -42,14 +42,14 @@ class TriggerScheduler(AppClass): self.governor_control.set_governor(governor_name) - async def callback_trigger(self, _trigger: Trigger) -> None: + async def async_trigger(self, _trigger: Trigger) -> None: """Run a callback_trigger with a specific name and check its status at a given interval.""" await _trigger.async_run() while True: self.log.debug("callback trigger %s, state: %s", _trigger.name, _trigger.trigger_state) await asyncio.sleep(_trigger.config.interval_in_seconds) - async def run_once_trigger(self, _trigger: Trigger) -> None: + async def sync_trigger(self, _trigger: Trigger) -> None: """Run a trigger with a specific name at a given interval.""" while True: start = monotonic() @@ -60,10 +60,10 @@ class TriggerScheduler(AppClass): async def start_trigger(self, _trigger: Trigger) -> None: """Start a new trigger.""" - if _trigger.config.type == "callback": - self.loop.create_task(self.callback_trigger(_trigger)) + if _trigger.config.type == "async": + self.loop.create_task(self.async_trigger(_trigger)) else: - self.loop.create_task(self.run_once_trigger(_trigger)) + self.loop.create_task(self.sync_trigger(_trigger)) self.running_triggers.append(_trigger) async def stop_triggers(self) -> None: diff --git a/cpu_governor_auto_adjust/triggers/__init__.py b/cpu_governor_auto_adjust/triggers/__init__.py index 8c0fa95..9312d12 100644 --- a/cpu_governor_auto_adjust/triggers/__init__.py +++ b/cpu_governor_auto_adjust/triggers/__init__.py @@ -1,7 +1,8 @@ -__all__ = ["test_trigger1", "test_trigger2", "roon", "wakeup", "cpu_load"] +__all__ = ["test_trigger1", "test_trigger2", "roon", "wakeup", "cpu_load", "roon_arc"] from .test_trigger1 import TestTrigger1 from .test_trigger2 import TestTrigger2 from .roon import RoonTrigger from .wakeup import WakeupTrigger from .cpu_load import CpuLoadTrigger +from .roon_arc import RoonArcTrigger diff --git a/cpu_governor_auto_adjust/triggers/log.py b/cpu_governor_auto_adjust/triggers/log.py new file mode 100644 index 0000000..bbc429d --- /dev/null +++ b/cpu_governor_auto_adjust/triggers/log.py @@ -0,0 +1,65 @@ +from cpu_governor_auto_adjust.trigger import Trigger +from cpu_governor_auto_adjust.config import Config +import asyncio +from datetime import datetime, timedelta +from functools import cached_property + + +class LogTrigger(Trigger): + def __init__(self, _config: Config) -> None: + super().__init__(_config) + self.timestamp_last_active_change = datetime.now() - timedelta(minutes=self.timeout_in_minutes + 1) + + @cached_property + def file(self) -> str: + return self.config.custom_config['logFile'] + + @cached_property + def timeout_in_minutes(self) -> float: + return float(self.config.custom_config['timeoutInMinutes']) + + @cached_property + def trigger_words(self) -> list: + _trigger_words = [] + if 'triggerWord' not in self.config.custom_config: + self.config.custom_config['triggerWords'] = _trigger_words + elif isinstance(self.config.custom_config['triggerWord'], str): + _trigger_words.append(self.config.custom_config['triggerWord']) + elif isinstance(self.config.custom_config['triggerWord'], list): + _trigger_words = self.config.custom_config['triggerWord'] + else: + raise ValueError("triggerWord must be a string or a list of strings") + return _trigger_words + + def set_active(self) -> None: + self.timestamp_last_active_change = datetime.now() + if not self.active: + self.log.info("activating trigger, log file: %s, trigger words: %s, governor: %s", self.file, self.trigger_words, self.governor.name) + self.active = True + + def set_inactive(self) -> None: + if self.active: + self.log.info("deactivating trigger, log file: %s, trigger words: %s, governor: %s", self.file, self.trigger_words, self.governor.name) + self.active = False + + def _process_line(self, line: str) -> None: + for word in self.trigger_words: + if word in line: + self.log.debug(line.strip()) + self.set_active() + return + + async def read_log(self) -> None: + with open(self.config.custom_config['logFile'], 'r') as _file: + _file.seek(0, 2) # Move to the end of the file + while True: + line = _file.readline() + if line: + self._process_line(line) + else: + await asyncio.sleep(0.1) + if (datetime.now() - self.timestamp_last_active_change) > timedelta(minutes=self.timeout_in_minutes): + self.set_inactive() + + async def async_run(self) -> None: + await self.read_log() diff --git a/cpu_governor_auto_adjust/triggers/roon_arc.py b/cpu_governor_auto_adjust/triggers/roon_arc.py new file mode 100644 index 0000000..aeb5904 --- /dev/null +++ b/cpu_governor_auto_adjust/triggers/roon_arc.py @@ -0,0 +1,7 @@ +from cpu_governor_auto_adjust.triggers.log import LogTrigger +from cpu_governor_auto_adjust.config import Config + + +class RoonArcTrigger(LogTrigger): + def __init__(self, _config: Config) -> None: + super().__init__(_config) diff --git a/cpu_governor_auto_adjust/triggers/test_trigger1.py b/cpu_governor_auto_adjust/triggers/test_trigger1.py index ea05628..6fdf10a 100644 --- a/cpu_governor_auto_adjust/triggers/test_trigger1.py +++ b/cpu_governor_auto_adjust/triggers/test_trigger1.py @@ -8,5 +8,5 @@ class TestTrigger1(Trigger): def run(self) -> None: choices = [False, True] - self.log.info("run check code of %s", self.__class__.__name__) + self.log.debug("run check code of %s", self.__class__.__name__) self.active = random.choice(choices)