node-opcua-client 2.117.0 → 2.119.0
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/dist/alarms_and_conditions/client_alarm_tools.d.ts +1 -1
- package/dist/alarms_and_conditions/client_alarm_tools.js +5 -8
- package/dist/alarms_and_conditions/client_alarm_tools.js.map +1 -1
- package/dist/alarms_and_conditions/client_alarm_tools_dump_event.d.ts +2 -2
- package/dist/alarms_and_conditions/client_alarm_tools_dump_event.js.map +1 -1
- package/dist/alarms_and_conditions/client_alarm_tools_extractConditionFields.d.ts +2 -2
- package/dist/alarms_and_conditions/client_alarm_tools_extractConditionFields.js.map +1 -1
- package/dist/alarms_and_conditions/client_tools.d.ts +1 -7
- package/dist/alarms_and_conditions/client_tools.js +15 -167
- package/dist/alarms_and_conditions/client_tools.js.map +1 -1
- package/dist/client_monitored_item_toolbox.js.map +1 -1
- package/dist/client_session.d.ts +9 -0
- package/dist/client_session_keepalive_manager.js.map +1 -1
- package/dist/client_subscription.d.ts +2 -1
- package/dist/client_subscription.js.map +1 -1
- package/dist/client_utils.d.ts +2 -2
- package/dist/client_utils.js +2 -2
- package/dist/client_utils.js.map +1 -1
- package/dist/index.d.ts +3 -6
- package/dist/index.js +3 -6
- package/dist/index.js.map +1 -1
- package/dist/private/client_base_impl.js +14 -37
- package/dist/private/client_base_impl.js.map +1 -1
- package/dist/private/client_monitored_item_group_impl.js.map +1 -1
- package/dist/private/client_monitored_item_impl.js.map +1 -1
- package/dist/private/client_publish_engine.js +4 -27
- package/dist/private/client_publish_engine.js.map +1 -1
- package/dist/private/client_session_impl.d.ts +4 -0
- package/dist/private/client_session_impl.js +14 -4
- package/dist/private/client_session_impl.js.map +1 -1
- package/dist/private/client_subscription_impl.js +4 -27
- package/dist/private/client_subscription_impl.js.map +1 -1
- package/dist/private/opcua_client_impl.js +2 -25
- package/dist/private/opcua_client_impl.js.map +1 -1
- package/dist/private/performance.js.map +1 -1
- package/dist/reconnection.js.map +1 -1
- package/dist/tools/findservers.js +4 -24
- package/dist/tools/findservers.js.map +1 -1
- package/dist/tools/read_history_server_capabilities.js.map +1 -1
- package/dist/verify.js.map +1 -1
- package/package.json +42 -41
- package/source/alarms_and_conditions/client_alarm_tools.ts +2 -6
- package/source/alarms_and_conditions/client_tools.ts +21 -185
- package/source/client_session.ts +10 -1
- package/source/client_subscription.ts +3 -2
- package/source/client_utils.ts +8 -5
- package/source/index.ts +3 -6
- package/source/private/client_base_impl.ts +3 -3
- package/source/private/client_publish_engine.ts +1 -1
- package/source/private/client_session_impl.ts +21 -8
- package/source/private/client_subscription_impl.ts +5 -5
- package/source/private/opcua_client_impl.ts +1 -1
- package/source/tools/findservers.ts +1 -1
- package/source/alarms_and_conditions/client_alarm.ts +0 -130
- package/source/alarms_and_conditions/client_alarm_list.ts +0 -112
- package/source/alarms_and_conditions/client_alarm_tools_acknowledge_all_conditions.ts +0 -187
- package/source/alarms_and_conditions/client_alarm_tools_dump_event.ts +0 -67
- package/source/alarms_and_conditions/client_alarm_tools_extractConditionFields.ts +0 -12
package/source/index.ts
CHANGED
|
@@ -10,17 +10,14 @@ export * from "./client_monitored_item_base";
|
|
|
10
10
|
export * from "./client_monitored_item";
|
|
11
11
|
export * from "./client_monitored_item_group";
|
|
12
12
|
export * from "./alarms_and_conditions/client_tools";
|
|
13
|
-
export * from "./alarms_and_conditions/client_alarm";
|
|
14
|
-
export * from "./alarms_and_conditions/client_alarm_list";
|
|
15
|
-
export * from "./alarms_and_conditions/client_alarm_tools";
|
|
16
|
-
export * from "./alarms_and_conditions/client_alarm_tools_extractConditionFields";
|
|
17
|
-
export * from "./alarms_and_conditions/client_alarm_tools_dump_event";
|
|
18
|
-
export * from "./alarms_and_conditions/client_alarm_tools_acknowledge_all_conditions";
|
|
19
13
|
export * from "./tools/findservers";
|
|
20
14
|
export * from "./tools/read_history_server_capabilities";
|
|
21
15
|
export * from "./client_utils";
|
|
22
16
|
export * from "./verify";
|
|
23
17
|
export * from "./user_identity_info";
|
|
18
|
+
export * from "./alarms_and_conditions/client_alarm_tools";
|
|
19
|
+
export * from "./alarms_and_conditions/client_tools";
|
|
20
|
+
export * from "node-opcua-alarm-condition";
|
|
24
21
|
|
|
25
22
|
export { assert } from "node-opcua-assert";
|
|
26
23
|
export * from "node-opcua-utils";
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* @module node-opcua-client-private
|
|
3
3
|
*/
|
|
4
4
|
// tslint:disable:no-unused-expression
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import async from "async";
|
|
8
8
|
import chalk from "chalk";
|
|
9
9
|
import { withLock } from "@ster5/global-mutex";
|
|
10
10
|
import { assert } from "node-opcua-assert";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @module node-opcua-client-private
|
|
3
3
|
*/
|
|
4
4
|
import { types } from "util";
|
|
5
|
-
import
|
|
5
|
+
import async from "async";
|
|
6
6
|
import chalk from "chalk";
|
|
7
7
|
import { assert } from "node-opcua-assert";
|
|
8
8
|
import { checkDebugFlag, make_debugLog, make_warningLog } from "node-opcua-debug";
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
PseudoDataValue
|
|
17
17
|
} from "node-opcua-client-dynamic-extension-object";
|
|
18
18
|
import { Certificate, Nonce } from "node-opcua-crypto";
|
|
19
|
-
import {
|
|
19
|
+
import { BrowseDirection, LocalizedTextLike } from "node-opcua-data-model";
|
|
20
20
|
import { DataValue } from "node-opcua-data-value";
|
|
21
21
|
import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
|
|
22
22
|
import { ExtensionObject } from "node-opcua-extension-object";
|
|
@@ -24,12 +24,12 @@ import { coerceNodeId, NodeId, NodeIdLike, resolveNodeId } from "node-opcua-node
|
|
|
24
24
|
import {
|
|
25
25
|
getBuiltInDataType,
|
|
26
26
|
getArgumentDefinitionHelper,
|
|
27
|
-
IBasicSession,
|
|
28
27
|
IBasicTransportSettings,
|
|
29
28
|
readAllAttributes,
|
|
30
29
|
NodeAttributes,
|
|
31
30
|
ResponseCallback,
|
|
32
|
-
BrowseDescriptionLike
|
|
31
|
+
BrowseDescriptionLike,
|
|
32
|
+
IBasicSessionAsync2
|
|
33
33
|
} from "node-opcua-pseudo-session";
|
|
34
34
|
import { AnyConstructorFunc } from "node-opcua-schemas";
|
|
35
35
|
import { ClientSecureChannelLayer, requestHandleNotSetValue, SignatureData } from "node-opcua-secure-channel";
|
|
@@ -102,7 +102,7 @@ import {
|
|
|
102
102
|
UserTokenType,
|
|
103
103
|
WriteValueOptions
|
|
104
104
|
} from "node-opcua-types";
|
|
105
|
-
import { buffer_ellipsis, getFunctionParameterNames, isNullOrUndefined
|
|
105
|
+
import { buffer_ellipsis, getFunctionParameterNames, isNullOrUndefined } from "node-opcua-utils";
|
|
106
106
|
import { DataType, Variant, VariantLike } from "node-opcua-variant";
|
|
107
107
|
|
|
108
108
|
import {
|
|
@@ -1836,7 +1836,13 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
|
|
|
1836
1836
|
const methodId = args[0] as MethodId;
|
|
1837
1837
|
const callback = args[1] as ResponseCallback<ArgumentDefinition>;
|
|
1838
1838
|
assert(typeof callback === "function");
|
|
1839
|
-
return getArgumentDefinitionHelper(this, methodId
|
|
1839
|
+
return getArgumentDefinitionHelper(this, methodId)
|
|
1840
|
+
.then((result) => {
|
|
1841
|
+
callback!(null, result);
|
|
1842
|
+
})
|
|
1843
|
+
.catch((err) => {
|
|
1844
|
+
callback(err);
|
|
1845
|
+
});
|
|
1840
1846
|
}
|
|
1841
1847
|
|
|
1842
1848
|
public async registerNodes(nodesToRegister: NodeIdLike[]): Promise<NodeId[]>;
|
|
@@ -2088,6 +2094,10 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
|
|
|
2088
2094
|
/** empty */
|
|
2089
2095
|
}
|
|
2090
2096
|
|
|
2097
|
+
/**
|
|
2098
|
+
* @deprecated
|
|
2099
|
+
* @private
|
|
2100
|
+
*/
|
|
2091
2101
|
public findMethodId(_nodeId: NodeIdLike, _methodName: string, _callback?: ResponseCallback<NodeId>): any {
|
|
2092
2102
|
/** empty */
|
|
2093
2103
|
}
|
|
@@ -2215,12 +2225,15 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
|
|
|
2215
2225
|
}
|
|
2216
2226
|
|
|
2217
2227
|
type promoteOpaqueStructure3WithCallbackFunc = (
|
|
2218
|
-
session:
|
|
2228
|
+
session: IBasicSessionAsync2,
|
|
2219
2229
|
callMethodResults: CallMethodResult[],
|
|
2220
2230
|
callback: ErrorCallback
|
|
2221
2231
|
) => void;
|
|
2222
2232
|
|
|
2223
|
-
async function promoteOpaqueStructure2(
|
|
2233
|
+
async function promoteOpaqueStructure2(
|
|
2234
|
+
session: IBasicSessionAsync2,
|
|
2235
|
+
callMethodResult: CallMethodResult
|
|
2236
|
+
): Promise<void> {
|
|
2224
2237
|
if (!callMethodResult || !callMethodResult.outputArguments || callMethodResult.outputArguments.length === 0) {
|
|
2225
2238
|
return;
|
|
2226
2239
|
}
|
|
@@ -2242,7 +2255,7 @@ function countOpaqueStructures(callMethodResults: CallMethodResult[]): number {
|
|
|
2242
2255
|
}, 0);
|
|
2243
2256
|
return opaqueStructureCount;
|
|
2244
2257
|
}
|
|
2245
|
-
async function promoteOpaqueStructure3(session:
|
|
2258
|
+
async function promoteOpaqueStructure3(session: IBasicSessionAsync2, callMethodResults: CallMethodResult[]): Promise<void> {
|
|
2246
2259
|
const opaqueStructureCount = countOpaqueStructures(callMethodResults);
|
|
2247
2260
|
if (0 === opaqueStructureCount) return;
|
|
2248
2261
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
// tslint:disable:unified-signatures
|
|
5
5
|
import { EventEmitter } from "events";
|
|
6
|
-
import
|
|
6
|
+
import async from "async";
|
|
7
7
|
import chalk from "chalk";
|
|
8
8
|
|
|
9
9
|
import { assert } from "node-opcua-assert";
|
|
@@ -35,9 +35,9 @@ import {
|
|
|
35
35
|
|
|
36
36
|
import { StatusCode, StatusCodes } from "node-opcua-status-code";
|
|
37
37
|
import { Callback, ErrorCallback } from "node-opcua-status-code";
|
|
38
|
-
import
|
|
38
|
+
import { isNullOrUndefined } from "node-opcua-utils";
|
|
39
39
|
import { promoteOpaqueStructureInNotificationData } from "node-opcua-client-dynamic-extension-object";
|
|
40
|
-
import { createMonitoredItemsLimit,
|
|
40
|
+
import { createMonitoredItemsLimit, IBasicSessionReadAsync, readOperationLimits } from "node-opcua-pseudo-session";
|
|
41
41
|
|
|
42
42
|
import { IBasicSessionWithSubscription } from "node-opcua-pseudo-session";
|
|
43
43
|
import { ClientMonitoredItemBase } from "../client_monitored_item_base";
|
|
@@ -123,7 +123,7 @@ function displayKeepAliveWarning(sessionTimeout: number, maxKeepAliveCount: numb
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
function createMonitoredItemsAndRespectOperationalLimits(
|
|
126
|
-
session:
|
|
126
|
+
session: IBasicSessionReadAsync & IBasicSessionWithSubscription,
|
|
127
127
|
createMonitorItemsRequest: CreateMonitoredItemsRequest,
|
|
128
128
|
callback: (err: Error | null, response?: CreateMonitoredItemsResponse) => void
|
|
129
129
|
) {
|
|
@@ -208,7 +208,7 @@ export class ClientSubscriptionImpl extends EventEmitter implements ClientSubscr
|
|
|
208
208
|
);
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
options.maxNotificationsPerPublish =
|
|
211
|
+
options.maxNotificationsPerPublish = isNullOrUndefined(options.maxNotificationsPerPublish)
|
|
212
212
|
? 0
|
|
213
213
|
: options.maxNotificationsPerPublish;
|
|
214
214
|
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from "events";
|
|
2
|
-
import { assert } from "node-opcua-assert";
|
|
3
|
-
import { make_warningLog } from "node-opcua-debug";
|
|
4
|
-
import { NodeId, resolveNodeId } from "node-opcua-nodeid";
|
|
5
|
-
import { StatusCode } from "node-opcua-status-code";
|
|
6
|
-
import { lowerFirstLetter } from "node-opcua-utils";
|
|
7
|
-
import { DataType, Variant } from "node-opcua-variant";
|
|
8
|
-
import { ClientSession } from "../client_session";
|
|
9
|
-
|
|
10
|
-
const warningLog = make_warningLog(__filename);
|
|
11
|
-
|
|
12
|
-
export interface TVariant<T> extends Variant {
|
|
13
|
-
value: T;
|
|
14
|
-
}
|
|
15
|
-
export interface TTwoStateStatus extends TVariant<string> {
|
|
16
|
-
id: TVariant<boolean>;
|
|
17
|
-
}
|
|
18
|
-
export interface EventStuff {
|
|
19
|
-
conditionId: TVariant<NodeId>;
|
|
20
|
-
eventType: TVariant<NodeId>;
|
|
21
|
-
eventId: TVariant<Buffer>;
|
|
22
|
-
retain: TVariant<boolean>;
|
|
23
|
-
activeState: TTwoStateStatus;
|
|
24
|
-
ackedState: TTwoStateStatus;
|
|
25
|
-
confirmedState: TTwoStateStatus;
|
|
26
|
-
conditionName?: TVariant<string>;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface ClientAlarm {
|
|
30
|
-
conditionId: NodeId;
|
|
31
|
-
eventType: NodeId;
|
|
32
|
-
fields: EventStuff;
|
|
33
|
-
on(eventName: "changed", eventHandler: () => void): this;
|
|
34
|
-
acknowledge(session: ClientSession, comment: string): Promise<StatusCode>;
|
|
35
|
-
getField(fieldName: string): Variant | null;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* describes a OPCUA Alarm as seen in the client side
|
|
40
|
-
*/
|
|
41
|
-
export class ClientAlarm extends EventEmitter {
|
|
42
|
-
public conditionId: NodeId;
|
|
43
|
-
public eventType: NodeId;
|
|
44
|
-
public eventId: Buffer;
|
|
45
|
-
public fields: EventStuff;
|
|
46
|
-
|
|
47
|
-
public constructor(eventFields: EventStuff) {
|
|
48
|
-
super();
|
|
49
|
-
this.conditionId = resolveNodeId(eventFields.conditionId.value);
|
|
50
|
-
this.eventType = resolveNodeId(eventFields.eventType.value);
|
|
51
|
-
this.eventId = eventFields.eventId.value;
|
|
52
|
-
this.fields = eventFields;
|
|
53
|
-
this.update(eventFields);
|
|
54
|
-
}
|
|
55
|
-
public async acknowledge(session: ClientSession, comment: string): Promise<StatusCode> {
|
|
56
|
-
return await session.acknowledgeCondition(this.conditionId, this.eventId, comment);
|
|
57
|
-
}
|
|
58
|
-
public async confirm(session: ClientSession, comment: string): Promise<StatusCode> {
|
|
59
|
-
return await session.confirmCondition(this.conditionId, this.eventId, comment);
|
|
60
|
-
}
|
|
61
|
-
public update(eventFields: EventStuff): void {
|
|
62
|
-
assert(this.conditionId.toString() === resolveNodeId(eventFields.conditionId.value).toString());
|
|
63
|
-
assert(this.eventType.toString() === resolveNodeId(eventFields.eventType.value).toString());
|
|
64
|
-
this.eventId = eventFields.eventId.value;
|
|
65
|
-
this.fields = eventFields;
|
|
66
|
-
}
|
|
67
|
-
public getRetain(): boolean {
|
|
68
|
-
return this.fields.retain.value;
|
|
69
|
-
}
|
|
70
|
-
public toString(): string {
|
|
71
|
-
return (
|
|
72
|
-
this.constructor.name +
|
|
73
|
-
": " +
|
|
74
|
-
this.conditionId.toString() +
|
|
75
|
-
" " +
|
|
76
|
-
this.eventType.toString() +
|
|
77
|
-
" " +
|
|
78
|
-
Object.entries(this.fields)
|
|
79
|
-
.filter(([key, value]) => value.dataType !== DataType.Null)
|
|
80
|
-
.map(([key, value]) => key.padEnd(30) + "=" + value.toString())
|
|
81
|
-
.join("\n") +
|
|
82
|
-
"\n\n"
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
public getField(fieldName: string): Variant | null {
|
|
87
|
-
return (this.fields as any)[fieldName] || null;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* @private
|
|
93
|
-
*/
|
|
94
|
-
export function fieldsToJson(fields: string[], eventFields: Variant[], flat?: boolean): EventStuff {
|
|
95
|
-
|
|
96
|
-
function setProperty(_data: Record<string, unknown>, fieldName: string, value: Variant) {
|
|
97
|
-
let name: string;
|
|
98
|
-
if (!fieldName || value === null) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
if (!flat) {
|
|
102
|
-
const f = fieldName.split(".");
|
|
103
|
-
if (f.length === 1) {
|
|
104
|
-
fieldName = lowerFirstLetter(fieldName);
|
|
105
|
-
_data[fieldName] = value;
|
|
106
|
-
} else {
|
|
107
|
-
for (let i = 0; i < f.length - 1; i++) {
|
|
108
|
-
name = lowerFirstLetter(f[i]);
|
|
109
|
-
_data[name] = _data[name] || {};
|
|
110
|
-
_data = _data[name] as Record<string, unknown>;
|
|
111
|
-
}
|
|
112
|
-
name = lowerFirstLetter(f[f.length - 1]);
|
|
113
|
-
_data[name] = value;
|
|
114
|
-
}
|
|
115
|
-
} else {
|
|
116
|
-
const name = fieldName.split(".").map(lowerFirstLetter).join(".");
|
|
117
|
-
_data[name] = value;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
if (fields.length > eventFields.length) {
|
|
121
|
-
warningLog("warning fields.length !== eventFields.length", fields.length, eventFields.length);
|
|
122
|
-
}
|
|
123
|
-
const data: any = {};
|
|
124
|
-
for (let index = 0; index < fields.length; index++) {
|
|
125
|
-
const variant = eventFields[index];
|
|
126
|
-
setProperty(data, fields[index], variant);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return data;
|
|
130
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from "events";
|
|
2
|
-
import { assert } from "node-opcua-assert";
|
|
3
|
-
import { DataType } from "node-opcua-basic-types";
|
|
4
|
-
import { NodeId } from "node-opcua-nodeid";
|
|
5
|
-
import { ClientAlarm, EventStuff } from "./client_alarm";
|
|
6
|
-
|
|
7
|
-
export interface ClientAlarmList {
|
|
8
|
-
on(eventName: "alarmChanged", handler: (alarm: ClientAlarm) => void): this;
|
|
9
|
-
on(eventName: "alarmDeleted", handler: (alarm: ClientAlarm) => void): this;
|
|
10
|
-
on(eventName: "newAlarm", handler: (alarm: ClientAlarm) => void): this;
|
|
11
|
-
|
|
12
|
-
emit(eventName: "alarmChanged", alarm: ClientAlarm): boolean;
|
|
13
|
-
emit(eventName: "newAlarm", alarm: ClientAlarm): boolean;
|
|
14
|
-
emit(eventName: "alarmDeleted", alarm: ClientAlarm): boolean;
|
|
15
|
-
}
|
|
16
|
-
// maintain a set of alarm list for a client
|
|
17
|
-
export class ClientAlarmList extends EventEmitter implements Iterable<ClientAlarm> {
|
|
18
|
-
private _map: { [key: string]: ClientAlarm } = {};
|
|
19
|
-
|
|
20
|
-
public constructor() {
|
|
21
|
-
super();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
public [Symbol.iterator](): Iterator<ClientAlarm> {
|
|
25
|
-
let pointer = 0;
|
|
26
|
-
const components = Object.values(this._map);
|
|
27
|
-
return {
|
|
28
|
-
next(): IteratorResult<ClientAlarm> {
|
|
29
|
-
if (pointer >= components.length) {
|
|
30
|
-
return {
|
|
31
|
-
done: true,
|
|
32
|
-
value: components[pointer++]
|
|
33
|
-
};
|
|
34
|
-
} else {
|
|
35
|
-
return {
|
|
36
|
-
done: false,
|
|
37
|
-
value: components[pointer++]
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
public alarms(): ClientAlarm[] {
|
|
45
|
-
return Object.values(this._map);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public update(eventField: EventStuff): void {
|
|
49
|
-
// Spec says:
|
|
50
|
-
// Clients shall check for multiple Event Notifications for a ConditionBranch to avoid
|
|
51
|
-
// overwriting a new state delivered together with an older state from the Refresh
|
|
52
|
-
// process.
|
|
53
|
-
|
|
54
|
-
const { conditionId, eventType } = eventField;
|
|
55
|
-
assert(conditionId, "must have a valid conditionId ( verify that event is a acknodweldgeable type");
|
|
56
|
-
const alarm = this.findAlarm(conditionId.value, eventType.value);
|
|
57
|
-
|
|
58
|
-
if (!alarm) {
|
|
59
|
-
const key = this.makeKey(conditionId.value, eventType.value);
|
|
60
|
-
const newAlarm = new ClientAlarm(eventField);
|
|
61
|
-
this._map[key] = newAlarm;
|
|
62
|
-
this.emit("newAlarm", newAlarm);
|
|
63
|
-
this.emit("alarmChanged", newAlarm);
|
|
64
|
-
} else {
|
|
65
|
-
alarm.update(eventField);
|
|
66
|
-
this.emit("alarmChanged", alarm);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
public removeAlarm(eventField: EventStuff): void {
|
|
70
|
-
const { conditionId, eventType } = eventField;
|
|
71
|
-
const alarm = this.findAlarm(conditionId.value, eventType.value);
|
|
72
|
-
if (alarm) {
|
|
73
|
-
alarm.update(eventField);
|
|
74
|
-
this._removeAlarm(alarm);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
public get length(): number {
|
|
79
|
-
return Object.keys(this._map).length;
|
|
80
|
-
}
|
|
81
|
-
public purgeUnusedAlarms(): void {
|
|
82
|
-
const alarms = this.alarms();
|
|
83
|
-
for (const alarm of alarms) {
|
|
84
|
-
if (!alarm.getRetain()) {
|
|
85
|
-
this._removeAlarm(alarm);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
private _removeAlarm(alarm: ClientAlarm) {
|
|
91
|
-
this.emit("alarmDeleted", alarm);
|
|
92
|
-
this.deleteAlarm(alarm.conditionId, alarm.eventType);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
private makeKey(conditionId: NodeId, eventType: NodeId) {
|
|
96
|
-
return conditionId.toString() + "|" + eventType.toString();
|
|
97
|
-
}
|
|
98
|
-
private findAlarm(conditionId: NodeId, eventType: NodeId): ClientAlarm | null {
|
|
99
|
-
const key = this.makeKey(conditionId, eventType);
|
|
100
|
-
const _c = this._map[key];
|
|
101
|
-
return _c || null;
|
|
102
|
-
}
|
|
103
|
-
private deleteAlarm(conditionId: NodeId, eventType: NodeId): boolean {
|
|
104
|
-
const key = this.makeKey(conditionId, eventType);
|
|
105
|
-
const _c = this._map[key];
|
|
106
|
-
if (_c) {
|
|
107
|
-
delete this._map[key];
|
|
108
|
-
return true;
|
|
109
|
-
}
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
import { resolveNodeId } from "node-opcua-nodeid";
|
|
2
|
-
import { constructEventFilter } from "node-opcua-service-filter";
|
|
3
|
-
import { AttributeIds, ReadValueIdOptions, TimestampsToReturn } from "node-opcua-service-read";
|
|
4
|
-
import { CreateSubscriptionRequestOptions, MonitoringParametersOptions } from "node-opcua-service-subscription";
|
|
5
|
-
import { StatusCode, StatusCodes } from "node-opcua-status-code";
|
|
6
|
-
import { DataType, Variant } from "node-opcua-variant";
|
|
7
|
-
import { checkDebugFlag, make_debugLog, make_errorLog } from "node-opcua-debug";
|
|
8
|
-
import { ClientSession } from "../client_session";
|
|
9
|
-
import { EventStuff, fieldsToJson } from "./client_alarm";
|
|
10
|
-
import { extractConditionFields } from "./client_alarm_tools_extractConditionFields";
|
|
11
|
-
import { callConditionRefresh } from "./client_tools";
|
|
12
|
-
|
|
13
|
-
const doDebug = checkDebugFlag(__filename);
|
|
14
|
-
const debugLog = make_debugLog(__filename);
|
|
15
|
-
const errorLog = make_errorLog(__filename);
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
*
|
|
19
|
-
* @param session
|
|
20
|
-
* @param eventStuff
|
|
21
|
-
* @param comment
|
|
22
|
-
*/
|
|
23
|
-
export async function acknowledgeCondition(session: ClientSession, eventStuff: EventStuff, comment: string): Promise<StatusCode> {
|
|
24
|
-
try {
|
|
25
|
-
const conditionId = eventStuff.conditionId.value;
|
|
26
|
-
const eventId = eventStuff.eventId.value;
|
|
27
|
-
return await session.acknowledgeCondition(conditionId, eventId, comment);
|
|
28
|
-
} catch (err) {
|
|
29
|
-
errorLog("Acknowledging alarm has failed !", err);
|
|
30
|
-
return StatusCodes.BadInternalError;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
export async function confirmCondition(session: ClientSession, eventStuff: EventStuff, comment: string): Promise<StatusCode> {
|
|
34
|
-
try {
|
|
35
|
-
const conditionId = eventStuff.conditionId.value;
|
|
36
|
-
const eventId = eventStuff.eventId.value;
|
|
37
|
-
return await session.confirmCondition(conditionId, eventId, comment);
|
|
38
|
-
} catch (err) {
|
|
39
|
-
errorLog("Acknowledging alarm has failed !", err);
|
|
40
|
-
return StatusCodes.BadInternalError;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Enumerate all events
|
|
46
|
-
* @param session
|
|
47
|
-
*/
|
|
48
|
-
export async function findActiveConditions(session: ClientSession): Promise<EventStuff[]> {
|
|
49
|
-
const request: CreateSubscriptionRequestOptions = {
|
|
50
|
-
maxNotificationsPerPublish: 10000,
|
|
51
|
-
priority: 6,
|
|
52
|
-
publishingEnabled: true,
|
|
53
|
-
requestedLifetimeCount: 1000,
|
|
54
|
-
requestedMaxKeepAliveCount: 100,
|
|
55
|
-
requestedPublishingInterval: 100
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const subscription = await session.createSubscription2(request);
|
|
59
|
-
|
|
60
|
-
const itemToMonitor: ReadValueIdOptions = {
|
|
61
|
-
attributeId: AttributeIds.EventNotifier,
|
|
62
|
-
nodeId: resolveNodeId("Server") // i=2253
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const fields = await extractConditionFields(session, "AcknowledgeableConditionType");
|
|
66
|
-
|
|
67
|
-
// note: we may want to have this select clause
|
|
68
|
-
// Or(OfType("AcknowledgeableConditionType"), OfType("RefreshStartEventType"), OfType("RefreshEndEventType"))
|
|
69
|
-
const eventFilter = constructEventFilter(fields);
|
|
70
|
-
|
|
71
|
-
const monitoringParameters: MonitoringParametersOptions = {
|
|
72
|
-
discardOldest: false,
|
|
73
|
-
filter: eventFilter,
|
|
74
|
-
queueSize: 100,
|
|
75
|
-
samplingInterval: 0
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const event_monitoringItem = await subscription.monitor(itemToMonitor, monitoringParameters, TimestampsToReturn.Both);
|
|
79
|
-
|
|
80
|
-
const acknowledgeableConditions: EventStuff[] = [];
|
|
81
|
-
|
|
82
|
-
let refreshStartEventHasBeenReceived = false;
|
|
83
|
-
let RefreshEndEventHasBeenReceived = false;
|
|
84
|
-
|
|
85
|
-
const RefreshStartEventType = resolveNodeId("RefreshStartEventType").toString();
|
|
86
|
-
const RefreshEndEventType = resolveNodeId("RefreshEndEventType").toString();
|
|
87
|
-
|
|
88
|
-
const promise: Promise<void> = new Promise((resolve, reject) => {
|
|
89
|
-
// now create a event monitored Item
|
|
90
|
-
event_monitoringItem.on("changed", (_eventFields: any) => {
|
|
91
|
-
const eventFields = _eventFields as Variant[];
|
|
92
|
-
|
|
93
|
-
try {
|
|
94
|
-
if (RefreshEndEventHasBeenReceived) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// dumpEvent(session, fields, eventFields);
|
|
99
|
-
const pojo = fieldsToJson(fields, eventFields) as any;
|
|
100
|
-
|
|
101
|
-
// make sure we only start recording event after the RefreshStartEvent has been received
|
|
102
|
-
if (!refreshStartEventHasBeenReceived) {
|
|
103
|
-
if (pojo.eventType.value.toString() === RefreshStartEventType) {
|
|
104
|
-
refreshStartEventHasBeenReceived = true;
|
|
105
|
-
}
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
if (pojo.eventType.value.toString() === RefreshEndEventType) {
|
|
109
|
-
RefreshEndEventHasBeenReceived = true;
|
|
110
|
-
resolve();
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
if (!pojo.conditionId.value) {
|
|
114
|
-
// not a Acknowledgeable condition
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (pojo.ackedState.id.dataType === DataType.Boolean) {
|
|
119
|
-
acknowledgeableConditions.push(pojo as EventStuff);
|
|
120
|
-
}
|
|
121
|
-
} catch (err) {
|
|
122
|
-
errorLog("Error !!", err);
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
// async call without waiting !
|
|
126
|
-
try {
|
|
127
|
-
callConditionRefresh(subscription);
|
|
128
|
-
} catch (err) {
|
|
129
|
-
// it is possible that server do not implement conditionRefresh ...
|
|
130
|
-
debugLog("Server may not implement conditionRefresh", err);
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
await promise;
|
|
135
|
-
|
|
136
|
-
// now shut down subscription
|
|
137
|
-
await subscription.terminate();
|
|
138
|
-
|
|
139
|
-
return acknowledgeableConditions;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export async function acknowledgeAllConditions(session: ClientSession, message: string): Promise<void> {
|
|
143
|
-
try {
|
|
144
|
-
let conditions = await findActiveConditions(session);
|
|
145
|
-
if (conditions.length === 0) {
|
|
146
|
-
debugLog("Warning: cannot find conditions ");
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// filter acknowledgeable conditions (no acked yet)
|
|
150
|
-
conditions = conditions.filter((pojo) => pojo.ackedState.id.value === false);
|
|
151
|
-
|
|
152
|
-
const promises: Array<Promise<StatusCode>> = [];
|
|
153
|
-
for (const eventStuff of conditions) {
|
|
154
|
-
promises.push(acknowledgeCondition(session, eventStuff, message));
|
|
155
|
-
}
|
|
156
|
-
const result = await Promise.all(promises);
|
|
157
|
-
// istanbul ignore next
|
|
158
|
-
if (doDebug) {
|
|
159
|
-
debugLog("Acked all results: ", result.map((e) => e.toString()).join(" "));
|
|
160
|
-
}
|
|
161
|
-
} catch (err) {
|
|
162
|
-
errorLog("Error", err);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
export async function confirmAllConditions(session: ClientSession, message: string): Promise<void> {
|
|
166
|
-
try {
|
|
167
|
-
let conditions = await findActiveConditions(session);
|
|
168
|
-
if (conditions.length === 0) {
|
|
169
|
-
debugLog("Warning: cannot find conditions ");
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// filter acknowledgeable conditions (no acked yet)
|
|
173
|
-
conditions = conditions.filter((pojo) => pojo.confirmedState.id.value === false);
|
|
174
|
-
|
|
175
|
-
const promises: Array<Promise<any>> = [];
|
|
176
|
-
for (const eventStuff of conditions) {
|
|
177
|
-
promises.push(confirmCondition(session, eventStuff, message));
|
|
178
|
-
}
|
|
179
|
-
const result = await Promise.all(promises);
|
|
180
|
-
// istanbul ignore next
|
|
181
|
-
if (doDebug) {
|
|
182
|
-
debugLog("Confirm all results: ", result.map((e) => e.toString()).join(" "));
|
|
183
|
-
}
|
|
184
|
-
} catch (err) {
|
|
185
|
-
errorLog("Error", err);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
import { AttributeIds } from "node-opcua-data-model";
|
|
3
|
-
import { NodeId } from "node-opcua-nodeid";
|
|
4
|
-
import { IBasicSession } from "node-opcua-pseudo-session";
|
|
5
|
-
import { DataType, Variant, VariantLike } from "node-opcua-variant";
|
|
6
|
-
|
|
7
|
-
import { make_warningLog } from "node-opcua-debug";
|
|
8
|
-
|
|
9
|
-
const warningLog = make_warningLog("ClientAlarmTool");
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
13
|
-
* @param session
|
|
14
|
-
* @param fields
|
|
15
|
-
* @param eventFields
|
|
16
|
-
*/
|
|
17
|
-
export async function dumpEvent(session: IBasicSession, fields: string[], eventFields: Variant[]): Promise<void> {
|
|
18
|
-
async function getBrowseName(_session: IBasicSession, nodeId: NodeId): Promise<string> {
|
|
19
|
-
const dataValue = await _session.read({
|
|
20
|
-
attributeId: AttributeIds.BrowseName,
|
|
21
|
-
nodeId
|
|
22
|
-
});
|
|
23
|
-
if (dataValue.statusCode.isGood()) {
|
|
24
|
-
const browseName = dataValue.value.value.name!;
|
|
25
|
-
return browseName;
|
|
26
|
-
} else {
|
|
27
|
-
return "???";
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
function w(str: string, l: number): string {
|
|
31
|
-
return (str || "").toString().padEnd(l, " ").substring(0, l);
|
|
32
|
-
}
|
|
33
|
-
async function __dumpEvent1(_session: IBasicSession, _fields: any, variant: VariantLike, index: number) {
|
|
34
|
-
if (variant.dataType === DataType.Null) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
if (variant.dataType === DataType.NodeId) {
|
|
38
|
-
const name = await getBrowseName(_session, variant.value);
|
|
39
|
-
warningLog(
|
|
40
|
-
chalk.yellow(w(name, 30), w(_fields[index], 25)),
|
|
41
|
-
chalk.cyan(w(DataType[variant.dataType], 10).toString()),
|
|
42
|
-
chalk.cyan.bold(name),
|
|
43
|
-
"(",
|
|
44
|
-
w(variant.value, 20),
|
|
45
|
-
")"
|
|
46
|
-
);
|
|
47
|
-
} else {
|
|
48
|
-
// tslint:disable-next-line: no-console
|
|
49
|
-
warningLog(
|
|
50
|
-
chalk.yellow(w("", 30), w(_fields[index], 25)),
|
|
51
|
-
chalk.cyan(w(DataType[variant.dataType as number], 10).toString()),
|
|
52
|
-
variant.value
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async function __dumpEvent(_session: IBasicSession, _fields: string[], _eventFields: Variant[]) {
|
|
58
|
-
let index = 0;
|
|
59
|
-
const promises = [];
|
|
60
|
-
for (const variant of _eventFields) {
|
|
61
|
-
promises.push(__dumpEvent1(_session, _fields, variant, index));
|
|
62
|
-
index++;
|
|
63
|
-
}
|
|
64
|
-
await Promise.all(promises);
|
|
65
|
-
}
|
|
66
|
-
await __dumpEvent(session, fields, eventFields);
|
|
67
|
-
}
|