Configuration¶
The monitoring system OpenADMS Node is configured by a single configuration file
in JavaScript Object Notation (JSON). The file is loaded once at the start of
OpenADMS Node. The path to the configuration file is passed as a command-line
argument. Example configuration files are located in directory
config/examples/
. At the moment, configuration files have to be written
manually. This will change in future, once a visual configuration tool is
available.
The configuration consists of several sections. The order of the sections is
arbitrary, but it is recommended to start with the core settings (core
),
followed by the used sensors with their commands listed under sensors
. See
directory sensors/
for sensor configuration files. The configuration of
the dynamically loaded modules must be placed under modules
.
{
"core": {
"modules": {
"myModule": "modules.example.MyModule"
},
"project": {
"name": "Example Project",
"id": "4a2e8b9d87d849e38bb6911b9f2364ea",
"description": "Project for testing only."
},
"node": {
"name": "Sensor Node 1",
"id": "6426bf58c20840768912f116740c4974",
"description": "The only sensor node in this project."
},
"intercom": {
"mqtt": {
"host": "127.0.0.1",
"port": 8883,
"keepAlive": 60,
"topic": "openadms",
"user": "client1".
"password": "secret",
"tls": false,
"caCerts": "mqtt_ca.crt"
}
}
},
"sensors": {
"mySensor": {
"description": "My Example Sensor",
"type": "generic",
"observations": [
{
"name": "doMeasure",
"description": "Does a measurement.",
"target": "point1",
"enabled": true,
"onetime": false,
"receivers": [ "preProcessor" ],
"nextReceiver": 0,
"requestSets": {
"doMeasure": {
"enabled": true,
"request": "m\r",
"responsePattern": "(?P<x>[+-]?\\d+\\.+\\d)",
"responseDelimiter": "\r",
"sleepTime": 1.0,
"timeout": 1.0
}
},
"requestsOrder": [ "doMeasure" ],
"responseSets": {
"x": {
"type": "float",
"unit": "m"
}
},
"sleepTime": 5.0
}
]
}
},
"modules": {
"myModule": {
"enabled": true
}
}
}
core |
Object |
Core configuration. |
modules |
Object |
List of OpenADMS Node modules to load. |
project |
Object |
Project information. |
node |
Object |
Sensor node information. |
intercom |
Object |
MQTT configuration for inter-module communication. |
sensors |
Object |
Sensors and their commands. |
modules |
Object |
Configuration of loaded modules. |
Example¶
Geodetic and geotechnical inclinometers are not only used in industrial surveying but also in deformation monitoring. This example shows how the OpenADMS monitoring system has to be configured in order to be used with a Leica Nivel210 inclinometer. More sensors can be added easily. This setup should work on most operating systems (Microsoft Windows, Linux, Unix).
The example requires a Leica Nivel210 inclinometer with serial data cable and power supply unit, as well as a system with a RS-232 port or a USB port with serial adapter.
Create an empty configuration file under config/nivel210.json
and copy the
following JSON structure into it:
{
"core": {
"modules": {},
"project": {},
"node": {},
"intercom": {}
},
"sensors": {},
"modules": {}
}
Now, we can fill the JSON objects with the actual configuration.
Loading the Modules¶
Modules used for the monitoring job have to be added to the modules object in
the core
section of the configuration file. The control of a Leica Nivel210
sensor requires at least four modules:
Scheduler for starting the observation,
SerialPort for sensor communication,
PreProcessor for sensor data extraction,
FileExporter to save the sensor data to a CSV file.
The name of each module instance can be chosen freely (spaces and special
characters are not allowed). It is recommended to write all names in lower camel
case (i. e., lowerCamelCase
). As a sane practice, the scheduler and the
serial port are named according to the used COM port (for example, COM1
on
Microsoft Windows and ttyU0
on Linux/Unix). All modules listed in the
modules object are loaded automatically at run-time:
{
"core": {
"modules": {
"schedulerCom1": "module.schedule.Scheduler",
"com1": "module.port.SerialPort",
"preProcessor": "module.processing.PreProcessor",
"fileExporter": "module.export.FileExporter"
}
}
}
Project Details¶
Some meta information about the monitoring project must be defined in the
project
section of the core configuration. Use a hex-only UUID4 as the
project id.
{
"core": {
"project": {
"name": "Example Project",
"id": "19481e0791604b489a8a9c4a25e9dd80",
"description": "Project for testing the Leica Nivel210."
}
}
}
Sensor Node Details¶
Each monitoring project consists of one or more sensor nodes. It is required to set a node name, a node id, and a node description. Use a hex-only UUID4 as the node id.
{
"core": {
"node": {
"name": "Sensor Node 1",
"id": "21bcf8c16a664b17bbc9cd4221fd8541",
"description": "The only sensor node in this project."
}
}
}
Communication¶
The modules communicate by using the MQTT messaging protocol. For this reason,
an MQTT message broker is required. Either run OpenADMS with the parameter
--with-mqtt-broker
or start an external one. The default configuration uses
the IP address 127.0.0.1
and the port 1883
, but can be altered to the
values set for the used MQTT message broker.
{
"core": {
"intercom": {
"mqtt": {
"host": "127.0.0.1",
"port": 8883,
"keepAlive": 60,
"topic": "example",
"user": "client1",
"password": "secret",
"tls": false,
"caCerts": "mqtt_ca.crt"
}
}
}
}
User and password are optional and not required for anonymous sessions. If TLS
encryption is enabled by setting tls
to true
, a CA certificate has to be
provided most likely. caCerts
is the path to the CA certificate of the MQTT
server.
Sensor¶
Add the sensor details and used commands to the configuration file:
{
"sensors": {
"nivel210": {
"description": "Leica Nivel210",
"type": "inclinometer",
"observations": [
{
"name": "getValues",
"description": "gets inclination and temperature",
"receivers": [
"preProcessor",
"fileExporter"
],
"nextReceiver":0,
"enabled": true,
"onetime": false,
"target": "nivel210",
"requestsOrder": [
"getXYTemp"
],
"requestSets": {
"getXYTemp": {
"enabled": true,
"request": "\\x16\\x02N0C0 G A\\x03\\x0d\\x0a",
"response": "",
"responseDelimiter": "\\x03",
"responsePattern": "X:(?P[-+]?[0-9]*\\.?[0-9]+) Y:(?P[-+]?[0-9]*\\.?[0-9]+) T:(?P[-+]?[0-9]*\\.?[0-9]+)",
"sleepTime":0.0,
"timeout":1.0
}
},
"responseSets": {
"temperature": {
"type": "float",
"unit": "C"
},
"x": {
"type": "float",
"unit": "mrad"
},
"y": {
"type": "float",
"unit": "mrad"
}
},
"sleepTime":0.30
}
]
}
}
}
Serial Port¶
The configuration of serial port modules is stored under ports
→ serial
→ module name. On Microsoft Windows, the port is COMx
, on Linux and Unix
/dev/ttyx
or /dev/ttyUx
, whereas x
is the number of the port. The
baud rate has to be set to the value the Nivel210 is configured to, most likely
9600
.
{
"modules": {
"ports": {
"serial": {
"com1": {
"port": "COM1",
"baudRate": 9600,
"byteSize": 8,
"stopBits": 1,
"parity": "none",
"timeout": 2.0,
"softwareFlowControl": false,
"hardwareFlowControl": false,
"maxAttepts": 1
}
}
}
}
}
Scheduler¶
Use a scheduler module to send commands to the sensor:
{
"modules": {
"schedulers": {
"schedulerCom1": {
"port": "com1",
"sensor": "nivel210",
"schedules": [
{
"enabled": true,
"startDate": "2017-01-01",
"endDate": "2020-12-31",
"weekdays": {},
"observations": [
"getValues"
]
}
]
}
}
}
}
Set port
to the name of the serial port configuration name and sensor
to
the name of the sensor configuration. Multiple schedules can be defined.
Commands to send to the sensor must be listed in observations
in their
correct order. Only listed observations will be performed.
Pre-Processor¶
The PreProcessor is called right after the SerialPort module and extracts the
values (temperature, inclination in X and Y) from the raw response of the
Nivel210. The response pattern of the request set getXYTemp
is used for the
extraction.
File Exporter¶
The name of the CSV file may be com1_nivel210_2019-05.csv
or similar and be
stored in directory data/
.
{
"modules": {
"fileExporter": {
"fileExtension": ".csv",
"fileName": "{{port}}_{{id}}_{{date}}",
"fileRotation": "monthly",
"paths": [
"./data"
],
"separator": ",",
"dateTimeFormat": "YYYY-MM-DDTHH:mm:ss.SSSSS"
}
}
}
Complete Configuration File¶
The complete configuration is listed below.
{
"core": {
"modules": {
"schedulerCom1": "modules.schedule.Scheduler",
"com1": "modules.port.SerialPort",
"preProcessor": "modules.processing.PreProcessor",
"fileExporter": "modules.export.FileExporter"
},
"project": {
"name": "Example Project",
"id": "19481e0791604b489a8a9c4a25e9dd80",
"description": "Project for testing the Leica Nivel210."
},
"node": {
"name": "Sensor Node 1",
"id": "21bcf8c16a664b17bbc9cd4221fd8541",
"description": "The only sensor node in this project."
},
"intercom": {
"mqtt": {
"host": "127.0.0.1",
"port": 1883,
"keepAlive": 60,
"topic": "example",
"user": "client1".
"password": "secret",
"tls": false,
"caCerts": "mqtt_ca.crt"
}
}
},
"sensors": {
"nivel210": {
"description": "Leica Nivel210",
"type": "inclinometer",
"observations": [
{
"name": "getValues",
"description": "gets inclination and temperature",
"receivers": [
"preProcessor",
"fileExporter"
],
"nextReceiver": 0,
"enabled": true,
"onetime": false,
"target": "nivel210",
"requestsOrder": [
"getXYTemp"
],
"requestSets": {
"getXYTemp": {
"enabled": true,
"request": "\\x16\\x02N0C0 G A\\x03\\x0d\\x0a",
"response": "",
"responseDelimiter": "\\x03",
"responsePattern": "X:(?P[-+]?[0-9]*\\.?[0-9]+) Y:(?P[-+]?[0-9]*\\.?[0-9]+) T:(?P[-+]?[0-9]*\\.?[0-9]+)",
"sleepTime": 0.0,
"timeout": 1.0
}
},
"responseSets": {
"temperature": {
"type": "float",
"unit": "C"
},
"x": {
"type": "float",
"unit": "mrad"
},
"y": {
"type": "float",
"unit": "mrad"
}
},
"sleepTime": 0.30
}
]
}
},
"modules": {
"ports": {
"serial": {
"com1": {
"port": "COM1",
"baudRate": 9600,
"byteSize": 8,
"stopBits": 1,
"parity": "none",
"timeout": 2.0,
"softwareFlowControl": false,
"hardwareFlowControl": false,
"maxAttepts": 1
}
}
},
"schedulers": {
"schedulerCom1": {
"port": "com1",
"sensor": "nivel210",
"schedules": [
{
"enabled": true,
"startDate": "2017-01-01",
"endDate": "2020-12-31",
"weekdays": {
},
"observations": [
"getValues"
]
}
]
}
},
"fileExporter": {
"fileExtension": ".csv",
"fileName": "{{port}}_{{id}}_{{date}}",
"fileRotation": "monthly",
"paths": [
"./data"
],
"separator": ",",
"dateTimeFormat": "YYYY-MM-DDTHH:mm:ss.SSSSS"
}
}
}
Running OpenADMS¶
To start the monitoring, change to the OpenADMS directory and run:
$ pipenv run ./openadms.py --config config/nivel210.json --with-mqtt-broker --debug