SYSFSSensor.cpp 2.3 KB
Newer Older
1
2
3
4
5
6
7
8
/*
 * SYSFSSensor.cpp
 *
 *  Created on: 18.11.2017
 *      Author: Micha Mueller
 */

#include "SYSFSSensor.h"
9
#include "timestamp.h"
10
#include <functional>
11
12
13
14

extern volatile int keepRunning;

using namespace std;
15
16
17
18
19

SYSFSSensor::SYSFSSensor(const std::string& name) {
	_name = name;
	_path = "";
	_mqtt = "";
Micha Mueller's avatar
Micha Mueller committed
20
	_minValues = 1;
21
22
23
	_interval = 1000;
	_file = NULL;
	_filter = false;
24
25
	//_regx = "";
	_substitution = "";
26
27
28
29

	_timer = NULL;
	_latestReading = 0;
	_readingQueue = NULL;
30
31
32
}

SYSFSSensor::~SYSFSSensor() {
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
	if (_readingQueue != NULL) {
		delete _readingQueue;
		_readingQueue = NULL;
	}
	if (_file != NULL) {
		fclose(_file);
		_file = NULL;
	}
}

void SYSFSSensor::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) {
Micha Mueller's avatar
Micha Mueller committed
52
		buf[nelem-1] = 0;
53

Micha Mueller's avatar
Micha Mueller committed
54
55
56
57
58
59
		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
Micha Mueller's avatar
Micha Mueller committed
60
				reading.value = stoll(regex_replace(buf, _regx, _substitution, regex_constants::format_sed | regex_constants::format_no_copy));
Micha Mueller's avatar
Micha Mueller committed
61
62
63
64
			} else {
				reading.value = stoll(buf);
			}
		} catch (const std::exception& e) {
Micha Mueller's avatar
Micha Mueller committed
65
#ifdef DEBUG
Micha Mueller's avatar
Micha Mueller committed
66
			cout << "Sensor " << _name << ": Could not parse value!" << endl;
Micha Mueller's avatar
Micha Mueller committed
67
#endif
Micha Mueller's avatar
Micha Mueller committed
68
			return;
69
70
		}

71
#ifdef DEBUG
Micha Mueller's avatar
Micha Mueller committed
72
	        cout << "[" << prettyPrintTimestamp(reading.timestamp) << "] " << _name << ": \"" << reading.value << "\"" << endl;
73
#endif
74
	}
Micha Mueller's avatar
Micha Mueller committed
75
	_readingQueue->push(reading);
76
77
}

78
void SYSFSSensor::readAsync() {
79
80
81
82
83
	uint64_t now = getTimestamp();
	read();
	if (_timer != NULL && keepRunning) {
		uint64_t next = now + MS_TO_NS(_interval);
		_timer->expires_at(timestamp2ptime(next));
84
		_timer->async_wait(std::bind(&SYSFSSensor::readAsync, this));
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
	}

}

void SYSFSSensor::startPolling(boost::asio::io_service& io) {
	if(_readingQueue == NULL) {
		_readingQueue = new boost::lockfree::spsc_queue<reading_t>(1024);
	}
	if(_file == NULL) {
		_file = fopen(_path.c_str(), "r");
		if (_file == NULL) {
			cerr << "Error opening sensor \"" << _name << "\": " << strerror(errno) << endl;
			return;
		}
	}
	_timer = new boost::asio::deadline_timer(io, boost::posix_time::seconds(0));
101
	_timer->async_wait(std::bind(&SYSFSSensor::readAsync, this));
102
}