Merge branch 'python-bindings'

pull/6/head
Michael Zillgith 9 years ago
commit 6c306870e9

@ -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)
@ -102,11 +104,11 @@ set(API_HEADERS
src/sampled_values/sv_publisher.h
)
IF(WIN32)
IF(MSVC)
include_directories(
src/vs
)
ENDIF(WIN32)
ENDIF(MSVC)
# write the detected stuff to this file
configure_file(config/stack_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config/stack_config.h)
@ -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")

@ -137,11 +137,11 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void ControlObjectClient_setOrigin(IntPtr self, string orIdent, int orCat);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void ControlObjectClient_enableInterlockCheck(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void ControlObjectClient_setInterlockCheck(IntPtr self, bool value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void ControlObjectClient_enableSynchroCheck(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void ControlObjectClient_setSynchroCheck(IntPtr self, bool value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalCommandTerminationHandler(IntPtr parameter,IntPtr controlClient);
@ -373,19 +373,37 @@ namespace IEC61850
/// <summary>
/// Enables the synchro check for operate commands
/// </summary>
[Obsolete("use SetSynchroCheck instead")]
public void EnableSynchroCheck ()
{
ControlObjectClient_enableSynchroCheck(controlObject);
ControlObjectClient_setSynchroCheck (controlObject, true);
}
/// <summary>
/// Enables the interlock check for operate and select commands
/// </summary>
public void EnableInterlockCheck ()
[Obsolete("use SetInterlockCheck instead")]
public void EnableInterlockCheck ()
{
ControlObjectClient_enableInterlockCheck(controlObject);
ControlObjectClient_setInterlockCheck (controlObject, true);
}
/// <summary>
/// Sets the value of the interlock check flag for operate and select commands
/// </summary>
public void SetInterlockCheck (bool value)
{
ControlObjectClient_setInterlockCheck (controlObject, value);
}
/// <summary>
/// Sets the value of the synchro check flag for operate command
/// </summary>
public void SetSynchroCheck (bool value)
{
ControlObjectClient_setSynchroCheck (controlObject, value);
}
/// <summary>
/// Gets the last received LastApplError (Additional Cause Diagnostics) value.
/// </summary>

@ -24,7 +24,7 @@ namespace example3
{
IsoConnectionParameters parameters = con.GetConnectionParameters();
parameters.SetRemoteAddresses(1,1, new byte[] {0x00, 0x01, 0x02, 0x03});
parameters.SetRemoteAddresses(1, new byte[] {0x00, 0x01}, new byte[] {0x00, 0x01, 0x02, 0x03});
con.ConnectTimeout = 10000;

@ -3,10 +3,10 @@ set(iec61850_client_example4_SRCS
client_example4.c
)
IF(WIN32)
IF(MSVC)
set_source_files_properties(${iec61850_client_example4_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
ENDIF(MSVC)
add_executable(iec61850_client_example4
${iec61850_client_example4_SRCS}

@ -3,10 +3,10 @@ set(iec61850_client_example_files_SRCS
client_example_files.c
)
IF(WIN32)
IF(MSVC)
set_source_files_properties(${iec61850_client_example_files_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
ENDIF(MSVC)
add_executable(iec61850_client_example_files
${iec61850_client_example_files_SRCS}

@ -3,10 +3,10 @@ set(iec61850_client_example_reporting_SRCS
client_example_reporting.c
)
IF(WIN32)
IF(MSVC)
set_source_files_properties(${iec61850_client_example_reporting_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
ENDIF(MSVC)
add_executable(iec61850_client_example_reporting
${iec61850_client_example_reporting_SRCS}

@ -3,10 +3,10 @@ set(mms_client_example2_SRCS
mms_client_example2.c
)
IF(WIN32)
IF(MSVC)
set_source_files_properties(${mms_client_example2_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
ENDIF(MSVC)
add_executable(mms_client_example2
${mms_client_example2_SRCS}

@ -3,10 +3,10 @@ set(mms_client_example3_SRCS
mms_client_example3.c
)
IF(WIN32)
IF(MSVC)
set_source_files_properties(${mms_client_example3_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
ENDIF(MSVC)
add_executable(mms_client_example3
${mms_client_example3_SRCS}

@ -3,10 +3,10 @@ set(mms_client_example4_SRCS
mms_client_example4.c
)
IF(WIN32)
IF(MSVC)
set_source_files_properties(${mms_client_example4_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
ENDIF(MSVC)
add_executable(mms_client_example4
${mms_client_example4_SRCS}

@ -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)

@ -213,14 +213,18 @@ endif()
set_source_files_properties(${lib_asn1c_SRCS}
PROPERTIES LANGUAGE C)
IF(MSVC)
set_source_files_properties(${lib_common_SRCS} ${lib_windows_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF()
IF(WITH_WPCAP)
IF(MSVC)
set_source_files_properties(${lib_goose_SRCS}
PROPERTIES LANGUAGE CXX)
set_source_files_properties(${lib_sv_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF()
ELSE()
add_definitions(-DEXCLUDE_ETHERNET_WINDOWS)
ENDIF()
@ -311,8 +315,10 @@ IF(UNIX)
)
ENDIF (CONFIG_SYSTEM_HAS_CLOCK_GETTIME)
ENDIF(UNIX)
IF(MINGW)
target_link_libraries(iec61850-shared ws2_32 iphlpapi)
target_link_libraries(iec61850 ws2_32 iphlpapi)
ENDIF(MINGW)
iF(WITH_WPCAP)
target_link_libraries(iec61850
${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/lib/wpcap.lib
@ -330,7 +336,6 @@ if(MSVC)
)
endif()
ELSE(WITH_WPCAP)
if(MSVC)
set_target_properties(iec61850-shared PROPERTIES

@ -848,12 +848,25 @@ ControlObjectClient_enableInterlockCheck(ControlObjectClient self)
self->interlockCheck = true;
}
void
ControlObjectClient_setInterlockCheck(ControlObjectClient self, bool value)
{
self->interlockCheck = value;
}
void
ControlObjectClient_enableSynchroCheck(ControlObjectClient self)
{
self->synchroCheck = true;
}
void
ControlObjectClient_setSynchroCheck(ControlObjectClient self, bool value)
{
self->synchroCheck = value;
}
void
ControlObjectClient_setLastApplError(ControlObjectClient self, LastApplError lastApplError)
{

@ -1510,12 +1510,36 @@ ControlObjectClient_setOrigin(ControlObjectClient self, const char* orIdent, int
void
ControlObjectClient_useConstantT(ControlObjectClient self, bool useConstantT);
/**
* \deprecated use ControlObjectClient_setInterlockCheck instead
*/
void
ControlObjectClient_enableInterlockCheck(ControlObjectClient self);
/**
* \deprecated use ControlObjectClient_setSynchroCheck instead
*/
void
ControlObjectClient_enableSynchroCheck(ControlObjectClient self);
/**
* \brief Set the value of the interlock check flag when a control command is sent
*
* \param self the ControlObjectClient instance
* \param value if true the server will perform a interlock check if supported
*/
void
ControlObjectClient_setInterlockCheck(ControlObjectClient self, bool value);
/**
* \brief Set the value of the synchro check flag when a control command is sent
*
* \param self the ControlObjectClient instance
* \param value if true the server will perform a synchro check if supported
*/
void
ControlObjectClient_setSynchroCheck(ControlObjectClient self, bool value);
/**
* \brief Private a callback handler that is invoked when a command termination message is received.

@ -1,7 +1,7 @@
/*
* mms_client_connection.h
*
* Copyright 2013 Michael Zillgith
* Copyright 2013-2016 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -49,6 +49,7 @@ typedef struct sMmsConnectionParameters {
int maxServOutstandingCalled;
int dataStructureNestingLevel;
int maxPduSize; /* local detail */
uint8_t servicesSupported[11];
} MmsConnectionParameters;
typedef struct {
@ -112,7 +113,7 @@ MmsConnection_setInformationReportHandler(MmsConnection self, MmsInformationRepo
void* parameter);
/**
* \brief Get the connection parameters for an MmsConnection instance
* \brief Get the ISO connection parameters for an MmsConnection instance
*
* \param self MmsConnection instance to operate on
* \return params the to be used by this connection
@ -120,6 +121,15 @@ MmsConnection_setInformationReportHandler(MmsConnection self, MmsInformationRepo
IsoConnectionParameters
MmsConnection_getIsoConnectionParameters(MmsConnection self);
/**
* \brief Get the MMS specific connection parameters for an MmsConnection instance
*
* \param self MmsConnection instance to operate on
* \return params the to be used by this connection
*/
MmsConnectionParameters
MmsConnection_getMmsConnectionParameters(MmsConnection self);
/**
* \brief User provided handler function that will be called if the connection to the server is lost
*

@ -841,6 +841,12 @@ MmsConnection_getIsoConnectionParameters(MmsConnection self)
return self->isoParameters;
}
MmsConnectionParameters
MmsConnection_getMmsConnectionParameters(MmsConnection self)
{
return self->parameters;
}
static void
waitForConnectResponse(MmsConnection self)
{

@ -130,6 +130,11 @@ mmsClient_parseInitiateResponse(MmsConnection self)
self->parameters.maxServOutstandingCalling = initiateResponse->negotiatedMaxServOutstandingCalling;
int i;
for (i = 0; i < 11; i++)
self->parameters.servicesSupported[i] = initiateResponse->mmsInitResponseDetail.servicesSupportedCalled.buf[i];
result = true;
}
else

@ -526,4 +526,6 @@ EXPORTS
MmsValue_setUtcTimeQuality
MmsValue_decodeMmsData
MmsValue_encodeMmsData
ControlObjectClient_setInterlockCheck
ControlObjectClient_setSynchroCheck

@ -600,4 +600,7 @@ EXPORTS
MmsValue_getUtcTimeQuality
MmsValue_decodeMmsData
MmsValue_encodeMmsData
MmsConnection_getMmsConnectionParameters
IedServer_updateVisibleStringAttributeValue
ControlObjectClient_setInterlockCheck
ControlObjectClient_setSynchroCheck

Loading…
Cancel
Save