polish(da12): auto-pull history on open; framer-cap HW note; seam tests (review)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -109,7 +109,7 @@ STALENESS = {
|
||||
"danger": (Color.DANGER, Color.DANGER_FILL),
|
||||
}
|
||||
|
||||
# Trend-chart series/element colors (DA-12 History dialog). 7-char #RRGGBB hex.
|
||||
# Trend-chart series/element colors (used by module chart dialogs). 7-char #RRGGBB hex.
|
||||
CHART = {
|
||||
"average": "#0096FF", # filtered-average line (brand azure)
|
||||
"current": "#7FB2D9", # instantaneous-current line (muted)
|
||||
|
||||
@@ -61,6 +61,7 @@ class HistoryDialog(QDialog):
|
||||
controller.historyChanged.connect(self._on_history_changed)
|
||||
controller.limitsChanged.connect(self._draw_limit_lines)
|
||||
self._reload()
|
||||
self.pull_history() # backfill {J} once on open (no-op if not connected)
|
||||
|
||||
def closeEvent(self, event) -> None:
|
||||
# Stop reacting to controller signals once closed (the controller outlives us).
|
||||
|
||||
@@ -136,6 +136,12 @@ not been validated against a real DA-12.** Items to confirm:
|
||||
several. Our decoder handles one frame = one batch; `MeasurementHistory.merge_backfill`
|
||||
accumulates and deduplicates across multiple calls, so either way is handled, but
|
||||
verify the frame count on hardware.
|
||||
**Framer cap:** `StreamFramer` (`cim_suite/modules/da12/protocol/framing.py`) has a
|
||||
4096-char incomplete-frame guard. A single `{J}` frame exceeding ~4096 chars
|
||||
(roughly >290 records) split across serial reads would be truncated. If hardware
|
||||
confirms one large `{J}` frame rather than multiple smaller ones, raise the
|
||||
`max_buffer` argument passed to `StreamFramer` in
|
||||
`cim_suite/modules/da12/domain/controller.py` accordingly.
|
||||
|
||||
2. **`{c}` → `{J}` round-trip** — send `request_history` for a sensor with known
|
||||
buffered records; confirm a `{J}` reply arrives within a normal response window
|
||||
|
||||
@@ -32,3 +32,10 @@ def test_noise_only_does_not_grow_unbounded():
|
||||
f = StreamFramer(max_buffer=8)
|
||||
assert f.feed("z" * 50) == []
|
||||
assert len(f._buf) <= 8
|
||||
|
||||
|
||||
def test_framer_reassembles_frame_split_across_two_feeds():
|
||||
f = StreamFramer()
|
||||
assert f.feed("{J00000002\t60D54E80\t01") == [] # no close yet
|
||||
out = f.feed("36\t60D54EBC\t013B}")
|
||||
assert out == ["J00000002\t60D54E80\t0136\t60D54EBC\t013B"]
|
||||
|
||||
@@ -77,3 +77,11 @@ def test_dialog_disconnects_on_close(qtbot):
|
||||
dlg.close()
|
||||
ctrl._process("{C01\t0066}") # should NOT trigger a reload now
|
||||
assert dlg.point_count() == before
|
||||
|
||||
|
||||
def test_dialog_expected_interval_reads_setting_6(qtbot):
|
||||
ctrl = StationController()
|
||||
ctrl.settings.upsert(m.SettingLine(row=6, text="Update Interval\t30", type_code=0))
|
||||
dlg = HistoryDialog(ctrl, _record(sid=1), None)
|
||||
qtbot.addWidget(dlg)
|
||||
assert dlg._expected_interval_ms() == 30000
|
||||
|
||||
Reference in New Issue
Block a user