Aller au contenu
Sylvain Joffraud l4w
Retour

Traccar `position.attributes` : bien plus que lat/lon

Quand on configure le forwarder JSON de Traccar (forward.type=json), le payload POSTé sur l’endpoint contient un objet position qui semble basique :

{
  "position": {
    "latitude": 47.20662,
    "longitude": -1.55239,
    "speed": 0,
    "fixTime": "2026-05-30T08:40:23.000Z"
  }
}

Sauf qu’il y a aussi un champ attributes qu’on néglige souvent à la première intégration :

"attributes": {
  "sat": 21,
  "rssi": 31,
  "battery": 4.12,
  "batteryLevel": 100,
  "charge": false,
  "motion": true,
  "ignition": false,
  "odometer": 0,
  "totalDistance": 635.42,
  "mode": 8,
  "blocked": false,
  "distance": 14.74
}

C’est là que les pépites se cachent.

Pourquoi c’est intéressant

Selon le protocole tracker, attributes contient potentiellement :

Le contenu exact varie selon le protocole (GT06, JT808, Teltonika, etc.). Traccar les normalise dans attributes.

Pattern de stockage flexible

Plutôt qu’une colonne par attribute possible, stocker tout en JSONB + extraire les fields-clés en colonnes dédiées pour les queries fréquentes :

ALTER TABLE positions
  ADD COLUMN battery     INT,      -- extrait pour query rapide
  ADD COLUMN attributes  JSONB;    -- tout le reste, queryable au besoin

Côté backend :

function extractBattery(attributes) {
  if (!attributes) return null;
  const lvl = attributes.batteryLevel;
  if (typeof lvl === 'number' && lvl >= 0 && lvl <= 100) return Math.round(lvl);
  const bat = attributes.battery;  // fallback voltage si pas de %
  if (typeof bat === 'number' && bat >= 0 && bat <= 100) return Math.round(bat);
  return null;
}

INSERT INTO positions (..., battery, attributes)
VALUES (..., $7, $8);  // [..., extractBattery(pos.attributes), JSON.stringify(pos.attributes)]

Bénéfices :

Lessons learned


Partager cet article :

Article précédent
`Access denied @localhost` : grant @'%' vs socket Unix
Article suivant
Leaflet : `L.geoJSON()` n’est pas un layer mais un groupe