- added python bindings

pull/6/head
Michael Zillgith 9 years ago
parent ebecd5a1ce
commit 1688fd872b

@ -8,6 +8,7 @@ if(DEFINED ENV{TOOLCHAIN})
endif()
project(libiec61850)
ENABLE_TESTING()
set(LIB_VERSION_MAJOR "0")
set(LIB_VERSION_MINOR "9")
@ -25,6 +26,7 @@ set(CONFIG_MMS_MAXIMUM_PDU_SIZE "65000" CACHE STRING "Configure the maximum size
set(CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS 5 CACHE STRING "Configure the maximum number of clients allowed to connect to the server")
option(BUILD_EXAMPLES "Build the examples" ON)
option(BUILD_PYTHON_BINDINGS "Build Python bindings" OFF)
option(CONFIG_MMS_SINGLE_THREADED "Compile for single threaded version" OFF)
option(CONFIG_MMS_THREADLESS_STACK "Optimize stack for threadless operation (warning: single- or multi-threaded server will not work!)" OFF)
@ -119,6 +121,9 @@ add_subdirectory(src)
INSTALL(FILES ${API_HEADERS} DESTINATION include/libiec61850)
IF(BUILD_PYTHON_BINDINGS)
add_subdirectory(pyiec61850)
ENDIF(BUILD_PYTHON_BINDINGS)
IF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
INCLUDE(InstallRequiredSystemLibraries)
@ -144,6 +149,3 @@ SET(CPACK_COMPONENTS_ALL Libraries ApplicationData)
INCLUDE(CPack)
ENDIF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")

@ -0,0 +1,23 @@
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
FIND_PACKAGE(PythonLibs REQUIRED)
FIND_PACKAGE ( PythonInterp REQUIRED )
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_SWIG_FLAGS "")
SET_PROPERTY(SOURCE iec61850.i PROPERTY CPLUSPLUS ON)
SWIG_ADD_MODULE(iec61850 python iec61850.i)
IF(WIN32)
SWIG_LINK_LIBRARIES(iec61850 ${PYTHON_LIBRARIES} iec61850 ws2_32)
ELSE()
SWIG_LINK_LIBRARIES(iec61850 ${PYTHON_LIBRARIES} iec61850-shared)
ENDIF(WIN32)
EXECUTE_PROCESS ( #Finding python modules install path
COMMAND ${PYTHON_EXECUTABLE} -c
"import site, sys; sys.stdout.write(site.getsitepackages()[-1])"
OUTPUT_VARIABLE PYTHON_SITE_DIR
)
INSTALL ( FILES ${CMAKE_BINARY_DIR}/iec61850.py DESTINATION ${PYTHON_SITE_DIR})
INSTALL ( TARGETS _iec61850 LIBRARY DESTINATION ${PYTHON_SITE_DIR})
add_test(test_pyiec61850 ${PYTHON_EXECUTABLE} test_pyiec61850.py)

@ -0,0 +1,41 @@
/* File : iec61850.i */
%module iec61850
%ignore ControlObjectClient_setTestMode(ControlObjectClient self);
%ignore CDA_OperBoolean(ModelNode* parent, bool isTImeActivated);
%ignore LogicalNode_hasBufferedReports(LogicalNode* node);
%ignore LogicalNode_hasUnbufferedReports(LogicalNode* node);
%ignore MmsConnection_setIsoConnectionParameters(MmsConnection self, IsoConnectionParameters* params);
%include "stdint.i"
%{
#include <iec61850_client.h>
#include <iec61850_model.h>
#include <iec61850_server.h>
ModelNode* toModelNode(LogicalNode * ln)
{
return (ModelNode*) ln;
}
ModelNode* toModelNode(DataObject * DO)
{
return (ModelNode*) DO;
}
DataAttribute* toDataAttribute(DataObject * DO)
{ return (DataAttribute*)DO;}
DataAttribute* toDataAttribute(ModelNode * MN)
{ return (DataAttribute*)MN;}
%}
%apply int *OUTPUT {IedClientError* error};
%include "iec61850_client.h"
%include "iso_connection_parameters.h"
%include "mms_client_connection.h"
%include "iso_connection_parameters.h"
%include "iec61850_common.h"
%include "mms_value.h"
%include "iec61850_model.h"
%include "iec61850_server.h"
%include "iec61850_dynamic_model.h"
%include "iec61850_cdc.h"
ModelNode* toModelNode(LogicalNode *);
ModelNode* toModelNode(DataObject *);
DataAttribute* toDataAttribute(DataObject *);
DataAttribute* toDataAttribute(ModelNode *);

@ -0,0 +1,82 @@
#!/usr/bin/python
import sys
import time
import iec61850
import threading
import traceback
import signal
import sys
def signal_handler(signal, frame):
global running
running =0
print('You pressed Ctrl+C!')
#sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
tcpPort = 8102
running = 1
class myIECServer():
def __init__(self):
self.__model = iec61850.IedModel_create("testmodel")
lDevice1 = iec61850.LogicalDevice_create("SENSORS", self.__model);
lln0 = iec61850.LogicalNode_create("LLN0", lDevice1);
ttmp1 = iec61850.LogicalNode_create("TTMP1", lDevice1);
iec61850.CDC_SAV_create("TmpSv", iec61850.toModelNode(ttmp1), 0, False)
iec61850.CDC_ASG_create("TmpSp", iec61850.toModelNode(ttmp1), 0, False)
self.__iedServer = iec61850.IedServer_create(self.__model)
iec61850.IedServer_start(self.__iedServer, tcpPort);
if not(iec61850.IedServer_isRunning(self.__iedServer)) :
print("Starting server failed! Exit.\n")
iec61850.IedServer_destroy(self.__iedServer)
sys.exit(-1)
def run(self):
global running
while running:
time.sleep(0.1)
self.stop()
def stop(self):
iec61850.IedServer_stop(self.__iedServer)
iec61850.IedServer_destroy(self.__iedServer)
iec61850.IedModel_destroy(self.__model)
def testClient():
con = iec61850.IedConnection_create()
error = iec61850.IedConnection_connect(con, "localhost", tcpPort)
if (error == iec61850.IED_ERROR_OK):
# Accessing to SAV values
theVal = "testmodelSENSORS/TTMP1.TmpSv.instMag.f"
theValType = iec61850.IEC61850_FC_MX
temperatureValue = iec61850.IedConnection_readFloatValue(con, theVal, theValType)
assert(temperatureValue[1]==0)
newValue= temperatureValue[0]+10
err = iec61850.IedConnection_writeFloatValue(con, theVal, theValType, newValue)
assert(err==21)
# Accessing to ASG values
theVal = "testmodelSENSORS/TTMP1.TmpSp.setMag.f"
theValType = iec61850.IEC61850_FC_SP
temperatureSetpoint = iec61850.IedConnection_readFloatValue(con, theVal, theValType)
print temperatureSetpoint
assert(temperatureValue[1]==0)
newValue= temperatureValue[0]+10
err = iec61850.IedConnection_writeFloatValue(con, theVal, theValType, newValue)
assert(err==0)
temperatureSetpoint = iec61850.IedConnection_readFloatValue(con, theVal, theValType)
print temperatureSetpoint
assert(temperatureSetpoint[0]==newValue)
iec61850.IedConnection_close(con)
else:
print "Connection error"
sys.exit(-1)
iec61850.IedConnection_destroy(con)
print "client ok"
try:
srv=myIECServer()
srvThread = threading.Thread(target = srv.run)
srvThread.start()
testClient()
running = 0
#signal.pause()
except:
running = 0
print "Error :"
traceback.print_exc(file=sys.stdout)
sys.exit(-1)
Loading…
Cancel
Save