@camstack/addon-import-alexa 0.2.197 → 0.2.198
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/CHANGELOG.md +6 -0
- package/dist/addon.js +678 -691
- package/dist/addon.mjs +678 -691
- package/package.json +2 -2
package/dist/addon.mjs
CHANGED
|
@@ -5674,7 +5674,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
5674
5674
|
return EventCategory;
|
|
5675
5675
|
}({});
|
|
5676
5676
|
//#endregion
|
|
5677
|
-
//#region ../types/dist/device-type-
|
|
5677
|
+
//#region ../types/dist/device-type-DxCT0krO.mjs
|
|
5678
5678
|
/**
|
|
5679
5679
|
import { errMsg } from '@camstack/types'
|
|
5680
5680
|
* Extract a human-readable message from an unknown error value.
|
|
@@ -5836,6 +5836,13 @@ var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
|
5836
5836
|
* filters that want "all devices with on-motion behaviour".
|
|
5837
5837
|
*/
|
|
5838
5838
|
DeviceFeature["MotionTrigger"] = "motion-trigger";
|
|
5839
|
+
/**
|
|
5840
|
+
* Device can be run for a chosen time and then stopped. Mirrors the
|
|
5841
|
+
* `timed-run` wrapper cap — the cap is bound by the core-blocks addon, not by
|
|
5842
|
+
* a driver, so the flag is derived from the device's bindings
|
|
5843
|
+
* (`featuresOfBoundCaps`). Gates the quick-run control in the viewer.
|
|
5844
|
+
*/
|
|
5845
|
+
DeviceFeature["TimedRun"] = "timed-run";
|
|
5839
5846
|
/** Light supports rgb-triplet color via `color` cap. */
|
|
5840
5847
|
DeviceFeature["LightColorRgb"] = "light-color-rgb";
|
|
5841
5848
|
/** Light supports HSV color via `color` cap. */
|
|
@@ -6059,7 +6066,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
6059
6066
|
return DeviceRole;
|
|
6060
6067
|
}({});
|
|
6061
6068
|
//#endregion
|
|
6062
|
-
//#region ../types/dist/sleep-
|
|
6069
|
+
//#region ../types/dist/sleep-7El4r5Bl.mjs
|
|
6063
6070
|
/**
|
|
6064
6071
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6065
6072
|
* window to float samples (D455).
|
|
@@ -8444,7 +8451,7 @@ function boundOf(list) {
|
|
|
8444
8451
|
* Base class for CamStack addons. Eliminates settings boilerplate:
|
|
8445
8452
|
*
|
|
8446
8453
|
* - Typed `config` property with automatic resolution from store + defaults
|
|
8447
|
-
* -
|
|
8454
|
+
* - the scoped settings API (`clusterSettings` / `nodeSettings` / `deviceDefaults`) auto-implemented
|
|
8448
8455
|
* - `getAddonSettings()` / `updateAddonSettings()` auto-implemented
|
|
8449
8456
|
* - `getDeviceSettings()` / `updateDeviceSettings()` auto-implemented
|
|
8450
8457
|
* - `ctx` accessor for the AddonContext (no manual `this.ctxRef` storage)
|
|
@@ -8454,7 +8461,7 @@ function boundOf(list) {
|
|
|
8454
8461
|
* Subclasses override:
|
|
8455
8462
|
* - `onInitialize()` — addon-specific init logic, return ProviderRegistration[]
|
|
8456
8463
|
* - `onShutdown()` — cleanup
|
|
8457
|
-
* - `
|
|
8464
|
+
* - `clusterSettingsSchema()` / `nodeSettingsSchema()` / `deviceSettingsSchema()` — UI schemas
|
|
8458
8465
|
*
|
|
8459
8466
|
* @example
|
|
8460
8467
|
* ```ts
|
|
@@ -8468,7 +8475,7 @@ function boundOf(list) {
|
|
|
8468
8475
|
* super({ maxRetries: 3, endpoint: 'http://localhost' })
|
|
8469
8476
|
* }
|
|
8470
8477
|
*
|
|
8471
|
-
* protected
|
|
8478
|
+
* protected clusterSettingsSchema() {
|
|
8472
8479
|
* return this.schema({
|
|
8473
8480
|
* sections: [{
|
|
8474
8481
|
* id: 'main', title: 'Settings',
|
|
@@ -8511,7 +8518,7 @@ var BaseAddon = class {
|
|
|
8511
8518
|
defaults;
|
|
8512
8519
|
/**
|
|
8513
8520
|
* Hidden-state paths that hold secrets (D787) — values the addon writes
|
|
8514
|
-
* itself (`
|
|
8521
|
+
* itself (`state()`, the scoped writers) that no form field declares.
|
|
8515
8522
|
* Stored in the keychain exactly like a `password` field. Syntax:
|
|
8516
8523
|
* `'snapshotSigningKey'`, `'identity.pincode'`, `'tokens[userId].accessToken'`
|
|
8517
8524
|
* (`key[<id field>]` addresses array items by id, never by index).
|
|
@@ -8521,7 +8528,7 @@ var BaseAddon = class {
|
|
|
8521
8528
|
/**
|
|
8522
8529
|
* D986 M4: the scoped schemas this addon declared, resolved once per capability
|
|
8523
8530
|
* (`loadScopedSchemas`) so the sync readers (`perNodeKeys`, the secret tree, the restart check)
|
|
8524
|
-
* see them. Empty until loaded
|
|
8531
|
+
* see them. Empty until loaded.
|
|
8525
8532
|
*/
|
|
8526
8533
|
_scopedByCap = /* @__PURE__ */ new Map();
|
|
8527
8534
|
_nodeKeysByCap = /* @__PURE__ */ new Map();
|
|
@@ -8707,7 +8714,7 @@ var BaseAddon = class {
|
|
|
8707
8714
|
/** Addon-specific cleanup. Override if needed. */
|
|
8708
8715
|
async onShutdown() {}
|
|
8709
8716
|
/**
|
|
8710
|
-
* Called after config is resolved during
|
|
8717
|
+
* Called after config is resolved during a settings write.
|
|
8711
8718
|
* Override to react to config changes (e.g. restart a sampler, reconnect a service).
|
|
8712
8719
|
* Not called during initialize() — use onInitialize() for initial setup.
|
|
8713
8720
|
*/
|
|
@@ -8736,82 +8743,12 @@ var BaseAddon = class {
|
|
|
8736
8743
|
scopedSettingsCapabilities() {
|
|
8737
8744
|
return [];
|
|
8738
8745
|
}
|
|
8739
|
-
/** Override to provide global-level settings UI schema. */
|
|
8740
|
-
globalSettingsSchema(_cap) {
|
|
8741
|
-
return null;
|
|
8742
|
-
}
|
|
8743
8746
|
/** Override to provide device-level settings UI schema. */
|
|
8744
8747
|
deviceSettingsSchema() {
|
|
8745
8748
|
return null;
|
|
8746
8749
|
}
|
|
8747
8750
|
/**
|
|
8748
|
-
*
|
|
8749
|
-
* ARE the configuration of its integration.
|
|
8750
|
-
*
|
|
8751
|
-
* Return the `ConfigSection.id`s, from {@link globalSettingsSchema}, that an
|
|
8752
|
-
* operator should find on the addon's integration page (System →
|
|
8753
|
-
* Integrations → <name>) rather than only in the cluster-wide list of every
|
|
8754
|
-
* addon. Empty (the default) means the addon has no integration-level
|
|
8755
|
-
* settings and no such surface is offered — this is opt-in, because whether
|
|
8756
|
-
* an addon's configuration IS its integration's configuration depends on the
|
|
8757
|
-
* nature of the integration.
|
|
8758
|
-
*
|
|
8759
|
-
* WHAT THIS IS NOT. It is not a scope. The selected sections keep living in
|
|
8760
|
-
* the ONE global schema, in the ONE addon store, written by the ONE
|
|
8761
|
-
* `updateGlobalSettings` path. There is deliberately no
|
|
8762
|
-
* `updateIntegrationSettings`: a second write path is how a surface acquires
|
|
8763
|
-
* a second store key, and this repo has shipped that twice (`btmPath@hub`,
|
|
8764
|
-
* D266). Selecting sections cannot introduce a key that selecting cannot.
|
|
8765
|
-
*
|
|
8766
|
-
* WHY IT IS A LIST OF SECTION IDS AND NOT A MARKER ON THE SECTION.
|
|
8767
|
-
* `ConfigFieldBase` used to carry `scope?: 'device' | 'global'` and it was
|
|
8768
|
-
* removed with the reason recorded at
|
|
8769
|
-
* `packages/types/src/interfaces/config-ui.ts:249` — *"a field's scope is
|
|
8770
|
-
* determined by WHICH schema it lives in, not by a field-level marker."* A
|
|
8771
|
-
* marker sprinkled across sections also has to borrow a field that already
|
|
8772
|
-
* means something else; borrowing `section.tab` put the literal word
|
|
8773
|
-
* "integration" into an operator-facing tab bar, because `tab` means "how to
|
|
8774
|
-
* GROUP this visually" and cannot also mean "where this lives" (D269
|
|
8775
|
-
* supersedes D268). One declaration, in one place, next to the schema whose
|
|
8776
|
-
* ids it names.
|
|
8777
|
-
*/
|
|
8778
|
-
integrationSettingSections() {
|
|
8779
|
-
return [];
|
|
8780
|
-
}
|
|
8781
|
-
async getGlobalSettings(overlay, cap, nodeId) {
|
|
8782
|
-
await this.loadScopedSchemas(cap);
|
|
8783
|
-
const schema = this.globalSettingsSchema(cap) ?? this.scopedFormSchema(cap);
|
|
8784
|
-
if (!schema) return { sections: [] };
|
|
8785
|
-
const projected = await this.readRawProjectedStore(nodeId, cap);
|
|
8786
|
-
return hydrateSchema(schema, overlay ? await this.overlayKeepingMarkers(projected, overlay) : projected, { inlineSecretsAsViews: true });
|
|
8787
|
-
}
|
|
8788
|
-
/**
|
|
8789
|
-
* The integration-level view of this addon's settings: exactly the sections
|
|
8790
|
-
* named by {@link integrationSettingSections}, hydrated from the SAME store
|
|
8791
|
-
* `getGlobalSettings` reads, and narrowed to cluster-scoped fields.
|
|
8792
|
-
*
|
|
8793
|
-
* Returns `null` when the addon declared nothing — an addon that opts out has
|
|
8794
|
-
* no integration settings surface at all, rather than an empty one that reads
|
|
8795
|
-
* as a failed load.
|
|
8796
|
-
*
|
|
8797
|
-
* Three properties hold BY CONSTRUCTION, which is why they are here in core
|
|
8798
|
-
* and not in whichever UI happens to render this:
|
|
8799
|
-
*
|
|
8800
|
-
* 1. **One key.** The payload is a SUBSET of the global schema, so a field
|
|
8801
|
-
* shown here is the same field, with the same bare key, that the addon's
|
|
8802
|
-
* own page shows. There is no integration-specific writer — callers save
|
|
8803
|
-
* through `updateGlobalSettings` — so a second store key is unreachable,
|
|
8804
|
-
* not merely discouraged.
|
|
8805
|
-
* 2. **No node scope.** `perNode: true` fields are DROPPED. Their store key
|
|
8806
|
-
* is `<key>@<nodeId>` and an integration is not a node; whichever node
|
|
8807
|
-
* such a field silently picked would be a wrong answer for the operator
|
|
8808
|
-
* who opened the page (D266).
|
|
8809
|
-
* 3. **No silent typo.** A declared id that names no section throws. The
|
|
8810
|
-
* alternative — skip it — turns a rename into a surface that quietly
|
|
8811
|
-
* empties, which looks exactly like an addon with nothing to configure.
|
|
8812
|
-
*/
|
|
8813
|
-
/**
|
|
8814
|
-
* The form schema of ONE integration instance, or `null` to use {@link globalSettingsSchema}.
|
|
8751
|
+
* The form schema of ONE integration instance, or `null` to use the scoped form.
|
|
8815
8752
|
*
|
|
8816
8753
|
* Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
|
|
8817
8754
|
* needs its connection fields, the default integration the addon's own sections. It is the
|
|
@@ -8984,6 +8921,19 @@ var BaseAddon = class {
|
|
|
8984
8921
|
const overlay = await this.scopedSettingsOverlay(scope, cap, nodeId);
|
|
8985
8922
|
return hydrateSchema(schema, overlay ? await this.overlayKeepingMarkers(stored, overlay) : stored, { inlineSecretsAsViews: true });
|
|
8986
8923
|
}
|
|
8924
|
+
/**
|
|
8925
|
+
* The scoped schemas this addon serves: one entry per loaded (capability, scope), capabilities
|
|
8926
|
+
* in declaration order, scopes in {@link SCOPED_SETTINGS_SCOPES} order. `[]` when it declares
|
|
8927
|
+
* nothing.
|
|
8928
|
+
*/
|
|
8929
|
+
async listScopedSettings() {
|
|
8930
|
+
await this.loadScopedSchemas();
|
|
8931
|
+
return [...this._scopedByCap].flatMap(([cap, entries]) => entries.map((entry) => ({
|
|
8932
|
+
cap,
|
|
8933
|
+
scope: entry.scope,
|
|
8934
|
+
sectionIds: entry.schema.sections.map((section) => section.id)
|
|
8935
|
+
})));
|
|
8936
|
+
}
|
|
8987
8937
|
/** The OPERATOR's write of declared keys of one scope (D787 secret semantics). */
|
|
8988
8938
|
async updateScopedSettings(scope, cap, patch, nodeId) {
|
|
8989
8939
|
this._operatorWriteDepth++;
|
|
@@ -9009,32 +8959,15 @@ var BaseAddon = class {
|
|
|
9009
8959
|
*/
|
|
9010
8960
|
async getIntegrationFormSchema(instance, nodeId) {
|
|
9011
8961
|
const scoped = await this.integrationFormSchema(instance);
|
|
9012
|
-
if (scoped === null) return this.
|
|
8962
|
+
if (scoped === null) return this.scopedForm(nodeId);
|
|
9013
8963
|
return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
|
|
9014
8964
|
}
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
const schema = this.
|
|
9019
|
-
if (!schema)
|
|
9020
|
-
|
|
9021
|
-
const sections = [];
|
|
9022
|
-
for (const id of declared) {
|
|
9023
|
-
const section = byId.get(id);
|
|
9024
|
-
if (!section) throw new Error(`${this.constructor.name}: integrationSettingSections() names unknown section "${id}". Known sections: [${[...byId.keys()].join(", ")}].`);
|
|
9025
|
-
const fields = dropPerNodeFields(section.fields);
|
|
9026
|
-
if (fields.length === 0) continue;
|
|
9027
|
-
sections.push({
|
|
9028
|
-
...section,
|
|
9029
|
-
fields
|
|
9030
|
-
});
|
|
9031
|
-
}
|
|
9032
|
-
if (sections.length === 0) return null;
|
|
9033
|
-
const projected = await this.readRawProjectedStore(nodeId);
|
|
9034
|
-
return hydrateSchema({
|
|
9035
|
-
...schema,
|
|
9036
|
-
sections
|
|
9037
|
-
}, projected, { inlineSecretsAsViews: true });
|
|
8965
|
+
/** The form of the scoped schemas this addon declared, hydrated from its store. */
|
|
8966
|
+
async scopedForm(nodeId) {
|
|
8967
|
+
await this.loadScopedSchemas();
|
|
8968
|
+
const schema = this.scopedFormSchema();
|
|
8969
|
+
if (!schema) return { sections: [] };
|
|
8970
|
+
return hydrateSchema(schema, await this.readRawProjectedStore(nodeId), { inlineSecretsAsViews: true });
|
|
9038
8971
|
}
|
|
9039
8972
|
/**
|
|
9040
8973
|
* The raw addon store PROJECTED onto the target node's bare per-node keys:
|
|
@@ -9043,8 +8976,8 @@ var BaseAddon = class {
|
|
|
9043
8976
|
* bare fallback), all `@`-scoped and stray bare per-node keys are dropped.
|
|
9044
8977
|
* A no-op passthrough when the schema declares no `perNode` field.
|
|
9045
8978
|
*
|
|
9046
|
-
* This is the sanctioned way for
|
|
9047
|
-
* the store for custom
|
|
8979
|
+
* This is the sanctioned way for an addon that needs
|
|
8980
|
+
* the store for custom logic (option narrowing, value snapping) to
|
|
9048
8981
|
* read it per-node — never `ctx.settings.readAddonStore()` directly.
|
|
9049
8982
|
* `nodeId` omitted ⇒ the local node (node-blind injection from ctx).
|
|
9050
8983
|
*
|
|
@@ -9096,7 +9029,7 @@ var BaseAddon = class {
|
|
|
9096
9029
|
}
|
|
9097
9030
|
/**
|
|
9098
9031
|
* Whether ONE global key of this addon's store was written, read three-way
|
|
9099
|
-
* (D651). For a question a hydrated view cannot answer:
|
|
9032
|
+
* (D651). For a question a hydrated view cannot answer: a hydrated form
|
|
9100
9033
|
* reports `value ?? default`, so "the operator chose the default" and "nobody
|
|
9101
9034
|
* chose" look the same, and a failed read looks like both. A `perNode` key is
|
|
9102
9035
|
* not supported here: its stored name is scoped.
|
|
@@ -9130,7 +9063,7 @@ var BaseAddon = class {
|
|
|
9130
9063
|
}
|
|
9131
9064
|
/**
|
|
9132
9065
|
* The OPERATOR's write — a settings form or an admin API call, dispatched by
|
|
9133
|
-
* the kernel.
|
|
9066
|
+
* the kernel. The one in-process write of the addon blob that is not a scoped write; a secret
|
|
9134
9067
|
* the operator sends is stored as sent even when it equals a pre-keychain
|
|
9135
9068
|
* inline value: the operator re-entering a password is a change, an addon
|
|
9136
9069
|
* writing back what it read is not (D787).
|
|
@@ -9143,9 +9076,6 @@ var BaseAddon = class {
|
|
|
9143
9076
|
this._operatorWriteDepth--;
|
|
9144
9077
|
}
|
|
9145
9078
|
}
|
|
9146
|
-
async updateGlobalSettings(patch, nodeId) {
|
|
9147
|
-
await this.applyGlobalPatch(patch, nodeId);
|
|
9148
|
-
}
|
|
9149
9079
|
/**
|
|
9150
9080
|
* REMOVE stored secrets — their keychain values and their markers (D787).
|
|
9151
9081
|
*
|
|
@@ -9188,8 +9118,7 @@ var BaseAddon = class {
|
|
|
9188
9118
|
await this.resolveConfig();
|
|
9189
9119
|
await this.onConfigChanged();
|
|
9190
9120
|
this.emitLifecycle(EventCategory.AddonUpdated, { level: "global" });
|
|
9191
|
-
|
|
9192
|
-
this.maybeAutoRestart(Object.keys(barePatch), [...legacy === null ? [] : [legacy], ...this.loadedScopedSchemas().map((entry) => entry.schema)]);
|
|
9121
|
+
this.maybeAutoRestart(Object.keys(barePatch), this.loadedScopedSchemas().map((entry) => entry.schema));
|
|
9193
9122
|
return true;
|
|
9194
9123
|
}
|
|
9195
9124
|
/**
|
|
@@ -9227,10 +9156,7 @@ var BaseAddon = class {
|
|
|
9227
9156
|
this._nodeKeysByCap = /* @__PURE__ */ new Map();
|
|
9228
9157
|
this._addonSecretTree = null;
|
|
9229
9158
|
}
|
|
9230
|
-
/**
|
|
9231
|
-
* The form the settings API serves while an addon declares no {@link globalSettingsSchema}: the
|
|
9232
|
-
* sections of its scoped schemas, so dropping the old hook does not blank the form.
|
|
9233
|
-
*/
|
|
9159
|
+
/** The form of an addon's scoped schemas: their sections, each shown once. */
|
|
9234
9160
|
scopedFormSchema(cap) {
|
|
9235
9161
|
const byId = /* @__PURE__ */ new Map();
|
|
9236
9162
|
for (const entry of this.loadedScopedSchemas(cap)) for (const section of entry.schema.sections) if (!byId.has(section.id)) byId.set(section.id, section);
|
|
@@ -9242,8 +9168,7 @@ var BaseAddon = class {
|
|
|
9242
9168
|
return [...this._scopedByCap.values()].flat();
|
|
9243
9169
|
}
|
|
9244
9170
|
/**
|
|
9245
|
-
* The field keys that are stored per node: every field of a {@link nodeSettingsSchema}
|
|
9246
|
-
* the fields the legacy {@link globalSettingsSchema} still marks `perNode: true`. Derived once
|
|
9171
|
+
* The field keys that are stored per node: every field of a {@link nodeSettingsSchema}. Derived once
|
|
9247
9172
|
* per `cap` argument and memoized (schemas are static declarations). Empty set ⇒ every
|
|
9248
9173
|
* per-node code path is bypassed and the settings API behaves like the node-agnostic one.
|
|
9249
9174
|
* Call {@link loadScopedSchemas} first (the async seams do).
|
|
@@ -9252,8 +9177,7 @@ var BaseAddon = class {
|
|
|
9252
9177
|
const cacheKey = cap ?? "";
|
|
9253
9178
|
const cached = this._nodeKeysByCap.get(cacheKey);
|
|
9254
9179
|
if (cached) return cached;
|
|
9255
|
-
const
|
|
9256
|
-
const keys = new Set(legacy ? legacy.sections.flatMap((section) => collectPerNodeFieldKeys(section.fields)) : []);
|
|
9180
|
+
const keys = /* @__PURE__ */ new Set();
|
|
9257
9181
|
for (const { scope, schema } of this.loadedScopedSchemas(cap)) {
|
|
9258
9182
|
if (scope !== "node") continue;
|
|
9259
9183
|
for (const section of schema.sections) for (const key of collectValueFieldKeys(section.fields)) keys.add(key);
|
|
@@ -9471,8 +9395,6 @@ var BaseAddon = class {
|
|
|
9471
9395
|
}
|
|
9472
9396
|
declaredKeySet() {
|
|
9473
9397
|
const keys = new Set(Object.keys(this.defaults));
|
|
9474
|
-
const schema = this.globalSettingsSchema();
|
|
9475
|
-
if (schema) for (const section of schema.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
|
|
9476
9398
|
for (const { schema: scoped } of this.loadedScopedSchemas()) for (const section of scoped.sections) for (const key of collectFieldKeys(section.fields)) keys.add(key);
|
|
9477
9399
|
for (const key of this._declaredStateKeys) keys.add(key);
|
|
9478
9400
|
for (const path of this.secretStatePaths) {
|
|
@@ -9570,7 +9492,7 @@ var BaseAddon = class {
|
|
|
9570
9492
|
/** The addon store's secret tree: schema fields by TYPE, plus `secretStatePaths`. */
|
|
9571
9493
|
addonSecretTree() {
|
|
9572
9494
|
if (this._addonSecretTree === null) {
|
|
9573
|
-
const tree = new Map(
|
|
9495
|
+
const tree = /* @__PURE__ */ new Map();
|
|
9574
9496
|
for (const { schema } of this.loadedScopedSchemas()) for (const [key, node] of secretTreeFromSchema(schema)) tree.set(key, node);
|
|
9575
9497
|
this._addonSecretTree = mergeSecretStatePaths(tree, this.secretStatePaths);
|
|
9576
9498
|
}
|
|
@@ -9782,47 +9704,6 @@ function classifyStoreError(err) {
|
|
|
9782
9704
|
if (TRANSPORT_PHRASES.some((f) => message.includes(f))) return "transport";
|
|
9783
9705
|
return "permanent";
|
|
9784
9706
|
}
|
|
9785
|
-
/**
|
|
9786
|
-
* Collect the keys of every field marked `perNode: true`, recursing into
|
|
9787
|
-
* layout containers (`group` fields and `sub-tabs` tabs) the same way
|
|
9788
|
-
* `hydrateSchema` does. Valueless structural fields (separator/info/…)
|
|
9789
|
-
* don't declare `perNode` and are excluded by the `in` narrowing.
|
|
9790
|
-
*/
|
|
9791
|
-
/**
|
|
9792
|
-
* The same fields with every `perNode: true` one removed, recursing into layout
|
|
9793
|
-
* containers exactly as {@link collectPerNodeFieldKeys} does. A container left
|
|
9794
|
-
* with no child is dropped rather than rendered empty.
|
|
9795
|
-
*
|
|
9796
|
-
* Used by `getIntegrationSettings`: an integration is not a node, so a field
|
|
9797
|
-
* whose store key is `<key>@<nodeId>` has no node to belong to there.
|
|
9798
|
-
*/
|
|
9799
|
-
function dropPerNodeFields(fields) {
|
|
9800
|
-
const kept = [];
|
|
9801
|
-
for (const field of fields) {
|
|
9802
|
-
if (field.type === "group") {
|
|
9803
|
-
const inner = dropPerNodeFields(field.fields);
|
|
9804
|
-
if (inner.length > 0) kept.push({
|
|
9805
|
-
...field,
|
|
9806
|
-
fields: inner
|
|
9807
|
-
});
|
|
9808
|
-
continue;
|
|
9809
|
-
}
|
|
9810
|
-
if (field.type === "sub-tabs") {
|
|
9811
|
-
const tabs = field.tabs.map((tab) => ({
|
|
9812
|
-
...tab,
|
|
9813
|
-
fields: dropPerNodeFields(tab.fields)
|
|
9814
|
-
})).filter((tab) => tab.fields.length > 0);
|
|
9815
|
-
if (tabs.length > 0) kept.push({
|
|
9816
|
-
...field,
|
|
9817
|
-
tabs
|
|
9818
|
-
});
|
|
9819
|
-
continue;
|
|
9820
|
-
}
|
|
9821
|
-
if ("perNode" in field && field.perNode === true) continue;
|
|
9822
|
-
kept.push(field);
|
|
9823
|
-
}
|
|
9824
|
-
return kept;
|
|
9825
|
-
}
|
|
9826
9707
|
/** The keys of the value-holding fields, recursing into layout containers. */
|
|
9827
9708
|
function collectValueFieldKeys(fields) {
|
|
9828
9709
|
const collected = [];
|
|
@@ -9855,21 +9736,6 @@ function collectFieldKeys(fields) {
|
|
|
9855
9736
|
}
|
|
9856
9737
|
return collected;
|
|
9857
9738
|
}
|
|
9858
|
-
function collectPerNodeFieldKeys(fields) {
|
|
9859
|
-
const collected = [];
|
|
9860
|
-
for (const field of fields) {
|
|
9861
|
-
if (field.type === "group") {
|
|
9862
|
-
collected.push(...collectPerNodeFieldKeys(field.fields));
|
|
9863
|
-
continue;
|
|
9864
|
-
}
|
|
9865
|
-
if (field.type === "sub-tabs") {
|
|
9866
|
-
for (const tab of field.tabs) collected.push(...collectPerNodeFieldKeys(tab.fields));
|
|
9867
|
-
continue;
|
|
9868
|
-
}
|
|
9869
|
-
if ("perNode" in field && field.perNode === true) collected.push(field.key);
|
|
9870
|
-
}
|
|
9871
|
-
return collected;
|
|
9872
|
-
}
|
|
9873
9739
|
/**
|
|
9874
9740
|
* Normalize an `ICamstackAddon.initialize()` return value into the
|
|
9875
9741
|
* `AddonInitResult` envelope. Arrays are wrapped into `{ providers }`;
|
|
@@ -12630,13 +12496,25 @@ Object.freeze({
|
|
|
12630
12496
|
"path": "temperature",
|
|
12631
12497
|
"valueType": "number"
|
|
12632
12498
|
}],
|
|
12633
|
-
"timed-run": [
|
|
12634
|
-
|
|
12635
|
-
|
|
12636
|
-
|
|
12637
|
-
|
|
12638
|
-
|
|
12639
|
-
|
|
12499
|
+
"timed-run": [
|
|
12500
|
+
{
|
|
12501
|
+
"path": "activeUntil",
|
|
12502
|
+
"valueType": "number"
|
|
12503
|
+
},
|
|
12504
|
+
{
|
|
12505
|
+
"path": "requestedBy",
|
|
12506
|
+
"valueType": "string"
|
|
12507
|
+
},
|
|
12508
|
+
{
|
|
12509
|
+
"path": "quickRun.duration",
|
|
12510
|
+
"valueType": "number"
|
|
12511
|
+
},
|
|
12512
|
+
{
|
|
12513
|
+
"path": "quickRun.unit",
|
|
12514
|
+
"valueType": "enum",
|
|
12515
|
+
"enumValues": ["s", "min"]
|
|
12516
|
+
}
|
|
12517
|
+
],
|
|
12640
12518
|
"update": [
|
|
12641
12519
|
{
|
|
12642
12520
|
"path": "currentVersion",
|
|
@@ -12860,7 +12738,7 @@ object({
|
|
|
12860
12738
|
params: record(string(), union([string(), number$1()])).optional()
|
|
12861
12739
|
});
|
|
12862
12740
|
//#endregion
|
|
12863
|
-
//#region ../types/dist/composition-
|
|
12741
|
+
//#region ../types/dist/composition-Bx0JvKUU.mjs
|
|
12864
12742
|
/**
|
|
12865
12743
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
12866
12744
|
*
|
|
@@ -14022,6 +13900,387 @@ var NodeColorIdSchema = _enum([
|
|
|
14022
13900
|
"node-h"
|
|
14023
13901
|
]);
|
|
14024
13902
|
//#endregion
|
|
13903
|
+
//#region ../types/dist/convert-BAzH15HU.mjs
|
|
13904
|
+
/**
|
|
13905
|
+
* Frozen unit → spec table. `•` in the doc marks each dimension's canonical
|
|
13906
|
+
* unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
|
|
13907
|
+
* `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
|
|
13908
|
+
* decimals). K derives from `°C = K − 273.15`.
|
|
13909
|
+
*/
|
|
13910
|
+
var UNIT_TABLE = {
|
|
13911
|
+
"°C": {
|
|
13912
|
+
dimension: "temperature",
|
|
13913
|
+
factor: 1,
|
|
13914
|
+
offset: 0
|
|
13915
|
+
},
|
|
13916
|
+
"°F": {
|
|
13917
|
+
dimension: "temperature",
|
|
13918
|
+
factor: 5 / 9,
|
|
13919
|
+
offset: -160 / 9
|
|
13920
|
+
},
|
|
13921
|
+
K: {
|
|
13922
|
+
dimension: "temperature",
|
|
13923
|
+
factor: 1,
|
|
13924
|
+
offset: -273.15
|
|
13925
|
+
},
|
|
13926
|
+
hPa: {
|
|
13927
|
+
dimension: "pressure",
|
|
13928
|
+
factor: 1,
|
|
13929
|
+
offset: 0
|
|
13930
|
+
},
|
|
13931
|
+
kPa: {
|
|
13932
|
+
dimension: "pressure",
|
|
13933
|
+
factor: 10,
|
|
13934
|
+
offset: 0
|
|
13935
|
+
},
|
|
13936
|
+
Pa: {
|
|
13937
|
+
dimension: "pressure",
|
|
13938
|
+
factor: .01,
|
|
13939
|
+
offset: 0
|
|
13940
|
+
},
|
|
13941
|
+
mbar: {
|
|
13942
|
+
dimension: "pressure",
|
|
13943
|
+
factor: 1,
|
|
13944
|
+
offset: 0
|
|
13945
|
+
},
|
|
13946
|
+
bar: {
|
|
13947
|
+
dimension: "pressure",
|
|
13948
|
+
factor: 1e3,
|
|
13949
|
+
offset: 0
|
|
13950
|
+
},
|
|
13951
|
+
inHg: {
|
|
13952
|
+
dimension: "pressure",
|
|
13953
|
+
factor: 33.8639,
|
|
13954
|
+
offset: 0
|
|
13955
|
+
},
|
|
13956
|
+
mmHg: {
|
|
13957
|
+
dimension: "pressure",
|
|
13958
|
+
factor: 1.33322,
|
|
13959
|
+
offset: 0
|
|
13960
|
+
},
|
|
13961
|
+
psi: {
|
|
13962
|
+
dimension: "pressure",
|
|
13963
|
+
factor: 68.9476,
|
|
13964
|
+
offset: 0
|
|
13965
|
+
},
|
|
13966
|
+
"m/s": {
|
|
13967
|
+
dimension: "speed",
|
|
13968
|
+
factor: 1,
|
|
13969
|
+
offset: 0
|
|
13970
|
+
},
|
|
13971
|
+
"km/h": {
|
|
13972
|
+
dimension: "speed",
|
|
13973
|
+
factor: 1 / 3.6,
|
|
13974
|
+
offset: 0
|
|
13975
|
+
},
|
|
13976
|
+
mph: {
|
|
13977
|
+
dimension: "speed",
|
|
13978
|
+
factor: .44704,
|
|
13979
|
+
offset: 0
|
|
13980
|
+
},
|
|
13981
|
+
kn: {
|
|
13982
|
+
dimension: "speed",
|
|
13983
|
+
factor: .514444,
|
|
13984
|
+
offset: 0
|
|
13985
|
+
},
|
|
13986
|
+
"mm/h": {
|
|
13987
|
+
dimension: "precipitation-rate",
|
|
13988
|
+
factor: 1,
|
|
13989
|
+
offset: 0
|
|
13990
|
+
},
|
|
13991
|
+
"in/h": {
|
|
13992
|
+
dimension: "precipitation-rate",
|
|
13993
|
+
factor: 25.4,
|
|
13994
|
+
offset: 0
|
|
13995
|
+
},
|
|
13996
|
+
m: {
|
|
13997
|
+
dimension: "length",
|
|
13998
|
+
factor: 1,
|
|
13999
|
+
offset: 0
|
|
14000
|
+
},
|
|
14001
|
+
mm: {
|
|
14002
|
+
dimension: "length",
|
|
14003
|
+
factor: .001,
|
|
14004
|
+
offset: 0
|
|
14005
|
+
},
|
|
14006
|
+
cm: {
|
|
14007
|
+
dimension: "length",
|
|
14008
|
+
factor: .01,
|
|
14009
|
+
offset: 0
|
|
14010
|
+
},
|
|
14011
|
+
km: {
|
|
14012
|
+
dimension: "length",
|
|
14013
|
+
factor: 1e3,
|
|
14014
|
+
offset: 0
|
|
14015
|
+
},
|
|
14016
|
+
in: {
|
|
14017
|
+
dimension: "length",
|
|
14018
|
+
factor: .0254,
|
|
14019
|
+
offset: 0
|
|
14020
|
+
},
|
|
14021
|
+
ft: {
|
|
14022
|
+
dimension: "length",
|
|
14023
|
+
factor: .3048,
|
|
14024
|
+
offset: 0
|
|
14025
|
+
},
|
|
14026
|
+
mi: {
|
|
14027
|
+
dimension: "length",
|
|
14028
|
+
factor: 1609.344,
|
|
14029
|
+
offset: 0
|
|
14030
|
+
},
|
|
14031
|
+
"m²": {
|
|
14032
|
+
dimension: "area",
|
|
14033
|
+
factor: 1,
|
|
14034
|
+
offset: 0
|
|
14035
|
+
},
|
|
14036
|
+
lx: {
|
|
14037
|
+
dimension: "illuminance",
|
|
14038
|
+
factor: 1,
|
|
14039
|
+
offset: 0
|
|
14040
|
+
},
|
|
14041
|
+
"W/m²": {
|
|
14042
|
+
dimension: "irradiance",
|
|
14043
|
+
factor: 1,
|
|
14044
|
+
offset: 0
|
|
14045
|
+
},
|
|
14046
|
+
W: {
|
|
14047
|
+
dimension: "power",
|
|
14048
|
+
factor: 1,
|
|
14049
|
+
offset: 0
|
|
14050
|
+
},
|
|
14051
|
+
kW: {
|
|
14052
|
+
dimension: "power",
|
|
14053
|
+
factor: 1e3,
|
|
14054
|
+
offset: 0
|
|
14055
|
+
},
|
|
14056
|
+
VA: {
|
|
14057
|
+
dimension: "apparent-power",
|
|
14058
|
+
factor: 1,
|
|
14059
|
+
offset: 0
|
|
14060
|
+
},
|
|
14061
|
+
Wh: {
|
|
14062
|
+
dimension: "energy",
|
|
14063
|
+
factor: 1,
|
|
14064
|
+
offset: 0
|
|
14065
|
+
},
|
|
14066
|
+
kWh: {
|
|
14067
|
+
dimension: "energy",
|
|
14068
|
+
factor: 1e3,
|
|
14069
|
+
offset: 0
|
|
14070
|
+
},
|
|
14071
|
+
MWh: {
|
|
14072
|
+
dimension: "energy",
|
|
14073
|
+
factor: 1e6,
|
|
14074
|
+
offset: 0
|
|
14075
|
+
},
|
|
14076
|
+
V: {
|
|
14077
|
+
dimension: "voltage",
|
|
14078
|
+
factor: 1,
|
|
14079
|
+
offset: 0
|
|
14080
|
+
},
|
|
14081
|
+
mV: {
|
|
14082
|
+
dimension: "voltage",
|
|
14083
|
+
factor: .001,
|
|
14084
|
+
offset: 0
|
|
14085
|
+
},
|
|
14086
|
+
A: {
|
|
14087
|
+
dimension: "current",
|
|
14088
|
+
factor: 1,
|
|
14089
|
+
offset: 0
|
|
14090
|
+
},
|
|
14091
|
+
mA: {
|
|
14092
|
+
dimension: "current",
|
|
14093
|
+
factor: .001,
|
|
14094
|
+
offset: 0
|
|
14095
|
+
},
|
|
14096
|
+
ppm: {
|
|
14097
|
+
dimension: "concentration-volume",
|
|
14098
|
+
factor: 1,
|
|
14099
|
+
offset: 0
|
|
14100
|
+
},
|
|
14101
|
+
ppb: {
|
|
14102
|
+
dimension: "concentration-volume",
|
|
14103
|
+
factor: .001,
|
|
14104
|
+
offset: 0
|
|
14105
|
+
},
|
|
14106
|
+
"µg/m³": {
|
|
14107
|
+
dimension: "concentration-mass",
|
|
14108
|
+
factor: 1,
|
|
14109
|
+
offset: 0
|
|
14110
|
+
},
|
|
14111
|
+
"mg/m³": {
|
|
14112
|
+
dimension: "concentration-mass",
|
|
14113
|
+
factor: 1e3,
|
|
14114
|
+
offset: 0
|
|
14115
|
+
},
|
|
14116
|
+
kg: {
|
|
14117
|
+
dimension: "mass",
|
|
14118
|
+
factor: 1,
|
|
14119
|
+
offset: 0
|
|
14120
|
+
},
|
|
14121
|
+
g: {
|
|
14122
|
+
dimension: "mass",
|
|
14123
|
+
factor: .001,
|
|
14124
|
+
offset: 0
|
|
14125
|
+
},
|
|
14126
|
+
lb: {
|
|
14127
|
+
dimension: "mass",
|
|
14128
|
+
factor: .453592,
|
|
14129
|
+
offset: 0
|
|
14130
|
+
},
|
|
14131
|
+
oz: {
|
|
14132
|
+
dimension: "mass",
|
|
14133
|
+
factor: .0283495,
|
|
14134
|
+
offset: 0
|
|
14135
|
+
},
|
|
14136
|
+
"%": {
|
|
14137
|
+
dimension: "percentage",
|
|
14138
|
+
factor: 1,
|
|
14139
|
+
offset: 0
|
|
14140
|
+
},
|
|
14141
|
+
L: {
|
|
14142
|
+
dimension: "volume",
|
|
14143
|
+
factor: 1,
|
|
14144
|
+
offset: 0
|
|
14145
|
+
},
|
|
14146
|
+
mL: {
|
|
14147
|
+
dimension: "volume",
|
|
14148
|
+
factor: .001,
|
|
14149
|
+
offset: 0
|
|
14150
|
+
},
|
|
14151
|
+
gal: {
|
|
14152
|
+
dimension: "volume",
|
|
14153
|
+
factor: 3.785411784,
|
|
14154
|
+
offset: 0
|
|
14155
|
+
},
|
|
14156
|
+
s: {
|
|
14157
|
+
dimension: "duration",
|
|
14158
|
+
factor: 1,
|
|
14159
|
+
offset: 0
|
|
14160
|
+
},
|
|
14161
|
+
ms: {
|
|
14162
|
+
dimension: "duration",
|
|
14163
|
+
factor: .001,
|
|
14164
|
+
offset: 0
|
|
14165
|
+
},
|
|
14166
|
+
min: {
|
|
14167
|
+
dimension: "duration",
|
|
14168
|
+
factor: 60,
|
|
14169
|
+
offset: 0
|
|
14170
|
+
},
|
|
14171
|
+
h: {
|
|
14172
|
+
dimension: "duration",
|
|
14173
|
+
factor: 3600,
|
|
14174
|
+
offset: 0
|
|
14175
|
+
},
|
|
14176
|
+
d: {
|
|
14177
|
+
dimension: "duration",
|
|
14178
|
+
factor: 86400,
|
|
14179
|
+
offset: 0
|
|
14180
|
+
},
|
|
14181
|
+
B: {
|
|
14182
|
+
dimension: "information",
|
|
14183
|
+
factor: 1,
|
|
14184
|
+
offset: 0
|
|
14185
|
+
},
|
|
14186
|
+
KiB: {
|
|
14187
|
+
dimension: "information",
|
|
14188
|
+
factor: 1024,
|
|
14189
|
+
offset: 0
|
|
14190
|
+
},
|
|
14191
|
+
MiB: {
|
|
14192
|
+
dimension: "information",
|
|
14193
|
+
factor: 1024 ** 2,
|
|
14194
|
+
offset: 0
|
|
14195
|
+
},
|
|
14196
|
+
GiB: {
|
|
14197
|
+
dimension: "information",
|
|
14198
|
+
factor: 1024 ** 3,
|
|
14199
|
+
offset: 0
|
|
14200
|
+
},
|
|
14201
|
+
TiB: {
|
|
14202
|
+
dimension: "information",
|
|
14203
|
+
factor: 1024 ** 4,
|
|
14204
|
+
offset: 0
|
|
14205
|
+
},
|
|
14206
|
+
kB: {
|
|
14207
|
+
dimension: "information",
|
|
14208
|
+
factor: 1e3,
|
|
14209
|
+
offset: 0
|
|
14210
|
+
},
|
|
14211
|
+
MB: {
|
|
14212
|
+
dimension: "information",
|
|
14213
|
+
factor: 1e6,
|
|
14214
|
+
offset: 0
|
|
14215
|
+
},
|
|
14216
|
+
GB: {
|
|
14217
|
+
dimension: "information",
|
|
14218
|
+
factor: 1e9,
|
|
14219
|
+
offset: 0
|
|
14220
|
+
},
|
|
14221
|
+
"°": {
|
|
14222
|
+
dimension: "angle",
|
|
14223
|
+
factor: 1,
|
|
14224
|
+
offset: 0
|
|
14225
|
+
},
|
|
14226
|
+
dBFS: {
|
|
14227
|
+
dimension: "sound-level",
|
|
14228
|
+
factor: 1,
|
|
14229
|
+
offset: 0
|
|
14230
|
+
},
|
|
14231
|
+
dBm: {
|
|
14232
|
+
dimension: "signal-level",
|
|
14233
|
+
factor: 1,
|
|
14234
|
+
offset: 0
|
|
14235
|
+
},
|
|
14236
|
+
mired: {
|
|
14237
|
+
dimension: "colour-temperature",
|
|
14238
|
+
factor: 1,
|
|
14239
|
+
offset: 0
|
|
14240
|
+
},
|
|
14241
|
+
kbps: {
|
|
14242
|
+
dimension: "bitrate",
|
|
14243
|
+
factor: 1,
|
|
14244
|
+
offset: 0
|
|
14245
|
+
},
|
|
14246
|
+
Mbps: {
|
|
14247
|
+
dimension: "bitrate",
|
|
14248
|
+
factor: 1e3,
|
|
14249
|
+
offset: 0
|
|
14250
|
+
},
|
|
14251
|
+
fps: {
|
|
14252
|
+
dimension: "rate",
|
|
14253
|
+
factor: 1,
|
|
14254
|
+
offset: 0
|
|
14255
|
+
}
|
|
14256
|
+
};
|
|
14257
|
+
/** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
|
|
14258
|
+
function specFor(unit) {
|
|
14259
|
+
return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
|
|
14260
|
+
}
|
|
14261
|
+
/** Value in `spec`'s unit → its dimension's canonical unit. */
|
|
14262
|
+
function toCanonical(value, spec) {
|
|
14263
|
+
return value * spec.factor + spec.offset;
|
|
14264
|
+
}
|
|
14265
|
+
/** Canonical-unit value → the unit described by `spec`. */
|
|
14266
|
+
function fromCanonical(canonical, spec) {
|
|
14267
|
+
return (canonical - spec.offset) / spec.factor;
|
|
14268
|
+
}
|
|
14269
|
+
/**
|
|
14270
|
+
* Graceful variant for the render path: returns the converted value, or
|
|
14271
|
+
* `undefined` when the conversion is refused (unknown unit / cross-dimension).
|
|
14272
|
+
* Never throws — a render caller falls back to the raw value + source unit.
|
|
14273
|
+
*/
|
|
14274
|
+
function tryConvertUnit(value, from, to) {
|
|
14275
|
+
if (from === to) return value;
|
|
14276
|
+
const fromSpec = specFor(from);
|
|
14277
|
+
if (!fromSpec) return void 0;
|
|
14278
|
+
const toSpec = specFor(to);
|
|
14279
|
+
if (!toSpec) return void 0;
|
|
14280
|
+
if (fromSpec.dimension !== toSpec.dimension) return void 0;
|
|
14281
|
+
return fromCanonical(toCanonical(value, fromSpec), toSpec);
|
|
14282
|
+
}
|
|
14283
|
+
//#endregion
|
|
14025
14284
|
//#region ../types/dist/index.mjs
|
|
14026
14285
|
var SMTP_INBOUND_DEFAULT_PORT = 2525;
|
|
14027
14286
|
var SMTP_INBOUND_DEFAULT_DOMAIN = "camstack.local";
|
|
@@ -43486,6 +43745,7 @@ var ExpressionBindingSourceSchema = union([
|
|
|
43486
43745
|
object({
|
|
43487
43746
|
kind: literal("global"),
|
|
43488
43747
|
sourceStableId: string(),
|
|
43748
|
+
addonId: string().optional(),
|
|
43489
43749
|
cap: string(),
|
|
43490
43750
|
fieldPath: string()
|
|
43491
43751
|
})
|
|
@@ -43612,385 +43872,6 @@ function extractSourceInfoFromMetadata(metadata) {
|
|
|
43612
43872
|
return parsed.data;
|
|
43613
43873
|
}
|
|
43614
43874
|
/**
|
|
43615
|
-
* Frozen unit → spec table. `•` in the doc marks each dimension's canonical
|
|
43616
|
-
* unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
|
|
43617
|
-
* `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
|
|
43618
|
-
* decimals). K derives from `°C = K − 273.15`.
|
|
43619
|
-
*/
|
|
43620
|
-
var UNIT_TABLE = {
|
|
43621
|
-
"°C": {
|
|
43622
|
-
dimension: "temperature",
|
|
43623
|
-
factor: 1,
|
|
43624
|
-
offset: 0
|
|
43625
|
-
},
|
|
43626
|
-
"°F": {
|
|
43627
|
-
dimension: "temperature",
|
|
43628
|
-
factor: 5 / 9,
|
|
43629
|
-
offset: -160 / 9
|
|
43630
|
-
},
|
|
43631
|
-
K: {
|
|
43632
|
-
dimension: "temperature",
|
|
43633
|
-
factor: 1,
|
|
43634
|
-
offset: -273.15
|
|
43635
|
-
},
|
|
43636
|
-
hPa: {
|
|
43637
|
-
dimension: "pressure",
|
|
43638
|
-
factor: 1,
|
|
43639
|
-
offset: 0
|
|
43640
|
-
},
|
|
43641
|
-
kPa: {
|
|
43642
|
-
dimension: "pressure",
|
|
43643
|
-
factor: 10,
|
|
43644
|
-
offset: 0
|
|
43645
|
-
},
|
|
43646
|
-
Pa: {
|
|
43647
|
-
dimension: "pressure",
|
|
43648
|
-
factor: .01,
|
|
43649
|
-
offset: 0
|
|
43650
|
-
},
|
|
43651
|
-
mbar: {
|
|
43652
|
-
dimension: "pressure",
|
|
43653
|
-
factor: 1,
|
|
43654
|
-
offset: 0
|
|
43655
|
-
},
|
|
43656
|
-
bar: {
|
|
43657
|
-
dimension: "pressure",
|
|
43658
|
-
factor: 1e3,
|
|
43659
|
-
offset: 0
|
|
43660
|
-
},
|
|
43661
|
-
inHg: {
|
|
43662
|
-
dimension: "pressure",
|
|
43663
|
-
factor: 33.8639,
|
|
43664
|
-
offset: 0
|
|
43665
|
-
},
|
|
43666
|
-
mmHg: {
|
|
43667
|
-
dimension: "pressure",
|
|
43668
|
-
factor: 1.33322,
|
|
43669
|
-
offset: 0
|
|
43670
|
-
},
|
|
43671
|
-
psi: {
|
|
43672
|
-
dimension: "pressure",
|
|
43673
|
-
factor: 68.9476,
|
|
43674
|
-
offset: 0
|
|
43675
|
-
},
|
|
43676
|
-
"m/s": {
|
|
43677
|
-
dimension: "speed",
|
|
43678
|
-
factor: 1,
|
|
43679
|
-
offset: 0
|
|
43680
|
-
},
|
|
43681
|
-
"km/h": {
|
|
43682
|
-
dimension: "speed",
|
|
43683
|
-
factor: 1 / 3.6,
|
|
43684
|
-
offset: 0
|
|
43685
|
-
},
|
|
43686
|
-
mph: {
|
|
43687
|
-
dimension: "speed",
|
|
43688
|
-
factor: .44704,
|
|
43689
|
-
offset: 0
|
|
43690
|
-
},
|
|
43691
|
-
kn: {
|
|
43692
|
-
dimension: "speed",
|
|
43693
|
-
factor: .514444,
|
|
43694
|
-
offset: 0
|
|
43695
|
-
},
|
|
43696
|
-
"mm/h": {
|
|
43697
|
-
dimension: "precipitation-rate",
|
|
43698
|
-
factor: 1,
|
|
43699
|
-
offset: 0
|
|
43700
|
-
},
|
|
43701
|
-
"in/h": {
|
|
43702
|
-
dimension: "precipitation-rate",
|
|
43703
|
-
factor: 25.4,
|
|
43704
|
-
offset: 0
|
|
43705
|
-
},
|
|
43706
|
-
m: {
|
|
43707
|
-
dimension: "length",
|
|
43708
|
-
factor: 1,
|
|
43709
|
-
offset: 0
|
|
43710
|
-
},
|
|
43711
|
-
mm: {
|
|
43712
|
-
dimension: "length",
|
|
43713
|
-
factor: .001,
|
|
43714
|
-
offset: 0
|
|
43715
|
-
},
|
|
43716
|
-
cm: {
|
|
43717
|
-
dimension: "length",
|
|
43718
|
-
factor: .01,
|
|
43719
|
-
offset: 0
|
|
43720
|
-
},
|
|
43721
|
-
km: {
|
|
43722
|
-
dimension: "length",
|
|
43723
|
-
factor: 1e3,
|
|
43724
|
-
offset: 0
|
|
43725
|
-
},
|
|
43726
|
-
in: {
|
|
43727
|
-
dimension: "length",
|
|
43728
|
-
factor: .0254,
|
|
43729
|
-
offset: 0
|
|
43730
|
-
},
|
|
43731
|
-
ft: {
|
|
43732
|
-
dimension: "length",
|
|
43733
|
-
factor: .3048,
|
|
43734
|
-
offset: 0
|
|
43735
|
-
},
|
|
43736
|
-
mi: {
|
|
43737
|
-
dimension: "length",
|
|
43738
|
-
factor: 1609.344,
|
|
43739
|
-
offset: 0
|
|
43740
|
-
},
|
|
43741
|
-
"m²": {
|
|
43742
|
-
dimension: "area",
|
|
43743
|
-
factor: 1,
|
|
43744
|
-
offset: 0
|
|
43745
|
-
},
|
|
43746
|
-
lx: {
|
|
43747
|
-
dimension: "illuminance",
|
|
43748
|
-
factor: 1,
|
|
43749
|
-
offset: 0
|
|
43750
|
-
},
|
|
43751
|
-
"W/m²": {
|
|
43752
|
-
dimension: "irradiance",
|
|
43753
|
-
factor: 1,
|
|
43754
|
-
offset: 0
|
|
43755
|
-
},
|
|
43756
|
-
W: {
|
|
43757
|
-
dimension: "power",
|
|
43758
|
-
factor: 1,
|
|
43759
|
-
offset: 0
|
|
43760
|
-
},
|
|
43761
|
-
kW: {
|
|
43762
|
-
dimension: "power",
|
|
43763
|
-
factor: 1e3,
|
|
43764
|
-
offset: 0
|
|
43765
|
-
},
|
|
43766
|
-
VA: {
|
|
43767
|
-
dimension: "apparent-power",
|
|
43768
|
-
factor: 1,
|
|
43769
|
-
offset: 0
|
|
43770
|
-
},
|
|
43771
|
-
Wh: {
|
|
43772
|
-
dimension: "energy",
|
|
43773
|
-
factor: 1,
|
|
43774
|
-
offset: 0
|
|
43775
|
-
},
|
|
43776
|
-
kWh: {
|
|
43777
|
-
dimension: "energy",
|
|
43778
|
-
factor: 1e3,
|
|
43779
|
-
offset: 0
|
|
43780
|
-
},
|
|
43781
|
-
MWh: {
|
|
43782
|
-
dimension: "energy",
|
|
43783
|
-
factor: 1e6,
|
|
43784
|
-
offset: 0
|
|
43785
|
-
},
|
|
43786
|
-
V: {
|
|
43787
|
-
dimension: "voltage",
|
|
43788
|
-
factor: 1,
|
|
43789
|
-
offset: 0
|
|
43790
|
-
},
|
|
43791
|
-
mV: {
|
|
43792
|
-
dimension: "voltage",
|
|
43793
|
-
factor: .001,
|
|
43794
|
-
offset: 0
|
|
43795
|
-
},
|
|
43796
|
-
A: {
|
|
43797
|
-
dimension: "current",
|
|
43798
|
-
factor: 1,
|
|
43799
|
-
offset: 0
|
|
43800
|
-
},
|
|
43801
|
-
mA: {
|
|
43802
|
-
dimension: "current",
|
|
43803
|
-
factor: .001,
|
|
43804
|
-
offset: 0
|
|
43805
|
-
},
|
|
43806
|
-
ppm: {
|
|
43807
|
-
dimension: "concentration-volume",
|
|
43808
|
-
factor: 1,
|
|
43809
|
-
offset: 0
|
|
43810
|
-
},
|
|
43811
|
-
ppb: {
|
|
43812
|
-
dimension: "concentration-volume",
|
|
43813
|
-
factor: .001,
|
|
43814
|
-
offset: 0
|
|
43815
|
-
},
|
|
43816
|
-
"µg/m³": {
|
|
43817
|
-
dimension: "concentration-mass",
|
|
43818
|
-
factor: 1,
|
|
43819
|
-
offset: 0
|
|
43820
|
-
},
|
|
43821
|
-
"mg/m³": {
|
|
43822
|
-
dimension: "concentration-mass",
|
|
43823
|
-
factor: 1e3,
|
|
43824
|
-
offset: 0
|
|
43825
|
-
},
|
|
43826
|
-
kg: {
|
|
43827
|
-
dimension: "mass",
|
|
43828
|
-
factor: 1,
|
|
43829
|
-
offset: 0
|
|
43830
|
-
},
|
|
43831
|
-
g: {
|
|
43832
|
-
dimension: "mass",
|
|
43833
|
-
factor: .001,
|
|
43834
|
-
offset: 0
|
|
43835
|
-
},
|
|
43836
|
-
lb: {
|
|
43837
|
-
dimension: "mass",
|
|
43838
|
-
factor: .453592,
|
|
43839
|
-
offset: 0
|
|
43840
|
-
},
|
|
43841
|
-
oz: {
|
|
43842
|
-
dimension: "mass",
|
|
43843
|
-
factor: .0283495,
|
|
43844
|
-
offset: 0
|
|
43845
|
-
},
|
|
43846
|
-
"%": {
|
|
43847
|
-
dimension: "percentage",
|
|
43848
|
-
factor: 1,
|
|
43849
|
-
offset: 0
|
|
43850
|
-
},
|
|
43851
|
-
L: {
|
|
43852
|
-
dimension: "volume",
|
|
43853
|
-
factor: 1,
|
|
43854
|
-
offset: 0
|
|
43855
|
-
},
|
|
43856
|
-
mL: {
|
|
43857
|
-
dimension: "volume",
|
|
43858
|
-
factor: .001,
|
|
43859
|
-
offset: 0
|
|
43860
|
-
},
|
|
43861
|
-
gal: {
|
|
43862
|
-
dimension: "volume",
|
|
43863
|
-
factor: 3.785411784,
|
|
43864
|
-
offset: 0
|
|
43865
|
-
},
|
|
43866
|
-
s: {
|
|
43867
|
-
dimension: "duration",
|
|
43868
|
-
factor: 1,
|
|
43869
|
-
offset: 0
|
|
43870
|
-
},
|
|
43871
|
-
ms: {
|
|
43872
|
-
dimension: "duration",
|
|
43873
|
-
factor: .001,
|
|
43874
|
-
offset: 0
|
|
43875
|
-
},
|
|
43876
|
-
min: {
|
|
43877
|
-
dimension: "duration",
|
|
43878
|
-
factor: 60,
|
|
43879
|
-
offset: 0
|
|
43880
|
-
},
|
|
43881
|
-
h: {
|
|
43882
|
-
dimension: "duration",
|
|
43883
|
-
factor: 3600,
|
|
43884
|
-
offset: 0
|
|
43885
|
-
},
|
|
43886
|
-
d: {
|
|
43887
|
-
dimension: "duration",
|
|
43888
|
-
factor: 86400,
|
|
43889
|
-
offset: 0
|
|
43890
|
-
},
|
|
43891
|
-
B: {
|
|
43892
|
-
dimension: "information",
|
|
43893
|
-
factor: 1,
|
|
43894
|
-
offset: 0
|
|
43895
|
-
},
|
|
43896
|
-
KiB: {
|
|
43897
|
-
dimension: "information",
|
|
43898
|
-
factor: 1024,
|
|
43899
|
-
offset: 0
|
|
43900
|
-
},
|
|
43901
|
-
MiB: {
|
|
43902
|
-
dimension: "information",
|
|
43903
|
-
factor: 1024 ** 2,
|
|
43904
|
-
offset: 0
|
|
43905
|
-
},
|
|
43906
|
-
GiB: {
|
|
43907
|
-
dimension: "information",
|
|
43908
|
-
factor: 1024 ** 3,
|
|
43909
|
-
offset: 0
|
|
43910
|
-
},
|
|
43911
|
-
TiB: {
|
|
43912
|
-
dimension: "information",
|
|
43913
|
-
factor: 1024 ** 4,
|
|
43914
|
-
offset: 0
|
|
43915
|
-
},
|
|
43916
|
-
kB: {
|
|
43917
|
-
dimension: "information",
|
|
43918
|
-
factor: 1e3,
|
|
43919
|
-
offset: 0
|
|
43920
|
-
},
|
|
43921
|
-
MB: {
|
|
43922
|
-
dimension: "information",
|
|
43923
|
-
factor: 1e6,
|
|
43924
|
-
offset: 0
|
|
43925
|
-
},
|
|
43926
|
-
GB: {
|
|
43927
|
-
dimension: "information",
|
|
43928
|
-
factor: 1e9,
|
|
43929
|
-
offset: 0
|
|
43930
|
-
},
|
|
43931
|
-
"°": {
|
|
43932
|
-
dimension: "angle",
|
|
43933
|
-
factor: 1,
|
|
43934
|
-
offset: 0
|
|
43935
|
-
},
|
|
43936
|
-
dBFS: {
|
|
43937
|
-
dimension: "sound-level",
|
|
43938
|
-
factor: 1,
|
|
43939
|
-
offset: 0
|
|
43940
|
-
},
|
|
43941
|
-
dBm: {
|
|
43942
|
-
dimension: "signal-level",
|
|
43943
|
-
factor: 1,
|
|
43944
|
-
offset: 0
|
|
43945
|
-
},
|
|
43946
|
-
mired: {
|
|
43947
|
-
dimension: "colour-temperature",
|
|
43948
|
-
factor: 1,
|
|
43949
|
-
offset: 0
|
|
43950
|
-
},
|
|
43951
|
-
kbps: {
|
|
43952
|
-
dimension: "bitrate",
|
|
43953
|
-
factor: 1,
|
|
43954
|
-
offset: 0
|
|
43955
|
-
},
|
|
43956
|
-
Mbps: {
|
|
43957
|
-
dimension: "bitrate",
|
|
43958
|
-
factor: 1e3,
|
|
43959
|
-
offset: 0
|
|
43960
|
-
},
|
|
43961
|
-
fps: {
|
|
43962
|
-
dimension: "rate",
|
|
43963
|
-
factor: 1,
|
|
43964
|
-
offset: 0
|
|
43965
|
-
}
|
|
43966
|
-
};
|
|
43967
|
-
/** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
|
|
43968
|
-
function specFor(unit) {
|
|
43969
|
-
return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
|
|
43970
|
-
}
|
|
43971
|
-
/** Value in `spec`'s unit → its dimension's canonical unit. */
|
|
43972
|
-
function toCanonical(value, spec) {
|
|
43973
|
-
return value * spec.factor + spec.offset;
|
|
43974
|
-
}
|
|
43975
|
-
/** Canonical-unit value → the unit described by `spec`. */
|
|
43976
|
-
function fromCanonical(canonical, spec) {
|
|
43977
|
-
return (canonical - spec.offset) / spec.factor;
|
|
43978
|
-
}
|
|
43979
|
-
/**
|
|
43980
|
-
* Graceful variant for the render path: returns the converted value, or
|
|
43981
|
-
* `undefined` when the conversion is refused (unknown unit / cross-dimension).
|
|
43982
|
-
* Never throws — a render caller falls back to the raw value + source unit.
|
|
43983
|
-
*/
|
|
43984
|
-
function tryConvertUnit(value, from, to) {
|
|
43985
|
-
if (from === to) return value;
|
|
43986
|
-
const fromSpec = specFor(from);
|
|
43987
|
-
if (!fromSpec) return void 0;
|
|
43988
|
-
const toSpec = specFor(to);
|
|
43989
|
-
if (!toSpec) return void 0;
|
|
43990
|
-
if (fromSpec.dimension !== toSpec.dimension) return void 0;
|
|
43991
|
-
return fromCanonical(toCanonical(value, fromSpec), toSpec);
|
|
43992
|
-
}
|
|
43993
|
-
/**
|
|
43994
43875
|
* A number a person types for a physical quantity — the input side of the
|
|
43995
43876
|
* value + unit contract (D972).
|
|
43996
43877
|
*
|
|
@@ -45688,26 +45569,23 @@ var SettingsSchemaWithValuesSchema = object({
|
|
|
45688
45569
|
var SettingsPatchSchema = record(string(), unknown());
|
|
45689
45570
|
/** The scope of a scoped-settings call (D986): where the capability declared the values. */
|
|
45690
45571
|
var ScopedSettingsScopeSchema = _enum(SCOPED_SETTINGS_SCOPES);
|
|
45572
|
+
/** One scoped schema an addon serves: its capability, scope and section ids. */
|
|
45573
|
+
var ScopedSettingsDeclarationSchema = object({
|
|
45574
|
+
cap: string(),
|
|
45575
|
+
scope: ScopedSettingsScopeSchema,
|
|
45576
|
+
sectionIds: array(string())
|
|
45577
|
+
});
|
|
45691
45578
|
/** Standard success response for update operations. */
|
|
45692
45579
|
var SettingsUpdateResultSchema = object({ success: literal(true) });
|
|
45693
45580
|
method(object({
|
|
45694
|
-
addonId: string(),
|
|
45695
|
-
nodeId: string().optional(),
|
|
45696
|
-
overlay: record(string(), unknown()).optional(),
|
|
45697
|
-
cap: string().optional()
|
|
45698
|
-
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
45699
|
-
addonId: string(),
|
|
45700
|
-
nodeId: string().optional(),
|
|
45701
|
-
patch: SettingsPatchSchema
|
|
45702
|
-
}), SettingsUpdateResultSchema, {
|
|
45703
|
-
kind: "mutation",
|
|
45704
|
-
auth: "admin"
|
|
45705
|
-
}), method(object({
|
|
45706
45581
|
addonId: string(),
|
|
45707
45582
|
cap: string(),
|
|
45708
45583
|
scope: ScopedSettingsScopeSchema,
|
|
45709
45584
|
nodeId: string().optional()
|
|
45710
45585
|
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
45586
|
+
addonId: string(),
|
|
45587
|
+
nodeId: string().optional()
|
|
45588
|
+
}), array(ScopedSettingsDeclarationSchema).nullable()), method(object({
|
|
45711
45589
|
addonId: string(),
|
|
45712
45590
|
cap: string(),
|
|
45713
45591
|
scope: ScopedSettingsScopeSchema,
|
|
@@ -45722,9 +45600,6 @@ method(object({
|
|
|
45722
45600
|
scope: ScopedSettingsScopeSchema,
|
|
45723
45601
|
nodeId: string().optional()
|
|
45724
45602
|
}), record(string(), unknown()).nullable()), method(object({
|
|
45725
|
-
addonId: string(),
|
|
45726
|
-
nodeId: string().optional()
|
|
45727
|
-
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
45728
45603
|
addonId: string(),
|
|
45729
45604
|
nodeId: string().optional(),
|
|
45730
45605
|
instance: IntegrationInstanceRefSchema
|
|
@@ -47287,7 +47162,7 @@ var BackupDestinationInfoSchema = object({
|
|
|
47287
47162
|
id: string(),
|
|
47288
47163
|
/**
|
|
47289
47164
|
* Manifest id of the owning addon. The Settings button on the
|
|
47290
|
-
* destination card opens that addon's
|
|
47165
|
+
* destination card opens that addon's scoped settings panel.
|
|
47291
47166
|
*/
|
|
47292
47167
|
addonId: string(),
|
|
47293
47168
|
/** Operator-toggled enable flag from the destination-policy table. */
|
|
@@ -52764,6 +52639,7 @@ method(InstancePinSchema, DeviceExportStatusSchema), method(_void(), array(Expor
|
|
|
52764
52639
|
kind: "mutation",
|
|
52765
52640
|
auth: "admin"
|
|
52766
52641
|
});
|
|
52642
|
+
var DeviceAliasSchema = string().max(64).regex(/^[a-z][a-z0-9_]*$/);
|
|
52767
52643
|
/**
|
|
52768
52644
|
* A SITE ZONE — a named part of the property that several locations belong to.
|
|
52769
52645
|
*
|
|
@@ -53250,6 +53126,12 @@ var DeviceInfoSchema = object({
|
|
|
53250
53126
|
addonId: string(),
|
|
53251
53127
|
type: _enum(DeviceType),
|
|
53252
53128
|
name: string(),
|
|
53129
|
+
/** The name a value template uses for this device (`{{ stufa_veranda.temperature }}`),
|
|
53130
|
+
* entity_id style. Generated once from the name at first registration, unique
|
|
53131
|
+
* cluster-wide, editable through `setAlias`, NOT changed by a rename (D1021).
|
|
53132
|
+
* Optional: a record produced by an older build omits it until the boot
|
|
53133
|
+
* backfill has run. */
|
|
53134
|
+
alias: DeviceAliasSchema.optional(),
|
|
53253
53135
|
/** Operator-organisational location label. `null` when unset. */
|
|
53254
53136
|
location: string().nullable(),
|
|
53255
53137
|
/** Soft-disabled flag. */
|
|
@@ -53569,6 +53451,25 @@ method(object({
|
|
|
53569
53451
|
}), _void(), {
|
|
53570
53452
|
kind: "mutation",
|
|
53571
53453
|
auth: "admin"
|
|
53454
|
+
}), method(object({
|
|
53455
|
+
deviceId: number$1(),
|
|
53456
|
+
alias: string()
|
|
53457
|
+
}), discriminatedUnion("ok", [object({
|
|
53458
|
+
ok: literal(true),
|
|
53459
|
+
alias: DeviceAliasSchema
|
|
53460
|
+
}), object({
|
|
53461
|
+
ok: literal(false),
|
|
53462
|
+
reason: _enum([
|
|
53463
|
+
"empty",
|
|
53464
|
+
"too-long",
|
|
53465
|
+
"grammar",
|
|
53466
|
+
"reserved",
|
|
53467
|
+
"taken"
|
|
53468
|
+
]),
|
|
53469
|
+
takenBy: number$1().optional()
|
|
53470
|
+
})]), {
|
|
53471
|
+
kind: "mutation",
|
|
53472
|
+
auth: "admin"
|
|
53572
53473
|
}), method(object({
|
|
53573
53474
|
deviceId: number$1(),
|
|
53574
53475
|
location: string().nullable()
|
|
@@ -67669,6 +67570,11 @@ var NcScheduleSchema = object({
|
|
|
67669
67570
|
* as a STATE SUMMARY at the end of each window of `schedule`.
|
|
67670
67571
|
*/
|
|
67671
67572
|
var NcSystemEventDeliveryModeSchema = _enum(["instant", "summary"]);
|
|
67573
|
+
_enum([
|
|
67574
|
+
"activation",
|
|
67575
|
+
"deactivation",
|
|
67576
|
+
"schedule"
|
|
67577
|
+
]);
|
|
67672
67578
|
/**
|
|
67673
67579
|
* How a summary window is SENT (D698): `rule` (absent) = ONE notification with
|
|
67674
67580
|
* every section; `section` = one notification per section with something to
|
|
@@ -67685,11 +67591,26 @@ var NcStateSummarySplitSchema = _enum(["rule", "section"]);
|
|
|
67685
67591
|
* midnight crossing); the send time is each window's END. Refused on the
|
|
67686
67592
|
* `alarm` family, which stays instant (`systemEventDeliveryProblems`).
|
|
67687
67593
|
*/
|
|
67688
|
-
var NcSystemEventDeliverySchema = discriminatedUnion("mode", [
|
|
67689
|
-
mode: literal("
|
|
67690
|
-
|
|
67691
|
-
|
|
67692
|
-
|
|
67594
|
+
var NcSystemEventDeliverySchema = discriminatedUnion("mode", [
|
|
67595
|
+
object({ mode: literal("instant") }),
|
|
67596
|
+
object({
|
|
67597
|
+
mode: literal("summary"),
|
|
67598
|
+
schedule: NcScheduleSchema,
|
|
67599
|
+
split: NcStateSummarySplitSchema.optional()
|
|
67600
|
+
}),
|
|
67601
|
+
object({
|
|
67602
|
+
mode: literal("modes"),
|
|
67603
|
+
/** The bad edge, and every kind that has a single edge. */
|
|
67604
|
+
onActivation: boolean(),
|
|
67605
|
+
/** The recovery edges of the classes of the selected kinds (derived, never stored per kind). */
|
|
67606
|
+
onDeactivation: boolean(),
|
|
67607
|
+
/** A state summary at the end of each window; absent = no summary. */
|
|
67608
|
+
onSchedule: object({
|
|
67609
|
+
schedule: NcScheduleSchema,
|
|
67610
|
+
grouping: NcStateSummarySplitSchema
|
|
67611
|
+
}).optional()
|
|
67612
|
+
})
|
|
67613
|
+
]);
|
|
67693
67614
|
/** Fuzzy plate matcher — OCR noise makes exact match useless (spec row 12/13). */
|
|
67694
67615
|
var NcPlateMatcherSchema = object({
|
|
67695
67616
|
/**
|
|
@@ -75780,93 +75701,27 @@ var RunningFlipEventDataSchema = object({
|
|
|
75780
75701
|
phase: string().nullable()
|
|
75781
75702
|
});
|
|
75782
75703
|
var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
|
|
75783
|
-
/**
|
|
75784
|
-
|
|
75785
|
-
|
|
75786
|
-
|
|
75787
|
-
|
|
75788
|
-
|
|
75789
|
-
|
|
75790
|
-
|
|
75791
|
-
|
|
75792
|
-
|
|
75793
|
-
|
|
75794
|
-
|
|
75795
|
-
|
|
75796
|
-
|
|
75797
|
-
|
|
75798
|
-
|
|
75799
|
-
|
|
75800
|
-
|
|
75801
|
-
|
|
75802
|
-
|
|
75803
|
-
|
|
75804
|
-
DeviceType.WaterHeater,
|
|
75805
|
-
DeviceType.Humidifier,
|
|
75806
|
-
DeviceType.Fan,
|
|
75807
|
-
DeviceType.Climate,
|
|
75808
|
-
DeviceType.Thermostat,
|
|
75809
|
-
DeviceType.PetFeeder,
|
|
75810
|
-
DeviceType.Heater
|
|
75811
|
-
],
|
|
75812
|
-
apply: "add",
|
|
75813
|
-
path: "running",
|
|
75814
|
-
sources: [
|
|
75815
|
-
{
|
|
75816
|
-
kind: "switch",
|
|
75817
|
-
transforms: [{ kind: "identity" }]
|
|
75818
|
-
},
|
|
75819
|
-
{
|
|
75820
|
-
kind: "binary",
|
|
75821
|
-
transforms: [{ kind: "identity" }, { kind: "invert" }]
|
|
75822
|
-
},
|
|
75823
|
-
{
|
|
75824
|
-
kind: "numeric",
|
|
75825
|
-
requiredUnit: "W",
|
|
75826
|
-
transforms: [{
|
|
75827
|
-
kind: "threshold",
|
|
75828
|
-
comparisons: ["gte", "lte"],
|
|
75829
|
-
comparison: "gte",
|
|
75830
|
-
defaultThreshold: 5,
|
|
75831
|
-
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
75832
|
-
defaultStopDwellMs: RUNNING_POWER_STOP_DELAY_MS,
|
|
75833
|
-
thresholdUnit: "W"
|
|
75834
|
-
}]
|
|
75835
|
-
}
|
|
75836
|
-
],
|
|
75837
|
-
companions: [
|
|
75838
|
-
{
|
|
75839
|
-
kind: "constant",
|
|
75840
|
-
path: "source",
|
|
75841
|
-
value: "assigned",
|
|
75842
|
-
when: "always"
|
|
75843
|
-
},
|
|
75844
|
-
{
|
|
75845
|
-
kind: "constant",
|
|
75846
|
-
path: "phase",
|
|
75847
|
-
value: null,
|
|
75848
|
-
when: "add"
|
|
75849
|
-
},
|
|
75850
|
-
{
|
|
75851
|
-
kind: "clock",
|
|
75852
|
-
path: "lastFetchedAt",
|
|
75853
|
-
when: "always"
|
|
75854
|
-
},
|
|
75855
|
-
{
|
|
75856
|
-
kind: "transition-time",
|
|
75857
|
-
path: "since",
|
|
75858
|
-
sourceChangedAt: "prefer"
|
|
75859
|
-
}
|
|
75860
|
-
],
|
|
75861
|
-
sourceReport: {
|
|
75862
|
-
status: "assignment-status",
|
|
75863
|
-
runtimeField: "source",
|
|
75864
|
-
nativeValue: "native",
|
|
75865
|
-
assignedValue: "assigned"
|
|
75866
|
-
},
|
|
75867
|
-
advancedExpression: true
|
|
75868
|
-
}]
|
|
75869
|
-
};
|
|
75704
|
+
/**
|
|
75705
|
+
* Customize offers "running" only where a job makes sense (D933): a cycle,
|
|
75706
|
+
* a clean, a mow, playback, or another appliance that is on and working.
|
|
75707
|
+
* The cap itself stays on every type — a camera can still report running
|
|
75708
|
+
* natively; it just has no card.
|
|
75709
|
+
*/
|
|
75710
|
+
var RUNNING_CUSTOMIZE_DEVICE_TYPES = [
|
|
75711
|
+
DeviceType.Washer,
|
|
75712
|
+
DeviceType.Dryer,
|
|
75713
|
+
DeviceType.Dishwasher,
|
|
75714
|
+
DeviceType.Vacuum,
|
|
75715
|
+
DeviceType.LawnMower,
|
|
75716
|
+
DeviceType.MediaPlayer,
|
|
75717
|
+
DeviceType.WaterHeater,
|
|
75718
|
+
DeviceType.Humidifier,
|
|
75719
|
+
DeviceType.Fan,
|
|
75720
|
+
DeviceType.Climate,
|
|
75721
|
+
DeviceType.Thermostat,
|
|
75722
|
+
DeviceType.PetFeeder,
|
|
75723
|
+
DeviceType.Heater
|
|
75724
|
+
];
|
|
75870
75725
|
var runningStateCapability = {
|
|
75871
75726
|
name: "running-state",
|
|
75872
75727
|
scope: "device",
|
|
@@ -75886,7 +75741,78 @@ var runningStateCapability = {
|
|
|
75886
75741
|
durability: "restored",
|
|
75887
75742
|
history: { fields: { running: { kind: "boolean" } } },
|
|
75888
75743
|
volatileStateFields: ["lastFetchedAt"],
|
|
75889
|
-
customize:
|
|
75744
|
+
customize: {
|
|
75745
|
+
version: 1,
|
|
75746
|
+
overridable: [{
|
|
75747
|
+
path: "running",
|
|
75748
|
+
by: "running"
|
|
75749
|
+
}],
|
|
75750
|
+
targets: [{
|
|
75751
|
+
id: "running",
|
|
75752
|
+
cardinality: "scalar",
|
|
75753
|
+
vocabulary: {
|
|
75754
|
+
cap: "running-state",
|
|
75755
|
+
stateField: "running"
|
|
75756
|
+
},
|
|
75757
|
+
deviceTypes: RUNNING_CUSTOMIZE_DEVICE_TYPES,
|
|
75758
|
+
apply: "add",
|
|
75759
|
+
path: "running",
|
|
75760
|
+
sources: [
|
|
75761
|
+
{
|
|
75762
|
+
kind: "switch",
|
|
75763
|
+
transforms: [{ kind: "identity" }]
|
|
75764
|
+
},
|
|
75765
|
+
{
|
|
75766
|
+
kind: "binary",
|
|
75767
|
+
transforms: [{ kind: "identity" }, { kind: "invert" }]
|
|
75768
|
+
},
|
|
75769
|
+
{
|
|
75770
|
+
kind: "numeric",
|
|
75771
|
+
requiredUnit: "W",
|
|
75772
|
+
transforms: [{
|
|
75773
|
+
kind: "threshold",
|
|
75774
|
+
comparisons: ["gte", "lte"],
|
|
75775
|
+
comparison: "gte",
|
|
75776
|
+
defaultThreshold: 5,
|
|
75777
|
+
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
75778
|
+
defaultStopDwellMs: RUNNING_POWER_STOP_DELAY_MS,
|
|
75779
|
+
thresholdUnit: "W"
|
|
75780
|
+
}]
|
|
75781
|
+
}
|
|
75782
|
+
],
|
|
75783
|
+
companions: [
|
|
75784
|
+
{
|
|
75785
|
+
kind: "constant",
|
|
75786
|
+
path: "source",
|
|
75787
|
+
value: "assigned",
|
|
75788
|
+
when: "always"
|
|
75789
|
+
},
|
|
75790
|
+
{
|
|
75791
|
+
kind: "constant",
|
|
75792
|
+
path: "phase",
|
|
75793
|
+
value: null,
|
|
75794
|
+
when: "add"
|
|
75795
|
+
},
|
|
75796
|
+
{
|
|
75797
|
+
kind: "clock",
|
|
75798
|
+
path: "lastFetchedAt",
|
|
75799
|
+
when: "always"
|
|
75800
|
+
},
|
|
75801
|
+
{
|
|
75802
|
+
kind: "transition-time",
|
|
75803
|
+
path: "since",
|
|
75804
|
+
sourceChangedAt: "prefer"
|
|
75805
|
+
}
|
|
75806
|
+
],
|
|
75807
|
+
sourceReport: {
|
|
75808
|
+
status: "assignment-status",
|
|
75809
|
+
runtimeField: "source",
|
|
75810
|
+
nativeValue: "native",
|
|
75811
|
+
assignedValue: "assigned"
|
|
75812
|
+
},
|
|
75813
|
+
advancedExpression: true
|
|
75814
|
+
}]
|
|
75815
|
+
}
|
|
75890
75816
|
};
|
|
75891
75817
|
/**
|
|
75892
75818
|
* scene-monitor — device-scoped reference-region state cap. An operator marks
|
|
@@ -78820,6 +78746,11 @@ var TimedRunUnitSchema = _enum(["s", "min"]);
|
|
|
78820
78746
|
_enum(["switch", "pet-fountain"]);
|
|
78821
78747
|
DeviceType.Heater, DeviceType.PetFountain;
|
|
78822
78748
|
var TIMED_RUN_DEVICE_TYPES = [DeviceType.Heater, DeviceType.PetFountain];
|
|
78749
|
+
/** One duration, as the one-tap run asks for it. */
|
|
78750
|
+
var TimedRunQuickRunSchema = object({
|
|
78751
|
+
duration: number$1().positive().finite(),
|
|
78752
|
+
unit: TimedRunUnitSchema
|
|
78753
|
+
});
|
|
78823
78754
|
/** Why a request was not carried out. Typed, so a caller can say it in words. */
|
|
78824
78755
|
var TimedRunRefusalSchema = _enum([
|
|
78825
78756
|
"unsupported-device",
|
|
@@ -78840,8 +78771,23 @@ var TimedRunStatusSchema = object({
|
|
|
78840
78771
|
activeUntil: number$1().nullable(),
|
|
78841
78772
|
/** Who asked for the run (a user id or an addon id); `null` when nothing is armed or it did not say. */
|
|
78842
78773
|
requestedBy: string().nullable(),
|
|
78774
|
+
/**
|
|
78775
|
+
* The one-tap run of THIS device: what a "Run" button on any surface starts. `null` when
|
|
78776
|
+
* the device is gone or its type has no timed run; a status from before this field
|
|
78777
|
+
* existed has none, and a surface falls back to the type's default.
|
|
78778
|
+
*/
|
|
78779
|
+
quickRun: TimedRunQuickRunSchema.nullable(),
|
|
78843
78780
|
lastFetchedAt: number$1()
|
|
78844
78781
|
});
|
|
78782
|
+
/** What the settings form needs: the unit, the bounds and the type's default. */
|
|
78783
|
+
var TimedRunOptionsSchema = object({
|
|
78784
|
+
unit: TimedRunUnitSchema,
|
|
78785
|
+
/** The longest run, in `unit`. */
|
|
78786
|
+
maxDuration: number$1(),
|
|
78787
|
+
defaultDuration: number$1()
|
|
78788
|
+
});
|
|
78789
|
+
/** The one-tap run duration, in the type's unit; `null` returns to the type's default. */
|
|
78790
|
+
var TimedRunSettingsPatchSchema = object({ quickRunDuration: number$1().positive().finite().nullable().optional() });
|
|
78845
78791
|
var timedRunCapability = {
|
|
78846
78792
|
name: "timed-run",
|
|
78847
78793
|
scope: "device",
|
|
@@ -78849,7 +78795,24 @@ var timedRunCapability = {
|
|
|
78849
78795
|
kind: "wrapper",
|
|
78850
78796
|
defaultActive: true,
|
|
78851
78797
|
deviceTypes: TIMED_RUN_DEVICE_TYPES,
|
|
78798
|
+
deviceConfig: { ui: {
|
|
78799
|
+
kind: "derived-form",
|
|
78800
|
+
builderId: "timed-run",
|
|
78801
|
+
tab: "general"
|
|
78802
|
+
} },
|
|
78852
78803
|
methods: {
|
|
78804
|
+
getOptions: method(object({ deviceId: number$1().int() }), TimedRunOptionsSchema),
|
|
78805
|
+
/**
|
|
78806
|
+
* The one-tap run of this device. A duration above the type's maximum is
|
|
78807
|
+
* REFUSED (thrown), like `runFor`: the maximum is a safety bound.
|
|
78808
|
+
*/
|
|
78809
|
+
setSettings: method(object({
|
|
78810
|
+
deviceId: number$1().int(),
|
|
78811
|
+
settings: TimedRunSettingsPatchSchema
|
|
78812
|
+
}), _void(), {
|
|
78813
|
+
kind: "mutation",
|
|
78814
|
+
auth: "admin"
|
|
78815
|
+
}),
|
|
78853
78816
|
/**
|
|
78854
78817
|
* Turn the device on and arm its off. A run already armed is replaced (the
|
|
78855
78818
|
* new deadline wins). Refuses with a typed reason above the type's maximum.
|
|
@@ -83550,13 +83513,6 @@ Object.freeze({
|
|
|
83550
83513
|
access: "view",
|
|
83551
83514
|
role: "admin"
|
|
83552
83515
|
},
|
|
83553
|
-
"addonSettings.getGlobalSettings": {
|
|
83554
|
-
capName: "addon-settings",
|
|
83555
|
-
capScope: "system",
|
|
83556
|
-
addonId: null,
|
|
83557
|
-
access: "view",
|
|
83558
|
-
role: "admin"
|
|
83559
|
-
},
|
|
83560
83516
|
"addonSettings.getIntegrationFormSchema": {
|
|
83561
83517
|
capName: "addon-settings",
|
|
83562
83518
|
capScope: "system",
|
|
@@ -83564,14 +83520,14 @@ Object.freeze({
|
|
|
83564
83520
|
access: "view",
|
|
83565
83521
|
role: "admin"
|
|
83566
83522
|
},
|
|
83567
|
-
"addonSettings.
|
|
83523
|
+
"addonSettings.getScopedSettings": {
|
|
83568
83524
|
capName: "addon-settings",
|
|
83569
83525
|
capScope: "system",
|
|
83570
83526
|
addonId: null,
|
|
83571
83527
|
access: "view",
|
|
83572
83528
|
role: "admin"
|
|
83573
83529
|
},
|
|
83574
|
-
"addonSettings.
|
|
83530
|
+
"addonSettings.listScopedSettings": {
|
|
83575
83531
|
capName: "addon-settings",
|
|
83576
83532
|
capScope: "system",
|
|
83577
83533
|
addonId: null,
|
|
@@ -83599,13 +83555,6 @@ Object.freeze({
|
|
|
83599
83555
|
access: "create",
|
|
83600
83556
|
role: "admin"
|
|
83601
83557
|
},
|
|
83602
|
-
"addonSettings.updateGlobalSettings": {
|
|
83603
|
-
capName: "addon-settings",
|
|
83604
|
-
capScope: "system",
|
|
83605
|
-
addonId: null,
|
|
83606
|
-
access: "create",
|
|
83607
|
-
role: "admin"
|
|
83608
|
-
},
|
|
83609
83558
|
"addonSettings.updateScopedSettings": {
|
|
83610
83559
|
capName: "addon-settings",
|
|
83611
83560
|
capScope: "system",
|
|
@@ -85776,6 +85725,13 @@ Object.freeze({
|
|
|
85776
85725
|
access: "create",
|
|
85777
85726
|
role: "admin"
|
|
85778
85727
|
},
|
|
85728
|
+
"deviceManager.setAlias": {
|
|
85729
|
+
capName: "device-manager",
|
|
85730
|
+
capScope: "system",
|
|
85731
|
+
addonId: null,
|
|
85732
|
+
access: "create",
|
|
85733
|
+
role: "admin"
|
|
85734
|
+
},
|
|
85779
85735
|
"deviceManager.setChildLayout": {
|
|
85780
85736
|
capName: "device-manager",
|
|
85781
85737
|
capScope: "system",
|
|
@@ -92559,6 +92515,13 @@ Object.freeze({
|
|
|
92559
92515
|
access: "create",
|
|
92560
92516
|
role: "viewer"
|
|
92561
92517
|
},
|
|
92518
|
+
"timedRun.getOptions": {
|
|
92519
|
+
capName: "timed-run",
|
|
92520
|
+
capScope: "device",
|
|
92521
|
+
addonId: null,
|
|
92522
|
+
access: "view",
|
|
92523
|
+
role: "viewer"
|
|
92524
|
+
},
|
|
92562
92525
|
"timedRun.getStatus": {
|
|
92563
92526
|
capName: "timed-run",
|
|
92564
92527
|
capScope: "device",
|
|
@@ -92573,6 +92536,13 @@ Object.freeze({
|
|
|
92573
92536
|
access: "create",
|
|
92574
92537
|
role: "viewer"
|
|
92575
92538
|
},
|
|
92539
|
+
"timedRun.setSettings": {
|
|
92540
|
+
capName: "timed-run",
|
|
92541
|
+
capScope: "device",
|
|
92542
|
+
addonId: null,
|
|
92543
|
+
access: "create",
|
|
92544
|
+
role: "admin"
|
|
92545
|
+
},
|
|
92576
92546
|
"toast.onToast": {
|
|
92577
92547
|
capName: "toast",
|
|
92578
92548
|
capScope: "system",
|
|
@@ -93503,6 +93473,7 @@ function offered(received) {
|
|
|
93503
93473
|
};
|
|
93504
93474
|
}
|
|
93505
93475
|
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
93476
|
+
string().min(1).max(4096);
|
|
93506
93477
|
Object.freeze({
|
|
93507
93478
|
"accessories.getStatus": [{
|
|
93508
93479
|
name: "deviceId",
|
|
@@ -94186,6 +94157,11 @@ Object.freeze({
|
|
|
94186
94157
|
form: "single",
|
|
94187
94158
|
optional: false
|
|
94188
94159
|
}],
|
|
94160
|
+
"deviceManager.setAlias": [{
|
|
94161
|
+
name: "deviceId",
|
|
94162
|
+
form: "single",
|
|
94163
|
+
optional: false
|
|
94164
|
+
}],
|
|
94189
94165
|
"deviceManager.setChildLayout": [{
|
|
94190
94166
|
name: "deviceId",
|
|
94191
94167
|
form: "single",
|
|
@@ -96250,6 +96226,11 @@ Object.freeze({
|
|
|
96250
96226
|
form: "single",
|
|
96251
96227
|
optional: false
|
|
96252
96228
|
}],
|
|
96229
|
+
"timedRun.getOptions": [{
|
|
96230
|
+
name: "deviceId",
|
|
96231
|
+
form: "single",
|
|
96232
|
+
optional: false
|
|
96233
|
+
}],
|
|
96253
96234
|
"timedRun.getStatus": [{
|
|
96254
96235
|
name: "deviceId",
|
|
96255
96236
|
form: "single",
|
|
@@ -96260,6 +96241,11 @@ Object.freeze({
|
|
|
96260
96241
|
form: "single",
|
|
96261
96242
|
optional: false
|
|
96262
96243
|
}],
|
|
96244
|
+
"timedRun.setSettings": [{
|
|
96245
|
+
name: "deviceId",
|
|
96246
|
+
form: "single",
|
|
96247
|
+
optional: false
|
|
96248
|
+
}],
|
|
96263
96249
|
"update.getStatus": [{
|
|
96264
96250
|
name: "deviceId",
|
|
96265
96251
|
form: "single",
|
|
@@ -97329,6 +97315,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
97329
97315
|
[...RULE_TEXT],
|
|
97330
97316
|
[...RULE_TEXT],
|
|
97331
97317
|
[...RULE_TEXT],
|
|
97318
|
+
[...RULE_TEXT],
|
|
97332
97319
|
[...RULE_BODY_ONLY],
|
|
97333
97320
|
[...RULE_TEXT],
|
|
97334
97321
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|