node-opcua-client 2.118.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.
Files changed (43) hide show
  1. package/dist/alarms_and_conditions/client_alarm_tools.d.ts +1 -1
  2. package/dist/alarms_and_conditions/client_alarm_tools.js +5 -8
  3. package/dist/alarms_and_conditions/client_alarm_tools.js.map +1 -1
  4. package/dist/alarms_and_conditions/client_tools.d.ts +1 -7
  5. package/dist/alarms_and_conditions/client_tools.js +15 -147
  6. package/dist/alarms_and_conditions/client_tools.js.map +1 -1
  7. package/dist/client_monitored_item_toolbox.js.map +1 -1
  8. package/dist/client_session.d.ts +9 -0
  9. package/dist/client_session_keepalive_manager.js.map +1 -1
  10. package/dist/client_subscription.d.ts +2 -1
  11. package/dist/client_subscription.js.map +1 -1
  12. package/dist/client_utils.js.map +1 -1
  13. package/dist/index.d.ts +3 -6
  14. package/dist/index.js +3 -6
  15. package/dist/index.js.map +1 -1
  16. package/dist/private/client_base_impl.js +2 -2
  17. package/dist/private/client_base_impl.js.map +1 -1
  18. package/dist/private/client_monitored_item_group_impl.js.map +1 -1
  19. package/dist/private/client_monitored_item_impl.js.map +1 -1
  20. package/dist/private/client_publish_engine.js +1 -1
  21. package/dist/private/client_publish_engine.js.map +1 -1
  22. package/dist/private/client_session_impl.d.ts +4 -0
  23. package/dist/private/client_session_impl.js +7 -3
  24. package/dist/private/client_session_impl.js.map +1 -1
  25. package/dist/private/client_subscription_impl.js.map +1 -1
  26. package/dist/private/opcua_client_impl.js.map +1 -1
  27. package/dist/private/performance.js.map +1 -1
  28. package/dist/reconnection.js.map +1 -1
  29. package/dist/tools/findservers.js.map +1 -1
  30. package/dist/tools/read_history_server_capabilities.js.map +1 -1
  31. package/dist/verify.js.map +1 -1
  32. package/package.json +32 -31
  33. package/source/alarms_and_conditions/client_alarm_tools.ts +2 -6
  34. package/source/alarms_and_conditions/client_tools.ts +21 -185
  35. package/source/client_session.ts +10 -1
  36. package/source/client_subscription.ts +3 -2
  37. package/source/index.ts +3 -6
  38. package/source/private/client_session_impl.ts +4 -0
  39. package/source/alarms_and_conditions/client_alarm.ts +0 -130
  40. package/source/alarms_and_conditions/client_alarm_list.ts +0 -112
  41. package/source/alarms_and_conditions/client_alarm_tools_acknowledge_all_conditions.ts +0 -187
  42. package/source/alarms_and_conditions/client_alarm_tools_dump_event.ts +0 -67
  43. package/source/alarms_and_conditions/client_alarm_tools_extractConditionFields.ts +0 -12
@@ -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 { IBasicSessionReadAsyncSimple } 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: IBasicSessionReadAsyncSimple, fields: string[], eventFields: Variant[]): Promise<void> {
18
- async function getBrowseName(_session: IBasicSessionReadAsyncSimple, 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: IBasicSessionReadAsyncSimple, _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: IBasicSessionReadAsyncSimple, _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
- }
@@ -1,12 +0,0 @@
1
- import { NodeIdLike } from "node-opcua-nodeid";
2
- import { simpleBrowsePathsToString, extractFields, ISessionForExtractField } from "node-opcua-pseudo-session";
3
-
4
- export async function extractConditionFields(session: ISessionForExtractField, conditionNodeId: NodeIdLike): Promise<string[]> {
5
- // conditionNodeId could be a Object of type ConditionType
6
- // or it could be directly a ObjectType which is a subType of ConditionType
7
- const p = await extractFields(session, conditionNodeId);
8
- const fields1 = simpleBrowsePathsToString(p.map((a) => a.path));
9
- // add this field which will always be added
10
- fields1.push("ConditionId");
11
- return fields1;
12
- }