Add LVSolarBuck64 firmware and debug console with uv support
STM32G474RB firmware for solar buck converter with MPPT, CC control, Vfly compensation, and adaptive deadtime. Includes Textual TUI debug console for real-time telemetry, parameter tuning, and SQLite logging. Added pyproject.toml for uv: `cd code64 && uv run debug-console` Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
102
code64/debug_console/widgets/param_group.py
Normal file
102
code64/debug_console/widgets/param_group.py
Normal file
@@ -0,0 +1,102 @@
|
||||
"""Editable parameter rows per controller group."""
|
||||
from textual.app import ComposeResult
|
||||
from textual.containers import Vertical, Horizontal
|
||||
from textual.widgets import Static, Input, Button
|
||||
|
||||
from ..protocol import ParamDef, PARAMS, build_param_write
|
||||
|
||||
|
||||
class ParamRow(Horizontal):
|
||||
"""Single parameter row with label, current value, input, and send button."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
ParamRow {
|
||||
height: auto;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
ParamRow .param-label {
|
||||
width: 16;
|
||||
height: 1;
|
||||
padding: 0 1;
|
||||
}
|
||||
ParamRow .param-value {
|
||||
width: 14;
|
||||
height: 1;
|
||||
padding: 0 1;
|
||||
color: $success;
|
||||
}
|
||||
ParamRow Input {
|
||||
width: 1fr;
|
||||
}
|
||||
ParamRow Button {
|
||||
width: 6;
|
||||
min-width: 6;
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, param: ParamDef, send_callback):
|
||||
super().__init__()
|
||||
self.param = param
|
||||
self._send_callback = send_callback
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Static(self.param.name, classes="param-label")
|
||||
yield Static("---", id=f"val_{self.param.id:02x}", classes="param-value")
|
||||
yield Input(placeholder="new", id=f"input_{self.param.id:02x}")
|
||||
yield Button("Go", id=f"btn_{self.param.id:02x}", variant="primary")
|
||||
|
||||
def set_current_value(self, value: float):
|
||||
fmt = self.param.fmt
|
||||
label = self.query_one(f"#val_{self.param.id:02x}", Static)
|
||||
label.update(f"{value:{fmt}}")
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
inp = self.query_one(Input)
|
||||
try:
|
||||
value = float(inp.value)
|
||||
except ValueError:
|
||||
return
|
||||
frame = build_param_write(self.param.id, self.param.ptype, value)
|
||||
self._send_callback(frame)
|
||||
inp.value = ""
|
||||
|
||||
def on_input_submitted(self, event: Input.Submitted) -> None:
|
||||
try:
|
||||
value = float(event.value)
|
||||
except ValueError:
|
||||
return
|
||||
frame = build_param_write(self.param.id, self.param.ptype, value)
|
||||
self._send_callback(frame)
|
||||
event.input.value = ""
|
||||
|
||||
|
||||
class ParamGroup(Vertical):
|
||||
"""A group of parameter rows for one controller."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
ParamGroup {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding: 0 1;
|
||||
margin: 0 0 1 0;
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, group_name: str, send_callback):
|
||||
super().__init__()
|
||||
self.group_name = group_name
|
||||
self._send_callback = send_callback
|
||||
self._params = [p for p in PARAMS if p.group == group_name]
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Static(f"[bold]{self.group_name} CONTROLLER[/bold]")
|
||||
for p in self._params:
|
||||
yield ParamRow(p, self._send_callback)
|
||||
|
||||
def update_param(self, param_id: int, value: float):
|
||||
for row in self.query(ParamRow):
|
||||
if row.param.id == param_id:
|
||||
row.set_current_value(value)
|
||||
return
|
||||
Reference in New Issue
Block a user