SysfsConfigurator.cpp 4.8 KB
Newer Older
1
/*
2
 * SysfsConfigurator.cpp
3
4
5
6
7
 *
 *  Created on: 18.11.2017
 *      Author: Micha Mueller
 */

8
#include "SysfsConfigurator.h"
9

10
11
12
13
14
15
16
17
#include <iostream>

#include <boost/foreach.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;

18
SysfsConfigurator::SysfsConfigurator() {}
19

20
SysfsConfigurator::~SysfsConfigurator() {}
21

22
bool SysfsConfigurator::readConfig(std::string cfgPath) {
23
24
	Configurator::readConfig(cfgPath);

25
26
	boost::property_tree::iptree cfg;
	boost::property_tree::read_info(cfgPath, cfg);
27

28
29
30
31
32
33
34
35
36
	//read global variables (if present overwrite those from global.conf)
	boost::optional<boost::property_tree::iptree&> globalVals = cfg.get_child_optional("global");
	if (globalVals) {
		BOOST_FOREACH(boost::property_tree::iptree::value_type &global, cfg.get_child("global")) {
			if(boost::iequals(global.first, "mqttprefix")) {
				_mqttPrefix = global.second.data();
				if (_mqttPrefix[_mqttPrefix.length()-1] != '/') {
					_mqttPrefix.append("/");
				}
37
				LOG(debug) << "  Using own MQTT-Prefix " << _mqttPrefix;
38
39
40
41
			} else if (boost::iequals(global.first, "cacheInterval")) {
				_cacheInterval = stoul(global.second.data());
				LOG(debug) << "  Using own caching interval " << _cacheInterval << " [s]";
				_cacheInterval *= 1000;
42
			} else {
43
				LOG(warning) << "  Value \"" << global.first << "\" not recognized. Omitting...";
44
45
46
47
			}
		}
	}

48
49
50
	//read template sensors
	BOOST_FOREACH(boost::property_tree::iptree::value_type &sensor, cfg.get_child("SensorTemplate")) {
		if (boost::iequals(sensor.first, "sensor")) {
51
			LOG(debug) << "Template Sensor \"" << sensor.second.data() << "\"";
52
			if (!sensor.second.empty()) {
53
				SysfsSensor sysfsSensor(sensor.second.data());
54
55
56
57
58
59
60
61
62
				readSensor(sysfsSensor, sensor.second);
				_templateSensors.insert(sensorMap_t::value_type(sysfsSensor.getName(), sysfsSensor));
			}
		}
	}

	//read one sensor at a time
	BOOST_FOREACH(boost::property_tree::iptree::value_type &sensor, cfg.get_child("sensors")) {
		if (boost::iequals(sensor.first, "sensor")) {
63
			LOG(debug) << "Sensor \"" << sensor.second.data() << "\"";
64
			if (!sensor.second.empty()) {
65
				SysfsSensor* sysfsSensor = new SysfsSensor(sensor.second.data());
66
67
68
69

				//first check if default sensor is given
				boost::optional<boost::property_tree::iptree&> defaultS = sensor.second.get_child_optional("default");
				if(defaultS) {
70
					LOG(debug) << "  Using \"" << defaultS.get().data() << "\" as default.";
71
72
					sensorMap_t::iterator it = _templateSensors.find(defaultS.get().data());
					if(it != _templateSensors.end()) {
73
74
						*sysfsSensor = it->second;
						sysfsSensor->setName(sensor.second.data());
75
					} else {
76
						LOG(warning) << "Template sensor \"" << defaultS.get().data() << "\" not found! Using standard values.";
77
78
79
					}
				}
				//read remaining values
80
				readSensor(*sysfsSensor, sensor.second);
81
82
83
84
				_sensors.push_back(sysfsSensor);
			}
		}
	}
85
	return true;
86
87
}

88
void SysfsConfigurator::readSensor(SysfsSensor& sensor, boost::property_tree::iptree& config) {
89
90
91
92
	BOOST_FOREACH(boost::property_tree::iptree::value_type &s, config) {
		if (boost::iequals(s.first, ("path"))) {
			sensor.setPath(s.second.data());
		} else if (boost::iequals(s.first, "interval")) {
93
			sensor.setInterval(stoull(s.second.data()));
94
		} else if (boost::iequals(s.first, "mqttsuffix")) {
95
			sensor.setMqtt(_mqttPrefix + s.second.data());
96
97
98
99
100
101
102
103
104
105
106
107
		} else if (boost::iequals(s.first, "minValues")) {
			sensor.setMinValues(stoull(s.second.data()));
		} else if (boost::iequals(s.first, "filter")) {
			sensor.setFilter(true);
			string input = s.second.data();

			//check if input has sed format of "s/.../.../" for substitution
			regex checkSubstitute("s([^\\\\]{1})([\\S|\\s]*)\\1([\\S|\\s]*)\\1");
			smatch matchResults;

			if(regex_match(input, matchResults, checkSubstitute)) {
				//input has substitute format
108
109
				LOG(debug) << "  Init Regex with: " << matchResults[2].str();
				LOG(debug) << "  Substitution:	" << matchResults[3].str();
110
111
112
113
				sensor.setRegex(regex(matchResults[2].str(), regex_constants::extended));
				sensor.setSubstitution(matchResults[3].str());
			} else {
				//input is only a regex
114
				LOG(debug) << "  Init Regex with " << input;
115
116
117
118
119
120
				sensor.setRegex(regex(input, regex_constants::extended));
				sensor.setSubstitution("&");
			}
		} else if (boost::iequals(s.first, "default")) {
			//avoid unnecessary "Value not recognized" message
		} else {
121
			LOG(warning) << "  Value \"" << s.first << "\" not recognized. Omitting...";
122
123
		}
	}
124
125
126

	sensor.setCacheInterval(_cacheInterval);

127
128
129
130
	LOG(debug) << "  Path    : " << sensor.getPath();
	LOG(debug) << "  MQTT    : " << sensor.getMqtt();
	LOG(debug) << "  Interval: " << sensor.getInterval();
	LOG(debug) << "  minValues:" << sensor.getMinValues();
131
132
	if (sensor.hasFilter()) {
		//regex cannot be converted back to string
133
		LOG(debug) << "  Using regular expression to filter data";
134
135
136
137
	}
	return;
}