BACnet4J COV Setup: Implement Subscriptions and Alerts

James Nishida6 min read
Industrial NetworkingOther ManufacturerTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

A BACnet4J device that handles only Read Property Request traffic does not yet provide COV operation. Add server-side subscription management, change detection, notification transmission, and expiration or cancellation handling. A configuration switch can expose an implemented capability, but it cannot supply the missing runtime behavior.

Implementation Go/No-Go Check

Before anything else, confirm whether the Slave Device Test Program already contains a COV service path. Search its documented capabilities and runtime diagnostics rather than assuming that successful property reads imply COV support.

Observed result Meaning Next check
Only Read Property Request is handled The device can answer polling requests, but no subscription path has been demonstrated. Check incoming COV subscription handling.
A subscription request reaches application code The protocol stack recognizes the service. Verify acceptance, storage, and response.
The request is accepted but no notification follows Subscription intake works; change detection or notification dispatch is incomplete. Trace the monitored value and outbound traffic.
Notifications stop after a period The subscription may have expired, been replaced, or lost its communication path. Inspect lifetime state and renewal traffic.

Do not move on until the test client can issue a COV subscription request and the device can distinguish that request from ordinary property reads. If the test program has no handler or extension point for it, additional BACnet4J application code is required.

Subscription Intake Check

COV is subscriber-driven. A client requests monitoring of an object, and the server retains enough state to address notifications and manage the subscription. Reading a property neither creates nor renews that state.

  1. Start the BACnet4J device and the test client with protocol logging or packet capture active.
  2. Send one COV subscription request for an object whose value can be changed deliberately.
  3. Confirm that the request arrives at the device. No arrival points to addressing, routing, device discovery, or client configuration rather than change-detection logic.
  4. Confirm that the application accepts or rejects the request explicitly. A timeout means the service is not dispatched, the response path is broken, or an exception interrupted processing.
  5. After acceptance, inspect the active-subscription state. It must retain the monitored object, subscriber destination, subscriber process reference, confirmation preference, and requested lifetime information.

If the stack decodes the request but the application never records it, implement the service callback or handler appropriate to the installed BACnet4J version. Do not copy an API method name from another release; locate the subscription service interface in the version actually used by the project.

Active-State Decision

A valid subscription is temporary runtime state, not a permanent device property. The server uses it to decide who receives a notification, which object is monitored, whether acknowledgment is expected, and when monitoring ends.

State reading Diagnosis Action
No entry after acceptance The handler acknowledges without registering the subscription. Add or connect the subscription registry.
Entry exists with the wrong object Request fields are mapped incorrectly. Correct object lookup before testing changes.
Entry disappears immediately Lifetime interpretation, cancellation handling, or cleanup logic is wrong. Trace creation and removal decisions.
Entry remains after its lifetime Expiration processing is missing. Add periodic expiration and removal.
Repeated requests create duplicates Renewal is being treated as an unrelated subscription. Update the matching entry according to its subscription identity.

Test renewal and cancellation separately from initial creation. A server that only adds entries will eventually send duplicate notifications or retain stale destinations. A server that keys entries too broadly can overwrite a different client’s subscription.

Change-Detection Check

After confirming active state, change the monitored value through the same application path used during normal operation. Editing an unrelated variable or changing a displayed value without updating the BACnet object will not exercise COV processing.

  1. Record the monitored property’s current value.
  2. Apply one controlled change that should qualify for reporting.
  3. Confirm that the BACnet object now exposes the new value to a read request.
  4. Trace whether the change reaches the COV evaluation path.
  5. Confirm that the qualifying rule marks the subscription for notification.

The qualifying rule depends on the object and property semantics. Some values can be evaluated as state changes; analog-style values may use an increment or deadband. Read the object configuration or BACnet4J object implementation to identify the rule actually applied. Do not convert every internal update into a notification: doing so defeats COV traffic reduction and can flood subscribers with unchanged or insignificant values.

If a read returns the new value but COV evaluation never runs, connect the application’s value-update path to the BACnet object’s change mechanism. Directly mutating storage outside that mechanism can bypass listeners, comparison logic, or event dispatch.

Notification-Path Check

When change detection succeeds, inspect the outbound path. The server must build a notification from the active subscription, address it to the subscriber, and use the requested confirmed or unconfirmed behavior.

  1. Confirm that notification construction runs once for the qualifying change.
  2. Verify that the destination comes from the active subscription rather than from a fixed test address.
  3. Capture outbound BACnet traffic at the server interface.
  4. If a packet leaves but the client shows nothing, check routing, network selection, client filtering, and the return path.
  5. If confirmed delivery is used, verify acknowledgment handling and observe any retransmission or failure diagnostics produced by the stack.

An initial notification may be generated when a subscription is established, depending on the implemented service behavior. Treat that initial report separately from a later notification caused by a value change. Otherwise, one startup packet can be mistaken for proof that ongoing detection works.

Implementation and Commissioning Procedure

  1. Register COV subscription handling in the BACnet4J server application. Confirm that an incoming request reaches the handler before adding object logic.
  2. Validate the requested object and service conditions. Return an explicit protocol response through the stack; do not silently discard unsupported requests.
  3. Create an active-subscription record containing the subscriber, monitored object, process reference, delivery preference, and lifetime state. Confirm the record immediately after acceptance.
  4. Connect normal value updates to COV evaluation. Confirm with a property read that the BACnet object holds the changed value, then verify that the qualifying rule fires.
  5. Dispatch the notification through BACnet4J using the stored destination and delivery preference. Confirm the packet in a capture and the update at the client.
  6. Implement renewal, cancellation, and expiration. Confirm that renewal updates the intended record, cancellation removes it, and expiration stops later notifications.
  7. Restart the device and repeat the test. Confirm that no old runtime subscription survives unless persistence was deliberately designed, then create a fresh subscription and reproduce the full sequence.

Frequently Asked Questions

Why does BACnet4J answer reads but not send COV notifications?

Read Property Request support proves only the polling path. Add subscription intake, active-state storage, qualifying change detection, and outbound notification dispatch.

Why does a COV subscription succeed but value changes stay silent?

First confirm that a read returns the changed value. If it does, trace whether the update passed through the BACnet object’s COV evaluation path and whether the change met its configured qualifying rule.

Why does COV work once and then stop?

Inspect the active subscription for expiration, cancellation, replacement, or a lost destination path. Renew the subscription, change the monitored value again, and finish by confirming both the outbound packet and the client’s updated value.

Back to blog