APDU Issue/Question
-
I have several BACnet devices on my test network and I'm trying to learn Bacnet4J as I have some ideas of future uses for my own BACnet items.
The first thing I'm trying to do is find the devices, read the objects in the devices and check the present values of the devices. I have used the whois to get the devices and I can get the property refernces. But when I call for the property values I get an error:
The line of code I'm using is:
PropertyValues pvs = localDevice.readProperties(device, refs);
and the error I get is:
com.serotonin.bacnet4j.exception.AbortAPDUException: Abort(server=true, original InvokeId=3, abortReason=Other)
I don't know what it means or how to handle it because it's not really an exception making back to my catch.
Also on another note I had to turn off one of my older BACnet panel because it gives me APDU errors also. Is it possible the older panels are compatible? This is the error I get from that panel when I turn it on:
Exception in thread "main" com.serotonin.bacnet4j.exception.AbortAPDUException: Abort(server=true, originalInvokeId=15, abortReason=Segmentation not supported) at com.serotonin.bacnet4j.LocalDevice.send(LocalDevice.java:428) at com.serotonin.bacnet4j.LocalDevice.send(LocalDevice.java:401) at com.serotonin.bacnet4j.LocalDevice.send(LocalDevice.java:394) at com.serotonin.bacnet4j.LocalDevice.sendReadPropertyAllowNull(LocalDev ice.java:716) at DiscoveryTest.main(DiscoveryTest.java:62)
I am familiar with BACnet and java but it's been a long time since I've programed from scratch, so if there is any place for me to look up and understand why I have communication errors, let me know because it just seems like I'm missing something easy. Thanks!
-Jeremy
-
Hi Jeremy,
In both cases i suspect the problem is that, 1) the BACnet devices do not support segregation, and 2) their objects lists are too long to fit into a single response packet. So, when BACnet4J asks for the object list it fails for reasons chosen by the manufacturer (i.e. not necessarily consistent, although i've seen that "segregation not supported" error before).
I've had a fix for the described problem (hopefully the same problem you're having) around for a bit, but i haven't uploaded a new version to SF. I've checked in an updated JAR though, so if you have access to the CVS you can get it there. Otherwise, i'll upload it here.
-
I downloaded version 1.14 jar file from the CVS on sourceforge but I still get the same result. I tried with another vendor panel and a get a similar issue. I can't seem to call for PropertyValues without an ADPU error.
I'm switched from a Siemens Bacnet panel to a KMC bacnet pane and now I get:
com.serotonin.bacnet4j.exception.RejectAPDUException: Reject(originalInvokeId=3, rejectReason=0)
Here is my code I'm playing with trying to learn the functions and how to use them.
/* Copyright (C) 2006-2009 Serotonin Software Technologies Inc. @author Matthew Lohbihler */ import com.serotonin.bacnet4j.*; import com.serotonin.bacnet4j.apdu.*; import com.serotonin.bacnet4j.base.*; import com.serotonin.bacnet4j.enums.*; import com.serotonin.bacnet4j.event.*; import com.serotonin.bacnet4j.exception.*; import com.serotonin.bacnet4j.obj.*; import com.serotonin.bacnet4j.npdu.*; import com.serotonin.bacnet4j.util.*; import com.serotonin.bacnet4j.service.*; import com.serotonin.bacnet4j.service.acknowledgement.*; import com.serotonin.bacnet4j.service.confirmed.*; import com.serotonin.bacnet4j.service.unconfirmed.*; import com.serotonin.bacnet4j.type.*; import com.serotonin.bacnet4j.type.constructed.*; import com.serotonin.bacnet4j.type.enumerated.*; import com.serotonin.bacnet4j.type.error.*; import com.serotonin.bacnet4j.type.eventParameter.*; import com.serotonin.bacnet4j.type.notificationParameters.*; import com.serotonin.bacnet4j.type.primitive.*; import java.util.*; /** * @author Matthew Lohbihler * @author Jeremy DuMont */ public class QuickTest { public static void main(String[] args) throws Exception { LocalDevice localDevice = new LocalDevice(150, "255.255.255.255"); try { localDevice.initialize(); localDevice.sendBroadcast(47808, new WhoIsRequest(null,null)); Thread.sleep(5000); //iterate through list for( RemoteDevice device: localDevice.getRemoteDevices() ) { localDevice.getExtendedDeviceInformation(device); List<ObjectIdentifier> oids = ((SequenceOf<ObjectIdentifier>)localDevice.sendReadPropertyAllowNull(device, device.getObjectIdentifier(), PropertyIdentifier.objectList)).getValues(); PropertyReferences refs = new PropertyReferences(); refs.add(device.getObjectIdentifier(), PropertyIdentifier.all); for (ObjectIdentifier oid : oids) { refs.add(oid, PropertyIdentifier.all); } System.out.println("Start read properties"); final long start = System.currentTimeMillis(); System.out.println("device=" + device +"\n"); System.out.println("refs=" + refs.getProperties() +"\n" + "refs.size()=" + refs.size() +"\n"); //for( PropertyReference prop : refs.getProperties() ){ // System.out.println("property Identifier=" + prop.getPropertyIdentifier()); //} PropertyValues pvs = localDevice.readProperties(device, refs); System.out.println(String.format("Properties read done in %d ms", System.currentTimeMillis() - start)); // now list devices in the object System.out.println("Device information = " + device.toExtendedString() + "\n"); for (ObjectIdentifier oid : oids) { System.out.println(String.format("\t%s", oid)); for (ObjectPropertyReference opr : pvs) { if (oid.equals(opr.getObjectIdentifier())) { System.out.println(String.format("\t\t%s = %s", opr.getPropertyIdentifier().toString(), pvs.getNoErrorCheck(opr))); } } } System.out.println("\n\n"); }//for Thread.sleep(2000); }catch(Exception e){ System.out.println (e); } finally { localDevice.terminate(); } } }
-
Hi Jeremy,
Sadly, i don't have any BACnet equipment around to test with. At what line are you getting that response? The PropertyIdentifier.objectList line? Also, can you tell me if the device that is complaining supports segmentation or not?
-
Ok, so I've been doing so playing and here is what I learned. I broke my PropertyRefernces down into a small list of only 1 element each and them call for the PropertyValues and now it works until it gets to the file object. Both the Siemens and the KMC panel have file objects in them but apparently you can't read the PropertyValues on a file object or it crashes out. Now I just need to figure out some way of making it keeping going after an error.
In terms of segmentation, the older MS/TP panel I have does not support it apparently but the 2 newer Ethernet panels do have it and it works.
Thanks for the help, I'm getting a much better understanding of the Bacnet4J but I still don't understand why the file objects error out, but I have seen this on other BACnet workstations where the files cannot be retrieved or backed up.
Here is my code I'm currently using:
/* Copyright (C) 2006-2009 Serotonin Software Technologies Inc. @author Matthew Lohbihler */ import com.serotonin.bacnet4j.*; import com.serotonin.bacnet4j.apdu.*; import com.serotonin.bacnet4j.base.*; import com.serotonin.bacnet4j.enums.*; import com.serotonin.bacnet4j.event.*; import com.serotonin.bacnet4j.exception.*; import com.serotonin.bacnet4j.obj.*; import com.serotonin.bacnet4j.npdu.*; import com.serotonin.bacnet4j.util.*; import com.serotonin.bacnet4j.service.*; import com.serotonin.bacnet4j.service.acknowledgement.*; import com.serotonin.bacnet4j.service.confirmed.*; import com.serotonin.bacnet4j.service.unconfirmed.*; import com.serotonin.bacnet4j.type.*; import com.serotonin.bacnet4j.type.constructed.*; import com.serotonin.bacnet4j.type.enumerated.*; import com.serotonin.bacnet4j.type.error.*; import com.serotonin.bacnet4j.type.eventParameter.*; import com.serotonin.bacnet4j.type.notificationParameters.*; import com.serotonin.bacnet4j.type.primitive.*; import java.util.*; /** * @author Matthew Lohbihler * @author Jeremy DuMont */ public class QuickTest { public static void main(String[] args) throws Exception { LocalDevice localDevice = new LocalDevice(150, "255.255.255.255"); try { localDevice.initialize(); localDevice.sendBroadcast(47808, new WhoIsRequest(null,null)); Thread.sleep(5000); //iterate through list for( RemoteDevice device: localDevice.getRemoteDevices() ) { localDevice.getExtendedDeviceInformation(device); List<ObjectIdentifier> oids = ((SequenceOf<ObjectIdentifier>)localDevice.sendReadPropertyAllowNull(device, device.getObjectIdentifier(), PropertyIdentifier.objectList)).getValues(); PropertyReferences refs = new PropertyReferences(); refs.add(device.getObjectIdentifier(), PropertyIdentifier.all); for (ObjectIdentifier oid : oids) { refs.add(oid, PropertyIdentifier.all); } System.out.println("Start read properties"); final long start = System.currentTimeMillis(); List<PropertyReferences> refsSmall = refs.getPropertiesPartitioned(1); System.out.println("number of property refernce set =" + refsSmall.size() ); PropertyValues pvs = localDevice.readProperties(device, refsSmall.get(0) ); //System.out.println("Set number 2"); //pvs = localDevice.readProperties(device, refsSmall.get(1) ); //PropertyValues pvs = localDevice.readProperties(device, refs ); //PropertyValues pvs = localDevice.readOidPresentValues(device, oids); System.out.println(String.format("Properties read done in %d ms", System.currentTimeMillis() - start)); // now list devices in the object //System.out.println("Device information = " + device.toExtendedString() + "\n"); ObjectIdentifier lastOid = null; for( PropertyReferences ref: refsSmall ){ pvs = localDevice.readProperties(device, ref ); //System.out.println(String.format("\t%s", oid)); for (ObjectPropertyReference opr : pvs) { if( lastOid == null || !lastOid.equals( opr.getObjectIdentifier() ) ) System.out.println( String.format("\t%s", opr.getObjectIdentifier()) ); lastOid = opr.getObjectIdentifier(); System.out.println(String.format("\t\t%s = %s", opr.getPropertyIdentifier().toString(), pvs.getNoErrorCheck(opr))); } } System.out.println("\n\n"); }//for Thread.sleep(2000); }catch(Exception e){ System.out.println (e); } finally { localDevice.terminate(); } } }
and here is the output I get from a small Siemens Panel:
Start read properties number of property refernce set =9 Properties read done in 140 ms Binary Output 0 Priority array = [PriorityValue(nullValue=Null), PriorityValue(n ullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), Pr iorityValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullVa lue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), Priorit yValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=N ull), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValu e(nullValue=Null), PriorityValue(nullValue=Null)] Status flags = [false, true, false, false] Polarity = 0 Present value = 0 Inactive text = OFF Out of service = false Object type = Binary Output Object name = test.point Object identifier = Binary Output 0 Active text = ON Event state = normal Device type = LDO Reliability = 7 Relinquish default = 0 Description = test point sys Analog Value 10003 Description = Relinquish default = 0.0 COV increment = 0.0 Reliability = 0 Object identifier = Analog Value 10003 Object type = Analog Value Object name = !BACNETPXCC:BATT Status flags = [false, false, false, false] Out of service = false Units = Present value = 0.0 Priority array = [PriorityValue(nullValue=Null), PriorityValue(n ullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), Pr iorityValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullVa lue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), Priorit yValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=N ull), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValu e(nullValue=Null), PriorityValue(nullValue=Null)] Event state = normal Analog Value 10004 Object identifier = Analog Value 10004 Relinquish default = 0.0 Object name = !BACNETPXCC:BATT2 Status flags = [false, false, false, false] Object type = Analog Value Event state = normal Reliability = 0 Units = Description = COV increment = 0.0 Out of service = false Priority array = [PriorityValue(nullValue=Null), PriorityValue(n ullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), Pr iorityValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullVa lue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), Priorit yValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=N ull), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValu e(nullValue=Null), PriorityValue(nullValue=Null)] Present value = 0.0 Analog Value 10002 Reliability = 0 Event state = normal Relinquish default = 0.0 Object name = !BACNETPXCC:ALMCT2 Object identifier = Analog Value 10002 Priority array = [PriorityValue(nullValue=Null), PriorityValue(n ullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), Pr iorityValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullVa lue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), Priorit yValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=N ull), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValu e(nullValue=Null), PriorityValue(nullValue=Null)] Object type = Analog Value Units = Description = Out of service = false COV increment = 0.0 Present value = 0.0 Status flags = [false, false, false, false] Analog Value 10001 Out of service = false Object name = !BACNETPXCC:ALMCNT Status flags = [false, false, false, false] Object type = Analog Value COV increment = 0.0 Present value = 0.0 Description = Units = Priority array = [PriorityValue(nullValue=Null), PriorityValue(n ullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), Pr iorityValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullVa lue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), Priorit yValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValue(nullValue=N ull), PriorityValue(nullValue=Null), PriorityValue(nullValue=Null), PriorityValu e(nullValue=Null), PriorityValue(nullValue=Null)] Event state = normal Object identifier = Analog Value 10001 Reliability = 0 Relinquish default = 0.0 File 0 File size = 0 File type = File access method = 1 Object identifier = File 0 Read only = true Modification date = Encodable(com.serotonin.bacnet4j.type.constr ucted.DateTime) Archive = false Object name = 7001.db Description = Field Panel Database Object type = File com.serotonin.bacnet4j.exception.AbortAPDUException: Abort(server=true, original InvokeId=10, abortReason=Other)
-
Yeah, "Other" isn't very descriptive. I suppose there may be a log or something on the device that might provide some details, but then you probably won't be able to get that out either, at least through BACnet. It could just be that the file is too big to send. Even with segmentation the restrictions of UDP and the window size impose a limit on how much information can be sent. Maybe we should push for BACnet/TCP.
-
Sorry I made a mistake, it's actually the device Object itself that's giving me issues.
refs.add(device.getObjectIdentifier(), PropertyIdentifier.all);
that line puts the object itself in the list to get the PropertyValues, but for some reason when I call this line with the device in the references it error's out:
pvs = localDevice.readProperties(device, ref );
then I get this error:
com.serotonin.bacnet4j.exception.AbortAPDUException: Abort(server=true, original InvokeId=11, abortReason=Other)
-
Again, "Other" isn't very useful. Is there another way you can find out why the device is aborting?