当前位置: 首页 > wzjs >正文

网站开发与维护价格网站开发合同 保密条款

网站开发与维护价格,网站开发合同 保密条款,天津网站建设网站,在线设计网站源码专栏文章目录 第一章 IEC 61850标准协议解读 0.导言 第二章 IEC 61850标准协议解读 1.建模讲解 第三章 IEC 61850标准协议解读 2.基于Java的MMS实现 目录 专栏文章目录前言1 依赖库引入2 创建服务端3 创建客户端4 读写模型4.1 服务端读写4.2 客户端读写 5.报告6 文件服务6.1 读…

专栏文章目录

第一章 IEC 61850标准协议解读 0.导言
第二章 IEC 61850标准协议解读 1.建模讲解
第三章 IEC 61850标准协议解读 2.基于Java的MMS实现


目录

  • 专栏文章目录
  • 前言
  • 1 依赖库引入
  • 2 创建服务端
  • 3 创建客户端
  • 4 读写模型
    • 4.1 服务端读写
    • 4.2 客户端读写
  • 5.报告
  • 6 文件服务
    • 6.1 读取文件目录
    • 6.2 读取文件内容
    • 6.3 删除文件
    • 6.4 上传(写)文件(建设中)
  • 7 Goose服务(建设中)
  • 附录&参考资料

前言

1 依赖库引入

这个依赖库起先于beanit/iec61850bean,博主在使用过程中,有一些问题(没有文件服务、对接南瑞的1.0客户端测试软件有问题、模型中枚举类型索引和code不能同时支持等),所以修复这些问题并发布到了maven的中央仓库。有兴趣的小伙伴欢迎参与建设,提交pr和issues

<!-- https://github.com/mujave/iec61850bean -->
<dependency><groupId>com.github.mujave</groupId><artifactId>iec61850bean</artifactId><version>1.9.1.11</version>
</dependency>

2 创建服务端

public class SimpleServerClientTest{private static final Logger log = LoggerFactory.getLogger(SimpleServerClientTest.class);private static final int PORT = 102;private static final String ICD_FILE = "src/test/resources/simple-test.icd";//服务端能力对象private ServerSap serverSap;//模型文件能力对象private ServerModel serverModel;private void startServer() throws SclParseException, IOException {//从本地加载一个icd文件,并在102端口暴漏一个mms服务端serverSap = new ServerSap(PORT, 0, null, SclParser.parse(ICD_FILE).get(0), null);this.serverModel = this.serverSap.getModelCopy();}
}

3 创建客户端

public class SimpleServerClientTest implements ClientEventListener{private static final Logger log = LoggerFactory.getLogger(SimpleServerClientTest.class);ClientAssociation clientAssociation;private ServerModel clientModel;private void startClient() throws IOException, ServiceError {//创建客户端能力对象ClientSap clientSap = new ClientSap();//与服务端建立连接this.clientAssociation =clientSap.associate(InetAddress.getByName("localhost"), PORT, "", this);//获取模型文件能力对象this.clientModel = this.clientAssociation.retrieveModel();// 客户端也可以离线的方式读取本地的模型文件//this.clientModel = SclParser.parse(ICD_FILE).get(0);}@Overridepublic void newReport(Report report) {// 这一部分在5章节详细说明}@Overridepublic void associationClosed(IOException e) {log.error("Iec61850 mms server has closed");}
}

4 读写模型

4.1 服务端读写

 public void testSetValueForServer() throws IOException, ServiceError, InterruptedException {List<BasicDataAttribute> writeList = CollUtil.newArrayList();//通过模型中DA的引用名称找到对应的对象BdaBoolean v1 = (BdaBoolean) serverModel.findModelNode("FKMONT/GGIO1.Ind1.stVal", Fc.ST);//设置对应要写入的值v1.setValue(false);//将DA加入到待写入集合中writeList.add(v1);BdaFloat32 v2 = (BdaFloat32) serverModel.findModelNode("FKMONT/GGIO2.AnInd1.mag.f", Fc.MX);//读取模型该节点的当前值System.out.println(v2.getFloat().floatValue());v2.setFloat(1.2f);writeList.add(v2);//服务端通过服务端能力对象将数据集写入到模型serverSap.setValues(writeList);
}

4.2 客户端读写

public void testSetValueForClient() throws IOException, ServiceError, InterruptedException {BdaBoolean v1 = (BdaBoolean) clientModel.findModelNode("FKMONT/GGIO1.Ind1.stVal", Fc.ST);System.out.println(v1.getValue()); //falseBdaFloat32 v2 = (BdaFloat32) clientModel.findModelNode("FKMONT/GGIO2.AnInd1.mag.f", Fc.MX);System.out.println(v2.getFloat());//0.0// 调用4.1的方法模拟服务端数据变化testSetValueForServer();//通过客户端能力对象读取服务端模型中的最新数据clientAssociation.getDataValues(v1); System.out.println(v1.getValue());//trueclientAssociation.getDataValues(v2);System.out.println(v2.getFloat().floatValue()); //1.2
}

5.报告

在上一篇博客在3.3.3部分里介绍到关于报告的模型定义,这里我在复制一下

<LN0 inst="" lnClass="LLN0" lnType="GEXIN_LLN0"><!-- 数据集:顾名思义就是数对对象的集合,定义数据集之后,使用 ReportControl报告定义这些数据发生变动时发送报告FCDA 各属性ldInst:逻辑设备实例名称lnClass:逻辑节点类型 lnInst:逻辑节点实例号 对应DO的name.目前国内规范一般按照遥信、遥测分为两各数据集,一个报告遥测量浮点型,一个报告遥信量布尔型--><DataSet name="ds01Din" desc="遥信单点信息数据集(含可控点)"><FCDA doName="Ind1" fc="ST" ldInst="MONT" lnClass="GGIO" lnInst="1"/><FCDA doName="Ind1" fc="ST" ldInst="MONT" lnClass="GGIO" lnInst="3"/></DataSet><!-- 引用ds01Din数据集--><ReportControl bufTime="0" buffered="false" confRev="1" datSet="ds01Din" intgPd="30000" name="brcb01Din" rptID="MONT/LLN0$BR$brcb01Din"><!-- 其中数据对象的dchg、qchg当数据变化、品质变化时都触发报告进行上送 --><TrgOps dchg="true" dupd="true" period="false" qchg="true"/><OptFields dataSet="true" entryID="true" reasonCode="true" seqNum="true" timeStamp="true"/><!-- max属性是IED可以支持的报告实例个数。IED初始化时为每个报告生成max个实例,分别以报告控制块名+实例号(01,02...)进行区分,如brcb01DinO1、brcb01Din02。每个client在连接时以不同的报告实例号占用一个报告实例。每个报告实例按照client指定的属性上送报告--><RptEnabled max="5"/></ReportControl>
</LN0>
@Test
public void reportEnableTest() throws ServiceError, IOException {HashSet<Object> enableReportNamees = new HashSet<>();Collection<Urcb> urcbs = this.clientModel.getUrcbs();for (Urcb urcb : urcbs) {clientAssociation.getRcbValues(urcb);String rptId = urcb.getRptId().getStringValue();log.info("1.{}(rptID:{}) {}", urcb.getName(), rptId, urcb.getRptEna().getValue());if (!enableReportNamees.contains(rptId)) {// 同一个rptId开启一次报告使能就可以clientAssociation.enableReporting(urcb);enableReportNamees.add(rptId);}}for (Urcb urcb : urcbs) {clientAssociation.getRcbValues(urcb);log.info("2.{}(rptID:{}) {}", urcb.getName(), urcb.getRptId().getStringValue(), urcb.getRptEna().getValue());}}

输出打印如下:

1.brcb01Din05(rptID:MONT/LLN0$BR$brcb01Din) false
1.brcb01Din02(rptID:MONT/LLN0$BR$brcb01Din) false
1.brcb01Din01(rptID:MONT/LLN0$BR$brcb01Din) false
1.brcb01Din04(rptID:MONT/LLN0$BR$brcb01Din) false
1.brcb01Din03(rptID:MONT/LLN0$BR$brcb01Din) false2.brcb01Din05(rptID:MONT/LLN0$BR$brcb01Din) true
2.brcb01Din02(rptID:MONT/LLN0$BR$brcb01Din) false
2.brcb01Din01(rptID:MONT/LLN0$BR$brcb01Din) false
2.brcb01Din04(rptID:MONT/LLN0$BR$brcb01Din) false
2.brcb01Din03(rptID:MONT/LLN0$BR$brcb01Din) false

开启报告使能之后,对应数据集的数据在服务端变更时(或者开启周期发送后)客户端就会收到报告了,这里你的客户端需要实现一下ClientEventListener接口,在newReport方法中就会有回调数据过来了,这里就不再赘述,打印进行解析就可以了

@Test
public void reportTest() throws ServiceError, IOException, InterruptedException {//让客户端开启报告reportEnableTest();//调用服务端发送数据testSetValueForServer();
}@Override
public void newReport(Report report) {System.out.println("got a report.");System.out.println(report);
}

输出打印如下:

got a report.
Report ID: MONT/LLN0$BR$brcb01Din
Data set reference: FKMONT/LLN0.ds01Din
Sequence number: 0
Time of entry (unix timestamp): 1745846525390
Reported data set members:
FKMONT/GGIO1.Ind1 [ST]
FKMONT/GGIO1.Ind1.stVal: false
FKMONT/GGIO1.Ind1.q: 0000
FKMONT/GGIO1.Ind1.t: 1970-01-01T00:00:00Z, reason: data-change

6 文件服务

文件服务在原本的beanit/iec61850bean中,仅支持客户端的实现,如果你是服务端的话,需要换成我在文章开头的pom,因为我修改了源码,使其服务端支持了文件(目录)读取的能力。
服务端实现的时候,需要在服务端启动之后设置文件服务的根路径,具体以代码如下

//客户端读取到的所有文件内容都是基于这个路径下的,如果不设置的话,就是程序的启动目录
serverSap.setFileServiceParentPath("/home/test");
//客户端读取目录时,是否上报子文件夹,如果设置false,则仅上报根目录下的文件
serverSap.setReportFileDirectory(false);

6.1 读取文件目录

@Test
public void testGetFileDirectory() throws IOException, ServiceError, InterruptedException {List<FileInformation> fileDirectory = this.clientAssociation.getFileDirectory("COMTRADE");int i = 0;for (FileInformation fileInformation : fileDirectory) {log.info("{} - {} sizeof: {} {}", ++i, fileInformation.getFilename(), fileInformation.getFileSize(),DateUtil.formatDateTime(fileInformation.getLastModified().getTime()));}
}

6.2 读取文件内容

@Test
public void testGetFile() throws IOException, ServiceError, InterruptedException {this.clientAssociation.getFile("/chart.txt", (byte[] fileData, boolean moreFollows) -> {log.info("Received {} bytes of file data. More data follows: {}", fileData.length, moreFollows);//这里直接进行保存,可以使用追加方式写文件log.info("\n{}", new String(fileData));return moreFollows;});
}

6.3 删除文件

@Test
public void testDeleteFile() throws ServiceError, IOException {this.clientAssociation.deleteFile("要删除的文件名字");
}

6.4 上传(写)文件(建设中)

客户端写文件到服务端正在开发中,预计在2025.05月底完成,持续更新

7 Goose服务(建设中)

客户端写文件到服务端正在开发中,预计在2025.07月底完成,持续更新


附录&参考资料

暂无,更新中


文章转载自:

http://HdG7EBzA.fbbpj.cn
http://BlXb9TyW.fbbpj.cn
http://W4cnRjzB.fbbpj.cn
http://xEgvauEy.fbbpj.cn
http://N7PYOOdb.fbbpj.cn
http://cEVC81Xm.fbbpj.cn
http://iuVA2gfi.fbbpj.cn
http://UsMIU1KV.fbbpj.cn
http://hk9o3Zq5.fbbpj.cn
http://PjOk7quq.fbbpj.cn
http://5Yheiug4.fbbpj.cn
http://FSVqqjn1.fbbpj.cn
http://et9dvDsf.fbbpj.cn
http://gKJoimAW.fbbpj.cn
http://S3DrRAeC.fbbpj.cn
http://DvXyRUG1.fbbpj.cn
http://X7YNJhCf.fbbpj.cn
http://6BM3OHS8.fbbpj.cn
http://AN9Digdg.fbbpj.cn
http://R4JXQ7LQ.fbbpj.cn
http://e8rvnSPZ.fbbpj.cn
http://T1WXOP0D.fbbpj.cn
http://o0qRqHd9.fbbpj.cn
http://rAoqBzCO.fbbpj.cn
http://qxsIbbsL.fbbpj.cn
http://c0aG1RUz.fbbpj.cn
http://cv4AGIGP.fbbpj.cn
http://YfaDqLLZ.fbbpj.cn
http://RLCpTPHT.fbbpj.cn
http://pPn2IC0R.fbbpj.cn
http://www.dtcms.com/wzjs/679346.html

相关文章:

  • 旅游网站开发近五年参考文献网页游戏烈焰传奇
  • 黄冈网站建设费用做业务一般要注册哪些网站
  • s什么网站可以接单做设计赚钱海南综合网站
  • 湛江城乡建设网站安阳网站建设哪家便宜
  • 免费文案素材网站石家庄正定网站建设
  • 网站漏扫wordpress图片上传到哪里
  • 动易网站 修改栏目名字桂林网络公司有哪些
  • 大连模板网站制作公司西安网站建设维护
  • sem算网站设计吗怎么推广自己做的网站吗
  • 织梦响应式网站怎么做如何让网站快照新
  • 手机公司网站建设比较好的4399页游网站
  • 酒店网站程序房地产信息管理系统软件
  • 南京网站建设网学习软件app
  • 邵阳高端网站建设办一家建筑公司流程
  • 网站开发工程师绩效考核外贸网站推广计划
  • 网站快照描述中山专业制作网站
  • 不孕不育网站建设总结建网站英语怎么说
  • 大作业网站建设方案应用开发工程师
  • 开发大型网站的最主流语言上街郑州网站建设
  • 南京做网站南京乐识好别人的域名解析到了我的网站上
  • 济阳县做网站公司做视频up主视频网站
  • 如何找网站制作北京建设信源官方网站
  • 购物网站英语泉州网站优化排名推广
  • 网站域名后缀那个好门户网站建设和运行保障招标文件
  • 网站建设私活千万别自学软件编程
  • 网站域名需要申请桐乡 网站建设
  • 网站分页网站改版升级
  • 广州网站seo推广广东省建设职业注册中心网站
  • 深圳外贸网站建设设计公司网站培训
  • 北京网站建设++知乎不能上传图片到网站