-
Notifications
You must be signed in to change notification settings - Fork 1
/
bacnet-object.js
152 lines (134 loc) · 4.62 KB
/
bacnet-object.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//
// BACnet device implementation.
// Objects attached to devices.
//
const bacnet = require('bacstack');
const BACnetObjectProperty = require('./bacnet-object-property');
const Util = require('./util');
class BACnetObject
{
constructor(instance, typeId, name) {
this.instance = instance;
this.objects = {};
this.properties = {};
// The type is set aEvery instance of this class is a BACnet device.
this.addProperty(bacnet.enum.PropertyIdentifier.OBJECT_TYPE).value = typeId;
this.addProperty(bacnet.enum.PropertyIdentifier.OBJECT_NAME).value = name;
}
/**
* Add a new property if it doesn't already exist, and return it either way.
*/
addProperty(propertyId, typeId = undefined) {
return (
this.properties[propertyId]
|| (
this.properties[propertyId] = new BACnetObjectProperty(propertyId, typeId)
)
);
}
/// Delete an ele
delProperty(propertyId, index = undefined) {
if (index !== undefined) delete this.properties[propertyId][index];
else delete this.properties[propertyId];
}
getProperty(propertyId) {
// Some properties are generated dynamically
switch (propertyId) {
case bacnet.enum.PropertyIdentifier.OBJECT_IDENTIFIER: {
// Construct this one from the other properties.
const prop = new BACnetObjectProperty(propertyId, undefined, true);
prop._value = {
// Object type, e.g. BE.ObjectTypesSupported.DEVICE
// Is this typeId?
type: this.getProperty(bacnet.enum.PropertyIdentifier.OBJECT_TYPE).value,
// Instance number.
instance: this.instance,
};
return prop;
}
case bacnet.enum.PropertyIdentifier.PROPERTY_LIST: {
// Return a list of all properties.
// These properties are not included per the BACnet standard.
const ignoreProps = [
bacnet.enum.PropertyIdentifier.OBJECT_NAME,
bacnet.enum.PropertyIdentifier.OBJECT_TYPE,
bacnet.enum.PropertyIdentifier.OBJECT_IDENTIFIER,
bacnet.enum.PropertyIdentifier.PROPERTY_LIST,
];
const prop = new BACnetObjectProperty(propertyId, undefined, true);
prop._value = Object
.keys(this.properties)
.map(p => parseInt(p))
.filter(p => !ignoreProps.includes(p))
;
return prop;
}
case bacnet.enum.PropertyIdentifier.OBJECT_LIST: {
let objectList = [];
Object.keys(this.objects).forEach(objectInstance => {
const obj = this.objects[objectInstance];
objectList.push({
type: obj.getProperty(bacnet.enum.PropertyIdentifier.OBJECT_TYPE),
instance: obj.instance,
});
});
const prop = new BACnetObjectProperty(propertyId, undefined, true);
prop._value = objectList;
return prop;
}
case bacnet.enum.PropertyIdentifier.PROTOCOL_OBJECT_TYPES_SUPPORTED: {
// Run through all our objects and return just the types in use.
let typeList = {};
Object.keys(this.objects).forEach(objectInstance => {
const obj = this.objects[objectInstance];
const type = obj.getProperty(bacnet.enum.PropertyIdentifier.OBJECT_TYPE).value;
typeList[type] = true;
});
const prop = new BACnetObjectProperty(propertyId, undefined, true);
prop._value = Object.keys(typeList).map(t => parseInt(t));
return prop;
}
default:
break;
}
return this.properties[propertyId];
}
/**
* Return an object with the properties as string keys, suitable for passing
* to console.log() to check the current state of the object.
*
* This is more useful than dumping `this.properties`, as this function will
* convert the enums from integers into strings.
*/
dumpProperties() {
let fullPropList = Object.keys(this.properties).map(p => parseInt(p));
// Include dynamic props in the dump
fullPropList.push(bacnet.enum.PropertyIdentifier.PROTOCOL_OBJECT_TYPES_SUPPORTED);
fullPropList.push(bacnet.enum.PropertyIdentifier.OBJECT_IDENTIFIER);
fullPropList.push(bacnet.enum.PropertyIdentifier.PROPERTY_LIST);
fullPropList.push(bacnet.enum.PropertyIdentifier.OBJECT_LIST);
let props = {};
fullPropList.forEach(key => {
const property = this.getProperty(key);
const keyName = Util.getPropName(key);
props[keyName] = property.valueAsString();
});
return props;
}
/**
* Add a new object to the device, such as a sensor reading.
*
* @param Number instance
* ID number for the item. Typically these start at 1.
*
* @param bacnet.enum.ObjectType objectTypeId
* Object type, such as an analogue input or digital output.
*
* @param string name
* User-friendly name for the object, such as "Room temperature".
*/
addObject(instance, objectTypeId, name) {
return this.objects[instance] = new BACnetObject(instance, objectTypeId, name);
}
};
module.exports = BACnetObject;