ConfiguratorTemplate.h 20.9 KB
Newer Older
1
/*
2
 * ConfiguratorTemplate.h
3
4
5
6
7
 *
 *  Created on: 13.01.2018
 *      Author: Micha Mueller
 */

8
9
#ifndef SRC_CONFIGURATORTEMPLATE_H_
#define SRC_CONFIGURATORTEMPLATE_H_
10

11
12
13
14
15
16
#include <map>

#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/info_parser.hpp>
17
18
19
#include "ConfiguratorInterface.h"
#include "SensorBase.h"
#include "SensorGroupTemplate.h"
20

21
//#define STRCMP(node,str) boost::iequals(node.first,str) //DEPRECATED
Micha Mueller's avatar
Micha Mueller committed
22
#define CFG_VAL	boost::property_tree::iptree&
23

24
#define ADD						BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config)
25
#define ATTRIBUTE(name,setter)		do { if (boost::iequals(val.first, name)) { s.setter(val.second.data()); } } while(0)
Micha Mueller's avatar
Micha Mueller committed
26
#define SETTING(name)				if (boost::iequals(val.first, name))
27

Micha Mueller's avatar
Micha Mueller committed
28
/**
29
 * Non-virtual interface template for the configurators.
Micha Mueller's avatar
Micha Mueller committed
30
 */
31
template <class SBase, class SGroup, class SEntity = nullptr_t>
32
class ConfiguratorTemplate : public ConfiguratorInterface {
33
	//the template shall only be instantiated for classes which derive from SensorBase/SensorGroup
34
	static_assert(std::is_base_of<SensorBase, SBase>::value, "SBase must derive from SensorBase!");
35
	static_assert(std::is_base_of<SensorGroupInterface, SGroup>::value, "SGroup must derive from SensorGroupInterface!");
36

37
protected:
38
39
	typedef std::map<std::string, SGroup*> sGroupMap_t;
	typedef std::map<std::string, SEntity*> sEntityMap_t;
40

41
public:
42
	ConfiguratorTemplate() :
43
44
45
		_entityName("INVALID"),
		_groupName("INVALID"),
		_baseName("INVALID"),
46
47
48
		_cfgPath(""),
		_mqttPrefix(""),
		_cacheInterval(900000) {}
49

50
51
	ConfiguratorTemplate(const ConfiguratorTemplate&) = delete;

52
	virtual ~ConfiguratorTemplate() {
53
54
		for (auto g : _sensorGroups) {
			delete g;
55
		}
56
57
58
		for (auto e : _sensorEntitys) {
			delete e;
		}
59
		for (auto tg : _templateSensorGroups) {
60
			delete tg.second;
61
62
		}
		for (auto te : _templateSensorEntitys) {
63
			delete te.second;
64
		}
65
		_sensorGroupInterfaces.clear();
66
67
		_sensorGroups.clear();
		_sensorEntitys.clear();
68
		_templateSensorGroups.clear();
69
		_templateSensorEntitys.clear();
70
	}
71

72
73
	ConfiguratorTemplate& operator=(const ConfiguratorTemplate&) = delete;

Micha Mueller's avatar
Micha Mueller committed
74
75
	/**
	 * Read in the given configuration
76
	 *
77
78
	 * Overwriting this method is only required if a custom logic is really necessary!
	 *
Micha Mueller's avatar
Micha Mueller committed
79
	 * @param	cfgPath Path to the config-file
80
81
	 *
	 * @return	True on success, false otherwise
Micha Mueller's avatar
Micha Mueller committed
82
	 */
83
	bool readConfig(std::string cfgPath) {
84
		_cfgPath = cfgPath;
85
86
87
88
89

		boost::property_tree::iptree cfg;
		boost::property_tree::read_info(cfgPath, cfg);

		//read global variables (if present overwrite those from global.conf)
90
91
		readGlobal(cfg);

92
93
94
		//read groups and templates for groups. If present also entity/-template stuff
		BOOST_FOREACH(boost::property_tree::iptree::value_type &val, cfg) {
			//TODO allow for template sensors?
95
			//TODO allow single sensors for convenience?
96
97
98
99
			//template entity
			if (boost::iequals(val.first, "template_" + _entityName)) {
				LOG(debug) << "Template " << _entityName << " \"" << val.second.data() << "\"";
				if (!val.second.empty()) {
Micha Mueller's avatar
Micha Mueller committed
100
101
102
					//name of an entity is only used to identify templates and is not stored otherwise
					SEntity* entity = new SEntity();
					if (readSensorEntity(*entity, val.second, true)) {
103
						auto ret = _templateSensorEntitys.insert(std::pair<std::string, SEntity*>(val.second.data(), entity));
104
						if(!ret.second) {
105
							LOG(warning) << "Template " << _entityName << " " << val.second.data() << " already exists! Omitting...";
Micha Mueller's avatar
Micha Mueller committed
106
							delete entity;
107
108
109
						}
					} else {
						LOG(warning) << "Template " << _entityName << " \"" << val.second.data() << "\" has bad values! Ignoring...";
Micha Mueller's avatar
Micha Mueller committed
110
						delete entity;
111
112
113
114
115
116
117
118
					}
				}
			//template group
			} else if (boost::iequals(val.first, "template_" + _groupName)) {
				LOG(debug) << "Template " << _groupName << " \"" << val.second.data() << "\"";
				if (!val.second.empty()) {
					SGroup* group = new SGroup(val.second.data());
					if (readSensorGroup(*group, val.second)) {
119
						auto ret = _templateSensorGroups.insert(std::pair<std::string, SGroup*>(val.second.data(), group));
120
						if(!ret.second) {
121
							LOG(warning) << "Template " << _groupName << " " << val.second.data() << " already exists! Omitting...";
Micha Mueller's avatar
Micha Mueller committed
122
							delete group;
123
						}
124
125
					} else {
						LOG(warning) << "Template " << _groupName << " \"" << val.second.data() << "\" has bad values! Ignoring...";
Micha Mueller's avatar
Micha Mueller committed
126
						delete group;
127
128
					}
				}
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
			//template single sensor
			} else if (boost::iequals(val.first, "template_single_" + _baseName)) {
				LOG(debug) << "Template single " << _baseName << " \"" << val.second.data() << "\"";
				if (!val.second.empty()) {
					SGroup* group = new SGroup(val.second.data());
					if (readSensorGroup(*group, val.second)) {
						//group which consists of only one sensor
						SBase* sensor = new SBase(val.second.data());
						if (readSensorBase(*sensor, val.second)) {
							group->pushBackSensor(sensor);
							auto ret = _templateSensorGroups.insert(std::pair<std::string, SGroup*>(val.second.data(), group));
							if(!ret.second) {
								LOG(warning) << "Template single " << _baseName << " " << val.second.data() << " already exists! Omitting...";
								delete group;
							}
						} else {
							LOG(warning) << "Template single " << _baseName << " " << val.second.data() << " could not be read! Omitting";
							delete group;
						}
					} else {
						LOG(warning) << "Template single " << _baseName << " \"" << val.second.data() << "\" has bad values! Ignoring...";
						delete group;
					}
				}
153
154
155
156
			//entity
			} else if (boost::iequals(val.first, _entityName)) {
				LOG(debug) << _entityName << " \"" << val.second.data() << "\"";
				if (!val.second.empty()) {
Micha Mueller's avatar
Micha Mueller committed
157
158
					SEntity* entity = new SEntity();
					if (readSensorEntity(*entity, val.second, false)) {
159
160
161
						_sensorEntitys.push_back(entity);
					} else {
						LOG(warning) << _entityName << " \"" << val.second.data() << "\" has bad values! Ignoring...";
Micha Mueller's avatar
Micha Mueller committed
162
						delete entity;
163
					}
164
165
166
167
168
169
170
				}
			//group
			} else if (boost::iequals(val.first, _groupName)) {
				LOG(debug) << _groupName << " \"" << val.second.data() << "\"";
				if (!val.second.empty()) {
					SGroup* group = new SGroup(val.second.data());
					if (readSensorGroup(*group, val.second)) {
171
						storeSensorGroup(group);
172
173
					} else {
						LOG(warning) << _groupName << " \"" << val.second.data() << "\" has bad values! Ignoring...";
Micha Mueller's avatar
Micha Mueller committed
174
						delete group;
175
176
					}
				}
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
			//single sensor
			} else if (boost::iequals(val.first, "single_" + _baseName)) {
				LOG(debug) << "Single " << _baseName << " \"" << val.second.data() << "\"";
				if (!val.second.empty()) {
					SGroup* group = new SGroup(val.second.data());
					if (readSensorGroup(*group, val.second)) {
						//group which consists of only one sensor
						SBase* sensor;
						//perhaps one sensor is already present because it was copied from the template group
						if (group->getSensors().size() != 0) {
							sensor = dynamic_cast<SBase*>(group->getSensors()[0]);
							sensor->setName(val.second.data());
							if (readSensorBase(*sensor, val.second)) {
								storeSensorGroup(group);
							} else {
								LOG(warning) << "Single " << _baseName << " " << val.second.data() << " could not be read! Omitting";
								delete group;
							}
						} else {
							sensor = new SBase(val.second.data());
							if (readSensorBase(*sensor, val.second)) {
								group->pushBackSensor(sensor);
								storeSensorGroup(group);
							} else {
								LOG(warning) << "Single " << _baseName << " " << val.second.data() << " could not be read! Omitting";
								delete group;
							}
						}
					} else {
						LOG(warning) << "Single " << _baseName << " \"" << val.second.data() << "\" has bad values! Ignoring...";
						delete group;
					}
				}
210
211
			}
		}
212
213
214
215
		//read of config finished. Now we build the mqtt-topic for every sensor
		for(auto g : _sensorGroups) {
			for(auto s : g->getSensors()) {
				s->setMqtt(_mqttPrefix + g->getMqttPart() + s->getMqtt());
216
				LOG(debug) << g->getGroupName() << "::" << s->getName() << " using MQTT-topic \"" << s->getMqtt() << "\"";
217
218
			}
		}
219
		return true;
220
221
222
223
	}

	/**
	 * Clear internal storage and read in the configuration again.
224
225
	 *
	 * @return	True on success, false otherwise
226
	 */
227
	bool reReadConfig() final {
Micha Mueller's avatar
Micha Mueller committed
228
229
		//bring everything to a halt
		for(auto g : _sensorGroups) {
230
			g->stop();
Micha Mueller's avatar
Micha Mueller committed
231
232
233
234
235
236
		}

		//wait until everything is halted
		for(auto g : _sensorGroups) {
			g->wait();
		}
237

238
		//clean up sensors/groups/entitys and templates
Micha Mueller's avatar
Micha Mueller committed
239
240
241
		for(auto g : _sensorGroups) {
			delete g;
		}
242
243
244
		for(auto e : _sensorEntitys) {
			delete e;
		}
245
		for (auto tg : _templateSensorGroups) {
246
			delete tg.second;
247
248
		}
		for (auto te : _templateSensorEntitys) {
249
			delete te.second;
250
		}
251
		_sensorGroupInterfaces.clear();
Micha Mueller's avatar
Micha Mueller committed
252
		_sensorGroups.clear();
253
		_sensorEntitys.clear();
254
		_templateSensorGroups.clear();
255
		_templateSensorEntitys.clear();
256

Micha Mueller's avatar
Micha Mueller committed
257
		//back to the very beginning
258
		return readConfig(_cfgPath);
259
	}
260

261
262
263
264
265
266
267
	/**
	 * Sets internal variables with the ones provided by pluginSettings.
	 * This method should be called once after constructing a configurator
	 * to provide him with the global default values.
	 *
	 * @param pluginSettings	Struct with global default settings for the plugins.
	 */
268
	void setGlobalSettings(const pluginSettings_t& pluginSettings) final {
269
270
		_mqttPrefix = pluginSettings.mqttPrefix;
		_cacheInterval = pluginSettings.cacheInterval;
271
272

		derivedSetGlobalSettings(pluginSettings);
273
274
	}

Micha Mueller's avatar
Micha Mueller committed
275
276
277
278
279
	/**
	 * Get all sensor groups
	 *
	 * @return	Vector containing pointers to all sensor groups of this plugin
	 */
Micha Mueller's avatar
Micha Mueller committed
280
	std::vector<SensorGroupInterface*>& getSensorGroups() final {
281
282
283
		return _sensorGroupInterfaces;
	}

284
protected:
285
286
287
	void storeSensorGroup(SGroup* sGroup) {
		_sensorGroups.push_back(sGroup);
		_sensorGroupInterfaces.push_back(sGroup);
Micha Mueller's avatar
Micha Mueller committed
288
289
	}

290
291
	/**
	 * Non-virtual interface method for class-internal use only.
292
	 * Reads and sets the common base values of a sensor base (currently none),
293
294
	 * then calls the corresponding derived function to read plugin specific
	 * values.
295
	 *
296
	 * @param sBase		The sensor base for which to set the values
297
298
299
300
	 * @param config	A boost property (sub-)tree containing the sensor values
	 *
	 * @return	True on success, false otherwise
	 */
Micha Mueller's avatar
Micha Mueller committed
301
	bool readSensorBase(SBase& sBase, CFG_VAL config) {
302
303
304
305
306
307
308
309
		//TODO default templates useful?
		BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config) {
			if (boost::iequals(val.first, "mqttsuffix")) {
				sBase.setMqtt(val.second.data());
			}
		}
		sensorBase(sBase, config);
		return true;
310
311
312
313
	}

	/**
	 * Non-virtual interface method for class-internal use only.
314
315
	 * Reads and sets the common base values of a sensor group, then calls
	 * the corresponding derived function to read in plugin specific values.
316
	 *
317
	 * @param sGroup	The sensor group for which to set the values
318
319
320
321
	 * @param config	A boost property (sub-)tree containing the sensor values
	 *
	 * @return	True on success, false otherwise
	 */
Micha Mueller's avatar
Micha Mueller committed
322
	bool readSensorGroup(SGroup& sGroup, CFG_VAL config) {
323
		sGroup.setCacheInterval(_cacheInterval);
324
325
326
327
328
329
330
331
		//first check if default group is given
		boost::optional<boost::property_tree::iptree&> def = config.get_child_optional("default");
		if(def) {
			//we copy all values from default (including copy constructing its sensors)
			//if own sensors are specified they are appended
			LOG(debug) << "  Using \"" << def.get().data() << "\" as default.";
			auto it = _templateSensorGroups.find(def.get().data());
			if(it != _templateSensorGroups.end()) {
332
333
				sGroup = *(it->second);
				sGroup.setGroupName(config.data());
334
335
336
337
338
			} else {
				LOG(warning) << "Template " << _groupName << "\"" << def.get().data() << "\" not found! Using standard values.";
			}
		}

339
		//read in values inherited from SensorGroupInterface
340
		BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config) {
341
			if (boost::iequals(val.first, "interval")) {
342
				sGroup.setInterval(stoull(val.second.data()));
343
			} else if (boost::iequals(val.first, "minValues")) {
344
				sGroup.setMinValues(stoull(val.second.data()));
345
346
			} else if (boost::iequals(val.first, "mqttPart")) {
				sGroup.setMqttPart(val.second.data());
347
348
			} else if (boost::iequals(val.first, _baseName)) {
				LOG(debug) << "  " << _baseName << " " << val.second.data();
349
350
				SBase* sensor = new SBase(val.second.data());
				if (readSensorBase(*sensor, val.second)) {
351
					sGroup.pushBackSensor(sensor);
352
				} else {
353
					LOG(warning) << _baseName << " " << sGroup.getGroupName() << "::" << sensor->getName() << " could not be read! Omitting";
Micha Mueller's avatar
Micha Mueller committed
354
					delete sensor;
355
				}
356
357
358
			}
		}

359
360
361
		//TODO keep debug logging for config?
//		LOG(debug) << "  Interval : " << sGroup.getInterval();
//		LOG(debug) << "  minValues: " << sGroup.getMinValues();
362

363
364
		sensorGroup(sGroup, config);
		return true;
365
366
	}

367
368
369
370
371
372
373
	/**
	 * Non-virtual interface method for class-internal use only.
	 * Reads and sets the common base values of a sensor entity, then calls
	 * the corresponding derived function to read in plugin specific values.
	 *
	 * @param sEntity	The aggregating entity for which to set the values
	 * @param config	A boost property (sub-)tree containing the sensor values
Micha Mueller's avatar
Micha Mueller committed
374
375
	 * @param isTemplate	Indicate if sEntity is a template. If so, also store
	 * 						the corresponding sGroups in the template map
376
377
378
	 *
	 * @return	True on success, false otherwise
	 */
Micha Mueller's avatar
Micha Mueller committed
379
	bool readSensorEntity(SEntity& sEntity, CFG_VAL config, bool isTemplate) {
380
381
382
383
384
385
386
		//first check if default entity is given
		boost::optional<boost::property_tree::iptree&> def = config.get_child_optional("default");
		if(def) {
			//we copy all values from default
			LOG(debug) << "  Using \"" << def.get().data() << "\" as default.";
			auto it = _templateSensorEntitys.find(def.get().data());
			if(it != _templateSensorEntitys.end()) {
387
				sEntity = *(it->second);
Micha Mueller's avatar
Micha Mueller committed
388
389
390
391
				for(auto g : _templateSensorGroups) {
					if (isEntityOfGroup(*(it->second), *(g.second))) {
						SGroup* group = new SGroup(*(g.second));
						setEntityForGroup(sEntity, *group);
392
						storeSensorGroup(group);
Micha Mueller's avatar
Micha Mueller committed
393
394
					}
				}
395
396
397
398
			} else {
				LOG(warning) << "Template " << _entityName << "\"" << def.get().data() << "\" not found! Using standard values.";
			}
		}
Micha Mueller's avatar
Micha Mueller committed
399

400
		sensorEntity(sEntity, config);
Micha Mueller's avatar
Micha Mueller committed
401
402
403
404

		BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config) {
			if (boost::iequals(val.first, _groupName)) {
				LOG(debug) << "  " << _groupName << " " << val.second.data();
405
406
407
408
409
410
411
412
413
414
415
416
				if (!val.second.empty()) {
					SGroup* group = new SGroup(val.second.data());
					if(readSensorGroup(*group, val.second)) {
						setEntityForGroup(sEntity, *group);
						if (isTemplate) {
							auto ret = _templateSensorGroups.insert(std::pair<std::string, SGroup*>(val.second.data(), group));
							if(!ret.second) {
								LOG(warning) << "Template " << _groupName << " " << val.second.data() << " already exists! Omitting...";
								delete group;
							}
						} else {
							storeSensorGroup(group);
Micha Mueller's avatar
Micha Mueller committed
417
418
						}
					} else {
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
457
458
459
460
461
462
463
464
465
466
467
468
						LOG(warning) << _groupName << " " << group->getGroupName() << " could not be read! Omitting";
						delete group;
					}
				}
			} else if (boost::iequals(val.first, "single_" + _baseName)) {
				LOG(debug) << "Single " << _baseName << " \"" << val.second.data() << "\"";
				if (!val.second.empty()) {
					SGroup* group = new SGroup(val.second.data());
					//group which consists of only one sensor
					if (readSensorGroup(*group, val.second)) {
						setEntityForGroup(sEntity, *group);
						if (isTemplate) {
							SBase* sensor = new SBase(val.second.data());
							if (readSensorBase(*sensor, val.second)) {
								group->pushBackSensor(sensor);
								auto ret = _templateSensorGroups.insert(std::pair<std::string, SGroup*>(val.second.data(), group));
								if(!ret.second) {
									LOG(warning) << "Template single " << _baseName << " " << val.second.data() << " already exists! Omitting...";
									delete group;
								}
							} else {
								LOG(warning) << "Template single " << _baseName << " " << val.second.data() << " could not be read! Omitting";
								delete group;
							}
						} else {
							SBase* sensor;
							//perhaps one sensor is already present because it was copied from the template group
							if (group->getSensors().size() != 0) {
								sensor = dynamic_cast<SBase*>(group->getSensors()[0]);
								sensor->setName(val.second.data());
								if (readSensorBase(*sensor, val.second)) {
									storeSensorGroup(group);
								} else {
									LOG(warning) << "Single " << _baseName << " " << val.second.data() << " could not be read! Omitting";
									delete group;
								}
							} else {
								sensor = new SBase(val.second.data());
								if (readSensorBase(*sensor, val.second)) {
									group->pushBackSensor(sensor);
									storeSensorGroup(group);
								} else {
									LOG(warning) << "Single " << _baseName << " " << val.second.data() << " could not be read! Omitting";
									delete group;
								}
							}
						}
					} else {
						LOG(warning) << "Single " << _baseName << " \"" << val.second.data() << "\" has bad values! Ignoring...";
						delete group;
Micha Mueller's avatar
Micha Mueller committed
469
470
471
472
473
					}
				}
			}
		}

474
475
476
477
478
		if(!isTemplate) {
			for(auto g : _sensorGroups) {
				if(isEntityOfGroup(sEntity, *g)) {
					finalizeGroup(*g);
				}
Micha Mueller's avatar
Micha Mueller committed
479
480
			}
		}
481
		return true;
482
483
	}

Micha Mueller's avatar
Micha Mueller committed
484
	bool readGlobal(CFG_VAL config) {
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
		boost::optional<boost::property_tree::iptree&> globalVals = config.get_child_optional("global");
		if (globalVals) {
			BOOST_FOREACH(boost::property_tree::iptree::value_type &global, config.get_child("global")) {
				if (boost::iequals(global.first, "mqttprefix")) {
					_mqttPrefix = global.second.data();
					if (_mqttPrefix[_mqttPrefix.length()-1] != '/') {
						_mqttPrefix.append("/");
					}
					LOG(debug) << "  Using own MQTT-Prefix " << _mqttPrefix;
				} else if (boost::iequals(global.first, "cacheInterval")) {
					_cacheInterval = stoul(global.second.data());
					LOG(debug) << "  Using own caching interval " << _cacheInterval << " [s]";
					_cacheInterval *= 1000;
				}
			}
500
			global(config.get_child("global"));
501
		}
502
		return true;
503
504
	}

505
	/**
506
	 * Virtual interface method, responsible for setting global values specifically
507
508
509
510
	 * for its plugin.
	 *
	 * @param pluginSettings	The struct with global default plugin settings
	 */
511
512
513
	virtual void derivedSetGlobalSettings(const pluginSettings_t& pluginSettings) {
		//Overwrite if necessary
	}
514
515
516

	/**
	 * Pure virtual interface method, responsible for reading plugin-specific sensor
517
	 * base values.
518
	 *
Micha Mueller's avatar
Micha Mueller committed
519
	 * @param s			The sensor base for which to set the values
520
521
	 * @param config	A boost property (sub-)tree containing the sensor values
	 */
Micha Mueller's avatar
Micha Mueller committed
522
	virtual void sensorBase(SBase& s, CFG_VAL config) = 0;
523
524
525
526
527

	/**
	 * Pure virtual interface method, responsible for reading plugin-specific sensor
	 * group values.
	 *
Micha Mueller's avatar
Micha Mueller committed
528
	 * @param s			The sensor group for which to set the values
529
	 * @param config	A boost property (sub-)tree containing the group values
530
	 */
Micha Mueller's avatar
Micha Mueller committed
531
	virtual void sensorGroup(SGroup& s, CFG_VAL config) = 0;
532

533
534
535
536
	/**
	 * Virtual interface method, responsible for reading plugin-specific sensor
	 * entity values.
	 *
Micha Mueller's avatar
Micha Mueller committed
537
	 * @param s			The sensor entity for which to set the values
538
539
	 * @param config	A boost property (sub-)tree containing the entity values
	 */
Micha Mueller's avatar
Micha Mueller committed
540
	virtual void sensorEntity(SEntity& s, CFG_VAL config) {
541
542
543
		//Overwrite if necessary
		LOG(warning) << "Method sensorEntity called, but was not overwritten! Either you have unwanted entitys in your config file or forgot to overwrite this method";
	}
544

Micha Mueller's avatar
Micha Mueller committed
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
	/**
	 * Check if e is the corresponding entity of g
	 *
	 * @param e
	 * @param g
	 *
	 * @return	True if (g.entity == &e)
	 */
	//TODO not very convenient for writing plugins. Are there better solutions?
	virtual bool isEntityOfGroup(SEntity& e, SGroup& g) {
		//Overwrite if necessary
		LOG(warning) << "Method isEntityOfGroup called, but was not overwritten! Either you have unwanted entitys in your config file or forgot to overwrite this method";
		return false;
	}

	/**
	 * Sets e as entity for group g
	 *
	 * @param e
	 * @param g
	 */
	//TODO not very convenient for writing plugins. Are there better solutions?
	virtual void setEntityForGroup(SEntity& e, SGroup& g) {
		//Overwrite if necessary
		LOG(warning) << "Method setEntityForGroup called, but was not overwritten! Either you have unwanted entitys in your config file or forgot to overwrite this method";
	}

	/**
	 * Finalize the group g with everything it needs from its entity (set e.g. the mqttPart for entity)
	 *
	 * @param g
	 */
	//TODO not very convenient for writing plugins. Are there better solutions?
	virtual void finalizeGroup(SGroup& g) {
		//Overwrite if necessary
		LOG(warning) << "Method finalizeEntityGroup called, but was not overwritten! Either you have unwanted entitys in your config file or forgot to overwrite this method";
	}

583
584
585
586
587
	/**
	 * Virtual interface method, responsible for reading plugin-specific global values.
	 *
	 * @param config	A boost property (sub-)tree containing the global values
	 */
Micha Mueller's avatar
Micha Mueller committed
588
	virtual void global(CFG_VAL config) {}
589

590
591
	std::string		_entityName;
	std::string		_groupName;
592
	std::string		_baseName;
593
594
595
596

	std::string 	_cfgPath;
	std::string		_mqttPrefix;
	unsigned int	_cacheInterval;
597
598
599
	std::vector<SensorGroupInterface*> _sensorGroupInterfaces;
	std::vector<SGroup*>	_sensorGroups;
	std::vector<SEntity*>	_sensorEntitys;
600
601
	sGroupMap_t		_templateSensorGroups;
	sEntityMap_t	_templateSensorEntitys;
602
603
};

604
#endif /* SRC_CONFIGURATORTEMPLATE_H_ */