IPMISensorGroup.cpp 3.18 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
 * IPMISingleSensor.cpp
 *
 *  Created on: 18 Jan 2017
 *      Author: Michael Ott (original), Micha Müller
 */

#include "IPMISensorGroup.h"
#include "IPMIHost.h"

#include <boost/tokenizer.hpp>
#include <boost/foreach.hpp>
#include <boost/regex.hpp>
#include <boost/bind.hpp>
#include <boost/lockfree/spsc_queue.hpp>

#include <iostream>
#include <exception>
#include <chrono>

IPMISensorGroup::IPMISensorGroup(const std::string& name) :
		SensorGroupTemplate(name) {
	_host = nullptr;
}

26
27
28
29
IPMISensorGroup::IPMISensorGroup(const IPMISensorGroup& other) :
    SensorGroupTemplate(other),
    _host(other._host) {}

30
31
IPMISensorGroup::~IPMISensorGroup() {}

32
33
34
35
36
37
38
IPMISensorGroup& IPMISensorGroup::operator=(const IPMISensorGroup& other) {
  SensorGroupTemplate::operator=(other);
  _host = other._host;

  return *this;
}

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
void IPMISensorGroup::init(boost::asio::io_service& io) {
	SensorGroupTemplate::init(io);
	if (_host) {
		_host->initializeStrand(io);
	} else {
		LOG(error)<< "No host set for sensorgroup " << _groupName << "! Cannot initialize sensor.";
	}
}

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

	if (_host) {
		_keepRunning = 1;
		_pendingTasks++;
		_timer->async_wait(_host->getStrand()->wrap(boost::bind(&IPMISensorGroup::readAsync, this)));
		LOG(info) << "Sensorgroup " << _groupName << " started.";
	} else {
61
		LOG(error) << "No host set for sensorgroup " << _groupName << "! Cannot start polling.";
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
		return;
	}
}

void IPMISensorGroup::stop() {
	_keepRunning = 0;
	//cancel any outstanding readAsync()
	_timer->cancel();
	LOG(info)<< "Sensorgroup " << _groupName << " stopped.";
}

void IPMISensorGroup::read() {
	reading_t reading;
	reading.timestamp = getTimestamp();

77
	for(const auto& s : _sensors) {
78
79
		try {
			if (s->getRecordId() != 0) { /* recordId was set */
80
81
82
83
84
			    std::vector<uint8_t> sdrRecord = s->getSdrRecord();
			    if (sdrRecord.size() == 0) {
				_host->getSdrRecord(s->getRecordId(), sdrRecord);
				s->setSdrRecord(sdrRecord);
			    }
85
			    reading.value = _host->readSensorRecord(sdrRecord);
86
			} else { /* use raw command */
87
				reading.value = _host->sendRawCmd(s->getRawCmd(), s->getLsb(), s->getMsb());
88
			}
89
#ifdef DEBUG
Micha Mueller's avatar
Micha Mueller committed
90
			LOG(debug) << _groupName << "::" << s->getName() << " raw reading: \"" << reading.value << "\"";
91
#endif
92
			s->storeReading(reading, s->getFactor());
93
94
		} catch (const std::exception& e) {
			LOG(error) << _groupName << "::" << s->getName() << " could not read value: " << e.what();
95
		    continue;
96
97
98
99
100
101
102
103
104
105
		}
	}
}

void IPMISensorGroup::readAsync() {
	uint64_t now = getTimestamp();
	if (now >= _host->getDelayNextReadUntil()) {
		read();
	}
	if (_timer && _keepRunning) {
106
		uint64_t next = nextReadingTime();
107
108
109
110
111
112
113
114
115
		while (next < _host->getDelayNextReadUntil()) {
			next += MS_TO_NS(_interval);
		}
		_timer->expires_at(timestamp2ptime(next));
		_pendingTasks++;
		_timer->async_wait(_host->getStrand()->wrap(boost::bind(&IPMISensorGroup::readAsync, this)));
	}
	_pendingTasks--;
}
Micha Mueller's avatar
Micha Mueller committed
116
117
118
119
120
121
122
123

void IPMISensorGroup::printConfig(LOG_LEVEL ll) {
    if (_host) {
      LOG_VAR(ll) << "   Host: " << _host->getHostName();
    } else {
      LOG_VAR(ll) << "   No Host set!";
    }
}