You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libiec61850/pyiec61850/eventHandlers/controlActionHandler.hpp

408 lines
15 KiB
C++

#ifndef PYIEC61850_CONTROLACTIONHANDLER_HPP
#define PYIEC61850_CONTROLACTIONHANDLER_HPP
#include "eventHandler.hpp"
/*
* Abstract class for processing the received 'Control' check events.
*/
class CheckHandlerForPython: public EventHandler {
public:
virtual ~CheckHandlerForPython() {}
virtual void setReceivedData(void *i_data_p)
{
// copy the received data
ControlAction *l_my_data_p = static_cast<ControlAction*>(i_data_p);
_libiec61850_control_action = *l_my_data_p;
}
void setMmsValue(MmsValue *i_data_value)
{
_libiec61850_mms_value = i_data_value;
}
void setIedServer(IedServer *i_ied_server)
{
// copy the pointer and get to server
IedServer *l_my_server_p = i_ied_server;
_libiec61850_ied_server = *l_my_server_p;
}
void setTest(bool i_test)
{
_libiec61850_test = i_test;
}
void setInterlockCheck(bool i_interlock_check)
{
_libiec61850_interlock_check = i_interlock_check;
}
CheckHandlerResult getCheckHandlerResult()
{
return _libiec61850_check_handler_result;
}
CheckHandlerResult _libiec61850_check_handler_result; // Should be set during "trigger" callback function
ControlAction _libiec61850_control_action;
MmsValue* _libiec61850_mms_value;
IedServer _libiec61850_ied_server;
bool _libiec61850_test;
bool _libiec61850_interlock_check;
};
/*
* Abstract class for processing the received 'Control' wait for execution events.
*/
class WaitForExecutionHandlerForPython: public EventHandler {
public:
virtual ~WaitForExecutionHandlerForPython() {}
virtual void setReceivedData(void *i_data_p)
{
// copy the received data
ControlAction *l_my_data_p = static_cast<ControlAction*>(i_data_p);
_libiec61850_control_action = *l_my_data_p;
}
void setMmsValue(MmsValue *i_data_value)
{
_libiec61850_mms_value = i_data_value;
}
void setIedServer(IedServer *i_ied_server)
{
// copy the pointer and get to server
IedServer *l_my_server_p = i_ied_server;
_libiec61850_ied_server = *l_my_server_p;
}
void setTest(bool i_test)
{
_libiec61850_test = i_test;
}
void setSynchroCheck(bool i_synchro_check)
{
_libiec61850_synchro_check = i_synchro_check;
}
ControlHandlerResult getControlHandlerResult()
{
return _libiec61850_control_handler_result;
}
ControlHandlerResult _libiec61850_control_handler_result; // Should be set during "trigger" callback function
ControlAction _libiec61850_control_action;
MmsValue* _libiec61850_mms_value;
IedServer _libiec61850_ied_server;
bool _libiec61850_test;
bool _libiec61850_synchro_check;
};
/*
* Abstract class for processing the received 'Control' events.
*/
class ControlHandlerForPython: public EventHandler {
public:
virtual ~ControlHandlerForPython() {}
virtual void setReceivedData(void *i_data_p)
{
// copy the received data
ControlAction *l_my_data_p = static_cast<ControlAction*>(i_data_p);
_libiec61850_control_action = *l_my_data_p;
}
void setMmsValue(MmsValue *i_data_value)
{
_libiec61850_mms_value = i_data_value;
}
void setIedServer(IedServer *i_ied_server)
{
// copy the pointer and get to server
IedServer *l_my_server_p = i_ied_server;
_libiec61850_ied_server = *l_my_server_p;
}
void setTest(bool i_test)
{
_libiec61850_test = i_test;
}
ControlHandlerResult getControlHandlerResult()
{
return _libiec61850_control_handler_result;
}
ControlHandlerResult _libiec61850_control_handler_result; // Should be set during "trigger" callback function
ControlAction _libiec61850_control_action;
MmsValue* _libiec61850_mms_value;
IedServer _libiec61850_ied_server;
bool _libiec61850_test;
};
/*
* Class for the subscription to the 'Control' events
*/
class ControlSubscriberForPython: public EventSubscriber {
public:
ControlSubscriberForPython(): EventSubscriber()
{
m_ied_server = nullptr;
m_control_object = nullptr;
m_perform_check_handler_p = nullptr;
m_wait_handler_p = nullptr;
m_control_handler_p = nullptr;
}
virtual ~ControlSubscriberForPython() {
if (m_perform_check_handler_p) {
delete m_perform_check_handler_p;
}
m_perform_check_handler_p = nullptr;
if (m_wait_handler_p) {
delete m_wait_handler_p;
}
m_wait_handler_p = nullptr;
if (m_control_handler_p) {
delete m_control_handler_p;
}
m_control_handler_p = nullptr;
}
// Getters
CheckHandlerForPython *getCheckHandler()
{
return m_perform_check_handler_p;
}
WaitForExecutionHandlerForPython *getWaitHandler()
{
return m_wait_handler_p;
}
ControlHandlerForPython *getControlHandler()
{
return m_control_handler_p;
}
// Subscriber: assign callbacks to IedServer
virtual bool subscribe()
{
// preconditions
if (nullptr == m_ied_server) {
fprintf(stderr, "ControlSubscriber::subscribe() failed: 'ied server' is null\n");
return false;
}
if (nullptr == m_control_object) {
fprintf(stderr, "ControlSubscriber::subscribe() failed: 'control object' is null\n");
return false;
}
// install the libiec61850 callbacks for the different control states, if handler are set:
// the 'function pointer' is the 'static' method of this class
if (m_perform_check_handler_p) {
IedServer_setPerformCheckHandler(m_ied_server,
m_control_object,
(ControlPerformCheckHandler) ControlSubscriberForPython::triggerPerformCheckHandler,
&m_ied_server);
}
if (m_wait_handler_p){
IedServer_setWaitForExecutionHandler(m_ied_server,
m_control_object,
(ControlWaitForExecutionHandler) ControlSubscriberForPython::triggerWaitForExecutionHandler,
&m_ied_server);
}
if (m_control_handler_p) {
IedServer_setControlHandler(m_ied_server,
m_control_object,
(ControlHandler) ControlSubscriberForPython::triggerControlHandler,
&m_ied_server);
}
char *l_object_ref = ModelNode_getObjectReference( (ModelNode*) m_control_object, NULL);
std::string objs(l_object_ref);
std::string dirs = std::string(ModelNode_getObjectReference( (ModelNode*) m_control_object, NULL));
return (EventSubscriber::registerNewSubscriber(this, l_object_ref));
}
// Static method: it is the control perform check 'callback' for libiec61850 in C
static CheckHandlerResult triggerPerformCheckHandler(ControlAction action, void* parameter, MmsValue* ctlVal, bool test, bool interlockCheck)
{
PyThreadStateLock PyThreadLock;
// Preconditions
if (nullptr == parameter) {
fprintf(stderr, "ControlSubscriber::triggerPerformCheckHandler() failed: input object is null\n");
return CONTROL_HARDWARE_FAULT; // Status may not
}
DataObject* control_object = ControlAction_getControlObject(action);
std::string l_object_ref = ModelNode_getObjectReference( (ModelNode*) control_object, NULL);
// Search the appropriate 'EventSubscriber' object
ControlSubscriberForPython *l_registered_subscriber = (ControlSubscriberForPython*) EventSubscriber::findSubscriber(l_object_ref);
if (l_registered_subscriber) {
CheckHandlerForPython *l_perform_check_handler_p = l_registered_subscriber->getCheckHandler();
if (l_perform_check_handler_p) {
l_perform_check_handler_p->setReceivedData(&action);
l_perform_check_handler_p->setMmsValue(ctlVal);
l_perform_check_handler_p->setIedServer((IedServer*) parameter);
l_perform_check_handler_p->setTest(test);
l_perform_check_handler_p->setInterlockCheck(interlockCheck);
l_perform_check_handler_p->trigger();
fprintf(stderr, "triggerPerformCheckHandler::triggerPerformCheckHandler() end\n");
return l_perform_check_handler_p->getCheckHandlerResult();
}
else {
fprintf(stderr, "ControlSubscriber::triggerPerformCheckHandler() failed: EventHandler is undefined\n");
return CONTROL_HARDWARE_FAULT;
}
}
else {
fprintf(stderr, "ControlSubscriber::triggerPerformCheckHandler() failed: subscriber is not registered\n");
return CONTROL_HARDWARE_FAULT;
}
}
// Static method: it is the control wait for execution 'callback' for libiec61850 in C
static ControlHandlerResult triggerWaitForExecutionHandler(ControlAction controlAction, void* parameter, MmsValue* value, bool test, bool synchroCheck)
{
PyThreadStateLock PyThreadLock;
// Preconditions
if (nullptr == parameter) {
fprintf(stderr, "ControlSubscriber::triggerWaitForExecutionHandler() failed: input object is null\n");
return CONTROL_RESULT_FAILED;
}
DataObject* control_object = ControlAction_getControlObject(controlAction);
std::string l_object_ref = ModelNode_getObjectReference( (ModelNode*) control_object, NULL);
// Search the appropriate 'EventSubscriber' object
ControlSubscriberForPython *l_registered_subscriber = (ControlSubscriberForPython*) EventSubscriber::findSubscriber(l_object_ref);
if (l_registered_subscriber) {
WaitForExecutionHandlerForPython *l_wait_handler_p = l_registered_subscriber->getWaitHandler();
if (l_wait_handler_p) {
l_wait_handler_p->setReceivedData(&controlAction);
l_wait_handler_p->setMmsValue(value);
l_wait_handler_p->setIedServer((IedServer*) parameter);
l_wait_handler_p->setTest(test);
l_wait_handler_p->setSynchroCheck(synchroCheck);
l_wait_handler_p->trigger();
fprintf(stderr, "triggerWaitForExecutionHandler::triggerWaitForExecutionHandler() end\n");
return l_wait_handler_p->getControlHandlerResult();
}
else {
fprintf(stderr, "ControlSubscriber::triggerWaitForExecutionHandler() failed: EventHandler is undefined\n");
return CONTROL_RESULT_FAILED;
}
}
else {
fprintf(stderr, "ControlSubscriber::triggerWaitForExecutionHandler() failed: subscriber is not registered\n");
return CONTROL_RESULT_FAILED;
}
}
// Static method: it is the control 'callback' for libiec61850 in C
static ControlHandlerResult triggerControlHandler(ControlAction controlAction, void* parameter, MmsValue* value, bool test)
{
PyThreadStateLock PyThreadLock;
// Preconditions
if (nullptr == parameter) {
fprintf(stderr, "ControlSubscriber::triggerControlHandler() failed: input object is null\n");
return CONTROL_RESULT_FAILED;
}
DataObject* control_object = ControlAction_getControlObject(controlAction);
std::string l_object_ref = ModelNode_getObjectReference( (ModelNode*) control_object, NULL);
// Search the appropriate 'EventSubscriber' object
ControlSubscriberForPython *l_registered_subscriber = (ControlSubscriberForPython*) EventSubscriber::findSubscriber(l_object_ref);
if (l_registered_subscriber) {
ControlHandlerForPython *l_control_handler_p = l_registered_subscriber->getControlHandler();
if (l_control_handler_p) {
l_control_handler_p->setReceivedData(&controlAction);
l_control_handler_p->setMmsValue(value);
l_control_handler_p->setIedServer((IedServer*) parameter);
l_control_handler_p->setTest(test);
l_control_handler_p->trigger();
fprintf(stderr, "triggerControlHandler::triggerControlHandler() end\n");
return l_control_handler_p->getControlHandlerResult();
}
else {
fprintf(stderr, "ControlSubscriber::triggerControlHandler() failed: EventHandler is undefined\n");
return CONTROL_RESULT_FAILED;
}
}
else {
fprintf(stderr, "ControlSubscriber::triggerControlHandler() failed: subscriber is not registered\n");
return CONTROL_RESULT_FAILED;
}
}
// Setters
void setIedServer(const IedServer &i_ied_server)
{
m_ied_server = i_ied_server;
}
void setControlObject(DataObject *i_control_object)
{
m_control_object = i_control_object;
}
void setCheckHandler(CheckHandlerForPython* i_check_handler_p)
{
m_perform_check_handler_p = i_check_handler_p;
}
void setWaitHandler(WaitForExecutionHandlerForPython* i_wait_handler_p)
{
m_wait_handler_p = i_wait_handler_p;
}
void setControlHandler(ControlHandlerForPython* i_control_handler_p)
{
m_control_handler_p = i_control_handler_p;
}
private:
// Parameters
IedServer m_ied_server;
DataObject* m_control_object;
CheckHandlerForPython* m_perform_check_handler_p;
WaitForExecutionHandlerForPython* m_wait_handler_p;
ControlHandlerForPython* m_control_handler_p;
};
#endif