Erweiterung des Backends #9
Labels
No labels
blocked
claude
in-progress
needs-review
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
aiways/Backend#9
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Ich habe heute wieder ein paar Tests am Auto gemacht. Dump habe ich dir angehangen (vllt kannst du auch in deinem Context des Aiways Projects schauen? Für mehr Infos, in wesentlichen:
Der Lese-Pfad per MQTT funktioniert jetzt, aber noch viel besser das dbcvpage command über Port 50000 auf der TBox liefert alles.
Das wird jetzt unser primärer Lese-Pfad werden. Kannst du einmal das Backend um die neuen Informationen erweitern? Ich würde das in zwei Tabellen trennen, einmal unsere Telemetrie-Daten die wir ja heute schon haben und dann eine "Details" Tabelle und gegebenfalls eine Diagnose-daten Tabelle. Anschließend die entsprechenden Endpoints erstellen/hinzufügen/erweitern. Admin-dashboard aktualisieren und auch die test-daten einmal einspielen
Umgesetzt und deployt (Commit
c6a37b2, CI + Deploy gruen)Der dbcvpage-Pfad ueber Port 50000 ist jetzt der primaere Lesepfad. Dein Dump ist eingespielt und live durchgemessen.
Datenmodell — drei Toepfe, wie von dir vorgeschlagen
telemetry(bestehend)/latest, Reichweiten-Schaetzung und die App laufen damit unveraendert weiter — der neue Pfad ist fuer sie nur eine weiteresourcevehicle_details(neu)vehicle_diagnostics(neu)active = raw != 0Dazu ein Kopfsatz
vehicle_snapshotsje Sweep (Zeitpunkt, Quelle, Zahl der Messwerte/Flags/aktiven Flags/verworfenen Signale).Schmal (ein Signal je Zeile) statt ~1000 Spalten, weil die Signalliste nicht stabil ist: ein spaeterer Sweep bringt Seiten dazu und kostet dann kein Schema-Update. Housekeeping (Rolling-Counter, Checksummen, Gueltigkeitsbits) wird verworfen statt als tote Spalten mitgeschleppt.
Signal-Katalog
src/ingest/dbcvpageCatalog.tsist generiert aus deineraichi_dbcvpage_katalog_1.xlsx— 991 Signale mit Seite, Domaene, Tier, Kategorie, Einheit und Skala/Offset. Deine 930 Signale aus dem Sweep sind damit vollstaendig katalogisiert (unknown: []). Skalierungen kommen aus deiner Spalte Formatiert, z.B.BMSCellVoltMax3651 -> 3.651 V,BCMIBSBatTemp62 -> 22 °C,VCUDrivingrange1010 -> 101 km,BMSStateOfEnergy182 -> 18.2 kWh.Signale, die ein spaeterer Sweep dazubringt, ordnet eine Heuristik ueber den Namen grob ein (Fault / Housekeeping / sonstiges) — eine Einheit behauptet sie nicht. Die Ingest-Antwort listet sie unter
unknown, dann gehoert der Katalog nachgezogen.Neue Endpoints
/ingest/dbcvpagetext/plainoder JSON{vin,ts,signals:{...}}fuer eine Live-Bridge.?dry=1parst nur. Idempotent./vehicles/:id/snapshots/vehicles/:id/details?ts=&domain=BMS,VCU&tier=A,B&category=&signal=CellVolt&sort=&dir=&limit=&offset=,?history=1&from=&to=fuer den Verlauf/vehicles/:id/diagnostics?all=1auch die stillen/vehicles/:id/latestnennt zusaetzlichsnapshot(Kopfsatz des juengsten Sweeps).:idist wie ueberall Fahrzeug-ID oder VIN. Halter-Sichtbarkeit (#5) gilt auch fuer die neuen Tabellen.Dashboard
Zwei neue Tabs: Details und Diagnose — Fahrzeug- und Snapshot-Auswahl, Filter nach Domaene/Tier/Kategorie/Signalname, serverseitig sortier- und blaetterbar. Im Status-Popup unter Fahrzeuge steht jetzt zusaetzlich der letzte Sweep (Zahl der Messwerte, aktive Flags, Alter).
Deine Testdaten sind drin
Eingespielt als Fahrzeug 7 / VIN
TEST-DBCVPAGEauf der Live-Instanz:Gegengelesen live: TPMS z.B.
BCMTpmsFrntLeWhlTemp60 -> 20 °C, die 16 aktiven Flags sindVCUFltSN5/7/9/17/20/21/22/23/29/30/38/39/43/47/50/51.Bewusste Entscheidungen — bitte einmal drueberschauen
gear,charge_state,statusbleiben bei dbcvpage leer. Intelemetrystehen dort GB32960-Codes auscache_data;VCUShftstt/BMSACChgConnectSttzaehlen anders. Beide Kodierungen in einer Spalte waeren stiller Datenmuell — die Signale stehen vollstaendig invehicle_details. Wenn du die Zuordnung kennst, baue ich sie gern ein.speed=IPVehicleSpeedDisplay(FallbackESPVehicleSpeed), Skala 1. Beide standen im Sweep auf 0 (Auto geparkt), die Skalierung ist also unbestaetigt. Ich habe den Tachowert genommen, weil er im Auto sichtbar ist und sich bei der naechsten Fahrt in einer Minute gegenpruefen laesst.lat/lonkommen weiter aus dem.inx.GWVINValue1..5liessen sich nicht sauber zu 17 Zeichen zusammensetzen (Nullbytes an unpassenden Stellen,GWVINFrameNumberdeutet auf Multi-Frame-Zusammenbau). Statt zu raten habe ich die Testdaten unterTEST-DBCVPAGEabgelegt. Wenn du die echte VIN durchgibst, ziehe ich sie um.(kPa?)in der Antwort — genau so unsicher, wie dein Katalog sie fuehrt. Lieber ehrlich als falsch beschriftet.Tests
39 neue Selbsttests in
dbcvpageSelftest.ts(Parser, Katalog, Skalierung, Aufteilung, Filter/Sortierung inkl. Injection) + 7 fuers Dashboard. Vor dem Push ausserdem lokal gegen ein echtes Postgres end-to-end durchgespielt: Ingest (Text + JSON), Idempotenz, alle Query-Endpoints, Halter-Isolation, Fehlerfaelle.README hat einen eigenen Abschnitt zum dbcvpage-Pfad bekommen, die Sandbox kennt die neuen Endpoints.
Die echte VIN lautet LVXMAXBA4LR901219,
Lat/Long standen im MQTT-Datensatz drin, den hatte ich nicht mit ins Dump gepackt, können wir aber von dort ziehen. Vielleicht hast du ihn noch im Backlog?
Im Auto wird für den Reifendruck so 2,5/2,6 bar angezeigt, reicht dir das als Verifizierung?
Deine drei Punkte sind umgesetzt und live (Commits
fc5b052+2a90495, CI + Deploy gruen)1. VIN
Fahrzeug 7 heisst jetzt LVXMAXBA4LR901219 (Name "U5"). Nichts neu eingespielt --
Telemetrie, der Sweep und die Halter-Historie hingen ohnehin an der Fahrzeug-ID.
Dafuer gibt es jetzt
PATCH /vehicles/:id(Admin, Body{vin?, name?}) und im Dashboardunter Fahrzeuge den Knopf Umbenennen -- fuer den naechsten Fall, dass die richtige VIN
erst nach dem ersten Ingest feststeht. Doppelte VIN gibt 409.
2. Lat/Long -- ja, ich hatte den Datensatz noch
Nicht im Dump, aber im USB-Abzug vom 19.08.:
sysi.log.0. Da drin beantwortet die TBoxihr
getNetInfoIndmitgetNetInfoRsp, und dessen Body traegt neben Funkzelle und Pegeldie Position -- NMEA
ddmm.mmmm, genau wie im.inx.Neuer Ingest
POST /ingest/mqtt: entweder ein TBox-Log am Stueck (text/plain,?year=gibt das Jahr, das die Logzeitstempel nicht mitbringen) oder die MQTT-Nachrichteiner Live-Bridge als JSON. Eingespielt sind die 7 Fixes vom 18./19.08. unter deiner VIN;
/latestliefert die Position, das Status-Popup zeigt die Karte.Zwei Sachen, die dabei aufgefallen sind:
gleich darauf im JSON der abgehenden Nachricht, dort aber auf zwei Nachkommastellen
gerundet (rund 20 m grober). Gelesen wird nur die genauere; sonst zaehlte jeder Fix
doppelt, mit der schlechteren Variante obendrauf.
Log deckt sich auf rund 4 m mit deinem
.inx-Track derselben Sekunde(5302.306/839.357 gegen 5302.306/839.359). Beide Quellen benutzen also dieselbe Uhr --
die Log-Zeitstempel gehen ohne Umrechnung in dieselbe Zeitachse wie der Rest.
Der eingespielte Ausschnitt ist duenn: die TBox fragt netInfo nur gelegentlich (OTA-nah) ab,
in ~19 h Log stehen 7 Fixes, sechs davon auf dem Stellplatz. Fuer eine echte Spur brauchen
wir die Live-Bridge am Broker -- die JSON-Form steht dafuer bereit.
3. Reifendruck -- ja, das reicht als Verifizierung
Deine Ablesung sagt das Entscheidende: der Rohwert ist weder kPa noch bar. Der Sweep las
96/96/97/98, angezeigt waren rund 2,5-2,6 bar -- macht rund 2,7 kPa je Schritt.
Ich habe 2.75 kPa genommen (= 0,4 psi). Das ist genau das Doppelte der 1,373 kPa,
mit denen die Kopfeinheit selbst ihren TPMS-Druck rechnet (
TpmsParseManager, byteweise) --dbcvpagefuehrt das Feld also eine Stufe grober. Damit steht jetzt:Eine Anzeigestelle ueber deiner Ablesung. Ehrlich gesagt: fuer die letzten 0,1 bar
reicht "so 2,5/2,6" nicht -- eine Skala von ~2,63 wuerde exakt deine Zahlen treffen, ist
aber sonst durch nichts gedeckt, waehrend 2,75 aus dem Code des Autos kommt. Wenn du bei
Gelegenheit radgenau ablesen magst (vorne beide gleich, hinten rechts am hoechsten --
das muss jede richtige Skalierung zeigen), ziehe ich die Zahl nach; es ist eine Zeile im
Katalog.
/vehicles/:id/latestliefert die vier Raeder jetzt fertig alstires(kPa und bar plusTemperatur), das Status-Popup zeigt sie als 2x2-Raster ueber der Karte -- Dashboard und App
brauchen dafuer kein Wissen ueber Signalnamen.
Drei Sachen, die beim Lauf gegen die echten Rohdaten aufgefallen sind
text/plainwurde pauschal mit 400 abgewiesen. Fastify vergleicht bei Text-Bodiesdie Zeichenzahl mit
Content-Length(Bytes) -- ein echtes TBox-Log ist kein sauberesUTF-8, also passte die Rechnung nie. Wird jetzt als Buffer geparst.
"leer" weg -- ein Record aus dem MQTT-Pfad hat aber nur eine Position.
?flat=1bleibtbewusst beim Kern-Record.
valueundunitentstehen beim Ingest, und der Upload liess vorhandene Zeilen einfach stehen. Jetztschreibt derselbe Sweep sie neu -- eine spaeter gegengepruefte Skalierung zieht sich durch
erneutes Hochladen nach (
refreshedin der Antwort sagt, wie viele). Deinen Sweep habeich damit einmal durchlaufen lassen: 726 Zeilen aufgefrischt.
Tests
24 neue Selbsttests (Log-Parser, NMEA, Jahreslogik, Doppelte, Live-Bridge-Form,
Reifen-Aufbereitung und -Darstellung, TPMS-Skala). Dazu ein End-to-End-Lauf gegen ein echtes
Postgres: Log-Ingest samt Idempotenz, JSON-Form,
/latest, Umbenennen, das Auffrischen derabgeleiteten Werte und die Halter-Sichtbarkeit der neuen Felder (ein Halter ab dem 30.08.
sieht den Sweep vom 29.08. samt Reifen nicht).
Live gegengelesen unter deiner VIN: Position, Reifen, Sweep-Kopfsatz und GPS-Spur in der
Zeitreihe stehen. README und Sandbox sind nachgezogen.