@attraccess/plugin-wago 0.1.0-nightly.950.1 → 0.1.0-nightly.952.1
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/index.js +150 -35
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -51671,6 +51671,13 @@ var CONFIGURATION_CAPABILITY = `configuration-v${CONFIGURATION_PROTOCOL_VERSION}
|
|
|
51671
51671
|
var REQUIRED_CAPABILITIES = ["claim", "heartbeat", CONFIGURATION_CAPABILITY];
|
|
51672
51672
|
var SUPPORTED_PROTOCOL_MAJOR = 1;
|
|
51673
51673
|
function parseAnnouncement(payload) {
|
|
51674
|
+
const heartbeat = parseHeartbeat(payload);
|
|
51675
|
+
const input = JSON.parse(payload.toString("utf8"));
|
|
51676
|
+
if (typeof input.pairingCode !== "string" || !input.pairingCode.trim())
|
|
51677
|
+
throw new Error("announcement pairingCode is required");
|
|
51678
|
+
return { ...heartbeat, pairingCode: input.pairingCode.trim() };
|
|
51679
|
+
}
|
|
51680
|
+
function parseHeartbeat(payload) {
|
|
51674
51681
|
let value;
|
|
51675
51682
|
try {
|
|
51676
51683
|
value = JSON.parse(payload.toString("utf8"));
|
|
@@ -51679,7 +51686,7 @@ function parseAnnouncement(payload) {
|
|
|
51679
51686
|
}
|
|
51680
51687
|
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("announcement must be an object");
|
|
51681
51688
|
const input = value;
|
|
51682
|
-
const required = ["hardwareId", "
|
|
51689
|
+
const required = ["hardwareId", "protocolVersion", "runtimeVersion"];
|
|
51683
51690
|
for (const key of required)
|
|
51684
51691
|
if (typeof input[key] !== "string" || !input[key].trim()) throw new Error(`announcement ${key} is required`);
|
|
51685
51692
|
if (!Array.isArray(input.capabilities) || input.capabilities.some((item) => typeof item !== "string"))
|
|
@@ -51688,7 +51695,6 @@ function parseAnnouncement(payload) {
|
|
|
51688
51695
|
throw new Error("announcement sequence must be a non-negative integer");
|
|
51689
51696
|
return {
|
|
51690
51697
|
hardwareId: input.hardwareId.trim(),
|
|
51691
|
-
pairingCode: input.pairingCode.trim(),
|
|
51692
51698
|
enrollmentSecret: typeof input.enrollmentSecret === "string" ? input.enrollmentSecret.trim() : void 0,
|
|
51693
51699
|
fingerprint: typeof input.fingerprint === "string" ? input.fingerprint.trim() : void 0,
|
|
51694
51700
|
protocolVersion: input.protocolVersion.trim(),
|
|
@@ -51749,7 +51755,7 @@ function parseOperationalMessage(prefix, topic, payload) {
|
|
|
51749
51755
|
const value = parseObject(payload, "operational message");
|
|
51750
51756
|
const timestamp = requiredTimestamp(value.timestamp);
|
|
51751
51757
|
const sequence = requiredSequence(value.sequence);
|
|
51752
|
-
if (
|
|
51758
|
+
if (typeof value.streamId !== "string" || !value.streamId.trim() || value.streamId.length > 128)
|
|
51753
51759
|
throw new Error("operational streamId is invalid");
|
|
51754
51760
|
const streamId = value.streamId;
|
|
51755
51761
|
if (suffix === "state") {
|
|
@@ -51760,7 +51766,7 @@ function parseOperationalMessage(prefix, topic, payload) {
|
|
|
51760
51766
|
message: {
|
|
51761
51767
|
category: "state",
|
|
51762
51768
|
timestamp,
|
|
51763
|
-
|
|
51769
|
+
streamId,
|
|
51764
51770
|
sequence,
|
|
51765
51771
|
connected: value.connected,
|
|
51766
51772
|
revision: value.revision,
|
|
@@ -51772,7 +51778,6 @@ function parseOperationalMessage(prefix, topic, payload) {
|
|
|
51772
51778
|
};
|
|
51773
51779
|
}
|
|
51774
51780
|
if (suffix === "measurements") {
|
|
51775
|
-
if (streamId === void 0) throw new Error("operational streamId is required for measurements");
|
|
51776
51781
|
return {
|
|
51777
51782
|
hardwareId,
|
|
51778
51783
|
message: {
|
|
@@ -51792,7 +51797,7 @@ function parseOperationalMessage(prefix, topic, payload) {
|
|
|
51792
51797
|
message: {
|
|
51793
51798
|
category: "fault",
|
|
51794
51799
|
timestamp,
|
|
51795
|
-
|
|
51800
|
+
streamId,
|
|
51796
51801
|
sequence,
|
|
51797
51802
|
channelId: value.channelId,
|
|
51798
51803
|
code: value.code,
|
|
@@ -51807,7 +51812,7 @@ function parseOperationalMessage(prefix, topic, payload) {
|
|
|
51807
51812
|
message: {
|
|
51808
51813
|
category: "acknowledgement",
|
|
51809
51814
|
timestamp,
|
|
51810
|
-
|
|
51815
|
+
streamId,
|
|
51811
51816
|
sequence,
|
|
51812
51817
|
id: value.id,
|
|
51813
51818
|
status: value.status,
|
|
@@ -53430,7 +53435,7 @@ var WagoService = class {
|
|
|
53430
53435
|
async onHeartbeat(hardwareId, payload) {
|
|
53431
53436
|
let heartbeat;
|
|
53432
53437
|
try {
|
|
53433
|
-
heartbeat =
|
|
53438
|
+
heartbeat = parseHeartbeat(payload);
|
|
53434
53439
|
} catch (error) {
|
|
53435
53440
|
this.context.logger.warn(
|
|
53436
53441
|
`Ignoring invalid WAGO heartbeat: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -58179,6 +58184,7 @@ var MAX_CACHE_ENTRIES = 2e3;
|
|
|
58179
58184
|
var MAX_PENDING_DISPATCHES = 100;
|
|
58180
58185
|
var MAX_CONCURRENT_DISPATCHES = 10;
|
|
58181
58186
|
var MAX_TIMEOUT_MS = 2147483647;
|
|
58187
|
+
var MAX_RETIRED_STREAMS = 128;
|
|
58182
58188
|
var WagoFlowService = class {
|
|
58183
58189
|
constructor(context) {
|
|
58184
58190
|
__publicField(this, "context", context);
|
|
@@ -58187,8 +58193,12 @@ var WagoFlowService = class {
|
|
|
58187
58193
|
__publicField(this, "settings");
|
|
58188
58194
|
__publicField(this, "cache", /* @__PURE__ */ new Map());
|
|
58189
58195
|
__publicField(this, "controllerByHardwareId", /* @__PURE__ */ new Map());
|
|
58190
|
-
__publicField(this, "
|
|
58191
|
-
__publicField(this, "
|
|
58196
|
+
__publicField(this, "streams", /* @__PURE__ */ new Map());
|
|
58197
|
+
__publicField(this, "offlineControllers", /* @__PURE__ */ new Set());
|
|
58198
|
+
__publicField(this, "unavailableHardware", /* @__PURE__ */ new Set());
|
|
58199
|
+
__publicField(this, "unavailableConfiguration", /* @__PURE__ */ new Set());
|
|
58200
|
+
__publicField(this, "appliedConfigurations", /* @__PURE__ */ new Map());
|
|
58201
|
+
__publicField(this, "processingByController", /* @__PURE__ */ new Map());
|
|
58192
58202
|
__publicField(this, "channelCache", /* @__PURE__ */ new Map());
|
|
58193
58203
|
__publicField(this, "waiters", /* @__PURE__ */ new Set());
|
|
58194
58204
|
__publicField(this, "waitersByKey", /* @__PURE__ */ new Map());
|
|
@@ -58221,6 +58231,14 @@ var WagoFlowService = class {
|
|
|
58221
58231
|
const settings = await this.settings.findOneBy({ id: 1 });
|
|
58222
58232
|
if (!settings) return;
|
|
58223
58233
|
const controllers = await this.controllers.find({ where: { trustState: "claimed" } });
|
|
58234
|
+
const controllerIds = new Set(controllers.map((controller) => controller.id));
|
|
58235
|
+
for (const id of this.offlineControllers) if (!controllerIds.has(id)) this.offlineControllers.delete(id);
|
|
58236
|
+
for (const id of this.unavailableHardware) if (!controllerIds.has(id)) this.unavailableHardware.delete(id);
|
|
58237
|
+
for (const id of this.unavailableConfiguration)
|
|
58238
|
+
if (!controllerIds.has(id)) this.unavailableConfiguration.delete(id);
|
|
58239
|
+
for (const id of this.appliedConfigurations.keys())
|
|
58240
|
+
if (!controllerIds.has(id)) this.appliedConfigurations.delete(id);
|
|
58241
|
+
for (const id of this.streams.keys()) if (!controllerIds.has(id)) this.streams.delete(id);
|
|
58224
58242
|
this.channelCache.clear();
|
|
58225
58243
|
const revisions = await this.loadLatestAppliedRevisions(controllers.map((controller) => controller.id));
|
|
58226
58244
|
for (const revision of revisions) this.cacheChannels(revision);
|
|
@@ -58295,7 +58313,7 @@ var WagoFlowService = class {
|
|
|
58295
58313
|
};
|
|
58296
58314
|
properties.minimumIntervalMs = { type: "number", title: "Minimum interval (ms)", minimum: 0 };
|
|
58297
58315
|
if (channel?.capabilities.includes("measurement"))
|
|
58298
|
-
properties.minimumChange = { type: "number", title: "Minimum change", minimum: 0 };
|
|
58316
|
+
properties.minimumChange = { type: "number", title: "Minimum change (wire units)", minimum: 0 };
|
|
58299
58317
|
}
|
|
58300
58318
|
if (kind !== "event")
|
|
58301
58319
|
properties.category = {
|
|
@@ -58305,7 +58323,10 @@ var WagoFlowService = class {
|
|
|
58305
58323
|
oneOf: this.readCategories(channel).map((category) => ({ const: category, title: category }))
|
|
58306
58324
|
};
|
|
58307
58325
|
if (kind === "wait") {
|
|
58308
|
-
properties.equals = {
|
|
58326
|
+
properties.equals = {
|
|
58327
|
+
type: config.category === "measurement" ? "number" : "boolean",
|
|
58328
|
+
title: config.category === "measurement" ? "Equals (wire value)" : "Equals"
|
|
58329
|
+
};
|
|
58309
58330
|
properties.timeoutMs = { type: "number", title: "Timeout (ms)", minimum: 1, maximum: MAX_TIMEOUT_MS };
|
|
58310
58331
|
}
|
|
58311
58332
|
return { dynamic: true, type: "object", properties, required: ["controllerId", "channelId", "category"] };
|
|
@@ -58317,7 +58338,7 @@ var WagoFlowService = class {
|
|
|
58317
58338
|
const entries = [...this.cache.values()].filter(
|
|
58318
58339
|
(state) => state.controllerId === config.controllerId && state.channelId === config.channelId && (!config.category || state.category === config.category)
|
|
58319
58340
|
);
|
|
58320
|
-
return entries.sort((left, right) => right.
|
|
58341
|
+
return entries.sort((left, right) => right.receivedAt - left.receivedAt)[0] ?? null;
|
|
58321
58342
|
}
|
|
58322
58343
|
async wait(config) {
|
|
58323
58344
|
if (typeof config.controllerId !== "number" || typeof config.channelId !== "string" || typeof config.category !== "string")
|
|
@@ -58325,8 +58346,8 @@ var WagoFlowService = class {
|
|
|
58325
58346
|
const current = this.read(config);
|
|
58326
58347
|
if (current && this.matchesCondition(current, config)) return current;
|
|
58327
58348
|
const timeoutMs = typeof config.timeoutMs === "number" && Number.isFinite(config.timeoutMs) && config.timeoutMs > 0 ? Math.min(config.timeoutMs, MAX_TIMEOUT_MS) : 3e4;
|
|
58349
|
+
const waiterKey = this.cacheKey(config.controllerId, config.channelId, config.category);
|
|
58328
58350
|
return new Promise((resolve2) => {
|
|
58329
|
-
const waiterKey = this.cacheKey(config.controllerId, config.channelId, config.category);
|
|
58330
58351
|
const cleanup = () => {
|
|
58331
58352
|
clearTimeout(timer);
|
|
58332
58353
|
this.waiters.delete(wake);
|
|
@@ -58362,29 +58383,90 @@ var WagoFlowService = class {
|
|
|
58362
58383
|
const entry = this.controllerByHardwareId.get(hardwareId);
|
|
58363
58384
|
if (!entry || entry.serverId !== serverId) return;
|
|
58364
58385
|
const { controller } = entry;
|
|
58365
|
-
const previous = this.sequences.get(controller.id);
|
|
58366
58386
|
const eventTime = Date.parse(event.timestamp);
|
|
58367
|
-
|
|
58368
|
-
|
|
58387
|
+
if (eventTime > Date.now()) {
|
|
58388
|
+
this.context.logger.warn(`Ignoring future-dated WAGO event for ${controller.hardwareId}`);
|
|
58389
|
+
return;
|
|
58390
|
+
}
|
|
58391
|
+
const previous = this.processingByController.get(controller.id) ?? Promise.resolve();
|
|
58392
|
+
const processing = previous.catch(() => void 0).then(() => this.processMessage(controller, event, eventTime));
|
|
58393
|
+
this.processingByController.set(controller.id, processing);
|
|
58394
|
+
try {
|
|
58395
|
+
await processing;
|
|
58396
|
+
} finally {
|
|
58397
|
+
if (this.processingByController.get(controller.id) === processing)
|
|
58398
|
+
this.processingByController.delete(controller.id);
|
|
58399
|
+
}
|
|
58400
|
+
}
|
|
58401
|
+
async processMessage(controller, event, eventTime) {
|
|
58402
|
+
const channels = await this.channels(controller.id);
|
|
58403
|
+
let stream = this.streams.get(controller.id);
|
|
58404
|
+
if (stream?.exhausted) return;
|
|
58405
|
+
if (!stream || stream.active !== event.streamId) {
|
|
58406
|
+
if (event.category !== "state" || stream?.retired.has(event.streamId) || stream && (!event.connected || Date.now() - eventTime > STALE_AFTER_MS2 || eventTime <= stream.latestSourceTime)) {
|
|
58407
|
+
this.context.logger.warn(`Ignoring unestablished or retired WAGO stream for ${controller.hardwareId}`);
|
|
58408
|
+
return;
|
|
58409
|
+
}
|
|
58410
|
+
if (stream && stream.retired.size >= MAX_RETIRED_STREAMS) {
|
|
58411
|
+
stream.exhausted = true;
|
|
58412
|
+
for (const state of this.cache.values()) if (state.controllerId === controller.id) state.invalidated = true;
|
|
58413
|
+
this.context.logger.warn(
|
|
58414
|
+
`WAGO stream history exhausted for ${controller.hardwareId}; refusing further samples`
|
|
58415
|
+
);
|
|
58416
|
+
return;
|
|
58417
|
+
}
|
|
58418
|
+
const retired = stream?.retired ?? /* @__PURE__ */ new Set();
|
|
58419
|
+
if (stream) retired.add(stream.active);
|
|
58420
|
+
stream = {
|
|
58421
|
+
active: event.streamId,
|
|
58422
|
+
latestSourceTime: eventTime,
|
|
58423
|
+
sampleNotBefore: eventTime,
|
|
58424
|
+
retired,
|
|
58425
|
+
sequences: /* @__PURE__ */ new Map()
|
|
58426
|
+
};
|
|
58427
|
+
this.streams.set(controller.id, stream);
|
|
58428
|
+
for (const state of this.cache.values()) if (state.controllerId === controller.id) state.invalidated = true;
|
|
58429
|
+
}
|
|
58430
|
+
const previous = stream.sequences.get(event.category);
|
|
58431
|
+
if (previous !== void 0 && event.sequence <= previous) {
|
|
58369
58432
|
this.context.logger.warn(`Ignoring duplicate or out-of-order WAGO event for ${controller.hardwareId}`);
|
|
58370
58433
|
return;
|
|
58371
58434
|
}
|
|
58372
|
-
if (previous !== void 0 && event.sequence <= previous)
|
|
58373
|
-
this.context.logger.warn(`Resetting WAGO event sequence after controller reconnect for ${controller.hardwareId}`);
|
|
58374
58435
|
if (previous !== void 0 && event.sequence > previous + 1)
|
|
58375
58436
|
this.context.logger.warn(
|
|
58376
58437
|
`WAGO event sequence gap for ${controller.hardwareId}: ${previous} to ${event.sequence}`
|
|
58377
58438
|
);
|
|
58378
|
-
|
|
58379
|
-
|
|
58380
|
-
|
|
58381
|
-
|
|
58382
|
-
|
|
58383
|
-
|
|
58384
|
-
|
|
58385
|
-
|
|
58386
|
-
|
|
58387
|
-
|
|
58439
|
+
stream.sequences.set(event.category, event.sequence);
|
|
58440
|
+
stream.latestSourceTime = Math.max(stream.latestSourceTime, eventTime);
|
|
58441
|
+
if (event.category === "state") {
|
|
58442
|
+
const wasUnavailable = this.offlineControllers.has(controller.id) || this.unavailableHardware.has(controller.id) || this.unavailableConfiguration.has(controller.id) || stream.stateTimestamp !== void 0 && Date.now() - stream.stateTimestamp > STALE_AFTER_MS2;
|
|
58443
|
+
stream.stateTimestamp = eventTime;
|
|
58444
|
+
if (event.connected) this.offlineControllers.delete(controller.id);
|
|
58445
|
+
else this.offlineControllers.add(controller.id);
|
|
58446
|
+
if (event.readiness?.hardwareAvailable === false) this.unavailableHardware.add(controller.id);
|
|
58447
|
+
else if (event.readiness?.hardwareAvailable === true) this.unavailableHardware.delete(controller.id);
|
|
58448
|
+
const applied = this.appliedConfigurations.get(controller.id);
|
|
58449
|
+
if (applied && event.revision === applied.revision && event.contentHash === applied.contentHash)
|
|
58450
|
+
this.unavailableConfiguration.delete(controller.id);
|
|
58451
|
+
else this.unavailableConfiguration.add(controller.id);
|
|
58452
|
+
if (wasUnavailable || !event.connected || this.unavailableHardware.has(controller.id) || this.unavailableConfiguration.has(controller.id))
|
|
58453
|
+
stream.sampleNotBefore = Math.max(stream.sampleNotBefore, eventTime);
|
|
58454
|
+
for (const state of this.cache.values()) {
|
|
58455
|
+
if (state.controllerId !== controller.id) continue;
|
|
58456
|
+
if (wasUnavailable || !event.connected || this.unavailableHardware.has(controller.id) || this.unavailableConfiguration.has(controller.id) || state.category === "state")
|
|
58457
|
+
state.invalidated = true;
|
|
58458
|
+
}
|
|
58459
|
+
for (const channel of channels) {
|
|
58460
|
+
const value = channel.capabilities.includes("input") && Object.hasOwn(event.inputs ?? {}, channel.id) ? event.inputs[channel.id] : channel.capabilities.includes("output") && Object.hasOwn(event.outputs, channel.id) ? event.outputs[channel.id] : void 0;
|
|
58461
|
+
if (typeof value === "boolean") this.store(controller, channel.id, event, value);
|
|
58462
|
+
}
|
|
58463
|
+
} else if ("channelId" in event) {
|
|
58464
|
+
const channel = channels.find((channel2) => channel2.id === event.channelId);
|
|
58465
|
+
if (!channel || event.category === "measurement" && !channel.capabilities.includes("measurement")) return;
|
|
58466
|
+
this.store(controller, event.channelId, event, event.category === "measurement" ? event.value : event);
|
|
58467
|
+
}
|
|
58468
|
+
}
|
|
58469
|
+
store(controller, channelId, event, value) {
|
|
58388
58470
|
const state = {
|
|
58389
58471
|
controllerId: controller.id,
|
|
58390
58472
|
hardwareId: controller.hardwareId,
|
|
@@ -58393,7 +58475,12 @@ var WagoFlowService = class {
|
|
|
58393
58475
|
value,
|
|
58394
58476
|
timestamp: event.timestamp,
|
|
58395
58477
|
sequence: event.sequence,
|
|
58396
|
-
|
|
58478
|
+
streamId: event.streamId,
|
|
58479
|
+
...event.category === "measurement" ? { unit: event.unit, kind: event.kind } : {},
|
|
58480
|
+
...event.category === "state" ? { revision: event.revision, contentHash: event.contentHash } : {},
|
|
58481
|
+
receivedAt: Date.now(),
|
|
58482
|
+
offline: this.offlineControllers.has(controller.id),
|
|
58483
|
+
invalidated: this.unavailableHardware.has(controller.id) || this.unavailableConfiguration.has(controller.id) || Date.parse(event.timestamp) < (this.streams.get(controller.id)?.sampleNotBefore ?? 0)
|
|
58397
58484
|
};
|
|
58398
58485
|
const cacheKey = this.cacheKey(controller.id, channelId, event.category);
|
|
58399
58486
|
const previous = this.cache.get(cacheKey);
|
|
@@ -58435,6 +58522,16 @@ var WagoFlowService = class {
|
|
|
58435
58522
|
cacheChannels(revision) {
|
|
58436
58523
|
try {
|
|
58437
58524
|
const channels = JSON.parse(revision.snapshot).logicalChannels;
|
|
58525
|
+
const previous = this.appliedConfigurations.get(revision.controllerId);
|
|
58526
|
+
if (previous?.revision !== revision.revision || previous?.contentHash !== revision.contentHash) {
|
|
58527
|
+
this.unavailableConfiguration.add(revision.controllerId);
|
|
58528
|
+
for (const state of this.cache.values())
|
|
58529
|
+
if (state.controllerId === revision.controllerId) state.invalidated = true;
|
|
58530
|
+
}
|
|
58531
|
+
this.appliedConfigurations.set(revision.controllerId, {
|
|
58532
|
+
revision: revision.revision,
|
|
58533
|
+
contentHash: revision.contentHash
|
|
58534
|
+
});
|
|
58438
58535
|
this.channelCache.set(revision.controllerId, channels);
|
|
58439
58536
|
return channels;
|
|
58440
58537
|
} catch {
|
|
@@ -58447,21 +58544,21 @@ var WagoFlowService = class {
|
|
|
58447
58544
|
}
|
|
58448
58545
|
categories(channel) {
|
|
58449
58546
|
return [
|
|
58450
|
-
...channel?.capabilities.
|
|
58547
|
+
...channel?.capabilities.some((capability) => capability === "input" || capability === "output") ? ["state"] : [],
|
|
58451
58548
|
...channel?.capabilities.includes("measurement") ? ["measurement"] : [],
|
|
58452
58549
|
"fault"
|
|
58453
58550
|
];
|
|
58454
58551
|
}
|
|
58455
58552
|
readCategories(channel) {
|
|
58456
58553
|
return [
|
|
58457
|
-
...channel?.capabilities.
|
|
58554
|
+
...channel?.capabilities.some((capability) => capability === "input" || capability === "output") ? ["state"] : [],
|
|
58458
58555
|
...channel?.capabilities.includes("measurement") ? ["measurement"] : []
|
|
58459
58556
|
];
|
|
58460
58557
|
}
|
|
58461
58558
|
matchesEvent(config, nodeId, state, previous) {
|
|
58462
58559
|
if (config.controllerId !== state.controllerId || config.channelId !== state.channelId || config.category !== state.category)
|
|
58463
58560
|
return false;
|
|
58464
|
-
if (typeof config.minimumChange === "number" && typeof state.value === "number" && typeof previous?.value === "number" && Math.abs(state.value - previous.value) < config.minimumChange)
|
|
58561
|
+
if (typeof config.minimumChange === "number" && typeof state.value === "number" && typeof previous?.value === "number" && previous.streamId === state.streamId && previous.unit === state.unit && previous.kind === state.kind && Math.abs(state.value - previous.value) < config.minimumChange)
|
|
58465
58562
|
return false;
|
|
58466
58563
|
if (typeof config.minimumIntervalMs === "number") {
|
|
58467
58564
|
const lastDispatchAt = this.lastDispatchAtByNode.get(nodeId);
|
|
@@ -58471,10 +58568,26 @@ var WagoFlowService = class {
|
|
|
58471
58568
|
return true;
|
|
58472
58569
|
}
|
|
58473
58570
|
matchesCondition(state, config) {
|
|
58474
|
-
return config.equals === void 0 || state.value === config.equals;
|
|
58571
|
+
return this.freshness(state).available && (config.equals === void 0 || state.value === config.equals);
|
|
58572
|
+
}
|
|
58573
|
+
freshness(state) {
|
|
58574
|
+
const age = Date.now() - Date.parse(state.timestamp);
|
|
58575
|
+
const stale = !Number.isFinite(age) || age < 0 || age > STALE_AFTER_MS2;
|
|
58576
|
+
const offline = state.offline === true || this.offlineControllers.has(state.controllerId);
|
|
58577
|
+
const stream = this.streams.get(state.controllerId);
|
|
58578
|
+
const stateTimestamp = stream?.stateTimestamp;
|
|
58579
|
+
const connectionStale = stateTimestamp === void 0 || Date.now() - stateTimestamp > STALE_AFTER_MS2;
|
|
58580
|
+
return {
|
|
58581
|
+
stale,
|
|
58582
|
+
offline,
|
|
58583
|
+
connectionStale,
|
|
58584
|
+
available: !stale && !offline && !connectionStale && stream?.active === state.streamId && !stream.exhausted && Date.parse(state.timestamp) >= stream.sampleNotBefore && !state.invalidated && !this.unavailableHardware.has(state.controllerId) && !this.unavailableConfiguration.has(state.controllerId)
|
|
58585
|
+
};
|
|
58475
58586
|
}
|
|
58476
58587
|
payload(state) {
|
|
58477
|
-
|
|
58588
|
+
const payload = { ...state };
|
|
58589
|
+
delete payload.invalidated;
|
|
58590
|
+
return { ...payload, ...this.freshness(state) };
|
|
58478
58591
|
}
|
|
58479
58592
|
dispatch() {
|
|
58480
58593
|
while (this.activeDispatches < MAX_CONCURRENT_DISPATCHES && this.dispatches.length) {
|
|
@@ -58488,6 +58601,8 @@ var WagoFlowService = class {
|
|
|
58488
58601
|
}
|
|
58489
58602
|
}
|
|
58490
58603
|
async trigger({ state, previous }) {
|
|
58604
|
+
const stream = this.streams.get(state.controllerId);
|
|
58605
|
+
if (stream?.active !== state.streamId || stream.exhausted) return;
|
|
58491
58606
|
try {
|
|
58492
58607
|
await this.context.flows.trigger(
|
|
58493
58608
|
"plugin.wago.event-received",
|