feat(debug): add debug read with CSV export

- Parse F1 debug data via family-independent temp formula
  (bits 4-14 scaled by 2**(i-8), sign at bit 0)
- Save sensor+debug temps side-by-side to debug_info.csv
- Wire READ DEBUG button in StatusActionsPanel
- Rename ReplayChart → RunChart; move into GraphTab
- Extract PanelBox/SectionTitle/PanelSlider in ReadoutPanel
  to cut ~300 lines of duplicated styling
- Add rightRailWidth token to Theme for consistent rail sizing
- Wrap ReadoutPanel in ScrollView so Thresholds card stays
  reachable when E-C delta rows appear
This commit is contained in:
jack
2026-07-11 18:39:29 -07:00
parent fed4d9b590
commit 9e3bec9031
13 changed files with 349 additions and 451 deletions
@@ -18,9 +18,11 @@ from pygui.backend.models.data_model import TemperatureTableModel
from pygui.backend.utils import slot_error_boundary
from pygui.backend.visualization.graph_view import GraphView
from pygui.serialcomm.data_parser import (
convert_to_debug_temperatures,
convert_to_temperatures,
parse_binary_data,
remove_trailing_zeros,
save_debug_csv,
save_to_csv,
)
from pygui.serialcomm.serial_port import WaferInfo
@@ -555,10 +557,29 @@ class DeviceController(QObject):
self._debugFinished.emit({"error": "F1 read failed"})
return
fc = (
self._last_wafer_info.get("familyCode", "")
if self._last_wafer_info
else ""
)
sensor_hex = parse_binary_data(sensor_data, fc)
debug_hex = parse_binary_data(debug_data, fc)
if not sensor_hex or not debug_hex:
self._debugFinished.emit({"error": "Debug binary parse failed"})
return
temp_data = convert_to_temperatures(sensor_hex, fc)
debug_temp_data = convert_to_debug_temperatures(debug_hex)
csv_path = save_debug_csv(temp_data, debug_temp_data, self._save_data_dir)
if csv_path is None:
self._debugFinished.emit({"error": "Debug CSV save failed"})
return
self._debugFinished.emit({
"success": True,
"sensor_bytes": len(sensor_data),
"debug_bytes": len(debug_data),
"csv_path": csv_path,
})
except Exception as exc:
log.exception("Debug worker crashed: %s", exc)
@@ -572,10 +593,11 @@ class DeviceController(QObject):
self._set_connection_status("Connected")
sensor_bytes = result.get("sensor_bytes", 0)
debug_bytes = result.get("debug_bytes", 0)
self._append_log(
f"Debug read complete: {sensor_bytes} sensor bytes, "
f"{debug_bytes} debug bytes"
)
csv_path = result.get("csv_path", "")
msg = f"Debug read complete: {sensor_bytes} sensor bytes, {debug_bytes} debug bytes"
if csv_path:
msg += f", CSV written to {csv_path}"
self._append_log(msg)
else:
self._set_connection_status("Disconnected")
err_msg = result.get("error", "Debug read failed")