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

Test sample don't compile, please update


  • The sample sources on github don't compile against the official version (4.1.6). Could somebody please update at least this one:

    https://github.com/infiniteautomation/BACnet4J/blob/master/src_test/com/serotonin/bacnet4j/test/SlaveDeviceTest.java

    Thanks!


  • This part of the source was left for legacy reference but is not intended to be updated. If you import the repository as an Eclipse project you will see that this folder is not on the build path.


  • Where can I see how to implement a Slave device with the updated library?



  • Thanks, this has been very helpful! But how do I translate this to the new API?

            localDevice.getConfiguration().setProperty(PropertyIdentifier.objectName,
                    new CharacterString("my device"));

  • You would create a BACnet Object for the "device" object type, and on that object set its properties, and add the BACnet object to the local device. There is an example of instantiating a BACnet object in Terry's link, and there is a

    public BACnetObject writePropertyInternal(final PropertyIdentifier pid, final Encodable value)
    

    method you can invoke on the BACnetObject to set the properties.


  • Thanks, I made past the compilation phase. But now my device isn't discovered on the network by the client... what is the meaning of

                    .withLocalBindAddress("0.0.0.0")
                    .withLocalNetworkNumber(20)
                    .withBroadcast(broadcast, 255)
    

    I assumed the first one was the ip address of the client (not sure why the code has 0.0.0.0, and have no idea on what to put on the second.
    Then I start with

            // Start the local device.
            localDevice.initialize();
            
            // Send an iam.
            localDevice.sendGlobalBroadcast(localDevice.getIAm());
    
            localDevice.sendGlobalBroadcast(new WhoIsRequest());

  • I assumed the first one was the ip address of the client (not sure why the code has 0.0.0.0,

    The bind address is the network address the local device is listening on. This is information the operating system uses to route the message, and because BACnet uses broadcasts it is often necessary to bind the 0 address (at least in any bits not covered by the subnet) to inform the operating system you would like to receive the broadcasts. So, this is the address your local device is listening on

    have no idea on what to put on the second.

    The network number is part of the BACnet specification.

    ..withBroadcast(broadcast, 255)

    This seems like Terry's link may have brought you astray.. If we consult that method's signature: BACnet4J Github we see

    public IpNetworkBuilder withBroadcast(final String broadcastAddress, final int networkPrefixLength)
    

    So that network prefix is way too long (unless someone spec'ed out IPv6x2 and I missed the message). The code it calls to convert that into a subnet mask will treat anything greater than 31 as a netmask of 255.255.255.255 which is probably not what you want. You probably want 24, for 255.255.255.0 or to match whatever your network prefix length actually is.


  • Thanks, but still unable to make it work. I noticed that on the old version of the bacnet4j it was necessary to set the IP address of the client but this setting is no longer present.

    The support from Bacnet test tool is telling me that my device is not hearing the who-is message.


  • You can experiment with a different broadcast address perhaps, such as the broadcast address specific to the network segment you've defined. Like, 192.168.1.255 for the 192.168.1.0/24 network.


  • I've changed the broadcast address but didn't help either... I've tried with wireshark and with the old version I see the bacnet packets

    0_1536138422760_bacnet.png

    With the new version I don't see anything.

    Is there some logging that I can enable to see if at least the "who-is" packet is received from the device?
    Thanks


  • Is there some logging that I can enable to see if at least the "who-is" packet is received from the device?

    Yes. You can probably use the debug-log4j2.xml file from Mango/classes/ with the Java argument -Dlog4j.configurationFile=/path/to/Mango/classes/debug-log4j2.xml which has the entry <AsyncLogger includeLocation="true" name="com.serotonin.bacnet4j" level="debug"/> (which you can lower to "trace" level logging for even more information), and you will see output into the command line and into the location specified in the debug-log4j2.xml file (the ma.log file). Or you can supply a log4j2 configuration of your own devising. The main things is that the com.serotonin.bacnet4j package be logging at either trace or debug level.


  • Bacnet4j 4.x requires Java8, which I do not have, so I switched to Bacnet4j 3.x
    Is Bacnet4j 3.x still supported?

    Also I got

    com.serotonin.bacnet4j.exception.BACnetRuntimeException: com.serotonin.bacnet4j.exception.BACnetServiceException: class=Property, code=writeAccessDenied
            at com.serotonin.bacnet4j.obj.BACnetObject.writeProperty(BACnetObject.java:355)
            at com.ups.bacnet.Bacnet.run(Bacnet.java:619)
            at java.lang.Thread.run(Thread.java:748)
    Caused by: com.serotonin.bacnet4j.exception.BACnetServiceException: class=Property, code=writeAccessDenied
            at com.serotonin.bacnet4j.obj.mixin.CommandableMixin.writeProperty(CommandableMixin.java:132)
            at com.serotonin.bacnet4j.obj.BACnetObject.writeProperty(BACnetObject.java:430)
            at com.serotonin.bacnet4j.obj.BACnetObject.writeProperty(BACnetObject.java:352)
            ... 2 common frames omitted
    

    While doing

    AnalogValueObject avin1;
    avin1 = new AnalogValueObject(localDevice.getNextInstanceObjectNumber(ObjectType.analogInput),"Input voltage", 232, EngineeringUnits.volts, false);
    localDevice.addObject(avin1);
    avin1.writeProperty(PropertyIdentifier.presentValue, new Real(1));
    

  • Bacnet4j 4.x requires Java8, which I do not have, so I switched to Bacnet4j 3.x
    Is Bacnet4j 3.x still supported?

    Not really. No further development is likely to be done on 3.x to my knowledge, but the original author is still the maintainer so he has some discretion over that.

    While doing

    All i'm noticing offhand is that you're using ObjectType.analogInput instead of ObjectType.analogValue to get the next object number when you're making an AnalogValueObject - which is probably not what was desired.

    After that I notice those are probably line numbers from 3.x because they do not align with the current state of the code. I couldn't figure out quite which method signature for 'writeProperty' you were attempting to invoke, either. Do you have a link to the repository in the state you're using it?



  • I solved by replacing writeProperty with writePropertyImpl which skips "using mixins"... no idea of what is it.

    Also I noticed that on the old version the device was always discovered, but with this version, the device is discovered only if started while the client is running. I suspect that the old version did send getIAM periodically...


  • Also: how does this snippet translates with the new API?

            obj.setProperty(PropertyIdentifier.objectName, new CharacterString("Mains status"));
            obj.setProperty(PropertyIdentifier.inactiveText, new CharacterString("Not present"));
            obj.setProperty(PropertyIdentifier.activeText, new CharacterString("Present"));
    

    Thanks


  • Are you perhaps looking for the writePropertyInternal method of BACnetObject ?


  • Ok thanks, that solves most of my issues. But I noticed that on the old version the device was always discovered, but with this version, the device is discovered only if started while the client is running. I suspect that the old version did send getIAM periodically...

    Should I start a thread and send getIAM every 30 seconds or so?


  • Do you mean WhoIsRequest? You could elect to send another WhoIs in certain situations (such as not finding all the devices you expect, on a timer, etc) but you'll note that the LocalDevice::getRemoteDevice method calls RemoteDeviceFinder.findDevice (at least in the most recent version of it) which will specifically send the WhoIs for that device. Recall that there is the device cache in the local device to prevent retrying device resolution over and over rapidly if a device isn't found.