SysfsSensorGroup.cpp 3.14 KB
Newer Older
1
2
3
4
5
6
7
8
/*
 * SysfsSensorGroup.cpp
 *
 *  Created on: 18.11.2017
 *      Author: Michael Ott (original), Micha Mueller
 */

#include <functional>
9
#include <cstring>
10
11
12
13
14
#include "SysfsSensorGroup.h"

using namespace std;

SysfsSensorGroup::SysfsSensorGroup(const std::string& name) :
15
16
17
18
	SensorGroupTemplate(name),
	_path("") {
	_file = NULL;
}
19

20
21
22
23
24
25
SysfsSensorGroup::SysfsSensorGroup(const SysfsSensorGroup& other) :
    SensorGroupTemplate(other),
    _path(other._path) {
  _file = NULL;
}

26
27
SysfsSensorGroup::~SysfsSensorGroup() {}

28
29
30
31
32
33
34
35
SysfsSensorGroup& SysfsSensorGroup::operator=(const SysfsSensorGroup& other) {
  SensorGroupTemplate::operator=(other);
  _path = other._path;
  _file = NULL;

  return *this;
}

36
37
38
39
40
41
42
void SysfsSensorGroup::start() {
	if (_keepRunning) {
		//we have been started already
		LOG(info) << "Sensorgroup " << _groupName << " already running.";
		return;
	}

43
44
45
46
47
	if(_file == NULL) {
		_file = fopen(_path.c_str(), "r");
		if (_file == NULL) {
			LOG(error) << "Error starting group\"" << _groupName << "\": " << strerror(errno);
			return;
48
49
50
51
52
53
54
55
56
57
58
59
60
61
		}
	}

	_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();

62
63
64
	if (_file != NULL) {
		fclose(_file);
		_file = NULL;
65
66
67
68
69
70
71
72
	}
	LOG(info) << "Sensorgroup " << _groupName << " stopped.";
}

void SysfsSensorGroup::read() {
	reading_t reading;
	char buf[1024];

73
74
	fseek(_file, 0, SEEK_SET);
	size_t nelem = fread(buf, 1, 1024, _file);
75
76
	reading.timestamp = getTimestamp();

77
78
	if (nelem) {
		buf[nelem-1] = 0;
79
		for(const auto& s : _sensors) {
80
			reading.value = 0;
81
82
83
84
85
86
			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
87
88
89
90
91
92
93

					//reading.value = stoll(regex_replace(buf, s->getRegex(), s->getSubstitution(), boost::regex_constants::format_sed | boost::regex_constants::format_no_copy));
					//there is no 1:1 match for the std::regex_replace function used previously, but the code below should have the same outcome
					std::string input(buf);
					std::string result;
					boost::regex_replace(std::back_inserter(result), input.begin(), input.end(), s->getRegex(), s->getSubstitution().c_str(), boost::regex_constants::format_sed | boost::regex_constants::format_no_copy);
					reading.value = stoll(result);
94
95
96
				} else {
					reading.value = stoll(buf);
				}
97
#ifdef DEBUG
Micha Mueller's avatar
Micha Mueller committed
98
				LOG(debug) << _groupName << "::" << s->getName() << " raw reading: \"" << reading.value << "\"";
99
#endif
100
				s->storeReading(reading);
101
			} catch (const std::exception& e) {
102
103
				LOG(error) << _groupName << "::" << s->getName() << " could not read value: " << e.what();
				continue;
104
			}
105
106
107
		}
	} else {
		LOG(error) << _groupName << " could not read file!";
108
109
110
111
112
113
	}
}

void SysfsSensorGroup::readAsync() {
	read();
	if (_timer && _keepRunning) {
114
		_timer->expires_at(timestamp2ptime(nextReadingTime()));
115
116
117
118
119
		_pendingTasks++;
		_timer->async_wait(std::bind(&SysfsSensorGroup::readAsync, this));
	}
	_pendingTasks--;
}