PDUConfigurator.cpp 5.62 KB
Newer Older
1
2
3
4
5
6
7
8
9
/*
 * PDUConfigurator.cpp
 *
 *  Created on: 24.02.2018
 *      Author: Micha Mueller
 */

#include "PDUConfigurator.h"

10
#include <iostream>
11
#include <sstream>
12
13
14

using namespace std;

15
PDUConfigurator::PDUConfigurator() {}
16

17
PDUConfigurator::~PDUConfigurator() {}
18

19
bool PDUConfigurator::derivedReadConfig(boost::property_tree::iptree& cfg) {
20
21
	//read one pdu at a time
	BOOST_FOREACH(boost::property_tree::iptree::value_type &pdu, cfg.get_child("pdus")) {
22
		if (STRCMP(pdu, "pdu")) {
23
			LOG(debug) << "PDU \"" << pdu.second.data() << "\"";
24
25
26
27
28
29
30
			if (!pdu.second.empty()) {
				//create PDU at end of list
				_pdus.push_back(PDUUnit());
				PDUUnit& pduUnit = _pdus.back();

				//read PDU-values
				BOOST_FOREACH(boost::property_tree::iptree::value_type &val, pdu.second) {
31
					if (STRCMP(val, "TTL")) {
32
						pduUnit.setTTL(stoull(val.second.data()));
33
						LOG(debug) << "  TTL	" << pduUnit.getTTL();
34
					} else if (STRCMP(val, "host")) {
35
36
37
38
39
40
41
						std::string host = val.second.data();
						size_t pos = host.find(':');
						if (pos != string::npos) {
							pduUnit.setHost(host);
						} else {
							pduUnit.setHost(host + ":443");
						}
42
						LOG(debug) << "  Host	" << pduUnit.getHost();
43
					} else if (STRCMP(val, "request")) {
44
45
						pduUnit.setRequest(val.second.data());
						LOG(debug) << "  Request:	\n" << pduUnit.getRequest();
46
					} else if (STRCMP(val, "sensors")) {
47
						BOOST_FOREACH(boost::property_tree::iptree::value_type &sensor, val.second) {
48
							LOG(debug) << "Sensor \"" << sensor.second.data() << "\"";
49
							if (!sensor.second.empty()) {
50
								std::string name = pdu.second.data() + "_" + sensor.second.data();
51
								PDUSingleSensor* pduSensor = new PDUSingleSensor(name);
52
53
54
55

								//first check if default sensor is given
								boost::optional<boost::property_tree::iptree&> defaultC = sensor.second.get_child_optional("default");
								if(defaultC) {
56
									LOG(debug) << "  Using \"" << defaultC.get().data() << "\" as default.";
57
58
									sensorMap_t::iterator it = _templateSensors.find(defaultC.get().data());
									if(it != _templateSensors.end()) {
59
										*pduSensor = it->second;
60
										pduSensor->setName(name);
61
									} else {
62
										LOG(warning) << "  Template sensor \"" << defaultC.get().data() << "\" not found! Using standard values.";
63
64
65
66
									}
								}

								//read remaining values
67
								if(readSensorBase(*pduSensor, sensor.second)) {
68
									//set pointer to corresponding pdu
69
70
									pduSensor->setPdu(&pduUnit);
									_sensors.push_back(pduSensor);
71
								} else {
Micha Mueller's avatar
Micha Mueller committed
72
									LOG(warning) << "  Sensor \"" << sensor.second.data() << "\" has bad values! Ignoring...";
73
74
75
76
77
78
79
80
								}
							}
						}
					}
				}
			}
		}
	}
81
	return true;
82
83
}

84
bool PDUConfigurator::derivedReadSensorBase(PDUSensorBase& sensor, boost::property_tree::iptree& config) {
85
	BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config) {
86
		if (STRCMP(val, "mqttsuffix")) {
87
			sensor.setMqtt(_mqttPrefix + val.second.data());
88
		} else if (STRCMP(val, "path")) {
89
			parsePathString(sensor, val.second.data());
90
91
92
		}
	}

93
	LOG(debug) << "  MQTT     : " << sensor.getMqtt();
94
	return true;
95
96
}

97
void PDUConfigurator::parsePathString(PDUSensorBase& sensor, const std::string& pathString) {
98
	LOG(debug) << "  Using " << pathString << " as XML search path";
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
136
137
138
139

	std::vector<std::string> subStrings;

	std::stringstream pathStream(pathString);
	std::string item;
	//split into parts if a attribute (indicated by '(' ')') was defined
	while (std::getline(pathStream, item, ')')) {
		subStrings.push_back(item);
	}

	for (auto subStr : subStrings) {
		//extract the attributes from the path-parts
		if (subStr.find('(') != std::string::npos) { //attribute specified
			std::stringstream pathWithAttributesSStream(subStr);

			//split into path and attributes string
			std::string subPath, attributeString;
			std::getline(pathWithAttributesSStream, subPath, '(');
			std::getline(pathWithAttributesSStream, attributeString);

			if (subPath.front() == '.') {
				subPath.erase(0, 1);
			}

			//now further split the attributes string as multiple attributes could be defined
			std::vector<std::string> attributes;
			std::stringstream attributeStream(attributeString);
			while (std::getline(attributeStream, item, ',')) {
				attributes.push_back(item);
			}
			attributesVector_t attrs;
			for (auto att : attributes) {
				//part attributes into name and value
				if (att.find('=') != std::string::npos) {
					std::stringstream attStream(att);

					std::string attName, attVal;
					std::getline(attStream, attName, '=');
					std::getline(attStream, attVal);

					attrs.push_back(std::make_pair(attName, attVal));
140
					LOG(debug) << "  Attribute: " << attName << "=" << attVal;
141
				} else { //should not happen. If it does the path was malformed
142
					LOG(error) << "  Could not parse XML-path!";
143
144
145
146
147
148
149
150
					return;
				}
			}
			//split of the last child in the path. Required to iterate over multiple nodes which only differ in the attributes with BOOST_FOREACH
			auto index = subPath.find_last_of('.');
			if (index != std::string::npos) {
				std::string subPathChild(subPath.substr(++index));
				subPath.erase(--index);
151
				sensor.pushBackXMLPathPart(std::make_tuple(subPath, subPathChild, attrs));
152
				LOG(debug) << "  Subpath: " << subPath << " ; Child: " << subPathChild;
153
			} else {//the path contained only one node
154
				sensor.pushBackXMLPathPart(std::make_tuple("", subPath, attrs));
155
				LOG(debug) << "  Child: " << subPath;
156
157
158
159
160
			}
		} else { //no attributes specified. Last (sub)path
			if (subStr.front() == '.') {
				subStr.erase(0, 1);
			}
161
			sensor.pushBackXMLPathPart(std::make_tuple(subStr, "", attributesVector_t()));
162
			LOG(debug) << "  (Sub)path: " << subStr;
163
164
165
166
167
			break;
		}
	}
}