@camstack/system 1.2.483 → 1.2.485
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/{agent-https-CHZpVx3I.js → agent-https-DBP7P-ee.js} +1 -1
- package/dist/{agent-https-NP141VCW.mjs → agent-https-_EXvi6F8.mjs} +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +13 -5
- package/dist/builtins/composer/composer.addon.mjs +13 -5
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-history/device-history.addon.d.ts +2 -0
- package/dist/builtins/device-history/device-history.addon.js +248 -4
- package/dist/builtins/device-history/device-history.addon.mjs +248 -4
- package/dist/builtins/device-history/query/history-query.d.ts +5 -1
- package/dist/builtins/device-history/runtime/history-runtime.d.ts +18 -1
- package/dist/builtins/device-history/store/history-schema.d.ts +2 -0
- package/dist/builtins/device-history/store/history-store.d.ts +11 -0
- package/dist/builtins/device-history/store/series-scale.d.ts +37 -0
- package/dist/builtins/device-manager/device-manager.addon.js +3 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +3 -2
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +3 -3
- package/dist/builtins/keychain/index.mjs +3 -3
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +2 -2
- package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
- package/dist/builtins/local-network/local-network.addon.js +2 -2
- package/dist/builtins/local-network/local-network.addon.mjs +2 -2
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/record-entries/index.js +1 -1
- package/dist/builtins/record-entries/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +2 -2
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +2 -2
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +3 -3
- package/dist/builtins/system-config/system-config.addon.mjs +280 -280
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-CQxrCexr.js → composition-sources-BSQneZV9.js} +1 -1
- package/dist/{composition-sources-CC13wGKL.mjs → composition-sources-BnZpIA8u.mjs} +1 -1
- package/dist/{constants-DMB-ex5z.mjs → constants-7D7xjw0h.mjs} +1 -1
- package/dist/{constants-Bt0NFXDm.js → constants-CQfTeCnB.js} +1 -1
- package/dist/{device-ca-HQKcvofS.mjs → device-ca-Bzd6UO_c.mjs} +1 -1
- package/dist/{device-ca-CSLMfr4Q.js → device-ca-D_4dI5gv.js} +1 -1
- package/dist/{dist-DvKEKSap.mjs → dist-Df6c0RX_.mjs} +614 -522
- package/dist/{dist-2gZWO597.js → dist-xCNJAQMh.js} +625 -521
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/{hub-mdns-ciao-CVf6mxIZ.mjs → hub-mdns-ciao-D7GMnEz0.mjs} +2 -2
- package/dist/{hub-mdns-ciao-Bs3cn9C1.js → hub-mdns-ciao-DRfmLR_Z.js} +2 -2
- package/dist/index.js +7 -7
- package/dist/index.mjs +7 -7
- package/dist/{restore-archive-EFYeCdrG.mjs → restore-archive-Co70oRya.mjs} +78 -78
- package/dist/{restore-archive-_mgadWlk.js → restore-archive-DA7N6ZZA.js} +1 -1
- package/dist/{retention-qugQGYuY.js → retention-DNDOPW7Z.js} +1 -1
- package/dist/{retention-FFJW3-3P.mjs → retention-DfCW-dZS.mjs} +1 -1
- package/dist/{wal-maintenance-TCW_esAc.mjs → wal-maintenance-71-j48Ci.mjs} +0 -0
- package/dist/{wal-maintenance-DbUC_wdC.js → wal-maintenance-CA0L6WZ9.js} +0 -0
- package/package.json +7 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
2
|
-
const require_dist = require("./dist-
|
|
2
|
+
const require_dist = require("./dist-xCNJAQMh.js");
|
|
3
3
|
const require_x509_es = require("./x509.es-WtnRNyYS.js");
|
|
4
4
|
let zod = require("zod");
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ji as defineRecordKinds } from "./dist-
|
|
1
|
+
import { Ji as defineRecordKinds } from "./dist-Df6c0RX_.mjs";
|
|
2
2
|
import { C as backdatedNotBefore, S as withUtcTimeEncoding, _ as NameConstraints, a as KeyUsageFlags, c as Pkcs10CertificateRequest, d as SubjectKeyIdentifierExtension, f as X509Certificate$1, g as GeneralSubtrees, h as GeneralSubtree, i as Extension, l as Pkcs10CertificateRequestGenerator, m as cryptoProvider, n as BasicConstraintsExtension, o as KeyUsagesExtension, p as X509CertificateGenerator, r as ExtendedKeyUsageExtension, s as PemConverter, t as AuthorityKeyIdentifierExtension, u as SubjectAlternativeNameExtension, v as GeneralName, x as AsnConvert } from "./x509.es-BRiJgOvu.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { X509Certificate, createHash, createPrivateKey, randomBytes, webcrypto } from "node:crypto";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-xCNJAQMh.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _t as addonPagesCapability,
|
|
1
|
+
import { _t as addonPagesCapability, ja as EventCategory, ni as BaseAddon, ti as errMsg } from "../../dist-Df6c0RX_.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-xCNJAQMh.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ja as EventCategory, ni as BaseAddon, ti as errMsg, yt as addonWidgetsCapability } from "../../dist-Df6c0RX_.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-xCNJAQMh.js");
|
|
7
7
|
const require_read_all_rows$1 = require("../../read-all-rows-CVoO1ONM.js");
|
|
8
8
|
//#region src/builtins/alerts/alert-episode-policy.ts
|
|
9
9
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Gi as createEvent, Ji as defineRecordKinds, St as alertsCapability, bn as isAlertEpisodeSeverity, bt as alertEpisodeId, i as AlertSchema,
|
|
1
|
+
import { Gi as createEvent, Ji as defineRecordKinds, St as alertsCapability, bn as isAlertEpisodeSeverity, bt as alertEpisodeId, i as AlertSchema, ja as EventCategory, ni as BaseAddon, ti as errMsg, xt as alertEpisodePayload, yn as isAlertEpisodeOpen } from "../../dist-Df6c0RX_.mjs";
|
|
2
2
|
import { t as require_read_all_rows } from "../../read-all-rows-TaPqdWNF.mjs";
|
|
3
3
|
//#region src/builtins/alerts/alert-episode-policy.ts
|
|
4
4
|
/**
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-xCNJAQMh.js");
|
|
7
7
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
8
8
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
9
9
|
deadZoneFraction: .5,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Et as bareAddonId, I as FIRST_LEVEL_MACRO_CLASSES,
|
|
1
|
+
import { Et as bareAddonId, I as FIRST_LEVEL_MACRO_CLASSES, ja as EventCategory, ni as BaseAddon, ra as isEvent, rr as ptzAutotrackCapability, ti as errMsg } from "../../dist-Df6c0RX_.mjs";
|
|
2
2
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
3
3
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
4
4
|
deadZoneFraction: .5,
|
|
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-xCNJAQMh.js");
|
|
7
7
|
const require_read_all_rows$1 = require("../../read-all-rows-CVoO1ONM.js");
|
|
8
|
-
const require_restore_archive = require("../../restore-archive-
|
|
8
|
+
const require_restore_archive = require("../../restore-archive-DA7N6ZZA.js");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
10
10
|
let node_fs_promises = require("node:fs/promises");
|
|
11
11
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Or as storageOccupancyCapability, Tt as backupCapability, Vn as mayWriteToLocation,
|
|
1
|
+
import { Ea as toNodeId, Or as storageOccupancyCapability, Tt as backupCapability, Vn as mayWriteToLocation, fa as nodePin, ja as EventCategory, ni as BaseAddon } from "../../dist-Df6c0RX_.mjs";
|
|
2
2
|
import { t as require_read_all_rows } from "../../read-all-rows-TaPqdWNF.mjs";
|
|
3
|
-
import { _ as backupRecordStoresOf, a as BackupSnapshotRefusedError, d as ENCRYPTED_BACKUP_SUFFIX, f as generateBackupKeyPair, g as backupOrchestratorRecordKinds, i as BackupCancelledError, l as BackupKeyFormatError, m as parseBackupSecretKey, n as precheckRestoreKey, o as DEFAULT_BACKUP_DATABASES, p as parseBackupPublicKey, r as prepareRestoreArchive, s as SystemBackupService } from "../../restore-archive-
|
|
3
|
+
import { _ as backupRecordStoresOf, a as BackupSnapshotRefusedError, d as ENCRYPTED_BACKUP_SUFFIX, f as generateBackupKeyPair, g as backupOrchestratorRecordKinds, i as BackupCancelledError, l as BackupKeyFormatError, m as parseBackupSecretKey, n as precheckRestoreKey, o as DEFAULT_BACKUP_DATABASES, p as parseBackupPublicKey, r as prepareRestoreArchive, s as SystemBackupService } from "../../restore-archive-Co70oRya.mjs";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import * as fsp from "node:fs/promises";
|
|
6
6
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-xCNJAQMh.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
//#region src/builtins/calendars/calendar-color.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ji as defineRecordKinds, Mt as calendarsCapability, g as CalendarPreferencesSchema, ni as BaseAddon } from "../../dist-
|
|
1
|
+
import { Ji as defineRecordKinds, Mt as calendarsCapability, g as CalendarPreferencesSchema, ni as BaseAddon } from "../../dist-Df6c0RX_.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/builtins/calendars/calendar-color.ts
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-xCNJAQMh.js");
|
|
7
7
|
let zod = require("zod");
|
|
8
8
|
let _camstack_types_node = require("@camstack/types/node");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ar as streamCatalogCapability, Cr as snapshotCapability, Gi as createEvent, Gn as motionCapability, Hn as memoizePinnedFfmpeg, N as DeclaredDevices, Nt as cameraGridLayoutCapability, Qr as DeviceFeature, T as DERIVED_CAMERA_SILENCED_CAP_NAMES, Vr as buildFfmpegArgs, X as MOTION_CLOSE_AFTER_MS, a as BaseDevice,
|
|
1
|
+
import { Ar as streamCatalogCapability, Cr as snapshotCapability, Gi as createEvent, Gn as motionCapability, Hn as memoizePinnedFfmpeg, N as DeclaredDevices, Nt as cameraGridLayoutCapability, Qr as DeviceFeature, T as DERIVED_CAMERA_SILENCED_CAP_NAMES, Vr as buildFfmpegArgs, X as MOTION_CLOSE_AFTER_MS, a as BaseDevice, ei as DeviceType, ja as EventCategory, ni as BaseAddon, qt as declarationOwnerNodeId, ta as hydrateSchema, ti as errMsg } from "../../dist-Df6c0RX_.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { FfmpegProcess } from "@camstack/types/node";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
7
|
-
const require_composition_sources = require("../../composition-sources-
|
|
8
|
-
const require_retention = require("../../retention-
|
|
6
|
+
const require_dist = require("../../dist-xCNJAQMh.js");
|
|
7
|
+
const require_composition_sources = require("../../composition-sources-BSQneZV9.js");
|
|
8
|
+
const require_retention = require("../../retention-DNDOPW7Z.js");
|
|
9
9
|
let zod = require("zod");
|
|
10
10
|
//#region src/builtins/shared/device-state-changed.ts
|
|
11
11
|
/** Structural narrowing helper for untrusted bus payloads. */
|
|
@@ -569,7 +569,7 @@ function withEntry(map, key, value) {
|
|
|
569
569
|
return new Map([...map, [key, value]]);
|
|
570
570
|
}
|
|
571
571
|
function nativeTakenReason(addonId, when) {
|
|
572
|
-
return `a native provider (${addonId}) ${when} — the cap is not grafted and its claim is kept
|
|
572
|
+
return `a native provider (${addonId}) ${when} — the cap is not grafted and its claim is kept`;
|
|
573
573
|
}
|
|
574
574
|
var ComposerGrafts = class {
|
|
575
575
|
ports;
|
|
@@ -610,9 +610,10 @@ var ComposerGrafts = class {
|
|
|
610
610
|
if (ports === void 0) return;
|
|
611
611
|
const { deviceId } = input;
|
|
612
612
|
const added = input.enabled && input.settled ? addedCapsOf(input.features) : [];
|
|
613
|
+
const nativeNow = new Set([...input.nativeCaps.entries()].filter(([, owner]) => owner !== require_dist.COMPOSER_ADDON_ID).map(([cap]) => cap));
|
|
613
614
|
const replaced = new Set(input.features.filter((f) => f.mode === "replace").map((f) => f.cap));
|
|
614
615
|
for (const cap of ports.grafted(deviceId)) {
|
|
615
|
-
if (!replaced.has(cap)) continue;
|
|
616
|
+
if (!nativeNow.has(cap) && !replaced.has(cap)) continue;
|
|
616
617
|
this.logger.info("a native provider serves a grafted cap — the graft is removed; the claim stays", {
|
|
617
618
|
tags: { deviceId },
|
|
618
619
|
meta: { cap }
|
|
@@ -1161,6 +1162,13 @@ function logPlanTransition(logger, previous, p, liveTags) {
|
|
|
1161
1162
|
}
|
|
1162
1163
|
});
|
|
1163
1164
|
else if (p.problems.length === 0) logger.info("composition plans again", extras);
|
|
1165
|
+
else if (target.kind === "existing" && target.deviceId !== null && p.problems.some((line) => line.includes("native-capability-replace"))) logger.warn(`stored customization ${p.block.id} replaces a native capability — refused`, {
|
|
1166
|
+
tags: { deviceId: target.deviceId },
|
|
1167
|
+
meta: {
|
|
1168
|
+
...extras.meta,
|
|
1169
|
+
problems: p.problems
|
|
1170
|
+
}
|
|
1171
|
+
});
|
|
1164
1172
|
else logger.warn(p.declaration === null ? "composition does not plan — no device is declared for it" : "composition no longer plans — its device is kept offline with no capabilities", extras);
|
|
1165
1173
|
}
|
|
1166
1174
|
//#endregion
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $n as planComposition, Br as COMPOSER_ADDON_ID, Gi as createEvent, Gr as compositionFeatureEnabled, Hr as cloneStatefulExpressionMemory, It as composerCapability, Jr as compositionSourceKey, Kr as compositionItemFieldPath, Lt as compositionFieldKey, N as DeclaredDevices, Ot as buildCapabilityLookup, Ur as composedDeviceRef, Wr as composedDeviceStableId, Xr as disarmRoseMemory, Yr as createStatefulExpressionMemory, Zr as toExpressionValue, a as BaseDevice, cn as evaluateCompositionField, d as COMPOSED_ITEM_FIXED_FIELDS, dn as expressionContainsBuiltinCall, ei as DeviceType,
|
|
2
|
-
import { n as normalizedNativeOwner } from "../../composition-sources-
|
|
3
|
-
import { i as DAY_MS, m as capSeriesKey, t as DEFAULT_RETENTION } from "../../retention-
|
|
1
|
+
import { $n as planComposition, Br as COMPOSER_ADDON_ID, Gi as createEvent, Gr as compositionFeatureEnabled, Hr as cloneStatefulExpressionMemory, It as composerCapability, Jr as compositionSourceKey, Kr as compositionItemFieldPath, Lt as compositionFieldKey, N as DeclaredDevices, Ot as buildCapabilityLookup, Ur as composedDeviceRef, Wr as composedDeviceStableId, Xr as disarmRoseMemory, Yr as createStatefulExpressionMemory, Zr as toExpressionValue, a as BaseDevice, cn as evaluateCompositionField, d as COMPOSED_ITEM_FIXED_FIELDS, dn as expressionContainsBuiltinCall, ei as DeviceType, ja as EventCategory, ni as BaseAddon, qr as compositionSliceKey, r as ALL_CAPABILITY_DEFINITIONS, ti as errMsg } from "../../dist-Df6c0RX_.mjs";
|
|
2
|
+
import { n as normalizedNativeOwner } from "../../composition-sources-BnZpIA8u.mjs";
|
|
3
|
+
import { i as DAY_MS, m as capSeriesKey, t as DEFAULT_RETENTION } from "../../retention-DfCW-dZS.mjs";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/builtins/shared/device-state-changed.ts
|
|
6
6
|
/** Structural narrowing helper for untrusted bus payloads. */
|
|
@@ -564,7 +564,7 @@ function withEntry(map, key, value) {
|
|
|
564
564
|
return new Map([...map, [key, value]]);
|
|
565
565
|
}
|
|
566
566
|
function nativeTakenReason(addonId, when) {
|
|
567
|
-
return `a native provider (${addonId}) ${when} — the cap is not grafted and its claim is kept
|
|
567
|
+
return `a native provider (${addonId}) ${when} — the cap is not grafted and its claim is kept`;
|
|
568
568
|
}
|
|
569
569
|
var ComposerGrafts = class {
|
|
570
570
|
ports;
|
|
@@ -605,9 +605,10 @@ var ComposerGrafts = class {
|
|
|
605
605
|
if (ports === void 0) return;
|
|
606
606
|
const { deviceId } = input;
|
|
607
607
|
const added = input.enabled && input.settled ? addedCapsOf(input.features) : [];
|
|
608
|
+
const nativeNow = new Set([...input.nativeCaps.entries()].filter(([, owner]) => owner !== COMPOSER_ADDON_ID).map(([cap]) => cap));
|
|
608
609
|
const replaced = new Set(input.features.filter((f) => f.mode === "replace").map((f) => f.cap));
|
|
609
610
|
for (const cap of ports.grafted(deviceId)) {
|
|
610
|
-
if (!replaced.has(cap)) continue;
|
|
611
|
+
if (!nativeNow.has(cap) && !replaced.has(cap)) continue;
|
|
611
612
|
this.logger.info("a native provider serves a grafted cap — the graft is removed; the claim stays", {
|
|
612
613
|
tags: { deviceId },
|
|
613
614
|
meta: { cap }
|
|
@@ -1156,6 +1157,13 @@ function logPlanTransition(logger, previous, p, liveTags) {
|
|
|
1156
1157
|
}
|
|
1157
1158
|
});
|
|
1158
1159
|
else if (p.problems.length === 0) logger.info("composition plans again", extras);
|
|
1160
|
+
else if (target.kind === "existing" && target.deviceId !== null && p.problems.some((line) => line.includes("native-capability-replace"))) logger.warn(`stored customization ${p.block.id} replaces a native capability — refused`, {
|
|
1161
|
+
tags: { deviceId: target.deviceId },
|
|
1162
|
+
meta: {
|
|
1163
|
+
...extras.meta,
|
|
1164
|
+
problems: p.problems
|
|
1165
|
+
}
|
|
1166
|
+
});
|
|
1159
1167
|
else logger.warn(p.declaration === null ? "composition does not plan — no device is declared for it" : "composition no longer plans — its device is kept offline with no capabilities", extras);
|
|
1160
1168
|
}
|
|
1161
1169
|
//#endregion
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-xCNJAQMh.js");
|
|
7
7
|
const require_formatter = require("../../formatter-xbxeV4GD.js");
|
|
8
8
|
//#region src/builtins/console-logging/console-destination.ts
|
|
9
9
|
var LEVEL_RANK = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ln as logDestinationCapability, ni as BaseAddon } from "../../dist-
|
|
1
|
+
import { Ln as logDestinationCapability, ni as BaseAddon } from "../../dist-Df6c0RX_.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-DkYZ4LXp.mjs";
|
|
3
3
|
//#region src/builtins/console-logging/console-destination.ts
|
|
4
4
|
var LEVEL_RANK = {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-xCNJAQMh.js");
|
|
4
4
|
const require_read_all_rows$1 = require("../../read-all-rows-CVoO1ONM.js");
|
|
5
|
-
const require_composition_sources = require("../../composition-sources-
|
|
5
|
+
const require_composition_sources = require("../../composition-sources-BSQneZV9.js");
|
|
6
6
|
const require_prefix_range = require("../../prefix-range-D_KueXbQ.js");
|
|
7
7
|
const require_prefix_walk = require("../../prefix-walk-Dv6MLZlM.js");
|
|
8
8
|
let zod = require("zod");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $n as planComposition, Bt as coreBlockComposition,
|
|
1
|
+
import { $n as planComposition, Bt as coreBlockComposition, Ht as coreBlockSourceKind, Ji as defineRecordKinds, Jr as compositionSourceKey, Kn as normalizeCoreBlockWrite, N as DeclaredDevices, Oa as transformSecretWrite, Ot as buildCapabilityLookup, Pr as validateComposition, Rt as compositionSourceRefs, Ui as collectSecretMarkerRefs, Ur as composedDeviceRef, Ut as coreBlocksCapability, Vt as coreBlockIdFromAddonId, Zt as describeComposableCaps, dr as resolveCoreBlockFiles, f as COMPOSER_RUNNER_ID, la as isSecretRefOwnedBy, m as CORE_BLOCK_ADDON_PREFIX, ni as BaseAddon, p as CORE_BLOCKS_ADDON_ID, r as ALL_CAPABILITY_DEFINITIONS, sa as isSecretMarker, sr as replacedFieldKeys, ta as hydrateSchema, ti as errMsg, tr as problemsBlockSave, ur as resolveCoreBlockEntry, v as CoreBlockSchema, wa as secretTreeFromSchema, xa as resolveSecretMarkers, zt as coreBlockAddonId } from "../../dist-Df6c0RX_.mjs";
|
|
2
2
|
import { t as require_read_all_rows } from "../../read-all-rows-TaPqdWNF.mjs";
|
|
3
|
-
import { t as describeCompositionSources } from "../../composition-sources-
|
|
3
|
+
import { t as describeCompositionSources } from "../../composition-sources-BnZpIA8u.mjs";
|
|
4
4
|
import { t as prefixRange } from "../../prefix-range-Dl0znowN.mjs";
|
|
5
5
|
import { n as unwrapStoredValue, t as loadPrefixed } from "../../prefix-walk-DAOBSyH1.mjs";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
@@ -41,6 +41,8 @@ export declare class DeviceHistoryAddon extends BaseAddon<DeviceHistoryConfig> {
|
|
|
41
41
|
/** Readiness of both provided caps, on the bare node this runner belongs to. */
|
|
42
42
|
private emitStoreReadiness;
|
|
43
43
|
private retention;
|
|
44
|
+
/** Unraid array counters still stored in GiB. A failed listing throws to the caller. */
|
|
45
|
+
private legacyScales;
|
|
44
46
|
private requireRuntime;
|
|
45
47
|
protected onInitialize(): Promise<ProviderRegistration[]>;
|
|
46
48
|
override onHubReachable(): Promise<void>;
|
|
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
7
|
-
const require_retention = require("../../retention-
|
|
6
|
+
const require_dist = require("../../dist-xCNJAQMh.js");
|
|
7
|
+
const require_retention = require("../../retention-DNDOPW7Z.js");
|
|
8
8
|
//#region src/builtins/device-history/capture/point-writer.ts
|
|
9
9
|
var FLUSH_INTERVAL_MS = 1e4;
|
|
10
10
|
var MAX_BUFFER_AGE_MS = 6e4;
|
|
@@ -451,6 +451,13 @@ var MAX_SCOPES = 50;
|
|
|
451
451
|
/** The power-meter series the energy key is derived from, meter first. */
|
|
452
452
|
var ENERGY_METER_KEY = require_retention.capSeriesKey("power-meter", "kwhTotal");
|
|
453
453
|
var ENERGY_POWER_KEY = require_retention.capSeriesKey("power-meter", "watts");
|
|
454
|
+
/**
|
|
455
|
+
* Series whose quantity is chosen per device (D944). Weather is not here:
|
|
456
|
+
* each weather field has its own quantity on the capability, and the catalog
|
|
457
|
+
* unit is that base. A past weather point stored in another unit cannot be
|
|
458
|
+
* rescaled — the unit at sample time was not kept.
|
|
459
|
+
*/
|
|
460
|
+
var DEVICE_QUANTITY_KEYS = new Set([require_retention.capSeriesKey("numeric-sensor", "value")]);
|
|
454
461
|
function retentionMsOf(tier, policy) {
|
|
455
462
|
if (tier === "raw") return policy.rawDays * require_retention.DAY_MS;
|
|
456
463
|
if (tier === "5m") return policy.fiveMinuteDays * require_retention.DAY_MS;
|
|
@@ -717,12 +724,26 @@ var HistoryQuery = class {
|
|
|
717
724
|
/** The metric's fixed unit, else the device's own (a `unitFrom` field), else unknown. */
|
|
718
725
|
async unitOf(subject, series, fixed, slices) {
|
|
719
726
|
if (fixed !== null || subject.kind !== "device" || !series.key.startsWith("cap:")) return fixed;
|
|
727
|
+
if (DEVICE_QUANTITY_KEYS.has(series.key)) {
|
|
728
|
+
const quantity = await this.quantityOf(subject.deviceId);
|
|
729
|
+
if (quantity === null || quantity === "device" || quantity === "none") return null;
|
|
730
|
+
return require_dist.historyUnitFor(quantity) ?? null;
|
|
731
|
+
}
|
|
720
732
|
const spec = this.specOf(series.key);
|
|
721
733
|
if (spec?.unitFrom === void 0) return null;
|
|
722
734
|
const capName = series.key.slice(require_retention.CAP_KEY_PREFIX.length, series.key.indexOf("."));
|
|
723
735
|
const slice = await this.sliceOf(subject.deviceId, capName, slices);
|
|
724
736
|
return slice === null ? null : require_retention.readUnit(slice, spec.unitFrom);
|
|
725
737
|
}
|
|
738
|
+
quantityOf(deviceId) {
|
|
739
|
+
const pending = this.quantities.get(deviceId);
|
|
740
|
+
if (pending !== void 0) return pending;
|
|
741
|
+
const read = this.deps.readDeviceQuantity;
|
|
742
|
+
const run = read === void 0 ? Promise.resolve(null) : read(deviceId).catch(() => null);
|
|
743
|
+
this.quantities.set(deviceId, run);
|
|
744
|
+
return run;
|
|
745
|
+
}
|
|
746
|
+
quantities = /* @__PURE__ */ new Map();
|
|
726
747
|
specOf(key) {
|
|
727
748
|
const body = key.slice(require_retention.CAP_KEY_PREFIX.length);
|
|
728
749
|
const dot = body.indexOf(".");
|
|
@@ -882,6 +903,59 @@ var OrphanSeries = class {
|
|
|
882
903
|
}
|
|
883
904
|
};
|
|
884
905
|
//#endregion
|
|
906
|
+
//#region src/builtins/device-history/store/series-scale.ts
|
|
907
|
+
/**
|
|
908
|
+
* One-shot rescales of series whose every stored point shared one factor
|
|
909
|
+
* (D944). A reading already in the base unit is at or above `legacyMax` and
|
|
910
|
+
* is left alone, so a second pass does not multiply it again.
|
|
911
|
+
*
|
|
912
|
+
* Rollup `sum` / `tw_sum` follow the bucket when min, max and last are still
|
|
913
|
+
* in the old unit. Judging the sum itself would skip a day's samples of a
|
|
914
|
+
* large gauge (many × GiB already exceeds the ceiling) and keep the raw
|
|
915
|
+
* points and the rollup in different units.
|
|
916
|
+
*/
|
|
917
|
+
var GIB_TO_BYTES = 1024 ** 3;
|
|
918
|
+
var DAY_TO_SECONDS = 86400;
|
|
919
|
+
/** A homelab array in GiB is below 1 MiB; the same array in bytes is not. */
|
|
920
|
+
var INFORMATION_LEGACY_MAX = 1024 ** 2;
|
|
921
|
+
/** Desiccant life in days is below this; the same life in seconds is not. */
|
|
922
|
+
var DESICCANT_LEGACY_MAX_DAYS = 1e4;
|
|
923
|
+
var DESICCANT_SERIES_KEY = "cap:pet-feeder.desiccantLeftDays";
|
|
924
|
+
var DESICCANT_SCALE_ID = "pet-feeder-desiccant-days-to-seconds";
|
|
925
|
+
var UNRAID_INFORMATION_KEYS = [
|
|
926
|
+
"array_total",
|
|
927
|
+
"array_used",
|
|
928
|
+
"array_free"
|
|
929
|
+
];
|
|
930
|
+
var NUMERIC_SENSOR_SERIES_KEY = "cap:numeric-sensor.value";
|
|
931
|
+
/** The stored number after one rescale, or the same number when it is already base. */
|
|
932
|
+
function scaledMagnitude(value, factor, legacyMax) {
|
|
933
|
+
if (!Number.isFinite(value) || value === 0) return value;
|
|
934
|
+
if (Math.abs(value) >= legacyMax) return value;
|
|
935
|
+
return value * factor;
|
|
936
|
+
}
|
|
937
|
+
function rollupIsLegacy(row, legacyMax) {
|
|
938
|
+
const samples = [
|
|
939
|
+
row.min,
|
|
940
|
+
row.max,
|
|
941
|
+
...row.last === null ? [] : [row.last]
|
|
942
|
+
];
|
|
943
|
+
if (samples.some((value) => !Number.isFinite(value))) return false;
|
|
944
|
+
if (samples.every((value) => value === 0)) return false;
|
|
945
|
+
return samples.every((value) => Math.abs(value) < legacyMax);
|
|
946
|
+
}
|
|
947
|
+
/** Unraid array capacity children. Other numeric sensors on the same key stay put. */
|
|
948
|
+
function unraidInformationScale(deviceId, entityKey) {
|
|
949
|
+
if (!UNRAID_INFORMATION_KEYS.includes(entityKey)) return null;
|
|
950
|
+
return {
|
|
951
|
+
seriesKey: NUMERIC_SENSOR_SERIES_KEY,
|
|
952
|
+
deviceId,
|
|
953
|
+
factor: GIB_TO_BYTES,
|
|
954
|
+
legacyMax: INFORMATION_LEGACY_MAX,
|
|
955
|
+
migrationId: `unraid-gib-to-bytes:${String(deviceId)}`
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
//#endregion
|
|
885
959
|
//#region src/builtins/device-history/store/history-schema.ts
|
|
886
960
|
var HISTORY_NAMESPACE = "device-history";
|
|
887
961
|
var COLLECTIONS = {
|
|
@@ -892,7 +966,9 @@ var COLLECTIONS = {
|
|
|
892
966
|
rollup1h: "rollup-1h",
|
|
893
967
|
rollup1d: "rollup-1d",
|
|
894
968
|
optOuts: "device-opt-outs",
|
|
895
|
-
departures: "device-departures"
|
|
969
|
+
departures: "device-departures",
|
|
970
|
+
/** One row per applied base-unit rescale, in history.db so it travels with the points. */
|
|
971
|
+
appliedScales: "applied-scales"
|
|
896
972
|
};
|
|
897
973
|
function rollupCollectionOf(tier) {
|
|
898
974
|
if (tier === "5m") return COLLECTIONS.rollup5m;
|
|
@@ -1145,6 +1221,21 @@ var HISTORY_DECLARATIONS = [
|
|
|
1145
1221
|
columns: ["device_id"],
|
|
1146
1222
|
unique: true
|
|
1147
1223
|
}]
|
|
1224
|
+
},
|
|
1225
|
+
{
|
|
1226
|
+
namespace: HISTORY_NAMESPACE,
|
|
1227
|
+
collection: COLLECTIONS.appliedScales,
|
|
1228
|
+
database: "history",
|
|
1229
|
+
columns: [{
|
|
1230
|
+
name: "id",
|
|
1231
|
+
type: "TEXT",
|
|
1232
|
+
primaryKey: true,
|
|
1233
|
+
notNull: true
|
|
1234
|
+
}, {
|
|
1235
|
+
name: "applied_at",
|
|
1236
|
+
type: "INTEGER",
|
|
1237
|
+
notNull: true
|
|
1238
|
+
}]
|
|
1148
1239
|
}
|
|
1149
1240
|
];
|
|
1150
1241
|
//#endregion
|
|
@@ -1561,7 +1652,98 @@ var HistoryStore = class {
|
|
|
1561
1652
|
filter: { where: { device_id: deviceId } }
|
|
1562
1653
|
});
|
|
1563
1654
|
}
|
|
1655
|
+
/** True when this rescale already finished. A missing row is "not yet". */
|
|
1656
|
+
async scaleApplied(id) {
|
|
1657
|
+
return (await this.door.query.query({
|
|
1658
|
+
namespace: HISTORY_NAMESPACE,
|
|
1659
|
+
collection: COLLECTIONS.appliedScales,
|
|
1660
|
+
filter: {
|
|
1661
|
+
where: { id },
|
|
1662
|
+
limit: 1
|
|
1663
|
+
}
|
|
1664
|
+
})).length > 0;
|
|
1665
|
+
}
|
|
1666
|
+
async markScale(id, at) {
|
|
1667
|
+
await this.door.upsertMany.mutate({
|
|
1668
|
+
namespace: HISTORY_NAMESPACE,
|
|
1669
|
+
collection: COLLECTIONS.appliedScales,
|
|
1670
|
+
conflict: ["id"],
|
|
1671
|
+
records: [{
|
|
1672
|
+
id,
|
|
1673
|
+
data: {
|
|
1674
|
+
id,
|
|
1675
|
+
applied_at: at
|
|
1676
|
+
}
|
|
1677
|
+
}]
|
|
1678
|
+
});
|
|
1679
|
+
}
|
|
1680
|
+
/**
|
|
1681
|
+
* Multiply one series' raw points and rollups that are still in the old
|
|
1682
|
+
* unit. Points already at or above `legacyMax` stay. Returns how many rows
|
|
1683
|
+
* changed.
|
|
1684
|
+
*/
|
|
1685
|
+
async scaleSeries(seriesId, factor, legacyMax) {
|
|
1686
|
+
const raw = await this.scaleRaw(seriesId, factor, legacyMax);
|
|
1687
|
+
let rollups = 0;
|
|
1688
|
+
for (const tier of [
|
|
1689
|
+
"5m",
|
|
1690
|
+
"1h",
|
|
1691
|
+
"1d"
|
|
1692
|
+
]) rollups += await this.scaleRollupTier(tier, seriesId, factor, legacyMax);
|
|
1693
|
+
return raw + rollups;
|
|
1694
|
+
}
|
|
1695
|
+
async scaleRaw(seriesId, factor, legacyMax) {
|
|
1696
|
+
let after = -1;
|
|
1697
|
+
let changed = 0;
|
|
1698
|
+
for (;;) {
|
|
1699
|
+
const rows = await this.readRaw(seriesId, after + 1, Number.MAX_SAFE_INTEGER, READ_PAGE, "asc");
|
|
1700
|
+
if (rows.length === 0) break;
|
|
1701
|
+
const next = rows.flatMap((row) => {
|
|
1702
|
+
const value = scaledMagnitude(row.value, factor, legacyMax);
|
|
1703
|
+
return value === row.value ? [] : [{
|
|
1704
|
+
seriesId,
|
|
1705
|
+
ts: row.ts,
|
|
1706
|
+
value
|
|
1707
|
+
}];
|
|
1708
|
+
});
|
|
1709
|
+
if (next.length > 0) {
|
|
1710
|
+
await this.upsertRaw(next);
|
|
1711
|
+
changed += next.length;
|
|
1712
|
+
}
|
|
1713
|
+
const last = rows[rows.length - 1];
|
|
1714
|
+
if (last === void 0 || rows.length < 5e3) break;
|
|
1715
|
+
after = last.ts;
|
|
1716
|
+
}
|
|
1717
|
+
return changed;
|
|
1718
|
+
}
|
|
1719
|
+
async scaleRollupTier(tier, seriesId, factor, legacyMax) {
|
|
1720
|
+
let after = -1;
|
|
1721
|
+
let changed = 0;
|
|
1722
|
+
for (;;) {
|
|
1723
|
+
const rows = await this.readRollups(tier, seriesId, after + 1, Number.MAX_SAFE_INTEGER, READ_PAGE, "asc");
|
|
1724
|
+
if (rows.length === 0) break;
|
|
1725
|
+
const next = rows.flatMap((row) => rollupIsLegacy(row, legacyMax) ? [scaleRollup(row, factor)] : []);
|
|
1726
|
+
if (next.length > 0) {
|
|
1727
|
+
await this.upsertRollups(tier, next);
|
|
1728
|
+
changed += next.length;
|
|
1729
|
+
}
|
|
1730
|
+
const last = rows[rows.length - 1];
|
|
1731
|
+
if (last === void 0 || rows.length < 5e3) break;
|
|
1732
|
+
after = last.bucketStart;
|
|
1733
|
+
}
|
|
1734
|
+
return changed;
|
|
1735
|
+
}
|
|
1564
1736
|
};
|
|
1737
|
+
function scaleRollup(row, factor) {
|
|
1738
|
+
return {
|
|
1739
|
+
...row,
|
|
1740
|
+
sum: row.sum * factor,
|
|
1741
|
+
min: row.min * factor,
|
|
1742
|
+
max: row.max * factor,
|
|
1743
|
+
last: row.last === null ? null : row.last * factor,
|
|
1744
|
+
twSum: row.twSum === null ? null : row.twSum * factor
|
|
1745
|
+
};
|
|
1746
|
+
}
|
|
1565
1747
|
//#endregion
|
|
1566
1748
|
//#region src/builtins/device-history/rollup/rollup-math.ts
|
|
1567
1749
|
/**
|
|
@@ -2131,7 +2313,8 @@ var HistoryRuntime = class {
|
|
|
2131
2313
|
retention: deps.retention,
|
|
2132
2314
|
catalog,
|
|
2133
2315
|
itemCatalog,
|
|
2134
|
-
readCapSlice: deps.readCapSlice
|
|
2316
|
+
readCapSlice: deps.readCapSlice,
|
|
2317
|
+
readDeviceQuantity: deps.readDeviceQuantity
|
|
2135
2318
|
});
|
|
2136
2319
|
this.departures = new require_retention.DepartureTracker(this.store, this.registry, logger);
|
|
2137
2320
|
this.registry.onRemove((series) => {
|
|
@@ -2167,10 +2350,53 @@ var HistoryRuntime = class {
|
|
|
2167
2350
|
await this.capture.seed();
|
|
2168
2351
|
}
|
|
2169
2352
|
async finishBoot() {
|
|
2353
|
+
await this.applyLegacyScales();
|
|
2170
2354
|
const series = await this.rollup.bootRecompute(this.deps.clock());
|
|
2171
2355
|
this.deps.logger.info("device-history: recent rollup window rebuilt", { meta: { series } });
|
|
2172
2356
|
await this.reconcile();
|
|
2173
2357
|
}
|
|
2358
|
+
/**
|
|
2359
|
+
* PetKit desiccant was stored in days; the quantity base is seconds.
|
|
2360
|
+
* Unraid array counters were stored in GiB; the base is bytes. Both
|
|
2361
|
+
* factors are honest because the unit never varied inside the series.
|
|
2362
|
+
* Weather and numeric-sensor are not rescaled: the unit at sample time
|
|
2363
|
+
* was not stored, so a factor would invent a number (D393).
|
|
2364
|
+
*/
|
|
2365
|
+
async applyLegacyScales() {
|
|
2366
|
+
await this.scaleMatching(DESICCANT_SERIES_KEY, void 0, DAY_TO_SECONDS, DESICCANT_LEGACY_MAX_DAYS, DESICCANT_SCALE_ID);
|
|
2367
|
+
const list = this.deps.listLegacyScales;
|
|
2368
|
+
if (list === void 0) return;
|
|
2369
|
+
let subjects;
|
|
2370
|
+
try {
|
|
2371
|
+
subjects = await list();
|
|
2372
|
+
} catch (err) {
|
|
2373
|
+
this.deps.logger.warn("device-history: legacy scale listing failed — stored points unchanged", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
2374
|
+
return;
|
|
2375
|
+
}
|
|
2376
|
+
for (const subject of subjects) await this.scaleMatching(subject.seriesKey, subject.deviceId, subject.factor, subject.legacyMax, subject.migrationId);
|
|
2377
|
+
}
|
|
2378
|
+
async scaleMatching(key, deviceId, factor, legacyMax, migrationId) {
|
|
2379
|
+
if (await this.store.scaleApplied(migrationId)) return;
|
|
2380
|
+
const subject = deviceId === void 0 ? void 0 : require_retention.subjectIdOf({
|
|
2381
|
+
kind: "device",
|
|
2382
|
+
deviceId
|
|
2383
|
+
});
|
|
2384
|
+
const series = this.registry.all().filter((row) => {
|
|
2385
|
+
if (row.key !== key) return false;
|
|
2386
|
+
return subject === void 0 || row.subject === subject;
|
|
2387
|
+
});
|
|
2388
|
+
let changed = 0;
|
|
2389
|
+
for (const row of series) changed += await this.store.scaleSeries(row.id, factor, legacyMax);
|
|
2390
|
+
await this.store.markScale(migrationId, this.deps.clock());
|
|
2391
|
+
if (changed > 0) this.deps.logger.info("device-history: rescaled a series into its base unit", {
|
|
2392
|
+
...deviceId === void 0 ? {} : { tags: { deviceId } },
|
|
2393
|
+
meta: {
|
|
2394
|
+
migrationId,
|
|
2395
|
+
key,
|
|
2396
|
+
changed
|
|
2397
|
+
}
|
|
2398
|
+
});
|
|
2399
|
+
}
|
|
2174
2400
|
startTimers() {
|
|
2175
2401
|
const every = (ms, run) => {
|
|
2176
2402
|
const timer = setInterval(() => {
|
|
@@ -2448,6 +2674,19 @@ var DeviceHistoryAddon = class extends require_dist.BaseAddon {
|
|
|
2448
2674
|
dayDays: positiveOr(c.dayDays, 0) > 0 ? c.dayDays : null
|
|
2449
2675
|
};
|
|
2450
2676
|
}
|
|
2677
|
+
/** Unraid array counters still stored in GiB. A failed listing throws to the caller. */
|
|
2678
|
+
async legacyScales() {
|
|
2679
|
+
const devices = await this.ctx.api.deviceManager.listAll.query({});
|
|
2680
|
+
const scales = [];
|
|
2681
|
+
for (const device of devices) {
|
|
2682
|
+
if (device.addonId !== "provider-unraid") continue;
|
|
2683
|
+
const entityKey = device.config["entityKey"];
|
|
2684
|
+
if (typeof entityKey !== "string") continue;
|
|
2685
|
+
const scale = unraidInformationScale(device.id, entityKey);
|
|
2686
|
+
if (scale !== null) scales.push(scale);
|
|
2687
|
+
}
|
|
2688
|
+
return scales;
|
|
2689
|
+
}
|
|
2451
2690
|
requireRuntime() {
|
|
2452
2691
|
if (this.runtime === null) throw new Error("device-history is starting — the history store is not open yet");
|
|
2453
2692
|
return this.runtime;
|
|
@@ -2541,6 +2780,11 @@ var DeviceHistoryAddon = class extends require_dist.BaseAddon {
|
|
|
2541
2780
|
deviceId,
|
|
2542
2781
|
capName
|
|
2543
2782
|
}),
|
|
2783
|
+
readDeviceQuantity: async (deviceId) => {
|
|
2784
|
+
const quantity = (await api.deviceManager.getDevice.query({ deviceId }))?.sourceInfo?.quantity;
|
|
2785
|
+
return require_dist.isReadingQuantity(quantity) ? quantity : null;
|
|
2786
|
+
},
|
|
2787
|
+
listLegacyScales: () => this.legacyScales(),
|
|
2544
2788
|
retention: () => this.retention(),
|
|
2545
2789
|
logger: this.ctx.logger,
|
|
2546
2790
|
clock: () => Date.now()
|