From a56c3ed36f0c6af0690593821d58fdc4ab676ddd Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 29 Mar 2025 21:35:57 +0100 Subject: [PATCH] CpuLoadTrigger: support low threshold instead of cooldown period --- cpu_governor_auto_adjust.xml | 14 ++-- cpu_governor_auto_adjust/triggers/cpu_load.py | 78 +++++++++++-------- pyproject.toml | 2 +- 3 files changed, 54 insertions(+), 40 deletions(-) diff --git a/cpu_governor_auto_adjust.xml b/cpu_governor_auto_adjust.xml index e5b9e0f..854ae63 100644 --- a/cpu_governor_auto_adjust.xml +++ b/cpu_governor_auto_adjust.xml @@ -46,20 +46,22 @@ cpu_load - Info + Debug sync 5 performance - 0.3 - 0.2 - 0.1 - 3 + 0.35 + 0.25 + 0.15 + 0.3 + 0.2 + 0.1 roon_arc - Debug + Info async 5 performance diff --git a/cpu_governor_auto_adjust/triggers/cpu_load.py b/cpu_governor_auto_adjust/triggers/cpu_load.py index da07e12..c4a1bd8 100644 --- a/cpu_governor_auto_adjust/triggers/cpu_load.py +++ b/cpu_governor_auto_adjust/triggers/cpu_load.py @@ -2,33 +2,43 @@ from cpu_governor_auto_adjust.trigger import Trigger from cpu_governor_auto_adjust.config import Config from functools import cached_property from os import getloadavg -from datetime import datetime, timedelta class CpuLoadTrigger(Trigger): def __init__(self, _config: Config) -> None: super().__init__(_config) - self.timestamp_last_governor_change = datetime.now() - timedelta(minutes=self.cooldown_period_in_minutes + 1) @cached_property - def one_minute_load_threshold(self) -> float: - return float(self.config.custom_config['oneMinuteLoadThreshold']) + def one_minute_high_threshold(self) -> float: + return float(self.config.custom_config['oneMinuteHighThreshold']) @cached_property - def five_minute_load_threshold(self) -> float: - return float(self.config.custom_config['fiveMinuteLoadThreshold']) + def five_minute_high_threshold(self) -> float: + return float(self.config.custom_config['fiveMinuteHighThreshold']) @cached_property - def ten_minute_load_threshold(self) -> float: - return float(self.config.custom_config['tenMinuteLoadThreshold']) + def ten_minute_high_threshold(self) -> float: + return float(self.config.custom_config['tenMinuteHighThreshold']) @cached_property - def threshold(self) -> tuple[float, float, float]: - return self.one_minute_load_threshold, self.five_minute_load_threshold, self.ten_minute_load_threshold + def high_threshold(self) -> tuple[float, float, float]: + return self.one_minute_high_threshold, self.five_minute_high_threshold, self.ten_minute_high_threshold @cached_property - def cooldown_period_in_minutes(self) -> float: - return float(self.config.custom_config['cooldownPeriodInMinutes']) + def one_minute_low_threshold(self) -> float: + return float(self.config.custom_config['oneMinuteLowThreshold']) + + @cached_property + def five_minute_low_threshold(self) -> float: + return float(self.config.custom_config['fiveMinuteLowThreshold']) + + @cached_property + def ten_minute_low_threshold(self) -> float: + return float(self.config.custom_config['tenMinuteLowThreshold']) + + @cached_property + def low_threshold(self) -> tuple[float, float, float]: + return self.one_minute_low_threshold, self.five_minute_low_threshold, self.ten_minute_low_threshold @property def current_load(self) -> tuple[float, float, float]: @@ -36,35 +46,37 @@ class CpuLoadTrigger(Trigger): self.log.debug("current load: %s", _current_load) return _current_load - def current_load_average_over_threshold(self) -> bool: - return any(load >= threshold for load, threshold in zip(self.current_load, self.threshold)) + @property + def current_load_average_over_high_threshold(self) -> bool: + return any(load >= threshold for load, threshold in zip(self.current_load, self.high_threshold)) + + @property + def current_load_average_over_under_threshold(self) -> bool: + return any(load <= threshold for load, threshold in zip(self.current_load, self.low_threshold)) def run(self) -> None: current_active = self.active - current_time = datetime.now() - new_active = self.current_load_average_over_threshold() + new_high_load_active = self.current_load_average_over_high_threshold + new_low_load_active = self.current_load_average_over_under_threshold - if not current_active and new_active: + if not current_active and new_high_load_active: self.log.info( - "activating trigger, load: %s, threshold: %s, governor: %s", - self.current_load, self.threshold, self.governor.name + "activating trigger, load: %s, high threshold: %s, governor: %s", + self.current_load, self.high_threshold, self.governor.name ) - self.timestamp_last_governor_change = current_time + self.active = True - elif current_active and new_active: - self.log.debug("trigger is already active, load: %s, threshold: %s", self.current_load, self.threshold) - self.timestamp_last_governor_change = current_time + elif current_active and new_high_load_active: + self.log.debug( + "trigger is already active, load: %s, high threshold: %s", + self.current_load, self.high_threshold + ) - elif current_active and not new_active: - if (current_time - timedelta(minutes=self.cooldown_period_in_minutes)) < self.timestamp_last_governor_change: - self.log.debug("cooldown period, staying on governor: %s, current load: %s", self.governor.name, self.current_load) - return - + elif current_active and new_low_load_active: self.log.info( - "deactivating trigger, load: %s, threshold: %s, governor: %s", - self.current_load, self.threshold, self.governor.name + "deactivating trigger, load: %s, low threshold: %s, governor: %s", + self.current_load, self.low_threshold, self.governor.name ) + self.active = False else: - self.log.debug("trigger is already inactive, load: %s, threshold: %s", self.current_load, self.threshold) - - self.active = new_active + self.log.debug("trigger is already inactive, load: %s, threshold: %s", self.current_load, self.high_threshold) diff --git a/pyproject.toml b/pyproject.toml index 864488f..3ce7433 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "cpu_governor_auto_adjust" -version = "0.2.9" +version = "0.3.1" description = "This application has been developed to automatically change cpu governor based on certain triggers." authors = [ { name = "Martin Reurekas", email = "martin@semrks.nl" }