From d57c3c66cdda02af7b4eae9f5d8aeab2f6d8f9ef Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Mon, 14 Jul 2025 18:15:39 +0300 Subject: [PATCH] atx: independent power/reset regions --- kvmd/plugins/atx/__init__.py | 3 ++- kvmd/plugins/atx/disabled.py | 4 ++++ kvmd/plugins/atx/gpio.py | 23 +++++++++++++++-------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/kvmd/plugins/atx/__init__.py b/kvmd/plugins/atx/__init__.py index d8bea96d..5f09f29a 100644 --- a/kvmd/plugins/atx/__init__.py +++ b/kvmd/plugins/atx/__init__.py @@ -54,7 +54,8 @@ class BaseAtx(BasePlugin): async def poll_state(self) -> AsyncGenerator[dict, None]: # ==== Granularity table ==== # - enabled -- Full - # - busy -- Partial + # - busy -- Partial, follows with acts + # - acts -- Partial, follows with busy # - leds -- Partial # =========================== diff --git a/kvmd/plugins/atx/disabled.py b/kvmd/plugins/atx/disabled.py index 60c2fa5b..a829acca 100644 --- a/kvmd/plugins/atx/disabled.py +++ b/kvmd/plugins/atx/disabled.py @@ -43,6 +43,10 @@ class Plugin(BaseAtx): return { "enabled": False, "busy": False, + "acts": { + "power": False, + "reset": False, + }, "leds": { "power": False, "hdd": False, diff --git a/kvmd/plugins/atx/gpio.py b/kvmd/plugins/atx/gpio.py index 578d2717..cfa7660f 100644 --- a/kvmd/plugins/atx/gpio.py +++ b/kvmd/plugins/atx/gpio.py @@ -75,7 +75,8 @@ class Plugin(BaseAtx): # pylint: disable=too-many-instance-attributes self.__long_click_delay = long_click_delay self.__notifier = aiotools.AioNotifier() - self.__region = aiotools.AioExclusiveRegion(AtxIsBusyError, self.__notifier) + self.__power_region = aiotools.AioExclusiveRegion(AtxIsBusyError, self.__notifier) + self.__reset_region = aiotools.AioExclusiveRegion(AtxIsBusyError, self.__notifier) self.__line_req: (gpiod.LineRequest | None) = None @@ -122,9 +123,15 @@ class Plugin(BaseAtx): # pylint: disable=too-many-instance-attributes ) async def get_state(self) -> dict: + power_busy = self.__power_region.is_busy() + reset_busy = self.__reset_region.is_busy() return { "enabled": True, - "busy": self.__region.is_busy(), + "busy": (power_busy or reset_busy), + "acts": { + "power": power_busy, + "reset": reset_busy, + }, "leds": { "power": self.__reader.get(self.__power_led_pin), "hdd": self.__reader.get(self.__hdd_led_pin), @@ -175,13 +182,13 @@ class Plugin(BaseAtx): # pylint: disable=too-many-instance-attributes # ===== async def click_power(self, wait: bool) -> None: - await self.__click("power", self.__power_switch_pin, self.__click_delay, wait) + await self.__click("power", self.__power_region, self.__power_switch_pin, self.__click_delay, wait) async def click_power_long(self, wait: bool) -> None: - await self.__click("power_long", self.__power_switch_pin, self.__long_click_delay, wait) + await self.__click("power_long", self.__power_region, self.__power_switch_pin, self.__long_click_delay, wait) async def click_reset(self, wait: bool) -> None: - await self.__click("reset", self.__reset_switch_pin, self.__click_delay, wait) + await self.__click("reset", self.__reset_region, self.__reset_switch_pin, self.__click_delay, wait) # ===== @@ -189,14 +196,14 @@ class Plugin(BaseAtx): # pylint: disable=too-many-instance-attributes return (await self.get_state())["leds"]["power"] @aiotools.atomic_fg - async def __click(self, name: str, pin: int, delay: float, wait: bool) -> None: + async def __click(self, name: str, region: aiotools.AioExclusiveRegion, pin: int, delay: float, wait: bool) -> None: if wait: - with self.__region: + with region: await self.__inner_click(name, pin, delay) else: await aiotools.run_region_task( f"Can't perform ATX {name} click or operation was not completed", - self.__region, self.__inner_click, name, pin, delay, + region, self.__inner_click, name, pin, delay, ) @aiotools.atomic_fg