@bitpoolos/edge-bacnet 1.2.5 → 1.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/ISSUE_TEMPLATE/bug_report.md +41 -0
- package/bacnet_client.js +414 -200
- package/bacnet_device.js +52 -0
- package/bacnet_gateway.html +836 -602
- package/bacnet_gateway.js +223 -128
- package/bacnet_read.html +64 -34
- package/bacnet_read.js +8 -3
- package/bacnet_server.js +193 -40
- package/bacnet_write.html +125 -33
- package/bacnet_write.js +1 -1
- package/common.js +152 -131
- package/package.json +2 -3
- package/resources/icons/icon-read.svg +19 -0
- package/resources/icons/icon-write.svg +16 -0
- package/resources/node-bacstack-ts/dist/lib/client.js +3 -3
- package/resources/style.css +11 -0
package/bacnet_write.html
CHANGED
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
});
|
|
97
97
|
},
|
|
98
98
|
addAllClicked(slotProps) {
|
|
99
|
-
|
|
99
|
+
let app = this;
|
|
100
100
|
//update UI
|
|
101
101
|
if (this.writeDevices) {
|
|
102
102
|
let foundIndex = this.writeDevices.findIndex(ele => ele.key == slotProps.node.key && ele.label == slotProps.node.label);
|
|
@@ -115,7 +115,8 @@
|
|
|
115
115
|
return ele.address == slotProps.node.ipAddr && ele.deviceId == slotProps.node.deviceId;
|
|
116
116
|
}
|
|
117
117
|
});
|
|
118
|
-
let
|
|
118
|
+
let deviceAddress = app.getDeviceAddress(device.address);
|
|
119
|
+
let key = `${deviceAddress}-${device.deviceId}`;
|
|
119
120
|
let points = this.pointList[key];
|
|
120
121
|
|
|
121
122
|
if (!this.pointsToWrite[key] || typeof this.pointsToWrite[key] == 'undefined') {
|
|
@@ -131,6 +132,7 @@
|
|
|
131
132
|
node.hiddenDeployToggle = !node.prevHiddenToggleState;
|
|
132
133
|
},
|
|
133
134
|
removeAllClicked(slotProps) {
|
|
135
|
+
let app = this;
|
|
134
136
|
//update UI
|
|
135
137
|
if (this.writeDevices.length > 0) {
|
|
136
138
|
let foundIndex = this.writeDevices.findIndex(ele => ele.key == slotProps.node.key && ele.label == slotProps.node.label);
|
|
@@ -146,7 +148,8 @@
|
|
|
146
148
|
return ele.address == slotProps.node.ipAddr && ele.deviceId == slotProps.node.deviceId;
|
|
147
149
|
}
|
|
148
150
|
});
|
|
149
|
-
let
|
|
151
|
+
let deviceAddress = app.getDeviceAddress(device.address);
|
|
152
|
+
let key = `${deviceAddress}-${device.deviceId}`;
|
|
150
153
|
if (this.pointsToWrite[key]) {
|
|
151
154
|
delete this.pointsToWrite[key];
|
|
152
155
|
}
|
|
@@ -155,15 +158,31 @@
|
|
|
155
158
|
node.hiddenDeployToggle = !node.prevHiddenToggleState;
|
|
156
159
|
},
|
|
157
160
|
addPointClicked(slotProps) {
|
|
158
|
-
|
|
161
|
+
let app = this;
|
|
159
162
|
//update UI
|
|
160
163
|
let parentDeviceName = slotProps.node.parentDevice;
|
|
161
164
|
let foundDeviceIndex = this.writeDevices ? this.writeDevices.findIndex(ele => ele.label == parentDeviceName) : -1;
|
|
162
|
-
let
|
|
165
|
+
let device = this.deviceList.find(ele => ele.deviceName == parentDeviceName);
|
|
166
|
+
let deviceAddress = app.getDeviceAddress(device.address);
|
|
167
|
+
let key = `${deviceAddress}-${device.deviceId}`;
|
|
168
|
+
let parentDevice = this.devices.find(ele => ele.ipAddr == deviceAddress);
|
|
169
|
+
let childDevice;
|
|
170
|
+
if(device.isMstp) {
|
|
171
|
+
let foundChildIndex = parentDevice.children[1].children.findIndex(ele => ele.label == parentDeviceName);
|
|
172
|
+
if(foundChildIndex !== -1) {
|
|
173
|
+
childDevice = parentDevice.children[1].children[foundChildIndex];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
163
176
|
|
|
164
177
|
if (foundDeviceIndex == -1) {
|
|
165
178
|
//no read devices present, add new
|
|
166
|
-
let newReadParent
|
|
179
|
+
let newReadParent;
|
|
180
|
+
if(childDevice) {
|
|
181
|
+
newReadParent = {...childDevice};
|
|
182
|
+
} else {
|
|
183
|
+
newReadParent = {...parentDevice};
|
|
184
|
+
}
|
|
185
|
+
|
|
167
186
|
newReadParent.children = [];
|
|
168
187
|
newReadParent.children.push(slotProps.node);
|
|
169
188
|
|
|
@@ -180,17 +199,12 @@
|
|
|
180
199
|
|
|
181
200
|
slotProps.node.showAdded = true;
|
|
182
201
|
|
|
202
|
+
console.log("write point added, slotProps.node: ", slotProps.node);
|
|
203
|
+
|
|
183
204
|
this.$forceUpdate();
|
|
184
205
|
|
|
185
206
|
//update node-red data structure
|
|
186
|
-
|
|
187
|
-
if(ele.address.address) {
|
|
188
|
-
return ele.address.address == parentDevice.ipAddr && ele.deviceId == parentDevice.deviceId;
|
|
189
|
-
} else {
|
|
190
|
-
return ele.address == parentDevice.ipAddr && ele.deviceId == parentDevice.deviceId;
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
let key = `${device.address}-${device.deviceId}`;
|
|
207
|
+
|
|
194
208
|
let point = this.pointList[key][slotProps.node.pointName];
|
|
195
209
|
point.deviceId = device.deviceId;
|
|
196
210
|
point.deviceAddress = device.address;
|
|
@@ -208,10 +222,13 @@
|
|
|
208
222
|
|
|
209
223
|
if (!found) this.pointsToWrite.push(point);
|
|
210
224
|
|
|
225
|
+
console.log("this.pointsToWrite: ", this.pointsToWrite);
|
|
226
|
+
|
|
211
227
|
//force a deploy state
|
|
212
228
|
node.hiddenDeployToggle = !node.prevHiddenToggleState;
|
|
213
229
|
},
|
|
214
230
|
removePointClicked(slotProps) {
|
|
231
|
+
let app = this;
|
|
215
232
|
//update UI
|
|
216
233
|
let parentDeviceName = slotProps.node.parentDevice;
|
|
217
234
|
let foundDeviceIndex = this.writeDevices ? this.writeDevices.findIndex(ele => ele.label == parentDeviceName) : -1;
|
|
@@ -237,7 +254,8 @@
|
|
|
237
254
|
return ele.address == parentDevice.ipAddr && ele.deviceId == parentDevice.deviceId;
|
|
238
255
|
}
|
|
239
256
|
});
|
|
240
|
-
let
|
|
257
|
+
let deviceAddress = app.getDeviceAddress(device.address);
|
|
258
|
+
let key = `${deviceAddress}-${device.deviceId}`;
|
|
241
259
|
let point = this.pointList[key][slotProps.node.pointName];
|
|
242
260
|
point.deviceId = device.deviceId;
|
|
243
261
|
|
|
@@ -255,6 +273,16 @@
|
|
|
255
273
|
//force a deploy state
|
|
256
274
|
node.hiddenDeployToggle = !node.prevHiddenToggleState;
|
|
257
275
|
},
|
|
276
|
+
getDeviceAddress(addr) {
|
|
277
|
+
switch(typeof addr) {
|
|
278
|
+
case "object":
|
|
279
|
+
return addr.address;
|
|
280
|
+
case "string":
|
|
281
|
+
return addr;
|
|
282
|
+
default:
|
|
283
|
+
return addr;
|
|
284
|
+
}
|
|
285
|
+
},
|
|
258
286
|
isDeviceActive(slotProps) {
|
|
259
287
|
let app = this;
|
|
260
288
|
if (((Date.now() - slotProps.node.lastSeen) / 1000) < app.pollFrequency) {
|
|
@@ -349,13 +377,13 @@
|
|
|
349
377
|
<script type="text/html" data-template-name="Bacnet-Write">
|
|
350
378
|
<style>
|
|
351
379
|
.p-treenode-label {
|
|
352
|
-
/* color: white; */
|
|
353
380
|
color: black;
|
|
354
381
|
width: 100%;
|
|
355
382
|
}
|
|
356
383
|
.p-tree {
|
|
357
384
|
background: inherit !important;
|
|
358
385
|
border: inherit !important;
|
|
386
|
+
padding-right: 0px !important;
|
|
359
387
|
}
|
|
360
388
|
.p-button {
|
|
361
389
|
margin-right: .5rem;
|
|
@@ -367,15 +395,11 @@
|
|
|
367
395
|
float: right;
|
|
368
396
|
}
|
|
369
397
|
.addPointButton:hover, .minusPointButton:hover {
|
|
370
|
-
/* background: #282A36 !important; */
|
|
371
398
|
background: #d5d5d5 !important;
|
|
372
399
|
}
|
|
373
400
|
.pointLabel {
|
|
374
401
|
font-weight: 400;
|
|
375
402
|
}
|
|
376
|
-
/* .p-treenode-children {
|
|
377
|
-
background-color: #f0f0f0;
|
|
378
|
-
} */
|
|
379
403
|
.deviceLabel {
|
|
380
404
|
font-weight: 100;
|
|
381
405
|
}
|
|
@@ -388,12 +412,10 @@
|
|
|
388
412
|
.bacnetbutton {
|
|
389
413
|
background: none;
|
|
390
414
|
border: none;
|
|
391
|
-
/* color: white; */
|
|
392
415
|
color: black;
|
|
393
416
|
font-weight: 400;
|
|
394
417
|
}
|
|
395
418
|
.bacnetbutton:hover {
|
|
396
|
-
/* background: #21232e; */
|
|
397
419
|
background: #f0f0f0;
|
|
398
420
|
border-radius: 10px;
|
|
399
421
|
}
|
|
@@ -403,17 +425,13 @@
|
|
|
403
425
|
}
|
|
404
426
|
.p-treenode-children > li > .p-treenode-children > li {
|
|
405
427
|
font-size: 14px;
|
|
406
|
-
height:
|
|
428
|
+
/* height: 35px; */
|
|
407
429
|
color: #b5b5b5 !important;
|
|
408
430
|
}
|
|
409
431
|
.p-treenode-children > li > .p-treenode-children > .p-treenode-label {
|
|
410
432
|
color: #b5b5b5 !important;
|
|
411
433
|
}
|
|
412
|
-
.p-treenode-children > li > .p-treenode-children > li:last-child {
|
|
413
|
-
padding-bottom: 30px;
|
|
414
|
-
}
|
|
415
434
|
.p-tree-toggler:enabled:hover {
|
|
416
|
-
/* background: #21232e !important; */
|
|
417
435
|
background: #d5d5d5 !important;
|
|
418
436
|
}
|
|
419
437
|
.p-tree-toggler:focus {
|
|
@@ -425,14 +443,15 @@
|
|
|
425
443
|
}
|
|
426
444
|
.statusOnline {
|
|
427
445
|
color: #11c511;
|
|
428
|
-
|
|
429
446
|
}
|
|
430
447
|
.statusOffline {
|
|
431
448
|
color: red;
|
|
432
449
|
}
|
|
450
|
+
/*
|
|
433
451
|
.deviceLabel {
|
|
434
|
-
position:
|
|
452
|
+
position: absolute;
|
|
435
453
|
}
|
|
454
|
+
*/
|
|
436
455
|
.objectPropertiesLabel {
|
|
437
456
|
display: flex !important;
|
|
438
457
|
flex-direction: row;
|
|
@@ -441,23 +460,60 @@
|
|
|
441
460
|
.p-tree .p-tree-container .p-treenode .p-treenode-content:focus {
|
|
442
461
|
outline: 0 none !important;
|
|
443
462
|
outline-offset: 0 !important;
|
|
444
|
-
box-shadow: inset 0 0 0
|
|
463
|
+
box-shadow: inset 0 0 0 1px #bdbdbd !important;
|
|
464
|
+
}
|
|
465
|
+
.checkbox-round {
|
|
466
|
+
width: 13px !important;
|
|
467
|
+
height: 13px !important;
|
|
468
|
+
background-color: white;
|
|
469
|
+
border-radius: 50%;
|
|
470
|
+
vertical-align: middle;
|
|
471
|
+
border: 1px solid #ddd;
|
|
472
|
+
appearance: none;
|
|
473
|
+
-webkit-appearance: none;
|
|
474
|
+
outline: none;
|
|
475
|
+
cursor: pointer;
|
|
476
|
+
}
|
|
477
|
+
.checkbox-round:checked {
|
|
478
|
+
background-color: #00AEEF;
|
|
479
|
+
}
|
|
480
|
+
.checkbox-round:focus {
|
|
481
|
+
outline: none !important;
|
|
445
482
|
}
|
|
446
483
|
.p-tree-filter:focus, .p-tree-filter:focus-visible, .p-inputtext:enabled:hover {
|
|
447
|
-
box-shadow: inset 0 0 0 0.15rem #
|
|
484
|
+
box-shadow: inset 0 0 0 0.15rem #dfdcdc !important;
|
|
448
485
|
border-color: transparent !important;
|
|
449
486
|
}
|
|
450
487
|
.bacnetbutton > .pi {
|
|
451
488
|
display: flex;
|
|
452
489
|
}
|
|
490
|
+
.p-tree-container {
|
|
491
|
+
margin: 0 !important;
|
|
492
|
+
}
|
|
453
493
|
.reloadButtonIcon {
|
|
454
494
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
|
|
455
495
|
}
|
|
496
|
+
.removeAllDevicesButton {
|
|
497
|
+
border: none;
|
|
498
|
+
background: none;
|
|
499
|
+
font-size: 14px !important;
|
|
500
|
+
float: right;
|
|
501
|
+
display: flex;
|
|
502
|
+
align-items: center;
|
|
503
|
+
}
|
|
504
|
+
.removeAllDevicesButton:hover {
|
|
505
|
+
background-color: #d5d5d5;
|
|
506
|
+
border-radius: 10px;
|
|
507
|
+
}
|
|
456
508
|
.reloadButton {
|
|
457
509
|
border: none;
|
|
458
510
|
background: none;
|
|
459
|
-
|
|
460
|
-
|
|
511
|
+
font-size: 14px !important;
|
|
512
|
+
float: right;
|
|
513
|
+
}
|
|
514
|
+
.rebuildDataButton {
|
|
515
|
+
border: none;
|
|
516
|
+
background: none;
|
|
461
517
|
font-size: 14px !important;
|
|
462
518
|
float: right;
|
|
463
519
|
}
|
|
@@ -465,11 +521,47 @@
|
|
|
465
521
|
background-color: #d5d5d5;
|
|
466
522
|
border-radius: 10px;
|
|
467
523
|
}
|
|
524
|
+
.rebuildDataButton:hover {
|
|
525
|
+
background-color: #d5d5d5;
|
|
526
|
+
border-radius: 10px;
|
|
527
|
+
}
|
|
528
|
+
.headerDiv {
|
|
529
|
+
display: flex;
|
|
530
|
+
flex-direction: row;
|
|
531
|
+
flex-wrap: nowrap;
|
|
532
|
+
justify-content: space-around;
|
|
533
|
+
height: 20px;
|
|
534
|
+
}
|
|
535
|
+
.msgTypeDiv {
|
|
536
|
+
display: flex;
|
|
537
|
+
align-items: flex-start;
|
|
538
|
+
flex-direction: column;
|
|
539
|
+
}
|
|
540
|
+
.p-progressbar .p-progressbar-value {
|
|
541
|
+
background: #00AEEF !important;
|
|
542
|
+
}
|
|
468
543
|
.p-treenode-label {
|
|
469
544
|
overflow: hidden;
|
|
470
545
|
white-space: nowrap;
|
|
471
546
|
text-overflow: ellipsis;
|
|
472
547
|
}
|
|
548
|
+
.buttonGroup {
|
|
549
|
+
padding-left: 7px;
|
|
550
|
+
}
|
|
551
|
+
#read-readList-tab {
|
|
552
|
+
display: flex;
|
|
553
|
+
flex-direction: column;
|
|
554
|
+
}
|
|
555
|
+
.removeAllDevicesDiv {
|
|
556
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
|
557
|
+
padding-right: 20px;
|
|
558
|
+
}
|
|
559
|
+
.p-tree .p-treenode-children {
|
|
560
|
+
padding: 0 !important;
|
|
561
|
+
}
|
|
562
|
+
.p-tree-toggler .p-link {
|
|
563
|
+
width: 25px !important;
|
|
564
|
+
}
|
|
473
565
|
|
|
474
566
|
</style>
|
|
475
567
|
|
package/bacnet_write.js
CHANGED
|
@@ -15,7 +15,7 @@ module.exports = function (RED) {
|
|
|
15
15
|
|
|
16
16
|
node.on('input', function(msg) {
|
|
17
17
|
|
|
18
|
-
let value = msg.payload == "null" ? null :
|
|
18
|
+
let value = msg.payload == "null" ? null : msg.payload;
|
|
19
19
|
let priority = node.priority == "null" ? null : parseInt(node.priority);
|
|
20
20
|
|
|
21
21
|
let output = {
|