Skip to content

fix(sniffer): history raw per address; annotation wins over template - #122

Merged
madejackson merged 1 commit into
mainfrom
fix/sniffer-history-raw-per-address-annotation-precedence
Oct 19, 2026
Merged

madejackson merged 1 commit into
mainfrom
fix/sniffer-history-raw-per-address-annotation-precedence

Conversation

@madejackson

Copy link
Copy Markdown

Problem

1. History „Raw" zeigt zu viele Wörter
Ein Block-Read (z.B. addr 0–7, 8 Regs) wurde als eine Zeile mit address = t.address gespeichert. rawValue war der komplette Wort-String (249 0 0 0 0 521 0 0) — auf der Zeile von addr 0. Der User will in der History jede Adresse als eigene Zeile sehen, deren Raw exakt das Wort an dieser Adresse ist.

2. Annotation (Bleistift) wurde vom Template überschrieben
enrichRegister ließ eine manuelle Annotation nur gelten, wenn kein Template (specKey) die Adresse besitzt (row.annotated && !row.specKey). War einem Register ein Template zugeordnet (z.B. thermokon-wrf06), gewann das Template immer — die vom User über den Stift gesetzte UOM (°F) und Converter-Formel wurden ignoriert. Außerdem trug der History-Pfad die Annotation gar nicht erst aus dem Store in die Zeile.

Lösung

  • getRegisterHistoryFlat: ein Response-Telegramm wird pro Wort in eine Zeile pro Adresse gesplittet (address = base + idx, words = [word], rawValue = String(word)). Die Adressen-Filterung (&address=) wird auf die aufgelöste Adresse angewendet.
  • Die manuelle Annotation (converter/uom/description/annotated) wird aus der gespeicherten Register-Zeile in die History-Zeile übernommen und in enrichRegister vor dem Template ausgewertet:
    • parsebare Formel (z.B. number * 2) → wird direkt angewendet;
    • nur UOM/Description annotiert (z.B. °F) → fällt zur Template-Interpretation durch, behält aber die annotierte Einheit/Beschreibung.
  • Unit-Tests für Splitting + Annotation-Vorrang ergänzt (backend/tests/server/snifferService_history_test.ts).

Tests

  • npx vitest run --config vitest.config.mts → 646 passed / 7 skipped, keine Failures
  • npx tsc --project tsconfig.production.json → ok
  • eslint auf geänderte Dateien → 0 Errors (nur vorbestehende Warning)

Verhalten nach dem Fix (History, Slave 5, thermokon-wrf06, 8-Wort-Read)

addr raw value uom description
0 249 24.9 °C temperature_si
1 0 – % relative_humidity
2 0 – – –
3 0 – – –
4 0 – – –
5 521 521 ppm co2
6 0 – – –
7 0 – – –

Annotierte °F-Zeile (addr 0, uom: °F, converter: number, Template zugeordnet): raw 250, value 25, uom °F, description Temperature.

…over template

- getRegisterHistoryFlat: a block read (e.g. addr 0..7) is now split into
  one row PER register address, each carrying only its own word for raw
  and value interpretation. Previously the whole word block was attached
  to the first address, so 'raw' showed values of neighbouring registers.
- The manual annotation (pencil: converter/uom/description) is now carried
  from the stored register row into history rows and takes precedence over
  the template spec - previously it was only honoured when no template
  owned the register. A parseable formula is applied directly; a bare
  uom/description annotation falls through to the template interpretation
  but keeps the annotated unit/description.
- add unit tests for both behaviours.
@madejackson
madejackson merged commit 1ec56d6 into main Oct 19, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant