How to send ruuvitag sensor data to the iota tangle with mam using a raspberry pi 3
The IOTA tangle (https://www.iota.org/) is a distributed ledger thought to be used for machine to machine economics. Compared to first and second generation distributed ledgers like bitcoin or ethereum, it does not use a blockchain, where blocks are written synchronously, but a so called tangle. In order to attach a transaction to the tangle,one needs to confirm two older transactions by doing a small proof of work. As each transaction confirms two earlier transaction, the scalability of the tangle is much better compared to classical blockchain based distributed ledgers. A further advantage is that there is no mining in IOTA and thus also no transaction fees. If you want to know more about the tangle and its structure, I highly recommand to watch the tutorials by mobilefish:
https://www.youtube.com/playlist?list=PLmL13yqb6OxdIf6CQMHf7hUcDZBbxHyza
Small amount of data can be written directly onto the tangle, by using for example MAM (masked authenticated messaging). This allows to write a stream of data to the tangle. Only people who are listening to the specific stream will then receive this data. As the data is masked (encrypted), nobody else can receive this data.
In this example, I use a ruuvitag. This small device generates weather data (temperature, humidity, air pressure, ...). I write it every 30 seconds to the tangle using mam. First, however, we need to read data from the ruuvitag. In this example, we will use javascript, because the IOTA mam client library is already written in javascript (I would love to use python instead...). First we need to install the bluetooth libraries, and you might also need libudev-dev:
sudo apt-get install bluez bluez-hcidump
sudo apt-get install libudev-dev
Then let's see if we can get some data out of the ruuvitag with javascript. We need the node.js ruuvitag library. All example code you can get from my github account. You can clone it with:
mkdir /home/pi/
git clone https://github.com/magictimelapse/ruuvitag-iota.git
cd ruuvitag-iota
Then we install the ruuvitag module. This module depends on noble, so we also install it:
npm install node-ruuvitag --production
npm install noble
This will take a moment. Let's see that there is no error, then open your favorite editor (e.g. nano) and write the following file, or find it in the folder called 1:
cd 1
const ruuvi = require('node-ruuvitag');
ruuvi.on('found', tag => {
console.log('Found RuuviTag, id: ' + tag.id);
tag.on('updated', data => {
console.log('Got data from RuuviTag ' + tag.id + ':\n' +
JSON.stringify(data, null, '\t'));
});
});
Save it as ruuvi-example.js. Run it with:
node ruuvi-example.js
Every couple of seconds there should be something like:
Got data from RuuviTag d6a08223138b:
{
"dataFormat": 3,
"rssi": -74,
"humidity": 72.5,
"temperature": 9.21,
"pressure": 98387,
"accelerationX": 5,
"accelerationY": -31,
"accelerationZ": 1067,
"battery": 3049
}
That's already the data from the ruuvitag in json format.
Now we only need to write this data to the tangle. Luckily, there is already a javascript module for that, which you can find in mobilefish's repository. For convenience, I copied it into the git repository in lib. Furthermore, we need the official javascript iota client and the moment javascript module:
cd /home/pi/ruuvitag-iota
npm install iota.lib.js
npm install moment
In the repository, you find in the 1 folder the two javascript file mam_receive.js and mam_publish.js. They are copied from mobilefish's repository, and adjusted such that they submit data to the IOTA main tangle. I selected a node from:
https://iotasalad.org/nodes
You can choose one yourself and change it. You can have different nodes for the data receiver and the data publisher! The script mam_publish.js generates random data and sends it via MAM to the tangle. Thus we can test if our connection to the tangle works before we marry it with the data read out from the ruuvitag. Run the publisher script with:
node mam_publish.js
And wait for some output:
json= { data: 84, dateTime: '25/12/2018 10:30:32' }, e.g.
Root: EKHZLDFNAMRZDICOMAQEGCHKI9GZXERCE99ZPKIXCJQCMEDQUOGTXECCSEUOJFFCVSOLFUCUY9ER9OXFE
Address: BFUJIFBIPC9KGBWCWGJLFHGMTRMBJYNUCDISZOLBGQPUVEIJZYSYINYIIKLWVXUVPWDBMNMNGBUKHGRNU
Copy the Root hash. Open a second terminal on the raspberry pi and run the receiver with the argument the root hash.
node mam_receive.js <ROOT HASH FROM ABOVE>
You will see after some time, that you receive the data you are submitting to the tangle:
received data
25/12/2018 10:55:00
70
As a last step, we need to marry the ruuvitag sensor readout with the mam_publish.js and adjust the mam_receive.js such that the data is displayed correctly. I do this in a probably very un-javascript way, by writing the data onto a global variable data_ruuvi, which is a json dictionary, and then instead of sending the random data, I send this global variable to the tangle. Works great as a proof of concept! You can use the script mam_publish_ruuvi.js in the repository:
node mam_publish_ruuvi.js
and get the output:
node mam_publish_ruuvi.js
json= {}
Root: XWYFDAEROSVOZZBOXNADSFOIAVZDVNIYKGRZOAVPBGUPDASQCRYKJZYWQMJK9TIFDUSQJIOSKEOIXFYKN
Address: 9ESZYNJHD9BAVAZOSOCVQMVHBKDHJWEIEAZHEMEPVMOXQJGREAVGPRLRVCHYMPC9QCEWZUVVRNHOMWCIL
Found RuuviTag, id: d6a08223138b
published data
undefined
undefined
XWYFDAEROSVOZZBOXNADSFOIAVZDVNIYKGRZOAVPBGUPDASQCRYKJZYWQMJK9TIFDUSQJIOSKEOIXFYKN
json= { dataFormat: 3,
rssi: -82,
humidity: 84,
temperature: 3.05,
pressure: 98876,
accelerationX: 2,
accelerationY: -30,
accelerationZ: 1071,
battery: 3019 }
Root: DEWOYDLUYJQPYZMOHELZBZHTJRFKZDNGSZSVXTLPNRDCUXAOIGFZEEAGL99YOVFLGEKRCUEZXWTKRCMSG
Address: SUYT9COUUWOCHTEZPPRVAARBCZLJQHKMLWTSH9ZVSIOEQXWVIVSVIPYHOKYUIKCUDKOELDFBTLUUGIFPJ
You see that in the first iteration, the ruuvitag was not ready, so an empty dictionary was send. In the second round, it worked.
You can receive this data with the same mam_receive.js script from above, just adjust to the new root:
node mam_receive.js <new root>
Remark: After checking out the repository, you can run
npm install
from the directory /home/pi/ruuvitag-iota
This will read the package.json file and install all dependencies.
Thanks for nice info