From e12a76023ee28ab5f6b9a4fbe5c332ea2a4c6be8 Mon Sep 17 00:00:00 2001
From: Jacopo Scazzosi
Date: Tue, 21 Apr 2026 11:22:36 +0200
Subject: [PATCH 1/6] feat: adds handling of Out_Of_Service property
* refactors BDObject constructor options into dictionary (used to be individual positional args)
* adds `inservice` and `outofservice` events to BDObject, triggered by changes to Out_Of_Service property
* adds constructor option to BDObject to set network writability of Out_Of_Service property
* adds test suite dedicated to Out_Of_Service property
---
src/objects/binaryvalue.ts | 6 +-
src/objects/characterstringvalue.ts | 6 +-
src/objects/device/device.ts | 2 +-
src/objects/device/types.ts | 3 +-
src/objects/generic/object.ts | 51 +++-
src/objects/multistatevalue.ts | 6 +-
src/objects/numeric/numeric.ts | 6 +-
src/objects/structuredview.ts | 10 +-
src/objects/temporal/datetimevalue.ts | 6 +-
src/objects/temporal/datevalue.ts | 6 +-
src/objects/temporal/timevalue.ts | 6 +-
src/tests/outofservice.test.ts | 425 ++++++++++++++++++++++++++
12 files changed, 499 insertions(+), 34 deletions(-)
create mode 100644 src/tests/outofservice.test.ts
diff --git a/src/objects/binaryvalue.ts b/src/objects/binaryvalue.ts
index 3412ef6..204f706 100644
--- a/src/objects/binaryvalue.ts
+++ b/src/objects/binaryvalue.ts
@@ -1,6 +1,6 @@
import { BDSingletProperty } from '../properties/index.js';
-import { BDObject } from './generic/object.js';
+import { BDObject, type BDObjectOpts } from './generic/object.js';
import {
ObjectType,
ApplicationTag,
@@ -8,7 +8,7 @@ import {
BinaryPV,
} from '@bacnet-js/client';
-export interface BDBinaryValueOpts {
+export interface BDBinaryValueOpts extends BDObjectOpts {
name: string,
writable: boolean,
description?: string,
@@ -20,7 +20,7 @@ export class BDBinaryValue extends BDObject {
readonly presentValue: BDSingletProperty;
constructor(opts: BDBinaryValueOpts) {
- super(ObjectType.BINARY_VALUE, opts.name, opts.description);
+ super(ObjectType.BINARY_VALUE, opts);
this.presentValue = this.addProperty(new BDSingletProperty(
PropertyIdentifier.PRESENT_VALUE, ApplicationTag.ENUMERATED, opts.writable ?? false, opts.presentValue ?? BinaryPV.INACTIVE));
diff --git a/src/objects/characterstringvalue.ts b/src/objects/characterstringvalue.ts
index 01992b3..6e2985e 100644
--- a/src/objects/characterstringvalue.ts
+++ b/src/objects/characterstringvalue.ts
@@ -1,6 +1,6 @@
import { BDSingletProperty } from '../properties/index.js';
-import { BDObject } from './generic/object.js';
+import { BDObject, type BDObjectOpts } from './generic/object.js';
import {
ObjectType,
ApplicationTag,
@@ -8,7 +8,7 @@ import {
CharacterStringEncoding,
} from '@bacnet-js/client';
-export interface BDCharacterStringValueOpts {
+export interface BDCharacterStringValueOpts extends BDObjectOpts {
name: string,
writable?: boolean,
description?: string,
@@ -20,7 +20,7 @@ export class BDCharacterStringValue extends BDObject {
readonly presentValue: BDSingletProperty;
constructor(opts: BDCharacterStringValueOpts) {
- super(ObjectType.CHARACTERSTRING_VALUE, opts.name, opts.description);
+ super(ObjectType.CHARACTERSTRING_VALUE, opts);
this.presentValue = this.addProperty(new BDSingletProperty(
PropertyIdentifier.PRESENT_VALUE, ApplicationTag.CHARACTER_STRING, opts.writable ?? false, opts.presentValue ?? '', CharacterStringEncoding.UTF_8));
diff --git a/src/objects/device/device.ts b/src/objects/device/device.ts
index 353c1b6..754202a 100644
--- a/src/objects/device/device.ts
+++ b/src/objects/device/device.ts
@@ -176,7 +176,7 @@ export class BDDevice extends BDObject implements AsyncEventEmitter, object: BDObject],
+ /** Emitted when the object's {@link BDObject#outOfService | Out_Of_Service} property is set to `false`, either from the network or locally */
+ inservice: [],
+ /** Emitted when the object's {@link BDObject#outOfService | Out_Of_Service} property is set to `true`, either from the network or locally */
+ outofservice: [],
}
/**
@@ -68,6 +72,33 @@ const unlistedProperties: PropertyIdentifier[] = [
PropertyIdentifier.PROPERTY_LIST,
];
+/**
+ * Common options for all BACnet objects
+ *
+ * This interface defines the base configuration parameters shared by every
+ * BACnet object type. Subclass-specific option interfaces (e.g.
+ * {@link BDNumericValueOpts}, {@link BDBinaryValueOpts}) extend this
+ * interface with additional properties.
+ */
+export interface BDObjectOpts {
+ /** The object's name (`Object_Name` property) */
+ name: string;
+ /** An optional textual description of the object (`Description` property) */
+ description?: string;
+ /**
+ * Whether the `Out_Of_Service` property is writable from the BACnet network.
+ *
+ * When `true`, remote BACnet clients can set the object's `Out_Of_Service`
+ * property to `TRUE` or `FALSE`. Changing the property causes the object to
+ * emit an {@link BDObjectEvents.outofservice | outofservice}
+ * or {@link BDObjectEvents.inservice | inservice} event accordingly. Default
+ * is `false`.
+ *
+ * @defaultValue `false`
+ */
+ writableOutOfService?: boolean;
+}
+
/**
* Base class for all BACnet objects
*
@@ -113,7 +144,7 @@ export class BDObject extends AsyncEventEmitter {
* Creates a new BACnet object
*
*/
- constructor(type: ObjectType, name: string, description: string = '') {
+ constructor(type: ObjectType, opts: BDObjectOpts) {
super();
@@ -122,7 +153,7 @@ export class BDObject extends AsyncEventEmitter {
this.#propertyList = [];
this.objectName = this.addProperty(new BDSingletProperty(
- PropertyIdentifier.OBJECT_NAME, ApplicationTag.CHARACTER_STRING, false, name));
+ PropertyIdentifier.OBJECT_NAME, ApplicationTag.CHARACTER_STRING, false, opts.name));
this.objectType = this.addProperty(new BDSingletProperty(
PropertyIdentifier.OBJECT_TYPE, ApplicationTag.ENUMERATED, false, type));
@@ -134,10 +165,10 @@ export class BDObject extends AsyncEventEmitter {
PropertyIdentifier.PROPERTY_LIST, () => this.#propertyList));
this.description = this.addProperty(new BDSingletProperty(
- PropertyIdentifier.DESCRIPTION, ApplicationTag.CHARACTER_STRING, false, description));
+ PropertyIdentifier.DESCRIPTION, ApplicationTag.CHARACTER_STRING, false, opts.description ?? ''));
this.outOfService = this.addProperty(new BDSingletProperty(
- PropertyIdentifier.OUT_OF_SERVICE, ApplicationTag.BOOLEAN, false, false));
+ PropertyIdentifier.OUT_OF_SERVICE, ApplicationTag.BOOLEAN, opts.writableOutOfService ?? false, false));
this.statusFlags = this.addProperty(new BDSingletProperty(
PropertyIdentifier.STATUS_FLAGS, ApplicationTag.BIT_STRING, false, new StatusFlagsBitString()));
@@ -148,6 +179,14 @@ export class BDObject extends AsyncEventEmitter {
this.reliability = this.addProperty(new BDSingletProperty(
PropertyIdentifier.RELIABILITY, ApplicationTag.ENUMERATED, false, Reliability.NO_FAULT_DETECTED));
+ this.outOfService.on('aftercov', (raw) => {
+ if (raw.value) {
+ this.___emit('outofservice');
+ } else {
+ this.___emit('inservice');
+ }
+ });
+
}
get identifier(): BACNetAppData {
@@ -164,6 +203,10 @@ export class BDObject extends AsyncEventEmitter {
throw new Error('Cannot get object device: object has not been added to a device yet');
}
+ isOutOfService(): boolean {
+ return this.outOfService.getValue();
+ }
+
/**
* Adds a property to this object
*
diff --git a/src/objects/multistatevalue.ts b/src/objects/multistatevalue.ts
index e484331..a3a8f57 100644
--- a/src/objects/multistatevalue.ts
+++ b/src/objects/multistatevalue.ts
@@ -7,7 +7,7 @@ import {
BDPolledSingletProperty,
} from '../properties/index.js';
-import { BDObject } from './generic/object.js';
+import { BDObject, type BDObjectOpts } from './generic/object.js';
import {
ObjectType,
@@ -20,7 +20,7 @@ import {
import { BDError } from '../errors.js';
-export interface BDMultiStateValueOpts {
+export interface BDMultiStateValueOpts extends BDObjectOpts {
name: string,
states: [first: string, ...rest: string[]],
writable?: boolean,
@@ -38,7 +38,7 @@ export class BDMultiStateValue extends BDObject {
assert(opts.states.length > 0, 'states array must not be empty');
- super(ObjectType.MULTI_STATE_VALUE, opts.name, opts.description);
+ super(ObjectType.MULTI_STATE_VALUE, opts);
const numberOfStatesValue = opts.states.length;
diff --git a/src/objects/numeric/numeric.ts b/src/objects/numeric/numeric.ts
index 0d2ec5e..202c7c7 100644
--- a/src/objects/numeric/numeric.ts
+++ b/src/objects/numeric/numeric.ts
@@ -1,6 +1,6 @@
import { BDSingletProperty } from '../../properties/index.js';
-import { BDObject } from '../generic/object.js';
+import { BDObject, type BDObjectOpts } from '../generic/object.js';
import {
ObjectType,
ApplicationTag,
@@ -9,7 +9,7 @@ import {
type BACNetObjectID,
} from '@bacnet-js/client';
-export interface BDNumericValueOpts {
+export interface BDNumericValueOpts extends BDObjectOpts {
name: string,
unit: EngineeringUnits,
writable?: boolean,
@@ -45,7 +45,7 @@ export class BDNumericObject extends BDObje
readonly minPresentValue: BDSingletProperty;
constructor(type: ObjectType, tag: Tag, opts: BDNumericValueOpts) {
- super(type, opts.name, opts.description);
+ super(type, opts);
this.presentValue = this.addProperty(new BDSingletProperty(
PropertyIdentifier.PRESENT_VALUE, tag, opts.writable ?? false, opts.presentValue));
diff --git a/src/objects/structuredview.ts b/src/objects/structuredview.ts
index 590f85f..39f56f0 100644
--- a/src/objects/structuredview.ts
+++ b/src/objects/structuredview.ts
@@ -4,7 +4,7 @@ import {
BDPolledArrayProperty,
} from '../properties/index.js';
-import { BDObject } from './generic/object.js';
+import { BDObject, type BDObjectOpts } from './generic/object.js';
import {
ObjectType,
@@ -14,11 +14,7 @@ import {
type BACNetAppData,
} from '@bacnet-js/client';
-import {
- type BDDevice,
-} from './device/device.js';
-
-export interface BDStructuredViewOpts {
+export interface BDStructuredViewOpts extends BDObjectOpts {
name: string,
description?: string,
nodeType?: NodeType,
@@ -40,7 +36,7 @@ export class BDStructuredView extends BDObject {
constructor(opts: BDStructuredViewOpts) {
- super(ObjectType.STRUCTURED_VIEW, opts.name, opts.description);
+ super(ObjectType.STRUCTURED_VIEW, opts);
this.#subordinates = new Set();
this.#subortinateData = [];
diff --git a/src/objects/temporal/datetimevalue.ts b/src/objects/temporal/datetimevalue.ts
index f3ff3df..0e60798 100644
--- a/src/objects/temporal/datetimevalue.ts
+++ b/src/objects/temporal/datetimevalue.ts
@@ -1,13 +1,13 @@
import { BDSingletProperty } from '../../properties/index.js';
-import { BDObject } from '../generic/object.js';
+import { BDObject, type BDObjectOpts } from '../generic/object.js';
import {
ObjectType,
ApplicationTag,
PropertyIdentifier,
} from '@bacnet-js/client';
-export interface BDDateTimeValueOpts {
+export interface BDDateTimeValueOpts extends BDObjectOpts {
name: string,
writable?: boolean,
description?: string,
@@ -19,7 +19,7 @@ export class BDDateTimeValue extends BDObject {
readonly presentValue: BDSingletProperty;
constructor(opts: BDDateTimeValueOpts) {
- super(ObjectType.DATETIME_VALUE, opts.name, opts.description);
+ super(ObjectType.DATETIME_VALUE, opts);
this.presentValue = this.addProperty(new BDSingletProperty(
PropertyIdentifier.PRESENT_VALUE, ApplicationTag.DATETIME, opts.writable ?? false, opts.presentValue ?? new Date()));
diff --git a/src/objects/temporal/datevalue.ts b/src/objects/temporal/datevalue.ts
index 4b283c3..8299162 100644
--- a/src/objects/temporal/datevalue.ts
+++ b/src/objects/temporal/datevalue.ts
@@ -1,13 +1,13 @@
import { BDSingletProperty } from '../../properties/index.js';
-import { BDObject } from '../generic/object.js';
+import { BDObject, type BDObjectOpts } from '../generic/object.js';
import {
ObjectType,
ApplicationTag,
PropertyIdentifier,
} from '@bacnet-js/client';
-export interface BDDateValueOpts {
+export interface BDDateValueOpts extends BDObjectOpts {
name: string,
writable?: boolean,
description?: string,
@@ -19,7 +19,7 @@ export class BDDateValue extends BDObject {
readonly presentValue: BDSingletProperty;
constructor(opts: BDDateValueOpts) {
- super(ObjectType.DATE_VALUE, opts.name, opts.description);
+ super(ObjectType.DATE_VALUE, opts);
this.presentValue = this.addProperty(new BDSingletProperty(
PropertyIdentifier.PRESENT_VALUE, ApplicationTag.DATE, opts.writable ?? false, opts.presentValue ?? new Date()));
diff --git a/src/objects/temporal/timevalue.ts b/src/objects/temporal/timevalue.ts
index a253cbf..b533fba 100644
--- a/src/objects/temporal/timevalue.ts
+++ b/src/objects/temporal/timevalue.ts
@@ -1,13 +1,13 @@
import { BDSingletProperty } from '../../properties/index.js';
-import { BDObject } from '../generic/object.js';
+import { BDObject, type BDObjectOpts } from '../generic/object.js';
import {
ObjectType,
ApplicationTag,
PropertyIdentifier,
} from '@bacnet-js/client';
-export interface BDTimeValueOpts {
+export interface BDTimeValueOpts extends BDObjectOpts {
name: string,
writable?: boolean,
description?: string,
@@ -19,7 +19,7 @@ export class BDTimeValue extends BDObject {
readonly presentValue: BDSingletProperty;
constructor(opts: BDTimeValueOpts) {
- super(ObjectType.TIME_VALUE, opts.name, opts.description);
+ super(ObjectType.TIME_VALUE, opts);
this.presentValue = this.addProperty(new BDSingletProperty(
PropertyIdentifier.PRESENT_VALUE, ApplicationTag.TIME, opts.writable ?? false, opts.presentValue ?? new Date()));
diff --git a/src/tests/outofservice.test.ts b/src/tests/outofservice.test.ts
new file mode 100644
index 0000000..b950301
--- /dev/null
+++ b/src/tests/outofservice.test.ts
@@ -0,0 +1,425 @@
+import { it, describe, beforeEach, afterEach } from 'node:test';
+import { deepStrictEqual, rejects } from 'node:assert';
+import { BDDevice } from '../objects/device/device.js';
+import { bsReadProperty, bsWriteProperty } from './bacnet-stack-client.js';
+import { BDAnalogValue } from '../objects/numeric/analogvalue.js';
+import { BDBinaryValue } from '../objects/binaryvalue.js';
+import { BDCharacterStringValue } from '../objects/characterstringvalue.js';
+import { ApplicationTag, BinaryPV, EngineeringUnits, ObjectType, PropertyIdentifier } from '@bacnet-js/client';
+
+describe('Out_Of_Service (not writable by default)', () => {
+
+ let device: BDDevice;
+
+ beforeEach(async () => {
+ device = new BDDevice(1, {
+ name: 'Test Device',
+ });
+ device.on('error', console.error);
+ device.addObject(new BDAnalogValue({
+ name: 'Default AV',
+ unit: EngineeringUnits.DEGREES_CELSIUS,
+ presentValue: 20,
+ }));
+ });
+
+ afterEach(async () => {
+ device.destroy();
+ });
+
+ it('should read Out_Of_Service as FALSE', async () => {
+ const value = await bsReadProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'FALSE');
+ });
+
+ it('should reject writing Out_Of_Service when not writable', async () => {
+ await rejects(
+ bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1),
+ );
+ });
+
+ it('should still read Out_Of_Service as FALSE after a rejected write', async () => {
+ await rejects(
+ bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1),
+ );
+ const value = await bsReadProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'FALSE');
+ });
+
+});
+
+describe('Out_Of_Service (writable, AnalogValue)', () => {
+
+ let device: BDDevice;
+ let av: BDAnalogValue;
+
+ beforeEach(async () => {
+ device = new BDDevice(1, {
+ name: 'Test Device',
+ });
+ device.on('error', console.error);
+ av = device.addObject(new BDAnalogValue({
+ name: 'Writable OOS AV',
+ unit: EngineeringUnits.DEGREES_CELSIUS,
+ presentValue: 22.5,
+ writableOutOfService: true,
+ }));
+ });
+
+ afterEach(async () => {
+ device.destroy();
+ });
+
+ it('should read Out_Of_Service as FALSE initially', async () => {
+ const value = await bsReadProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'FALSE');
+ });
+
+ it('should write TRUE to Out_Of_Service and read it back', async () => {
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ const value = await bsReadProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'TRUE');
+ });
+
+ it('should write TRUE then FALSE to Out_Of_Service and read back FALSE', async () => {
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 0);
+ const value = await bsReadProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'FALSE');
+ });
+
+ it('should report isOutOfService() as true after writing TRUE via BACnet', async () => {
+ deepStrictEqual(av.isOutOfService(), false);
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ deepStrictEqual(av.isOutOfService(), true);
+ });
+
+ it('should report isOutOfService() as false after writing FALSE via BACnet', async () => {
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ deepStrictEqual(av.isOutOfService(), true);
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 0);
+ deepStrictEqual(av.isOutOfService(), false);
+ });
+
+ it('should emit the outofservice event when Out_Of_Service is written to TRUE', async () => {
+ let emitted = false;
+ av.on('outofservice', () => { emitted = true; });
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ deepStrictEqual(emitted, true);
+ });
+
+ it('should emit the inservice event when Out_Of_Service is written back to FALSE', async () => {
+ let emitted = false;
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ av.on('inservice', () => { emitted = true; });
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 0);
+ deepStrictEqual(emitted, true);
+ });
+
+ it('should not emit inservice when Out_Of_Service is written to TRUE', async () => {
+ let emitted = false;
+ av.on('inservice', () => { emitted = true; });
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ deepStrictEqual(emitted, false);
+ });
+
+ it('should not emit outofservice when Out_Of_Service is written to FALSE', async () => {
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ let emitted = false;
+ av.on('outofservice', () => { emitted = true; });
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 0);
+ deepStrictEqual(emitted, false);
+ });
+
+ it('should not affect the Present_Value when toggling Out_Of_Service', async () => {
+ const before = await bsReadProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.PRESENT_VALUE);
+ deepStrictEqual(parseFloat(before), 22.5);
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ const during = await bsReadProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.PRESENT_VALUE);
+ deepStrictEqual(parseFloat(during), 22.5);
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 0);
+ const after = await bsReadProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.PRESENT_VALUE);
+ deepStrictEqual(parseFloat(after), 22.5);
+ });
+
+});
+
+describe('Out_Of_Service (writable, BinaryValue)', () => {
+
+ let device: BDDevice;
+ let bv: BDBinaryValue;
+
+ beforeEach(async () => {
+ device = new BDDevice(1, {
+ name: 'Test Device',
+ });
+ device.on('error', console.error);
+ bv = device.addObject(new BDBinaryValue({
+ name: 'Writable OOS BV',
+ writable: false,
+ presentValue: BinaryPV.ACTIVE,
+ writableOutOfService: true,
+ }));
+ });
+
+ afterEach(async () => {
+ device.destroy();
+ });
+
+ it('should read Out_Of_Service as FALSE initially', async () => {
+ const value = await bsReadProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'FALSE');
+ });
+
+ it('should write TRUE to Out_Of_Service and read it back', async () => {
+ await bsWriteProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ const value = await bsReadProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'TRUE');
+ });
+
+ it('should write TRUE then FALSE to Out_Of_Service and read back FALSE', async () => {
+ await bsWriteProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ await bsWriteProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 0);
+ const value = await bsReadProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'FALSE');
+ });
+
+ it('should report isOutOfService() correctly', async () => {
+ deepStrictEqual(bv.isOutOfService(), false);
+ await bsWriteProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ deepStrictEqual(bv.isOutOfService(), true);
+ await bsWriteProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 0);
+ deepStrictEqual(bv.isOutOfService(), false);
+ });
+
+ it('should emit outofservice and inservice events', async () => {
+ let outOfServiceCount = 0;
+ let inServiceCount = 0;
+ bv.on('outofservice', () => { outOfServiceCount++; });
+ bv.on('inservice', () => { inServiceCount++; });
+ await bsWriteProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ deepStrictEqual(outOfServiceCount, 1);
+ deepStrictEqual(inServiceCount, 0);
+ await bsWriteProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 0);
+ deepStrictEqual(outOfServiceCount, 1);
+ deepStrictEqual(inServiceCount, 1);
+ });
+
+ it('should not affect the Present_Value when toggling Out_Of_Service', async () => {
+ const before = await bsReadProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.PRESENT_VALUE);
+ deepStrictEqual(before.trim(), 'active');
+ await bsWriteProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ const during = await bsReadProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.PRESENT_VALUE);
+ deepStrictEqual(during.trim(), 'active');
+ await bsWriteProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 0);
+ const after = await bsReadProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.PRESENT_VALUE);
+ deepStrictEqual(after.trim(), 'active');
+ });
+
+});
+
+describe('Out_Of_Service (writable, CharacterStringValue)', () => {
+
+ let device: BDDevice;
+
+ beforeEach(async () => {
+ device = new BDDevice(1, {
+ name: 'Test Device',
+ });
+ device.on('error', console.error);
+ device.addObject(new BDCharacterStringValue({
+ name: 'Writable OOS CSV',
+ presentValue: 'hello',
+ writableOutOfService: true,
+ }));
+ });
+
+ afterEach(async () => {
+ device.destroy();
+ });
+
+ it('should write TRUE to Out_Of_Service and read it back', async () => {
+ await bsWriteProperty(1, ObjectType.CHARACTERSTRING_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ const value = await bsReadProperty(1, ObjectType.CHARACTERSTRING_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'TRUE');
+ });
+
+ it('should not affect the Present_Value when toggling Out_Of_Service', async () => {
+ await bsWriteProperty(1, ObjectType.CHARACTERSTRING_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ const value = await bsReadProperty(1, ObjectType.CHARACTERSTRING_VALUE, 1, PropertyIdentifier.PRESENT_VALUE);
+ deepStrictEqual(value.trim(), '"hello"');
+ });
+
+});
+
+describe('Out_Of_Service (not writable, BinaryValue)', () => {
+
+ let device: BDDevice;
+
+ beforeEach(async () => {
+ device = new BDDevice(1, {
+ name: 'Test Device',
+ });
+ device.on('error', console.error);
+ device.addObject(new BDBinaryValue({
+ name: 'Non-writable OOS BV',
+ writable: false,
+ presentValue: BinaryPV.INACTIVE,
+ }));
+ });
+
+ afterEach(async () => {
+ device.destroy();
+ });
+
+ it('should reject writing Out_Of_Service when not writable', async () => {
+ await rejects(
+ bsWriteProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1),
+ );
+ });
+
+ it('should remain FALSE after a rejected write attempt', async () => {
+ await rejects(
+ bsWriteProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1),
+ );
+ const value = await bsReadProperty(1, ObjectType.BINARY_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'FALSE');
+ });
+
+});
+
+describe('Out_Of_Service (writable, Device)', () => {
+
+ let device: BDDevice;
+
+ beforeEach(async () => {
+ device = new BDDevice(1, {
+ name: 'Test Device',
+ writableOutOfService: true,
+ });
+ device.on('error', console.error);
+ });
+
+ afterEach(async () => {
+ device.destroy();
+ });
+
+ it('should read Out_Of_Service as FALSE initially', async () => {
+ const value = await bsReadProperty(1, ObjectType.DEVICE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'FALSE');
+ });
+
+ it('should write TRUE to Out_Of_Service and read it back', async () => {
+ await bsWriteProperty(1, ObjectType.DEVICE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ const value = await bsReadProperty(1, ObjectType.DEVICE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'TRUE');
+ });
+
+ it('should report isOutOfService() correctly', async () => {
+ deepStrictEqual(device.isOutOfService(), false);
+ await bsWriteProperty(1, ObjectType.DEVICE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ deepStrictEqual(device.isOutOfService(), true);
+ });
+
+ it('should emit outofservice and inservice events', async () => {
+ let outOfServiceCount = 0;
+ let inServiceCount = 0;
+ device.on('outofservice', () => { outOfServiceCount++; });
+ device.on('inservice', () => { inServiceCount++; });
+ await bsWriteProperty(1, ObjectType.DEVICE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ deepStrictEqual(outOfServiceCount, 1);
+ deepStrictEqual(inServiceCount, 0);
+ await bsWriteProperty(1, ObjectType.DEVICE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 0);
+ deepStrictEqual(outOfServiceCount, 1);
+ deepStrictEqual(inServiceCount, 1);
+ });
+
+});
+
+describe('Out_Of_Service (writableOutOfService: false explicit)', () => {
+
+ let device: BDDevice;
+
+ beforeEach(async () => {
+ device = new BDDevice(1, {
+ name: 'Test Device',
+ });
+ device.on('error', console.error);
+ device.addObject(new BDAnalogValue({
+ name: 'Explicit non-writable OOS',
+ unit: EngineeringUnits.DEGREES_CELSIUS,
+ presentValue: 10,
+ writableOutOfService: false,
+ }));
+ });
+
+ afterEach(async () => {
+ device.destroy();
+ });
+
+ it('should reject writing Out_Of_Service when explicitly set to false', async () => {
+ await rejects(
+ bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1),
+ );
+ });
+
+ it('should read Out_Of_Service as FALSE', async () => {
+ const value = await bsReadProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'FALSE');
+ });
+
+ it('should report isOutOfService() as false', async () => {
+ deepStrictEqual(device.isOutOfService(), false);
+ });
+
+});
+
+describe('Out_Of_Service (multiple objects, mixed writability)', () => {
+
+ let device: BDDevice;
+ let writableAv: BDAnalogValue;
+ let readonlyAv: BDAnalogValue;
+
+ beforeEach(async () => {
+ device = new BDDevice(1, {
+ name: 'Test Device',
+ });
+ device.on('error', console.error);
+ writableAv = device.addObject(new BDAnalogValue({
+ name: 'Writable OOS AV',
+ unit: EngineeringUnits.DEGREES_CELSIUS,
+ presentValue: 10,
+ writableOutOfService: true,
+ }));
+ readonlyAv = device.addObject(new BDAnalogValue({
+ name: 'Readonly OOS AV',
+ unit: EngineeringUnits.PERCENT,
+ presentValue: 50,
+ }));
+ });
+
+ afterEach(async () => {
+ device.destroy();
+ });
+
+ it('should allow writing Out_Of_Service on the writable object', async () => {
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ const value = await bsReadProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'TRUE');
+ });
+
+ it('should reject writing Out_Of_Service on the non-writable object', async () => {
+ await rejects(
+ bsWriteProperty(1, ObjectType.ANALOG_VALUE, 2, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1),
+ );
+ });
+
+ it('should not affect the non-writable object when the writable one changes', async () => {
+ await bsWriteProperty(1, ObjectType.ANALOG_VALUE, 1, PropertyIdentifier.OUT_OF_SERVICE, 16, ApplicationTag.BOOLEAN, 1);
+ deepStrictEqual(writableAv.isOutOfService(), true);
+ deepStrictEqual(readonlyAv.isOutOfService(), false);
+ const value = await bsReadProperty(1, ObjectType.ANALOG_VALUE, 2, PropertyIdentifier.OUT_OF_SERVICE);
+ deepStrictEqual(value.trim(), 'FALSE');
+ });
+
+});
\ No newline at end of file
From 9a800df33d27772fef332951aace02ba05a901f8 Mon Sep 17 00:00:00 2001
From: Jacopo Scazzosi
Date: Tue, 21 Apr 2026 11:25:47 +0200
Subject: [PATCH 2/6] chore: updates doc
---
docs/assets/hierarchy.js | 2 +-
docs/assets/navigation.js | 2 +-
docs/assets/search.js | 2 +-
docs/classes/AsyncEventEmitter.html | 12 +++----
docs/classes/BDAbstractProperty.html | 20 +++++------
docs/classes/BDAnalogInput.html | 15 ++++----
docs/classes/BDAnalogOutput.html | 21 +++++------
docs/classes/BDAnalogValue.html | 15 ++++----
docs/classes/BDArrayProperty.html | 20 +++++------
docs/classes/BDBinaryValue.html | 15 ++++----
docs/classes/BDCharacterStringValue.html | 15 ++++----
docs/classes/BDDateTimeValue.html | 15 ++++----
docs/classes/BDDateValue.html | 15 ++++----
docs/classes/BDDevice.html | 19 +++++-----
docs/classes/BDError.html | 8 ++---
docs/classes/BDIntegerValue.html | 15 ++++----
docs/classes/BDMultiStateValue.html | 15 ++++----
docs/classes/BDObject.html | 17 ++++-----
docs/classes/BDPolledArrayProperty.html | 20 +++++------
docs/classes/BDPolledSingletProperty.html | 24 ++++++-------
docs/classes/BDPositiveIntegerValue.html | 15 ++++----
docs/classes/BDSingletProperty.html | 24 ++++++-------
docs/classes/BDStructuredView.html | 17 ++++-----
docs/classes/BDTimeValue.html | 15 ++++----
docs/classes/TaskQueue.html | 6 ++--
docs/enums/BDPropertyType.html | 6 ++--
docs/hierarchy.html | 2 +-
docs/interfaces/BDAnalogInputOpts.html | 14 ++++++--
docs/interfaces/BDAnalogOutputOpts.html | 14 ++++++--
docs/interfaces/BDAnalogValueOpts.html | 14 ++++++--
docs/interfaces/BDBinaryValueOpts.html | 14 ++++++--
.../BDCharacterStringValueOpts.html | 14 ++++++--
docs/interfaces/BDDateTimeValueOpts.html | 14 ++++++--
docs/interfaces/BDDateValueOpts.html | 14 ++++++--
docs/interfaces/BDDeviceEvents.html | 12 ++++---
docs/interfaces/BDDeviceOpts.html | 36 +++++++++++--------
docs/interfaces/BDIntegerValueOpts.html | 14 ++++++--
docs/interfaces/BDMultiStateValueOpts.html | 14 ++++++--
docs/interfaces/BDObjectEvents.html | 8 +++--
.../BDPositiveIntegerValueOpts.html | 14 ++++++--
docs/interfaces/BDPropertyAccessContext.html | 4 +--
docs/interfaces/BDPropertyEvents.html | 6 ++--
docs/interfaces/BDStructuredViewOpts.html | 14 ++++++--
docs/interfaces/BDSubscription.html | 16 ++++-----
docs/interfaces/BDTimeValueOpts.html | 14 ++++++--
docs/types/BDAnalogValueObjectType.html | 2 +-
docs/types/BDObjectUID.html | 2 +-
docs/types/BDPropertyUID.html | 2 +-
docs/types/EventArgs.html | 2 +-
docs/types/EventKey.html | 2 +-
docs/types/EventListener.html | 2 +-
docs/types/EventMap.html | 2 +-
docs/types/Task.html | 2 +-
53 files changed, 394 insertions(+), 244 deletions(-)
diff --git a/docs/assets/hierarchy.js b/docs/assets/hierarchy.js
index 3316637..1c20b7e 100644
--- a/docs/assets/hierarchy.js
+++ b/docs/assets/hierarchy.js
@@ -1 +1 @@
-window.hierarchyData = "eJyVlD1v2zAQhv/LzZdGpChF0uY0GToEDuAiS+FBoZmarUwZ5CmBEfi/F1RQIfRHSC8ahJd8+Bzv+A6278lB84sJViIXFfK8WiJY9dIpSbo3Dpp3YP5j2o2CBm7vZqbt+t/zgbYDzbfkAOGvNitoeFEiDLaDBrQhZV9aqdz18YJva9p0gCC71jlogNzqyu9wNa2CPQLLzlInIuPVf+K42RHuLOrjh8fwU3Y/zGVyUz7RLT8lN26S4jYG42o8r05QntpuUBeoTfkENQS51t3KKuN7ChlnS38OcfYcKbZjMGIbgjNkeebJRV0G5FttWrtLIH8Kxut8kxUB5afeqATGFIsTKiYCwl1LKYQpFifUPD8iJHoE0YSBy/IQ9TB0pBeUpnQQTsAxEdbu+7q1rSRlF2S1SWnDUytSHpaCB+AF2UHSYNXqSau3r5FhNgEm2OdOn7mdkfevytD9RhMp+xXtKHzRrNWiRibKElklxHI8ShkO3ezZka/fo+23ytIuMvMH6QT36uCG589/lIw8pB+ZS0yLusSbrMCKCax5jr6P0XcX+ptGX4hRvxZ1OEnqVcvYCI2ZmOp+/w8NKnyo"
\ No newline at end of file
+window.hierarchyData = "eJyVlUFvgjAYhv9Lz3WTCli96fSww+ISFy+Lhwp1doNiSnExxv++r5gRKyLlAgHer0/f9nvLCaks0zkaf3p+QDAJAkx8f42R4tuER1pkEj6ekGcukqUcjdF0NpEsyb4Whd4XerGHcox+hIzRmAQhRoVKQCWk5mrLIp4/1wuedjpNoCpKWA7jI53HPTNCr6pCZ4y8ZmpF9Aj9J5aD1XCNqMsLgyH+Hc6r7Gau0jt6GzRCXbyVwnZrsJd3KCuWFLyDtUrvYA0+7kQSKy5NT2FY27WZRxA0zcPFbSlscWuDgTwoyaFHLPJUSKaODuQrYfs6D29a6EOk3IFRydoJdBBahBnTLoRK1k4Y+bRGcPRhSR0C1w/tZL8ViRZL7WbpRuyA84Z2973smGIRdOxSKyFd2vBehcvBQu1Ng+oi0oXi8Urw38dIW+sAg/P7CjbJjzKaH7jU81RomPkjWk3cKWsjSrEX9An2KCUmc+bBjvsm12b93lW250ofWzJ/o3bwDmALuNh8w8/rMeai6eIUzhIMSceQRQxpwaaPsekubHYam4Uo7cPdThI/iKgtQqWmzer5/Ac2THzD"
\ No newline at end of file
diff --git a/docs/assets/navigation.js b/docs/assets/navigation.js
index 3a3a1d2..c1b2cfc 100644
--- a/docs/assets/navigation.js
+++ b/docs/assets/navigation.js
@@ -1 +1 @@
-window.navigationData = "eJyV199v2jAQB/D/xc9oXZG6H7xB4QG1iE6wvkx7MOYGboMT2Re2aNr/PhFKcJLz2X3lvv7YcexT+PFXIPxBMRKT6ZPNC7BYrasCxEAUEvdiJMCUB3fTrn7Y4yETA/GqzVaMvvwbNMrYVUbNjmBwdtCIYK+QyqRz4G56kbZ2O/S9yXS8cWilwsv8fbCfiYhGZvlubooSSexaTnGWJbLQuZ4iPcushDBUlyOOtbJiN8oP8NZEG2mr4Jq8Mu/c7+Xp1YBdodUm/JBUjpenEmGtDxAkW4G4xTopBhy1ooG6wo+eWZsTt+WtwI+dG4Qd2OAD+HVeWpQZ6hVyu9GJ8N5y8wKKvB3nCj/6Kc8y2EZPNRFLcVfa7DJgGwsZjNlOoz5C7J1QOV5OWO+7VrpCWyosLWyfNfwmuVaC19ibmHQL19K9fiuBEppScmdfFuiujjYI9pdU3QZ/SrXJ4d2nYJOPmtdYClpvSNRsUjzp9WOG7KR4kurIjB2K85O0ejSj93JxNoVM5eoGXn+0BDUvkoJxC2sCPOS3Dobrxni0094Zl0jy9Lnls7voR3iM6p/MYkPxyCRvjXSsFDh3n5u6EpiByqbx7Ja0QzzYbtjMdvSDEbjcOGV1gTo3IdKL8FjKfX/HXff7ZH182n9gsCp67bSJdeSPXz/f3g2JQ/t9Pu2LTSmuXF4i6XjFmFQfgrHdua7SFJKEB6hI4AGqpPGP2iEY/9+dh1yKSdJCFiSykEVs/OmjoDv29Bs97ud/0YoQ4A=="
\ No newline at end of file
+window.navigationData = "eJyV101z2jAQBuD/4nOmaZhJP3KDwIFpM6QDzaXTgzAbUGNkj7Si9XT632tMMLK8WilHvK8ey7K0g3/8zRD+YHaXTaaPuqxAY72qK8iuskrgrrkOyu7Ndb/6bof7oom8SLXJ7j79u+qUsalVPjuAwtleIoK+QHkhjAFzPYj0tZuR602m47VBLXI8338IDjMRUYmi3M5VZZHELuUUZ2GRhU71FOlJFBbCUFuOOFqLml0oN8BbE6mEroNzcsq8c78Tx1cDeolaqvBDUjlengqEldxDkOwF4hbrpBhwkDkNtBV+9EzrkjgtrwV+7FwhbEEHH8Ct89KDLVAukVsNL8J7i/UvyMnTcarwox/LooBNdFcTsRR32WyzAtjGQgZjtpEoDxB7J1SOlxPm+6aZNgfN5mg1bJ4k/Ca5XoLX2JOYdApXwrx8s0AJXSm5sy8qNBdHNousn0XuN/hjqk+Obj8Em3zUvMRS0HZBomaX4kmnHzOkl+JJqiMzdijO36TXoxl9kIuzKWQq1zbw9k9LUHMiKRg3sS7AQ27rYDg/xqNee2dcIsnTp5bPrqIb4TGqfzKTDcUjN3ltpOO8Ucx9qdpK4A5UNo1nl6Qf4sF+w2aWYxiMwHZtci0rlKUKkU6Ex1LO+xvOutsn2+3T/4DB5pffTruYJ7///PHmdkRs2u/z6VDsSnHl/BJJxynGpHYTjPXW+EpXSBK+QE0CzfWk8V+lQVDu152DnItJ0oOoSKS5Hht//FPgjz1eo8f9/A/RihDg"
\ No newline at end of file
diff --git a/docs/assets/search.js b/docs/assets/search.js
index 57b2903..22ebbb9 100644
--- a/docs/assets/search.js
+++ b/docs/assets/search.js
@@ -1 +1 @@
-window.searchData = "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";
\ No newline at end of file
+window.searchData = "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";
\ No newline at end of file
diff --git a/docs/classes/AsyncEventEmitter.html b/docs/classes/AsyncEventEmitter.html
index cf98107..1dfa180 100644
--- a/docs/classes/AsyncEventEmitter.html
+++ b/docs/classes/AsyncEventEmitter.html
@@ -4,20 +4,20 @@
BACnet components. It allows objects to register listeners for specific events
and trigger those events asynchronously.
Index
Constructors
Methods
addListener
Type Parameters
- K extends string | number | symbol
Methods
addListener
Type Parameters
- K extends string | number | symbol
off
Type Parameters
- K extends string | number | symbol
The event emitter's instance for chaining
-
on
on
Type Parameters
- K extends string | number | symbol
The callback function for chaining
-
removeListener
Type Parameters
- K extends string | number | symbol
An interface mapping event names to their argument arrays
-