Files
radar_system/python_app/gui/controllers/control_button_controller.py
T
2026-10-06 12:32:26 +03:00

78 lines
3.0 KiB
Python

"""Bind the optional GPIO watcher to the shared reference-capture action."""
from collections.abc import Callable
import logging
from PyQt6.QtCore import QObject
from python_app.gui.control_button import ControlButtonWatcher
from python_app.gui.controllers.log_controller import LogController
from python_app.models.run_config_schema import ControlButtonModel
logger = logging.getLogger(__name__)
class ControlButtonController(QObject):
def __init__(self, parent: QObject, current_config: Callable[[], ControlButtonModel],
capture_reference: Callable[[], None], log: LogController) -> None:
super().__init__(parent)
self._config, self._capture_reference = current_config, capture_reference
self._log = log
self._watcher: ControlButtonWatcher | None = None
self._closed = False
def start(self) -> None:
if self._closed or self._watcher is not None:
return
config = self._config()
if not config.enabled:
return
if config.pin < 0 or not config.gpio_chip or config.action != ControlButtonModel.ACTION_CAPTURE_TMP_REFERENCE:
logger.warning("GPIO control button configuration is incomplete or unsupported; watcher not started")
return
watcher = None
try:
watcher = ControlButtonWatcher(chip=config.gpio_chip, pin=config.pin, active_low=config.active_low,
bias=config.bias, debounce_ms=config.debounce_ms, parent=self)
watcher.pressed.connect(self._pressed)
watcher.failed.connect(self._failed)
watcher.start()
self._watcher = watcher
logger.info("GPIO control button watching %s pin=%d action=%s", config.gpio_chip, config.pin, config.action)
except Exception:
logger.warning("Failed to start GPIO control button watcher", exc_info=True)
if watcher is not None:
self._disconnect(watcher)
watcher.deleteLater()
def _pressed(self) -> None:
if not self._closed and self._watcher is not None:
logger.info("GPIO control button pressed: capturing tmp reference")
with self._log.capture_errors():
self._capture_reference()
def _failed(self, message: str) -> None:
logger.warning("GPIO control button watcher stopped: %s", message)
def close(self) -> None:
self._closed = True
watcher, self._watcher = self._watcher, None
if watcher is None:
return
self._disconnect(watcher)
try:
watcher.stop()
except Exception:
logger.warning("Error stopping GPIO control button watcher", exc_info=True)
finally:
self._disconnect(watcher)
watcher.deleteLater()
@staticmethod
def _disconnect(watcher: ControlButtonWatcher) -> None:
for signal in (watcher.pressed, watcher.failed):
try:
signal.disconnect()
except (TypeError, RuntimeError):
pass