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

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

using namespace std;

SysfsSensorGroup::SysfsSensorGroup(const std::string& name) :
16
17
18
19
	SensorGroupTemplate(name),
	_path("") {
	_file = NULL;
}
20
21
22
23
24
25
26
27
28
29

SysfsSensorGroup::~SysfsSensorGroup() {}

void SysfsSensorGroup::start() {
	if (_keepRunning) {
		//we have been started already
		LOG(info) << "Sensorgroup " << _groupName << " already running.";
		return;
	}

30
31
32
33
34
	if(_file == NULL) {
		_file = fopen(_path.c_str(), "r");
		if (_file == NULL) {
			LOG(error) << "Error starting group\"" << _groupName << "\": " << strerror(errno);
			return;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
		}
	}

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

49
50
51
	if (_file != NULL) {
		fclose(_file);
		_file = NULL;
52
53
54
55
56
57
58
59
	}
	LOG(info) << "Sensorgroup " << _groupName << " stopped.";
}

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

60
61
	fseek(_file, 0, SEEK_SET);
	size_t nelem = fread(buf, 1, 1024, _file);
62
63
	reading.timestamp = getTimestamp();

64
65
66
67
	if (nelem) {
		buf[nelem-1] = 0;
		for(auto s : _sensors) {
			reading.value = 0;
68
69
70
71
72
73
			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
74
75
76
77
78
79
80

					//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);
81
82
83
84
				} else {
					reading.value = stoll(buf);
				}
			} catch (const std::exception& e) {
85
86
				LOG(error) << _groupName << "::" << s->getName() << " could not read value: " << e.what();
				continue;
87
			}
88
#ifdef DEBUG
89
			LOG(debug) << _groupName << "::" << s->getName() << ": \"" << reading.value << "\"";
90
#endif
91
92
93
94
95
96
			//to keep the _cacheIndex uniform for all sensors store value in every case
			s->storeReading(reading, _cacheIndex);
		}
		_cacheIndex = (_cacheIndex + 1) % _cacheSize;
	} else {
		LOG(error) << _groupName << " could not read file!";
97
98
99
100
101
102
103
104
105
106
107
108
109
110
	}
}

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--;
}