How to automate reading and writing values in yabe with bacnet4j Jar

317 views Asked by At

I am new to bacnet automation and to bacnet4j, We have a bacnet server that broadcast bacnet points and I could see that in yabe manually by adding the device. In this case, my laptop and the server are connected to the same network. How can i automate the same? I need to read and write the values. From where should i start? could anyone help

3

There are 3 answers

0
Peter Knall On

I found the initial learning curve to get started with BACnet4J somewhat steep, however I was able to get started with BAC0 far quicker (which is in Python). You may find that easier.

0
DennisVM-D2i On

An answer of mine (if not out of date) might help slightly, at least as a bare-bones starting-point (possibly accelerating your progress) -

https://stackoverflow.com/questions/77480088/connect-to-bacnet-device-with-java-using-bacnet4j/77501045#77501045

Forewarning: I'm not a BACnet4J developer nor a Java developer; and I'm using Windows 10.

To start with, you could add 'SLF4J' ('reload4') to get a small sense of what is occurring, e.g. something like so (- having got the libraries online):

-classpath %CD%;Lib\bacnet4j-3.2.2.jar;Lib\slf4j-api-1.7.36.jar;Lib\commons-lang3-3.12.0.jar;Lib\reload4j-1.2.19.jar;Lib\slf4j-reload4j-1.7.36.jar

E.g. With the 'log4j.properties' configured:

log = Logs

# Define the root logger with appender file
log4j.rootLogger = DEBUG, FILE

# Define the file appender
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${log}/Log.txt

# Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%d %m%n

And at the beginning of your 'main()' method - to be sure you've configured the logging properly:

            Logger logger = LoggerFactory.getLogger(Main.class);

            logger.info("- Main() -");

You can also (install &) run Wireshark (as Administrator), and put a 'capture filter' of something like 'udp portrange 47808-47823' to see the BACnet/IP traffic that is flowing.

Now more so to your question.

After the device's 'initialize()', you probably need a 'Listener' class to listen out for the 'I-Am's being received:

            localDevice.getEventHandler().addListener(new Listener());

With listener class that is something remotely like this:

    static class Listener extends DeviceEventAdapter
    {
        @Override
        public void iAmReceived(RemoteDevice d)
        {
            try
            {
                System.out.println("IAm received from " + d);
                System.out.println("Segmentation: " + d.getSegmentationSupported());
                d.setSegmentationSupported(Segmentation.noSegmentation);

                Address a = new Address(new Unsigned16(0), new OctetString(new byte[] { (byte) 0xc0, (byte) 0xa8, 0x1,
                        0x5, (byte) 0xba, (byte) 0xc0 }));

                System.out.println("Equals: " + a.equals(d.getAddress()));
                getExtendedDeviceInformation(d);
                System.out.println("Done getting extended information");

                List oids = ((SequenceOf) RequestUtils.sendReadPropertyAllowNull(localDevice, d,
                        d.getObjectIdentifier(), PropertyIdentifier.objectList)).getValues();
                System.out.println(oids);
            }
            catch (BACnetException e)
            {
                e.printStackTrace();
            }
        }
    }

    static void getExtendedDeviceInformation(RemoteDevice d)
        throws BACnetException
    {
        ObjectIdentifier oid = d.getObjectIdentifier();

        ReadPropertyAck ack;

        // -

        System.out.println("ExtDevInfo:  Getting 'Object-Name' .  .   .");

        ack =
            (ReadPropertyAck)
                (
                    localDevice.send(
                        d,
                        new ReadPropertyRequest(
                            oid,
                            PropertyIdentifier.objectName)).get()
                );

        d.setName(ack.getValue().toString());

        // -

        System.out.println("ExtDevInfo:  Getting 'Vendor-Identifier' .  .   .");

        ack =
            (ReadPropertyAck)
                (
                    localDevice.send(
                        d,
                        new ReadPropertyRequest(
                            oid,
                            PropertyIdentifier.vendorIdentifier)).get()
                );

        d.setVendorId(((Unsigned16) ack.getValue()).intValue());

        // -

        System.out.println("ExtDevInfo:  Getting 'Vendor-Name' .  .   .");

        ack =
            (ReadPropertyAck)
                (
                    localDevice.send(
                        d,
                        new ReadPropertyRequest(
                            oid,
                            PropertyIdentifier.vendorName)).get()
                );

        d.setVendorName(ack.getValue().toString());


        // -

        System.out.println("ExtDevInfo:  Getting 'Protocol-Version' .  .   .");

        ack =
            (ReadPropertyAck)
                (
                    localDevice.send(
                        d,
                        new ReadPropertyRequest(
                            oid,
                            PropertyIdentifier.protocolVersion)).get()
                );

        d.setProtocolVersion((UnsignedInteger) ack.getValue());

        // -

        System.out.println("ExtDevInfo:  Getting 'Protocol-Revision' .  .   .");

        ack =
            (ReadPropertyAck)
                (
                    localDevice.send(
                        d,
                        new ReadPropertyRequest(
                            oid,
                            PropertyIdentifier.protocolRevision)).get()
                );

        d.setProtocolRevision((UnsignedInteger) ack.getValue());

        // -

        // Get the device's supported services
        System.out.println("ExtDevInfo:  Getting 'Protocol-Services-Supported' .  .   .");

        ack =
            (ReadPropertyAck)
                (
                    localDevice.send(
                        d,
                        new ReadPropertyRequest(
                            oid,
                            PropertyIdentifier.protocolServicesSupported))
                ).get();

        d.setServicesSupported((ServicesSupported) ack.getValue());

        // -

        System.out.println();
    }

But I'm guessing that this framework, will not fire the listener's 'iAmReceived()' method, if it's for the same device, so you would either need to define another 'device' (/might be good to try as an alternative/easier? starting-point test), or as you've done try using another device (- unless I'm wrong I'm not sure why this API does not appear to have a 'client'-only class / you seem to have to use a 'device' as being the client).

But I'm guessing the problem with you set-up, might be the (local/'255.255.255.255') 'Who-Is' broadcast, whereby it's only going to broadcast to the local subnet, and to devices that are using the same port #; so in terms of orchestrating that, you'd probably be better off using the IPv4 (only) range of addresses (- IPv6 is cack in this regard in that they've reduced the localhost to being only 1 address rather than like IPv4 a localhost range of addresses or even 5-10 addresses?!), so you can have both the client and server device listening upon the same (Class 'A') network but with the same port #.

Ignoring the fact that I seem to have a newer(?) version of the BACnet4J library, i.e. method-names differences:

            IpNetwork network =
                new IpNetworkBuilder()
                        .localBindAddress("127.0.0.1")
                        .port(47810)
                        .subnetMask(hostAddress)
                        .build();

E.g. Possibly something close to what could work for two local host addresses:

// https://repo1.maven.org/maven2/org/slf4j/slf4j-reload4j/1.7.36/

import java.util.List;

import com.serotonin.bacnet4j.LocalDevice;
import com.serotonin.bacnet4j.RemoteDevice;
import com.serotonin.bacnet4j.event.DeviceEventAdapter;
import com.serotonin.bacnet4j.exception.BACnetException;
import com.serotonin.bacnet4j.exception.BACnetTimeoutException;
// import com.serotonin.bacnet4j.npdu.Network;
import com.serotonin.bacnet4j.npdu.ip.IpNetwork;
import com.serotonin.bacnet4j.npdu.ip.IpNetworkBuilder;
// import com.serotonin.bacnet4j.npdu.ip.IpNetworkUtils;
import com.serotonin.bacnet4j.service.acknowledgement.ReadPropertyAck;
import com.serotonin.bacnet4j.service.confirmed.ReadPropertyRequest;
import com.serotonin.bacnet4j.service.unconfirmed.WhoIsRequest;
import com.serotonin.bacnet4j.transport.DefaultTransport;
import com.serotonin.bacnet4j.transport.Transport;
import com.serotonin.bacnet4j.type.constructed.Address;
import com.serotonin.bacnet4j.type.constructed.SequenceOf;
import com.serotonin.bacnet4j.type.constructed.ServicesSupported;
import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier;
import com.serotonin.bacnet4j.type.enumerated.Segmentation;
import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
import com.serotonin.bacnet4j.type.primitive.OctetString;
import com.serotonin.bacnet4j.type.primitive.Unsigned16;
import com.serotonin.bacnet4j.type.primitive.UnsignedInteger;
import com.serotonin.bacnet4j.util.RequestUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class Main
{
    private static LocalDevice localDevice;

    public static void main(String[] args)
        throws Exception
    {
        try
        {
            Logger logger = LoggerFactory.getLogger(Main.class);

            logger.info("- Main() -");

            String hostAddress = "127.255.255.255";
            //String hostAddress = "192.168.0.255";
            //String hostAddress = "192.168.56.255";
            //String hostAddress = "192.168.255.255";

            IpNetwork network =
                new IpNetworkBuilder()
                        .localBindAddress("127.0.0.1")
                        .port(47810)
                        .subnetMask(hostAddress)
                        .build();

            Transport transport = new DefaultTransport(network);

            localDevice = new LocalDevice(3227671, transport);
            localDevice.initialize();

            localDevice.getEventHandler().addListener(new Listener());

            localDevice.sendGlobalBroadcast(new WhoIsRequest());

            int remoteId = 999;
            List<RemoteDevice> remoteDevices = localDevice.getRemoteDevices();

            Thread.sleep(3000);

            RemoteDevice d = remoteDevices.get(0);

            ObjectIdentifier oid = d.getObjectIdentifier();

            ReadPropertyAck ack;

            // -

            System.out.println("ExtDevInfo:  Getting 'Object-Name' .  .   .");

            ack =
                (ReadPropertyAck)
                    (
                        localDevice.send(
                            d,
                            new ReadPropertyRequest(
                                oid,
                                PropertyIdentifier.objectName)).get()
                    );

            d.setName(ack.getValue().toString());

            // -

            System.out.println("ExtDevInfo:  Getting 'Vendor-Identifier' .  .   .");

            ack =
                (ReadPropertyAck)
                    (
                        localDevice.send(
                            d,
                            new ReadPropertyRequest(
                                oid,
                                PropertyIdentifier.vendorIdentifier)).get()
                    );

            d.setVendorId(((Unsigned16) ack.getValue()).intValue());

            // -

            System.out.println("ExtDevInfo:  Getting 'Vendor-Name' .  .   .");

            ack =
                (ReadPropertyAck)
                    (
                        localDevice.send(
                            d,
                            new ReadPropertyRequest(
                                oid,
                                PropertyIdentifier.vendorName)).get()
                    );

            d.setVendorName(ack.getValue().toString());


            // -

            System.out.println("ExtDevInfo:  Getting 'Protocol-Version' .  .   .");

            ack =
                (ReadPropertyAck)
                    (
                        localDevice.send(
                            d,
                            new ReadPropertyRequest(
                                oid,
                                PropertyIdentifier.protocolVersion)).get()
                    );

            d.setProtocolVersion((UnsignedInteger) ack.getValue());

            // -

            System.out.println("ExtDevInfo:  Getting 'Protocol-Revision' .  .   .");

            ack =
                (ReadPropertyAck)
                    (
                        localDevice.send(
                            d,
                            new ReadPropertyRequest(
                                oid,
                                PropertyIdentifier.protocolRevision)).get()
                    );

            d.setProtocolRevision((UnsignedInteger) ack.getValue());

            // -

            // Get the device's supported services
            System.out.println("ExtDevInfo:  Getting 'Protocol-Services-Supported' .  .   .");

            ack =
                (ReadPropertyAck)
                    (
                        localDevice.send(
                            d,
                            new ReadPropertyRequest(
                                oid,
                                PropertyIdentifier.protocolServicesSupported))
                    ).get();

            d.setServicesSupported((ServicesSupported) ack.getValue());

            // -

            System.out.println();
        }
        catch (BACnetTimeoutException exc)
        {
            System.out.flush();

            System.err.println(exc.getMessage());
            System.err.flush();
        }
        catch (BACnetException exc)
        {
            System.out.flush();

            System.err.println(exc.getMessage());
            System.err.flush();
        }
        catch (Exception exc)
        {
            System.out.flush();

            System.err.println(exc.getMessage());
            System.err.flush();
        }
        finally
        {
            localDevice.terminate();

            System.out.println();
        }
    }

    static class Listener extends DeviceEventAdapter
    {
        @Override
        public void iAmReceived(RemoteDevice d)
        {
            try
            {
                System.out.println("IAm received from " + d);
                System.out.println("Segmentation: " + d.getSegmentationSupported());
                d.setSegmentationSupported(Segmentation.noSegmentation);

                Address a = new Address(new Unsigned16(0), new OctetString(new byte[] { (byte) 0xc0, (byte) 0xa8, 0x1,
                        0x5, (byte) 0xba, (byte) 0xc0 }));

                System.out.println("Equals: " + a.equals(d.getAddress()));

                return;
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    static void getExtendedDeviceInformation(RemoteDevice d)
        throws BACnetException
    {
        ObjectIdentifier oid = d.getObjectIdentifier();

        ReadPropertyAck ack;

        // -

        System.out.println("ExtDevInfo:  Getting 'Object-Name' .  .   .");

        ack =
            (ReadPropertyAck)
                (
                    localDevice.send(
                        d,
                        new ReadPropertyRequest(
                            oid,
                            PropertyIdentifier.objectName)).get()
                );

        d.setName(ack.getValue().toString());

        // -

        System.out.println("ExtDevInfo:  Getting 'Vendor-Identifier' .  .   .");

        ack =
            (ReadPropertyAck)
                (
                    localDevice.send(
                        d,
                        new ReadPropertyRequest(
                            oid,
                            PropertyIdentifier.vendorIdentifier)).get()
                );

        d.setVendorId(((Unsigned16) ack.getValue()).intValue());

        // -

        System.out.println("ExtDevInfo:  Getting 'Vendor-Name' .  .   .");

        ack =
            (ReadPropertyAck)
                (
                    localDevice.send(
                        d,
                        new ReadPropertyRequest(
                            oid,
                            PropertyIdentifier.vendorName)).get()
                );

        d.setVendorName(ack.getValue().toString());


        // -

        System.out.println("ExtDevInfo:  Getting 'Protocol-Version' .  .   .");

        ack =
            (ReadPropertyAck)
                (
                    localDevice.send(
                        d,
                        new ReadPropertyRequest(
                            oid,
                            PropertyIdentifier.protocolVersion)).get()
                );

        d.setProtocolVersion((UnsignedInteger) ack.getValue());

        // -

        System.out.println("ExtDevInfo:  Getting 'Protocol-Revision' .  .   .");

        ack =
            (ReadPropertyAck)
                (
                    localDevice.send(
                        d,
                        new ReadPropertyRequest(
                            oid,
                            PropertyIdentifier.protocolRevision)).get()
                );

        d.setProtocolRevision((UnsignedInteger) ack.getValue());

        // -

        // Get the device's supported services
        System.out.println("ExtDevInfo:  Getting 'Protocol-Services-Supported' .  .   .");

        ack =
            (ReadPropertyAck)
                (
                    localDevice.send(
                        d,
                        new ReadPropertyRequest(
                            oid,
                            PropertyIdentifier.protocolServicesSupported))
                ).get();

        d.setServicesSupported((ServicesSupported) ack.getValue());

        // -

        System.out.println();
    }
}

0
Sharan JOhn On

Yes you can write a bacnet Object as per priority u allowed thridparty system to write into your Point . For that go to Global commander Plugin and write