• J
    Joshua

    Hi again,

    What is the remote device cache designed for? If I want to store a local representation of the state of a remote BACnet device that is on the network, is the remote device cache the built-in way to go about this?

    Basically I'm thinking when I read from or write to the remote device, I would update the cache with the result, keeping a near up-to-date representation of the remote device on the local device. Is this the intended purpose of the cache?

    Thanks,
    Joshua

    posted in BACnet4J general discussion read more
  • J
    Joshua

    @phildunlap Perfect, thank you. Not sure how I missed that file before, but it will be extremely useful in the future.

    Cheers!

    posted in BACnet4J general discussion read more
  • J
    Joshua

    Hi again,

    We're trying to send a WritePropertyRequest to the Present Value property of a Binary Value object, however the response (ack) we get back from the remote device is an error, with errorClass = 2 // property and errorCode = 9 // invalidDataType. We're sending a property value of type Boolean, which is what I'd expect to be the accepted data type for a binary value, but maybe I'm wrong. Also I'm not quite sure about the propertyArrayIndex parameter. So I guess I'm wondering if the following parameters are correct:

    // Kotlin
    localDevice.send(remoteDevice,
                     WritePropertyRequest(ObjectIdentifier(ObjectType.binaryValue, 2), // object
                                          PropertyIdentifier.presentValue, // property
                                          null, // propertyArrayIndex. null since the present value property is not an array (?)
                                          Boolean.valueOf(true), // propertyValue
                                          UnsignedInteger(1)), // priority
                      ResponseConsumer())
    

    Thanks in advance,
    Joshua

    posted in BACnet4J general discussion read more
  • J
    Joshua

    @phildunlap

    You were right, my Kotlin dependency was using the java 7 stdlib, not 8. That's why it complained and crashed at the lambda.

    I will remember your tip about SIGSEGV in the future!

    Thank you.

    posted in BACnet4J general discussion read more
  • J
    Joshua

    Hey there,

    I've managed to get the BACnet4J library running on my Android Things device ( a master on an MS/TP network), communicating with another BACnet device (another master). See my previous question for more info.

    However, when I try to send a WhoIsRequest to the other device, it reads in the response and then my whole application crashes. Here is a log:

    2018-09-27 17:11:57.831 5290-5316/my.company.peripheraltest D/UartOutputStream: bytes written:	[55,ff,6,ff,11,0,4,1a,1,0,10,8,bc,f9]
    2018-09-27 17:11:57.832 5290-5316/my.company.peripheraltest W/System.err: [BACnet4J MS/TP node] DEBUG com.serotonin.bacnet4j.npdu.mstp.MasterNode - 17 doneWithToken:SendMaintenancePFM
    2018-09-27 17:11:57.846 5290-5316/my.company.peripheraltest D/UartOutputStream: bytes written:	[55,ff,1,13,11,0,0,6f]
    2018-09-27 17:11:57.867 5290-5316/my.company.peripheraltest W/System.err: [BACnet4J MS/TP node] DEBUG com.serotonin.bacnet4j.npdu.mstp.MasterNode - 17 pollForMaster:DoneWithPFM
    2018-09-27 17:11:57.881 5290-5316/my.company.peripheraltest D/UartOutputStream: bytes written:	[55,ff,0,18,11,0,0,35]
    2018-09-27 17:11:57.893 5290-5290/my.company.peripheraltest D/UartInputStream: bytes read:		[55,ff,6,ff,18,0,15,41]
    2018-09-27 17:11:57.894 5290-5316/my.company.peripheraltest W/System.err: [BACnet4J MS/TP node] DEBUG com.serotonin.bacnet4j.npdu.mstp.MasterNode - 17 passToken:SawTokenUser
    2018-09-27 17:11:57.902 5290-5290/my.company.peripheraltest D/UartInputStream: bytes read:		[1,20,ff,ff,0,ff,10,0]
    2018-09-27 17:11:57.910 5290-5290/my.company.peripheraltest D/UartInputStream: bytes read:		[c4,2,0,0,7c,22,1,e0]
    2018-09-27 17:11:57.921 5290-5290/my.company.peripheraltest D/UartInputStream: bytes read:		[91,3,22,1,4,83,b8]
    2018-09-27 17:11:57.923 5290-5316/my.company.peripheraltest W/System.err: [BACnet4J MS/TP node] DEBUG com.serotonin.bacnet4j.npdu.mstp.MasterNode - 17 idle:ReceivedDataNoReply
    2018-09-27 17:11:57.925 5290-5316/my.company.peripheraltest W/System.err: [BACnet4J MS/TP node] DEBUG com.serotonin.bacnet4j.npdu.Network - Received NPDU from local network. From=Address [networkNumber=0, macAddress=[18]], local=0
    2018-09-27 17:11:57.929 5290-5316/my.company.peripheraltest W/System.err: [BACnet4J MS/TP node] DEBUG com.serotonin.bacnet4j.npdu.Network - Received NPDU from [18]: NPDU [from=Address [networkNumber=0, macAddress=[18]], linkService=null, queue=[10,0,c4,2,0,0,7c,22,1,e0,91,3,22,1,4]]
    2018-09-27 17:11:57.933 5290-5290/my.company.peripheraltest D/UartInputStream: bytes read:		[55,ff,1,1b,18,0,0,7f]
        
        --------- beginning of crash
    2018-09-27 17:11:57.936 5290-5317/my.company.peripheraltest A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x68 in tid 5317 (BACnet4J transp), pid 5290 (.peripheraltest)
    2018-09-27 17:11:57.985 5322-5322/? I/crash_dump32: type=1400 audit(0.0:643): avc: denied { write } for name="trace_marker" dev="tracefs" ino=47 scontext=u:r:crash_dump:s0:c512,c768 tcontext=u:object_r:debugfs_tracing:s0 tclass=file permissive=1
    2018-09-27 17:11:58.048 5323-5323/? I/crash_dump32: obtaining output fd from tombstoned, type: kDebuggerdTombstone
    2018-09-27 17:11:58.049 196-196/? I//system/bin/tombstoned: received crash request for pid 5290
    2018-09-27 17:11:58.050 5323-5323/? I/crash_dump32: performing dump of process 5290 (target tid = 5317)
    2018-09-27 17:11:58.050 5323-5323/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    2018-09-27 17:11:58.051 5323-5323/? A/DEBUG: Build fingerprint: 'Things/iot_rpi3/rpi3:8.1.0/OIM1.180327.056/4925377:userdebug/dev-keys'
    2018-09-27 17:11:58.051 5323-5323/? A/DEBUG: Revision: '0'
    2018-09-27 17:11:58.051 5323-5323/? A/DEBUG: ABI: 'arm'
    2018-09-27 17:11:58.051 5323-5323/? A/DEBUG: pid: 5290, tid: 5317, name: BACnet4J transp  >>> my.company.peripheraltest <<<
    2018-09-27 17:11:58.051 5323-5323/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x68
    2018-09-27 17:11:58.051 5323-5323/? A/DEBUG: Cause: null pointer dereference
    ...
    

    The crash and dump are not very useful, but it does say that the cause is a null pointer dereference.

    Although I can't reproduce it right now, sometimes when I run in debug mode in Android Studio, I get a different crash error:

    2018-09-27 17:43:56.784 5998-6025/my.company.peripheraltest E/AndroidRuntime: FATAL EXCEPTION: BACnet4J transport for device 123
        Process: my.company.peripheraltest, PID: 5998
        java.lang.BootstrapMethodError: Exception from call site #50 bootstrap method
            at com.serotonin.bacnet4j.service.unconfirmed.IAmRequest.handle(IAmRequest.java:109)
            at com.serotonin.bacnet4j.transport.DefaultTransport.receiveAPDU(DefaultTransport.java:645)
            at com.serotonin.bacnet4j.transport.DefaultTransport.receiveImpl(DefaultTransport.java:573)
            at com.serotonin.bacnet4j.transport.DefaultTransport.run(DefaultTransport.java:493)
            at java.lang.Thread.run(Thread.java:764)
         Caused by: java.lang.NoClassDefFoundError: Invalid descriptor: ([FLjava/util/Map;Lkotlin/jvm/functions/Function1;)Ljava/util/Map;.
            at com.serotonin.bacnet4j.service.unconfirmed.IAmRequest.handle(IAmRequest.java:109) 
            at com.serotonin.bacnet4j.transport.DefaultTransport.receiveAPDU(DefaultTransport.java:645) 
            at com.serotonin.bacnet4j.transport.DefaultTransport.receiveImpl(DefaultTransport.java:573) 
            at com.serotonin.bacnet4j.transport.DefaultTransport.run(DefaultTransport.java:493) 
            at java.lang.Thread.run(Thread.java:764) 
    

    When I debug, I can get as far as line 109 of IAmRequest (in the handle method). That line is:

    localDevice.execute(() -> { ... });
    

    So I think it's to do with the runnable or something that is happening within the runnable, but I'm not sure. It doesn't get to line 118, which fires the IAmReceived callback.

    I've never seen this type of crash or error before, so any help would be appreciated. Maybe I'm just not setting everything up completely right.

    Here is my code:

    byte thermostatMACAddress = 17;
    int networkNumber = 0;
    int localDeviceId = 123;
    UartInputStream ins = new UartInputStream(uartDevice);
    UartOutputStream outs = new UartOutputStream(uartDevice, txControlPin);
    MasterNode thermostatNode = new MasterNode("UART", ins, outs, thermostatMACAddress, 1);
    MstpNetwork network = new MstpNetwork(thermostatNode, networkNumber);
    DefaultTransport transport = new DefaultTransport(network);
    localDevice = new LocalDevice(localDeviceId, transport);
    try {
        localDevice.initialize();
        localDevice.getEventHandler().addListener(new Listener());
        localDevice.sendLocalBroadcast(new WhoIsRequest());
    } catch (Exception e) {
        e.printStackTrace();
    }
    

    posted in BACnet4J general discussion read more
  • J
    Joshua

    @phildunlap

    If you don't have to worry about that, you can just set your network number to 0 which is the local network number.

    Great, I will use 0 for the network number.

    If you are looking to bridge the two networks, then you'll need a LocalDevice on each, and your code will be reading from one of them, and setting the object values on the other (so that it can be polled by the other devices on the 485 bus (or they could have registered for COV on those objects, or you can set them out to the devices)

    Could you explain this a little more further? I thought in our situation there's only one network, so I'm not quite sure what you mean by bridging the two networks.

    As I understand it, I need to set up my Android device as a LocalDevice and I will send commands to/subscribe to COVs on the heat pump, which will be a RemoteDevice. Do I need a second LocalDevice somewhere?

    Thanks for your help, I appreciate it.

    posted in BACnet4J general discussion read more
  • J
    Joshua

    Thanks Phil, I wasn't understanding the input stream concept correctly. I understand now I will have to provide my own implementation of InputStream/OutputStream that uses the Android Uart API.

    Thanks for clearing up my confusion!
    Joshua

    posted in BACnet4J general discussion read more
  • J
    Joshua

    Hi Phil,

    Thank you very much for your detailed reply.

    My main confusion is how the InputStream works. An InputStream does not represent a continuous stream of data, it only contains a fixed number of bytes, and there's no way to 'update' the input stream to add more bytes, without creating a new one. So I don't know how the library keeps on reading the continuous data from the device via an InputStream.

    posted in BACnet4J general discussion read more
  • J
    Joshua

    We're trying to implement BACnet on our Android Things device and we're wondering if/how we can use the BACnet4J library to accomplish this. Our device will act as a thermostat/heat pump controller.

    Our setup:

    • MSTP network
    • Using UART/RS-485 to communicate from Android Things device (master) to a BACnet-ready heat pump (another master)
    • Will be adding more devices to the MSTP network in the future

    I'm not exactly sure how to connect the way Android reads in bytes from UART to the BACnet4J library. Here is the documentation for Android Things UART: https://developer.android.com/things/sdk/pio/uart. With the setup described in the documentation (using the callback), I am able to read in bytes from the heat pump. Right now I can see by looking at the byte arrays coming in that it is polling for master, i.e.

    55 ff 1 0 18 0 0 91 
    55 ff 1 1 18 0 0 a2 
    55 ff 1 2 18 0 0 3a 
    ...
    

    My question is how do I convert the incoming bytes from the heat pump (and other devices on the network) into service requests/objects that my device can understand and respond to if necessary.

    Also, I understand that I need to set up my Android Things device as a LocalDevice. However the localDevice needs a Transport, which needs a (Mstp)Network, which needs a (Mstp)Node. I don't know how to set all this up. If someone could describe how to implement this hierarchy it would be greatly appreciated. Specifically

    • How do I set up the MstpNetwork? How do I choose the localNetworkNumber?
    • MstpNetwork needs an MstpNode. How does a Node differ from a local/remote device? Why is there only one Node per network? What should I provide for the portId parameter?

    I think it's probably obvious that I am new to BACnet and the BACnet4J library. I would be super grateful for any help!

    Thank you
    Joshua

    posted in BACnet4J general discussion read more