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
DCDBDEPLOYPATH ?= $(DCDBBASEPATH)/install
# 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
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
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
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