README.md 22.5 KB
Newer Older
Micha Mueller's avatar
Micha Mueller committed
1
2
3
4
5
6
## Intro
DCDB (DataCenter DataBase) is a database to collect various (sensor-)values of a datacenter for further analysis.
Harvesting of the data is task of the dcdbpusher.

# dcdbpusher

Micha Mueller's avatar
Micha Mueller committed
7
This is a general MQTT pusher which sends values of various sensors to the DCDB-database.
Micha Mueller's avatar
Micha Mueller committed
8
9
10
11
12
13
14
15
16
17
18
19
20
It unites and unifies the functionality of former separate sensor-pushers for IPMI, sysFS, perf-event and SNMP.

Build it by simply running
```bash
cd src/
make
```
or alternatively use
```bash
make debug
```
to build a version which will print additional debug-information during runtime.

21
The logic for the various sensors is encapsulated into plugins (shared dynamic libraries; the makefile will take care of compiling them for you). The dcdbpusher will dynamically open the libraries if they are specified in the [global configuration](#GC) file. Vice versa, if selected sensor-functionality, e.g. sysFS is not specified, the corresponding shared library libdcdbplugin_sysfs.so does not have to be present. 
Micha Mueller's avatar
Micha Mueller committed
22

Micha Mueller's avatar
Micha Mueller committed
23
24
25
26
You can run dcdbpusher by executing
```bash
./dcdbpusher path/to/configfile/
```
27
or run
Micha Mueller's avatar
Micha Mueller committed
28
29
30
```bash
./dcdbpusher -h
```
Micha Mueller's avatar
Micha Mueller committed
31
to print the help-section of dcdbpusher.
Micha Mueller's avatar
Micha Mueller committed
32

33
Dcdbpusher will check the given file-path for the global configuration file `global.conf`.
Micha Mueller's avatar
Micha Mueller committed
34

35
### <a name="GC">Global Configuration</a>
Micha Mueller's avatar
Micha Mueller committed
36

Micha Mueller's avatar
Micha Mueller committed
37
`global.conf` should have the following scheme:
Micha Mueller's avatar
Micha Mueller committed
38
39
```
global {
Micha Mueller's avatar
Micha Mueller committed
40
41
42
  mqttBroker localhost:1883
  mqttprefix /00112233445566778899AABB0000
  threads    24
Micha Mueller's avatar
Micha Mueller committed
43
  verbosity  0
Micha Mueller's avatar
Micha Mueller committed
44
  daemonize  false
Micha Mueller's avatar
Micha Mueller committed
45
  tempdir    ./../testDir/
46
47
}

Micha Mueller's avatar
Micha Mueller committed
48
plugins {
49

Micha Mueller's avatar
Micha Mueller committed
50
51
52
  plugin sysfs {
    path	./
    config	../data/sysfsTest.conf
53
54
55
  }
  
  plugin perfevent {
Micha Mueller's avatar
Micha Mueller committed
56
57
  	path
  	config
58
  }
Micha Mueller's avatar
Micha Mueller committed
59
60
}
```
Micha Mueller's avatar
Micha Mueller committed
61
Explanation of the values:
Micha Mueller's avatar
Micha Mueller committed
62

63
| Value &ensp; &ensp; &ensp; &ensp; &ensp; &ensp; | Explanation |
Micha Mueller's avatar
Micha Mueller committed
64
65
66
67
|:----- |:----------- |
| global | Wrapper structure for the global values.
| &ensp;&ensp;mqttBroker | Define address and port of the MQTT-broker which collects the messages (sensor values) send by dcdbpusher.
| &ensp;&ensp;mqttprefix | To not rewrite a full MQTT-topic for every sensor one can specify here a consistend prefix.
Micha Mueller's avatar
Micha Mueller committed
68
69
| &ensp;&ensp;threads | Specify how many threads should be created to handle the sensors async. Default value of threads is 1. Note that the MQTTPusher always starts an extra thread. So the actual number of started threads is always one more than defined here. Specifying not enough threads can result in a delay for some sensors until they are read.
| &ensp;&ensp;verbosity | Level of detail in the logfile (dcdb.log). Set to a value between 0 (all log-messages, default) and 5 (only fatal messages). NOTE: level of verbosity for the command-line log can be set via the -v flag independently when invoking dcdbpusher.
Micha Mueller's avatar
Micha Mueller committed
70
| &ensp;&ensp;daemonize | Set to 'true' if dcdbpusher should run detached as daemon. Default is false.
Micha Mueller's avatar
Micha Mueller committed
71
| &ensp;&ensp;tempdir | One can specify a writeable directory where dcdbpusher can write its temporary and logging files to. Default is the current (' ./ ' ) directory.
Micha Mueller's avatar
Micha Mueller committed
72
73
74
75
76
77
78
79
| | |
| plugins | In this section one can specify the plugins which should be used.
| &ensp;&ensp;plugin name | The plugin name is used to build the corresponding lib-name (e.g. sysfs --> libdcdbplugin_sysfs.1.0)
| &ensp;&ensp;&ensp;&ensp;path | Specify the path where the plugin (the shared library) is located. If left empty, dcdbpusher will look in the default lib-directories (usr/lib and friends) for the plugin-file.
| &ensp;&ensp;&ensp;&ensp;config | One can specify a separate config-file (including path to it) for the plugin to use. If not specified, dcdbpusher will look up pluginName.conf (e.g. sysfs.conf) in the same directory where global.conf is located.
| | |


80
Formats of the other sensor-specific config-files are explained in the corresponding [subsections](#IPMI). Example configuration-files can be found in the `config/` directory.
Micha Mueller's avatar
Micha Mueller committed
81
82
83


## MQTT topic
84

Micha Mueller's avatar
Micha Mueller committed
85
For communication between the different DCDB-components (database, dcdbpusher) the [MQTT protocol](https://mqtt.org/) is used. In order to identify each sensor, everyone has to have a unique MQTT topic assigned. A MQTT topic for DCDB consists of exactly 128 bits (= 32 hex characters), not including '/' separators.
86

Micha Mueller's avatar
Micha Mueller committed
87
88
89
# Plugins

The core of dcdbpusher is responsible of collecting all the sensor values and sending them to the database. However, the main functionality of the sensors comes from the various plugins. Every plugin corresponds to a special sensor functionality.
90
Although every plugin requires different configuration parameters for its sensor functionality, some parameters are required equally for every sensor. The config-files for the plugins can follow two schemes: one where every sensor is defined on his own, and one (e.g. for IPMI and PDU) where sensors are aggregated to a higher level unit. The two possible schemes and uniformly needed sensor parameters shall be explained in the following. Configuration parameters which are only required specifically for sensors within a plugin are explained in the corresponding [subsections](#IPMI).
Micha Mueller's avatar
Micha Mueller committed
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
```
 Standalone sensors:							| Sensors divided into units:
------------------------------------------------+------------------------------------------------
												|
global {										|global {
	mqttprefix /00112233445566778899AABB0000	|	mqttprefix /00112233445566778899AABB0000
}												|}
												|
SensorTemplate {								|SensorTemplate {
	sensor name {								|	sensor name {
		...										|		...
	}											|	}
												|
	...											|	...
}												|}
												|
sensors {										|Units {
 	sensor name1 {								|	sensorUnit u1 {
		default		A							|		unitParams		?
		interval	1000						|	
		mqttsuffix	0000						|		sensors {
		minValues	1							|			sensor name1 {
		params		?							|				default		A
	}											|				interval	1000
												|				mqttsuffix	000
	sensor name2 {								|				minValues	1
		...										|				params		?
	}											|			}
												|
	...											|			sensor name2 {
}												|				...
												|			}
												|			...
												|		}
												|	}
												|
												|	sensorUnit u2 {
												|		...
												|	}
												|
												|	...
												|}
```
Explanation of the values:

136
| Value &ensp; &ensp; &ensp; &ensp; &ensp; &ensp; &ensp; &ensp; &ensp; | Explanation |
Micha Mueller's avatar
Micha Mueller committed
137
138
139
140
141
|:----- |:----------- |
| global | Here one can overwrite the global values defined in `global.conf`. The overwritten values are only used in the scope of the specific plugin.
| &ensp;&ensp;mqttprefix | Currently only overwriting of the mqttprefix is supported.
| | |
| SensorTemplate | Define template sensors to be used later in the configuration. This feature is mainly for convenience reasons. One is not obligated to define any template sensors. However it is required to at least define an empty SensorTemplate {} structure.
142
| &ensp;&ensp;sensor name | Every template sensor needs a name for future reference. A template sensor can define every value (including values specific to a plugin) a normal sensor can (see below).
Micha Mueller's avatar
Micha Mueller committed
143
144
145
146
147
148
149
150
151
152
153
154
155
156
| | |
| Units | Section to define different units where sensors may be aggregated to. Not every plugin makes use of this subdivision. Where it is used it the Units may be named different.
| &ensp;&ensp;sensorUnit u1 | If the unit subdivision is used, subunits need to be used and also need to be named.
| &ensp;&ensp;&ensp;&ensp;unitParams | One may be able to define special parameters specific to the subunits. They should be explained with the corresponding plugin if it makes use of subunits.
| | |
| &ensp;&ensp;&ensp;&ensp;sensors | Define in this section the sensors for the plugin/subunit
| &ensp;&ensp;&ensp;&ensp;&ensp;&ensp;sensor name | Every sensor needs a unique name
| &ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;default | Mention here the name of the template sensor to be used. The sensor will be initialized with the exact same values as the template sensor. This field can be left out if all required values for the sensor are defined manually.
| &ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;interval | Time in [ms] between two consecutive sensor reads. Default is 1000[ms] = 1[s]
| &ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;mqttsuffix | Suffix which is appended to the MQTT-prefix. Together with the prefix this should be a globally unique MQTT-topic for every sensor.
| &ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;minValues | Minimum number of sensor reads the sensor should gather before they are sent together to the database. Useful to reduce MQTT-overhead. Default is 1 (every sensor value is sent on his own).
| &ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;params | Every plugin requires additional configuration parameters. Those may be unique to every plugin and are explained in the corresponding subsections below.

For an easy start one can begin with modifying the supplied example configuration files in the `/config` directory.
157

Micha Mueller's avatar
Micha Mueller committed
158
## <a name="IPMI">IPMI</a>
Micha Mueller's avatar
Micha Mueller committed
159

Micha Mueller's avatar
Micha Mueller committed
160
The [IPMI](https://en.wikipedia.org/wiki/Intelligent_Platform_Management_Interface) plugin enables dcdbpusher to collect sensor values offered by a baseboard management controller (BMC).
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

### config file format

The config file for the IPMI plugin should fulfill the following scheme:
```
global {
	sessiontimeout 500
	retransmissiontimeout 200
	mqttprefix /AABBAABBAABBAACCDDCCDDCC
}

templateSensors {
	sensor tempSens {
		...
	}
	
	...
}

hosts {
	host bmc1 {
		username "USERID"
		password "PASSW0RD"
		mqttprefix "/00/11/2233445566/778899AABB"
		
		sensors {
			sensor rawSens {
				default		tempSens
				interval	1000
				cmd			"0x00 0x2e 0x81 0x4d 0x4f 0x00 0x00 0x01 0x82 0x00 0x08"
				start		5
				stop		12
				mqttsuffix	99887766
			}
			
			sensor recordSens {
				recordId	4321
198
				factor		1.5
199
200
201
202
203
204
205
206
207
208
209
210
				mqttsuffix	11223345
			}
			
			...
		}
	}
	
	host bmc2 {
		...
	}
}
```
211
Explanation of the values specific for the IPMI plugin:
212
213
214
215
216
217
218
219
220
221
222

| Value &ensp; &ensp; &ensp; &ensp; &ensp; &ensp; &ensp; &ensp; &ensp; | Explanation |
|:----- |:----------- |
| sessiontimeout | Session timeout value for the IPMI-connection
| retransmissiontimeout | Retransmission timeout value for the IPMI-connection
| username | For the remote IPMI-connection login credentials are required
| password | For the remote IPMI-connection login credentials are required
| mqttprefix | One can define a different MQTT-prefix per host
| cmd | One can define a raw IPMI-command (in hex-notation) to be sent. In this case also the start and stop fields for the response have to be defined. Alternatively, one can define the record-ID of the sensor (see below).
| start | Required if raw command is sent
| stop | Required if raw command is sent
Micha Mueller's avatar
Micha Mueller committed
223
| recordId | Define the record-ID of the sensor to be read. One can look up the corresponding record-IDs for every sensor with the "ipmi-sensors" command line tool (ships with the freeipmi-library). Alternatively, one can define a raw IPMI-command (see above).
224
| factor | One can specify a factor to scale the read value before it is stored in the database (to adjust precision).
225

Micha Mueller's avatar
Micha Mueller committed
226
227
228
## Perf-event

The Perf-event functionality is tasked with collecting data from the CPUs various performance counters (PMUs).
229
> NOTE &ensp;&ensp;&ensp; The perf-event plugin measures PMUs for all processes running on a specific CPU. Therefore a value of less than 1 is required in `/proc/sys/kernel/perf_event_paranoid`. Other values (>=1) restrict the access to PMUs. See this [footnote](#fn1) for additional information.
Micha Mueller's avatar
Micha Mueller committed
230
231

### config file format
Micha Mueller's avatar
Micha Mueller committed
232
For the perf-event plugin the sensors are renamed to counters. Nevertheless the rules and explanations from the generic config file still apply.
Micha Mueller's avatar
Micha Mueller committed
233
```
Micha Mueller's avatar
Micha Mueller committed
234
CounterTemplate {
Micha Mueller's avatar
Micha Mueller committed
235
236
237
238
239
  counter A {...}
  counter B {...}
  ...
}

Micha Mueller's avatar
Micha Mueller committed
240
241
242
243
counters {
  counter c_name {
    default     A
    interval    1000
244
245
    mqttsuffix  0000	// Perfpusher uses a separate MQTT-topic for every CPU. For every used CPU the mqttsuffix is increased by one. 
    					// Dcdbpusher will terminate if an suffix is used twice! Example:
246
247
    					// For counter A the mqttsuffix 00A8 is given and the system on which perfpusher is run has 8 cores. Then perfpusher uses
    					// the mqtt-suffixe 00A8, 00A9, 00AA, 00AB, 00AC, 00AD, 00AE, 00AF for the 8 cores.
248
    					// As they are already used by counter A, any other counter must not use those. Counter B can e.g. start with mqttsuffix 00B0.
Micha Mueller's avatar
Micha Mueller committed
249
    minValues   1
250
251
252
253
254
255
    type        XX		// Type of which the counter should be. Each type determines different possible values for the config-field. 
    					// Possible type-values are described below.
    config      YY		// Together with the type-field config determines which performance counter should be read. 
    					// Possible values and what they measure are listed below.
    cpus		0,1,2-4 // One can define a comma-separated list of cpu numbers (also value ranges can be specified, e.g. 2-4 equals 2,3,4). 
    					// The hardware counter will then be only opened on the specified cpus.
Micha Mueller's avatar
Micha Mueller committed
256
257
258
259
260
261
262
263
264
265
266
267
  }

  counter c_name2 {
    ...
  }

  ...
}
```

### type and config

Micha Mueller's avatar
Micha Mueller committed
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
(see the [perf_event_open man-page](http://man7.org/linux/man-pages/man2/perf_event_open.2.html) for more detailed explanations)

| Type | Config | Explanation |
|:----:|:------ |:----------- |
| PERF_TYPE_HARDWARE | | generalized hardware CPU events
| " | PERF_COUNT_HW_CPU_CYCLES | total cycles (affected by frequency scaling)
| " | PERF_COUNT_HW_INSTRUCTIONS | retired instructions
| " | PERF_COUNT_HW_CACHE_REFERENCES | cache accesses (usually last level)
| " | PERF_COUNT_HW_CACHE_MISSES | cache misses (usually last level)
| " | PERF_COUNT_HW_BRANCH_INSTRUCTIONS | retired branch instructions
| " | PERF_COUNT_HW_BRANCH_MISSES | mispredicted branch instructions
| " | PERF_COUNT_HW_BUS_CYCLES | bus cycles
| " | PERF_COUNT_HW_STALLED_CYCLES_FRONTEND | stalled cycles during issue
| " | PERF_COUNT_HW_STALLED_CYCLES_BACKEND  | stalled cycles during retirement
| " | PERF_COUNT_HW_REF_CPU_CYCLES | total cycles (unaffected by frequency scaling)
283
| | | |
Micha Mueller's avatar
Micha Mueller committed
284
285
286
287
288
289
290
291
292
293
294
| PERF_TYPE_SOFTWARE | | software events provided by the kernel
| " | PERF_COUNT_SW_CPU_CLOCK | reports CPU clock
| " | PERF_COUNT_SW_TASK_CLOCK | clock count specific to the running task
| " | PERF_COUNT_SW_PAGE_FAULTS | number of page faults
| " | PERF_COUNT_SW_CONTEXT_SWITCHES | count of context switches
| " | PERF_COUNT_SW_CPU_MIGRATIONS | times the process has migrated to a new CPU
| " | PERF_COUNT_SW_PAGE_FAULTS_MIN | number of minor page faults (no disk-I/O)
| " | PERF_COUNT_SW_PAGE_FAULTS_MAJ | number of major page faults (disk-I/O was required)
| " | PERF_COUNT_SW_ALIGNMENT_FAULTS | alignment faults when accessing unaligned memory
| " | PERF_COUNT_SW_EMULATION_FAULTS | number of unimplemented instructions which had to be emulated
| " | PERF_COUNT_SW_DUMMY | placeholder which counts nothing
295
| | | |
Micha Mueller's avatar
Micha Mueller committed
296
297
| PERF_TYPE_TRACEPOINT | | not yet implemented
| PERF_TYPE_HW_CACHE | | not yet implemented
298
| | | |
Micha Mueller's avatar
Micha Mueller committed
299
300
| PERF_TYPE_RAW | | user can define architecture-specific raw events here.
| " | *XXXX* | Config must be an hex value (without 0x prefix). See <sup>[2](#fn2)</sup>
301
| | | |
Micha Mueller's avatar
Micha Mueller committed
302
| PERF_TYPE_BREAKPOINT | --- | config not required, any values will be ignored. However config must still be specified (even if empty)
Micha Mueller's avatar
Micha Mueller committed
303

304
#### Footnotes
Micha Mueller's avatar
Micha Mueller committed
305
306
307

Taken from the [perf_event_open man-page](http://man7.org/linux/man-pages/man2/perf_event_open.2.html):

308
309
310
<a name="fn1">**1**</a>: &ensp; The pid and cpu arguments allow specifying which process and CPU to monitor:  
[...]  
pid == -1 and cpu >= 0  
311
This measures all processes/threads on the specified CPU. This requires CAP_SYS_ADMIN capability or a /proc/sys/kernel/perf_event_paranoid value of less than 1.
312
313
314
315

[...]

The perf_event_paranoid file can be set to restrict access to the performance counters.
Micha Mueller's avatar
Micha Mueller committed
316
317
318
319
320
321
322

| Value | Restriction |
|:-----:|:----------- |
| 2 | allow only user-space measurements (default since Linux 4.6) |
| 1 | allow both kernel and user measurements (default before Linux 4.6) |
| 0 | allow access to CPU-specific data but not raw trace-point samples |
| -1 | no restrictions |
Micha Mueller's avatar
Micha Mueller committed
323
324
325
	
The existence of the perf_event_paranoid file is the official method for determining if a kernel supports perf_event_open()

Micha Mueller's avatar
Micha Mueller committed
326
<a name="fn2">**2**</a>: &ensp; If type is *PERF_TYPE_RAW*, then a custom "raw" config value is needed. Most CPUs support events that are not covered by the "generalized" events. These are implementation defined; see your CPU manual (for example the Intel Volume 3B documentation or the AMD BIOS and Kernel Developer Guide). The libpfm4 library can be used to translate from the name in the architectural manual to the raw hex value perf_event_open() expects in this field.
Micha Mueller's avatar
Micha Mueller committed
327
328
329

## snmp

Micha Mueller's avatar
Micha Mueller committed
330
331
332
## sysFS

SysFS sensors read data from sysFS files. The configuration file of the plugin corresponds to the generic plugin configuration with standalone sensors. Additionally for a sysFS sensor the following parameters are mandatory/possible:
333

Micha Mueller's avatar
Micha Mueller committed
334
335
336
| Value | Explanation |
|:----- |:----------- |
| path | Path to the sysFS file the sensor should read from. This parameter is mandatory.
337
| filter | One can define an optional filter if the sysFS file consists of more than only the sensor value. Please note the following points for filters: <br> 1.  The filter supports substitutions. For substitution sed syntax ("s/.../.../") is used. Therefore extended regular expressions (ERE) are used as regex-syntax. ERE is closest to Basic RE (BRE), which is actually used by sed, but requires less escaping. <br> 2.  If a \ ("backslash") is needed in the regex (for escaping), always use \\ ("double backslash") as the regex is read in as string and strings also escape with backslash <br> 3.  Whitespaces are actually used as value separators in the config files. If your filter requires whitespaces either use [[:space:]] in the regex or put it in quotation marks ("") <br> 4.  To be able to reference parts of the match (for substitution) use groups. Groups are created with parentheses. <br>  5.  If using character classes like [[:digit:]] always make sure to use double brackets ("[[" and "]]") or they will not be recognized. <br>  See [ERE-syntax](https://www.gnu.org/software/sed/manual/html_node/ERE-syntax.html#ERE-syntax) <br>  See [substitution syntax](http://www.boost.org/doc/libs/1_65_1/libs/regex/doc/html/boost_regex/format/sed_format.html)
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

## PDU

The Power Delivery Unit (PDU) plugin is in charge of sending a network-request to the PDUs and gathering specified sensor data from the XML-file response.

### config file format

The config file for the PDU plugin should fulfill the following scheme:
```
global {
	mqttprefix	/00112233445566778899AABBCCDD
}

SensorTemplate {
	sensor tempSens {
		...
	}
	
	...
}

pdus {
	pdu rack1 {
361
		host	example.com:443
362
		TTL		500
363
		request	"I hereby demand\n a response called \"response\""
364
365
366
367
368
		
		sensors {
			sensors pcs1 {
				default			tempSens
				interval		2000
369
				path			"root.node1.node2(id=1).node3(id=1,type=2).valueNode"
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
				mqttsuffix		0001
				minValues		3
			}
			
			sensor pcs2 {
				...
			}
		}
	}
	
	pdu rack2 {
		...
	}
}
```
Micha Mueller's avatar
Micha Mueller committed
385
Explanation of the values specific for the PDU plugin:
Micha Mueller's avatar
Micha Mueller committed
386

387
| Value | Explanation |
388
|:----- |:----------- |
389
| host | Hostname and (optional) port where to fetch the XML-file with sensor data from. If no port is specified, 443 is used. The plugin requests the file via HTTPS.
390
| TTL | To avoid requesting a current XML-file every time a sensor wants to read his value, one can define a time to live (TTL) for the file here. A new XML-file is requested at the earliest if the TTL has expired. Default value is 1000[ms].
Micha Mueller's avatar
Micha Mueller committed
391
| request | Define the request to be sent to the host via HTTPS as a string. One should put the request in quotation marks (' " ') to enable the use of whitespaces within the request. Special characters (like usage of ' " ' within the request) should be escaped (' " ' --> ' \" '; ' \ ' --> ' \\\\ '; newline --> ' \n '; ...).
392
| path | Define a dot-separated path to the value to be read in the XML file. One can specify attribute values a node has to fulfil in brackets after the node. Even multiple (comma-separated) attributes can be given, however no whitespaces should be used (!) as they will not be filtered and could therefore be treat as part of the attributes name.
393

394
395
396
## BACnet

The BACnet plugin enables dcdbpusher to communicate and request data from devices which communicate via the BACnet protocol. A so called "read property" request is sent by the plugin to the BACnet devices as configured in the config file. The response value is then stored in the database. Usually one is only interested in collecting the current reading of a BACnet device (property PROP_PRESENT_VALUE, ID 85). However, also reading of other properties is supported.
397
> NOTE &ensp;&ensp;&ensp; On startup BACnet plugin does no device discovery. Instead it relies on the user providing an `address_cache` file with addresses of all required BACnet devices. One can generate such a address-file for example by using the `bacwi` demo tool provided by the BACnet-Stack. Currently the `address_cache` file is expected to be in the same directory as the dcdbpusher binary.
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

### config file format

The config file for the BACnet plugin should fulfill the following scheme:
```
global {
	mqttPrefix	/FF112233445566778899FFFF
	interface	eth0
	port		22222
	apdu_timeout	200
	apdu_retries	1
}

templates {
  property def0 {
413
    factor		100
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
	id			85
    interval    1000
    minValues   3
  }
  
  property def1 {
  	...
  }
}

devices {
	device dev1 {
		instance	1234
		mqttPart	FF
		
		object o1 {
			type 	8
			instance	1234
			mqttPart	FF
			property test1 {
				default def0
				id	85
				mqttsuffix	0000
			}
			property smth {
				...
			}
		}
		
		object o2 {
			...
		}
	}
	
	device jklo {
		...
	}
}
```
Explanation of the values specific for the BACnet plugin:

| Value | Explanation |
|:----- |:----------- |
Micha Mueller's avatar
Micha Mueller committed
457
| interface | Network interface (IPv4) which is to be used by the plugin to send its "Read Property" requests.
458
459
460
461
| port | Port to use on the interface
| apdu_timeout | Value of µ-seconds before sending a request times out.
| apdu_retries | How often should sending a request be retried.
| templates | One can define template properties in this section for convenience.
462
| factor | Described in the section for the [IPMI-plugin](#IPMI).
463
| devices | Starts the part in the config file where the actual BACnet devices are configured. A BACnet device consists of multiple nested parts: device > objects > properties.
Micha Mueller's avatar
Micha Mueller committed
464
| mqttPart | One can define a partial MQTT topic on each nesting level, which will be appended to the MQTT prefix. Together with the mqttsuffix of a property this will make up the whole MQTT topic of a property (aka sensor). MQTT topic = mqttPrefix + mqttPart (device) + mqttPart (object) + mqttsuffix.
465
466
467
468
469
470
| instance (device) | Instance of the BACnet-device.
| type | Type of the object within the device.
| instance (object) | Instance of the object within the device.
| id | ID of the property to be read from the BACnet device-object. Assignment of numbers to properties is done according to the enum as defined in `bacenum.h`.


Micha Mueller's avatar
Micha Mueller committed
471
#### TODOS
472
* perhaps xml-file example for pdu
473
* snmp, more about mqtt-topic