SensorGroupTemplate.h 4.11 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
//================================================================================
// Name        : SensorGroupTemplate.h
// Author      : Micha Mueller
// Copyright   : Leibniz Supercomputing Centre
// Description : Interface template for sensor group functionality.
//================================================================================

//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2018-2019 Leibniz Supercomputing Centre
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//================================================================================
26
27
28
29

#ifndef SENSORGROUPTEMPLATE_H_
#define SENSORGROUPTEMPLATE_H_

30
#include "SensorGroupInterface.h"
31

32
33
34
#include "timestamp.h"

#include <vector>
35
#include <memory>
36

37
38
39
40
41
/**
 * @brief Interface template for sensor group implementations.
 *
 * @ingroup pusherplugins
 */
42
43
44
45
46
template <typename S>
class SensorGroupTemplate : public SensorGroupInterface {
	//the template shall only be instantiated for classes which derive from SensorBase
	static_assert(std::is_base_of<SensorBase, S>::value, "S must derive from SensorBase!");

47
48
49
protected:
	using S_Ptr = std::shared_ptr<S>;

50
51
52
53
public:
	SensorGroupTemplate(const std::string groupName) :
		SensorGroupInterface(groupName) {}

54
55
56
	SensorGroupTemplate(const SensorGroupTemplate& other) :
		SensorGroupInterface(other) {
		for(auto s : other._sensors) {
57
			S_Ptr sensor = std::make_shared<S>(*s);
58
59
60
61
62
			_sensors.push_back(sensor);
			_baseSensors.push_back(sensor);
		}
	}

63
	virtual ~SensorGroupTemplate() {
64
65
		_sensors.clear();
		_baseSensors.clear();
66
67
	}

68
69
70
71
72
73
	SensorGroupTemplate& operator=(const SensorGroupTemplate& other) {
		SensorGroupInterface::operator=(other);
		_sensors.clear();
		_baseSensors.clear();

		for(auto s : other._sensors) {
74
			S_Ptr sensor = std::make_shared<S>(*s);
75
76
77
78
79
80
81
			_sensors.push_back(sensor);
			_baseSensors.push_back(sensor);
		}

		return *this;
	}

82
	virtual void pushBackSensor(SBasePtr s) override {
83
84
		//check if dynamic cast returns nullptr
		if (S_Ptr dSensor = std::dynamic_pointer_cast<S>(s)) {
85
86
87
			_sensors.push_back(dSensor);
			_baseSensors.push_back(s);
		} else {
88
			LOG(warning) << "Group " << _groupName << ": Type mismatch when storing sensor! Sensor omitted";
89
90
91
		}
	}

92
	virtual std::vector<SBasePtr>& getSensors() override	{ return _baseSensors; }
93

Alessio Netti's avatar
Alessio Netti committed
94
	virtual void init(boost::asio::io_service& io) override {
95
		SensorGroupInterface::init(io);
96
97

		for(auto s : _sensors) {
98
			s->initSensor(_interval);
99
100
101
		}
	}

102
	virtual void printConfig(LOG_LEVEL ll) override {
103
	  LOG_VAR(ll) << "            Sensors:";
104
105
106
107
108
109
	  for(auto s : _sensors) {
	    s->SensorBase::printConfig(ll, lg);
	    s->printConfig(ll, lg);
	  }
	}

110
protected:
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
	/** Calculate timestamp for the next reading
	 * @return 	Timestamp in the future to wait for
	 */
	uint64_t nextReadingTime() {
		uint64_t now = getTimestamp();
		uint64_t next;
		if (_sync) {
			uint64_t interval64 = static_cast<uint64_t>(_interval);
			uint64_t now_ms = now / 1000 / 1000;
			uint64_t waitToStart = interval64 - (now_ms%interval64); //synchronize all measurements with other sensors
			if(!waitToStart ){ // less than 1 ms seconds is too small, so we wait the entire interval for the next measurement
					return (now_ms + interval64)*1000*1000;
			}
			return (now_ms + waitToStart)*1000*1000;
		} else {
			return now + MS_TO_NS(_interval);
		}
	}

130
131
	std::vector<S_Ptr> _sensors;
	std::vector<SBasePtr> _baseSensors;
132
133
134
};

#endif /* SENSORGROUPTEMPLATE_H_ */