快速开发BACnet产品之二 (关于BACnetLib类结构的说明)

来源:互联网 发布:板式床 品牌 知乎 编辑:程序博客网 时间:2024/04/27 13:56
 1.      前言:

BACnetLib是一个以C语言实现核心代码,通过接口调用,实现C++,C#,Java语言开发的一个第三方开发包,想正确使用此开发包,必须先了解下其面向对象的类结构,说来其实也简单,其类结构并不像MFC那样复杂,多重继承,只是一个简单的外壳封装,以方便用户能快速开发bacnet产品;

2.      类结构概述:

目前BACnetLib已完整实现BACnet2004所有对象和服务;

在使用此类结构之前,读者必须对bacnet协议有所了解,尤其是基础数据类型的定义,先作以下说明:

协议中已预定义了以下基础数据类型:

0 = Null

1 = Boolean

2 = Unsigned Integer

3 = Signed Integer (2's complement notation)

4 = Real (ANSI/IEEE-754 floating point)

5 = Double (ANSI/IEEE-754 double precisionfloating point)

6 = Octet String

7 = Character String

8 = Bit String

9 = Enumerated

10 = Date

11 = Time

12 = BACnetObjectIdentifier

这些类型在BACnetLib中都已经完成封装,在此基础类型之上,协议定义了每个对象的属性,及互操作时服务要用到的成员变量;

 

以下是2004版协议中描述的对象和服务:

     对象列表:

1. Accumulator Object

                   2.Analog Input Object

                   3.Analog Output Object

                   4.Analog Value Object

                   5.Averaging Object

                   6.Binary Input Object

                   7.Binary Output Object

                   8.Binary Value Object

                   9.Calendar Object

                   10.Command Object

                   11.Device Object

                   12.Event Enrollment Object

                   13.File Object

                   14.Group Object

                   15.Life Safety Point Object

                   16.Life Safety Zone Object

                   17.Loop Object

                   18.Multi-state Input Object

                   19.Multi-state Output Object

                   20.Multi-state Value Object

                   21.Notification Class Object

                   22.Program Object

                   23.Pulse Converter Object

                   24.Schedule Object

                   25.Trend Log Object

    服务列表:

1.      AcknowledgeAlarmService

                   2.      ConfirmedCOVNotification Service

                   3.      UnconfirmedCOVNotification Service

                   4.      ConfirmedEventNotification Service

                   5.      UnconfirmedEventNotification Service

                   6.      GetAlarmSummary Service

                   7.      GetEnrollmentSummary Service

                   8.      GetEventInformation Service

                   9.      LifeSafetyOperation Service

                   10.   SubscribeCOV Service

                   11.   AtomicReadFile Service

                   12.   AtomicWriteFile Service

                   13.   AddListElement Service

                   14.   RemoveListElement Service

                   15.   CreateObject Service

                   16.   DeleteObject Service

                   17.   ReadProperty Service

                   18.   ReadPropertyMultiple Service

                   19.   ReadRange Service

                   20.   WriteProperty Service

                   21.   WritePropertyMultiple Service

                   22.   DeviceCommunicationControl Service

                   23.   ConfirmedPrivateTransfer Service

                   24.   UnconfirmedPrivateTransfer Service

                   25.   ReinitializeDevice Service

                   26.   ConfirmedTextMessage Service

                   27.   UnconfirmedTextMessage Service

                   28.   TimeSynchronization Service

                   29.   UTCTimeSynchronization Service

                   30.   Who-Has Service

                   31.   I-Have Service

                   32.   Who-Is Service

                   33.   I-Am Service

      以上所有对象和服务,BACnetLib都已将其封装成对象,用户可直接使用;

3.      类库详细使用流程:

总体来说,每个类方法均使用Set为写操作,Get为读操作的命名方式,调用流程如下:

C++语言调用:

1.      协议库初始化并启动;

CMyBACnetLibDriverLib;                           //定义接库对象;

DriverLib.GetAppSetting().SetProcessID(222);//设置进程ID号;

DriverLib.GetAppSetting().SetDevCtrlPassword("1234");//设定设备控制密码

stringtestpassword = DriverLib.GetAppSetting().GetDevCtrlPassword();

DriverLib.GetAppSetting().SetEnabledOfSegmentSupport(true);//设置是否支持分段功能;

DriverLib.GetLinkConfig().SetType(LINK_BIP);//设置当前链路层类型;//这个很重要;

DriverLib.GetLinkConfig().Get_BIP_Configure().SetBIPPort(47808);//设置BIP端口类型,一般是默认端口号;

DriverLib.GetLinkConfig().Get_BIP_Configure().SetEnabledOfActiveBVLLBBMD(false);//是否开启BBMD功能,一般不开启;

DriverLib.GetLinkConfig().Get_BIP_Configure().SetEnabledOfActiveForignRegister(false);//是否开启外部设备注册功能,一般不开启;

DriverLib.GetLinkConfig().Get_BIP_Configure().SetIPUint(192,0);//设置当前设备的本地IP地址;

DriverLib.GetLinkConfig().Get_BIP_Configure().SetIPUint(168,1);//

DriverLib.GetLinkConfig().Get_BIP_Configure().SetIPUint(1,2);//

DriverLib.GetLinkConfig().Get_BIP_Configure().SetIPUint(107,3);//

ULONG_Fdeviceid = 88;//当前设备的设备号;

intresult = DriverLib.Init(3,deviceid);//输入参数是,当前设备的网络号,当前设备的设备号;

if(result==0)//初始化结果;

         return 0;

2.      添加本地对象;

//增加对象;

DriverLib.GetDeviceList().GetData(0).GetObjectList().Add(12,OBJECT_ANALOG_INPUT);

DriverLib.GetDeviceList().GetData(0).GetObjectList().Add(13,OBJECT_ANALOG_INPUT);

DriverLib.GetDeviceList().GetData(0).GetObjectList().Add(14,OBJECT_ANALOG_INPUT);

DriverLib.GetDeviceList().GetData(0).GetObjectList().Add(15,OBJECT_ANALOG_INPUT);

 

3.      更改本地址对象属性;

//更新对象当前值;

DriverLib.GetDeviceList().GetData(0).GetObjectList().GetData(15,OBJECT_ANALOG_INPUT).GetAnalogInputObject().SetPresentValue(12.5f);

DriverLib.GetDeviceList().GetData(0).GetObjectList().GetData(12,OBJECT_ANALOG_INPUT).GetAnalogInputObject().SetPresentValue(22.5f);

 

4.      发送服务获取远程对象的属性;

 

CBACnetServiceReadPropertyhello_bacnet_world;//声明服务对象;

hello_bacnet_world.GetTargetAddress().SetBroadCastType(false);//设定是否广播;

 

CBACnetAddress  addresstmp = hello_bacnet_world.GetSourceAddress();//获取本地地址;

MyLib->GetLocalAddress(&addresstmp);

 

//设定读服务的目标对象ID号和对象类型,目标属性值;

hello_bacnet_world.GetRequest().GetObjectIdentifier().SetInstance(MyLib->GetDeviceList().GetData(devinfor_index).GetDeviceId());

hello_bacnet_world.GetRequest().GetObjectIdentifier().SetObjectType(OBJECT_DEVICE);

hello_bacnet_world.GetRequest().SetPropertyIdentifier(Property_objectList);

 

//如果目标设备未经过BACnet路由器连接,则认为在同一网络中,只要配置本地地址的网络号即可;

//否则将无法收到应答;

hello_bacnet_world.GetTargetAddress().SetNetwork(MyLib->GetDeviceList().GetData(devinfor_index).GetNetwork());

 

//服务发送给的目标地址;

hello_bacnet_world.GetTargetAddress().GetBIPMacAddress().SetLength(6);

hello_bacnet_world.GetTargetAddress().GetBIPMacAddress().SetMac(MyLib->GetDeviceList().GetData(devinfor_index).GetMac().GetMac(0),0);

hello_bacnet_world.GetTargetAddress().GetBIPMacAddress().SetMac(MyLib->GetDeviceList().GetData(devinfor_index).GetMac().GetMac(1),1);

hello_bacnet_world.GetTargetAddress().GetBIPMacAddress().SetMac(MyLib->GetDeviceList().GetData(devinfor_index).GetMac().GetMac(2),2);

hello_bacnet_world.GetTargetAddress().GetBIPMacAddress().SetMac(MyLib->GetDeviceList().GetData(devinfor_index).GetMac().GetMac(3),3);

hello_bacnet_world.GetTargetAddress().GetBIPMacAddress().SetPortBAC(47808);

 

boolresult = hello_bacnet_world.Execute();

 

//获取读服务的结果;

printf("result:%d\n",result);

if(result == true)

{

if(hello_bacnet_world.GetAck().GetPropertyValue().GetDataType() !=BACNET_PROPERTYDATATYPE_OBJECTLISTSUPPORTED_LIST)

{

hello_bacnet_world.Destroy();

return0;

}

 

Test_ReadProperty_DeviceAllObject_List(MyLib,devinfor_index,&hello_bacnet_world.GetAck().GetPropertyValue().GetObjectSupportedList());

}

hello_bacnet_world.Destroy();

 

5.      触发接收服务请求事件;

 

//用户可以在此函数内处理,接收到的服务请求,并处理完成后,返回;

INT_FWho_Has_OnReceive(CBACnetServiceWhoHas* service)

{

         return 1;

}

 

C#语言调用:

1.      协议库初始化并启动;

BACnetLibInterface.BACnetLibraryDriverLib = new BACnetLibInterface.BACnetLibrary();

DriverLib.GetAppSetting().SetProcessID(222);

DriverLib.GetAppSetting().SetDevCtrlPassword("1234");

stringtestpassword = DriverLib.GetAppSetting().GetDevCtrlPassword();

DriverLib.GetAppSetting().SetEnabledOfSegmentSupport(true);

DriverLib.GetLinkConfig().SetType(BACnetLibEnumtype.BACnetLINKTYPE.LINK_BIP);

DriverLib.GetLinkConfig().Get_BIP_Configure().SetBIPPort(47808);

DriverLib.GetLinkConfig().Get_BIP_Configure().SetEnabledOfActiveBVLLBBMD(false);

DriverLib.GetLinkConfig().Get_BIP_Configure().SetEnabledOfActiveForignRegister(false);

DriverLib.GetLinkConfig().Get_BIP_Configure().SetIPUint(192,168,1,107);//根据本机电脑IP,配置;

stringmyip = DriverLib.GetLinkConfig().Get_BIP_Configure().GetIPAddress();

Console.WriteLine("myip:{0}",myip);

 

DriverLib.SetActiveExplore(false);//设定为非浏览模式;

if(DriverLib.Init(3, 56) == 0)

{

    DriverLib.Destroy();

    return;

}

 

2.      添加本地对象;

//添加本地对象;

DriverLib.GetDeviceList().GetData(0).GetObjectList().Add(15,BACnetLibEnumtype.BACNET_OBJECT_TYPE.OBJECT_ANALOG_INPUT);

DriverLib.GetDeviceList().GetData(0).GetObjectList().Add(16,BACnetLibEnumtype.BACNET_OBJECT_TYPE.OBJECT_ANALOG_INPUT);

DriverLib.GetDeviceList().GetData(0).GetObjectList().Add(17,BACnetLibEnumtype.BACNET_OBJECT_TYPE.OBJECT_ANALOG_INPUT);

 

3.      更改本地址对象属性;

 

DriverLib.GetDeviceList().GetData(0).GetObjectList().GetData(0).GetAnalogInputObject().SetPresentValue(12.5f);

DriverLib.GetDeviceList().GetData(0).GetObjectList().GetData(1).GetAnalogInputObject().SetPresentValue(12.5f);

 

 

4.      发送服务获取远程对象的属性;

 

       static intTest_ReadProperty_Request_Float(ref BACnetLibInterface.BACnetLibrary MyLib, intDevID, BACnetLibEnumtype.BACNET_OBJECT_TYPE ObjType, int ObjID)

        {

             BACnetLibInterface.BACnetServiceReadPropertyhello_bacnet_world = new BACnetLibInterface.BACnetServiceReadProperty();

            if (hello_bacnet_world == null)

                return 0;

            if (hello_bacnet_world.getCPtr() ==0)

                return 0;

 

                hello_bacnet_world.GetTargetAddress().SetBroadCastType(true);

        

                BACnetLibInterface.BACnetAddress addresstmp = MyLib.GetLocalAddress();

            hello_bacnet_world.GetSourceAddress().SetNetwork(addresstmp.GetNetwork());

           hello_bacnet_world.GetSourceAddress().GetBIPMacAddress().SetLength(addresstmp.GetBIPMacAddress().GetLength());

           hello_bacnet_world.GetSourceAddress().GetBIPMacAddress().SetPort(addresstmp.GetBIPMacAddress().GetPort());

           hello_bacnet_world.GetSourceAddress().GetBIPMacAddress().SetMac(addresstmp.GetBIPMacAddress().GetMac(0),0);

           hello_bacnet_world.GetSourceAddress().GetBIPMacAddress().SetMac(addresstmp.GetBIPMacAddress().GetMac(1),1);

           hello_bacnet_world.GetSourceAddress().GetBIPMacAddress().SetMac(addresstmp.GetBIPMacAddress().GetMac(2),2);

           hello_bacnet_world.GetSourceAddress().GetBIPMacAddress().SetMac(addresstmp.GetBIPMacAddress().GetMac(3),3);

           hello_bacnet_world.GetSourceAddress().GetBIPMacAddress().SetMac(addresstmp.GetBIPMacAddress().GetMac(4),4);

           hello_bacnet_world.GetSourceAddress().GetBIPMacAddress().SetMac(addresstmp.GetBIPMacAddress().GetMac(5),5);

 

                hello_bacnet_world.GetRequest().GetObjectIdentifier().SetInstance(ObjID);

                hello_bacnet_world.GetRequest().GetObjectIdentifier().SetObjectType(ObjType);

                hello_bacnet_world.GetRequest().SetPropertyIdentifier(BACnetLibEnumtype.BACnetPropertyIdentifier.Property_presentValue);

 

                //如果目标设备未经过BACnet路由器连接,则认为在同一网络中,只要配置本地地址的网络号即可;

                //否则将无法收到应答;

                hello_bacnet_world.GetTargetAddress().SetNetwork(3);

 

                int devcount = MyLib.GetDeviceList().GetCount();

                int isfind=0;

                for(int i=0;i<devcount;i++)

                {

                           if(MyLib.GetDeviceList().GetData(i).GetDeviceId()==DevID)

                           {

                                   hello_bacnet_world.GetTargetAddress().GetBIPMacAddress().SetLength(6);

                                   hello_bacnet_world.GetTargetAddress().GetBIPMacAddress().SetMac(MyLib.GetDeviceList().GetData(i).GetMac().GetMac(0),0);

                                   hello_bacnet_world.GetTargetAddress().GetBIPMacAddress().SetMac(MyLib.GetDeviceList().GetData(i).GetMac().GetMac(1),1);

                                   hello_bacnet_world.GetTargetAddress().GetBIPMacAddress().SetMac(MyLib.GetDeviceList().GetData(i).GetMac().GetMac(2),2);

                                   hello_bacnet_world.GetTargetAddress().GetBIPMacAddress().SetMac(MyLib.GetDeviceList().GetData(i).GetMac().GetMac(3),3);

                                   hello_bacnet_world.GetTargetAddress().GetBIPMacAddress().SetPort(47808);

                                    isfind = 1;

                           }

                }

            if (isfind == 0)

            {

                hello_bacnet_world.Destroy();

                return 0;

            }

 

                bool result = hello_bacnet_world.Execute();

 

           Console.WriteLine("result:{0}",result);

                if (result==true)

                {

                if(hello_bacnet_world.GetAck().GetPropertyValue().GetDataType() != BACnetLibEnumtype.BACNET_PROPERTYDATA_DEFINE_TYPE.BACNET_PROPERTYDATATYPE_REAL)

                {

                   hello_bacnet_world.Destroy();

                    return 0;

                }

                           float value =hello_bacnet_world.GetAck().GetPropertyValue().GetReal();

                          Console.WriteLine("GetPresentValue:{0}",value);

                }

           

 

            hello_bacnet_world.Destroy();

 

                return 1;

        }

 

 

5.      触发接收服务请求事件;

 

public  int Who_Is_OnReceive(intBACnetServiceWhoIs_Handle)       

{

   BACnetServiceWhoIs service = newBACnetServiceWhoIs(BACnetServiceWhoIs_Handle);

   service.Print();

   return 1;

}

 

Java语言调用:

1.      协议库初始化并启动;

BACnetJNI= new JBACnetInterface();

mylibrary= BACnetJNI.new JBACnetLibrary();

 

mylibrary.GetAppSetting().SetProcessID(12345);

mylibrary.GetAppSetting().SetEnabledOfSegmentSupport(true);

mylibrary.GetAppSetting().SetDevCtrlPassword("123456");

 

//枚举类型只能赋值,不能new出来;

JBACnetEnumtype.JBACnetLINKTYPEtype = JBACnetEnumtype.JBACnetLINKTYPE.LINK_BIP;

mylibrary.GetLinkConfig().SetType(type);

 

mylibrary.GetLinkConfig().Get_BIP_Configure().SetBIPPort(47808);

mylibrary.GetLinkConfig().Get_BIP_Configure().SetEnabledOfActiveBVLLBBMD(false);

mylibrary.GetLinkConfig().Get_BIP_Configure().SetEnabledOfActiveForignRegister(false);

mylibrary.GetLinkConfig().Get_BIP_Configure().SetIPUint(192,168,1,107);//配置本地IP地址;

mylibrary.GetLinkConfig().Print();

 

if(mylibrary.Init(100, 500)==0)

         return;

 

2.      添加本地对象;

//1:新增10个BI对象;

for(intp=100;p<120;p++){

         mylibrary.GetDeviceList().GetData(0).GetObjectList().

         Add(p,JBACnetEnumtype.JBACnetOBJECTTYPE.OBJECT_BINARY_INPUT);

}

 

for(intp=600;p<700;p++){

         mylibrary.GetDeviceList().GetData(0).GetObjectList().

         Add(p,JBACnetEnumtype.JBACnetOBJECTTYPE.OBJECT_BINARY_OUTPUT);

}

 

 

 

 

3.      更改本地址对象属性;

mylibrary.GetDeviceList().GetData(0).GetObjectList().GetData(0).GetAnalogInputObject().SetPresentValue(105.2f);

 

4.      发送服务获取远程对象的属性;

 

         public static intGetRemoteObjectValue_AO(int objectid){

                   JBACnetServiceReadPropertyserivce = BACnetJNI.new JBACnetServiceReadProperty();

                   serivce.GetRequest().GetObjectIdentifier().SetInstance(objectid);

                serivce.GetRequest().GetObjectIdentifier().SetObjectType(JBACnetEnumtype.JBACnetOBJECTTYPE.OBJECT_ANALOG_OUTPUT);

                   serivce.GetRequest().SetPropertyIdentifier(JBACnetEnumtype.JBACnetPropertyIdentifier.Property_presentValue);

            

                   serivce.GetSourceAddress().SetNetwork(100);

                   serivce.GetSourceAddress().GetBIPMacAddress().SetPort(47808);

                   serivce.GetSourceAddress().GetBIPMacAddress().SetMac(192,0);     

                   serivce.GetSourceAddress().GetBIPMacAddress().SetMac(168,1);     

                   serivce.GetSourceAddress().GetBIPMacAddress().SetMac(2,   2);    

                   serivce.GetSourceAddress().GetBIPMacAddress().SetMac(7,3);          

                  

                   serivce.GetTargetAddress().SetNetwork(100);

                   serivce.GetTargetAddress().GetBIPMacAddress().SetPort(47808);

                   serivce.GetTargetAddress().GetBIPMacAddress().SetMac(192,0);     

                   serivce.GetTargetAddress().GetBIPMacAddress().SetMac(168,1);     

                   serivce.GetTargetAddress().GetBIPMacAddress().SetMac(2,   2);    

                   serivce.GetTargetAddress().GetBIPMacAddress().SetMac(101,3);

                  

                   if (serivce.Execute()==true)

                   {

                           

                            if(serivce.GetAck()==null){

                                     serivce.Destroy();

                                     return 0;

                            }

                            if(serivce.GetAck().GetPropertyValue()==null){

                                     serivce.Destroy();

                                     return 0;

                            }

                            if(serivce.GetAck().GetPropertyValue().GetDataType()==null){

                                     serivce.Destroy();

                                     return 0;

                            }

                            //有返回数据;

                            if(serivce.GetAck().GetPropertyValue().GetDataType()!=null){

                                     //System.out.println("GetDataTypeis not null");

                                     System.out.println("ackis ok!");

                                     if(serivce.GetAck().GetPropertyValue().GetDataType().GetValue()

                                                   ==JBACnetEnumtype.JBACNET_PROPERTYDATA_DEFINE_TYPE.BACNET_PROPERTYDATATYPE_REAL.GetValue())

                                {

                                         floatftemp = serivce.GetAck().GetPropertyValue().GetReal();

                                         analogpresentvalue= ftemp;

                                        //System.out.println("presentvalue:"+ftemp);

                                }

                            }

                   }

                   else{         

                            serivce.Destroy();

                            return 0;

                   }

                   serivce.Destroy();   

                   return 1;

         }       

 

 

5.      触发接收服务请求事件;

 

                   public intWrite_Property_OnRecieve(

                                     JBACnetServiceWritePropertyservice, JBACnetError Error) {

                            System.out.println("Write_Property_OnRecieveReceive data");

                            //if (service!=null){service.Print();}

 

                            service.GetRequest().GetObjectIdentifier().Print();

                            if(service.GetRequest().GetPropertyValue().GetDataType()!=null){

 

                                     if(service.GetRequest().GetPropertyValue().GetDataType().GetValue()

                                                   ==JBACnetEnumtype.JBACNET_PROPERTYDATA_DEFINE_TYPE.BACNET_PROPERTYDATATYPE_REAL.GetValue())

                                {

                                         floatftemp = service.GetRequest().GetPropertyValue().GetReal();

                                        System.out.println("writerequest value:"+ftemp);

                                }

                                     else if(service.GetRequest().GetPropertyValue().GetDataType().GetValue()

                                                   ==JBACnetEnumtype.JBACNET_PROPERTYDATA_DEFINE_TYPE.BACNET_PROPERTYDATATYPE_ENUMERATED.GetValue())

                                {

                                         intitemp = service.GetRequest().GetPropertyValue().GetEnumerated();

                                        System.out.println("writerequest value:"+itemp);

                                }

                            }

 

                            // ---------------用户处理代码段---------------------

//                         MainActivity dlg =(MainActivity) mContextCustom;

//                         Message m = newMessage();

//                         m.what =2;//Write_Property_OnRecieve

//                         dlg.mHandler.sendMessage(m);

                            // ---------------用户处理代码段---------------------

                            return 1;

                   }

 

4.      总结:

综上所述,使用BACnetLib开发包时,不管C++,C# , Java语言,其类库结构都相同,只是语言语法不同而已,用户只要多使用几次就会觉得简单方便;

如网友有问题,可直接联系我,在之后的时间里,我会陆续推出很多关于bacnet相关应用的文章,尽请期待;

QQ: 2979430184

Email: fhg6000@163.com

 

 

 

 

0 0
原创粉丝点击