• Recent
    • Tags
    • Popular
    • Register
    • Login

    Please Note This forum exists for community support for the Mango product family and the Radix IoT Platform. Although Radix IoT employees participate in this forum from time to time, there is no guarantee of a response to anything posted here, nor can Radix IoT, LLC guarantee the accuracy of any information expressed or conveyed. Specific project questions from customers with active support contracts are asked to send requests to support@radixiot.com.

    Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website Mango 5 Documentation Website

    Simple Examples

    BACnet4J general discussion
    4
    28
    32.2k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M
      mlohbihler
      last edited by

      Hi Arne,

      Are you just trying to discover your remote device? I'm not sure what problem you're having.

      Best regards,
      Matthew

      1 Reply Last reply Reply Quote 0
      • A
        apl
        last edited by

        I tried it without any bacnet hardware.

        The docs says one can use the software as device (maybe 1-wire to bacnet gateway on PC)?

        or I misunderstand the docs?

        Arne

        1 Reply Last reply Reply Quote 0
        • M
          mlohbihler
          last edited by

          Yes, the software will work in a software-only environment, but you need to be careful in choosing port numbers. BACnet4J actually works better than some commercial packages in this regard in the sense that it properly will handle broadcasts when non-standard port numbers are used, but that doesn't let the developer off the hook. :) The problem is that when you run BACnet4J on a single host, only one of them can have the standard port number 0xBAC0.

          For example, I'll use the SlaveDeviceTest included in the source. It creates a device that listens on port 2068. When i want to discover this device on the same workstation (say, using DiscoveryTest), i need to make sure the LocalDevice i use there listens on a different port number, and that i send my WhoIs broadcast to port 2068.

          This code should do the trick:

          
                  LocalDevice localDevice = new LocalDevice(1234, "192.168.0.255");
                  localDevice.initialize();
                  localDevice.sendBroadcast(2068, new WhoIsRequest(null, null));
          
          

          ... at least, when you add in the code that lists out discovered devices (also in DiscoveryTest).

          Best regards,
          Matthew

          1 Reply Last reply Reply Quote 0
          • A
            apl
            last edited by

            I changedt the IP-Addresses to localhost ans set the Port of the localDevice to default +1.
            running this I get an:

            com.serotonin.bacnet4j.exception.ErrorAPDUException: ErrorAPDU(choice=12, errorClass=Object, errorCode=Unknown object

            at: localDevice.getExtendedDeviceInformation(d);

            Any Idea what happend?

            
                @SuppressWarnings("unchecked")
                public static void main(String[] args) throws Exception {
                    LocalDevice localDevice = new LocalDevice(1234, "127.0.0.255");
                    localDevice.setPort(LocalDevice.DEFAULT_PORT + 1);
                    localDevice.initialize();
                    try {
                        RemoteDevice rd = new RemoteDevice(105, new Address(new UnsignedInteger(LocalDevice.DEFAULT_PORT),
                                new OctetString(new byte[]{127, 0, 0, 1})), null);
                        rd.setSegmentationSupported(Segmentation.segmentedBoth);
                        rd.setMaxAPDULengthAccepted(1476);
                        localDevice.addRemoteDevice(rd);
            
                        // Wait a bit for responses to come in.
                        Thread.sleep(2000);
            
                        // Get extended information for all remote devices.
                        for (RemoteDevice d : localDevice.getRemoteDevices()) {
                            localDevice.getExtendedDeviceInformation(d);
            
                            List<ObjectIdentifier> oids = ((SequenceOf<ObjectIdentifier>) localDevice.sendReadPropertyAllowNull(
                                    d, d.getObjectIdentifier(), PropertyIdentifier.objectList)).getValues();
            
                            PropertyReferences refs = new PropertyReferences();
                            for (ObjectIdentifier oid : oids) {
                                addPropertyReferences(refs, oid);
                            }
            
                            localDevice.readProperties(d, refs);
                            System.out.println(d);
                        }
            
                        // Wait a bit for responses to come in.
                        Thread.sleep(2000);
                    } finally {
                        localDevice.terminate();
                    }
                }
            
            

            If you add the following constructot to OctetSting:

                public OctetString(int ... intValues) {
                    this.value = new byte[intValues.length];
                    for (int i = 0; i < intValues.length; i++) {
                        this.value* = (byte)intValues*;
                    }
                }
            

            One can write ```
            new OctetString(206, 210, 100, 134);

            
            
            Arne 
            
            1 Reply Last reply Reply Quote 0
            • M
              mlohbihler
              last edited by

              Hi Arne,

              I think i see what the problem is. The DiscoveryTest code has been modified over time to suit some different tests, and so not all of the code in there is necessary for what you want to do. In particular you do not need to declare remote devices yourself - this would defeat the purpose of discovery after all. All the code you should need is this (I have not compiled or tested this, so modify as required):

              
                  public static void main(String[] args) throws Exception {
                      LocalDevice localDevice = new LocalDevice(1234, "192.168.0.255");
                      localDevice.initialize();
                      
                      // Who is
                      localDevice.sendBroadcast(2068, new WhoIsRequest(null, null));
                      
                      // Wait a bit for responses to come in.
                      Thread.sleep(1000);
                      
                      // Get extended information for all remote devices.
                      for (RemoteDevice d : localDevice.getRemoteDevices()) {
                         ... use existing code
                      }
                      
                      // Wait a bit for responses to come in.
                      Thread.sleep(2000);
                      
                      localDevice.terminate();
                  }
              
              

              Change port numbers as you see fit. In this example i've assumed that some remote device is running on port 2068 - presumably the SlaveDeviceTest example.

              I mentioned before an issue with commercial products not handling non-standard ports properly. If i recall correctly, this issue is as follows. Say i create a LocalDevice listening on port 8000. I use this to send a WhoIs broadcast to port 0xBAC0 (the standard port). Many commercial packages will return their IAm response over port 0xBAC0, which is incorrect. The original port 8000 is available to the remote device, but for whatever reason it is not used. Please be aware of this may happen when you are creating your BACnet network. BACnet4J handles its use of ports correctly.

              Best regards,
              Matthew

              1 Reply Last reply Reply Quote 0
              • M
                mlohbihler
                last edited by

                Oh, as an explanation of why you got that error... You created the RemoteDevice yourself and added it to your list of remote devices with "localDevice.addRemoteDevice(rd);". Then, in the loop, you asked this remote device for a property that it does not have (because you didn't give the property to it). So, you got an "Unknown Object" error.

                Best regards,
                Matthew

                1 Reply Last reply Reply Quote 0
                • A
                  apl
                  last edited by

                  Thanks, step done ...

                  Are you Interested in the changed code?

                  next: How to read the Properties of the objects ai0,ai1,bi0,bi1,msg0,ao0 set by SimpleTest? - or in which testfiles are there?

                  Arne

                  1 Reply Last reply Reply Quote 0
                  • M
                    mlohbihler
                    last edited by

                    Are you Interested in the changed code?
                    Sure, if you think it will help other users, post it up.

                    next: How to read the Properties of the objects
                    You send some form of a "read properties" request. Below is a snippet of how Mango does it. It's contextual to Mango, but i think you should be able to figure out what is going on.

                        private void pollDevice(RemoteDevice d, List&lt;DataPointRT&gt; points, long time) {
                            // Gather the points into a list of point references.
                            PropertyReferences refs = new PropertyReferences();
                            for (DataPointRT dp : points) {
                                BACnetIPPointLocatorRT locator = (BACnetIPPointLocatorRT)dp.getPointLocator();
                                refs.add(locator.getOid(), locator.getPid());
                            }
                            
                            try {
                                // Send the read request.
                                PropertyValues values = localDevice.readProperties(d, refs);
                                
                                // Dereference the property values back into the points.
                                for (DataPointRT dp : points) {
                                    BACnetIPPointLocatorRT locator = (BACnetIPPointLocatorRT)dp.getPointLocator();
                                    Encodable encodable = values.getNoErrorCheck(locator.getOid(), locator.getPid());
                                    if (encodable == null)
                                        fireDeviceExceptionEvent("event.bacnet.readError", dp.getVO().getName(), "no value returned");
                                    else if (encodable instanceof BACnetError)
                                        fireDeviceExceptionEvent("event.bacnet.readError", dp.getVO().getName(),
                                                ((BACnetError)encodable).getErrorCode());
                                    else {
                                        Object value = encodableToValue(encodable, dp.getDataTypeId());
                                        dp.updatePointValue(new PointValueTime(value, time));
                                    }
                                }
                            }
                            catch (BACnetException e) {
                                fireMessageExceptionEvent("event.bacnet.readDevice", d.getAddress().toIpString(), e.getMessage());
                            }
                        }
                    
                    

                    Best regards,
                    Matthew

                    1 Reply Last reply Reply Quote 0
                    • A
                      apl
                      last edited by

                      So this two classes should work straight out of the box on any machine ;-)

                      DeviceTest

                      /*
                       * ============================================================================
                       * GNU Lesser General Public License
                       * ============================================================================
                       *
                       * Copyright (C) 2006-2009 Serotonin Software Technologies Inc. http://serotoninsoftware.com
                       * @author Matthew Lohbihler
                       * 
                       * This library is free software; you can redistribute it and/or
                       * modify it under the terms of the GNU Lesser General Public
                       * License as published by the Free Software Foundation; either
                       * version 2.1 of the License, or (at your option) any later version.
                       * 
                       * This library is distributed in the hope that it will be useful,
                       * but WITHOUT ANY WARRANTY; without even the implied warranty of
                       * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                       * Lesser General Public License for more details.
                       * 
                       * You should have received a copy of the GNU Lesser General Public
                       * License along with this library; if not, write to the Free Software
                       * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
                       */
                      package com.serotonin.bacnet4j.test;
                      
                      import com.serotonin.bacnet4j.RemoteObject;
                      import com.serotonin.bacnet4j.obj.BACnetObject;
                      import com.serotonin.bacnet4j.type.Encodable;
                      import com.serotonin.bacnet4j.type.constructed.Choice;
                      import com.serotonin.bacnet4j.type.constructed.PropertyValue;
                      import com.serotonin.bacnet4j.type.constructed.TimeStamp;
                      import com.serotonin.bacnet4j.type.enumerated.EventState;
                      import com.serotonin.bacnet4j.type.enumerated.EventType;
                      import com.serotonin.bacnet4j.type.enumerated.MessagePriority;
                      import com.serotonin.bacnet4j.type.enumerated.NotifyType;
                      import com.serotonin.bacnet4j.type.notificationParameters.NotificationParameters;
                      import com.serotonin.bacnet4j.type.primitive.Boolean;
                      import com.serotonin.bacnet4j.type.primitive.CharacterString;
                      import java.io.IOException;
                      import java.util.List;
                      
                      import com.serotonin.bacnet4j.LocalDevice;
                      import com.serotonin.bacnet4j.RemoteDevice;
                      import com.serotonin.bacnet4j.event.DeviceEventListener;
                      import com.serotonin.bacnet4j.exception.BACnetException;
                      import com.serotonin.bacnet4j.service.unconfirmed.WhoIsRequest;
                      import com.serotonin.bacnet4j.type.constructed.BACnetError;
                      import com.serotonin.bacnet4j.type.constructed.PropertyReference;
                      import com.serotonin.bacnet4j.type.constructed.SequenceOf;
                      import com.serotonin.bacnet4j.type.enumerated.ObjectType;
                      import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier;
                      import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
                      import com.serotonin.bacnet4j.type.primitive.UnsignedInteger;
                      import com.serotonin.bacnet4j.util.PropertyReferences;
                      import com.serotonin.bacnet4j.util.PropertyValues;
                      
                      /**
                       * Discovers and devices and print all properties of all objects found.
                       *
                       *
                       *
                       * @author Matthew Lohbihler
                       * @author Arne Plöse
                       */
                      public class DiscoveryTest {
                      
                          public static String BROADCAST_ADDRESS = "127.0.0.255";
                          private LoopDevice loopDevice;
                          private LocalDevice localDevice;
                      
                          public DiscoveryTest(String broadcastAddress, int port) throws IOException {
                              localDevice = new LocalDevice(1234, broadcastAddress);
                              localDevice.setPort(port);
                              localDevice.getEventHandler().addListener(new DeviceEventListener() {
                      
                                  public void listenerException(Throwable e) {
                                      System.out.println("DiscoveryTest listenerException");
                                  }
                      
                                  public void iAmReceived(RemoteDevice d) {
                                      System.out.println("DiscoveryTest iAmReceived");
                                      synchronized (DiscoveryTest.this) {
                                          DiscoveryTest.this.notifyAll();
                                      }
                                  }
                      
                                  public boolean allowPropertyWrite(BACnetObject obj, PropertyValue pv) {
                                      System.out.println("DiscoveryTest allowPropertyWrite");
                                      return true;
                                  }
                      
                                  public void propertyWritten(BACnetObject obj, PropertyValue pv) {
                                      System.out.println("DiscoveryTest propertyWritten");
                                  }
                      
                                  public void iHaveReceived(RemoteDevice d, RemoteObject o) {
                                      System.out.println("DiscoveryTest iHaveReceived");
                                  }
                      
                                  public void covNotificationReceived(UnsignedInteger subscriberProcessIdentifier, RemoteDevice initiatingDevice, ObjectIdentifier monitoredObjectIdentifier, UnsignedInteger timeRemaining, SequenceOf<PropertyValue> listOfValues) {
                                      System.out.println("DiscoveryTest covNotificationReceived");
                                  }
                      
                                  public void eventNotificationReceived(UnsignedInteger processIdentifier, RemoteDevice initiatingDevice, ObjectIdentifier eventObjectIdentifier, TimeStamp timeStamp, UnsignedInteger notificationClass, UnsignedInteger priority, EventType eventType, CharacterString messageText, NotifyType notifyType, Boolean ackRequired, EventState fromState, EventState toState, NotificationParameters eventValues) {
                                      System.out.println("DiscoveryTest eventNotificationReceived");
                                  }
                      
                                  public void textMessageReceived(RemoteDevice textMessageSourceDevice, Choice messageClass, MessagePriority messagePriority, CharacterString message) {
                                      System.out.println("DiscoveryTest textMessageReceived");
                                  }
                      
                                  public void privateTransferReceived(UnsignedInteger vendorId, UnsignedInteger serviceNumber, Encodable serviceParameters) {
                                      System.out.println("DiscoveryTest privateTransferReceived");
                                  }
                              });
                              localDevice.initialize();
                      
                          }
                      
                          public void doDiscover() throws Exception {
                              // Who is
                              System.out.println("Send Broadcast WhoIsRequest() ");
                              // Send the broadcast to the correct port of the LoopDevice !!!
                              localDevice.sendBroadcast(loopDevice.getPort(), new WhoIsRequest(null, null));
                      
                              // wait for notification in iAmReceived() Timeout 2 sec
                              synchronized (this) {
                                  final long start = System.currentTimeMillis();
                                  this.wait(2000);
                                  System.out.println(" waited for iAmReceived: " + (System.currentTimeMillis() - start) + " ms");
                              }
                      
                      
                              System.out.println("Start iterating remote devices");
                      
                              // Get extended information for all remote devices.
                              for (RemoteDevice d : localDevice.getRemoteDevices()) {
                      
                                  localDevice.getExtendedDeviceInformation(d);
                      
                                  List<ObjectIdentifier> oids = ((SequenceOf<ObjectIdentifier>) localDevice.sendReadPropertyAllowNull(
                                          d, d.getObjectIdentifier(), PropertyIdentifier.objectList)).getValues();
                      
                                  PropertyReferences refs = new PropertyReferences();
                                  for (ObjectIdentifier oid : oids) {
                                      addPropertyReferences(refs, oid);
                                  }
                      
                                  localDevice.readProperties(d, refs);
                                  System.out.println("Values of d: " + d);
                                  try {
                                      // Send the read request.
                                      PropertyValues values = localDevice.readProperties(d, refs);
                      
                                      // Dereference the property values back into the points.
                                      for (ObjectIdentifier oid : oids) {
                                          printObject(oid, refs, values);
                                      }
                                  } catch (BACnetException e) {
                                      System.out.println("event.bacnet.readDevice ADDRESS: " + e.getMessage());
                                  }
                      
                              }
                      
                              System.out.println("Remote devices done...");
                          }
                      
                          /**
                           * Note same Bropadcast address, but different ports!!!
                           * @param args
                           * @throws java.lang.Exception
                           */
                          @SuppressWarnings("unchecked")
                          public static void main(String[] args) throws Exception {
                              DiscoveryTest dt = new DiscoveryTest(BROADCAST_ADDRESS, LocalDevice.DEFAULT_PORT);
                              dt.setLoopDevice(new LoopDevice(BROADCAST_ADDRESS, LocalDevice.DEFAULT_PORT + 1));
                              try {
                                  dt.doDiscover();
                              } finally {
                                  dt.localDevice.terminate();
                                  System.out.println("Cleanup loopDevice");
                                  dt.getLoopDevice().doTerminate();
                              }
                          }
                      
                          private void addPropertyReferences(PropertyReferences refs, ObjectIdentifier oid) {
                              refs.add(oid, PropertyIdentifier.objectName);
                      
                              ObjectType type = oid.getObjectType();
                              if (ObjectType.accumulator.equals(type)) {
                                  refs.add(oid, PropertyIdentifier.units);
                              } else if (ObjectType.analogInput.equals(type) ||
                                      ObjectType.analogOutput.equals(type) ||
                                      ObjectType.analogValue.equals(type) ||
                                      ObjectType.pulseConverter.equals(type)) {
                                  refs.add(oid, PropertyIdentifier.units);
                              } else if (ObjectType.binaryInput.equals(type) ||
                                      ObjectType.binaryOutput.equals(type) ||
                                      ObjectType.binaryValue.equals(type)) {
                                  refs.add(oid, PropertyIdentifier.inactiveText);
                                  refs.add(oid, PropertyIdentifier.activeText);
                              } else if (ObjectType.lifeSafetyPoint.equals(type)) {
                                  refs.add(oid, PropertyIdentifier.units);
                              } else if (ObjectType.loop.equals(type)) {
                                  refs.add(oid, PropertyIdentifier.outputUnits);
                              } else if (ObjectType.multiStateInput.equals(type) ||
                                      ObjectType.multiStateOutput.equals(type) ||
                                      ObjectType.multiStateValue.equals(type)) {
                                  refs.add(oid, PropertyIdentifier.stateText);
                              } else {
                                  return;
                              }
                      
                              refs.add(oid, PropertyIdentifier.presentValue);
                          }
                      
                          /**
                           * @return the loopDevice
                           */
                          public LoopDevice getLoopDevice() {
                              return loopDevice;
                          }
                      
                          /**
                           * @param loopDevice the loopDevice to set
                           */
                          public void setLoopDevice(LoopDevice loopDevice) {
                              this.loopDevice = loopDevice;
                          }
                      
                          private void printObject(ObjectIdentifier oid, PropertyReferences refs, PropertyValues values) {
                              System.out.println("\t" + oid);
                              // print propertie
                              for (PropertyReference pr : refs.getProperties().get(oid)) {
                                  Encodable encodable = values.getNoErrorCheck(oid, pr);
                                  if (encodable == null) {
                                      System.out.println("event.bacnet.readError: no value returned");
                                  } else if (encodable instanceof BACnetError) {
                                      System.out.println("event.bacnet.readError NAME: " + ((BACnetError) encodable).getErrorCode());
                                  } else {
                                      System.out.println(String.format("\t\t %s = %s", pr.getPropertyIdentifier(), encodable.toString()));
                                  }
                              }
                          }
                      }
                      
                      

                      LoopDevice

                      /*
                       * ============================================================================
                       * GNU Lesser General Public License
                       * ============================================================================
                       *
                       * Copyright (C) 2006-2009 Serotonin Software Technologies Inc. http://serotoninsoftware.com
                       * @author Matthew Lohbihler
                       * 
                       * This library is free software; you can redistribute it and/or
                       * modify it under the terms of the GNU Lesser General Public
                       * License as published by the Free Software Foundation; either
                       * version 2.1 of the License, or (at your option) any later version.
                       * 
                       * This library is distributed in the hope that it will be useful,
                       * but WITHOUT ANY WARRANTY; without even the implied warranty of
                       * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                       * Lesser General Public License for more details.
                       * 
                       * You should have received a copy of the GNU Lesser General Public
                       * License along with this library; if not, write to the Free Software
                       * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
                       */
                      package com.serotonin.bacnet4j.test;
                      
                      import com.serotonin.bacnet4j.LocalDevice;
                      import com.serotonin.bacnet4j.RemoteDevice;
                      import com.serotonin.bacnet4j.RemoteObject;
                      import com.serotonin.bacnet4j.event.DeviceEventListener;
                      import com.serotonin.bacnet4j.exception.BACnetServiceException;
                      import com.serotonin.bacnet4j.obj.BACnetObject;
                      import com.serotonin.bacnet4j.type.Encodable;
                      import com.serotonin.bacnet4j.type.constructed.Choice;
                      import com.serotonin.bacnet4j.type.constructed.PropertyValue;
                      import com.serotonin.bacnet4j.type.constructed.SequenceOf;
                      import com.serotonin.bacnet4j.type.constructed.TimeStamp;
                      import com.serotonin.bacnet4j.type.enumerated.BinaryPV;
                      import com.serotonin.bacnet4j.type.enumerated.EngineeringUnits;
                      import com.serotonin.bacnet4j.type.enumerated.EventState;
                      import com.serotonin.bacnet4j.type.enumerated.EventType;
                      import com.serotonin.bacnet4j.type.enumerated.MessagePriority;
                      import com.serotonin.bacnet4j.type.enumerated.NotifyType;
                      import com.serotonin.bacnet4j.type.enumerated.ObjectType;
                      import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier;
                      import com.serotonin.bacnet4j.type.notificationParameters.NotificationParameters;
                      import com.serotonin.bacnet4j.type.primitive.Boolean;
                      import com.serotonin.bacnet4j.type.primitive.CharacterString;
                      import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
                      import com.serotonin.bacnet4j.type.primitive.Real;
                      import com.serotonin.bacnet4j.type.primitive.UnsignedInteger;
                      import java.io.IOException;
                      
                      /**
                       *
                       * software only device default local loop ;-)
                       *
                       * @author mlohbihler
                       * @author aploese
                       */
                      public class LoopDevice implements Runnable {
                      
                          public static void main(String[] args) throws Exception {
                              LoopDevice ld = new LoopDevice("127.0.0.255", LocalDevice.DEFAULT_PORT + 1);
                              Thread.sleep(12000); // wait 2 min
                              ld.doTerminate();
                          }
                          private boolean terminate;
                          private LocalDevice localDevice;
                          private BACnetObject ai0;
                          private BACnetObject ai1;
                          private BACnetObject bi0;
                          private BACnetObject bi1;
                          private BACnetObject mso0;
                          private BACnetObject ao0;
                      
                          public LoopDevice(String broadcastAddress, int port) throws BACnetServiceException, IOException {
                              localDevice = new LocalDevice(1968, broadcastAddress);
                              localDevice.setPort(port);
                              localDevice.getEventHandler().addListener(new DeviceEventListener() {
                      
                                  public void listenerException(Throwable e) {
                                      System.out.println("loopDevice listenerException");
                                  }
                      
                                  public void iAmReceived(RemoteDevice d) {
                                      System.out.println("loopDevice iAmReceived");
                                  }
                      
                                  public boolean allowPropertyWrite(BACnetObject obj, PropertyValue pv) {
                                      System.out.println("loopDevice allowPropertyWrite");
                                      return true;
                                  }
                      
                                  public void propertyWritten(BACnetObject obj, PropertyValue pv) {
                                      System.out.println("loopDevice propertyWritten");
                                  }
                      
                                  public void iHaveReceived(RemoteDevice d, RemoteObject o) {
                                      System.out.println("loopDevice iHaveReceived");
                                  }
                      
                                  public void covNotificationReceived(UnsignedInteger subscriberProcessIdentifier, RemoteDevice initiatingDevice, ObjectIdentifier monitoredObjectIdentifier, UnsignedInteger timeRemaining, SequenceOf<PropertyValue> listOfValues) {
                                      System.out.println("loopDevice covNotificationReceived");
                                  }
                      
                                  public void eventNotificationReceived(UnsignedInteger processIdentifier, RemoteDevice initiatingDevice, ObjectIdentifier eventObjectIdentifier, TimeStamp timeStamp, UnsignedInteger notificationClass, UnsignedInteger priority, EventType eventType, CharacterString messageText, NotifyType notifyType, Boolean ackRequired, EventState fromState, EventState toState, NotificationParameters eventValues) {
                                      System.out.println("loopDevice eventNotificationReceived");
                                  }
                      
                                  public void textMessageReceived(RemoteDevice textMessageSourceDevice, Choice messageClass, MessagePriority messagePriority, CharacterString message) {
                                      System.out.println("loopDevice textMessageReceived");
                                  }
                      
                                  public void privateTransferReceived(UnsignedInteger vendorId, UnsignedInteger serviceNumber, Encodable serviceParameters) {
                                      System.out.println("loopDevice privateTransferReceived");
                                  }
                      
                              });
                      
                              // Set up a few objects.
                              ai0 = new BACnetObject(
                                      localDevice, localDevice.getNextInstanceObjectIdentifier(ObjectType.analogInput));
                              ai0.setProperty(PropertyIdentifier.units, EngineeringUnits.centimeters);
                              localDevice.addObject(getAi0());
                      
                              ai1 = new BACnetObject(
                                      localDevice, localDevice.getNextInstanceObjectIdentifier(ObjectType.analogInput));
                              ai0.setProperty(PropertyIdentifier.units, EngineeringUnits.percentObscurationPerFoot);
                              localDevice.addObject(getAi1());
                      
                              bi0 = new BACnetObject(
                                      localDevice, localDevice.getNextInstanceObjectIdentifier(ObjectType.binaryInput));
                              localDevice.addObject(getBi0());
                              bi0.setProperty(PropertyIdentifier.objectName, new CharacterString("Off and on"));
                              bi0.setProperty(PropertyIdentifier.inactiveText, new CharacterString("Off"));
                              bi0.setProperty(PropertyIdentifier.activeText, new CharacterString("On"));
                      
                              bi1 = new BACnetObject(
                                      localDevice, localDevice.getNextInstanceObjectIdentifier(ObjectType.binaryInput));
                              localDevice.addObject(getBi1());
                              bi1.setProperty(PropertyIdentifier.objectName, new CharacterString("Good and bad"));
                              bi1.setProperty(PropertyIdentifier.inactiveText, new CharacterString("Bad"));
                              bi1.setProperty(PropertyIdentifier.activeText, new CharacterString("Good"));
                      
                              mso0 = new BACnetObject(
                                      localDevice, localDevice.getNextInstanceObjectIdentifier(ObjectType.multiStateOutput));
                              mso0.setProperty(PropertyIdentifier.objectName, new CharacterString("Vegetable"));
                              mso0.setProperty(PropertyIdentifier.numberOfStates, new UnsignedInteger(4));
                              mso0.setProperty(PropertyIdentifier.stateText, 1, new CharacterString("Tomato"));
                              mso0.setProperty(PropertyIdentifier.stateText, 2, new CharacterString("Potato"));
                              mso0.setProperty(PropertyIdentifier.stateText, 3, new CharacterString("Onion"));
                              mso0.setProperty(PropertyIdentifier.stateText, 4, new CharacterString("Broccoli"));
                              mso0.setProperty(PropertyIdentifier.presentValue, new UnsignedInteger(1));
                              localDevice.addObject(getMso0());
                      
                              ao0 = new BACnetObject(
                                      localDevice, localDevice.getNextInstanceObjectIdentifier(ObjectType.analogOutput));
                              ao0.setProperty(PropertyIdentifier.objectName, new CharacterString("Settable analog"));
                              localDevice.addObject(getAo0());
                      
                      
                              // Start the local device.
                              localDevice.initialize();
                              new Thread(this).start();
                          }
                      
                          public void run() {
                              try {
                                  System.out.println("LoopDevice start changing values" + this);
                      
                                  // Let it go...
                                  float ai0value = 0;
                                  float ai1value = 0;
                                  boolean bi0value = false;
                                  boolean bi1value = false;
                      
                                  getMso0().setProperty(PropertyIdentifier.presentValue, new UnsignedInteger(2));
                                  while (!isTerminate()) {
                                      System.out.print("Change values of LoopDevice " + this);
                                      // Change the values.
                                      ai0value += 0.1;
                                      ai1value += 0.7;
                                      bi0value = !bi0value;
                                      bi1value = !bi1value;
                      
                      
                                      // Update the values in the objects.
                                      ai0.setProperty(PropertyIdentifier.presentValue, new Real(ai0value));
                                      ai1.setProperty(PropertyIdentifier.presentValue, new Real(ai1value));
                                      bi0.setProperty(PropertyIdentifier.presentValue, bi0value ? BinaryPV.active : BinaryPV.inactive);
                                      bi1.setProperty(PropertyIdentifier.presentValue, bi1value ? BinaryPV.active : BinaryPV.inactive);
                      
                                      synchronized (this) {
                                          wait(1000); // 1 second or notified (faster exit then stupid wait for 1 second)
                                      }
                                  }
                                  System.out.println("Close LoopDevive " + this);
                              } catch (Exception ex) {
                              }
                              localDevice.terminate();
                              localDevice = null;
                          }
                      
                          @Override
                          protected void finalize() throws Throwable {
                              if (localDevice != null) {
                                  localDevice.terminate();
                                  localDevice = null;
                              }
                          }
                      
                          /**
                           * @return the terminate
                           */
                          public boolean isTerminate() {
                              return terminate;
                          }
                      
                          /**
                           * @param terminate the terminate to set
                           */
                          public void doTerminate() {
                              this.terminate = true;
                              synchronized (this) {
                                  this.notifyAll(); // we may wait for this in run() ...
                              }
                          }
                      
                          /**
                           * @return the broadcastAddress
                           */
                          public String getBroadcastAddress() {
                              return localDevice.getBroadcastAddress();
                          }
                      
                          /**
                           * @return the port
                           */
                          public int getPort() {
                              return localDevice.getPort();
                          }
                      
                          /**
                           * @return the localDevice
                           */
                          public LocalDevice getLocalDevice() {
                              return localDevice;
                          }
                      
                          /**
                           * @return the ai0
                           */
                          public BACnetObject getAi0() {
                              return ai0;
                          }
                      
                          /**
                           * @return the ai1
                           */
                          public BACnetObject getAi1() {
                              return ai1;
                          }
                      
                          /**
                           * @return the bi0
                           */
                          public BACnetObject getBi0() {
                              return bi0;
                          }
                      
                          /**
                           * @return the bi1
                           */
                          public BACnetObject getBi1() {
                              return bi1;
                          }
                      
                          /**
                           * @return the mso0
                           */
                          public BACnetObject getMso0() {
                              return mso0;
                          }
                      
                          /**
                           * @return the ao0
                           */
                          public BACnetObject getAo0() {
                              return ao0;
                          }
                      }
                      
                      

                      Arne

                      1 Reply Last reply Reply Quote 0
                      • M
                        mlohbihler
                        last edited by

                        This is excellent Arne. Thanks very much for sharing your work.

                        Best regards,
                        Matthew

                        1 Reply Last reply Reply Quote 0
                        • A
                          apl
                          last edited by

                          Hi,

                          trying to read all property values by using this changed code in :

                              private void addPropertyReferences(PropertyReferences refs, ObjectIdentifier oid) {
                          
                                  for (int i = 0; i < 12; i++) {
                                      refs.add(oid, new PropertyIdentifier(75 + i));
                                  }
                          }
                          
                          

                          and choose values greater of 12 >> the app will fail.

                          Any hints?

                          Arne

                          1 Reply Last reply Reply Quote 0
                          • A
                            apl
                            last edited by

                            Hi Matthew,

                            the offending PropertyId are: 8, 87, 105, which throw a java.lang.reflect.InvocationTargetException.

                            Should I file a bug against it in the SF bug parade?

                            Arne

                            1 Reply Last reply Reply Quote 0
                            • M
                              mlohbihler
                              last edited by

                              Hi Arne,

                              I can't reproduce the problem. This code worked fine for me:

                                  public static void main(String[] args) throws Exception {
                                      ObjectIdentifier oid = new ObjectIdentifier(ObjectType.accumulator, 0);
                                      PropertyReferences refs = new PropertyReferences();
                                      
                                      for (int i=0; i&lt200; i++)
                                          refs.add(oid, new PropertyIdentifier(i));
                                  }
                              
                              

                              A stack trace goes a long way to explaining things. Maybe you can include that if you still have this problem.

                              Also, can you please start a new topic when you are changing subject. This thread is getting too expansive.

                              Best regards,
                              Matthew

                              1 Reply Last reply Reply Quote 0
                              • A
                                apl
                                last edited by

                                Sorry,

                                I thought this belongs also to create a bunch of example that runs out of the box.

                                OK, here is my stack trace:

                                com.serotonin.bacnet4j.exception.BACnetException: java.lang.reflect.InvocationTargetException
                                        at com.serotonin.bacnet4j.type.Encodable.read(Encodable.java:168)
                                        at com.serotonin.bacnet4j.type.constructed.SequenceOf.<init>(SequenceOf.java:54)
                                        at com.serotonin.bacnet4j.type.Encodable.readSequenceOf(Encodable.java:213)
                                        at com.serotonin.bacnet4j.service.acknowledgement.ReadPropertyMultipleAck.<init>(ReadPropertyMultipleAck.java:50)
                                        at com.serotonin.bacnet4j.service.acknowledgement.AcknowledgementService.createAcknowledgementService(AcknowledgementService.java:48)
                                        at com.serotonin.bacnet4j.apdu.ComplexACK.parseServiceData(ComplexACK.java:196)
                                        at com.serotonin.bacnet4j.npdu.ip.IpMessageControl.waitForAck(IpMessageControl.java:658)
                                        at com.serotonin.bacnet4j.npdu.ip.IpMessageControl.send(IpMessageControl.java:288)
                                        at com.serotonin.bacnet4j.npdu.ip.IpMessageControl.send(IpMessageControl.java:268)
                                        at com.serotonin.bacnet4j.npdu.ip.IpMessageControl.send(IpMessageControl.java:224)
                                        at com.serotonin.bacnet4j.LocalDevice.send(LocalDevice.java:411)
                                        at com.serotonin.bacnet4j.LocalDevice.send(LocalDevice.java:399)
                                        at com.serotonin.bacnet4j.LocalDevice.send(LocalDevice.java:392)
                                        at com.serotonin.bacnet4j.LocalDevice.readProperties(LocalDevice.java:760)
                                        at com.serotonin.bacnet4j.test.DiscoveryTest.doDiscover(DiscoveryTest.java:155)
                                        at com.serotonin.bacnet4j.test.DiscoveryTest.main(DiscoveryTest.java:187)
                                Caused by: java.lang.reflect.InvocationTargetException
                                        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
                                        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
                                        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
                                        at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
                                        at com.serotonin.bacnet4j.type.Encodable.read(Encodable.java:165)
                                        ... 15 more
                                Caused by: com.serotonin.bacnet4j.exception.BACnetException: java.lang.reflect.InvocationTargetException
                                        at com.serotonin.bacnet4j.type.Encodable.read(Encodable.java:168)
                                        at com.serotonin.bacnet4j.type.constructed.SequenceOf.<init>(SequenceOf.java:66)
                                        at com.serotonin.bacnet4j.type.Encodable.readSequenceOf(Encodable.java:224)
                                        at com.serotonin.bacnet4j.type.Encodable.readOptionalSequenceOf(Encodable.java:233)
                                        at com.serotonin.bacnet4j.type.constructed.ReadAccessResult.<init>(ReadAccessResult.java:64)
                                        ... 20 more
                                Caused by: java.lang.reflect.InvocationTargetException
                                        at sun.reflect.GeneratedConstructorAccessor3.newInstance(Unknown Source)
                                        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
                                        at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
                                        at com.serotonin.bacnet4j.type.Encodable.read(Encodable.java:165)
                                        ... 24 more
                                Caused by: com.serotonin.bacnet4j.exception.BACnetException: java.lang.reflect.InvocationTargetException
                                        at com.serotonin.bacnet4j.type.Encodable.read(Encodable.java:168)
                                        at com.serotonin.bacnet4j.type.Encodable.readWrapped(Encodable.java:318)
                                        at com.serotonin.bacnet4j.type.Encodable.readEncodable(Encodable.java:263)
                                        at com.serotonin.bacnet4j.type.constructed.ReadAccessResult$Result.<init>(ReadAccessResult.java:124)
                                        ... 28 more
                                Caused by: java.lang.reflect.InvocationTargetException
                                        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
                                        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
                                        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
                                        at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
                                        at com.serotonin.bacnet4j.type.Encodable.read(Encodable.java:165)
                                        ... 31 more
                                Caused by: com.serotonin.bacnet4j.exception.BACnetException: java.lang.reflect.InvocationTargetException
                                        at com.serotonin.bacnet4j.type.Encodable.read(Encodable.java:168)
                                        at com.serotonin.bacnet4j.type.constructed.SequenceOf.<init>(SequenceOf.java:54)
                                        at com.serotonin.bacnet4j.type.constructed.PriorityArray.<init>(PriorityArray.java:41)
                                        ... 36 more
                                Caused by: java.lang.reflect.InvocationTargetException
                                        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
                                        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
                                        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
                                        at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
                                        at com.serotonin.bacnet4j.type.Encodable.read(Encodable.java:165)
                                        ... 38 more
                                Caused by: com.serotonin.bacnet4j.exception.BACnetErrorException
                                        at com.serotonin.bacnet4j.type.Encodable.popStart(Encodable.java:109)
                                        at com.serotonin.bacnet4j.type.AmbiguousValue.<init>(AmbiguousValue.java:11)
                                        at com.serotonin.bacnet4j.type.constructed.PriorityValue.<init>(PriorityValue.java:83)
                                        ... 43 more
                                

                                Any Idea?

                                Arne

                                1 Reply Last reply Reply Quote 0
                                • A
                                  apl
                                  last edited by

                                  Hi Matthew,

                                  this happends by ObjectType == multiStateOutput and analogOutput

                                  Arne

                                  1 Reply Last reply Reply Quote 0
                                  • M
                                    mlohbihler
                                    last edited by

                                    If the goal is to provide a set of simple examples, i would think the reporting of possible errors would just clutter things up.

                                    But in any case, i still cannot reproduce this error. It appears to be an incorrectly formatted response. I expanded my test code to the following. It won't work for you because i added some convenience methods in the PropertyValues object, but i think you'll see what i'm getting at.

                                            LocalDevice localDevice = new LocalDevice(1234, &quot;192.168.0.255&quot;);
                                            localDevice.initialize();
                                            localDevice.sendBroadcast(2068, new WhoIsRequest(null, null));
                                            
                                            Thread.sleep(1000);
                                            
                                            RemoteDevice d = localDevice.getRemoteDevices().get(0);
                                            
                                            ObjectIdentifier oid = new ObjectIdentifier(ObjectType.analogInput, 0);
                                            PropertyReferences refs = new PropertyReferences();
                                            for (int i=0; i&lt200; i++)
                                                refs.add(oid, new PropertyIdentifier(i));
                                            
                                            PropertyValues pvs = localDevice.readProperties(d, refs);
                                            for (ObjectPropertyReference opr : pvs)
                                                System.out.println(pvs.getNoErrorCheck(opr));
                                            
                                            Thread.sleep(2000);
                                            
                                            localDevice.terminate();
                                    
                                    

                                    The listener that returned the response is the SlaveDeviceTest example.

                                    Best regards,
                                    Matthew

                                    1 Reply Last reply Reply Quote 0
                                    • M
                                      mlohbihler
                                      last edited by

                                      Hi Arne,

                                      I have a fix for the PriorityArray (87). The class was not decoding properly. I have checked the updates into the CVS repo, but did not release a new version of the library. Here are the changes:

                                      In PriorityArray, added an int to the constructor:

                                          public PriorityArray(ByteQueue queue, int contextId) throws BACnetException {
                                              super(queue, PriorityValue.class, contextId);
                                          }
                                      
                                      

                                      In Encodable, added this method:

                                          protected static &lt;T extends Encodable&gt; T readSequenceType(ByteQueue queue, Class&lt;T&gt; clazz, int contextId)
                                                  throws BACnetException {
                                              popStart(queue, contextId);
                                              T result;
                                              try {
                                                  result = clazz.getConstructor(new Class[] {ByteQueue.class, Integer.TYPE}).newInstance(
                                                          new Object[] {queue, contextId});
                                              }
                                              catch (Exception e) {
                                                  throw new BACnetException(e);
                                              }
                                              popEnd(queue, contextId);
                                              return result;
                                          }
                                      
                                      

                                      ... and added a call to that method in this method as shown:

                                          protected static Encodable readEncodable(ByteQueue queue, ObjectType objectType,
                                                  PropertyIdentifier propertyIdentifier, UnsignedInteger propertyArrayIndex, int contextId)
                                                  throws BACnetException {
                                              // A property array index of 0 indicates a request for the length of an array.
                                              if (propertyArrayIndex != null && propertyArrayIndex.intValue() == 0)
                                                  return readWrapped(queue, UnsignedInteger.class, contextId);
                                              
                                              if (!matchNonEndTag(queue, contextId))
                                                  throw new BACnetErrorException(ErrorClass.property, ErrorCode.missingRequiredParameter);
                                              
                                              PropertyTypeDefinition def = ObjectProperties.getPropertyTypeDefinition(objectType, propertyIdentifier);
                                              if (def == null)
                                                  return new AmbiguousValue(queue, contextId);
                                              
                                              if (propertyArrayIndex != null && !def.isSequence())
                                                  throw new BACnetErrorException(ErrorClass.property, ErrorCode.propertyIsNotAList);
                                              if (propertyArrayIndex == null && def.isSequence())
                                                  return readSequenceOf(queue, def.getClazz(), contextId);
                                              if (propertyArrayIndex == null && SequenceOf.class.isAssignableFrom(def.getClazz()))
                                                  return readSequenceType(queue, def.getClazz(), contextId);
                                              
                                              return readWrapped(queue, def.getClazz(), contextId);
                                          }
                                      
                                      

                                      Can you let me know if this has any effect on the other types you mentioned (8 and 105).

                                      Best regards,
                                      Matthew

                                      1 Reply Last reply Reply Quote 0
                                      • A
                                        apl
                                        last edited by

                                        Thank you, iI got it from CVS.

                                        so here is my next "streamlined" ex DiscoveryTest example

                                        It sends a WhoIs Request, waits for the first device to answer (in doDiscover()).
                                        And then it requests all available Properties with PropertyIdentifier.all.
                                        Then it prints the properties sorted by ObjectId.

                                        /*
                                         * ============================================================================
                                         * GNU Lesser General Public License
                                         * ============================================================================
                                         *
                                         * Copyright (C) 2006-2009 Serotonin Software Technologies Inc. http://serotoninsoftware.com
                                         * @author Matthew Lohbihler
                                         * 
                                         * This library is free software; you can redistribute it and/or
                                         * modify it under the terms of the GNU Lesser General Public
                                         * License as published by the Free Software Foundation; either
                                         * version 2.1 of the License, or (at your option) any later version.
                                         * 
                                         * This library is distributed in the hope that it will be useful,
                                         * but WITHOUT ANY WARRANTY; without even the implied warranty of
                                         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                                         * Lesser General Public License for more details.
                                         * 
                                         * You should have received a copy of the GNU Lesser General Public
                                         * License along with this library; if not, write to the Free Software
                                         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
                                         */
                                        package com.serotonin.bacnet4j.test;
                                        
                                        import com.serotonin.bacnet4j.RemoteObject;
                                        import com.serotonin.bacnet4j.exception.BACnetException;
                                        import com.serotonin.bacnet4j.obj.BACnetObject;
                                        import com.serotonin.bacnet4j.type.Encodable;
                                        import com.serotonin.bacnet4j.type.constructed.Choice;
                                        import com.serotonin.bacnet4j.type.constructed.PropertyValue;
                                        import com.serotonin.bacnet4j.type.constructed.TimeStamp;
                                        import com.serotonin.bacnet4j.type.enumerated.EventState;
                                        import com.serotonin.bacnet4j.type.enumerated.EventType;
                                        import com.serotonin.bacnet4j.type.enumerated.MessagePriority;
                                        import com.serotonin.bacnet4j.type.enumerated.NotifyType;
                                        import com.serotonin.bacnet4j.type.notificationParameters.NotificationParameters;
                                        import com.serotonin.bacnet4j.type.primitive.Boolean;
                                        import com.serotonin.bacnet4j.type.primitive.CharacterString;
                                        import java.io.IOException;
                                        import java.util.List;
                                        
                                        import com.serotonin.bacnet4j.LocalDevice;
                                        import com.serotonin.bacnet4j.RemoteDevice;
                                        import com.serotonin.bacnet4j.event.DeviceEventListener;
                                        import com.serotonin.bacnet4j.service.unconfirmed.WhoIsRequest;
                                        import com.serotonin.bacnet4j.type.constructed.ObjectPropertyReference;
                                        import com.serotonin.bacnet4j.type.constructed.SequenceOf;
                                        import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier;
                                        import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
                                        import com.serotonin.bacnet4j.type.primitive.UnsignedInteger;
                                        import com.serotonin.bacnet4j.util.PropertyReferences;
                                        import com.serotonin.bacnet4j.util.PropertyValues;
                                        import java.util.ArrayList;
                                        
                                        /**
                                         * Discovers and devices and print all properties of all objects found.
                                         * this is done by using PropertyIdentifier.all so the Device will send all propertys that are set.
                                         * if you want poll all PropertyId {@link ReadPropertyRangeTest}.
                                         *
                                         * @author Matthew Lohbihler
                                         * @author Arne Plöse
                                         */
                                        public class ReadAllAvailabeProperties {
                                        
                                            public static String BROADCAST_ADDRESS = "127.0.0.255";
                                            private LoopDevice loopDevice;
                                            private LocalDevice localDevice;
                                            // remote devices found
                                            private List<RemoteDevice> remoteDevices = new ArrayList<RemoteDevice>();
                                        
                                            public ReadAllAvailabeProperties(String broadcastAddress, int port) throws IOException {
                                                localDevice = new LocalDevice(1234, broadcastAddress);
                                                localDevice.setPort(port);
                                                localDevice.getEventHandler().addListener(new DeviceEventListener() {
                                        
                                                    public void listenerException(Throwable e) {
                                                        System.out.println("DiscoveryTest listenerException");
                                                    }
                                        
                                                    public void iAmReceived(RemoteDevice d) {
                                                        System.out.println("DiscoveryTest iAmReceived");
                                                        remoteDevices.add(d);
                                                        synchronized (ReadAllAvailabeProperties.this) {
                                                            ReadAllAvailabeProperties.this.notifyAll();
                                                        }
                                                    }
                                        
                                                    public boolean allowPropertyWrite(BACnetObject obj, PropertyValue pv) {
                                                        System.out.println("DiscoveryTest allowPropertyWrite");
                                                        return true;
                                                    }
                                        
                                                    public void propertyWritten(BACnetObject obj, PropertyValue pv) {
                                                        System.out.println("DiscoveryTest propertyWritten");
                                                    }
                                        
                                                    public void iHaveReceived(RemoteDevice d, RemoteObject o) {
                                                        System.out.println("DiscoveryTest iHaveReceived");
                                                    }
                                        
                                                    public void covNotificationReceived(UnsignedInteger subscriberProcessIdentifier, RemoteDevice initiatingDevice, ObjectIdentifier monitoredObjectIdentifier, UnsignedInteger timeRemaining, SequenceOf<PropertyValue> listOfValues) {
                                                        System.out.println("DiscoveryTest covNotificationReceived");
                                                    }
                                        
                                                    public void eventNotificationReceived(UnsignedInteger processIdentifier, RemoteDevice initiatingDevice, ObjectIdentifier eventObjectIdentifier, TimeStamp timeStamp, UnsignedInteger notificationClass, UnsignedInteger priority, EventType eventType, CharacterString messageText, NotifyType notifyType, Boolean ackRequired, EventState fromState, EventState toState, NotificationParameters eventValues) {
                                                        System.out.println("DiscoveryTest eventNotificationReceived");
                                                    }
                                        
                                                    public void textMessageReceived(RemoteDevice textMessageSourceDevice, Choice messageClass, MessagePriority messagePriority, CharacterString message) {
                                                        System.out.println("DiscoveryTest textMessageReceived");
                                                    }
                                        
                                                    public void privateTransferReceived(UnsignedInteger vendorId, UnsignedInteger serviceNumber, Encodable serviceParameters) {
                                                        System.out.println("DiscoveryTest privateTransferReceived");
                                                    }
                                                });
                                                localDevice.initialize();
                                        
                                            }
                                        
                                            /**
                                             * Send a WhoIs request and wait for the first to answer
                                             * @throws java.lang.Exception
                                             */
                                            public void doDiscover() throws Exception {
                                                // Who is
                                                System.out.println("Send Broadcast WhoIsRequest() ");
                                                // Send the broadcast to the correct port of the LoopDevice !!!
                                                localDevice.sendBroadcast(loopDevice.getPort(), new WhoIsRequest(null, null));
                                        
                                                // wait for notification in iAmReceived() Timeout 2 sec
                                                synchronized (this) {
                                                    final long start = System.currentTimeMillis();
                                                    this.wait(2000);
                                                    System.out.println(" waited for iAmReceived: " + (System.currentTimeMillis() - start) + " ms");
                                                }
                                        
                                                // An other way to get to the list of devices
                                                // return localDevice.getRemoteDevices();
                                            }
                                        
                                            private void printDevices() throws BACnetException {
                                                for (RemoteDevice d : remoteDevices) {
                                        
                                                    localDevice.getExtendedDeviceInformation(d);
                                        
                                                    List<ObjectIdentifier> oids = ((SequenceOf<ObjectIdentifier>) localDevice.sendReadPropertyAllowNull(
                                                            d, d.getObjectIdentifier(), PropertyIdentifier.objectList)).getValues();
                                        
                                                    PropertyReferences refs = new PropertyReferences();
                                                    // add the property references of the "device object" to the list
                                                    refs.add(d.getObjectIdentifier(), PropertyIdentifier.all);
                                        
                                                    // and now from all objects under the device object >> ai0, ai1,bi0,bi1...
                                                    for (ObjectIdentifier oid : oids) {
                                                        refs.add(oid, PropertyIdentifier.all);
                                                    }
                                        
                                                    System.out.println("Start read properties");
                                                      final long start = System.currentTimeMillis();
                                        
                                                    PropertyValues pvs = localDevice.readProperties(d, refs);
                                                    System.out.println(String.format("Properties read done in %d ms", System.currentTimeMillis() - start));
                                                    printObject(d.getObjectIdentifier(), pvs);
                                                    for (ObjectIdentifier oid : oids) {
                                                        printObject(oid, pvs);
                                                    }
                                        
                                        
                                                }
                                        
                                                System.out.println("Remote devices done...");
                                            }
                                        
                                            private void printObject(ObjectIdentifier oid, PropertyValues pvs) {
                                                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)));
                                                    }
                                        
                                                }
                                            }
                                        
                                            /**
                                             * Note same Bropadcast address, but different ports!!!
                                             * @param args
                                             * @throws java.lang.Exception
                                             */
                                            @SuppressWarnings("unchecked")
                                            public static void main(String[] args) throws Exception {
                                                ReadAllAvailabeProperties dt = new ReadAllAvailabeProperties(BROADCAST_ADDRESS, LocalDevice.DEFAULT_PORT);
                                                try {
                                                    dt.setLoopDevice(new LoopDevice(BROADCAST_ADDRESS, LocalDevice.DEFAULT_PORT + 1));
                                                } catch (RuntimeException e) {
                                                    dt.localDevice.terminate();
                                                    throw e;
                                                }
                                                try {
                                                    dt.doDiscover();
                                                    dt.printDevices();
                                                } finally {
                                                    dt.localDevice.terminate();
                                                    System.out.println("Cleanup loopDevice");
                                                    dt.getLoopDevice().doTerminate();
                                                }
                                            }
                                        
                                            /**
                                             * @return the loopDevice
                                             */
                                            public LoopDevice getLoopDevice() {
                                                return loopDevice;
                                            }
                                        
                                            /**
                                             * @param loopDevice the loopDevice to set
                                             */
                                            public void setLoopDevice(LoopDevice loopDevice) {
                                                this.loopDevice = loopDevice;
                                            }
                                        }
                                        

                                        If you find this useful, you may add this to CVS.

                                        If you interested, I would write a read specific property the old DiscoveryTest and a writeProperty test.

                                        Arne

                                        1 Reply Last reply Reply Quote 0
                                        • M
                                          mlohbihler
                                          last edited by

                                          Hi Arne,

                                          This looks great. I will add it to the distribution, but a couple things:

                                          • I changed the class name from ReadAllAvailabeProperties to ReadAllAvailableProperties

                                          • You reference a class named LoopDevice for which i don't have the code. Can you provide it? (Is it just a RemoteObject?)

                                          Best regards,
                                          Matthew

                                          1 Reply Last reply Reply Quote 0
                                          • A
                                            apl
                                            last edited by

                                            Ok,

                                            here we go:

                                            /*
                                             * ============================================================================
                                             * GNU Lesser General Public License
                                             * ============================================================================
                                             *
                                             * Copyright (C) 2006-2009 Serotonin Software Technologies Inc. http://serotoninsoftware.com
                                             * @author Matthew Lohbihler
                                             * 
                                             * This library is free software; you can redistribute it and/or
                                             * modify it under the terms of the GNU Lesser General Public
                                             * License as published by the Free Software Foundation; either
                                             * version 2.1 of the License, or (at your option) any later version.
                                             * 
                                             * This library is distributed in the hope that it will be useful,
                                             * but WITHOUT ANY WARRANTY; without even the implied warranty of
                                             * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                                             * Lesser General Public License for more details.
                                             * 
                                             * You should have received a copy of the GNU Lesser General Public
                                             * License along with this library; if not, write to the Free Software
                                             * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
                                             */
                                            package com.serotonin.bacnet4j.test;
                                            
                                            import com.serotonin.bacnet4j.LocalDevice;
                                            import com.serotonin.bacnet4j.RemoteDevice;
                                            import com.serotonin.bacnet4j.RemoteObject;
                                            import com.serotonin.bacnet4j.event.DeviceEventListener;
                                            import com.serotonin.bacnet4j.exception.BACnetServiceException;
                                            import com.serotonin.bacnet4j.obj.BACnetObject;
                                            import com.serotonin.bacnet4j.type.Encodable;
                                            import com.serotonin.bacnet4j.type.constructed.Choice;
                                            import com.serotonin.bacnet4j.type.constructed.PropertyValue;
                                            import com.serotonin.bacnet4j.type.constructed.SequenceOf;
                                            import com.serotonin.bacnet4j.type.constructed.TimeStamp;
                                            import com.serotonin.bacnet4j.type.enumerated.BinaryPV;
                                            import com.serotonin.bacnet4j.type.enumerated.EngineeringUnits;
                                            import com.serotonin.bacnet4j.type.enumerated.EventState;
                                            import com.serotonin.bacnet4j.type.enumerated.EventType;
                                            import com.serotonin.bacnet4j.type.enumerated.MessagePriority;
                                            import com.serotonin.bacnet4j.type.enumerated.NotifyType;
                                            import com.serotonin.bacnet4j.type.enumerated.ObjectType;
                                            import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier;
                                            import com.serotonin.bacnet4j.type.enumerated.Reliability;
                                            import com.serotonin.bacnet4j.type.notificationParameters.NotificationParameters;
                                            import com.serotonin.bacnet4j.type.primitive.Boolean;
                                            import com.serotonin.bacnet4j.type.primitive.CharacterString;
                                            import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
                                            import com.serotonin.bacnet4j.type.primitive.Real;
                                            import com.serotonin.bacnet4j.type.primitive.UnsignedInteger;
                                            import java.io.IOException;
                                            
                                            /**
                                             *
                                             * software only device default local loop ;-)
                                             *
                                             * @author mlohbihler
                                             * @author aploese
                                             */
                                            public class LoopDevice implements Runnable {
                                            
                                                public static void main(String[] args) throws Exception {
                                                    LoopDevice ld = new LoopDevice("127.0.0.255", LocalDevice.DEFAULT_PORT + 1);
                                                    Thread.sleep(12000); // wait 2 min
                                                    ld.doTerminate();
                                                }
                                                private boolean terminate;
                                                private LocalDevice localDevice;
                                                private BACnetObject ai0;
                                                private BACnetObject ai1;
                                                private BACnetObject bi0;
                                                private BACnetObject bi1;
                                                private BACnetObject mso0;
                                                private BACnetObject ao0;
                                            
                                                public LoopDevice(String broadcastAddress, int port) throws BACnetServiceException, IOException {
                                                    localDevice = new LocalDevice(1968, broadcastAddress);
                                                    try {
                                                        localDevice.setPort(port);
                                                        localDevice.getEventHandler().addListener(new DeviceEventListener() {
                                            
                                                            public void listenerException(Throwable e) {
                                                                System.out.println("loopDevice listenerException");
                                                            }
                                            
                                                            public void iAmReceived(RemoteDevice d) {
                                                                System.out.println("loopDevice iAmReceived");
                                                            }
                                            
                                                            public boolean allowPropertyWrite(BACnetObject obj, PropertyValue pv) {
                                                                System.out.println("loopDevice allowPropertyWrite");
                                                                return true;
                                                            }
                                            
                                                            public void propertyWritten(BACnetObject obj, PropertyValue pv) {
                                                                System.out.println("loopDevice propertyWritten");
                                                            }
                                            
                                                            public void iHaveReceived(RemoteDevice d, RemoteObject o) {
                                                                System.out.println("loopDevice iHaveReceived");
                                                            }
                                            
                                                            public void covNotificationReceived(UnsignedInteger subscriberProcessIdentifier, RemoteDevice initiatingDevice, ObjectIdentifier monitoredObjectIdentifier, UnsignedInteger timeRemaining, SequenceOf<PropertyValue> listOfValues) {
                                                                System.out.println("loopDevice covNotificationReceived");
                                                            }
                                            
                                                            public void eventNotificationReceived(UnsignedInteger processIdentifier, RemoteDevice initiatingDevice, ObjectIdentifier eventObjectIdentifier, TimeStamp timeStamp, UnsignedInteger notificationClass, UnsignedInteger priority, EventType eventType, CharacterString messageText, NotifyType notifyType, Boolean ackRequired, EventState fromState, EventState toState, NotificationParameters eventValues) {
                                                                System.out.println("loopDevice eventNotificationReceived");
                                                            }
                                            
                                                            public void textMessageReceived(RemoteDevice textMessageSourceDevice, Choice messageClass, MessagePriority messagePriority, CharacterString message) {
                                                                System.out.println("loopDevice textMessageReceived");
                                                            }
                                            
                                                            public void privateTransferReceived(UnsignedInteger vendorId, UnsignedInteger serviceNumber, Encodable serviceParameters) {
                                                                System.out.println("loopDevice privateTransferReceived");
                                                            }
                                                        });
                                            
                                                        // for valid property values with valid datatypes see com.serotonin.bacnet4j.obj.ObjectProperties and ther look for the big static block at the end;
                                                        // properties of device object
                                                        localDevice.getConfiguration().setProperty(PropertyIdentifier.modelName, new CharacterString("BACnet4J LoopDevice"));
                                            
                                                        // Set up a few objects.
                                                        ai0 = new BACnetObject(localDevice, localDevice.getNextInstanceObjectIdentifier(ObjectType.analogInput));
                                            
                                                        //mandatory properties
                                                        ai0.setProperty(PropertyIdentifier.objectName, new CharacterString("G1-RLT03-TM-01")); // this is a cryptic encoded name of a temp sensor from a drawing... (ahm. actually taken from a book ;-))
                                                        ai0.setProperty(PropertyIdentifier.presentValue, new Real((float)11));
                                                        ai0.setProperty(PropertyIdentifier.outOfService, new Boolean(false));
                                                        ai0.setProperty(PropertyIdentifier.units, EngineeringUnits.degreesCelsius);
                                            
                                                        //some optional properties
                                                        ai0.setProperty(PropertyIdentifier.description, new CharacterString("temperature"));
                                                        ai0.setProperty(PropertyIdentifier.deviceType, new CharacterString("random values"));
                                                        ai0.setProperty(PropertyIdentifier.reliability, Reliability.noFaultDetected);
                                                        ai0.setProperty(PropertyIdentifier.updateInterval, new UnsignedInteger(10));
                                            
                                                        ai0.setProperty(PropertyIdentifier.minPresValue, new Real(-70));
                                                        ai0.setProperty(PropertyIdentifier.maxPresValue, new Real(120));
                                                        ai0.setProperty(PropertyIdentifier.resolution, new Real((float)0.1));
                                                        ai0.setProperty(PropertyIdentifier.profileName, new CharacterString("funny reader"));
                                            
                                                        localDevice.addObject(ai0);
                                            
                                                        ai1 = new BACnetObject(
                                                                localDevice, localDevice.getNextInstanceObjectIdentifier(ObjectType.analogInput));
                                                        ai1.setProperty(PropertyIdentifier.units, EngineeringUnits.percentObscurationPerFoot);
                                                        localDevice.addObject(ai1);
                                            
                                                        bi0 = new BACnetObject(
                                                                localDevice, localDevice.getNextInstanceObjectIdentifier(ObjectType.binaryInput));
                                                        localDevice.addObject(bi0);
                                                        bi0.setProperty(PropertyIdentifier.objectName, new CharacterString("Off and on"));
                                                        bi0.setProperty(PropertyIdentifier.inactiveText, new CharacterString("Off"));
                                                        bi0.setProperty(PropertyIdentifier.activeText, new CharacterString("On"));
                                            
                                                        bi1 = new BACnetObject(
                                                                localDevice, localDevice.getNextInstanceObjectIdentifier(ObjectType.binaryInput));
                                                        localDevice.addObject(bi1);
                                                        bi1.setProperty(PropertyIdentifier.objectName, new CharacterString("Good and bad"));
                                                        bi1.setProperty(PropertyIdentifier.inactiveText, new CharacterString("Bad"));
                                                        bi1.setProperty(PropertyIdentifier.activeText, new CharacterString("Good"));
                                            
                                                        mso0 = new BACnetObject(
                                                                localDevice, localDevice.getNextInstanceObjectIdentifier(ObjectType.multiStateOutput));
                                                        mso0.setProperty(PropertyIdentifier.objectName, new CharacterString("Vegetable"));
                                                        mso0.setProperty(PropertyIdentifier.numberOfStates, new UnsignedInteger(4));
                                                        mso0.setProperty(PropertyIdentifier.stateText, 1, new CharacterString("Tomato"));
                                                        mso0.setProperty(PropertyIdentifier.stateText, 2, new CharacterString("Potato"));
                                                        mso0.setProperty(PropertyIdentifier.stateText, 3, new CharacterString("Onion"));
                                                        mso0.setProperty(PropertyIdentifier.stateText, 4, new CharacterString("Broccoli"));
                                                        mso0.setProperty(PropertyIdentifier.presentValue, new UnsignedInteger(1));
                                                        localDevice.addObject(mso0);
                                            
                                                        ao0 = new BACnetObject(
                                                                localDevice, localDevice.getNextInstanceObjectIdentifier(ObjectType.analogOutput));
                                                        ao0.setProperty(PropertyIdentifier.objectName, new CharacterString("Settable analog"));
                                                        localDevice.addObject(ao0);
                                            
                                            
                                                        // Start the local device.
                                                        localDevice.initialize();
                                                        new Thread(this).start();
                                                    } catch (RuntimeException e) {
                                                        System.out.println("Ex in LoopDevice() ");
                                                        e.printStackTrace();
                                                        localDevice.terminate();
                                                        localDevice = null;
                                                        throw e;
                                                    }
                                                }
                                            
                                                public void run() {
                                                    try {
                                                        System.out.println("LoopDevice start changing values" + this);
                                            
                                                        // Let it go...
                                                        float ai0value = 0;
                                                        float ai1value = 0;
                                                        boolean bi0value = false;
                                                        boolean bi1value = false;
                                            
                                                        getMso0().setProperty(PropertyIdentifier.presentValue, new UnsignedInteger(2));
                                                        while (!isTerminate()) {
                                                            System.out.print("Change values of LoopDevice " + this);
                                            
                                            
                                                            // Update the values in the objects.
                                                            ai0.setProperty(PropertyIdentifier.presentValue, new Real(ai0value));
                                                            ai1.setProperty(PropertyIdentifier.presentValue, new Real(ai1value));
                                                            bi0.setProperty(PropertyIdentifier.presentValue, bi0value ? BinaryPV.active : BinaryPV.inactive);
                                                            bi1.setProperty(PropertyIdentifier.presentValue, bi1value ? BinaryPV.active : BinaryPV.inactive);
                                            
                                                            synchronized (this) {
                                                                wait(1000); // 1 second or notified (faster exit then stupid wait for 1 second)
                                                            }
                                                        }
                                                        System.out.println("Close LoopDevive " + this);
                                                    } catch (Exception ex) {
                                                    }
                                                    localDevice.terminate();
                                                    localDevice = null;
                                                }
                                            
                                                @Override
                                                protected void finalize() throws Throwable {
                                                    if (localDevice != null) {
                                                        localDevice.terminate();
                                                        localDevice = null;
                                                    }
                                                }
                                            
                                                /**
                                                 * @return the terminate
                                                 */
                                                public boolean isTerminate() {
                                                    return terminate;
                                                }
                                            
                                                /**
                                                 * @param terminate the terminate to set
                                                 */
                                                public void doTerminate() {
                                                    this.terminate = true;
                                                    synchronized (this) {
                                                        this.notifyAll(); // we may wait for this in run() ...
                                                    }
                                                }
                                            
                                                /**
                                                 * @return the broadcastAddress
                                                 */
                                                public String getBroadcastAddress() {
                                                    return localDevice.getBroadcastAddress();
                                                }
                                            
                                                /**
                                                 * @return the port
                                                 */
                                                public int getPort() {
                                                    return localDevice.getPort();
                                                }
                                            
                                                /**
                                                 * @return the localDevice
                                                 */
                                                public LocalDevice getLocalDevice() {
                                                    return localDevice;
                                                }
                                            
                                                /**
                                                 * @return the ai0
                                                 */
                                                public BACnetObject getAi0() {
                                                    return ai0;
                                                }
                                            
                                                /**
                                                 * @return the ai1
                                                 */
                                                public BACnetObject getAi1() {
                                                    return ai1;
                                                }
                                            
                                                /**
                                                 * @return the bi0
                                                 */
                                                public BACnetObject getBi0() {
                                                    return bi0;
                                                }
                                            
                                                /**
                                                 * @return the bi1
                                                 */
                                                public BACnetObject getBi1() {
                                                    return bi1;
                                                }
                                            
                                                /**
                                                 * @return the mso0
                                                 */
                                                public BACnetObject getMso0() {
                                                    return mso0;
                                                }
                                            
                                                /**
                                                 * @return the ao0
                                                 */
                                                public BACnetObject getAo0() {
                                                    return ao0;
                                                }
                                            }
                                            

                                            the classname was a typo, thank you.

                                            You (or probably me) can improve it to pass a broadcastaddress and timeout via main().

                                            Arne

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post