Commit 6f1ac25b authored by Micha Mueller's avatar Micha Mueller
Browse files

Merge branch 'refactor'

parents 183655ee fab46443
......@@ -9,8 +9,8 @@ global {
cacheInterval 90
}
templates {
property def0 {
sensorTemplates {
sensor def0 {
factor 100
id 85
interval 1000
......
......@@ -5,7 +5,7 @@ global {
mqttprefix /AABBAABBAABBAACCDDCCDDCC
}
templateSensors {
sensorTemplates {
sensor energy {
; type raw
factor 0.001
......
......@@ -2,7 +2,7 @@ global {
mqttprefix /00112233445566778899AABBCCDD
}
SensorTemplate {
sensorTemplates {
sensor def1 {
interval 1000
minValues 3
......
CounterTemplate {
counter def1 {
sensorTemplates {
sensor def1 {
interval 5000
mqttsuffix 0222
minValues 5
......@@ -7,26 +7,26 @@ CounterTemplate {
config PERF_COUNT_HW_INSTRUCTIONS
}
counter def2 {
sensor def2 {
interval 2000
type PERF_TYPE_HARDWARE
cpus 1,2
}
}
counters {
counter hw_instructions {
sensors {
sensor hw_instructions {
default def1
mqttsuffix 0020
}
counter hw_branch_instructions {
sensor hw_branch_instructions {
default def2
mqttsuffix 0024
config PERF_COUNT_HW_BRANCH_INSTRUCTIONS
}
counter hw_branch_misses {
sensor hw_branch_misses {
default def2
mqttsuffix 002C
config PERF_COUNT_HW_BRANCH_MISSES
......@@ -41,13 +41,13 @@ groups {
minValues 3
cpus 2-3
counter references {
sensor references {
mqttsuffix 10
type PERF_TYPE_HARDWARE
config PERF_COUNT_HW_CACHE_REFERENCES
}
counter misses {
sensor misses {
mqttsuffix 20
type PERF_TYPE_HARDWARE
config PERF_COUNT_HW_CACHE_MISSES
......@@ -60,19 +60,19 @@ groups {
minValues 3
cpus 1-4
counter sw_pagefaults {
sensor sw_pagefaults {
mqttsuffix 30
type PERF_TYPE_SOFTWARE
config PERF_COUNT_SW_PAGE_FAULTS
}
counter sw_context_switches {
sensor sw_context_switches {
mqttsuffix 34
type PERF_TYPE_SOFTWARE
config PERF_COUNT_SW_CONTEXT_SWITCHES
}
counter sw_cpu_migrations {
sensor sw_cpu_migrations {
mqttsuffix 38
type PERF_TYPE_SOFTWARE
config PERF_COUNT_SW_CPU_MIGRATIONS
......
......@@ -2,7 +2,7 @@ global {
mqttprefix /00112233445566778899AABBCC
}
templates {
sensorTemplates {
sensor temp1 {
interval 1000
minValues 3
......
......@@ -2,7 +2,7 @@ global {
mqttPrefix /FF112233445566778899AABBFFFF
}
SensorTemplate {
sensorTemplates {
sensor def1 {
path /home/micha/LRZ/dcdbOwnFork/sysfspusher/temp
interval 1000
......
/*
* Configurator.h
*
* Created on: 13.01.2018
* Author: Micha Mueller
*/
#ifndef SRC_CONFIGURATOR_H_
#define SRC_CONFIGURATOR_H_
#include "Sensor.h"
#include "SensorGroup.h"
#include <vector>
#include <string>
typedef struct {
std::string mqttPrefix;
std::string tempdir;
unsigned int cacheInterval;
} pluginSettings_t;
/**
* Base class, which defines the interface for the configurators in the shared dynamic libraries.
* This base class shall not be constructed on itw own.
*/
class Configurator {
public:
Configurator() : _cacheInterval(900000) {}
virtual ~Configurator() {
for (auto s : _sensors) {
delete s;
}
}
/**
* Read in the given configuration
* @param cfgPath Path to the config-file
* @return true on success, false otherwise
*/
virtual bool readConfig(std::string cfgPath) {
_cfgPath = cfgPath;
return true;
}
/**
* Clear internal storage and read in the configuration again.
*/
virtual bool reReadConfig() {
for (auto s : _sensors) {
s->stopPolling();
}
for(auto g : _sensorGroups) {
g->stopPolling();
}
for (auto s : _sensors) {
s->wait();
}
for(auto g : _sensorGroups) {
g->wait();
}
for (auto s : _sensors) {
delete s;
}
for(auto g : _sensorGroups) {
delete g;
}
_sensors.clear();
_sensorGroups.clear();
return true;
}
virtual void setGlobalSettings(const pluginSettings_t& pluginSettings) {
_mqttPrefix = pluginSettings.mqttPrefix;
_cacheInterval = pluginSettings.cacheInterval;
}
std::vector<Sensor*>& getSensors() {
return _sensors;
}
std::vector<SensorGroup*>& getSensorGroups() {
return _sensorGroups;
}
protected:
std::string _cfgPath;
std::string _mqttPrefix;
unsigned int _cacheInterval;
std::vector<Sensor*> _sensors;
std::vector<SensorGroup*> _sensorGroups;
boost::log::sources::severity_logger<boost::log::trivial::severity_level> lg;
};
//typedef for more readable usage of create()- and destroy()-methods, required for dynamic libraries
typedef Configurator* create_t();
typedef void destroy_t(Configurator*);
#endif /* SRC_CONFIGURATOR_H_ */
/*
* ConfiguratorInterface.h
*
* Created on: 06.08.2018
* Author: Micha Mueller
*/
#ifndef SRC_CONFIGURATORINTERFACE_H_
#define SRC_CONFIGURATORINTERFACE_H_
#include "Sensor.h"
#include "SensorGroup.h"
#include <string>
#include <vector>
typedef struct {
std::string mqttPrefix;
std::string tempdir;
unsigned int cacheInterval;
} pluginSettings_t;
/**
* Abstract interface which defines the functionality of a configurator
*/
class ConfiguratorInterface {
public:
virtual ~ConfiguratorInterface() {}
virtual bool readConfig(std::string cfgPath) = 0;
virtual bool reReadConfig() = 0;
virtual void setGlobalSettings(const pluginSettings_t& pluginSettings) = 0;
virtual std::vector<Sensor*>& getSensors() = 0;
virtual std::vector<SensorGroup*>& getSensorGroups() = 0;
};
//typedef for more readable usage of create()- and destroy()-methods, required for dynamic libraries
typedef ConfiguratorInterface* create_t();
typedef void destroy_t(ConfiguratorInterface*);
#endif /* SRC_CONFIGURATORINTERFACE_H_ */
/*
* Configurator.h
*
* Created on: 13.01.2018
* Author: Micha Mueller
*/
#ifndef SRC_CONFIGURATORTEMPLATE_H_
#define SRC_CONFIGURATORTEMPLATE_H_
#include "ConfiguratorInterface.h"
#include <map>
#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/info_parser.hpp>
/**
* Non-virtual interface template for the configurators.
*/
template <typename S>
class ConfiguratorTemplate : public ConfiguratorInterface {
//the template shall only be instantiated for classes which implement the sensor interface
static_assert(std::is_base_of<Sensor, S>::value, "S must derive from Sensor!");
protected:
typedef std::map<std::string, S> sensorMap_t;
public:
ConfiguratorTemplate() : _cacheInterval(900000) {}
virtual ~ConfiguratorTemplate() {
for (auto s : _sensors) {
delete s;
}
}
/**
* Read in the given configuration
*
* @param cfgPath Path to the config-file
*
* @return True on success, false otherwise
*/
bool readConfig(std::string cfgPath) final {
_cfgPath = cfgPath;
boost::property_tree::iptree cfg;
boost::property_tree::read_info(cfgPath, cfg);
//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("/");
}
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;
} else {
LOG(error) << " Value \"" << global.first << "\" not recognized. Omitting for the moment";
}
}
}
//read template sensors
boost::optional<boost::property_tree::iptree&> tempSens = cfg.get_child_optional("sensorTemplates");
if (tempSens) {
BOOST_FOREACH(boost::property_tree::iptree::value_type &sensorVal, cfg.get_child("sensorTemplates")) {
if (boost::iequals(sensorVal.first, "sensor")) {
LOG(debug) << "Template Sensor \"" << sensorVal.second.data() << "\"";
if (!sensorVal.second.empty()) {
S sensor(sensorVal.second.data());
if(readSensor(sensor, sensorVal.second)) {
_templateSensors.insert(std::pair<std::string, S>(sensor.getName(), sensor));
} else {
LOG(warning) << "Template sensor \"" << sensorVal.second.data() << "\" has bad values! Ignoring...";
}
}
}
}
}
//read in plugin specific stuff (including actual sensors)
return derivedReadConfig(cfg);
}
/**
* Clear internal storage and read in the configuration again.
*
* @return True on success, false otherwise
*/
bool reReadConfig() final {
//bring everything to a halt
for (auto s : _sensors) {
s->stopPolling();
}
for(auto g : _sensorGroups) {
g->stopPolling();
}
//wait until everything is halted
for (auto s : _sensors) {
s->wait();
}
for(auto g : _sensorGroups) {
g->wait();
}
//clean up plugin specific stuff
derivedReReadConfig();
//clean up sensors and groups
for (auto s : _sensors) {
delete s;
}
for(auto g : _sensorGroups) {
delete g;
}
_sensors.clear();
_sensorGroups.clear();
_templateSensors.clear();
//back to the very beginning
return readConfig(_cfgPath);
}
/**
* 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.
*/
void setGlobalSettings(const pluginSettings_t& pluginSettings) final {
_mqttPrefix = pluginSettings.mqttPrefix;
_cacheInterval = pluginSettings.cacheInterval;
derivedSetGlobalSettings(pluginSettings);
}
/**
* Get all sensors
*
* @return Vector containing pointers to all sensors of this plugin
*/
std::vector<Sensor*>& getSensors() final {
return _sensors;
}
/**
* Get all sensor groups
*
* @return Vector containing pointers to all sensor groups of this plugin
*/
std::vector<SensorGroup*>& getSensorGroups() {
return _sensorGroups;
}
protected:
/**
* Non-virtual interface method for class-internal use only.
* Reads and sets the common base values of a sensor, then calls
* the corresponding derived function.
*
* @param sensor The sensor for which to set the values
* @param config A boost property (sub-)tree containing the sensor values
*
* @return True on success, false otherwise
*/
bool readSensor(S& sensor, boost::property_tree::iptree& config) {
//read in base values
BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config) {
if (boost::iequals(val.first, "interval")) {
sensor.setInterval(stoull(val.second.data()));
} else if (boost::iequals(val.first, "minValues")) {
sensor.setMinValues(stoull(val.second.data()));
} else {
//do nothing. Derived function should read in other values
}
}
sensor.setCacheInterval(_cacheInterval);
LOG(debug) << " Interval : " << sensor.getInterval();
LOG(debug) << " minValues: " << sensor.getMinValues();
return derivedReadSensor(sensor, config);
}
/**
* Pure virtual interface method, responsible for reading the plugin-specific
* configuration part.
*
* @param cfg The (root) boost property tree from the plugins configuration file
*
* @return True on success, false otherwise
*/
virtual bool derivedReadConfig(boost::property_tree::iptree& cfg) = 0;
/**
* Pure virtual interface method, responsible for the plugin specific part if
* re-reading the config.
*/
virtual void derivedReReadConfig() = 0;
/**
* Pure virtual interface method, responsible for setting global values specifically
* for its plugin.
*
* @param pluginSettings The struct with global default plugin settings
*/
virtual void derivedSetGlobalSettings(const pluginSettings_t& pluginSettings) = 0;
/**
* Pure virtual interface method, responsible for reading plugin-specific sensor
* values.
*
* @param sensor The sensor for which to set the values
* @param config A boost property (sub-)tree containing the sensor values
*
* @return True on success, false otherwise
*/
virtual bool derivedReadSensor(S& sensor, boost::property_tree::iptree& config) = 0;
std::string _cfgPath;
std::string _mqttPrefix;
unsigned int _cacheInterval;
std::vector<Sensor*> _sensors;
std::vector<SensorGroup*> _sensorGroups;
sensorMap_t _templateSensors;
boost::log::sources::severity_logger<boost::log::trivial::severity_level> lg;
};
#endif /* SRC_CONFIGURATORTEMPLATE_H_ */
......@@ -17,13 +17,13 @@
#include <string>
#include <vector>
#include "Configurator.h"
#include "ConfiguratorInterface.h"
//struct of values required for a dynamic library.
typedef struct {
std::string id;
void* DL;
Configurator* configurator;
ConfiguratorInterface* configurator;
create_t* create;
destroy_t* destroy;
} dl_t;
......
......@@ -7,10 +7,7 @@
#include "BACnetConfigurator.h"
#include <boost/property_tree/info_parser.hpp>
#include <boost/foreach.hpp>
#include <boost/optional.hpp>
#include <boost/algorithm/string.hpp>
#include <iostream>
BACnetConfigurator::BACnetConfigurator() {
......@@ -23,11 +20,7 @@ BACnetConfigurator::~BACnetConfigurator() {
}
}
bool BACnetConfigurator::readConfig(std::string cfgPath) {
Configurator::readConfig(cfgPath);
boost::property_tree::iptree cfg;
boost::property_tree::read_info(cfgPath, cfg);
bool BACnetConfigurator::derivedReadConfig(boost::property_tree::iptree& cfg) {
_bacClient = new BACnetClient();
std::string interface, address_cache, mqttPartDevice, mqttPartObject;
unsigned port = 47808, timeout = 1000, apdu_timeout = 200, apdu_retries = 0;
......@@ -55,15 +48,9 @@ bool BACnetConfigurator::readConfig(std::string cfgPath) {
apdu_retries = stoul(global.second.data());
LOG(debug) << " apdu_retries " << apdu_retries;
} else if (boost::iequals(global.first, "mqttprefix")) {
_mqttPrefix = global.second.data();
if (_mqttPrefix[_mqttPrefix.length()-1] != '/') {
_mqttPrefix.append("/");
}
LOG(debug) << " Using own MQTT-Prefix " << _mqttPrefix;
//avoid unnecessary "Value not recognized" messages
} else if (boost::iequals(global.first, "cacheInterval")) {
_cacheInterval = stoul(global.second.data());
LOG(debug) << " Using own caching interval " << _cacheInterval << " [s]";
_cacheInterval *= 1000;
//avoid unnecessary "Value not recognized" messages
} else {
LOG(error) << " Value \"" << global.first << "\" not recognized. Omitting...";
}
......@@ -76,21 +63,6 @@ bool BACnetConfigurator::readConfig(std::string cfgPath) {
return false;
}
//read template sensors
BOOST_FOREACH(boost::property_tree::iptree::value_type &sensor, cfg.get_child("templates")) {
if (boost::iequals(sensor.first, "property")) {
LOG(debug) << "Template Sensor \"" << sensor.second.data() << "\"";
if (!sensor.second.empty()) {
BACnetSensor bacnetSensor(sensor.second.data());
if(readSensor(bacnetSensor, sensor.second)) {
_templateSensors.insert(sensorMap_t::value_type(bacnetSensor.getName(), bacnetSensor));
} else {
LOG(warning) << "Template sensor \"" << sensor.second.data() << "\" has bad values! Ignoring...";
}
}
}
}
BOOST_FOREACH(boost::property_tree::iptree::value_type &device, cfg.get_child("devices")) {
if (boost::iequals(device.first, ("device"))) {
LOG(debug) << "Device " << device.second.data();
......@@ -140,8 +112,8 @@ bool BACnetConfigurator::readConfig(std::string cfgPath) {
bacSensor->setDeviceInstance(deviceInstance);
bacSensor->setObjectInstance(objInstance);
bacSensor->setObjectType(objType);
bacSensor->setMqtt(_mqttPrefix + mqttPartDevice + mqttPartObject);
bacSensor->setBACnetClient(_bacClient);
bacSensor->setMqtt(_mqttPrefix + mqttPartDevice + mqttPartObject);
//read remaining values
if(readSensor(*bacSensor, object.second)) {
_sensors.push_back(bacSensor);
......@@ -160,31 +132,29 @@ bool BACnetConfigurator::readConfig(std::string cfgPath) {
return true;
}
bool BACnetConfigurator::readSensor(BACnetSensor& sensor, boost::property_tree::iptree& config) {
void BACnetConfigurator::derivedReReadConfig() {
delete _bacClient;
_bacClient = NULL;
}
bool BACnetConfigurator::derivedReadSensor(BACnetSensor& sensor, boost::property_tree::iptree& config) {
BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config) {
if (boost::iequals(val.first, "interval")) {
sensor.setInterval(stoull(val.second.data()));
//avoid unnecessary "Value not recognized" messages
} else if (boost::iequals(val.first, "minValues")) {
} else if (boost::iequals(val.first, "default")) {
} else if (boost::iequals(val.first, "mqttsuffix")) {