Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit a58d9f72 authored by Michael Ott's avatar Michael Ott
Browse files

Initial commit for Siemens S7 PLC plugin

parent 8bcb3dfb
...@@ -3,7 +3,7 @@ DCDBDEPSPATH ?= $(DCDBBASEPATH)/deps ...@@ -3,7 +3,7 @@ DCDBDEPSPATH ?= $(DCDBBASEPATH)/deps
DCDBDEPLOYPATH ?= $(DCDBBASEPATH)/install DCDBDEPLOYPATH ?= $(DCDBBASEPATH)/install
# dcdbpusher plugins to be built # dcdbpusher plugins to be built
PLUGINS = sysfs ipmi pdu bacnet snmp procfs tester gpfsmon msr PLUGINS = sysfs ipmi pdu bacnet snmp procfs tester gpfsmon msr s7plc
# data analytics plugins to be built # data analytics plugins to be built
OPERATORS = aggregator smoothing regressor classifier clustering cssignatures job_aggregator testeroperator filesink smucngperf persystsql OPERATORS = aggregator smoothing regressor classifier clustering cssignatures job_aggregator testeroperator filesink smucngperf persystsql
......
...@@ -121,3 +121,5 @@ libdcdbplugin_caliper.$(LIBEXT): sensors/caliper/CaliperSensorGroup.o sensors/ca ...@@ -121,3 +121,5 @@ libdcdbplugin_caliper.$(LIBEXT): sensors/caliper/CaliperSensorGroup.o sensors/ca
libdcdbplugin_nvml.$(LIBEXT): sensors/nvml/nvmlSensorGroup.o sensors/nvml/nvmlConfigurator.o libdcdbplugin_nvml.$(LIBEXT): sensors/nvml/nvmlSensorGroup.o sensors/nvml/nvmlConfigurator.o
$(NVCC) -shared --compiler-options '-fPIC' -o $@ $^ -L$(DCDBDEPLOYPATH)/lib/ -lboost_log -lboost_system -lnvidia-ml $(NVCC) -shared --compiler-options '-fPIC' -o $@ $^ -L$(DCDBDEPLOYPATH)/lib/ -lboost_log -lboost_system -lnvidia-ml
libdcdbplugin_s7plc.$(LIBEXT): sensors/s7plc/s7plcSensorGroup.o sensors/s7plc/s7plcController.o sensors/s7plc/s7plcConfigurator.o
$(CXX) $(LIBFLAGS)$@ -o $@ $^ -L$(DCDBDEPLOYPATH)/lib/ -lboost_log -lboost_system -lsnap7
controller test {
Host 127.0.0.1
Rack 0
Slot 2
group db1 {
sensor s1 {
DB 1;
offset 4;
type REAL;
}
sensor s2 {
DB 2;
offset 8;
type DWORD;
}
}
}
//================================================================================
// Name : s7plcConfigurator.cpp
// Author : Michael Ott
// Contact :
// Copyright :
// Description : Source file for s7plc plugin configurator class.
//================================================================================
//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2020 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.
//================================================================================
#include "s7plcConfigurator.h"
s7plcConfigurator::s7plcConfigurator() {
/*
* TODO
* If you want sensor or group to be named differently in the config file, you can change it here
*/
_entityName = "controller";
_groupName = "group";
_baseName = "sensor";
}
s7plcConfigurator::~s7plcConfigurator() {}
void s7plcConfigurator::sensorBase(s7plcSensorBase& s, CFG_VAL config) {
ADD {
ATTRIBUTE("DB", setDB);
ATTRIBUTE("Offset", setOffset);
ATTRIBUTE("Type", setType);
}
}
void s7plcConfigurator::sensorGroup(s7plcSensorGroup& s, CFG_VAL config) {
ADD {
}
}
void s7plcConfigurator::sensorEntity(s7plcController& s, CFG_VAL config) {
ADD {
/*
* TODO
* Add ATTRIBUTE macros for Controller attributes
*/
ATTRIBUTE("Host", setHost);
ATTRIBUTE("Rack", setRack);
ATTRIBUTE("Slot", setSlot);
}
}
void s7plcConfigurator::printConfiguratorConfig(LOG_LEVEL ll) {
/*
* TODO
* Log attributes here for debug reasons or delete this method if there are
* not attributes to log.
*/
LOG_VAR(ll) << " NumSpacesAsIndention: " << 2;
}
//================================================================================
// Name : s7plcConfigurator.h
// Author : Michael Ott
// Contact :
// Copyright :
// Description : Header file for s7plc plugin configurator class.
//================================================================================
//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2020 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.
//================================================================================
#ifndef S7PLC_S7PLCCONFIGURATOR_H_
#define S7PLC_S7PLCCONFIGURATOR_H_
#include "../../includes/ConfiguratorTemplateEntity.h"
#include "s7plcSensorGroup.h"
#include "s7plcController.h"
/**
* @brief ConfiguratorTemplate specialization for this plugin.
*
* @ingroup s7plc
*/
class s7plcConfigurator : public ConfiguratorTemplateEntity<s7plcSensorBase, s7plcSensorGroup, s7plcController> {
public:
s7plcConfigurator();
virtual ~s7plcConfigurator();
protected:
/* Overwritten from ConfiguratorTemplate */
void sensorBase(s7plcSensorBase& s, CFG_VAL config) override;
void sensorGroup(s7plcSensorGroup& s, CFG_VAL config) override;
void sensorEntity(s7plcController& s, CFG_VAL config) override;
//TODO implement if required
//void global(CFG_VAL config) override;
//void derivedSetGlobalSettings(const pluginSettings_t& pluginSettings) override;
void printConfiguratorConfig(LOG_LEVEL ll) final override;
};
extern "C" ConfiguratorInterface* create() {
return new s7plcConfigurator;
}
extern "C" void destroy(ConfiguratorInterface* c) {
delete c;
}
#endif /* S7PLC_S7PLCCONFIGURATOR_H_ */
//================================================================================
// Name : s7plcController.cpp
// Author : Michael Ott
// Contact :
// Copyright :
// Description : Source file for s7plcController class.
//================================================================================
//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2020 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.
//================================================================================
#include "s7plcController.h"
s7plcController::s7plcController(const std::string& name) :
EntityInterface(name) {
_host = "";
_rack = 0;
_slot = 2;
_client = Cli_Create();
}
s7plcController::s7plcController(const s7plcController& other) :
EntityInterface(other) {
/*
* TODO
* Copy construct attributes
*/
}
s7plcController::~s7plcController() {
Cli_Destroy(&_client);
}
s7plcController& s7plcController::operator=(const s7plcController& other) {
EntityInterface::operator=(other);
/*
* TODO
* Implement assignment operator here
*/
return *this;
}
/*
* TODO
* Implement own methods
*/
int s7plcController::connect() {
return Cli_ConnectTo(_client, _host.c_str(), _rack, _slot);
}
int s7plcController::disconnect() {
return Cli_Disconnect(_client);
}
int s7plcController::read(int DB, int offset, int size, void* buf) {
int ret = Cli_DBRead(_client, DB, offset, size, buf);
if (ret != 0) {
char buf[1024];
Cli_ErrorText(ret, buf, 1024);
throw std::runtime_error("Error reading DB: " + std::string(buf));
}
return ret;
}
void s7plcController::execOnInit() {
/*
* TODO
* Implement logic to initialize the entity here or remove method if not required.
* Will be called exactly once at startup.
*/
}
void s7plcController::printEntityConfig(LOG_LEVEL ll, unsigned int leadingSpaces) {
std::string leading(leadingSpaces, ' ');
LOG_VAR(ll) << leading << "Host: " << _host;
LOG_VAR(ll) << leading << "Rack: " << _rack;
LOG_VAR(ll) << leading << "Slot: " << _slot;
}
//================================================================================
// Name : s7plcController.h
// Author : Michael Ott
// Contact :
// Copyright :
// Description : Header file for s7plcController class.
//================================================================================
//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2020 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.
//================================================================================
#ifndef S7PLCCONTROLLER_H_
#define S7PLCCONTROLLER_H_
#include "../../includes/EntityInterface.h"
#include "snap7.h"
/**
* @brief This class handles s7plc Controller.
*
* @ingroup s7plc
*/
class s7plcController : public EntityInterface {
public:
s7plcController(const std::string& name);
s7plcController(const s7plcController& other);
virtual ~s7plcController();
s7plcController& operator=(const s7plcController& other);
void setHost(const std::string &host) { _host = host; }
void setRack(const std::string &rack) { _rack = stoi(rack); }
void setSlot(const std::string &slot) { _slot = stoi(slot); }
int connect();
int disconnect();
int read(int DB, int offset, int size, void* buf);
void execOnInit() final override;
void printEntityConfig(LOG_LEVEL ll, unsigned int leadingSpaces) final override;
private:
std::string _host;
int _rack;
int _slot;
S7Object _client;
};
#endif /* S7PLCCONTROLLER_H_ */
//================================================================================
// Name : s7plcSensorBase.h
// Author : Michael Ott
// Contact :
// Copyright :
// Description : Sensor base class for s7plc plugin.
//================================================================================
//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2020 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.
//================================================================================
/**
* @defgroup s7plc s7plc plugin
* @ingroup pusherplugins
*
* @brief Describe your plugin in one sentence
*/
#ifndef S7PLC_S7PLCSENSORBASE_H_
#define S7PLC_S7PLCSENSORBASE_H_
#include "sensorbase.h"
#include "s7plcController.h"
/*
* TODO
* Add plugin specific includes
*/
/**
* @brief SensorBase specialization for this plugin.
*
* @ingroup s7plc
*/
class s7plcSensorBase : public SensorBase {
public:
s7plcSensorBase(const std::string& name) :
SensorBase(name) {
_db = 0;
_offset = 0;
_type = sensorType::undefined;
}
s7plcSensorBase(const s7plcSensorBase& other) :
SensorBase(other) {
/*
* TODO
* Copy construct plugin specific attributes
*/
}
virtual ~s7plcSensorBase() {
/*
* TODO
* If necessary, deconstruct plugin specific attributes
*/
}
s7plcSensorBase& operator=(const s7plcSensorBase& other) {
SensorBase::operator=(other);
/*
* TODO
* Implement assignment operator for plugin specific attributes
*/
return *this;
}
enum sensorType {
undefined = 0,
BIT,
BYTE,
INT,
DINT,
WORD,
DWORD,
REAL
};
void setDB(const std::string &db) { _db = stoi(db); }
void setOffset(const std::string &offset) { _offset = stoi(offset); }
void setType(const std::string &type) {
if (boost::iequals(type, "BIT")) {
_type = BIT;
} else if (boost::iequals(type, "BYTE")) {
_type = BYTE;
} else if (boost::iequals(type, "INT")) {
_type = INT;
} else if (boost::iequals(type, "DINT")) {
_type = DINT;
} else if (boost::iequals(type, "WORD")) {
_type = WORD;
} else if (boost::iequals(type, "DWORD")) {
_type = DWORD;
} else if (boost::iequals(type, "REAL")) {
_type = REAL;
} else {
_type = undefined;
}
}
int getDB() { return _db; }
int getOffset() { return _offset; }
sensorType getType() { return _type; }
std::string getTypeString() const {
switch (_type) {
case BIT:
return std::string("BIT");
case BYTE:
return std::string("BYTE");
case INT:
return std::string("INT");
case DINT:
return std::string("DINT");
case WORD:
return std::string("WORD");
case DWORD:
return std::string("DWORD");
case REAL:
return std::string("REAL");
default:
return std::string("undefined");
}
}
void printConfig(LOG_LEVEL ll, LOGGER& lg, unsigned leadingSpaces = 16) {
std::string leading(leadingSpaces+4, ' ');
LOG_VAR(ll) << leading<< "DB: " << _db;
LOG_VAR(ll) << leading<< "Offset: " << _offset;
LOG_VAR(ll) << leading<< "Type: " << getTypeString();
}
protected:
int _db;
int _offset;
sensorType _type;
};
#endif /* S7PLC_S7PLCSENSORBASE_H_ */
//================================================================================
// Name : s7plcSensorGroup.cpp
// Author : Michael Ott
// Contact :
// Copyright :
// Description : Source file for s7plc sensor group class.
//================================================================================
//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2020 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.
//================================================================================
#include "s7plcSensorGroup.h"
#include "timestamp.h"
s7plcSensorGroup::s7plcSensorGroup(const std::string& name) :
SensorGroupTemplateEntity(name) {
/*
* TODO
* Construct attributes
*/
}
s7plcSensorGroup::s7plcSensorGroup(const s7plcSensorGroup& other) :
SensorGroupTemplateEntity(other) {
/*
* TODO
* Copy construct attributes
*/
}
s7plcSensorGroup::~s7plcSensorGroup() {
/*
* TODO
* Tear down attributes
*/
}
s7plcSensorGroup& s7plcSensorGroup::operator=(const s7plcSensorGroup& other) {
SensorGroupTemplate::operator=(other);
/*
* TODO
* Implement assignment operator
*/
return *this;
}
void s7plcSensorGroup::execOnInit() {
/*
* TODO
* Implement one time initialization logic for this group here
* (e.g. allocate memory for buffer) or remove this method if not
* required.
*/
}
bool s7plcSensorGroup::execOnStart() {
/*
* TODO
* Implement logic before the group starts polling here
* (e.g. open a file descriptor) or remove this method if not required.
*/
return true;
}
void s7plcSensorGroup::execOnStop() {
/*
* TODO
* Implement logic when the group stops polling here
* (e.g. close a file descriptor) or remove this method if not required.
*/
}
void s7plcSensorGroup::read() {
reading_t reading;
reading.timestamp = getTimestamp();
if (_entity->connect() == 0) {
for(auto s : _sensors) {
try {
int ret = 1;
uint64_t val = 0;
switch (s->getType()) {
case s7plcSensorBase::sensorType::BYTE:
uint8_t b;
ret = _entity->read(s->getDB(), s->getOffset(), 1, &b);
val = b;
break;
case s7plcSensorBase::sensorType::INT:
int16_t i;
ret = _entity->read(s->getDB(), s->getOffset(), 2, &i);
val = i;
break;
case s7plcSensorBase::sensorType::DINT:
int32_t di;
ret = _entity->read(s->getDB(), s