Commit d48f1354 authored by Micha Mueller's avatar Micha Mueller
Browse files

WIP: Adapt sysfs plugin to new architecture

parent 2e69d5ea
......@@ -47,14 +47,14 @@ bool SysfsConfigurator::derivedReadConfig(boost::property_tree::iptree& cfg) {
return true;
}
bool SysfsConfigurator::derivedReadSensorBase(SysfsSensorBase& sensor, boost::property_tree::iptree& config) {
bool SysfsConfigurator::derivedReadSensorBase(SysfsSensorBase& sBase, boost::property_tree::iptree& config) {
BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config) {
if (STRCMP(val, "mqttsuffix")) {
sensor.setMqtt(_mqttPrefix + val.second.data());
sBase.setMqtt(_mqttPrefix + val.second.data());
} else if (STRCMP(val, ("path"))) {
sensor.setPath(val.second.data());
sBase.setPath(val.second.data());
} else if (STRCMP(val, "filter")) {
sensor.setFilter(true);
sBase.setFilter(true);
string input = val.second.data();
//check if input has sed format of "s/.../.../" for substitution
......@@ -65,20 +65,20 @@ bool SysfsConfigurator::derivedReadSensorBase(SysfsSensorBase& sensor, boost::pr
//input has substitute format
LOG(debug) << " Init Regex with: " << matchResults[2].str();
LOG(debug) << " Substitution: " << matchResults[3].str();
sensor.setRegex(regex(matchResults[2].str(), regex_constants::extended));
sensor.setSubstitution(matchResults[3].str());
sBase.setRegex(regex(matchResults[2].str(), regex_constants::extended));
sBase.setSubstitution(matchResults[3].str());
} else {
//input is only a regex
LOG(debug) << " Init Regex with " << input;
sensor.setRegex(regex(input, regex_constants::extended));
sensor.setSubstitution("&");
sBase.setRegex(regex(input, regex_constants::extended));
sBase.setSubstitution("&");
}
}
}
LOG(debug) << " MQTT : " << sensor.getMqtt();
LOG(debug) << " Path : " << sensor.getPath();
if (sensor.hasFilter()) {
LOG(debug) << " MQTT : " << sBase.getMqtt();
LOG(debug) << " Path : " << sBase.getPath();
if (sBase.hasFilter()) {
//regex cannot be converted back to string
LOG(debug) << " Using regular expression to filter data";
}
......
......@@ -10,9 +10,9 @@
#include "../../headers/ConfiguratorTemplate.h"
#include "SysfsSingleSensor.h"
#include "SysfsSensorGroup.h"
class SysfsConfigurator : public ConfiguratorTemplate<SysfsSensorBase, SysfsSingleSensor> {
class SysfsConfigurator : public ConfiguratorTemplate<SysfsSensorBase, SysfsSensorGroup> {
public:
SysfsConfigurator();
......@@ -23,7 +23,8 @@ protected:
bool derivedReadConfig(boost::property_tree::iptree& cfg) override;
void derivedReReadConfig() override { /* nothing to overwrite */ }
void derivedSetGlobalSettings(const pluginSettings_t& pluginSettings) override { /* nothing to overwrite */ }
bool derivedReadSensorBase(SysfsSensorBase& sensor, boost::property_tree::iptree& config) override;
bool derivedReadSensorBase(SysfsSensorBase& sBase, boost::property_tree::iptree& config) override;
bool derivedReadSensorGroup(SysfsSensorGroup& sGroup, boost::property_tree::iptree& config) override;
};
extern "C" ConfiguratorInterface* create() {
......
/*
* SysfsSensorGroup.cpp
*
* Created on: 18.11.2017
* Author: Michael Ott (original), Micha Mueller
*/
#include "timestamp.h"
#include <functional>
#include "SysfsSensorGroup.h"
using namespace std;
SysfsSensorGroup::SysfsSensorGroup(const std::string& name) :
SensorGroupTemplate(name) {}
SysfsSensorGroup::~SysfsSensorGroup() {}
void SysfsSensorGroup::start() {
if (_keepRunning) {
//we have been started already
LOG(info) << "Sensorgroup " << _groupName << " already running.";
return;
}
for(auto s : _sensors) {
if(s->getFile() == NULL) {
s->setFile(fopen(s->getPath().c_str(), "r"));
if (s->getFile() == NULL) {
LOG(error) << "Error starting sensor \"" << s->getName() << "\": " << strerror(errno);
return;
}
}
}
_keepRunning = 1;
_pendingTasks++;
_timer->async_wait(std::bind(&SysfsSensorGroup::readAsync, this));
LOG(info) << "Sensorgroup " << _groupName << " started.";
}
void SysfsSensorGroup::stop() {
_keepRunning = 0;
//wait before closing _file
wait();
for(auto s : _sensors) {
if (s->getFile() != NULL) {
fclose(s->getFile());
s->setFile(NULL);
}
}
LOG(info) << "Sensorgroup " << _groupName << " stopped.";
}
void SysfsSensorGroup::read() {
reading_t reading;
char buf[1024];
reading.timestamp = getTimestamp();
for(auto s : _sensors) {
fseek(s->getFile(), 0, SEEK_SET);
size_t nelem = fread(buf, 1, 1024, s->getFile());
if (nelem) {
buf[nelem-1] = 0;
try {
//filter the payload if necessary
if(s->hasFilter()) {
//substitution must have sed format
//if no substitution is defined the whole regex-match is copied as is.
//parts which do not match are not copied --> filter
reading.value = stoll(regex_replace(buf, s->getRegex(), s->getSubstitution(), regex_constants::format_sed | regex_constants::format_no_copy));
} else {
reading.value = stoll(buf);
}
} catch (const std::exception& e) {
#ifdef DEBUG
LOG(warning) << "SysfsSensor " << _name << " could not read value!";
#endif
return;
}
#ifdef DEBUG
LOG(debug) << _name << ": \"" << reading.value << "\"";
#endif
}
s->storeReading(reading, _cacheIndex);
}
_cacheIndex = (_cacheIndex + 1) % _cacheSize;
}
void SysfsSensorGroup::readAsync() {
uint64_t now = getTimestamp();
read();
if (_timer && _keepRunning) {
uint64_t next = now + MS_TO_NS(_interval);
_timer->expires_at(timestamp2ptime(next));
_pendingTasks++;
_timer->async_wait(std::bind(&SysfsSensorGroup::readAsync, this));
}
_pendingTasks--;
}
/*
* SysfsSingleSensor.h
* SysfsSensorGroup.h
*
* Created on: 18.11.2017
* Author: Michael Ott (original), Micha Mueller
*/
#ifndef SYSFSSINGLESENSOR_H_
#define SYSFSSINGLESENSOR_H_
#ifndef SYSFSSENSORGROUP_H_
#define SYSFSSENSORGROUP_H_
#include "SysfsSensorBase.h"
#include "../../headers/SingleSensor.h"
#include "../../headers/SensorGroupTemplate.h"
class SysfsSingleSensor : public SysfsSensorBase, public SingleSensor {
class SysfsSensorGroup : public SensorGroupTemplate<SysfsSensorBase> {
public:
SysfsSingleSensor(const std::string& name);
virtual ~SysfsSingleSensor();
SysfsSensorGroup(const std::string& name);
virtual ~SysfsSensorGroup();
void start() override;
void stop() override;
......@@ -26,4 +26,4 @@ private:
};
#endif /* SYSFSSINGLESENSOR_H_ */
#endif /* SYSFSSENSORGROUP_H_ */
/*
* SysfsSingleSensor.cpp
*
* Created on: 18.11.2017
* Author: Michael Ott (original), Micha Mueller
*/
#include "SysfsSingleSensor.h"
#include "timestamp.h"
#include <functional>
using namespace std;
SysfsSingleSensor::SysfsSingleSensor(const std::string& name) :
SensorBase(name), SysfsSensorBase(name), SingleSensor(name) {}
SysfsSingleSensor::~SysfsSingleSensor() {}
void SysfsSingleSensor::start() {
if (_keepRunning) {
//we have been started already
LOG(info) << "Sensor " << _name << " already running.";
return;
}
if(_file == NULL) {
_file = fopen(_path.c_str(), "r");
if (_file == NULL) {
LOG(error) << "Error starting sensor \"" << _name << "\": " << strerror(errno);
return;
}
}
_keepRunning = 1;
_pendingTasks++;
_timer->async_wait(std::bind(&SysfsSingleSensor::readAsync, this));
LOG(info) << "Sensor " << _name << " started.";
}
void SysfsSingleSensor::stop() {
_keepRunning = 0;
//wait before closing _file
wait();
if (_file != NULL) {
fclose(_file);
_file = NULL;
}
LOG(info) << "Sensor " << _name << " stopped.";
}
void SysfsSingleSensor::read() {
reading_t reading;
char buf[1024];
reading.timestamp = getTimestamp();
fseek(_file, 0, SEEK_SET);
size_t nelem = fread(buf, 1, 1024, _file);
if (nelem) {
buf[nelem-1] = 0;
try {
//filter the payload if necessary
if(_filter) {
//substitution must have sed format
//if no substitution is defined the whole regex-match is copied as is.
//parts which do not match are not copied --> filter
reading.value = stoll(regex_replace(buf, _regx, _substitution, regex_constants::format_sed | regex_constants::format_no_copy));
} else {
reading.value = stoll(buf);
}
} catch (const std::exception& e) {
#ifdef DEBUG
LOG(warning) << "SysfsSensor " << _name << " could not read value!";
#endif
return;
}
#ifdef DEBUG
LOG(debug) << _name << ": \"" << reading.value << "\"";
#endif
}
storeReading(reading, _cacheIndex);
_cacheIndex = (_cacheIndex + 1) % _cacheSize;
}
void SysfsSingleSensor::readAsync() {
uint64_t now = getTimestamp();
read();
if (_timer && _keepRunning) {
uint64_t next = now + MS_TO_NS(_interval);
_timer->expires_at(timestamp2ptime(next));
_pendingTasks++;
_timer->async_wait(std::bind(&SysfsSingleSensor::readAsync, this));
}
_pendingTasks--;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment