BACnetSensorGroup.cpp 3.95 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        : BACnetSensorGroup.cpp
// Author      : Micha Mueller
// Copyright   : Leibniz Supercomputing Centre
// Description : Source file for BACnet sensor group class.
//================================================================================

//================================================================================
// 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
30

#include "BACnetSensorGroup.h"

#include <functional>

31
BACnetSensorGroup::BACnetSensorGroup(const std::string& name) : SensorGroupTemplate(name), _deviceInstance(0) {
32
33
34
	_bacClient = nullptr;
}

35
36
37
38
BACnetSensorGroup::BACnetSensorGroup(const BACnetSensorGroup& other) : SensorGroupTemplate(other),
    _bacClient(other._bacClient),
    _deviceInstance(other._deviceInstance) {}

39
40
BACnetSensorGroup::~BACnetSensorGroup() {}

41
42
43
44
45
46
47
48
BACnetSensorGroup& BACnetSensorGroup::operator=(const BACnetSensorGroup& other) {
  SensorGroupTemplate::operator =(other);
  _bacClient = other._bacClient;
  _deviceInstance = other._deviceInstance;

  return *this;
}

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
void BACnetSensorGroup::init(boost::asio::io_service& io) {
	SensorGroupTemplate::init(io);
  	if(_bacClient) {
  		_bacClient->initializeStrand(io);
  	} else {
  		LOG(error) << "No BACnetClient set for sensor " << _groupName << "! Cannot initialize sensor.";
  	}
}

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

	if (_bacClient) {
		_keepRunning = 1;
		_pendingTasks++;
		_timer->async_wait(_bacClient->getStrand()->wrap(std::bind(&BACnetSensorGroup::readAsync, this)));
		LOG(info) << "Sensorgroup " << _groupName << " started.";
	} else {
		LOG(error) << "No BACnetClient set for sensorgroup " << _groupName << "! Cannot start polling.";
	}
}

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

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

86
	for(const auto& s : _sensors) {
87
		try {
88
			reading.value = _bacClient->readProperty(getDeviceInstance(), s->getObjectInstance(), s->getObjectType(), s->getPropertyId());
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
}

void BACnetSensorGroup::readAsync() {
	read();
	if (_timer && _keepRunning) {
104
		_timer->expires_at(timestamp2ptime(nextReadingTime()));
105
106
107
108
109
		_pendingTasks++;
		_timer->async_wait(_bacClient->getStrand()->wrap(std::bind(&BACnetSensorGroup::readAsync, this)));
	}
	_pendingTasks--;
}
110
111

void BACnetSensorGroup::printConfig(LOG_LEVEL ll) {
112
  LOG_VAR(ll) << "            deviceInstance: " << _deviceInstance;
113
  if (_bacClient) {
114
    LOG_VAR(ll) << "            BACClient set";
115
  } else {
116
    LOG_VAR(ll) << "            No BACClient set!";
117
118
  }
}