Skip to content

OEM telematics mapping

Most fleets do not stream raw OBD-II — they rely on the OEM's own telematics API. This page maps the published vendor schemas onto the N2E IoT contract.

The pattern is the same for every vendor:

[OEM API] ──poll/subscribe──> [Adapter (your service)] ──> /iot/telemetry  (N2E)

The adapter is just a small worker that runs on a schedule (Mercedes / IVECO / CAT publish at minute-level cadence, not 1 Hz). It pulls vehicle status, transforms each field into N2E's snake_case schema, and forwards the result.

Where to run the adapter

Run the adapter inside the Encore monorepo as a new service (e.g. backend/iot-mb, backend/iot-iveco, backend/iot-cat) — that way it inherits your authentication, observability and deployment story. It pushes into the same telemetryTopic PubSub the WebSocket endpoint uses.

Mercedes-Benz Fleet API (trucks and vans)

Mercedes ships a single B2B fleet API at https://connectivity.mercedes-benz.com that powers both heavy-duty trucks and the Vans Connect program. Auth is OAuth 2.0 (client credentials) tied to a fleet contract.

Typical resources you'll consume:

  • GET /vehicles/{vin}/odometer
  • GET /vehicles/{vin}/fuel
  • GET /vehicles/{vin}/location
  • GET /vehicles/{vin}/engineState
  • GET /vehicles/{vin}/tirepressure
  • GET /vehicles/{vin}/serviceInterval

Responses follow the pattern:

json
{
  "odometer": { "value": "142307.1", "unit": "KILOMETERS", "timestamp": "2026-05-19T08:32:11Z" }
}

Field mapping

Mercedes-Benz fieldN2E TelemetryEvent fieldConversion
vehicle.vinvehicle_iduse the VIN as your N2E vehicleId, or look up a tenant-local id
odometer.value (KILOMETERS)odometer_kmparseFloat — already km
odometer.timestamptimestampISO-8601, copy as-is
location.latitudecoordinates.latfloat
location.longitudecoordinates.longfloat (note long, not lng)
vehicleSpeed.value (KILOMETERS_PER_HOUR)speed_kmhfloat
engineHours.valueengine_hoursfloat (hours)
engineSpeed.value (RPM)powertrain.engine_rpmint
engineCoolantTemperature.value (DEGREES_CELSIUS)powertrain.coolant_temp_cfloat
oilPressure.value (KILOPASCAL)powertrain.oil_pressure_kpafloat
fuelConsumptionRate.value (LITRES_PER_HOUR)powertrain.fuel_rate_lphfloat
(not exposed)powertrain.engine_torque_pctdefault 0 if unavailable
(not exposed)powertrain.boost_pressure_kpadefault 0
noxConcentration.value (PPM)powertrain.nox_ppmfloat

Adapter sketch

ts
// backend/iot-mb/api.ts
import { CronJob } from 'encore.dev/cron'
import { telemetryTopic } from '../iot/events'
import type { TelemetryEvent } from '../iot/types'
import { fetchMb } from './mb-client'

export const sync = new CronJob('sync-mb', {
  title: 'Pull Mercedes-Benz Fleet API',
  every: '1m',
  endpoint: poll,
})

export const poll = api({ method: 'POST', path: '/iot-mb/poll' }, async () => {
  for (const vin of await fleetVins()) {
    const [odo, loc, speed, eng] = await Promise.all([
      fetchMb(`/vehicles/${vin}/odometer`),
      fetchMb(`/vehicles/${vin}/location`),
      fetchMb(`/vehicles/${vin}/vehicleSpeed`),
      fetchMb(`/vehicles/${vin}/engineState`),
    ])
    const frame: TelemetryEvent = {
      vehicle_id: vin,
      timestamp: odo.timestamp,
      powertrain: {
        engine_rpm: Number(eng.engineSpeed?.value ?? 0),
        engine_torque_pct: 0,
        fuel_rate_lph: Number(eng.fuelConsumptionRate?.value ?? 0),
        coolant_temp_c: Number(eng.engineCoolantTemperature?.value ?? 0),
        oil_pressure_kpa: Number(eng.oilPressure?.value ?? 0),
        boost_pressure_kpa: 0,
        nox_ppm: Number(eng.noxConcentration?.value ?? 0),
      },
      speed_kmh: Number(speed.value ?? 0),
      odometer_km: Number(odo.value ?? 0),
      engine_hours: Number(eng.engineHours?.value ?? 0),
      coordinates: {
        lat: Number(loc.latitude),
        long: Number(loc.longitude),
      },
    }
    await telemetryTopic.publish(frame)
  }
})

IVECO ON

IVECO ON is IVECO's connected-services platform for trucks and buses. It exposes a REST API (OAuth 2.0) similar in shape to the Mercedes one. Field names are slightly different but the units are consistent.

IVECO ON fieldN2E TelemetryEvent fieldNotes
asset.id or vinvehicle_idprefer VIN
timestamp (ISO)timestampUTC
position.latcoordinates.lat
position.loncoordinates.longrename lonlong
vehicleSpeed (km/h)speed_kmh
totalOdometer (km)odometer_km
totalEngineHoursengine_hours
engineRpmpowertrain.engine_rpm
engineLoadPctpowertrain.engine_torque_pctapproximate proxy for torque%
fuelRate (L/h)powertrain.fuel_rate_lph
coolantTemperature (°C)powertrain.coolant_temp_c
oilPressure (kPa)powertrain.oil_pressure_kpaconvert from bar × 100 if needed
turboBoostPressure (kPa)powertrain.boost_pressure_kpa
defNoxOut (ppm)powertrain.nox_ppmdownstream NOx sensor

Adapter pattern is identical to the Mercedes one — only the auth and field names change.

VisionLink covers Cat® on-highway trucks, off-highway haulers and heavy equipment. The Unified Suite API exposes asset health and operational data.

VisionLink fieldN2E TelemetryEvent fieldNotes
serialNumber or assetIdvehicle_iduse serial for off-highway, VIN for on-highway
lastReportedTimetimestampISO-8601
location.latitudecoordinates.lat
location.longitudecoordinates.longrename
lastKnownSpeed (km/h)speed_kmhconvert from mph if applicable
cumulativeOperatingHoursengine_hours
currentHourMeterengine_hoursfallback when cumulative not present
cumulativeIdleHours(drop)not stored on the wire
fuelRemaining (%)(drop)use fuelConsumptionRate instead
fuelConsumptionRate (L/h)powertrain.fuel_rate_lph
engineSpeed (rpm)powertrain.engine_rpm
engineLoadFactor (%)powertrain.engine_torque_pctproxy for torque%
coolantTemperature (°C)powertrain.coolant_temp_c
oilPressure (kPa)powertrain.oil_pressure_kpa
intakeBoostPressure (kPa)powertrain.boost_pressure_kpa
aftertreatmentNoxOut (ppm)powertrain.nox_ppm
cumulativeDistance (km)odometer_kmfor on-highway haulers

Off-highway equipment

For excavators, dozers and other off-highway assets that don't have a meaningful odometer_km or speed_kmh, send 0 for those fields and rely on engine_hours for utilisation. The AI risk rules already tolerate zeroed motion fields.

Generic adapter checklist

When you write a new OEM adapter:

  1. Authenticate with the OEM (usually OAuth 2.0 client credentials). Cache the token and refresh on 401.
  2. List the VINs / asset ids your tenant is allowed to query.
  3. Schedule a poll at the OEM's recommended cadence (typically 60 s).
  4. For each asset, pull the resources you need and merge them into one TelemetryEvent.
  5. Drop fields the OEM doesn't expose — set them to 0 rather than omitting (the schema is non-optional).
  6. Publish to telemetryTopic so the rest of the pipeline (storage, AI risk, dashboard) lights up automatically.
  7. Add a last_seen timestamp per asset so you can surface stale feeds in the Logs module.

Trip-end mapping

OEM APIs typically expose a trip or journey resource that closes when the ignition turns off. Map them to the trip-end payload:

OEM conceptN2E TripEndEvent field
trip.id / journey.uuidtrip_id
trip.endedAtend_timestamp
trip.videoFileSizeGb (if dashcam integrated)video_metadata.file_size_gb
trip.durationMinutesvideo_metadata.duration_minutes

If the OEM does not stream dashcam metadata, send zeros. The trip-end pipeline keys off vehicle_id + trip_id only.

Field reference disclaimer

Field names above reflect each OEM's publicly documented API surface at the time of writing. Vendor APIs evolve — always confirm exact resource paths, units, and authentication scopes with the OEM's developer portal before going to production:

If a field is missing or the unit differs, do the conversion in your adapter — never change the N2E contract.

N2E Fleet Management User Guide.