Publish GPS-data in a restricted channel and fetch the data from the tangle.
Prerequisites
- Raspberry Pi (I used the model 3B+) with internet connection
- GNSS-Module SAM-M8Q from u-blox
- NodeJS installed on your Raspi
Installation
You can download this repo to your Raspberry Pi and then run npm install to install all dependencies automatically.
npm-modules (also visible in package.json-file):
- @iota/mam v.0.7.3
- gps v.0.5.3
- serialport v.7.1.5
To install a npm module run npm install module_name.
Here's a small tutorial on how to track positional data over the IOTA tangle:
To connect your GNSS/GPS module to the Raspberry Pi you can use UART (Universal asynchronous receiver-transmitter):
Check this tutorial to see how GNSS/GPS data from the serial port can be viewed on the Raspberry Pi.
ℹ️ If the blue light of the GNSS/GPS module is blinking, you have GNSS reception.
ℹ️ If you receive something like $GPTXT,01,01,01,NMEA unknown msg*58, try to turn off the serial echo with stty -F /dev/ttyS0 -echo. It could as well be a short circuit.
Once you checked with cat /dev/ttyS0 that data is available, you can use this data inside a script.
The script checkGPS.js uses the npm module GPS.js to parse NMEA sentences from the serial port and log them in intervals to the terminal.
This is the data retrieved from the GPS state object:
let packet = {
time: gps.state.time,
lat: gps.state.lat,
lon: gps.state.lon,
alt: gps.state.alt,
speed: gps.state.speed,
processedLines: gps.state.processed,
}If this is working you are ready to publish the positional data to the tangle. By creating a restricted MAM channel, only people with the appropriate side key will be able to see the published data.
In this tutorial we first create a MAM state object and store it to a file. Like this the MAM state object will not be re-initialized in case the script execution crashes. I chose this solution as a hack to not overwrite old messages by re-using addresses.
Use mam_setup.js to setup the MAM state. Change seed and side key to your own. Do not use a seed that you use for other purposes. You can generate a new seed with cat /dev/urandom |tr -dc A-Z9|head -c${1:-81}.
The MAM state object will look something like this:
{
"subscribed":[],
"channel":{
"side_key":"MYSIDEKEY9999999999999999999999999999999999999999999999999999999999999999",
"mode":"restricted",
"next_root":null,
"security":2,
"start":0,
"count":1,
"next_count":1,
"index":0
},
"seed":"PHERELRURUYOJHR9KHTOESXYZTAIHIFRQSPAKNXBIIUIHRDZJQBIJVGIQYLXGVJELZZNDFYPKKR9JXEKO"
}As you can see, the start is at zero. Every published MAM message the index is increased by one.
In tracking.js the data packages are finally published to the tangle. First the mam state object is initialized and then changed to the one in the file. Then the data from the serial port is parsed and published to the tangle with
await Mam.attach(message.payload, message.address, 3, 9) If no GNSS data is available publishing will be skipped.
To fetch data from a restricted MAM channel you need a root and the side key of the channel. The actual fetch is performed with this statement:
await Mam.fetch(root, mode).then(data => {
data.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
}This will fetch the entire MAM channel starting from the given root. Depending on the number of messages this can take quite a while. An alternative method is to fetch the data and log it with a callback function (getCoordinate) like this:
await Mam.fetch(root,mode,sideKey,getCoordinate)If you would like to view the fetched data on a webpage take a look at weblogger.js which followed the example of this official IOTA tutorial.
Next step would be to display the fetched data on a map. I made a first example of that in my other repository IOTA-GPS-Tracker.
Please open an issue for support.
Please contribute using Github Flow. Create a branch, add commits, and open a pull request.
Credits to the IOTA foundation whose tutorials helped me to realize this project.
