Note
This is a "gated" feature of AWS IoT FleetWise for which you will need to request access. See here for more information, or contact the AWS Support Center.
The "Last Known State" (LKS) feature of AWS IoT FleetWise provides a lightweight method to collect signal data from vehicles and forward it to downstream consumers via IoT topic. The AWS IoT FleetWise signal catalog, vehicle model, and decoder manifest are created as normal (for detailed information regarding these resource types, refer to the AWS IoT FleetWise Developer Guide). Instead of using a campaign to collect data, a state template is created to specify which signals to collect - either periodically or on-change of signal value. These signals are then collected by the Reference Implementation for AWS IoT FleetWise (FWE), and sent to the AWS IoT FleetWise cloud via MQTT in Protobuf format. The AWS IoT FleetWise cloud then decodes and forwards the data again via IoT topic in Protobuf format to the customer's application. This is illustrated in the following diagram.
- Access to an AWS Account with administrator privileges.
- Your AWS account has access to AWS IoT FleetWise "gated" features. See here for more information, or contact the AWS Support Center.
- Logged in to the AWS Console in the
us-east-1
region using the account with administrator privileges.- Note: if you would like to use a different region you will need to change
us-east-1
to your desired region in each place that it is mentioned below. - Note: AWS IoT FleetWise is currently available in these regions.
- Note: if you would like to use a different region you will need to change
- A local Windows, Linux or MacOS machine.
An Ubuntu 20.04 development machine with 200GB free disk space will be required. A local Intel x86_64 (amd64) machine can be used, however it is recommended to use the following instructions to launch an AWS EC2 Graviton (arm64) instance. Pricing for EC2 can be found, here.
-
Launch an EC2 Graviton instance with administrator permissions: Launch CloudFormation Template.
-
Enter the Name of an existing SSH key pair in your account from here.
- Do not include the file suffix
.pem
. - If you do not have an SSH key pair, you will need to create one and download the corresponding
.pem
file. Be sure to update the file permissions:chmod 400 <PATH_TO_PEM>
- Do not include the file suffix
-
Select the checkbox next to 'I acknowledge that AWS CloudFormation might create IAM resources with custom names.'
-
Choose Create stack.
-
Wait until the status of the Stack is CREATE_COMPLETE; this can take up to five minutes.
-
Select the Outputs tab, copy the EC2 IP address, and connect via SSH from your local machine to the development machine.
ssh -i <PATH_TO_PEM> ubuntu@<EC2_IP_ADDRESS>
-
Run the following on the development machine to clone the latest FWE source code from GitHub.
git clone https://github.com/aws/aws-iot-fleetwise-edge.git ~/aws-iot-fleetwise-edge
To quickly run the demo, download the pre-built FWE binary:
-
If your development machine is ARM64 (the default if you launched an EC2 instance using the CloudFormation template above):
cd ~/aws-iot-fleetwise-edge \ && mkdir -p build \ && curl -L -o build/aws-iot-fleetwise-edge.tar.gz \ https://github.com/aws/aws-iot-fleetwise-edge/releases/latest/download/aws-iot-fleetwise-edge-arm64.tar.gz \ && tar -zxf build/aws-iot-fleetwise-edge.tar.gz -C build aws-iot-fleetwise-edge
-
If your development machine is x86_64:
cd ~/aws-iot-fleetwise-edge \ && mkdir -p build \ && curl -L -o build/aws-iot-fleetwise-edge.tar.gz \ https://github.com/aws/aws-iot-fleetwise-edge/releases/latest/download/aws-iot-fleetwise-edge-amd64.tar.gz \ && tar -zxf build/aws-iot-fleetwise-edge.tar.gz -C build aws-iot-fleetwise-edge
Alternatively if you would like to build the FWE binary from source, follow these instructions. If you already downloaded the binary above, skip to the next section.
-
Install the dependencies for FWE :
cd ~/aws-iot-fleetwise-edge \ && sudo -H ./tools/install-deps-native.sh \ && sudo ldconfig
-
Compile FWE with Last Known State support:
./tools/build-fwe-native.sh --with-lks-support
cd ~/aws-iot-fleetwise-edge \
&& sudo -H ./tools/install-socketcan.sh \
&& sudo -H ./tools/install-cansim.sh
-
Run the following on the development machine to provision an AWS IoT Thing with credentials:
cd ~/aws-iot-fleetwise-edge \ && mkdir -p build_config \ && ./tools/provision.sh \ --region us-east-1 \ --vehicle-name fwdemo-lks \ --certificate-pem-outfile build_config/certificate.pem \ --private-key-outfile build_config/private-key.key \ --endpoint-url-outfile build_config/endpoint.txt \ --vehicle-name-outfile build_config/vehicle-name.txt \ && ./tools/configure-fwe.sh \ --input-config-file configuration/static-config.json \ --output-config-file build_config/config-0.json \ --log-color Yes \ --log-level Trace \ --vehicle-name `cat build_config/vehicle-name.txt` \ --endpoint-url `cat build_config/endpoint.txt` \ --can-bus0 vcan0 \ --certificate-file `realpath build_config/certificate.pem` \ --private-key-file `realpath build_config/private-key.key` \ --persistency-path `realpath build_config`
-
Run FWE:
./build/aws-iot-fleetwise-edge build_config/config-0.json
You should see a message similar to the following in the log, indicating that Last Known State is enabled:
[LastKnownStateWorkerThread.cpp:60] [start()]: [Last Known State Inspection Thread started]
The instructions below will register your AWS account for AWS IoT FleetWise, create a demonstration vehicle model and register the virtual vehicle created in the previous section:
-
Open a new terminal on the development machine and run the following to install the dependencies of the demo script:
cd ~/aws-iot-fleetwise-edge/tools/cloud \ && sudo -H ./install-deps.sh
-
Run the following command to generate 'node' and 'decoder' JSON files from the input DBC file:
python3 dbc-to-nodes.py hscan.dbc can-nodes.json \ && python3 dbc-to-decoders.py hscan.dbc can-decoders.json
-
Run the demo script:
./demo.sh \ --region us-east-1 \ --vehicle-name fwdemo-lks \ --node-file can-nodes.json \ --decoder-file can-decoders.json \ --network-interface-file network-interface-can.json
-
When the script completes, you should see messages in FWE log indicating that it received a decoder manifest. You should also see a periodic
CHECKIN:
message showing the decoder manifest.
-
Run the following command to create a state template to collect the brake pedal pressure and engine torque:
SIGNAL_CATALOG_ARN=`aws iotfleetwise list-signal-catalogs \ --region us-east-1 \ | jq -r ".summaries[0].arn"` \ && aws iotfleetwise create-state-template \ --region us-east-1 \ --signal-catalog-arn ${SIGNAL_CATALOG_ARN} \ --name fwdemo-lks-template \ --state-template-properties ' [ "Vehicle.ABS.DemoBrakePedalPressure", "Vehicle.ECM.DemoEngineTorque" ]'
-
Run the following command to deploy the state template to the vehicle with the update strategy of
onChange
to cause FWE to send data when the signal value changes:aws iotfleetwise update-vehicle \ --region us-east-1 \ --vehicle-name fwdemo-lks \ --state-templates-to-add ' [ { "identifier": "fwdemo-lks-template", "stateTemplateUpdateStrategy": { "onChange": {} } } ]'
At this point the state template has been deployed to the vehicle and the vehicle is sending the collected data to AWS IoT FleetWise cloud. In the next step a Python script is used to subscribe to the LKS data topic to receive the collected data for the given state template.
-
Since the data is serialized in Protobuf format, it is necessary to firstly generate the Python bindings for the message file last_known_state_message.proto as follows:
source ../install-deps-versions.sh \ && if [ "$(uname -m)" == "aarch64" ]; then PROTOBUF_ARCH="aarch_64"; else PROTOBUF_ARCH="$(uname -m)"; fi \ && PROTOC_PACKAGE="protoc-${VERSION_PROTOBUF_RELEASE/v/}-linux-${PROTOBUF_ARCH}" \ && wget https://github.com/protocolbuffers/protobuf/releases/download/${VERSION_PROTOBUF_RELEASE}/${PROTOC_PACKAGE}.zip -O ~/${PROTOC_PACKAGE}.zip \ && unzip ~/${PROTOC_PACKAGE}.zip -d ~/${PROTOC_PACKAGE} \ && ~/${PROTOC_PACKAGE}/bin/protoc \ -I=../../interfaces/protobuf/schemas/cloudToCustomer \ --python_out . \ ../../interfaces/protobuf/schemas/cloudToCustomer/last_known_state_message.proto
-
Finally run the following Python script to subscribe to the collected data:
python3 lks-subscribe.py \ --region us-east-1 \ --vehicle-name fwdemo-lks \ --template-name fwdemo-lks-template
When a state template is deployed to a vehicle, it doesn't start collecting data right away. We need to send commands to Activate the state templates.
-
Open a new terminal on the development machine and run the following to create an IAM role to create the command payloads:
SERVICE_ROLE_ARN=`./manage-service-role.sh \ --service-role IoTCreateCommandPayloadServiceRole \ --service-principal iot.amazonaws.com \ --actions iotfleetwise:GenerateCommandPayload \ --resources '*'`
-
Run the following to create a command:
aws iot create-command \ --region us-east-1 \ --role-arn ${SERVICE_ROLE_ARN} \ --command-id fwdemo-lks-command \ --namespace "AWS-IoT-FleetWise" \ --mandatory-parameters '[ {"name":"$stateTemplate.name"}, {"name":"$stateTemplate.operation"} ]'
-
Send a command to FWE:
JOBS_ENDPOINT_URL=`aws iot describe-endpoint --region us-east-1 --endpoint-type iot:Jobs | jq -j .endpointAddress` \ && ACCOUNT_ID=`aws sts get-caller-identity | jq -r .Account` \ && aws iot-jobs-data start-command-execution \ --region us-east-1 \ --command-arn arn:aws:iot:us-east-1:${ACCOUNT_ID}:command/fwdemo-lks-command \ --target-arn arn:aws:iot:us-east-1:${ACCOUNT_ID}:thing/fwdemo-lks \ --parameters '{ "$stateTemplate.name": { "S": "fwdemo-lks-template" }, "$stateTemplate.operation": { "S": "fetchSnapshot" } }' \ --endpoint-url https://${JOBS_ENDPOINT_URL}
-
You can then try different commands by repeating the command above but passing
activate
ordeactivate
as$stateTemplate.operation
. -
Since the
activate
operation takes additional parameters, you have to create a separate command if you want to set those parameters:aws iot create-command \ --region us-east-1 \ --role-arn ${SERVICE_ROLE_ARN} \ --command-id fwdemo-lks-command-activate \ --namespace "AWS-IoT-FleetWise" \ --mandatory-parameters '[ {"name":"$stateTemplate.name"}, {"name":"$stateTemplate.operation"}, {"name":"$stateTemplate.deactivateAfterSeconds","defaultValue":{"L":60}} ]'
-
Then send an
activate
command that will automatically deactivate the state template after a few seconds:JOBS_ENDPOINT_URL=`aws iot describe-endpoint --region us-east-1 --endpoint-type iot:Jobs | jq -j .endpointAddress` \ && ACCOUNT_ID=`aws sts get-caller-identity | jq -r .Account` \ && aws iot-jobs-data start-command-execution \ --region us-east-1 \ --command-arn arn:aws:iot:us-east-1:${ACCOUNT_ID}:command/fwdemo-lks-command-activate \ --target-arn arn:aws:iot:us-east-1:${ACCOUNT_ID}:thing/fwdemo-lks \ --parameters '{ "$stateTemplate.name": { "S": "fwdemo-lks-template" }, "$stateTemplate.operation": { "S": "activate" }, "$stateTemplate.deactivateAfterSeconds": { "L": 20 } }' \ --endpoint-url https://${JOBS_ENDPOINT_URL}
The collected data should be similar to the following:
Established mqtt subscription to $aws/iotfleetwise/vehicles/fwdemo-lks/last_known_state/fwdemo-lks-template/data with [<SubackReasonCode.GRANTED_QOS_1: 1>] Received message on topic: $aws/iotfleetwise/vehicles/fwdemo-lks/last_known_state/fwdemo-lks-template/data Received message: { "timeMs": "1712670086473", "signals": [ { "name": "Vehicle.ABS.DemoBrakePedalPressure", "doubleValue": 375.0 } ] } Received message on topic: $aws/iotfleetwise/vehicles/fwdemo-lks/last_known_state/fwdemo-lks-template/data Received message: { "timeMs": "1712670091473", "signals": [ { "name": "Vehicle.ECM.DemoEngineTorque", "doubleValue": 100.0 }, { "name": "Vehicle.ABS.DemoBrakePedalPressure", "doubleValue": 225.0 } ] }
-
-
Run the following to clean up resources created by the
provision.sh
anddemo.sh
scripts, and the calls to create and add the state template:cd ~/aws-iot-fleetwise-edge/tools/cloud \ && aws iotfleetwise update-vehicle \ --region us-east-1 \ --vehicle-name fwdemo-lks \ --state-templates-to-remove fwdemo-lks-template \ && aws iotfleetwise delete-state-template \ --identifier fwdemo-lks-template \ --region us-east-1 \ && ./clean-up.sh
-
Delete the CloudFormation stack created earlier, which by default is called
fwdemo-lks
: https://us-east-1.console.aws.amazon.com/cloudformation/home