• 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

    Extend from RemoteDevice

    BACnet4J general discussion
    2
    5
    1.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.
    • A
      Andreas Vogt
      last edited by Andreas Vogt

      Hi guys,
      If I "extend" from the class "RemoteDevice" and then create a object of that, I can't use it to send regular BACnet requests. I always run in a NullPointerException.

      /17:02:40.933 [BACnet4J transport for device 10001] ERROR com.serotonin.bacnet4j.transport.DefaultTransport - Error during send: OutgoingConfirmed [maxAPDULengthAccepted=-1, segmentationSupported=null, service=ReadPropertyRequest [objectIdentifier=device 2098177, propertyIdentifier=object-list, propertyArrayIndex=null], consumer=com.serotonin.bacnet4j.transport.ServiceFutureImpl@10a4064, address=Address [networkNumber=0, macAddress=[c0,a8,1,b1,ba,c0]], linkService=null]
      java.lang.NullPointerException: null
      	at com.serotonin.bacnet4j.transport.DefaultTransport$OutgoingConfirmed.sendImpl(DefaultTransport.java:380)
      	at com.serotonin.bacnet4j.transport.DefaultTransport$Outgoing.send(DefaultTransport.java:336)
      	at com.serotonin.bacnet4j.transport.DefaultTransport.run(DefaultTransport.java:486)
      	at java.base/java.lang.Thread.run(Thread.java:830)
      17:02:40.933 [BACnet4J transport for device 10001] ERROR com.serotonin.bacnet4j.transport.DefaultTransport - Original send stack
      java.lang.Exception: null
      	at com.serotonin.bacnet4j.transport.DefaultTransport.send(DefaultTransport.java:292)
      	at com.serotonin.bacnet4j.transport.DefaultTransport.send(DefaultTransport.java:283)
      	at com.serotonin.bacnet4j.LocalDevice.send(LocalDevice.java:989)
      	at com.serotonin.bacnet4j.util.RequestUtils.sendOneAtATime(RequestUtils.java:425)
      	at com.serotonin.bacnet4j.util.RequestUtils.readProperties(RequestUtils.java:396)
      	at com.serotonin.bacnet4j.util.RequestUtils.readProperties(RequestUtils.java:257)
      	at com.serotonin.bacnet4j.util.RequestUtils.getProperties(RequestUtils.java:141)
      	at com.serotonin.bacnet4j.util.RequestUtils.getProperties(RequestUtils.java:136)
      	at com.bacnetbrowser.schoko.DeviceTest$Listener.iAmReceived(DeviceTest.java:40)
      	at com.serotonin.bacnet4j.event.DeviceEventHandler.fireIAmReceived(DeviceEventHandler.java:97)
      	at com.serotonin.bacnet4j.service.unconfirmed.IAmRequest.lambda$handle$0(IAmRequest.java:118)
      	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
      	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
      	at java.base/java.lang.Thread.run(Thread.java:830)
      

      The code I used for testing:

      public class DeviceTest {
          static LocalDevice localDevice;
      
          public static void main(String[] args) throws Exception {
              int localDevice_ID = 10001;
              IpNetworkBuilder ipNetworkBuilder = new IpNetworkBuilder();
              ipNetworkBuilder.withLocalBindAddress(IpNetwork.DEFAULT_BIND_IP);
              ipNetworkBuilder.withBroadcast("255.255.255.255", IpNetwork.BVLC_TYPE);
              ipNetworkBuilder.withPort(47808);
              DefaultTransport transport = new DefaultTransport(ipNetworkBuilder.build());
              localDevice = new LocalDevice(localDevice_ID, transport);
              localDevice.getEventHandler().addListener(new Listener());
              localDevice.initialize();
              localDevice.startRemoteDeviceDiscovery();
          }
      
          static class Listener extends DeviceEventAdapter {
              @Override
              public void iAmReceived(RemoteDevice d) {
                  System.out.println("I am received" + d);
                  Device device = new Device(localDevice, d.getInstanceNumber(), d.getAddress());
                  try {
                      Map<PropertyIdentifier, Encodable> values = RequestUtils.getProperties(
                              localDevice, device, device.getObjectIdentifier(),null,
                              PropertyIdentifier.objectList);
                      System.out.println(values);
                  } catch (BACnetException e) {
                      e.printStackTrace();
                  }
              }
          }
      
          static class Device extends RemoteDevice{
              public Device(LocalDevice localDevice, int instanceNumber, Address address) {
                  super(localDevice, instanceNumber, address);
              }
          }
      
      }
      

      I would be glad if somone could have a look and give me a feedback ;-)

      BR
      Andreas

      1 Reply Last reply Reply Quote 0
      • terrypackerT
        terrypacker
        last edited by

        @andreas-vogt what version of the code are you using? I can't see how that happens when reading the code on the master branch of BACnet4J. I would suggest you put a breakpoint in and find what is null. Then let me know and I can help you from there.

        1 Reply Last reply Reply Quote 0
        • A
          Andreas Vogt
          last edited by Andreas Vogt

          Hello @terrypacker, thank you for answering! :)

          I am using:

          <dependency>
          	<groupId>com.infiniteautomation</groupId>
          	<artifactId>bacnet4j</artifactId>
          	<version>5.0.2</version>
          </dependency>
          

          As I followd the stacktrace I found in the "DefaultTransport" that at the line 769 "Segmentation" is needed. So the "Segmentation" is the object which is null in the "extended" class.
          If I try:

          static class Listener extends DeviceEventAdapter {
            @Override
            public void iAmReceived(RemoteDevice d) {
          
            //Not null
            d.getSegmentationSupported();
            Device device = new Device(localDevice,d.getInstanceNumber(),d.getAddress());
          
            //Here happens a null pointer
            device.getSegmentationSupported();
            }
          }
          

          Therefore I was thinking of override this property and tried this:

          public class DeviceTest {
              static LocalDevice localDevice;
          
              public static void main(String[] args) throws Exception {
                  int localDevice_ID = 10001;
                  IpNetworkBuilder ipNetworkBuilder = new IpNetworkBuilder();
                  ipNetworkBuilder.withLocalBindAddress(IpNetwork.DEFAULT_BIND_IP);
                  ipNetworkBuilder.withBroadcast("255.255.255.255", IpNetwork.BVLC_TYPE);
                  ipNetworkBuilder.withPort(47808);
                  DefaultTransport transport = new DefaultTransport(ipNetworkBuilder.build());
                  localDevice = new LocalDevice(localDevice_ID, transport);
                  localDevice.getEventHandler().addListener(new Listener());
                  localDevice.initialize();
                  localDevice.startRemoteDeviceDiscovery();
              }
          
              static class Listener extends DeviceEventAdapter {
                  @Override
                  public void iAmReceived(RemoteDevice d) {
                      Device device = new Device(localDevice, d.getInstanceNumber(), d.getAddress(), d.getSegmentationSupported());
                      try {
                          Map<PropertyIdentifier, Encodable> values = RequestUtils.getProperties(
                                  localDevice, device, device.getObjectIdentifier(),null,
                                  PropertyIdentifier.objectList);
                          System.out.println(values);
                      } catch (BACnetException e) {
                          e.printStackTrace();
                      }
                  }
              }
          
              static class Device extends RemoteDevice{
                  Segmentation segmentation;
          
                  public Device(LocalDevice localDevice, int instanceNumber, Address address, Segmentation segmentation) {
                      super(localDevice, instanceNumber, address);
                      this.segmentation = segmentation;
                  }
          
                  @Override
                  public Segmentation getSegmentationSupported() {
                      return this.segmentation;
                  }
              }
          }
          

          But I am running in a new exception:

          10:32:31.350 [BACnet4J transport for device 10001] ERROR com.serotonin.bacnet4j.transport.DefaultTransport - Error during send: OutgoingConfirmed [maxAPDULengthAccepted=-1, segmentationSupported=segmented-both, service=ReadPropertyRequest [objectIdentifier=device 2098177, propertyIdentifier=object-list, propertyArrayIndex=null], consumer=com.serotonin.bacnet4j.transport.ServiceFutureImpl@36f5e9d5, address=Address [networkNumber=0, macAddress=[c0,a8,1,b1,ba,c0]], linkService=null]
          java.lang.NegativeArraySizeException: -7
          	at com.serotonin.bacnet4j.transport.DefaultTransport$OutgoingConfirmed.sendImpl(DefaultTransport.java:392)
          	at com.serotonin.bacnet4j.transport.DefaultTransport$Outgoing.send(DefaultTransport.java:336)
          	at com.serotonin.bacnet4j.transport.DefaultTransport.run(DefaultTransport.java:486)
          	at java.base/java.lang.Thread.run(Thread.java:830)
          10:32:31.350 [BACnet4J transport for device 10001] ERROR com.serotonin.bacnet4j.transport.DefaultTransport - Original send stack
          java.lang.Exception: null
          	at com.serotonin.bacnet4j.transport.DefaultTransport.send(DefaultTransport.java:292)
          	at com.serotonin.bacnet4j.transport.DefaultTransport.send(DefaultTransport.java:283)
          	at com.serotonin.bacnet4j.LocalDevice.send(LocalDevice.java:989)
          	at com.serotonin.bacnet4j.util.RequestUtils.sendOneAtATime(RequestUtils.java:425)
          	at com.serotonin.bacnet4j.util.RequestUtils.readProperties(RequestUtils.java:396)
          	at com.serotonin.bacnet4j.util.RequestUtils.readProperties(RequestUtils.java:257)
          	at com.serotonin.bacnet4j.util.RequestUtils.getProperties(RequestUtils.java:141)
          	at com.serotonin.bacnet4j.util.RequestUtils.getProperties(RequestUtils.java:136)
          	at com.bacnetbrowser.schoko.DeviceTest$Listener.iAmReceived(DeviceTest.java:41)
          	at com.serotonin.bacnet4j.event.DeviceEventHandler.fireIAmReceived(DeviceEventHandler.java:97)
          	at com.serotonin.bacnet4j.service.unconfirmed.IAmRequest.lambda$handle$0(IAmRequest.java:118)
          	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
          	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
          	at java.base/java.lang.Thread.run(Thread.java:830)
          

          This time there sems a problem with the getMaxAPDULengthAccepted() of the Remote Device so I overrided this property as well:

          public class DeviceTest {
              static LocalDevice localDevice;
          
              public static void main(String[] args) throws Exception {
                  int localDevice_ID = 10001;
                  IpNetworkBuilder ipNetworkBuilder = new IpNetworkBuilder();
                  ipNetworkBuilder.withLocalBindAddress(IpNetwork.DEFAULT_BIND_IP);
                  ipNetworkBuilder.withBroadcast("255.255.255.255", IpNetwork.BVLC_TYPE);
                  ipNetworkBuilder.withPort(47808);
                  DefaultTransport transport = new DefaultTransport(ipNetworkBuilder.build());
                  localDevice = new LocalDevice(localDevice_ID, transport);
                  localDevice.getEventHandler().addListener(new Listener());
                  localDevice.initialize();
                  localDevice.startRemoteDeviceDiscovery();
              }
          
              static class Listener extends DeviceEventAdapter {
                  @Override
                  public void iAmReceived(RemoteDevice d) {
                      Device device = new Device(localDevice, d.getInstanceNumber(), d.getAddress(), d.getSegmentationSupported());
                      try {
                          Map<PropertyIdentifier, Encodable> values = RequestUtils.getProperties(
                                  localDevice, device, device.getObjectIdentifier(),null,
                                  PropertyIdentifier.objectList);
                          System.out.println(values);
                      } catch (BACnetException e) {
                          e.printStackTrace();
                      }
                  }
              }
          
              static class Device extends RemoteDevice{
                  Segmentation segmentation;
                  int maxAPDULengthAccepted = 1476;
          
                  public Device(LocalDevice localDevice, int instanceNumber, Address address, Segmentation segmentation) {
                      super(localDevice, instanceNumber, address);
                      this.segmentation = segmentation;
                  }
          
                  @Override
                  public Segmentation getSegmentationSupported() {
                      return this.segmentation;
                  }
          
                  @Override
                  public int getMaxAPDULengthAccepted() {
                      return maxAPDULengthAccepted;
                  }
              }
          }
          

          This is working but I do not know if I am on the right way.

          BR
          Andreas

          1 Reply Last reply Reply Quote 0
          • terrypackerT
            terrypacker
            last edited by terrypacker

            @Andreas-Vogt you are not on the correct path with this solution. I suggest you take a look at how the IamRequest class calls iAmReceived(RemoteDevice d).

            Specifically this section of code from around line 110:

            final RemoteDevice rd = new RemoteDevice(localDevice, remoteDoi, from);
            rd.setDeviceProperty(PropertyIdentifier.maxApduLengthAccepted, maxAPDULengthAccepted);
            rd.setDeviceProperty(PropertyIdentifier.segmentationSupported, segmentationSupported);
            rd.setDeviceProperty(PropertyIdentifier.vendorIdentifier, vendorId);
            
            1 Reply Last reply Reply Quote 0
            • A
              Andreas Vogt
              last edited by Andreas Vogt

              Hi guys, its been a while since I opened this thread. I am sorry for my late answer but I was very busy lately..
              I have followed the call @terrypacker has mentioned and wanted to let you konw how I implemnted my BACnetDevice class which extends from the RemoteDevice back then. I am sure there is a better way but for me it is working. I guess that there are not many cases in which someone really needs to "extend" from Remotedevice.
              But...
              I'll have a closer look in the next weeks cause I'll do a littlebit refactoring in my code, if I can get a better solution I'll post the progress here. Just in case someone needs to know :)

              So my current implementation:

              In the constructor of my own class I am forcing to implement the missing properties.

              public BACnetDevice(LocalDevice localDevice, int instanceNumber, Address address, Segmentation segmentation,
                                int vendorIdentifier,int maxAPDULengthAccepted) {
                      super(localDevice, instanceNumber, address);
                      this.setDeviceProperty(PropertyIdentifier.maxApduLengthAccepted, new UnsignedInteger(maxAPDULengthAccepted));
                      this.setDeviceProperty(PropertyIdentifier.segmentationSupported, segmentation);
                      this.setDeviceProperty(PropertyIdentifier.vendorIdentifier, new UnsignedInteger(vendorIdentifier));
                  }
              

              By the listener I am fetching the needed properties from the existing instanz

              @Override
                  public void iAmReceived(RemoteDevice d) {
                      BACnetDevice bacnetDevice = new BACnetDevice(localDevice, d.getInstanceNumber(), d.getAddress(),
                              d.getSegmentationSupported(), d.getVendorIdentifier(), d.getMaxAPDULengthAccepted());
                      waitingRoomBacnetDevices.put(bacnetDevice.getInstanceNumber(), bacnetDevice);
                      LOG.info("Remote device " + d.getInstanceNumber() + " registered in waiting room of LocalDevice");
                  }
              
              1 Reply Last reply Reply Quote 0
              • First post
                Last post