some fixes

This commit is contained in:
Ayzen
2026-06-04 18:33:38 +03:00
parent eacea436a4
commit 22942d9dc9
26 changed files with 1352 additions and 153 deletions
+17 -1
View File
@@ -12,7 +12,12 @@ from python_app.models.run_config_schema import (
PreprocessNotchModel,
RunConfigModel,
)
from python_app.models.run_config_validation import load_ring_payload, load_switch_payload, validate_gpr_model
from python_app.models.run_config_validation import (
load_control_button_payload,
load_ring_payload,
load_switch_payload,
validate_gpr_model,
)
def _as_dict(value: Any, context: str) -> dict[str, Any]:
@@ -82,6 +87,7 @@ def run_config_from_dict(payload: dict[str, Any]) -> RunConfigModel:
switches_payload = _as_dict(payload.get("switches"), "switches")
port1_payload = _as_dict(switches_payload.get("port1"), "switches.port1")
port2_payload = _as_dict(switches_payload.get("port2"), "switches.port2")
control_button_payload = _as_dict(payload.get("control_button"), "control_button")
run_payload = _as_dict(payload.get("run"), "run")
preprocess_payload = _as_dict(payload.get("preprocess"), "preprocess")
gpr_payload = _as_dict(payload.get("gpr"), "gpr")
@@ -245,6 +251,7 @@ def run_config_from_dict(payload: dict[str, Any]) -> RunConfigModel:
load_switch_payload(port1_payload, model.output_switch)
load_switch_payload(port2_payload, model.input_switch)
load_control_button_payload(control_button_payload, model.control_button)
model.apply_device_model_constraints()
model.runtime.settling_ms = int(run_payload.get("settling_ms", model.runtime.settling_ms))
@@ -477,6 +484,15 @@ def run_config_to_dict(model: RunConfigModel) -> dict[str, Any]:
"invert_logic": model.input_switch.invert_logic,
},
},
"control_button": {
"enabled": model.control_button.enabled,
"gpio_chip": model.control_button.gpio_chip,
"pin": model.control_button.pin,
"active_low": model.control_button.active_low,
"bias": model.control_button.bias,
"debounce_ms": model.control_button.debounce_ms,
"action": model.control_button.action,
},
"run": {
"settling_ms": model.runtime.settling_ms,
"idle_sleep_ms": model.runtime.idle_sleep_ms,
+22
View File
@@ -126,6 +126,27 @@ class SwitchModel:
invert_logic: bool = False
@dataclass(slots=True)
class ControlButtonModel:
"""Physical GPIO push-button that triggers a runtime action on press.
Default wiring: the button sits between the GPIO line and GND with the
internal pull-up enabled, so the line idles high and a press drives it low
(``active_low``). The watcher reacts to the press edge only, so one push
yields one action. Disabled by default so non-Pi hosts never touch GPIO.
"""
ACTION_CAPTURE_TMP_REFERENCE = "capture_tmp_reference"
enabled: bool = False
gpio_chip: str = "/dev/gpiochip0"
pin: int = -1
active_low: bool = True
bias: str = ""
debounce_ms: int = 50
action: str = ACTION_CAPTURE_TMP_REFERENCE
@dataclass(slots=True)
class RingEndpointModel:
"""Shared-memory ring endpoint description."""
@@ -266,6 +287,7 @@ class RunConfigModel:
preprocess: PreprocessModel = field(default_factory=PreprocessModel)
gpr: GprModel = field(default_factory=GprModel)
combos: list[ComboModel] = field(default_factory=list)
control_button: ControlButtonModel = field(default_factory=ControlButtonModel)
LIBREVNA_MODEL = "librevna"
LIBREVNA_MULTI_MODEL = "librevna_multi"
+21 -1
View File
@@ -4,7 +4,13 @@ from __future__ import annotations
from typing import Any
from python_app.models.run_config_schema import ComboModel, GprModel, RingEndpointModel, SwitchModel
from python_app.models.run_config_schema import (
ComboModel,
ControlButtonModel,
GprModel,
RingEndpointModel,
SwitchModel,
)
def load_switch_payload(
payload: dict[str, Any],
@@ -23,6 +29,20 @@ def load_switch_payload(
target.invert_logic = bool(payload.get("invert_logic", target.invert_logic))
def load_control_button_payload(
payload: dict[str, Any],
target: ControlButtonModel,
) -> None:
"""Populate control-button model from payload preserving defaults."""
target.enabled = bool(payload.get("enabled", target.enabled))
target.gpio_chip = str(payload.get("gpio_chip", target.gpio_chip))
target.pin = int(payload.get("pin", target.pin))
target.active_low = bool(payload.get("active_low", target.active_low))
target.bias = str(payload.get("bias", target.bias))
target.debounce_ms = int(payload.get("debounce_ms", target.debounce_ms))
target.action = str(payload.get("action", target.action))
def load_ring_payload(payload: dict[str, Any], target: RingEndpointModel) -> None:
"""Populate ring endpoint model from payload preserving defaults."""
target.name = str(payload.get("name", target.name))