Pheromon is a open innovation project to deploy, administrate and harvest data from a swarm of sensors. It has been developed in the scope of project 6element dedicated to waste optimisation, and is now in production on the projet vamos.
Use our open API, you can have a look at the dedicated wiki.
Pheromon communicates with sensors over TCP using MQTT protocol. The MQTT broker dispatches the messages depending on the publish/subscribe status of various clients on various subjects. For example, a meteorological sensor will publish on the topics rain
and temperature
while a sensor measuring peoples fluxes will publish on wifidevices
and bluetoothdevices
. Meanwhile, the admin interface can publish to all sensors on the all
topic, or to one particular sensor on mySensorId
topic.
All the messages are persisted in a database that can be queried by a API able to answer queries like "give me all mesaurements of sensor X since Y".
Two clients are available for now.
The Dashboard is useful to visualize the measurements on a map.
You can also administrate your sensors with the Admin.
More on those clients later.
git clone git@github.com:anthill/pheromon.git
cd pheromon
Copy / Create the files PRIVATE/*.json
Install dependencies
npm install
Use this for development.
npm run dev
Use npm run stop-dev
to stop.
Use this for production.
npm run prod // launch the service
node database/management/init-db.js
node database/management/backup.js > backups/test.sql
or restore an previous db with
node database/management/restore.js backups/test.sql
you can also use a gziped file (comming from the automated backup for example).
MQTT is the communication protocol between the server and the sensors.
The communication protocol is composed of 3 elements:
From sensor to maestro:
init/mySensorSimId
, when sensor needs to initialize. There is no content.status/mySensorSimId/type
, when a sensor status updates. The content is a string describing the actual status.measurement/mySensorSimId/type
, when a measurement is sent from sensor. The content is an array of measurements.cmdResult/mySensorSimId
, when a sensor processed a command sent from maestro. The content is a string describing the output of the command.From maestro to sensor:
mySensorSimId
, when maestro sends command to sensor. The content is a string of the command.all
, when maestro sends command to all registered sensors. The content is a string of the command.We don't want sensors to have a manually hard-coded id (for deployment's simplicity) so we use mac addresses of devices:
Sequence
mySensorSimId
and all
topics, then sends an empty message on init/mySensorSimId
topic.mySensorSimId
in DB, creates Sensor if needed, and sends back [init
, parameters
] on simId
topic.parameters
and routines.Each time the sensor's status changes, a message is sent to the maestro to update the DB and react accordingly depending on the situation. Status can be of 3 types:
client
: state of communication between sensor and kerrigan serversignal
: power of signal between sensor and kerrigan serverwifi
: wifi monitoring state of sensor blue
: bluetooth monitoring state of sensorSequence
type
status to newStatus
.newStatus
on status/mySensorSimId/type
topic.mySensorSimId
in DB, creates Sensor if needed, and updates sensor in DB.By default, sensor has measurement capabilities (for wifi and bluetooth). Every n
minutes, sensor send measurements to kerrigan server to be recorded in DB.
Sequence
n
minutes has passed since last measurement on measurementType
.measurementContent
and sends measurementContent
on measurement/mySensorSimId/measurementType
topic.mySensorSimId
in DB, creates Sensor if needed, and then creates Measurement in DB.You can send commands to the sensors.
Sequence
command
to [mySensorSimId]
through socketIO.command
from client, and forwards it to the corresponding sensors through MQTT.command
, and sends back the result of the command on the topic cmdResult/mySensorSimId
mySensorSimId
in DB, creates Sensor if needed, and then updates Sensor in DB.You can run Pheromon tests in a dedicated docker.
You can use
npm run test
sudo useradd -m sensorSSH;
sudo passwd sensorSSH;
su sensorSSH -c 'ssh-keygen -t rsa -b 4096';
Add the sensor public key to the authorized_keys and vice-versa
Add group docker to the user
sudo usermod -G docker sensorSSH;
/etc/ssh/sshd_config
AllowTcpForwarding yes
GatewayPorts yes
sudo usermod -s /usr/sbin/nologin sensorSSH;
add "ip": ...
in pheromon secret.json
where kerrigan is the name of the host in .ssh/config
There are 2 PRIVATE files:
secret.json
: this file is very sensitive. Leaking it would potentially allow people to access your db, server, sensors, etc... It should not be required in non protected clients. Here, the only client that requires it is Admin
, whose access is protected by html_token
.
{
"server_ip": ..., // your server ip, used by the sensor updater
"html_token": ..., // token you should use to protect the access to your Admin client or database API
"mqtt_user": ..., // username for mqtt
"mqtt_token": ..., // MQTT for the broker to authenticate sensor
"cmd_token": ... // token to allow cmd sending to sensor
}
server_ip
is used in api/maestro.js
.
html_token
is used in api/api.js
and api/routes.js
.
cmd_token
is used in api/maestro.js
and api/clients/Admin/src/main.js
.
mapbox.json
: this file is not very sensitive. It only contains mapbox infos
{
"token": ..., // token for your mapbox account
"map_id": ..., // id of your map background,
"center": [16.1496297,-61.39705]
}
Both mapbox.json
fields are used in api/clients/Dashboard/src/main.js
.
Clone the repository.
Create a new branch to work in.
Make a pull request explaining why and what you changed.