Hopefully, you've already written a few basic rules to capture useful information for your app, but sometimes you need to do more than just collect certain event types. 

This tutorial will help you create rules to meet some common needs of connected car apps:

  • Correlate Device ID and VIN

  • Extract Vehicle Odometer Support

  • Other Advanced Examples

To create these rules, you'll need to log in to the Dashboard app and go to the rule wizard page.

Correlate Device ID and VIN

Suppose you want to maintain a lookup table of device ID and VIN.

1 ) Since VIN is reported in every trip start, we'll write a rule to capture this information from that event.

2) Instead of using the suggested rule name, we'll indicate what we're using this rule to do: map device ID to VIN.

3) Next, we'll pick out the fields we want from the event: device ID, VIN, and timestamp, so we know how recent the information is.

4) Before creating the rule, we must choose a destination for the output of this rule.

Extract Vehicle Odometer Support

An odometer reading is provided in every UDP event, but whether or not that odometer reading comes from the vehicle or from the device is not provided in every event. So let's create a lookup table for vehicle odometer support.

1) Since vehicle odometer support is provided in a UDP GPS message, we'll collect it from this event.

2) Instead of using the suggested rule name, we'll indicate what we're using this rule to do: record vehicle odometer support.

3) Next, we'll pick out the fields we want from the event: device ID, vehicle odometer support, and timestamp, so we know how recent the information is.

4) Choose a destination for this data.

5) Since most devices are configured to send many GPS events in a trip, and we only want to get this message once per trip, we'll have to customize this rule further.

The UDP GPS message has trigger reasons (see explanation below from our event catalog), so we'll filter by trip start. This will reduce the number of times we get the odometer support event to once per trip.

6) On the customization page, we'll refine the type of event to capture.

The customized where clause is also written below for you to copy and paste.

where and(eq(body.message.type, 'GPSMessage'), eq(body.message.messageTriggerReason, 'TripStart'))

Other Advanced Examples

The sample rules below use advanced concepts of our rule syntax and cannot be created with the basic rule creator. If you're interested in using these rules wholesale or as templates, you can copy the text and paste it into the text box on the advanced rule page of the Dashboard.

Fuel Level Decrease Events Excluding Certain Tags

This rule looks for fuel level decrease events from devices that are not tagged with a staging or testing tag and modifies the JSON output.

create rule ProdFuelDecrease
using myMap = {
    eventId = header.eventId,
    deviceId = header.deviceId,
    timestamp = body.header.timestamp,
    tripNumber = body.header.tripNumber,
    gps = {
latitude = body.header.latitude,
longitude = body.header.longitude
},
    eventType = body.message.fuelEventType,
    previousFuelLevelInPct = body.message.previousFuelLevel,
    currentFuelLevelInPct = body.message.currentFuelLevel,
    fuelConsumedSinceTripStartInGal = body.message.cumulativeFuelConsumed
    }
where and(eq(body.message.fuelEventType, 'FuelLevelDecrease'), and(not(contains(header.tags, 'staging')), not(contains(header.tags, 'testing'))))
with amqp(body = json(bindings.myMap))

JSON Output of Rule

The example below shows how an event that matched the rule above would appear when it was delivered to your app.

{
  "eventId": "bf1de4b4-c08a-4b20-a89f-9247e7270f2a",
  "deviceId": "6020981918",
  "timestamp": "2018-03-31T20:12:18-05:00",
  "tripNumber": 3,
  "gps": {
"latitude": 42.279937744140625,
"longitude": -83.74799346923828
},
  "eventType": "FuelLevelDecrease",
  "previousFuelLevelInPct": 54,
  "currentFuelLevelInPct": 14,
  "fuelConsumedSinceTripStartInGal": 5.394000053405762,
}

Speeding Events Longer Than 60 Seconds

This rule looks for speeding end events where the duration was greater than or equal to 60 seconds and modifies the JSON output.

create rule LongSpeedingEvent
using myMap = {
    eventId = header.eventId,
    deviceId = header.deviceId,
    timestamp = body.header.timestamp,
    tripNumber = body.header.tripNumber,
    gps = {
latitude = body.header.latitude,
longitude = body.header.longitude
},
    eventType = 'LongSpeedingEvent',
    speedingStartLatitude = body.message.initialLatitude,
    speedingStartLatitude = body.message.initialLongitude,
    speedingStartOdometer = body.message.startODO,
    speedingDurationInSec = body.message.duration,
    speedingDistance = body.message.distance,
    peakSpeed = body.message.peakSpeed,
    avgSpeed = body.message.averageSpeed
    }
where and(eq(body.message.type, 'OverSpeedingMessageEnd'), gte(body.message.duration, 60))
with amqp(body = json(bindings.myMap))

JSON Output of Rule

The example below shows how an event that matched the rule above would appear when it was delivered to your app.

{
  "eventId": "89c5bace-3965-481b-bdcc-79cdb8d4b18c",
  "deviceId": "6020981918",
  "timestamp": "2018-05-23T02:22:58-04:00",
  "tripNumber": 124,
  "gps": {
"latitude": 42.06966781616211,
"longitude": -86.4334945678711
},
  "eventType": "LongSpeedingEvents",
  "speedingStartLongitude": -86.49169921875,
  "speedingStartLatitude": 42.04869079589844,
  "speedingStartOdometer": 6163,
  "speedingDurationInSec": 158,
  "speedingDistance": 5.300000190734863,
  "peakSpeed": 124,
  "avgSpeed": 122
}

Current or Pending DTC Events

This rule looks for either current or pending DTC events and modifies the JSON output.

Note: If the event is a pending DTC, there is no milStatus field, so the milOn value would be null instead of a boolean (compare the two JSON outputs below).

Note: The key that provides the numDtcRecords has different names in the two events. In order to select the array regardless of which event came in, I specified a back-up field using the pipe character.

create rule CurrentOrPendingDTCs
using myMap = {
    eventId = header.eventId,
    deviceId = header.deviceId,
    timestamp = body.header.timestamp,
    tripNumber = body.header.tripNumber,
    gps = {
latitude = body.header.latitude,
longitude = body.header.longitude
},
    eventType = body.message.type,
    milOn = body.message.milStatus,
    numDtcRecords = length(body.message.dtcSpnOrPidRecords | body.message.dtcRecords),
    dtcRecords = body.message.dtcSpnOrPidRecords | body.message.dtcRecords
    }
where or(eq(body.message.type, 'VehicleCurrentDTCInfo'), eq(body.message.type, 'VehiclePendingDTCInfo'))
with amqp(body = json(bindings.myMap))

JSON Output of Rule (Current DTC Event)

The example below shows how a current DTC event that matched the rule above would appear when it was delivered to your app.

{
  "eventId": "fde9ffa9-2a0d-4ba6-960a-98ec9417e6af",
  "deviceId": "6020981918",
  "timestamp": "2018-01-16T17:31:28-05:00",
  "tripNumber": 87
  "eventType": "VehicleCurrentDTCInfo",
  "gps": {
"latitude": 42.54637908935547,
"longitude": -83.79325103759766
},
  "milOn": true,
  "numDtcRecords": 4,
  "dtcRecords": [
"P3412",
"C2745",
"B0888",
"P2222"
]
}

JSON Output of Rule (Pending DTC Event)

The example below shows how a pending DTC event that matched the rule above would appear when it was delivered to your app.

{
  "eventId": "42f8ef4b-b64c-4e2a-8523-5d9f09d0a78f

  "deviceId": "6020981918"
  "eventType": "VehiclePendingDTCInfo",
  "timestamp": "2018-04-10T12:11:15-05:00",
  "tripNumber": 9
  "gps": {
"latitude": 42.54637908935547,
"longitude": -83.79325103759766
},
  "milOn": null,
  "numDtcRecords": 1,
  "dtcRecords": [
    "P3412"
    ]
}
Did this answer your question?