diff options
author | Devaev Maxim <[email protected]> | 2020-09-12 22:16:14 +0300 |
---|---|---|
committer | Devaev Maxim <[email protected]> | 2020-09-12 22:16:14 +0300 |
commit | bddabc4742ebd130020efc14c53675bf5c96e134 (patch) | |
tree | 610e48a656b83c0f04094f71f319eea6a0e77cfb /kvmd | |
parent | fa5e6735edababe8f1d429ec98162fb7d508e1e0 (diff) |
using libgpiod for the relay msd
Diffstat (limited to 'kvmd')
-rw-r--r-- | kvmd/apps/cleanup/__init__.py | 5 | ||||
-rw-r--r-- | kvmd/plugins/msd/relay.py | 84 |
2 files changed, 65 insertions, 24 deletions
diff --git a/kvmd/apps/cleanup/__init__.py b/kvmd/apps/cleanup/__init__.py index ce321f42..795841c5 100644 --- a/kvmd/apps/cleanup/__init__.py +++ b/kvmd/apps/cleanup/__init__.py @@ -48,11 +48,6 @@ def _clear_gpio(config: Section) -> None: ("atx_gpio/power_switch", config.atx.power_switch_pin), ("atx_gpio/reset_switch", config.atx.reset_switch_pin), ] if config.atx.type == "gpio" else []), - - *([ - ("msd_relay/target", config.msd.target_pin), - ("msd_relay/reset", config.msd.reset_pin), - ] if config.msd.type == "relay" else []), ]: if pin >= 0: logger.info("Writing 0 to GPIO pin=%d (%s)", pin, name) diff --git a/kvmd/plugins/msd/relay.py b/kvmd/plugins/msd/relay.py index 409d3d71..07e9f85e 100644 --- a/kvmd/plugins/msd/relay.py +++ b/kvmd/plugins/msd/relay.py @@ -35,12 +35,12 @@ from typing import Optional import aiofiles import aiofiles.base +import gpiod from ...logging import get_logger from ... import aiotools from ... import aiofs -from ... import gpio from ...yamlconf import Option @@ -152,6 +152,59 @@ def _explore_device(device_path: str) -> _DeviceInfo: ) +class _Gpio: + def __init__( + self, + target_pin: int, + reset_pin: int, + reset_delay: float, + ) -> None: + + self.__target_pin = target_pin + self.__reset_pin = reset_pin + self.__reset_delay = reset_delay + + self.__chip: Optional[gpiod.Chip] = None + self.__target_line: Optional[gpiod.Line] = None + self.__reset_line: Optional[gpiod.Line] = None + + def open(self) -> None: + assert self.__chip is None + assert self.__target_line is None + assert self.__reset_line is None + + self.__chip = gpiod.Chip("/dev/gpiochip0") + + self.__target_line = self.__chip.get_line(self.__target_pin) + self.__target_line.request("kvmd/msd-relay/target", gpiod.LINE_REQ_DIR_OUT, default_val=0) + + self.__reset_line = self.__chip.get_line(self.__reset_pin) + self.__reset_line.request("kvmd/msd-relay/reset", gpiod.LINE_REQ_DIR_OUT, default_val=0) + + def close(self) -> None: + if self.__chip: + self.__chip.close() + + def switch_to_local(self) -> None: + assert self.__target_line + self.__target_line.set_value(0) + + def switch_to_server(self) -> None: + assert self.__target_line + self.__target_line.set_value(1) + + @contextlib.asynccontextmanager + async def reset(self) -> AsyncGenerator[None, None]: + assert self.__reset_line + try: + self.__reset_line.set_value(1) + await asyncio.sleep(self.__reset_delay) + self.__reset_line.set_value(0) + yield + finally: + self.__reset_line.set_value(0) + + # ===== class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes def __init__( # pylint: disable=super-init-not-called @@ -165,13 +218,11 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes reset_delay: float, ) -> None: - self.__target_pin = gpio.set_output(target_pin, False) - self.__reset_pin = gpio.set_output(reset_pin, False) - self.__device_path = device_path self.__init_delay = init_delay self.__init_retries = init_retries - self.__reset_delay = reset_delay + + self.__gpio = _Gpio(target_pin, reset_pin, reset_delay) self.__device_info: Optional[_DeviceInfo] = None self.__connected = False @@ -202,6 +253,9 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes "reset_delay": Option(1.0, type=valid_float_f01), } + def sysprep(self) -> None: + self.__gpio.open() + async def get_state(self) -> Dict: storage: Optional[Dict] = None drive: Optional[Dict] = None @@ -245,26 +299,18 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes @aiotools.atomic async def __inner_reset(self) -> None: - try: - gpio.write(self.__reset_pin, True) - await asyncio.sleep(self.__reset_delay) - gpio.write(self.__reset_pin, False) - - gpio.write(self.__target_pin, False) + async with self.__gpio.reset(): + self.__gpio.switch_to_local() self.__connected = False - await self.__load_device_info() get_logger(0).info("MSD reset has been successful") - finally: - gpio.write(self.__reset_pin, False) @aiotools.atomic async def cleanup(self) -> None: try: await self.__close_device_file() finally: - gpio.write(self.__target_pin, False) - gpio.write(self.__reset_pin, False) + self.__gpio.close() # ===== @@ -283,7 +329,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes if self.__connected: raise MsdConnectedError() - gpio.write(self.__target_pin, True) + self.__gpio.switch_to_server() self.__connected = True get_logger(0).info("MSD switched to Server") @@ -294,12 +340,12 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes if not self.__connected: raise MsdDisconnectedError() - gpio.write(self.__target_pin, False) + self.__gpio.switch_to_local() try: await self.__load_device_info() except Exception: if self.__connected: - gpio.write(self.__target_pin, True) + self.__gpio.switch_to_server() raise self.__connected = False get_logger(0).info("MSD switched to KVM: %s", self.__device_info) |