零基础实现IEC61850(二)数据更新

数据更新及接口

IEC61850将电力装置抽象为服务及数据模型,就好像盖了一个IEC61850的大厦,大厦里有楼层有房间,房间里放着数据,例如储能设备某电芯的电压就在IEC61850的大厦的某个房间中存放,如何将测量到的电压写到对应的房间呢?这就用到了YX-PIS的数据更新接口。
YX-PIS目前提供了五个数据更新接口,本文介绍如下四个接口
IEC61850_UpdateWithReference()
IEC61850_UpdateWithShortAddr()
IEC61850_Update()
IEC61850_UpdateWithQT()
还有一个批量更新的接口是需要通过控制块进行更新数据,本文暂不介绍,接口名称如下:
IEC61850_BatchUpdateControlBlockDatas()

先做一些改进

本文承接上一文的代码进行,为了方便先做一些调整

调整环境变量

环境变量Path中添加动态库目录,这样就不用将dll拷贝到可执行文件目录了
在这里插入图片描述

调整CID文件位置

在项目目录中新建cidFiles目录,将cid文件从可执行文件目录拷贝到这个目录
加载cid部分的代码调整如下:

error = IEC61850_LoadSCLFile(g_iec61850, "../../../cidFiles/testIED.cid");

调整CMakeList

为了使得MMS和CMS的切换更方便,调整后如下:

cmake_minimum_required (VERSION 3.8)

project ("iec61850server")

set(COMMUNICATION_PROTOCOL "MMS")     # 设置MMS或者CMS

if(COMMUNICATION_PROTOCOL STREQUAL "MMS")
include_directories("yx-pis-dll/mms/include")
link_directories(${CMAKE_SOURCE_DIR}/yx-pis-dll/mms)
#target_link_libraries(iec61850server mms-ctk)
elseif(COMMUNICATION_PROTOCOL STREQUAL "CMS")
include_directories("yx-pis-dll/cms/include")
link_directories(${CMAKE_SOURCE_DIR}/yx-pis-dll/cms)
#target_link_libraries(iec61850server cms-ctk)
endif()

add_executable (iec61850server "iec61850server.c" "IEC61850Functions.c")

if(COMMUNICATION_PROTOCOL STREQUAL "MMS")
target_link_libraries(iec61850server mms-ctk)
elseif(COMMUNICATION_PROTOCOL STREQUAL "CMS")
target_link_libraries(iec61850server cms-ctk)
endif()

建立好大厦的房间

通过建模工具打开模型文件testIED.cid文件,添加一个逻辑节点,相当于给大厦加盖一层楼
在这里插入图片描述
然后选择逻辑节点类
在这里插入图片描述
选择需要添加的数据
在这里插入图片描述
保存后效果如图:
在这里插入图片描述
那么这个数据i的引用我们可以看到是TEMPLATELDevice1/MMXU0.A.phsA.cVal.mag.i,这里面TEMPLATELDevice1是逻辑设备名称,由于我未设置逻辑设备名,所以采用IED名称+逻辑设备实例代替逻辑设备名。
保存这个模型后启动服务端,MMS通过iedscout读取,如图:
在这里插入图片描述
CMS通过cms-test-tool获取模型,如图:
在这里插入图片描述

添加源码文件

准备添加一个源码文件,专门用于一些函数调用的
在这里插入图片描述
改名为IEC61850Functions.c
在这里插入图片描述
同样方法增加IEC61850Functions.h文件

IEC61850Functions.h中增加代码

#pragma once

#include <stdio.h>
#include "IEC61850Types.h"
#include "IEC61850API.h"
#include "sysctype.h"

IEC61850Functions.c中增加代码

#include "IEC61850Functions.h"

extern IEC61850 g_iec61850;

iec61850server.c中

#include "IEC61850Types.h"
#include "IEC61850API.h"
#include "sysctype.h"

替换为

#include "IEC61850Functions.h"

通过引用更新

在IEC61850Functions.h增加函数原型IEC61850_ErrorCode UpdateMMXUPhsAMagi()
在IEC61850Functions.h增加函数定义

IEC61850_ErrorCode UpdateMMXUPhsAMagi()
{
	IEC61850_ErrorCode result = S_OK;
	S32 newVal = 0;
	IEC61850_DataAttributeData daData = { 0 };
	char* reference = "TEMPLATELDevice1/MMXU0.A.phsA.cVal.mag.i";

	printf("Enter an S32 value: ");
	scanf("%d", &newVal);

	daData.bitLength = sizeof(S32) * 8; 
	daData.type = IEC61850_DATATYPE_INT32;	  
	daData.pvData = &newVal;	

	result = IEC61850_UpdateWithReference(g_iec61850, reference, &daData);
}

iec61850server.c中main函数中getchar()之前调用该函数,调试运行程序按提示输入整数,例如12345,如图:
在这里插入图片描述
然后通过工具,读取当前值,MMS版如下图:
在这里插入图片描述
CMS版如下图:
在这里插入图片描述
说明数据更新成功。

通过短地址更新

再调整一下模型

在这里插入图片描述
在这里插入图片描述
按下图设置短地址
在这里插入图片描述
假设输入 B.i 然后保存

编码

在IEC61850Functions.h增加函数原型IEC61850_ErrorCode UpdateMMXUPhsBMagi()
在IEC61850Functions.h增加函数定义

IEC61850_ErrorCode UpdateMMXUPhsBMagi()
{
	IEC61850_ErrorCode result = S_OK;
	S32 newVal = 0;
	IEC61850_DataAttributeData daData = { 0 };
	char* sAddr = "B.i";

	printf("Enter an S32 value: ");
	scanf("%d", &newVal);

	daData.bitLength = sizeof(S32) * 8;
	daData.type = IEC61850_DATATYPE_INT32;
	daData.pvData = &newVal;

	result = IEC61850_UpdateWithShortAddr(g_iec61850, &sAddr, &daData, 1);
}

调用本函数并运行,输入整数,例如67890
在这里插入图片描述
MMS版本查询如图:
在这里插入图片描述
CMS版本查询截图略

通过DAID更新

在模型中添加DAID
在这里插入图片描述
在IEC61850Functions.h增加函数原型IEC61850_ErrorCode UpdateMMXUPhsCMagi()
在IEC61850Functions.h增加函数定义

IEC61850_ErrorCode UpdateMMXUPhsCMagi()
{
	IEC61850_ErrorCode result = S_OK;
	S32 newVal = 0;
	IEC61850_DataAttributeID daid = { 1, 0, 0, 0, 0 };
	IEC61850_DataAttributeData daData = { 0 };

	printf("Enter an S32 value: ");
	scanf("%d", &newVal);

	daData.bitLength = sizeof(S32) * 8;
	daData.type = IEC61850_DATATYPE_INT32;
	daData.pvData = &newVal;

	result = IEC61850_Update(g_iec61850, &daid, &daData, 1);
}

调用本函数并运行,输入整数,例如45678
在这里插入图片描述
MMS版本查询如图:
在这里插入图片描述
CMS版本查询截图略

更新数据及质量和时间

IEC61850_UpdateWithQT接口支持引用、短地址、DAID三种方式,本次以DAID为例
在IEC61850Functions.h增加函数原型IEC61850_ErrorCode UpdateMMXUPhsCMagiWithQT()
在IEC61850Functions.h增加函数定义

IEC61850_ErrorCode UpdateMMXUPhsCMagiWithQT()
{
	IEC61850_ErrorCode result = S_OK;
	S32 newVal = 0;
	IEC61850_DataAttributeID daid = { 1, 0, 0, 0, 0 };
	IEC61850_DataAttributeDataQT daData = { 0 };
	tIEC61850Quality q = IEC61850_QUALITY_FAILURE;
	IEC61850_TimeStamp t = { 0 };
	IEC61850_DataMapMode mapMode = IEC61850_MAP_MODE_DAID;

	printf("Enter an S32 value: ");
	scanf("%d", &newVal);

	IEC61850_GetTime(NULL, &t);

	daData.dataVal.bitLength = sizeof(S32) * 8;
	daData.dataVal.type = IEC61850_DATATYPE_INT32;
	daData.dataVal.pvData = &newVal;
	daData.q = &q;
	daData.t = &t;

	result = IEC61850_UpdateWithQT(g_iec61850, &daid, &daData, 1, mapMode);
}

调用该函数运行,输入整数,例如123
在这里插入图片描述
MMS版本查询如图:
在这里插入图片描述
可以看到出了数值123,质量和时间也同步得到了更新
CMS版查询截图略

IEC61850Functions.c中全部代码

#include "IEC61850Functions.h"

extern IEC61850 g_iec61850;

//采用引用方式更新A.PhsA数据
IEC61850_ErrorCode UpdateMMXUPhsAMagi()
{
	IEC61850_ErrorCode result = S_OK;
	S32 newVal = 0;
	IEC61850_DataAttributeData daData = { 0 };
	char* reference = "TEMPLATELDevice1/MMXU0.A.phsA.cVal.mag.i";

	printf("Enter an S32 value: ");
	scanf("%d", &newVal);

	daData.bitLength = sizeof(S32) * 8; 
	daData.type = IEC61850_DATATYPE_INT32;	  
	daData.pvData = &newVal;	

	result = IEC61850_UpdateWithReference(g_iec61850, reference, &daData);
}
//采用短地址方式更新A.PhsB数据
IEC61850_ErrorCode UpdateMMXUPhsBMagi()
{
	IEC61850_ErrorCode result = S_OK;
	S32 newVal = 0;
	IEC61850_DataAttributeData daData = { 0 };
	char* sAddr = "B.i";

	printf("Enter an S32 value: ");
	scanf("%d", &newVal);

	daData.bitLength = sizeof(S32) * 8;
	daData.type = IEC61850_DATATYPE_INT32;
	daData.pvData = &newVal;

	result = IEC61850_UpdateWithShortAddr(g_iec61850, &sAddr, &daData, 1);
}
//采用DAID方式更新A.PhsC数据
IEC61850_ErrorCode UpdateMMXUPhsCMagi()
{
	IEC61850_ErrorCode result = S_OK;
	S32 newVal = 0;
	IEC61850_DataAttributeID daid = { 1, 0, 0, 0, 0 };
	IEC61850_DataAttributeData daData = { 0 };

	printf("Enter an S32 value: ");
	scanf("%d", &newVal);

	daData.bitLength = sizeof(S32) * 8;
	daData.type = IEC61850_DATATYPE_INT32;
	daData.pvData = &newVal;

	result = IEC61850_Update(g_iec61850, &daid, &daData, 1);
}
//采用DAID方式更新A.PhsC数据,并同步更新质量和时间
IEC61850_ErrorCode UpdateMMXUPhsCMagiWithQT()
{
	IEC61850_ErrorCode result = S_OK;
	S32 newVal = 0;
	IEC61850_DataAttributeID daid = { 1, 0, 0, 0, 0 };
	IEC61850_DataAttributeDataQT daData = { 0 };
	tIEC61850Quality q = IEC61850_QUALITY_FAILURE;
	IEC61850_TimeStamp t = { 0 };
	IEC61850_DataMapMode mapMode = IEC61850_MAP_MODE_DAID;

	printf("Enter an S32 value: ");
	scanf("%d", &newVal);

	IEC61850_GetTime(NULL, &t);

	daData.dataVal.bitLength = sizeof(S32) * 8;
	daData.dataVal.type = IEC61850_DATATYPE_INT32;
	daData.dataVal.pvData = &newVal;
	daData.q = &q;
	daData.t = &t;

	result = IEC61850_UpdateWithQT(g_iec61850, &daid, &daData, 1, mapMode);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值