Decentralized Fleet Tracking with Blockchain
Last updated
Last updated
Asset tracking is a trend, but this project intends to work in a decentralized way storing each action, event or alert in a blockchain.
AdvancedFull instructions providedOver 3 days11,842
×
1
ELM327 OBDII - bluetooth
×
1
NEO-6M GPS
Disclaimer: I'm assuming that you are familiar with the technologies involved, such as PCB/schematic design tasks, nodejs development, soldering, and so on, since this is not a tutorial on how to solder or design PCB. I just want to show you how I designed a solution around asset tracking and blockchains.
This project is still in the documentation process, so the steps will be updated through the time.
The English language is not my native language, so may be some errors.
Asset tracking systems are a trend nowadays for the sake of security, resource optimisation and more. And as time goes on, we notice that by decentralizing asset tracking with a blockchain, we can validate each action of the assets as a transaction. That validation will be done by participants of the chain, making public (in some way) those actions and transactions in a secure space.
This approach allows the organisation to reach the CAP theorem, which affirms that there is no system that can cover that, but even this is violated by the blockchain. The blockchain can have:
Consistency
Availability
Having these 3 main features in an operation, the organisations can ensure that any action, event or transaction over its assets can be stored, validated and propagated, avoiding the missing information.
The project will be built using the following architecture:
The devices (the vehicles) will be collecting it's data using a custom device that can handle the OBDII messages, the gyroscope inclination and the GPS position and will be sent to the backend via GPRS module (Hologram Nova Modem). The message will be received and processed by the hologram platform. Then it will be routed to the Amazon API Gateway, which will act as a some sort of filter and will decide whether the message can be sent to the application or not.
Once the message is eligible to be processed, the message is sent to a microservice that runs in Amazon EC2. This service perform some decisions related to the message structure, the message history (based on a correlation ID) and other details that I'll cover later.
If the message can be processed according the rules, it's sent to Amazon IoT platform where each vehicle has a logical representation. This platform handles messages and acts according to configured rules. If the rules mark the message as eligible as an alarm or important event, that message will be sent to a lambda function, which will then send the message to a microservice that starts a transaction on the blockchain. If the transaction is stored in the blockchain succesfully, the service notifies all websockets subscribers (using the monitoring dashboard) to provide real time information (this step will not be covered in this phase of the project). As well, the service will send the message to Amazon Kinesis, which processes the event stream to allows us to have analytics over our realtime collected data. That stream also stores the valuable data on a S2 bucket.
When a transaction is stored in the blockchain, just to keep track of that transaction as a reference, the microservice will store that reference within as an Amazon Dynamo table.
The first step is to build the device that will read the OBDII data & GPS and send it to the backend. We will use the ELM327 Bluetooth reader, which allows us to read via Bluetooth the vehicle's data. For the Bluetooth connection and processing I'll use a Raspberry PI Zero W, which has a Bluetooth embedded module; this Raspberry PI Zero W also processes the GPS incoming data via I2C protocol. Those readings will be sent to the Amazon backend using the Hologram Nova modem.
According to the next schematic, we have to connect the GPS's TX pin to the Raspberry's RX pin and GPS's RX to the Raspberry's TX pin to ensure the serial communication. Also remember to wire the 5v and GND between them.
After the schematics design, I made a quick PCB and I milled it using my CNC.
I do not want to keep the GPS module and the Raspberry within the PCB area; I just want to have the pads of them in the PCB area.
The PCB looks like this:
I added a gyroscope to detect changes in the the angle of the vehicle to know of a possible accident (This feature is not covered in this version at software level, but I want to have it at hardware level).
Before writing the module software, we need a backend to talk to, so we need to setup our environment in order to get working on the server side software.
We need nodejs installed and some dependencies:
express
body-parser
As follows:
We need to setup global dependencies in order to access them from anywhere:
The npm init
command initialises our project in the current location; simply provide the information requested by npm. Now we have an empty structure with the node_modules directory within it.
First we need to include the required dependencies in a script that will be loaded from a main script; this script will be called webserver.js within the lib directory:
Also I defined the functions to be exported. The main structure is done.
Now we need to configure all the artifacts that the module will use in the configure function:
Now, start the webserver to listen for incoming requests in the start function:
Now we need an entry point that loads the modules we're writing; let's create a index.js script as an entry point:
Let's try our code:
Note: If you use nodemon rather than node, your changes will be reloaded on each file saving.
If you see a message like this:
... you are running a basic microservice so far.
Now that we have our webserver running, we need to define our endpoints:
Note that the received payload data is doubled base64 encoded, 1 from our device and 1 from the hologram cloud.
Before continuing writing our microservice code, we will define the IoT backend configuration to start receiving and sending data between the elements (see the reference architecture).
Go to https://console.aws.amazon.com and login to your AWS account to define the IoT configuration, and search for IoT:
On the IoT console, go to Manage > Types. From here we will define the basic structure for our things; a thing on Amazon IoT is a virtual representation of a real device.
Click on the 'Create' button and provide the data in the fields as follows:
Each searchable attribute is the data that differentiates each real thing; here I defined a vehicle's model and vehicle's VIN. You may define whatever you want.
Click on the 'create thing type' button to finish defining the new thing type.
Now, to create a virtual representation of our vehicle, go to Manage > Things and click on the 'Create' button.
Provide the data that will represent a real vehicle as follows:
See that we can define specific data for each vehicle based on the VehicleModelType we had defined before. Click on the 'Create thing' button.
Now, an important thing to do in order to publish data on behalf of our vehicle, we need to define the security schema; to do that, go to our vehicle definition, click on security option and click in the 'Create certificate' button. After that, download and save each file we will need in the next step. Also download the root CA file and click 'Activate'.
Finally we have to define a policy to be attached to the thing to allow the connection from our client; go to Secure > Policies > Create:
Click on 'Advanced mode' option and create a policy as follows:
Click on 'Create' and let's attach that policy to the thing; go to Manage > Thing > MyVehicle > Security > Click in the current certificate > click in 'Actions' > attach policy and select the created policy.
Now that we have the vehicle configured, we can begin coding the Amazon IoT client to send data from our vehicle to the backend.
The first thing to do is create a representation of our IoT thing locally; to do that, we'll create a javascript class within the lib directory as follows:
The only thing you need to update is the host property; that data can be obtained from the vehicle's details in the interact tab.
This class handles all the specific data for each device that can configure in the system.
Now, the handler will manage all the devices we configure and send messages on behalf of these to Amazon IoT:
Let's create a DeviceHandler.js file within the lib directory:
Now we have to instantiate the DeviceHandler from index.js as follows:
Now, let's process the incoming messages from our vehicle and send it to Amazon IoT; to do that, we need to receive the message in JSON format in the (already) defined endpoint and send it to Amazon IoT using the device definition we did in the previous step.
Add the next code to the /dh7/assetTracker/event end point:
This will look for a Thing (loaded from our config) and, if it exists, send the received message to Amazon IoT.
Let's start the server and post some random message to see the incoming message in Amazon IoT:
To see whether the message is received from MQTT, use the test client, subscribing to topic dh7/deviceMessage: