

AWS IoT FleetWise will no longer be open to new customers as of April 30, 2026. Existing AWS IoT FleetWise customers can continue using the service. The [Guidance for Connected Mobility on AWS](https://aws.amazon.com/solutions/guidance/connected-mobility-on-aws/) provides guidance on how to develop and deploy modular services for connected mobility solutions that can be used to achieve equivalent capabilities as AWS IoT FleetWise.

# Collect diagnostic trouble code data using AWS IoT FleetWise
<a name="diagnostic-trouble-codes"></a>

**Important**  
Access to certain AWS IoT FleetWise features is currently gated. For more information, see [AWS Region and feature availability in AWS IoT FleetWise](fleetwise-regions.md).

When a vehicle detects an error, it generates a diagnostic trouble code (DTC) and records a snapshot of the affected sensors or actuators. DTCs help you learn about errors in near real-time, understand what is causing them, and take corrective actions. AWS IoT FleetWise supports the collection of DTCs, including corresponding DTC snapshots and extended data through a data collection campaign. This topic introduces the concepts, workflows, and keywords that facilitate DTC data collection, illustrated with examples.

The following shows key concepts for using DTC.

**Custom defined functions**  
A custom defined function is the ability to invoke and execute your own functions predefined on the Edge Agent, extending the [custom decoding](network-agnostic-data-collection.md) concept. These functions are used in coordination with the AWS IoT FleetWise Agent. The Edge Agent for AWS IoT FleetWise software provides built-in functions for calculating signal statistics like minimum, maximum, and average values. A custom-defined function extends this capability by allowing you to create tailored logic for specific use cases. For diagnostic trouble code (DTC) data collection, developers can leverage custom functions to implement advanced data retrieval mechanisms, such as fetching DTC codes, snapshots, and extended data directly from the vehicle's Edge through Unified Diagnostic Services (UDS) or alternative diagnostic interfaces.   
For more information, see the [custom function guide](https://github.com/aws/aws-iot-fleetwise-edge/blob/main/docs/dev-guide/custom-function-dev-guide.md) and the [DTC data collection reference implementation](https://github.com/aws/aws-iot-fleetwise-edge/blob/main/docs/dev-guide/edge-agent-uds-dtc-dev-guide.md#dtc_query-function-implementation) in the *Edge Agent Developer Guide*.

**Signal fetching**  
In data collection campaigns, signals are typically collected continuously from a device and buffered on the Edge Agent software. Signals are then uploaded or stored periodically in time-based campaigns or triggered by specific conditions in condition-based campaigns. However, due to concerns about device traffic congestion, DTC signals can't be collected from devices and buffered continuously. To address this, AWS IoT FleetWise provides signal fetching, which ensures that the target signal is fetched discontinuously from a device.  
Signal fetching supports both periodic and condition-driven actions. You can define the fetching driven method, conditions, and exact actions using custom defined functions for each signal that should not be collected from a device continuously. For signals managed by the signal fetching mechanism, the trigger type and conditions for local storage or cloud upload are still governed by the `CollectionScheme`, both `timeBasedCollectionScheme` and `conditionBasedCollectionScheme` are supported, which is the same as regular signals.

The following topics show you how you can create and use DTCs.

**Topics**
+ [Diagnostic trouble code keywords](dtc-keywords.md)
+ [Create a data collection campaign for diagnostic trouble codes](dtc-data-collection.md)
+ [Diagnostic trouble code use cases](dtc-use-cases.md)

# Diagnostic trouble code keywords
<a name="dtc-keywords"></a>

**Important**  
Access to certain AWS IoT FleetWise features is currently gated. For more information, see [AWS Region and feature availability in AWS IoT FleetWise](fleetwise-regions.md).

**`signalsToFetch` parameter for create campaign**

Use the signalsToFetch syntax to configure how the signal information can be fetched on the Edge. Standard signal fetching is controlled by modeling as rules explicitly defined in a decoder manifest or custom defined through Edge First Modeling. With signals to fetch, you can define when and how data is fetched during campaigns. 

Signals to fetch allows the collection of DTC information. For example, you can create a signal of string type named `DTC_Info` that can contain DTC information for every engine control unit (ECU). Or, you can filter for a specific ECU.
+ `SignalFetchInformation` structure and param definitions.

  ```
  structure SignalFetchInformation {
      @required
      fullyQualifiedName: NodePath,
      @required
      signalFetchConfig: SignalFetchConfig,
      // Conditional language version for this config
      conditionLanguageVersion: languageVersion,
      @required
      actions: EventExpressionList,
  }
  ```
  + `fullyQualifiedName`: the fully qualified name (FQDN) of the signal that you want to use custom fetch for. 
  + `signalFetchConfig`: defines rules on how the above defined signals should be fetched. It supports time-based and condition-based fetch.
  + `conditionLanguageVersion`: the conditional language version used for parsing the expression in the config.
  + `actions`: a list of all action expressions evaluated on the Edge. The Edge will get the value of the defined signal.
**Important**  
Actions can only use `custom_function`.

## Campaign expression keywords
<a name="dtc-expression-keywords"></a>

The following expression takes a signal's fully qualified name supported by the vehicle and returns true if the signal doesn't have any data in the signal buffers on the Edge. Otherside, it returns false.

```
isNull(signalFqdn:String): Boolean
```

**Example usage**  

```
isNull($variable.`Vehicle.ECU1.DTC_INFO`) == false

We want to make sure DTC_Info signal is being generated
on edge.
```

This expression takes the following input:

**functionName:String**  
The name of the custom function that is supported by the Edge

**params: varargs*Expression***  
Parameters for `functionName`. This can be any list of expressions.  
Parameters support literal type: String, Int , Boolean, or Double.

```
custom_function(functionName:String, params: varargsExpression): Void
```

**Example usage**  

```
{
       "fullyQualifiedName":"Vehicle.ECU1.DTC_INFO",
       "signalFetchConfig":{
          "timeBased":{
             "executionFrequencyMs":2000
          }
       },
       "actions":"custom_function(“DTC_QUERY”, -1, 2, -1)"
    }
```

# Create a data collection campaign for diagnostic trouble codes
<a name="dtc-data-collection"></a>

**Important**  
Access to certain AWS IoT FleetWise features is currently gated. For more information, see [AWS Region and feature availability in AWS IoT FleetWise](fleetwise-regions.md).

This topic describes how to create a data collection campaign for diagnostic trouble codes (DTC).

1. Define a custom signal on the Edge. You need to define the decoding rules for the DTC signal on the Edge as a custom decoded signal. For more information, see [Tutorial: Configure network agnostic data collection using a custom decoding interface](network-agnostic-data-collection.md).

1. Define custom function on the Edge. You need to define a custom function for collecting DTC signals on the Edge at a compiled time.

   For more information, see the [custom function guide](https://github.com/aws/aws-iot-fleetwise-edge/blob/main/docs/dev-guide/custom-function-dev-guide.md ) and the [DTC data collection reference implementation](https://github.com/aws/aws-iot-fleetwise-edge/blob/main/docs/dev-guide/edge-agent-uds-dtc-dev-guide.md#dtc_query-function-implementation) in the *Edge Agent Developer Guide*.
**Note**  
An example custom defined function is `DTC_QUERY` as shown in the [demo script](https://github.com/aws/aws-iot-fleetwise-edge/blob/main/docs/dev-guide/edge-agent-uds-dtc-dev-guide.md).

1. Create a signal catalog that models a DTC signal as a string type.

   ```
   [
    {
       "branch": {
           "fullyQualifiedName": "Vehicle",
           "description": "Vehicle"
           }
         },
         {
       "branch": {
           "fullyQualifiedName": "Vehicle.ECU1",
           "description": "Vehicle.ECU1"
           }
         },
         {
       "sensor": {
           "fullyQualifiedName": "Vehicle.ECU1.DTC_INFO",
           "description": "Vehicle.ECU1.DTC_INFO",
           "dataType": "STRING"
         }
      }
    ]
   ```

1. Create and activate a vehicle model with the DTC signal added.

1. Create and activate a decoder manifest with the DTC signal added. The DTC signal should be a `CUSTOM_DECODING_SIGNAL` signal decoder type with a `CUSTOM_DECODING_INTERFACE` network interface type.  
**Example signal decoder**  

   ```
   [
     {
       "fullyQualifiedName": "Vehicle.ECU1.DTC_INFO",
       "interfaceId": "UDS_DTC",
       "type": "CUSTOM_DECODING_SIGNAL",
       "customDecodingSignal": {
         "id": "Vehicle.ECU1.DTC_INFO"
       }
     }
    ]
   ```  
**Example network interface**  

   ```
   [
     {
       "interfaceId": "UDS_DTC",
       "type": "CUSTOM_DECODING_INTERFACE",
       "customDecodingInterface": {
         "name": "NamedSignalInterface"
       }
     }
   ]
   ```
**Note**  
Controller Area Network (CAN) signals don't support the string data type.

1. Provision and create vehicles. The vehicles must utilize a vehicle model (model manifest) and decoder manifest that were activated in the previous steps.

1. Create and approve the campaign. You need to create a campaign by defining DTC signals (optionally with telemetry signals) and deploy it to vehicles.

1. Access the data in the defined destination. DTC data includes the `DTCCode`, `DTCSnapshot`, and `DTCExtendedDatastrings` as a raw string in the data destination defined in the campaign.

# Diagnostic trouble code use cases
<a name="dtc-use-cases"></a>

**Important**  
Access to certain AWS IoT FleetWise features is currently gated. For more information, see [AWS Region and feature availability in AWS IoT FleetWise](fleetwise-regions.md).

The following use cases assume the `DTC_QUERY` function was defined in the [demo script](https://github.com/aws/aws-iot-fleetwise-edge/blob/main/docs/dev-guide/edge-agent-uds-dtc-dev-guide.md).

## Periodic fetch
<a name="dtc-periodic-fetch"></a>

Fetch a DTC collection at configured intervals.

The following example is a campaign with periodic signal fetching of `Vehicle.DTC_INFO` for all DTCs with a status mask for all ECUs. There is a condition for data collected for `Vehicle.DTC_INFO`.

```
{
  "compression": "SNAPPY",
  "spoolingMode": "TO_DISK",
  "signalsToFetch": [
    {
      "fullyQualifiedName": "Vehicle.ECU1.DTC_INFO",
      "signalFetchConfig": {
        "timeBased": {
        // The FleetWise Edge Agent will query the UDS module for all DTCs every five seconds.
          "executionFrequencyMs": 5000
        }
      },
      "actions": [
      // Every five seconds, this action is called and its output is stored in the
      // signal history buffer of Vehicle.DTC_INFO
        "custom_function(\"DTC_QUERY\", -1, 2, -1)"
      ]
    }
  ],
  "signalsToCollect": [
    {
      "name": "Vehicle.ECU1.DTC_INFO"
    }
  ],
  "collectionScheme": {
    "conditionBasedCollectionScheme": {
      "conditionLanguageVersion": 1,
      // Whenever a new DTC is filled into the signal, the data is ingested.
      "expression": "!isNull($variable.`Vehicle.ECU1.DTC_INFO`)",
      "minimumTriggerIntervalMs": 1000,
      // Make sure that data is ingested only when there are new DTCs.
      "triggerMode": "RISING_EDGE"
    }
  },
  "dataDestinationConfigs": [
    {
      "s3Config": 
        {
          "bucketArn": "bucket-arn",
          "dataFormat": "PARQUET",
          "prefix": "campaign-name",
          "storageCompressionFormat": "GZIP"
        }
    }
  ]
}
```

## Condition-driven fetch
<a name="dtc-condition-fetch"></a>

Fetch a DTC collection when a condition is met. For example, when the CAN signal is `Vehicle.Ignition == 1`, fetch and upload the DTC data.

The following example campaign has condition-driven signal fetching of `Vehicle.ECU1.DTC_INFO` to check whether the DTC ("AAA123") is pending with recordNumber 1 for ECU-1. This campaign has time-based data collection and upload.

```
{
  "compression": "SNAPPY",
  "spoolingMode": "TO_DISK",
  "signalsToFetch": [
    {
      "fullyQualifiedName": "Vehicle.ECU1.DTC_INFO",
      "signalFetchConfig": {
        "conditionBased": {
        // The action will only run when the ignition is on.
          "conditionExpression": "$variable.`Vehicle.Ignition` == 1",
          "triggerMode": "ALWAYS"
        }
      },
      // The UDS module is only requested for the specific ECU address and the specific DTC Number/Status.
      "actions": ["custom_function(\"DTC_QUERY\", 1, 2, 8, \"0xAAA123\")"]
    }
  ],
  "signalsToCollect": [
    {
      "name": "Vehicle.ECU1.DTC_INFO"
    },
    {
      "name": "Vehicle.Ignition"
    }
  ],
  "collectionScheme": {
    "timeBasedCollectionScheme": {
      "periodMs": 10000
    }
  },
  "dataDestinationConfigs": [
    {
      "s3Config": 
        {
          "bucketArn": "bucket-arn",
          "dataFormat": "PARQUET",
          "prefix": "campaign-name",
          "storageCompressionFormat": "GZIP"
        }
    }
  ]
}
```

## On-demand fetch
<a name="fetch-dtc-for-fleet"></a>

Fetch a specific DTC for a fleet.

For an on-demand use case, you can use the same campaign as defined in the periodic fetch. The on-demand effect is achieved by suspending the campaign shortly after the campaign is deployed using the AWS IoT FleetWise console or by running the following CLI command.
+ Replace *command-name* with the command name.

```
aws iotfleetwise update-campaign \
    --name campaign-name \
    --action APPROVE
```

Then, suspend the campaign after the DTC data arrives.

```
aws iotfleetwise update-campaign \
    --name campaign-name \
    --action SUSPEND
```

You can resume the campaign again for DTC data fetching.

```
aws iotfleetwise update-campaign \
    --name campaign-name \
    --action RESUME
```