created roon_arc trigger

This commit is contained in:
2025-03-22 15:37:09 +01:00
parent 43ab617625
commit e68b426451
7 changed files with 101 additions and 15 deletions
+18 -6
View File
@@ -7,21 +7,21 @@
<trigger> <trigger>
<name>test_trigger1</name> <name>test_trigger1</name>
<logLevel>Info</logLevel> <logLevel>Info</logLevel>
<type>run_once</type> <type>sync</type>
<intervalInSeconds>1</intervalInSeconds> <intervalInSeconds>1</intervalInSeconds>
<governor>ondemand</governor> <governor>ondemand</governor>
</trigger> </trigger>
<trigger> <trigger>
<name>test_trigger2</name> <name>test_trigger2</name>
<logLevel>Info</logLevel> <logLevel>Info</logLevel>
<type>run_once</type> <type>sync</type>
<intervalInSeconds>3</intervalInSeconds> <intervalInSeconds>3</intervalInSeconds>
<governor>conservative</governor> <governor>conservative</governor>
</trigger> </trigger>
<trigger> <trigger>
<name>roon</name> <name>roon</name>
<logLevel>Info</logLevel> <logLevel>Info</logLevel>
<type>callback</type> <type>async</type>
<intervalInSeconds>2</intervalInSeconds> <intervalInSeconds>2</intervalInSeconds>
<governor>performance</governor> <governor>performance</governor>
<customConfig> <customConfig>
@@ -36,7 +36,7 @@
<trigger> <trigger>
<name>wakeup</name> <name>wakeup</name>
<logLevel>Info</logLevel> <logLevel>Info</logLevel>
<type>run_once</type> <type>sync</type>
<intervalInSeconds>5</intervalInSeconds> <intervalInSeconds>5</intervalInSeconds>
<governor>conservative</governor> <governor>conservative</governor>
<customConfig> <customConfig>
@@ -46,8 +46,8 @@
</trigger> </trigger>
<trigger> <trigger>
<name>cpu_load</name> <name>cpu_load</name>
<logLevel>Debug</logLevel> <logLevel>Info</logLevel>
<type>run_once</type> <type>sync</type>
<intervalInSeconds>5</intervalInSeconds> <intervalInSeconds>5</intervalInSeconds>
<governor>performance</governor> <governor>performance</governor>
<customConfig> <customConfig>
@@ -57,5 +57,17 @@
<cooldownPeriodInMinutes>3</cooldownPeriodInMinutes> <cooldownPeriodInMinutes>3</cooldownPeriodInMinutes>
</customConfig> </customConfig>
</trigger> </trigger>
<trigger>
<name>roon_arc</name>
<logLevel>Debug</logLevel>
<type>async</type>
<intervalInSeconds>5</intervalInSeconds>
<governor>performance</governor>
<customConfig>
<logFile>/home/martin/dev/roon_arc/RoonServer_log.txt</logFile>
<timeoutInMinutes>1</timeoutInMinutes>
<triggerWord>[Broker:Mobile]</triggerWord>
</customConfig>
</trigger>
</triggers> </triggers>
</cpuGovernorAutoAdjust> </cpuGovernorAutoAdjust>
+3 -2
View File
@@ -1,11 +1,12 @@
from types import MappingProxyType 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 = { _trigger_mapping = {
'test_trigger1': TestTrigger1, 'test_trigger1': TestTrigger1,
'test_trigger2': TestTrigger2, 'test_trigger2': TestTrigger2,
'roon': RoonTrigger, 'roon': RoonTrigger,
'wakeup': WakeupTrigger, 'wakeup': WakeupTrigger,
'cpu_load': CpuLoadTrigger 'cpu_load': CpuLoadTrigger,
'roon_arc': RoonArcTrigger
} }
trigger_mapping = MappingProxyType(_trigger_mapping) trigger_mapping = MappingProxyType(_trigger_mapping)
+5 -5
View File
@@ -42,14 +42,14 @@ class TriggerScheduler(AppClass):
self.governor_control.set_governor(governor_name) 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.""" """Run a callback_trigger with a specific name and check its status at a given interval."""
await _trigger.async_run() await _trigger.async_run()
while True: while True:
self.log.debug("callback trigger %s, state: %s", _trigger.name, _trigger.trigger_state) self.log.debug("callback trigger %s, state: %s", _trigger.name, _trigger.trigger_state)
await asyncio.sleep(_trigger.config.interval_in_seconds) 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.""" """Run a trigger with a specific name at a given interval."""
while True: while True:
start = monotonic() start = monotonic()
@@ -60,10 +60,10 @@ class TriggerScheduler(AppClass):
async def start_trigger(self, _trigger: Trigger) -> None: async def start_trigger(self, _trigger: Trigger) -> None:
"""Start a new trigger.""" """Start a new trigger."""
if _trigger.config.type == "callback": if _trigger.config.type == "async":
self.loop.create_task(self.callback_trigger(_trigger)) self.loop.create_task(self.async_trigger(_trigger))
else: else:
self.loop.create_task(self.run_once_trigger(_trigger)) self.loop.create_task(self.sync_trigger(_trigger))
self.running_triggers.append(_trigger) self.running_triggers.append(_trigger)
async def stop_triggers(self) -> None: async def stop_triggers(self) -> None:
@@ -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_trigger1 import TestTrigger1
from .test_trigger2 import TestTrigger2 from .test_trigger2 import TestTrigger2
from .roon import RoonTrigger from .roon import RoonTrigger
from .wakeup import WakeupTrigger from .wakeup import WakeupTrigger
from .cpu_load import CpuLoadTrigger from .cpu_load import CpuLoadTrigger
from .roon_arc import RoonArcTrigger
+65
View File
@@ -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()
@@ -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)
@@ -8,5 +8,5 @@ class TestTrigger1(Trigger):
def run(self) -> None: def run(self) -> None:
choices = [False, True] 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) self.active = random.choice(choices)