<Java物联网> 从主动到被动:Java中的BACnet设备属性查询

这篇具有很好参考价值的文章主要介绍了<Java物联网> 从主动到被动:Java中的BACnet设备属性查询。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

BACnet

使用软件

资源

模拟器

使用Java主动查

 引入maven

创建网络对象

获取远程设备

获取设备属性

使用DeviceEventAdapter订阅

初始化本地BACnet设备和IP网络配置:

启动本地设备和添加监听器:

搜寻远程设备:

发送订阅COV报文:

修改值并等待:

SubscribeDevice监听器:


BACnet

BACnet(Building Automation and Control Network)是一种常用于楼宇自动化和控制系统的通信协议,它允许设备在楼宇管理系统中进行相互通信和控制。在Java中进行BACnet物联网操作,我们可以使用BACnet4J库,它是一个用于BACnet通信的Java库。

使用软件

资源

由于是个人学习,所以一般不会有真实硬件可以测试,所以我们还需要准备模拟器。

在这方面,我已经准备好了资源。

链接:https://pan.baidu.com/s/1Pd1cTpOkYZ9p4tbrAUihUg 
提取码:w62j

模拟器

拿其中一个模拟器Yabe来配合这次学习

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询,Java物联网,bacnet,Java物联网,物联网,java

安装好后,我们只需要用到这两个功能即可。

我们点击Simulator功能,会弹出这么一个模拟框。

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询,Java物联网,bacnet,Java物联网,物联网,java

这是模拟一个真实设备温度设备,底下的deviceId则为设备唯一标识。

我们同时打开多台,就可以发现他们的唯一标识不一样。

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询,Java物联网,bacnet,Java物联网,物联网,java

接下来打开Yabe

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询,Java物联网,bacnet,Java物联网,物联网,java

选择Add device,然后输入本机ip地址

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询,Java物联网,bacnet,Java物联网,物联网,java

然后你就会发现,它把我们刚刚打开的两台模拟设备扫描进去了。

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询,Java物联网,bacnet,Java物联网,物联网,java

选中其中一台设备后,下面Address Space会显示几行数据,对某个数据右键选择订阅后,你会发现,我们可以拿到模拟设备中的某个值的实时数据。

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询,Java物联网,bacnet,Java物联网,物联网,java

从而,我们能判断出,哪个属性值对应的是模拟设备中的什么,基于软件对设备的通讯到此就结束了。

重点在于我们如何使用Java来使用BACnet进行设备之间的通讯。

使用Java主动查

 引入maven

在开始示例之前,请确保已经下载并配置了BACnet4J库。

        <!-- https://github.com/infiniteautomation/BACnet4J -->
        <dependency>
            <groupId>com.infiniteautomation</groupId>
            <artifactId>bacnet4j</artifactId>
            <version>6.0.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/bacnet/bacnet4j-6.0.0.jar</systemPath>
        </dependency>
        

通过测试,单引用bacnet4j依赖,是远远不够的。使用起来会报各种异常,

比如

  • slf4j的 NoClassDefFoundError: org/slf4j/LoggerFactory
  • warp的 NoClassDefFoundError: lohbihler/warp/WarpScheduledExecutorService
  • commons的 NoClassDefFoundError: org/apache/commons/lang3/StringUtils

因此还需要引入以下maven依赖

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.32</version> 
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version> 
        </dependency>
        <dependency>
            <groupId>ai.serotonin.oss</groupId>
            <artifactId>sero-scheduler</artifactId>
            <version>1.1.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/ai.serotonin.oss/sero-warp -->
        <dependency>
            <groupId>ai.serotonin.oss</groupId>
            <artifactId>sero-warp</artifactId>
            <version>1.0.0</version>
        </dependency>

创建网络对象

首先获取网段内的模拟设备,

//创建网络对象
IpNetwork ipNetwork = new IpNetworkBuilder()
    //本机的ip
    .withLocalBindAddress("192.168.1.12")
    //掩码和长度,如果不知道本机的掩码和长度的话,可以使用代码的工具类IpNetworkUtils获取
    .withSubnet("255.255.255.0", 24)
    //默认的UDP端口
    .withPort(47808)
    .withReuseAddress(true)
    .build();
//创建虚拟的本地设备,随意设置一个deviceId 设备的唯一标识
LocalDevice localDevice = new LocalDevice(LOCAL_DEVICE_ID, new DefaultTransport(ipNetwork));
//初始化本地设备
localDevice.initialize();
//搜寻网段内远程设备
localDevice.startRemoteDeviceDiscovery();

如果是ubuntu的情况下,建议去掉 withLocalBindAddress("192.168.1.12"),它会默认监听"0.0.0.0"这个地址,达到一样的效果。

跨网段的话,修改withSubnet()方法

获取远程设备

可以使用 LocalDevice 对象来获取远程设备,根据业务来选择以下方法:

//某个远程设备的id
private static final Integer REMOTE_DEVICE_ID = 311400;

//获取某个远程设备,REMOTE_DEVICE_ID是远程设备ID
RemoteDevice remoteDevice = localDevice.getRemoteDeviceBlocking(REMOTE_DEVICE_ID);

//获取所有远程设备
List<RemoteDevice> remoteDevices = localDevice.getRemoteDevices();

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询,Java物联网,bacnet,Java物联网,物联网,java

通过debug得知,获取到的数据没有区别。

获取设备属性

在物联网中,有一个叫物模型的抽象思想,其中有一个概念叫做属性,简单的说,一个温度检测设备里,它的在线离线是一个属性,温度也是一个属性。

接下来我们就去获取这个设备的所有属性。

//获取远程设备的标识符对象
List<ObjectIdentifier> objectList = RequestUtils.getObjectList(localDevice,remoteDevice).getValues();

通过debug可以看到这个属性集合中的数据 

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询,Java物联网,bacnet,Java物联网,物联网,java
是否觉得眼熟呢?是的,他就是对应上面进行订阅步骤的Address Space数据

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询,Java物联网,bacnet,Java物联网,物联网,java

 这里就是它的属性。

通过对比,我们可以知道Analog_Input:0是我们需要的温度属性。

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询,Java物联网,bacnet,Java物联网,物联网,java

 使用Java8获取温度属性对象

List<ObjectIdentifier> filter = objectList.stream().filter(e -> e.getObjectType().equals(ObjectType.analogInput) && e.getInstanceNumber() == 0).collect(Collectors.toList());

然后循环不断的获取该属性值的实时数据

while (true) {
                //根据对象属性标识符的类型进行取值操作 [测试工具模拟的设备点位的属性有objectName、description、present-value等等]
                //analog-input
                PropertyValues pvAiObjectName = readValueByProperty(localDevice, remoteDevice, filter, null, PropertyIdentifier.objectName);
                PropertyValues pvAiPresentValue = readValueByProperty(localDevice, remoteDevice, filter, null, PropertyIdentifier.presentValue);
                PropertyValues pvAiDescription = readValueByProperty(localDevice, remoteDevice, filter, null, PropertyIdentifier.description);
                for (ObjectIdentifier oi : filter) {
                    //取出点位对象不同类型分别对应的值
                    System.out.println(oi.getObjectType().toString() + " " + oi.getInstanceNumber() + " Name: " + pvAiObjectName.get(oi, PropertyIdentifier.objectName).toString());
                    System.out.println(oi.getObjectType().toString() + " " + oi.getInstanceNumber() + " PresentValue: " + pvAiPresentValue.get(oi, PropertyIdentifier.presentValue).toString());
                    System.out.println(oi.getObjectType().toString() + " " + oi.getInstanceNumber() + " Description: " + pvAiDescription.get(oi, PropertyIdentifier.description).toString());
                }
                Thread.sleep(1000);
}

抽一个通用的方法 readValueByProperty

public static PropertyValues readValueByProperty(final LocalDevice localDevice, final RemoteDevice d,final List<ObjectIdentifier> ois, final ReadListener callback, PropertyIdentifier propertyIdentifier) throws BACnetException
    {
        if (ois.size() == 0) {
            return new PropertyValues();
        }

        final PropertyReferences refs = new PropertyReferences();
        for (final ObjectIdentifier oid : ois) {
            refs.add(oid, propertyIdentifier);
        }

        return RequestUtils.readProperties(localDevice, d, refs, false, callback);
}

然后不断的读取和打印

<Java物联网> 从主动到被动:Java中的BACnet设备属性查询,Java物联网,bacnet,Java物联网,物联网,java

 这样就可以不断获取最新的实时值。

使用DeviceEventAdapter订阅

  1. 初始化本地BACnet设备和IP网络配置:

    //创建网络对象
    IpNetwork ipNetwork = new IpNetworkBuilder()
        //本机的ip
        .withLocalBindAddress("192.168.1.12")
        //掩码和长度,如果不知道本机的掩码和长度的话,可以使用代码的工具类IpNetworkUtils获取
        .withSubnet("255.255.255.0", 24)
        //默认的UDP端口
        .withPort(47808)
        .withReuseAddress(true)
        .build();
    //创建虚拟的本地设备,随意设置一个deviceId 设备的唯一标识
    LocalDevice localDevice = new LocalDevice(LOCAL_DEVICE_ID, new DefaultTransport(ipNetwork));
    
     
    • 首先,它创建了一个本地BACnet设备,并指定设备号为123,并为其分配了一个默认的传输实例(DefaultTransport)。
    • 然后,它使用IpNetworkBuilder构建了一个IP网络配置,包括本地绑定地址、子网掩码和长度、默认UDP端口和地址重用等,
  2. 启动本地设备和添加监听器:

    • 接下来,它初始化本地设备,然后添加了一个SubscribeDevice的监听器,该监听器继承自DeviceEventAdapter
       
      //初始化本地设备
      localDevice.initialize();
      //添加监听器
      localDevice.getEventHandler().addListener(new SubscribeDevice());
  3. 搜寻远程设备:

    • 调用localDevice.startRemoteDeviceDiscovery()方法,搜寻网段内的远程BACnet设备。
       
      //搜寻网段内远程设备
      localDevice.startRemoteDeviceDiscovery();
  4. 发送订阅COV报文:

    • 接下来,它使用localDevice.send方法发送了一个订阅COV请求(SubscribeCOVRequest)到远程设备,以订阅特定对象的变化。
    • 订阅COV请求包括订阅标识、被监视对象的对象标识符、是否要发送确认报文以及订阅的时长。
       
    •  //发送订阅COV报文 对应为订阅标识(不可为0),订阅对象,是否要发送确认报文,订阅时长(0为永久)
      localDevice.send(remoteDevice, new SubscribeCOVRequest(new UnsignedInteger(1), new ObjectIdentifier(ObjectType.analogInput, 0), Boolean.TRUE, new UnsignedInteger(0))).get();
                  
  5. 修改值并等待:

    • 之后,进入一个无限循环,每隔2秒向远程设备的某个对象(ObjectType.analogInput, 0)写入值77。
    • 这会触发远程设备发送COV通知给本地设备。
       
    • while (true){
             //修改值为77
             RequestUtils.writePresentValue(localDevice, remoteDevice, new ObjectIdentifier(ObjectType.analogValue, 0), new Real(77));
             Thread.sleep(2000);
      }
  6. SubscribeDevice监听器:

    • SubscribeDevice是一个自定义的监听器类,继承自DeviceEventAdapter
    • 它实现了covNotificationReceived方法,该方法在收到COV通知时被调用,处理实时数据更新。
       
    • class SubscribeDevice extends DeviceEventAdapter {
          @Override
          public void covNotificationReceived(final UnsignedInteger subscriberProcessIdentifier,
                                              final ObjectIdentifier initiatingDevice, final ObjectIdentifier monitoredObjectIdentifier,
                                              final UnsignedInteger timeRemaining, final SequenceOf<PropertyValue> listOfValues)
          {
      
              if (listOfValues.get(0).getPropertyArrayIndex()!=null) {
                  System.out.println(listOfValues.get(0).getValue());
                  System.out.println("===========================================================");
              }
          }
      }

通过这种方法不断的获取最新值。 文章来源地址https://www.toymoban.com/news/detail-611115.html

到了这里,关于<Java物联网> 从主动到被动:Java中的BACnet设备属性查询的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 网络攻击中主动攻击和被动攻击分别指什么?

    网络攻击是指针对计算机信息系统、基础设施、计算机网络或个人计算机设备的,任何类型的进攻动作,现如今网络攻击的手段可谓是五花八门,不过可以大致归归类,以下是详细的内容: 一、主动攻击 主动攻击会导致某些数据流的篡改和虚假数据流的产生。这类攻击可分

    2024年02月07日
    浏览(42)
  • 为什么说云蜜罐可以让安全防御工作由被动变主动

    蜜罐技术本质上是一种对攻击方进行欺骗的技术,通过布置一些作为诱饵的主机、网络服务或者信息,诱使攻击方对它们实施攻击,从而可以对攻击行为进行捕获和分析,了解攻击方所使用的工具与方法,推测攻击意图和动机,能够让防御方清晰地了解他们所面对的安全威胁

    2024年04月10日
    浏览(42)
  • 关于ftp的主动模式(Active Mode)和被动模式(Passive Mode)

    最近做一个项目用到FTP和其它系统进行文件传输,结果在FTP网络连接的问题上花了很多时间,由于太久没搞多FTP,忘记了FTP不单单开放21端口,客户端采用不同连接模式对网络有不同。在此重温一下FTP的主动模式和被动模式的相关知识。 ————————————————

    2024年02月15日
    浏览(39)
  • 【金融量化】如何判断一个基金是不是主动型基金还是被动型基金?

    主动型基金是指由基金经理或管理团队根据市场行情、个股研究等主观因素进行投资决策的基金,其资产配置和投资组合均由基金经理通过主动选股、择时等方式加以调整。 被动型基金则是指根据某个指数进行投资的基金,其资产配置和投资组合均是模拟指数所投资的资产,

    2024年02月11日
    浏览(47)
  • 主动式和被动式电容笔哪个好用?苹果平板平替笔排行

    被动式电容笔与主动式电容笔最大的不同在于主动式电容笔具有更广泛的应用领域,可以与不同种类的电容屏幕进行匹配。随着人们对其了解的不断深入,其应用也日益广泛。除此之外,平替电容笔的技术,也在不断的改进和提高,逐渐走向了更加实用性。下面,我就给大家

    2024年02月11日
    浏览(54)
  • BACnet物联网网关BACnet MS/TP

    BL103 BACnet网关是一款经济型楼宇自动化、暖通控制系统的物联网关,用于实现Modbus RTU 、Modbus TCP、DL/T645、BACnet IP、BACnet MS/TP等多种协议转换为Modbus TCP、OPC UA、MQTT、BACnet IP、华为云IoT、亚马逊云IoT、阿里云IoT、ThingsBoard、金鸽云等协议的网关。 BL103下行支持:Modbus RTU Master、

    2024年02月12日
    浏览(46)
  • 网络安全底座让勒索病毒攻击化被动为主动,为数字化转型打好安全地基

    根据Cyber Security Ventures的分析结果表明,2022年全世界每11s就会发生一次勒索软件攻击,与2019年每14s一次攻击预测相比,攻击数量增加了约20%。随着勒索软件威胁的不断加剧,一旦目标中招,目标受害者可能面临运营中断,机密信息泄露以及赎金经济损失等问题。随着勒索软件

    2024年04月14日
    浏览(50)
  • Full-Scanner是一个多功能扫描工具,支持被动/主动信息收集,漏洞扫描工具联动,可导入POC和EXP

    github项目地址:https://github.com/Zhao-sai-sai/Full-Scanner gitee项目地址:https://gitee.com/wZass/Full-Scanner 做挖漏洞渗透测试有的时候要去用这个工具那个工具去找感觉麻烦我自己就写了一个简单的整合工具,有互联网大佬不要喷我,我也是废物 Full-Scanner是一个多功能扫描工具,支持被动

    2024年02月06日
    浏览(50)
  • 合宙Air780e+luatos+阿里云物联网平台完成设备通信与控制(属性上报+4G远程点灯)

    之前发布的文章有采用合宙的4G LTE Cat.1模块,编程语言用的是lua,整体来说代码比较简洁,实现对华为云物联网平台的设备通信与控制,即采用一个变量作为模拟属性定时上报,并以一个LED灯作为受控设备进行云端命令的控制,本期内容为使用了 阿里云 物联网平台完成同样

    2024年02月06日
    浏览(50)
  • Modbus TCP/BACnet IP/MQTT物联网网关IOT-810介绍及其典型应用

    伴随着计算机技术以及互联网的发展,物联网这个概念已经逐渐进入我们的日常生活,例如智能泊车,智能家居,智能照明,智能楼宇等。智能楼宇是将传统的楼宇自控系统与物联网技术相融合,把系统中常见的传感器、设备、嵌入式计算机接入到网络,在云端统一进行管理

    2024年02月17日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包