Bacnet4J订阅COV报文


前言

因为公司项目需求要对接bacnet协议的设备,参考网上的一些文章对比下来决定使用bacnet4j进行java开发。老实说目前国内关于bacnet的文章蛮少的,所以我就来贡献一篇关于COV事件报文订阅的文章,其他事件的订阅其实也大同小异了。


一、Bacnet4J

GitHub上的bacnet4j项目包源码
我下面的内容基本上是参考他的测试代码写的,大家有兴趣可以多去研究研究源码。

二、使用步骤

1.Bacnet4J

Maven配置

<repositories>
   <repository>
        <releases>
            <enabled>false</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <id>ias-snapshots</id>
        <name>Infinite Automation Snapshot Repository</name>
        <url>https://maven.mangoautomation.net/repository/ias-snapshot/</url>
    </repository>
    <repository>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
        <id>ias-releases</id>
        <name>Infinite Automation Release Repository</name>
        <url>https://maven.mangoautomation.net/repository/ias-release/</url>
    </repository>
</repositories>
<dependencies>
	<dependency>
	     <groupId>com.infiniteautomation</groupId>
	     <artifactId>bacnet4j</artifactId>
	     <version>5.0.2</version>
	 </dependency>
</dependencies>

2.实例代码

主线程代码:

package BACnet;

import BACnet.listener.CovNotifListener;
import com.serotonin.bacnet4j.LocalDevice;
import com.serotonin.bacnet4j.RemoteDevice;
import com.serotonin.bacnet4j.npdu.ip.IpNetwork;
import com.serotonin.bacnet4j.npdu.ip.IpNetworkBuilder;
import com.serotonin.bacnet4j.service.confirmed.SubscribeCOVRequest;
import com.serotonin.bacnet4j.transport.DefaultTransport;
import com.serotonin.bacnet4j.type.enumerated.ObjectType;
import com.serotonin.bacnet4j.type.primitive.Boolean;
import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
import com.serotonin.bacnet4j.type.primitive.Real;
import com.serotonin.bacnet4j.type.primitive.UnsignedInteger;
import com.serotonin.bacnet4j.util.RequestUtils;

/**
 * @author BoringDragon
 * @date 2021-08-20
 */
public class BacnetCovSubscribe {
    public static void main(String[] args) {
        LocalDevice d = null;
        try {
        	//根据自己的实际IP地址进行配置
            IpNetwork ipNetwork = new IpNetworkBuilder()
                    .withLocalBindAddress("127.0.0.1")
                    .withSubnet("255.255.255.0", 24)
                    .withPort(47808)
                    .withReuseAddress(true)
                    .build();
            //deviceNumber 是在本地创建一个虚拟的设备进行通信,这个只要在本地不重复就可以随意写
            d = new LocalDevice(10000, new DefaultTransport(ipNetwork));
            //初始化设备
            d.initialize();
            //添加监听器
            d.getEventHandler().addListener(new CovNotifListener());
            //发送WhoIs请求网段的远端设备
            d.startRemoteDeviceDiscovery();
            //根据远端设备id获取远程设备
            RemoteDevice rd = d.getRemoteDevice(1605654).get();
            //发送订阅COV报文 对应为订阅标识(不可为0),订阅对象,是否要发送确认报文,订阅时长(0为永久)
            d.send(rd, new SubscribeCOVRequest(new UnsignedInteger(4), new ObjectIdentifier(ObjectType.analogValue, 0), Boolean.TRUE,
                    new UnsignedInteger(0))).get();
            while (true){
                //修改值为77
                RequestUtils.writePresentValue(d, rd, new ObjectIdentifier(ObjectType.analogValue, 0), new Real(77));
                Thread.sleep(2000);
            }
        } catch (Exception e) {
            e.printStackTrace();
            if(d != null){
                d.terminate();
            }
        }
    }
}

监听器代码:

package BACnet.listener;

import com.serotonin.bacnet4j.event.DeviceEventAdapter;
import com.serotonin.bacnet4j.type.constructed.PropertyValue;
import com.serotonin.bacnet4j.type.constructed.SequenceOf;
import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
import com.serotonin.bacnet4j.type.primitive.UnsignedInteger;
/**
 * @author BoringDragon
 * @date 2021-08-20
 */
public class CovNotifListener extends DeviceEventAdapter {
    @Override
    public void covNotificationReceived(final UnsignedInteger subscriberProcessIdentifier,
                                        final ObjectIdentifier initiatingDevice, final ObjectIdentifier monitoredObjectIdentifier,
                                        final UnsignedInteger timeRemaining, final SequenceOf<PropertyValue> listOfValues) {
        System.out.println("======================= Receive COV =======================");
        System.out.println("======================= subscriberProcessIdentifier =======================");
        System.out.println(subscriberProcessIdentifier);
        System.out.println("======================= initiatingDevice =======================");
        System.out.println(initiatingDevice);
        System.out.println("======================= monitoredObjectIdentifier =======================");
        System.out.println(monitoredObjectIdentifier);
        System.out.println("======================= timeRemaining =======================");
        System.out.println(timeRemaining);
        System.out.println("======================= listOfValues =======================");
        System.out.println(listOfValues);
        System.out.println(listOfValues.get(0).getValue());
        System.out.println("===========================================================");
    }
}

使用的模拟设备工具为Yabe的Bacnet.Room.Simulator,下图两个红框从上到下分别为我上面代码订阅的温度和设备id在这里插入图片描述


总结

结果如下图,因为没有设置OutOfService为false所以改值后会变回21.0
在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值