Test sample don't compile, please update
-
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
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 thecom.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?
-
https://github.com/infiniteautomation/BACnet4J/tree/a9696f25dde11ce7ee65b9a2487f91f015fce83a
This should be version 3.2.2 (the one I'm using)
-
I solved by replacing
writeProperty
withwritePropertyImpl
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.