How to integrate BACnet Change Of Value (COV) using BACnet4J
-
Hi Gatos,
I think the SlaveDeviceTest needs to know about the SimpleSubscriptionClient before it will accept COV requests from it. I found that if you start the SlaveDeviceTest, then the SimpleSubscriptionClient, stop the SimpleSubscriptionClient, comment out the sendBroadcast and then start it again. COV requests still work, that is because the slave device already knows about the SimpleSubscriptionClient.
An alternative to a broadcast would be to send a direct iAm to the slave device by adding this after line 25:
localDevice.sendUnconfirmed(d.getAddress(), null, localDevice.getIAm());
I'm still pretty new to BACnet myself, so I'm not sure the technical reason why simply attempting to subscribe by COV, doesn't implicitly add the device to the SlaveDeviceTest.
-
Hey,
Thanks, again!
I've read in the forum that you have done some research on the issue "COV subscriptions for Analog Inputs/Outputs".
Could you tell me what's the status there? Any solutions or workarounds for implementing it with bacnet4j described somewhere?Cheers,
Gatos -
Hi Gatos,
We're still in discussions with our client if they want us to implement COV subscriptions for analog values.
A simple workaround or "dirty hack" is simply to add
supportedObjectTypes.add(ObjectType.analogValue); supportedObjectTypes.add(ObjectType.analogInput); supportedObjectTypes.add(ObjectType.analogOutput);
to ObjectCovSubscription
That will make it accept the COV subscriptions, and it will send COV notifications, however, it will send a COV notification for any change of the analog value. Which for analog values is probably a bad thing, because they could be changing all the time. The real solution needs to implement some sort of threshold, so that COV notifications are only sent once the value changes enough.
-
Hi This Taresh,
can u please send me code to read analog values,
as it is urgently required for our project
-
Hi Taresh,
If you're talking about the analog COV subscription changes, that was merged in Nov 2012, see: http://forum.infiniteautomation.com/forum/posts/list/1207.page
-
Can u please share the code to read (Request and response sorce code for analog values)
am trying some what like this ,, but am getting timeout exception
package com.lnt.TestApp;
import java.util.List;
import com.serotonin.bacnet4j.LocalDevice;
import com.serotonin.bacnet4j.RemoteDevice;
import com.serotonin.bacnet4j.enums.MaxApduLength;
import com.serotonin.bacnet4j.npdu.ip.IpNetwork;
import com.serotonin.bacnet4j.service.acknowledgement.AcknowledgementService;
import com.serotonin.bacnet4j.service.acknowledgement.AtomicReadFileAck;
import com.serotonin.bacnet4j.service.acknowledgement.ReadPropertyAck;
import com.serotonin.bacnet4j.service.confirmed.AtomicReadFileRequest;
import com.serotonin.bacnet4j.service.confirmed.ConfirmedRequestService;
import com.serotonin.bacnet4j.service.confirmed.ReadPropertyRequest;
import com.serotonin.bacnet4j.service.unconfirmed.WhoIsRequest;
import com.serotonin.bacnet4j.transport.Transport;
import com.serotonin.bacnet4j.type.Encodable;
import com.serotonin.bacnet4j.type.constructed.Address;
import com.serotonin.bacnet4j.type.constructed.SequenceOf;
import com.serotonin.bacnet4j.type.enumerated.ObjectType;
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.util.RequestUtils;public class Test {
static LocalDevice lDevice;
static Address addr = new Address(0, "IP");public Test() { } public static void main(String args[]) { initializeDevice(); } public static void initializeDevice() { try { System.out.println("Initializing..."); IpNetwork ipNetwork = new IpNetwork("Ip", 47808,"Ip"); Transport transport = new Transport(ipNetwork); lDevice = new LocalDevice(9899, transport); lDevice.initialize(); lDevice.getEventHandler().addListener(new Listener()); lDevice.sendGlobalBroadcast(new WhoIsRequest()); Thread.sleep(500); getObjectList(lDevice, "Ip", 47808, 0); } catch (Exception e) { System.out.println("Error : " + e.getMessage()); } finally { closeDevice(); } } public static AcknowledgementService send(LocalDevice d, ConfirmedRequestService s) throws Exception {
// Address a = new Address(InetAddrCache.get("localhost", 0xbac1));
return d.send(addr, null, MaxApduLength.UP_TO_1476, Segmentation.segmentedBoth, s);
}public static void closeDevice() { try { lDevice.terminate(); } catch (Exception e) { System.out.println(e.getMessage()); } } private static void getObjectList(LocalDevice localDevice, String ip, int port, int deviceId) throws Exception { RemoteDevice fileDev = null; ObjectIdentifier file = null; ReadPropertyRequest readPropertyRequest; ReadPropertyAck reaPropertyAck; for (RemoteDevice d : localDevice.getRemoteDevices()) {
// ObjectIdentifier oid = d.getObjectIdentifier();
@SuppressWarnings("unchecked")
List<ObjectIdentifier> oids = ((SequenceOf<ObjectIdentifier>) RequestUtils
.sendReadPropertyAllowNull(localDevice, d, d.getObjectIdentifier(),PropertyIdentifier.objectList)).getValues();Address address[] = lDevice.getAllLocalAddresses(); OctetString octetString = new OctetString("Ip", 47808); for (int i = 0; i < oids.size(); i++) { System.out.println("OBjectIdentifier"+oids); } for (ObjectIdentifier oid : oids) { readPropertyRequest = new ReadPropertyRequest(oid, PropertyIdentifier.objectName); reaPropertyAck = (ReadPropertyAck) localDevice.send(d, readPropertyRequest); System.out.println("Value: " + reaPropertyAck.getValue()); if (oid.getObjectType().equals(ObjectType.file)) { fileDev = d; file = oid; AtomicReadFileRequest request = new AtomicReadFileRequest(file, false, 0, 1412); AtomicReadFileAck response = (AtomicReadFileAck) localDevice.send(fileDev, request); System.out.println("eof: " + response.getEndOfFile()); System.out.println("start: "+ response.getFileStartPosition()); System.out.println("data: " + new String(response.getFileData().getBytes())); System.out.println("length: "+ response.getFileData().getBytes().length); } if (oid.getObjectType().equals(ObjectType.analogValue)) { fileDev = d; file = oid; readPropertyRequest = new ReadPropertyRequest(new ObjectIdentifier(ObjectType.analogValue, 243), PropertyIdentifier.clientCovIncrement); reaPropertyAck = (ReadPropertyAck) localDevice.send(d, readPropertyRequest); System.out.println(reaPropertyAck.getValue()); } } } }
}
am getting timke exception for reading analog values
-
I haven't used BACNet4j for over a year, but from the code you provided, it doesn't look like you have another bacnet device that would be responding to the requests. You'd need to have a BACnet "server" or slave device actually sending the values.
For example, to get this test to work:
You need to have this test already running in the background:
I'd recommend that you start by getting the samples working, before trying other things.
-
No i have server running in my premisis,,,,
i can see the list of devices also.... if u see my output you can see objects
and the link u shared, am not able to open bcz restriction,,, can u please share the code??
-
I'm not going to paste the code in the forum, because you really need the bacnet4j source so that you can test it out, download the source from http://sourceforge.net/projects/bacnet4j/files/bacnet4j/1.3/
and make sure you don't have any problems with running all the tests.
And as I said before, it's been over a year since I touched bacnet4j, so good luck, I'm sure once you have the source, you'll figure out what is going wrong.