Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
Vourhey committed Dec 7, 2020
1 parent f37a60e commit d98bdce
Showing 1 changed file with 19 additions and 271 deletions.
290 changes: 19 additions & 271 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ Aira source package to input data from sensors. ROS-enabled telemetry agent

# Module For Your Aira Instance. Add Telemetry Agent

The Aira package allows you to read data from a SDS011 sensor and publish to different output channels.
The Aira package allows you to read data from a SDS011 sensor (and a few others) and publish to different output channels.
That said Aira is able to form Demand and Result messages and a few other channels.
Also it includes Datalog feature which is still experimental. It could be used to publish data to Substrate based blockchain by Robonomics.
Also it includes Datalog feature which is still experimental. It could be used to publish data to Substrate based blockchain by [Robonomics](https://parachain.robonomics.network/.

## Get a Package And Build

Expand All @@ -25,220 +25,12 @@ nix build -f release.nix
> Either do `sudo adduser liability dialout` or add the line to `/etc/nixos/configuration.nix` on NixOS:
> `users.users.liability.extraGroups = [ "dialout" ];`
## Configuration
## Documentation

Basically you can think of the package as a black box with one input (sensor data) and many outputs.
For now only SDS011 sensor is supported but if you are familiar with Python it'd be easy to add other sensors as well.
To prepare a sensor for the work with the package follow instructions on [Robonomics Wiki](https://wiki.robonomics.network/docs/connect-sensor-to-robonomics/) and use [another](https://wiki.robonomics.network/docs/configuration-options-description/) article to set a proper configuration for your instance.

Have a look at [configuration](config/default.yaml) file:

```yaml
# Please DO NOT edit this file
# Make a copy instead, make changes and pass the absolute path to the copy in arguments
general:
publish_interval: 300 # time between two published messages
comstation:
port: "/dev/ttyUSB0" # COM port of the device
work_period: 300 # time between two measurements in seconds
geo: "" # Geo coordinates as latitude,longitude
public_key: "" # If not provided, COMStation creates itself
tcpstation:
address: "" # IP and PORT to listen to, for example 0.0.0.0:31313
acl: # list of known addresses. If not specified accepts from everyone
# -
# -
luftdaten:
enable: true # whether or not publish to https://luftdaten.info/
robonomics:
enable: true # enable use of Robonomics Network
ipfs_provider: "" # ipfs endpoint
ipfs_topic: "airalab.lighthouse.5.robonomics.eth"
datalog:
enable: false # enable use of Datalog Robonomics subcommand
path: "" # path to Robonomics execution file
suri: "" # private key of publisher account
remote: "wss://substrate.ipci.io"
dump_interval: 3600 # time between two transactions in seconds
dev:
sentry: ""
```
At the moment it's possible to publish data to [Luftdaten](https://luftdaten.info/), [Robonomics Network](https://robonomics.network/) and [Datalog](https://github.com/airalab/robonomics).
The last one is experimental!
> DO NOT edit `config/default.yaml` file. Instead make a copy

Play around with the configuration!

Explanation of options:

* `general/publish_interval` - integer number from 1 and above. Tells how often send measurements. Keep in mind that if measurements from sensors come less often than this number connectivity sends last data
* `comstation/port` - valid path to com port, for example `/dev/ttyUSB0`. It is where a sensor is connected to
* `comstation/work_period` - integer from 0 to 1800. For SDS011 sensor 0 means continuous work. Recommended period is 300 seconds
* `comstation/geo` - `lat,lon` a string with two floats separated by a comma. It represents latitude and longitude of a sensor
* `comstation/public_key` - Ed25519 verifying key in hex format. If not provided connectivity generates a new one
* `tcpstation/address` - what address and port listen to. If you are willing to make it open for external connections put `0.0.0.0` as an address. `31313` is a port chosen by developers. You can pick any port you want but don't forget to change the port in an ESP firmware.
* `tcpstation/acl` - a list of known public keys in hex format
* `luftdaten/enable` - true/false. Whether or not publish data to [Luftdaten](https://devices.sensor.community/). Don't forget to register sensor's mac address on the site
* `robonomics/enable` - true/false. Whether or not publish data to IPFS topic according to Robonomics communication protocol
* `robonomics/ipfs_proveder` - an endpoint for IPFS daemon. By default it's `/ip4/127.0.0.1/tcp/5001/http` that means local daemon. The endpoint must by in multiaddr format. For example for [Infura.io](https://infura.io/) it would be `/dns/ipfs.infura.io/tcp/5001/https`
* `robonomics/ipfs_topic` - IPFS topic's name. If you want to use [DApp](sensors.robonomics.network) provided by Robonomics team leave it untouched
* `datalog/enable` - true/false. Enable/Disable saving log to [Robonomics on Substrate chain](https://ui.ipci.io/)
* `datalog/path` - full path to `robonomics` executable file. You can find the latest release on [this](https://github.com/airalab/robonomics/releases) page
* `datalog/suri` - a private key from substrate chain account
* `datalog/remote` - an endpoint to substrate instance
* `datalog/dump_interval` - specify a period of time for collecting log in seconds
* `dev/sentry` - for development purpose. If you have a [Sentry.io](https://sentry.io/) account you can put sentry's credentials in here

## Scenario #1: Connect SDS011 to serial port

The easiest and the most straight forward way to connect your sensor to the network is using serial port

Connect you SDS011 sensor to a USB port, let's assume it got `/dev/ttyUSB0` address. Copy configuration file:

```
cp config/default.yaml config/my.yaml
```

and make it look like:

```yaml
general:
publish_interval: 15 # time between two published messages
comstation:
port: "/dev/ttyUSB0" # COM port of the device
work_period: 300 # time between two measurements in seconds
geo: "59.944954,30.294534" # Geo coordinates as latitude,longitude
public_key: "" # If not provided, COMStation creates itself
tcpstation:
address: "" # IP and PORT to listen to, for example 0.0.0.0:31313
acl: # list of known addresses. If not specified accepts from everyone
# -
# -
luftdaten:
enable: true # whether or not publish to https://luftdaten.info/
robonomics:
enable: true # enable use of Robonomics Network
ipfs_provider: "" # ipfs endpoint
ipfs_topic: "airalab.lighthouse.5.robonomics.eth"
datalog:
enable: false # enable use of Datalog Robonomics subcommand
path: "" # path to Robonomics execution file
suri: "" # private key of publisher account
remote: "wss://substrate.ipci.io"
dump_interval: 3600 # time between two transactions in seconds
dev:
sentry: ""
```

Launch the agent:

```
source result/setup.bash
roslaunch sensors_connectivity agent.launch config:=/var/lib/liability/sensors-connectivity/config/my.yaml
```

## Scenario #2: Connect SDS011 via TCP

### ESP Board Preparation

First you need to generate a signing/verifying keys pair. To do so:

```
source result/setup.bash
./utils/generate_secrets.py -o ./boards/esp/ESP_TCP/
```

Now you have a `./boards/esp/ESP_TCP/secrest.h` file. The script also outputs verifying key, let's say it is `49de10e0762517d209b7e61d8fe47e3fc06d08609707aeb290b425847cd2ce56`

Now open `./boards/esp/ESP_TCP/ESP_TCP.ino` file in Arduino IDE. Install dependencies:

* [ESP Boards](https://arduino-esp8266.readthedocs.io/en/latest/installing.html)
* [SdsDustSensor library](https://github.com/lewapek/sds-dust-sensors-arduino-library). Could be installed by searching SdsDustSensor in `Sketch -> Include library -> Manage libraries` (Hotkey: `Ctrl + Shift + I`)
* Extract [Crypto](https://github.com/rweather/arduinolibs/tree/master/libraries/Crypto) folder to `~/Arduino/libraries`

You need to set `STASSID`, `STAPSK`, `HOST`, `GEO_LAT`, `GEO_LON`. Optional: `rxPin`, `txPin`, `work_period`, `port`

```
#ifndef STASSID
#define STASSID ""
#define STAPSK ""
#endif
#define rxPin 2 // D2 on ESP TX of the sensor is connected to RX of the board
#define txPin 3 // D3 on ESP and vice versa sensor's rx is connected to boards's tx
const char* host = "HOST";
const uint16_t port = 31313;
const float GEO_LAT = 0.0;
const float GEO_LON = 0.0;
const byte work_period = 5; // minutes
```

Upload the firmware

### Connectivity Configuration

```
cp config/default.yaml config/my.yaml
```
```yaml
general:
publish_interval: 15 # time between two published messages
comstation:
port: "" # COM port of the device
work_period: 300 # time between two measurements in seconds
geo: "" # Geo coordinates as latitude,longitude
public_key: "" # If not provided, COMStation creates itself
tcpstation:
address: "0.0.0.0:31313" # IP and PORT to listen to, for example 0.0.0.0:31313
acl: # list of known addresses. If not specified accepts from everyone
- 49de10e0762517d209b7e61d8fe47e3fc06d08609707aeb290b425847cd2ce56 # PUT YOUR VERIFYING KEY HERE
luftdaten:
enable: true # whether or not publish to https://luftdaten.info/
robonomics:
enable: true # enable use of Robonomics Network
ipfs_provider: "" # ipfs endpoint
ipfs_topic: "airalab.lighthouse.5.robonomics.eth"
datalog:
enable: false # enable use of Datalog Robonomics subcommand
path: "" # path to Robonomics execution file
suri: "" # private key of publisher account
remote: "wss://substrate.ipci.io"
dump_interval: 3600 # time between two transactions in seconds
dev:
sentry: ""
```

> Do not forget to open the port in system firewall
>
> On NixOS you can do:
> ```
> networking.firewall.allowedTCPPorts = [ 31313 ];
> ```
Launch connectivity:

```
roslaunch sensors_connectivity agent.launch config:=/var/lib/liability/sensors-connectivity/config/my.yaml
```

When initialization passed power your board or reset it. It's needed because the very first data from the board is header.
If connectivity doesn't receive the header it drops the connection.

If you need to connect more sensors to a single instance of connectivity repeat [ESP Board Preparation](#esp-board-preparation) for every sensor.
Then add all the keys to the configuration file, restart connectivity and power up/reset every board.

## Scenario #3: Connect Multiple Sensors and Publish to Datalog

In order to upload a firmware to ESP board read [ESP Board Preparation](#esp-board-preparation) section.

Connect SDS011 to a serial port.

### Install Robonomics
## Install Robonomics

From `root` user do:

Expand All @@ -261,45 +53,7 @@ nixos-rebuild switch
whereis robonomics
```

Let's assume you got the following path: `/nix/store/2gz2ik17w5xad8w819bsb05a23pbjbya-system-path/bin/robonomics`

### Configuration

```yaml
general:
publish_interval: 15 # time between two published messages
comstation:
port: "/dev/ttyUSB0" # COM port of the device
work_period: 300 # time between two measurements in seconds
geo: "59.944954,30.294534" # Geo coordinates as latitude,longitude
public_key: "" # If not provided, COMStation creates itself
tcpstation:
address: "0.0.0.0:31313" # IP and PORT to listen to, for example 0.0.0.0:31313
acl: # list of known addresses. If not specified accepts from everyone
- 49de10e0762517d209b7e61d8fe47e3fc06d08609707aeb290b425847cd2ce56 # PUT YOUR VERIFYING KEY HERE
luftdaten:
enable: true # whether or not publish to https://luftdaten.info/
robonomics:
enable: true # enable use of Robonomics Network
ipfs_provider: "" # ipfs endpoint
ipfs_topic: "airalab.lighthouse.5.robonomics.eth"
datalog:
enable: false # enable use of Datalog Robonomics subcommand
path: "/nix/store/2gz2ik17w5xad8w819bsb05a23pbjbya-system-path/bin/robonomics" # path to Robonomics execution file
suri: "0x....." # private key of publisher account
remote: "wss://substrate.ipci.io"
dump_interval: 3600 # time between two transactions in seconds
dev:
sentry: ""
```
Start connectivity first and then all your boards:
```
su - liability
cd sensors-connectivity
source result/setup.bash
roslaunch sensors_connectivity agent.launch config:=/var/lib/liability/sensors-connectivity/config/my.yaml
```
Let's assume you got the following path: `/nix/store/2gz2ik17w5xad8w819bsb05a23pbjbya-system-path/bin/robonomics`. Use the path in `datalog/path` option.

## Make a Service

Expand All @@ -313,7 +67,7 @@ systemd.services.connectivity = {
environment.ROS_MASTER_URI = "http://localhost:11311";
script = ''
source /var/lib/liability/sensors-connectivity/result/setup.bash \
&& roslaunch sensors_connectivity agent.launch config:=/var/lib/liability/sensors-connectivity/config/my.yaml
&& roslaunch sensors_connectivity agent.launch config:=/var/lib/liability/sensors-connectivity/config/my.json
'';
serviceConfig = {
Restart = "on-failure";
Expand All @@ -324,7 +78,7 @@ systemd.services.connectivity = {
};
```

Technically it's not necessary to specify the `default.yaml` configuration file, but if you did changes please put the absolute path to `config` parameter.
Technically it's not necessary to specify the `default.json` configuration file, but if you did changes please put the absolute path to `config` parameter.

After that run `nixos-rebuild switch`. The service should be up and running

Expand All @@ -344,21 +98,15 @@ journalctl -u connectivity -f
Example of output:
```bash
root@hq-nuc-sds011> tail /var/lib/liability/.ros/log/latest/connectivity-worker-1.log -f
[rosout][INFO] 2020-06-02 13:55:48,427: Starting process...
[rosout][INFO] 2020-06-02 13:55:48,430: airalab-com-v0.1.0: [{MAC: 94c6911b42d6, Uptime: 0:00:30.997699, M: {Public: 4aebc455889ee993a615c479eb069079f643a8210aca0c866f0a7d126b8160f2, PM2.5: 8.3, PM10: 16.7, geo: (0.0,0.0), timestamp: 1591091717}}]
[rosout][INFO] 2020-06-02 13:55:48,520: new connection from ('192.168.20.23', 57336)
[rosout][INFO] 2020-06-02 13:55:48,865: LuftdatenFeeder: sent successfuly
[rosout][INFO] 2020-06-02 13:55:48,868: RobonomicsFeeder: {"4aebc455889ee993a615c479eb069079f643a8210aca0c866f0a7d126b8160f2": {"model": 2, "timestamp": 1591091717, "measurement": {"pm25": 8.3, "pm10": 16.7, "geo": "0.0,0.0"}}}
[rosout][INFO] 2020-06-02 13:55:48,877: airalab-tcp-v0.1.0: []
[rosout][INFO] 2020-06-02 13:55:50,524: Peer name: ('192.168.20.23', 57336)
[rosout][INFO] 2020-06-02 13:55:50,527: Unknown peer yet
[rosout][INFO] 2020-06-02 13:55:50,531: Welcome to the party: (5dff08595b74db99a997dab6cab851092d27373168f5b04c1035fd2c0a520ee3,2)
[rosout][INFO] 2020-06-02 13:56:03,880: Starting process...
[rosout][INFO] 2020-06-02 13:56:03,884: airalab-com-v0.1.0: [{MAC: 94c6911b42d6, Uptime: 0:00:46.451368, M: {Public: 4aebc455889ee993a615c479eb069079f643a8210aca0c866f0a7d126b8160f2, PM2.5: 8.3, PM10: 16.7, geo: (0.0,0.0), timestamp: 1591091717}}]
[rosout][INFO] 2020-06-02 13:56:04,241: LuftdatenFeeder: sent successfuly
[rosout][INFO] 2020-06-02 13:56:04,246: RobonomicsFeeder: {"4aebc455889ee993a615c479eb069079f643a8210aca0c866f0a7d126b8160f2": {"model": 2, "timestamp": 1591091717, "measurement": {"pm25": 8.3, "pm10": 16.7, "geo": "0.0,0.0"}}}
[rosout][INFO] 2020-06-02 13:56:04,266: airalab-tcp-v0.1.0: []
[rosout][INFO] 2020-06-02 13:56:14,330: Peer name: ('192.168.20.23', 57336)
[rosout][INFO] 2020-06-02 13:56:14,334: I know you buddy!
[rosout][INFO] 2020-06-02 13:56:14,340: {Public: 5dff08595b74db99a997dab6cab851092d27373168f5b04c1035fd2c0a520ee3, PM2.5: 3.8, PM10: 7.1, geo: (53.507675,49.252785), timestamp: 1591091774}
[rosout][INFO] 2020-12-07 12:00:02,536: Starting process...
[rosout][INFO] 2020-12-07 12:00:02,541: {14542862: Measurement(public='0ed57cf15050d5fa56c8da5e382ec5af5e923d7ee2b931a81ef8381fc5ac921d', model=2, pm25=14.6, pm10=22.33, geo_lat='53.541009', geo_lon='49.402139', timestamp=1607338677), 15695587: Measurement(public='a8cdc84231d0dd62549a3cb697f2928976eb3b0852066f8c873e9851e0e2840f', model=2, pm25=3.15, pm10=8.43, geo_lat='59.936439', geo_lon='30.499921', timestamp=1607338693), 11117092: Measurement(public='20e67a8db1a66b3def367c737a6faf9a622a4c832efc9f91b37c358119653a04', model=2, pm25=7.97, pm10=15.32, geo_lat='55.741614', geo_lon='37.537618', timestamp=1607338714), 2630646: Measurement(public='b2add8c5b5ac9f63bf01932a732b397221e79305d0b767b1879afb72861b8469', model=2, pm25=18.73, pm10=31.62, geo_lat='48.828908', geo_lon='2.370269', timestamp=1607338744), 12624680: Measurement(public='c55b3d2a6b042203ed2e23989b2308052c2d9a0db61932a1b14f0f291860cd74', model=2, pm25=7.3, pm10=10.0, geo_lat='46.856023', geo_lon='40.314081', timestamp=1607338751)}
[rosout][INFO] 2020-12-07 12:00:02,545: HTTPServer status: True
[rosout][INFO] 2020-12-07 12:00:02,548: airalab-http-v0.3.0: [{MAC: a6802ccd9f70, Uptime: 4 days, 0:21:04.491420, M: {Public: 0ed57cf15050d5fa56c8da5e382ec5af5e923d7ee2b931a81ef8381fc5ac921d, PM2.5: 14.6, PM10: 22.33, geo: (53.541009,49.402139), timestamp: 1607338677}}, {MAC: a6802ccd9f70, Uptime: 4 days, 0:21:04.491431, M: {Public: a8cdc84231d0dd62549a3cb697f2928976eb3b0852066f8c873e9851e0e2840f, PM2.5: 3.15, PM10: 8.43, geo: (59.936439,30.499921), timestamp: 1607338693}}, {MAC: a6802ccd9f70, Uptime: 4 days, 0:21:04.491433, M: {Public: 20e67a8db1a66b3def367c737a6faf9a622a4c832efc9f91b37c358119653a04, PM2.5: 7.97, PM10: 15.32, geo: (55.741614,37.537618), timestamp: 1607338714}}, {MAC: a6802ccd9f70, Uptime: 4 days, 0:21:04.491435, M: {Public: b2add8c5b5ac9f63bf01932a732b397221e79305d0b767b1879afb72861b8469, PM2.5: 18.73, PM10: 31.62, geo: (48.828908,2.370269), timestamp: 1607338744}}, {MAC: a6802ccd9f70, Uptime: 4 days, 0:21:04.491437, M: {Public: c55b3d2a6b042203ed2e23989b2308052c2d9a0db61932a1b14f0f291860cd74, PM2.5: 7.3, PM10: 10.0, geo: (46.856023,40.314081), timestamp: 1607338751}}]
[rosout][INFO] 2020-12-07 12:00:02,551: RobonomicsFeeder: {"0ed57cf15050d5fa56c8da5e382ec5af5e923d7ee2b931a81ef8381fc5ac921d": {"model": 2, "timestamp": 1607338677, "measurement": {"pm25": 14.6, "pm10": 22.33, "geo": "53.541009,49.402139"}}}
[rosout][INFO] 2020-12-07 12:00:02,565: RobonomicsFeeder: {"a8cdc84231d0dd62549a3cb697f2928976eb3b0852066f8c873e9851e0e2840f": {"model": 2, "timestamp": 1607338693, "measurement": {"pm25": 3.15, "pm10": 8.43, "geo": "59.936439,30.499921"}}}
[rosout][INFO] 2020-12-07 12:00:02,578: RobonomicsFeeder: {"20e67a8db1a66b3def367c737a6faf9a622a4c832efc9f91b37c358119653a04": {"model": 2, "timestamp": 1607338714, "measurement": {"pm25": 7.97, "pm10": 15.32, "geo": "55.741614,37.537618"}}}
[rosout][INFO] 2020-12-07 12:00:02,592: RobonomicsFeeder: {"b2add8c5b5ac9f63bf01932a732b397221e79305d0b767b1879afb72861b8469": {"model": 2, "timestamp": 1607338744, "measurement": {"pm25": 18.73, "pm10": 31.62, "geo": "48.828908,2.370269"}}}
[rosout][INFO] 2020-12-07 12:00:02,604: RobonomicsFeeder: {"c55b3d2a6b042203ed2e23989b2308052c2d9a0db61932a1b14f0f291860cd74": {"model": 2, "timestamp": 1607338751, "measurement": {"pm25": 7.3, "pm10": 10.0, "geo": "46.856023,40.314081"}}}
[rosout][INFO] 2020-12-07 12:00:02,616: DatalogFeeder:
[rosout][INFO] 2020-12-07 12:00:02,618: Still collecting measurements...
```

0 comments on commit d98bdce

Please sign in to comment.