# LASS/Airbox and IOTA Integration
###### tags: `iota`
:::info
Collaboration between [LASS](http://lass-net.org/) community and [Distributed Ledger Labortory](http://dlt.csie.ncku.edu.tw/), National Cheng Kung University, Taiwan
Please contact `<jserv@ccns.ncku.edu.tw>` for further information.
:::
Overview: [LASS_and_IOTA_Integration.pdf](https://drive.google.com/open?id=1fYexv7dpHh9LJ0rTK_vjlse8EOtUSlhN)
Tutorial: [IOTA/TangleID + 空氣盒子教學](https://hackmd.io/s/H1HxM-2hz)
## What is IOTA?
* next generation public distributed ledger
* Tangle
* based on a Directed Acyclic Graph
* no Blocks
* no Chain
* no Miners
* ![](http://i.imgur.com/1vcRSLx.png)
* The Tangle Serguei Popov∗ October 1, 2017. Version 1.3
* features
* Scalability
* No Transaction Fees
* Decentralization
* Quantum-immunity
* [What is IOTA](https://iota.readme.io/docs/what-is-iota)
## What is LASS?
* "LASS" stands for "Location Aware Sensor System"
* open source and charity
* totally 5346 device in Taiwan (2018/2/10)
* [PM2.5 OPEN DATA PORTAL](https://pm25.lass-net.org/zh_tw/)
* [LASS - Data specification](https://paper.dropbox.com/doc/LASS-Data-specification-86K8vkbGWyCG7aMiP1odg)
* [LASS - data format](https://paper.dropbox.com/doc/LASS-data-format-Sk7rv3Omok5Sr4nkVO1Cd)
* Hack4U device
* [tutorial](https://paper.dropbox.com/doc/HACK4U4-Hack4u-87Live-TRmqFxXLJHXrKBo4kiR6O)
* ![Hack4U device](https://pm25.lass-net.org/LASS/assets/img/devices/HACK4U-87live-Zero.png)
## Why do we need IOTA for LASS?
* reduce latency and operating costs
* reduce the risk of attack and destruction
* ensure data integrity and proof-of-existence (PoE)
* reward platform, feedbacks with IOTA token
* ![](https://i.imgur.com/D5O0hyu.png)
## Technical Details
### Scenario
![](https://i.imgur.com/AyF4iNQ.png)
### Firmware Update
* USB
* OTA (regional network)
* [Ameba Arduino OTA](https://www.amebaiot.com/ameba-arduino-ota/)
* OTA (server) *(WIP)*
### Data Encoding
- [ ] Data
- header
| Field | Description | Values |
| ------------- |:--------------------------:| ------:|
| ver_format | MQTT record format version | 3 (default) |
| FAKE_GPS | GPS presence | 0 (GPS available), 1 (no GPS) |
| app | app name | |
| ver_app | LASS version | |
| device_id | unique | |
| gps_lon | longitude | |
| gps_lat | latitude | |
- body
- date / time
- string : 2017-12-17 07:01:55
- epoch : 1513494115 (32 bits)
- s_d0
- PM2.5
- 0 ~ 500 (16 bits)
- s_d1
- PM10
- 0 ~ 500 (16 bits)
- s_t0
- temperature
- -100 ~ 60 (8 bit)
- s_h0
- humidity
- 0 ~ 100 (8 bit)
- [ ] Huffman coding
* more common symbol <=> fewer bits
* difference between current and previous value
* e.g. temperature : 20, 21, 21, 19 => 20, +1, +0, -2
* analysis of historical data
* frequency for each symbol ('-50' ~ '49')
* ![](https://i.imgur.com/Fumigcm.png)
* there are **0.0108%** data out of -50 ~ 49
* discard these unreasonable data
* discard ratio : **0.0432%**
* Huffman’s algorithm pseudocode
```
http://cseweb.ucsd.edu/~kube/cls/100/Lectures/lec8/lec8-15.html
0. Determine the count of each symbol in the input message.
1. Create a forest of single-node trees. Each node in the initial forest represents a symbol from the set of possible symbols, and contains the count of that symbol in the message to be coded. Symbols with a count of zero are ignored (consider them to be impossible).
2. Loop while there is more than 1 tree in the forest:
2a. Remove the two trees from the forest that have the lowest count contained in their roots.
2b. Create a new node that will be the root of a new tree. This new tree will have those two trees just removed in step 2a as left and right subtrees. The count in the root of this new tree will be the sum of the counts in the roots of its subtrees. Label the edge from this new root to its left subtree “1”, and label the edge to its right subtree “0”.
2c. Insert this new tree in the forest, and go to 2.
3. Return the one tree in the forest as the Huffman code tree.
```
* result
| | compressed / uncompressed size | uncompressed / compressed size |
| -- | -- | -- |
| Theoretical value | 12.94 % | 7.73 |
| Experimental value | 9.784 % | 10.02 |
* Experimental
![](https://i.imgur.com/xbPPS3e.png)
```
-50 1110101010110111001
-49 1110101010110001111
-48 1110101010110101101
-47 1110101010110111000
-46 1110101010110110000
-45 1110101010110001100
-44 1110101010110011000
-43 1110101010110111101
-42 1110101010110100101
-41 1110101010110100010
-40 1110101010110010000
-39 1110101010110010111
-38 1110101010110011001
-37 1110101010110101100
-36 1110101010110010110
-35 1110101010110111111
-34 1110101010110111100
-33 1110101010110011111
-32 1110101010110101111
-31 1110101010110110100
-30 1110101010110110101
-29 1110101010110110111
-28 1110101010110010011
-27 1110101010110101011
-26 1110101010110001001
-25 1110101010110100001
-24 1110101010110100000
-23 1110101010110100110
-22 1110101010110000011
-21 1110101010110000010
-20 1110101010110010100
-19 111010101011111110
-18 1110101010110000000
-17 1110101010111000000
-16 111010101011111101
-15 111010101011111100
-14 111010101011111010
-13 111010101011100111
-12 111010101011100110
-11 111010101011100100
-10 111010101011100010
-9 111010101011101
-8 1110101010101
-7 1110101011
-6 111010100
-5 1110100
-4 1111
-3 0101
-2 110
-1 001
0 10
1 000
2 011
3 0100
4 11100
5 111011
6 11101011
7 11101010100
8 1110101010100
9 111010101011110
10 111010101011100001
11 111010101011100011
12 111010101011100101
13 111010101011111000
14 111010101011111001
15 111010101011111011
16 1110101010110110010
17 1110101010110110011
18 1110101010111000001
19 1110101010110000001
20 111010101011111111
21 1110101010110010101
22 1110101010110011010
23 1110101010110011011
24 1110101010110100111
25 1110101010110001000
26 1110101010110101010
27 1110101010110010010
28 1110101010110101110
29 1110101010110001010
30 1110101010110110001
31 1110101010110011100
32 1110101010110100100
33 1110101010110010001
34 1110101010110000111
35 1110101010110011110
36 1110101010110111110
37 1110101010110100011
38 1110101010110110110
39 1110101010110000110
40 1110101010110101001
41 1110101010110000101
42 1110101010110001101
43 1110101010110011101
44 1110101010110101000
45 1110101010110111011
46 1110101010110001011
47 1110101010110111010
48 1110101010110000100
49 1110101010110001110
```
- [ ] Base64
* represent binary data in an ASCII string
* 6 bits <=> 1 char
* `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`
- [ ] Compression Ratio
* datatype : **ASCII string**
* data : **body** (epoch, pm10, pm2.5, temperature, humidity)
* bundle **n-minutes** sensor data (default n = 10)
* uncompressed / compressed : 27n / (10.93 + 2.4n) , **7.73** (n = 10)
## [TangleID](https://tangleid.github.io/) API
* command: `new_claim`
* uuid: derive from MAC address
* msg: ver_format|FAKE_GPS|app|ver_app|device_id|gps_lon|gps_lat|latitude|encoded string
```
Make a HTTP request
POST /tangleid_backend/api/ HTTP/1.1
Host: 140.116.82.61
Content-Type: application/json
Content-Length: 185
{"command":"new_claim","uuid": "LASSBBMBOBABKBCBWAAB","part_a":"LASSBBMBOBABKBCBWAAB","part_b":"LASSBBMBOBABKBCBWAAB","exp_date":"","claim_pic":"","msg":"3|1|PM25|live|8CE7A927|120.971042|24.801909|Wn6jsKnVQAFuqqgALdVVCtVVSRVVU"}
```
* [TangleID API Reference](https://hackmd.io/s/SySrMTHJz)
## Data verification
*(WIP)*
```
$ cat Makefile
all:
g++ main.cpp encode.h -o main
test_one:
@./main
@python3 decode.py
diff test_input.txt test_output.txt
test:
for i in `seq 1 1 1000`; \
do \
make test_one ; \
done
```
```
$ make test
for i in `seq 1 1 1000`; \
do \
make test_one ; \
done
make[1]: Entering directory '/home/bevis/IOTA_LASS'
diff test_input.txt test_output.txt
make[1]: Leaving directory '/home/bevis/IOTA_LASS'
make[1]: Entering directory '/home/bevis/IOTA_LASS'
diff test_input.txt test_output.txt
make[1]: Leaving directory '/home/bevis/IOTA_LASS'
make[1]: Entering directory '/home/bevis/IOTA_LASS'
diff test_input.txt test_output.txt
...
```
## Open Data API
*(WIP)*
- python
```
$ python3 IOTAxLASS.py BBMBOBABKBCBWAAB
{
"device_id": "8CE7A927",
"s_t0": "24",
"app": "PM25",
"FAKE_GPS": "1",
"s_d0": "32",
"s_d1": "36",
"ver_format": "3",
"s_h0": "67",
"gps_lon": "120.971042",
"ver_app": "live",
"timestamp": "2018-02-02 16:31:11",
"gps_lat": "24.801909"
}
{
"device_id": "8CE7A927",
"s_t0": "24",
"app": "PM25",
"FAKE_GPS": "1",
"s_d0": "31",
"s_d1": "32",
"ver_format": "3",
"s_h0": "66",
"gps_lon": "120.971042",
"ver_app": "live",
"timestamp": "2018-02-02 16:32:11",
"gps_lat": "24.801909"
}
{
"device_id": "8CE7A927",
"s_t0": "24",
"app": "PM25",
"FAKE_GPS": "1",
"s_d0": "32",
"s_d1": "35",
"ver_format": "3",
"s_h0": "66",
"gps_lon": "120.971042",
"ver_app": "live",
"timestamp": "2018-02-02 16:33:11",
"gps_lat": "24.801909"
}
{
"device_id": "8CE7A927",
"s_t0": "24",
"app": "PM25",
"FAKE_GPS": "1",
"s_d0": "31",
"s_d1": "34",
"ver_format": "3",
"s_h0": "67",
"gps_lon": "120.971042",
"ver_app": "live",
"timestamp": "2018-02-02 16:34:11",
"gps_lat": "24.801909"
}
{
"device_id": "8CE7A927",
"s_t0": "24",
"app": "PM25",
"FAKE_GPS": "1",
"s_d0": "32",
"s_d1": "35",
"ver_format": "3",
"s_h0": "67",
"gps_lon": "120.971042",
"ver_app": "live",
"timestamp": "2018-02-02 16:35:12",
"gps_lat": "24.801909"
}
...
```
- php
![](https://i.imgur.com/nXdU05y.png)
![](https://i.imgur.com/i3d1vax.png)
## IOTA Message Length
- 2187 trytes
- Signature message fragment. In case there is a spent input, the signature of the private key is stored here. If no signature is required, it is empty (all 9's) and can be used for storing the message value when making a transfer. More to that later.
- [The Anatomy of a Transaction
](https://iota.readme.io/docs/the-anatomy-of-a-transaction)
- original : < 700 trytes
- compressed (avg): 158 trytes
- compressed (worst): <400 trytes
## Related projects
* [Ethereum virtual machine on top of Tangle](https://hackmd.io/4AqZiGdWQkuZMm1BbAI9pw)
* [Implementation](https://hackmd.io/s/SJo1-IBxQ)
* [Qubic: a protocol that specifies IOTA's solution for oracle machines, smart contracts, outsourced computations, etc.](https://qubic.iota.org/)
* [FPGA-accelerated TrustZone-enabled IOTA Swarm Nodes](https://hackmd.io/s/Hk-5i41bm)