@camstack/addon-import-alexa 0.2.178 → 0.2.179
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 +812 -259
- package/dist/addon.mjs +812 -259
- package/package.json +2 -2
package/dist/addon.js
CHANGED
|
@@ -834,7 +834,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
834
834
|
return EventCategory;
|
|
835
835
|
}({});
|
|
836
836
|
//#endregion
|
|
837
|
-
//#region ../types/dist/device-type-
|
|
837
|
+
//#region ../types/dist/device-type-CfHw_quR.mjs
|
|
838
838
|
/**
|
|
839
839
|
import { errMsg } from '@camstack/types'
|
|
840
840
|
* Extract a human-readable message from an unknown error value.
|
|
@@ -1023,6 +1023,9 @@ var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
|
1023
1023
|
DeviceFeature["CoverPositionable"] = "cover-positionable";
|
|
1024
1024
|
/** Cover exposes slat-tilt control. Gates the tilt slider UI. */
|
|
1025
1025
|
DeviceFeature["CoverTilt"] = "cover-tilt";
|
|
1026
|
+
/** Cover has a real stop: `stop` halts the travel in place. Gates the stop
|
|
1027
|
+
* control in exporters; a provider whose `stop` is a no-op never declares it. */
|
|
1028
|
+
DeviceFeature["CoverStoppable"] = "cover-stoppable";
|
|
1026
1029
|
/** Valve exposes intermediate position control (0..100). Gates the
|
|
1027
1030
|
* position slider / drag surface UI. */
|
|
1028
1031
|
DeviceFeature["ValvePositionable"] = "valve-positionable";
|
|
@@ -6035,7 +6038,7 @@ function number(params) {
|
|
|
6035
6038
|
return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
|
|
6036
6039
|
}
|
|
6037
6040
|
//#endregion
|
|
6038
|
-
//#region ../types/dist/sleep-
|
|
6041
|
+
//#region ../types/dist/sleep-hmSP-eJt.mjs
|
|
6039
6042
|
/**
|
|
6040
6043
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6041
6044
|
* window to float samples (D455).
|
|
@@ -6152,7 +6155,7 @@ function isKeychainStoredField(field) {
|
|
|
6152
6155
|
var SECRET_CLEAR = { $secretClear: true };
|
|
6153
6156
|
/** The `'***'` token D634 redaction writes for non-admins. */
|
|
6154
6157
|
var LEGACY_DEVICE_REDACTION = "***";
|
|
6155
|
-
function isRecord$
|
|
6158
|
+
function isRecord$7(value) {
|
|
6156
6159
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6157
6160
|
}
|
|
6158
6161
|
function makeSecretMarker(ref) {
|
|
@@ -6163,12 +6166,12 @@ function makeSecretMarker(ref) {
|
|
|
6163
6166
|
}
|
|
6164
6167
|
/** A stored marker: an object whose `$secret` is a non-empty string. */
|
|
6165
6168
|
function isSecretMarker(value) {
|
|
6166
|
-
if (!isRecord$
|
|
6169
|
+
if (!isRecord$7(value)) return false;
|
|
6167
6170
|
const ref = value["$secret"];
|
|
6168
6171
|
return typeof ref === "string" && ref.length > 0;
|
|
6169
6172
|
}
|
|
6170
6173
|
function isSecretClear(value) {
|
|
6171
|
-
return isRecord$
|
|
6174
|
+
return isRecord$7(value) && value["$secretClear"] === true;
|
|
6172
6175
|
}
|
|
6173
6176
|
/**
|
|
6174
6177
|
* The UI view of a stored secret field value: a marker becomes "set", inline
|
|
@@ -6921,7 +6924,7 @@ var KeychainWriteRefusedError = class extends Error {
|
|
|
6921
6924
|
}
|
|
6922
6925
|
};
|
|
6923
6926
|
var KEEP = { kind: "keep" };
|
|
6924
|
-
function isRecord$
|
|
6927
|
+
function isRecord$6(value) {
|
|
6925
6928
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6926
6929
|
}
|
|
6927
6930
|
function defaultMintId() {
|
|
@@ -6934,7 +6937,7 @@ function collectSecretMarkerRefs(value, out = []) {
|
|
|
6934
6937
|
return out;
|
|
6935
6938
|
}
|
|
6936
6939
|
if (Array.isArray(value)) for (const item of value) collectSecretMarkerRefs(item, out);
|
|
6937
|
-
else if (isRecord$
|
|
6940
|
+
else if (isRecord$6(value)) for (const child of Object.values(value)) collectSecretMarkerRefs(child, out);
|
|
6938
6941
|
return out;
|
|
6939
6942
|
}
|
|
6940
6943
|
async function storedValueEquals(secrets, marker, candidate) {
|
|
@@ -6989,7 +6992,7 @@ function rowId(row, idKey) {
|
|
|
6989
6992
|
return null;
|
|
6990
6993
|
}
|
|
6991
6994
|
async function writeArray(ctx, node, incoming, stored, fieldPath) {
|
|
6992
|
-
const storedRows = Array.isArray(stored) ? stored.filter(isRecord$
|
|
6995
|
+
const storedRows = Array.isArray(stored) ? stored.filter(isRecord$6) : [];
|
|
6993
6996
|
if (!Array.isArray(incoming)) {
|
|
6994
6997
|
ctx.deletes.push(...collectSecretMarkerRefs(storedRows));
|
|
6995
6998
|
return {
|
|
@@ -7005,7 +7008,7 @@ async function writeArray(ctx, node, incoming, stored, fieldPath) {
|
|
|
7005
7008
|
const kept = /* @__PURE__ */ new Set();
|
|
7006
7009
|
const rows = [];
|
|
7007
7010
|
for (const row of incoming) {
|
|
7008
|
-
if (!isRecord$
|
|
7011
|
+
if (!isRecord$6(row)) {
|
|
7009
7012
|
rows.push(row);
|
|
7010
7013
|
continue;
|
|
7011
7014
|
}
|
|
@@ -7030,7 +7033,7 @@ async function writeNode(ctx, node, incoming, stored, fieldPath) {
|
|
|
7030
7033
|
case "leaf": return writeLeaf(ctx, incoming, stored, fieldPath);
|
|
7031
7034
|
case "array": return writeArray(ctx, node, incoming, stored, fieldPath);
|
|
7032
7035
|
case "object": {
|
|
7033
|
-
if (!isRecord$
|
|
7036
|
+
if (!isRecord$6(incoming)) {
|
|
7034
7037
|
if (incoming === void 0) return KEEP;
|
|
7035
7038
|
ctx.deletes.push(...collectSecretMarkerRefs(stored));
|
|
7036
7039
|
return {
|
|
@@ -7038,7 +7041,7 @@ async function writeNode(ctx, node, incoming, stored, fieldPath) {
|
|
|
7038
7041
|
value: incoming
|
|
7039
7042
|
};
|
|
7040
7043
|
}
|
|
7041
|
-
const storedObj = isRecord$
|
|
7044
|
+
const storedObj = isRecord$6(stored) ? stored : {};
|
|
7042
7045
|
return {
|
|
7043
7046
|
kind: "value",
|
|
7044
7047
|
value: await writeMembers(ctx, node.children, incoming, storedObj, (m) => `${fieldPath}.${m}`)
|
|
@@ -7161,7 +7164,7 @@ async function resolveSecretMarkers(value, secrets, options = {}) {
|
|
|
7161
7164
|
value: items
|
|
7162
7165
|
};
|
|
7163
7166
|
}
|
|
7164
|
-
if (isRecord$
|
|
7167
|
+
if (isRecord$6(v)) {
|
|
7165
7168
|
const out = {};
|
|
7166
7169
|
for (const [k, child] of Object.entries(v)) {
|
|
7167
7170
|
const s = substitute(child);
|
|
@@ -7193,7 +7196,7 @@ var SecretOverwriteRefusedError = class extends Error {
|
|
|
7193
7196
|
this.name = "SecretOverwriteRefusedError";
|
|
7194
7197
|
}
|
|
7195
7198
|
};
|
|
7196
|
-
function isRecord$
|
|
7199
|
+
function isRecord$5(value) {
|
|
7197
7200
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7198
7201
|
}
|
|
7199
7202
|
function resolvedValue(pass, marker) {
|
|
@@ -7222,7 +7225,7 @@ function inArray(pass, incoming, stored) {
|
|
|
7222
7225
|
return incoming.map((item, index) => {
|
|
7223
7226
|
const twin = stored[index];
|
|
7224
7227
|
if (isSecretMarker(twin)) return typeof item === "string" && item === resolvedValue(pass, twin) ? twin : item;
|
|
7225
|
-
if (isRecord$
|
|
7228
|
+
if (isRecord$5(item) && isRecord$5(twin)) return inArrayRow(pass, item, twin);
|
|
7226
7229
|
if (Array.isArray(item) && Array.isArray(twin)) return inArray(pass, item, twin);
|
|
7227
7230
|
return item;
|
|
7228
7231
|
});
|
|
@@ -7233,7 +7236,7 @@ function inArrayRow(pass, incoming, stored) {
|
|
|
7233
7236
|
const twin = stored[key];
|
|
7234
7237
|
if (isSecretMarker(twin)) {
|
|
7235
7238
|
if (typeof value === "string" && value === resolvedValue(pass, twin)) out[key] = twin;
|
|
7236
|
-
} else if (isRecord$
|
|
7239
|
+
} else if (isRecord$5(value) && isRecord$5(twin)) out[key] = inArrayRow(pass, value, twin);
|
|
7237
7240
|
else if (Array.isArray(value) && Array.isArray(twin)) out[key] = inArray(pass, value, twin);
|
|
7238
7241
|
}
|
|
7239
7242
|
return out;
|
|
@@ -7241,7 +7244,7 @@ function inArrayRow(pass, incoming, stored) {
|
|
|
7241
7244
|
async function walk(pass, incoming, stored) {
|
|
7242
7245
|
if (isSecretMarker(stored)) return atMarker(pass, incoming, stored);
|
|
7243
7246
|
if (Array.isArray(incoming) && Array.isArray(stored)) return inArray(pass, incoming, stored);
|
|
7244
|
-
if (!isRecord$
|
|
7247
|
+
if (!isRecord$5(incoming) || !isRecord$5(stored)) return incoming;
|
|
7245
7248
|
const out = { ...incoming };
|
|
7246
7249
|
for (const [key, value] of Object.entries(incoming)) out[key] = await walk(pass, value, stored[key]);
|
|
7247
7250
|
return out;
|
|
@@ -7272,7 +7275,7 @@ async function restoreUnchangedSecrets(input) {
|
|
|
7272
7275
|
function isJsonEqual(a, b) {
|
|
7273
7276
|
if (Object.is(a, b)) return true;
|
|
7274
7277
|
if (Array.isArray(a)) return Array.isArray(b) && a.length === b.length && a.every((v, i) => isJsonEqual(v, b[i]));
|
|
7275
|
-
if (isRecord$
|
|
7278
|
+
if (isRecord$5(a) && isRecord$5(b)) {
|
|
7276
7279
|
const keys = Object.keys(a);
|
|
7277
7280
|
if (keys.length !== Object.keys(b).length) return false;
|
|
7278
7281
|
return keys.every((k) => Object.prototype.hasOwnProperty.call(b, k) && isJsonEqual(a[k], b[k]));
|
|
@@ -7296,7 +7299,7 @@ function markerKeysOf(blob, owner) {
|
|
|
7296
7299
|
}
|
|
7297
7300
|
function nodeFromStored(value, owner) {
|
|
7298
7301
|
if (isSecretMarker(value)) return isSecretRefOwnedBy(value.$secret, owner) ? { kind: "leaf" } : null;
|
|
7299
|
-
if (!isRecord$
|
|
7302
|
+
if (!isRecord$5(value)) return null;
|
|
7300
7303
|
const children = /* @__PURE__ */ new Map();
|
|
7301
7304
|
for (const [key, child] of Object.entries(value)) {
|
|
7302
7305
|
const node = nodeFromStored(child, owner);
|
|
@@ -7915,6 +7918,44 @@ var BaseAddon = class {
|
|
|
7915
7918
|
return null;
|
|
7916
7919
|
}
|
|
7917
7920
|
/**
|
|
7921
|
+
* D986 scoped settings: the form shape of the CLUSTER-wide settings one capability this addon
|
|
7922
|
+
* provides owns, or `null` when it has none. `cap` is a capability name the addon's manifest
|
|
7923
|
+
* declares. Stored as `addon-settings` rows `<addonId>.<field>`. The keys of this schema, of
|
|
7924
|
+
* {@link nodeSettingsSchema} and of {@link deviceDefaultsSchema} are disjoint, and a key never
|
|
7925
|
+
* contains `@` (guard `check-scoped-settings-declared`). SHAPE only: values are read by scope.
|
|
7926
|
+
*/
|
|
7927
|
+
async clusterSettingsSchema(_cap) {
|
|
7928
|
+
return null;
|
|
7929
|
+
}
|
|
7930
|
+
/**
|
|
7931
|
+
* D986: the form shape of the settings one capability owns PER NODE, or `null`. Stored as
|
|
7932
|
+
* `addon-settings` rows `<addonId>.<field>@<nodeId>` carrying `nodeId` in the row data, so a
|
|
7933
|
+
* forgotten node's rows go in one central delete.
|
|
7934
|
+
*/
|
|
7935
|
+
async nodeSettingsSchema(_cap) {
|
|
7936
|
+
return null;
|
|
7937
|
+
}
|
|
7938
|
+
/**
|
|
7939
|
+
* D986: the form shape of the FLEET DEFAULTS of the per-device settings one capability owns,
|
|
7940
|
+
* or `null`. Stored as `addon-settings` rows `<addonId>.<field>`; a device resolves its value
|
|
7941
|
+
* as device row, then this default, then the schema default (`resolveDeviceSettings`).
|
|
7942
|
+
*/
|
|
7943
|
+
async deviceDefaultsSchema(_cap) {
|
|
7944
|
+
return null;
|
|
7945
|
+
}
|
|
7946
|
+
/**
|
|
7947
|
+
* The host's read of the scoped declarations: the schema one capability declares for `scope`,
|
|
7948
|
+
* or `null`. Beside {@link getIntegrationFormSchema}, the same shape: the hook is protected, the
|
|
7949
|
+
* host asks this method.
|
|
7950
|
+
*/
|
|
7951
|
+
async getScopedSettingsSchema(scope, cap) {
|
|
7952
|
+
switch (scope) {
|
|
7953
|
+
case "cluster": return this.clusterSettingsSchema(cap);
|
|
7954
|
+
case "node": return this.nodeSettingsSchema(cap);
|
|
7955
|
+
case "device-defaults": return this.deviceDefaultsSchema(cap);
|
|
7956
|
+
}
|
|
7957
|
+
}
|
|
7958
|
+
/**
|
|
7918
7959
|
* What the create wizard and the integration edit page render for one instance: the addon's
|
|
7919
7960
|
* per-instance schema when it declares one, else its global schema (what they always showed).
|
|
7920
7961
|
*/
|
|
@@ -8708,47 +8749,6 @@ function normalizeAddonInitResult(result) {
|
|
|
8708
8749
|
if (Array.isArray(result)) return { providers: result };
|
|
8709
8750
|
return result;
|
|
8710
8751
|
}
|
|
8711
|
-
/**
|
|
8712
|
-
* The share-view scope kinds a share-link token can carry. The hub mints
|
|
8713
|
-
* and validates them (`ShareViewGrantSchema` builds its
|
|
8714
|
-
* enum from this list); a data plane names the kinds it ACCEPTS in `share`.
|
|
8715
|
-
*/
|
|
8716
|
-
var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
|
|
8717
|
-
/** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
|
|
8718
|
-
var PeerBytesTicketSchema = object({
|
|
8719
|
-
/** `http://127.0.0.1:<port>/<token>`. One `GET` takes it. */
|
|
8720
|
-
url: string().min(1),
|
|
8721
|
-
/**
|
|
8722
|
-
* The HOST node this URL means something on — the hub or a named agent,
|
|
8723
|
-
* never a runner. {@link AddonPeerBytes.open} compares it to its own and
|
|
8724
|
-
* refuses `cross-node` by name when they differ, without dialling.
|
|
8725
|
-
*/
|
|
8726
|
-
hostNodeId: string().min(1),
|
|
8727
|
-
expiresAtMs: number$1().int().nonnegative(),
|
|
8728
|
-
/**
|
|
8729
|
-
* What the producer DECLARED the body to be, when it knows — `null` when it
|
|
8730
|
-
* does not. Never `0` for unknown (D393): a consumer sizing a bound off this
|
|
8731
|
-
* must be able to tell "the producer did not say" from "the body is empty".
|
|
8732
|
-
*/
|
|
8733
|
-
declaredBytes: number$1().int().nonnegative().nullable()
|
|
8734
|
-
});
|
|
8735
|
-
/** Limits and names of `ctx.records` (D881). One authority; the engine and the facade read it. */
|
|
8736
|
-
/** The files a kind may live in. `history` is device-history's (D850), never records. */
|
|
8737
|
-
var RECORD_DATABASES = ["settings", "events"];
|
|
8738
|
-
/** The classes of a kind: the `@durable` vocabulary, one authority (replaces the annotation). */
|
|
8739
|
-
var RECORD_CLASSES = [
|
|
8740
|
-
"config",
|
|
8741
|
-
"ledger",
|
|
8742
|
-
"audit",
|
|
8743
|
-
"mirror",
|
|
8744
|
-
"ephemeral"
|
|
8745
|
-
];
|
|
8746
|
-
var RECORD_DEFAULT_MAX_DATA_BYTES = 64 * 1024;
|
|
8747
|
-
var RECORD_MAX_DATA_BYTES = 1024 * 1024;
|
|
8748
|
-
var RECORD_BATCH_MAX = 1e3;
|
|
8749
|
-
var RECORD_QUERY_MAX = 1e3;
|
|
8750
|
-
/** A kind in the `settings` file may not bound itself above this (D447: high volume is `events`). */
|
|
8751
|
-
var RECORD_SETTINGS_MAX_ROWS = 5e4;
|
|
8752
8752
|
var PREFIX = "records/";
|
|
8753
8753
|
/** The base of every records failure. `detail` is the human part of the message. */
|
|
8754
8754
|
var RecordsError = class extends Error {
|
|
@@ -8781,6 +8781,83 @@ var DeclarationRefusedError = class extends RecordsError {
|
|
|
8781
8781
|
this.name = "DeclarationRefusedError";
|
|
8782
8782
|
}
|
|
8783
8783
|
};
|
|
8784
|
+
/** Limits and names of `ctx.records` (D881). One authority; the engine and the facade read it. */
|
|
8785
|
+
/** The files a kind may live in. `history` is device-history's (D850), never records. */
|
|
8786
|
+
var RECORD_DATABASES = ["settings", "events"];
|
|
8787
|
+
/** The classes of a kind: the `@durable` vocabulary, one authority (replaces the annotation). */
|
|
8788
|
+
var RECORD_CLASSES = [
|
|
8789
|
+
"config",
|
|
8790
|
+
"ledger",
|
|
8791
|
+
"audit",
|
|
8792
|
+
"mirror",
|
|
8793
|
+
"ephemeral"
|
|
8794
|
+
];
|
|
8795
|
+
var RECORD_DEFAULT_MAX_DATA_BYTES = 64 * 1024;
|
|
8796
|
+
var RECORD_MAX_DATA_BYTES = 1024 * 1024;
|
|
8797
|
+
var RECORD_BATCH_MAX = 1e3;
|
|
8798
|
+
var RECORD_QUERY_MAX = 1e3;
|
|
8799
|
+
/** A kind in the `settings` file may not bound itself above this (D447: high volume is `events`). */
|
|
8800
|
+
var RECORD_SETTINGS_MAX_ROWS = 5e4;
|
|
8801
|
+
/**
|
|
8802
|
+
* Secret fields of a record, addressed the way a Zod schema declares them
|
|
8803
|
+
* (`collectZodSecretPaths`): dotted keys, `[]` for "each element of this array"
|
|
8804
|
+
* (`auth.accessToken`, `headers[].value`).
|
|
8805
|
+
*
|
|
8806
|
+
* Array elements are matched by a DECLARED id key (`secretArrayKeys`:
|
|
8807
|
+
* `{ headers: 'name' }`), never by index, so reordering a list keeps every
|
|
8808
|
+
* keychain ref (the same rule as `arrayItemFieldPath`). The concrete path of a
|
|
8809
|
+
* leaf names its element: `headers[X-Api].value`.
|
|
8810
|
+
*
|
|
8811
|
+
* Pure and browser-safe. Nothing here mutates: every transform returns a new value.
|
|
8812
|
+
*/
|
|
8813
|
+
/** The array prefixes (declared form, e.g. `headers` or `a.headers`) of a path. */
|
|
8814
|
+
function parseSecretPath(path) {
|
|
8815
|
+
if (path.length === 0) throw new InvalidRecordError("an empty secret path");
|
|
8816
|
+
return path.split(".").map((raw) => {
|
|
8817
|
+
const each = raw.endsWith("[]");
|
|
8818
|
+
const key = each ? raw.slice(0, -2) : raw;
|
|
8819
|
+
if (key.length === 0) throw new InvalidRecordError(`secret path "${path}" has an empty segment`);
|
|
8820
|
+
return {
|
|
8821
|
+
key,
|
|
8822
|
+
each
|
|
8823
|
+
};
|
|
8824
|
+
});
|
|
8825
|
+
}
|
|
8826
|
+
/** The declared array prefixes of `path` that need an id key (`headers`, `a.rows`). */
|
|
8827
|
+
function secretArrayPrefixes(path) {
|
|
8828
|
+
const segments = parseSecretPath(path);
|
|
8829
|
+
const prefixes = [];
|
|
8830
|
+
const walked = [];
|
|
8831
|
+
for (const segment of segments) {
|
|
8832
|
+
walked.push(segment.key);
|
|
8833
|
+
if (segment.each) prefixes.push(walked.join("."));
|
|
8834
|
+
}
|
|
8835
|
+
return prefixes;
|
|
8836
|
+
}
|
|
8837
|
+
/**
|
|
8838
|
+
* The share-view scope kinds a share-link token can carry. The hub mints
|
|
8839
|
+
* and validates them (`ShareViewGrantSchema` builds its
|
|
8840
|
+
* enum from this list); a data plane names the kinds it ACCEPTS in `share`.
|
|
8841
|
+
*/
|
|
8842
|
+
var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
|
|
8843
|
+
/** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
|
|
8844
|
+
var PeerBytesTicketSchema = object({
|
|
8845
|
+
/** `http://127.0.0.1:<port>/<token>`. One `GET` takes it. */
|
|
8846
|
+
url: string().min(1),
|
|
8847
|
+
/**
|
|
8848
|
+
* The HOST node this URL means something on — the hub or a named agent,
|
|
8849
|
+
* never a runner. {@link AddonPeerBytes.open} compares it to its own and
|
|
8850
|
+
* refuses `cross-node` by name when they differ, without dialling.
|
|
8851
|
+
*/
|
|
8852
|
+
hostNodeId: string().min(1),
|
|
8853
|
+
expiresAtMs: number$1().int().nonnegative(),
|
|
8854
|
+
/**
|
|
8855
|
+
* What the producer DECLARED the body to be, when it knows — `null` when it
|
|
8856
|
+
* does not. Never `0` for unknown (D393): a consumer sizing a bound off this
|
|
8857
|
+
* must be able to tell "the producer did not say" from "the body is empty".
|
|
8858
|
+
*/
|
|
8859
|
+
declaredBytes: number$1().int().nonnegative().nullable()
|
|
8860
|
+
});
|
|
8784
8861
|
function defOf(schema) {
|
|
8785
8862
|
const zodBag = Reflect.get(schema, "_zod");
|
|
8786
8863
|
if (typeof zodBag !== "object" || zodBag === null) return {};
|
|
@@ -8849,42 +8926,6 @@ function collectZodSecretPaths(schema, prefix = "") {
|
|
|
8849
8926
|
return [...new Set(paths)];
|
|
8850
8927
|
}
|
|
8851
8928
|
/**
|
|
8852
|
-
* Secret fields of a record, addressed the way a Zod schema declares them
|
|
8853
|
-
* (`collectZodSecretPaths`): dotted keys, `[]` for "each element of this array"
|
|
8854
|
-
* (`auth.accessToken`, `headers[].value`).
|
|
8855
|
-
*
|
|
8856
|
-
* Array elements are matched by a DECLARED id key (`secretArrayKeys`:
|
|
8857
|
-
* `{ headers: 'name' }`), never by index, so reordering a list keeps every
|
|
8858
|
-
* keychain ref (the same rule as `arrayItemFieldPath`). The concrete path of a
|
|
8859
|
-
* leaf names its element: `headers[X-Api].value`.
|
|
8860
|
-
*
|
|
8861
|
-
* Pure and browser-safe. Nothing here mutates: every transform returns a new value.
|
|
8862
|
-
*/
|
|
8863
|
-
/** The array prefixes (declared form, e.g. `headers` or `a.headers`) of a path. */
|
|
8864
|
-
function parseSecretPath(path) {
|
|
8865
|
-
if (path.length === 0) throw new InvalidRecordError("an empty secret path");
|
|
8866
|
-
return path.split(".").map((raw) => {
|
|
8867
|
-
const each = raw.endsWith("[]");
|
|
8868
|
-
const key = each ? raw.slice(0, -2) : raw;
|
|
8869
|
-
if (key.length === 0) throw new InvalidRecordError(`secret path "${path}" has an empty segment`);
|
|
8870
|
-
return {
|
|
8871
|
-
key,
|
|
8872
|
-
each
|
|
8873
|
-
};
|
|
8874
|
-
});
|
|
8875
|
-
}
|
|
8876
|
-
/** The declared array prefixes of `path` that need an id key (`headers`, `a.rows`). */
|
|
8877
|
-
function secretArrayPrefixes(path) {
|
|
8878
|
-
const segments = parseSecretPath(path);
|
|
8879
|
-
const prefixes = [];
|
|
8880
|
-
const walked = [];
|
|
8881
|
-
for (const segment of segments) {
|
|
8882
|
-
walked.push(segment.key);
|
|
8883
|
-
if (segment.each) prefixes.push(walked.join("."));
|
|
8884
|
-
}
|
|
8885
|
-
return prefixes;
|
|
8886
|
-
}
|
|
8887
|
-
/**
|
|
8888
8929
|
* Record kinds (D881): the declaration an addon makes of one kind of fact, the
|
|
8889
8930
|
* Zod row schema that describes it, and the helper that turns the two into the
|
|
8890
8931
|
* JSON the engine stores.
|
|
@@ -9724,6 +9765,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9724
9765
|
"backup",
|
|
9725
9766
|
"battery",
|
|
9726
9767
|
"binary",
|
|
9768
|
+
"board-key-source",
|
|
9727
9769
|
"brightness",
|
|
9728
9770
|
"broker",
|
|
9729
9771
|
"button",
|
|
@@ -9787,6 +9829,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9787
9829
|
"humidity-sensor",
|
|
9788
9830
|
"image",
|
|
9789
9831
|
"image-settings",
|
|
9832
|
+
"integration-instances",
|
|
9790
9833
|
"integrations",
|
|
9791
9834
|
"intercom",
|
|
9792
9835
|
"ir-transmitter",
|
|
@@ -9844,6 +9887,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9844
9887
|
"privacy-mask",
|
|
9845
9888
|
"ptz",
|
|
9846
9889
|
"ptz-autotrack",
|
|
9890
|
+
"pump-cycle",
|
|
9847
9891
|
"reboot",
|
|
9848
9892
|
"record-entries",
|
|
9849
9893
|
"recording",
|
|
@@ -11136,18 +11180,6 @@ Object.freeze({
|
|
|
11136
11180
|
"path": "pumpRunning",
|
|
11137
11181
|
"valueType": "boolean"
|
|
11138
11182
|
},
|
|
11139
|
-
{
|
|
11140
|
-
"path": "pumpIntervalEnabled",
|
|
11141
|
-
"valueType": "boolean"
|
|
11142
|
-
},
|
|
11143
|
-
{
|
|
11144
|
-
"path": "pumpOnTime",
|
|
11145
|
-
"valueType": "number"
|
|
11146
|
-
},
|
|
11147
|
-
{
|
|
11148
|
-
"path": "pumpOffTime",
|
|
11149
|
-
"valueType": "number"
|
|
11150
|
-
},
|
|
11151
11183
|
{
|
|
11152
11184
|
"path": "lastDrink",
|
|
11153
11185
|
"valueType": "number"
|
|
@@ -11271,6 +11303,20 @@ Object.freeze({
|
|
|
11271
11303
|
"valueType": "number"
|
|
11272
11304
|
}
|
|
11273
11305
|
],
|
|
11306
|
+
"pump-cycle": [
|
|
11307
|
+
{
|
|
11308
|
+
"path": "enabled",
|
|
11309
|
+
"valueType": "boolean"
|
|
11310
|
+
},
|
|
11311
|
+
{
|
|
11312
|
+
"path": "onTime",
|
|
11313
|
+
"valueType": "number"
|
|
11314
|
+
},
|
|
11315
|
+
{
|
|
11316
|
+
"path": "offTime",
|
|
11317
|
+
"valueType": "number"
|
|
11318
|
+
}
|
|
11319
|
+
],
|
|
11274
11320
|
"recording-archive": [
|
|
11275
11321
|
{
|
|
11276
11322
|
"path": "deviceId",
|
|
@@ -11720,7 +11766,7 @@ object({
|
|
|
11720
11766
|
params: record(string(), union([string(), number$1()])).optional()
|
|
11721
11767
|
});
|
|
11722
11768
|
//#endregion
|
|
11723
|
-
//#region ../types/dist/composition-
|
|
11769
|
+
//#region ../types/dist/composition-Dh3RfMx5.mjs
|
|
11724
11770
|
/**
|
|
11725
11771
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11726
11772
|
*
|
|
@@ -12934,6 +12980,73 @@ var NodeColorIdSchema = _enum([
|
|
|
12934
12980
|
"node-g",
|
|
12935
12981
|
"node-h"
|
|
12936
12982
|
]);
|
|
12983
|
+
//#endregion
|
|
12984
|
+
//#region ../types/dist/index.mjs
|
|
12985
|
+
var SMTP_INBOUND_DEFAULT_PORT = 2525;
|
|
12986
|
+
var SMTP_INBOUND_DEFAULT_DOMAIN = "camstack.local";
|
|
12987
|
+
var SMTP_INBOUND_DEFAULT_MAX_MESSAGE_BYTES = 25 * 1024 * 1024;
|
|
12988
|
+
/** The text excerpt a message carries on the bus. */
|
|
12989
|
+
var SMTP_INBOUND_TEXT_MAX_CHARS = 4096;
|
|
12990
|
+
var PortSchema = number$1().int().min(1).max(65535);
|
|
12991
|
+
/** A recipient local-part: what stands before the `@`. */
|
|
12992
|
+
var SmtpRecipientSchema = string().min(1).max(64).regex(/^[A-Za-z0-9._+-]+$/);
|
|
12993
|
+
object({
|
|
12994
|
+
port: PortSchema.default(SMTP_INBOUND_DEFAULT_PORT),
|
|
12995
|
+
bindHost: string().min(1).default("0.0.0.0"),
|
|
12996
|
+
domain: string().min(1).default(SMTP_INBOUND_DEFAULT_DOMAIN),
|
|
12997
|
+
requireAuth: boolean().default(true),
|
|
12998
|
+
username: string().default(""),
|
|
12999
|
+
password: string().default("").meta({ secret: true }),
|
|
13000
|
+
starttls: boolean().default(false),
|
|
13001
|
+
maxMessageBytes: number$1().int().positive().default(SMTP_INBOUND_DEFAULT_MAX_MESSAGE_BYTES)
|
|
13002
|
+
});
|
|
13003
|
+
object({
|
|
13004
|
+
host: string().min(1).nullable(),
|
|
13005
|
+
hostReason: string().nullable(),
|
|
13006
|
+
port: PortSchema,
|
|
13007
|
+
domain: string().min(1),
|
|
13008
|
+
requireAuth: boolean(),
|
|
13009
|
+
username: string(),
|
|
13010
|
+
password: string(),
|
|
13011
|
+
starttls: boolean()
|
|
13012
|
+
});
|
|
13013
|
+
object({
|
|
13014
|
+
recipients: array(SmtpRecipientSchema).min(1),
|
|
13015
|
+
/**
|
|
13016
|
+
* Who is subscribing. A second `subscribe` with the same id REPLACES that subscriber's
|
|
13017
|
+
* recipients (the way a consumer that restarted, or lost a device, declares its set again);
|
|
13018
|
+
* a recipient held by another subscriber is refused with `smtp-inbound/recipient-claimed`.
|
|
13019
|
+
* Absent, the subscriber is anonymous and unique.
|
|
13020
|
+
*/
|
|
13021
|
+
subscriberId: string().min(1).max(64).optional()
|
|
13022
|
+
});
|
|
13023
|
+
var SmtpInboundAttachmentSchema = object({
|
|
13024
|
+
filename: string(),
|
|
13025
|
+
contentType: string(),
|
|
13026
|
+
bytes: number$1().int().nonnegative()
|
|
13027
|
+
});
|
|
13028
|
+
/** The payload of one `broker.message` (the key is the recipient local-part). */
|
|
13029
|
+
var SmtpInboundMessageSchema = object({
|
|
13030
|
+
/** Monotonic per mailbox; a gap tells a consumer it missed an event. */
|
|
13031
|
+
seq: number$1().int().positive(),
|
|
13032
|
+
messageId: string(),
|
|
13033
|
+
receivedAt: number$1().int().nonnegative(),
|
|
13034
|
+
from: string(),
|
|
13035
|
+
to: string(),
|
|
13036
|
+
subject: string(),
|
|
13037
|
+
text: string().max(SMTP_INBOUND_TEXT_MAX_CHARS),
|
|
13038
|
+
attachments: array(SmtpInboundAttachmentSchema)
|
|
13039
|
+
});
|
|
13040
|
+
object({
|
|
13041
|
+
/** The newest seq issued so far (0 before any mail). */
|
|
13042
|
+
lastSeq: number$1().int().nonnegative(),
|
|
13043
|
+
/** The oldest seq still retained; messages below it are gone. */
|
|
13044
|
+
oldestSeq: number$1().int().nonnegative(),
|
|
13045
|
+
messages: array(object({
|
|
13046
|
+
key: string(),
|
|
13047
|
+
message: SmtpInboundMessageSchema
|
|
13048
|
+
}))
|
|
13049
|
+
});
|
|
12937
13050
|
new Set([
|
|
12938
13051
|
"track",
|
|
12939
13052
|
"face",
|
|
@@ -16093,8 +16206,18 @@ var LogChannelDescriptorSchema = object({
|
|
|
16093
16206
|
* the operator narrows to one camera, sees nothing, and concludes the code
|
|
16094
16207
|
* path was never taken.
|
|
16095
16208
|
*/
|
|
16096
|
-
perDevice: boolean()
|
|
16097
|
-
|
|
16209
|
+
perDevice: boolean(),
|
|
16210
|
+
/**
|
|
16211
|
+
* What the channel is FOR, so the UI can list the channels an addon offers.
|
|
16212
|
+
*
|
|
16213
|
+
* - `diagnostic` (the default): a per-component diagnostic armed from the
|
|
16214
|
+
* Levels page, emitted at its declared level.
|
|
16215
|
+
* - `debug`: a `debug.<channel>` dump watched live for a short window
|
|
16216
|
+
* (`ctx.debug`). Always per-device, and its lines are denied by the log
|
|
16217
|
+
* ring unless somebody is watching that device.
|
|
16218
|
+
*/
|
|
16219
|
+
kind: _enum(["diagnostic", "debug"]).default("diagnostic")
|
|
16220
|
+
}).refine((d) => d.kind !== "debug" || d.name.startsWith("debug.") && d.perDevice, { message: "a debug channel is named debug.<channel> and is per-device" });
|
|
16098
16221
|
/**
|
|
16099
16222
|
* An armed window over one channel, as the document hands it to a mirror.
|
|
16100
16223
|
*
|
|
@@ -19312,56 +19435,6 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
19312
19435
|
icon: "square",
|
|
19313
19436
|
args: { on: false }
|
|
19314
19437
|
},
|
|
19315
|
-
{
|
|
19316
|
-
id: "petFountain.intervalOn",
|
|
19317
|
-
method: "setPumpInterval",
|
|
19318
|
-
label: t("Pump cycle on", "Ciclo pompa attivo"),
|
|
19319
|
-
phrase: t("Run the pump of {device} on its on/off cycle", "Fai lavorare la pompa di {device} a ciclo acceso/spento"),
|
|
19320
|
-
icon: "timer",
|
|
19321
|
-
args: { on: true }
|
|
19322
|
-
},
|
|
19323
|
-
{
|
|
19324
|
-
id: "petFountain.intervalOff",
|
|
19325
|
-
method: "setPumpInterval",
|
|
19326
|
-
label: t("Pump cycle off", "Ciclo pompa spento"),
|
|
19327
|
-
phrase: t("Run the pump of {device} continuously", "Fai lavorare la pompa di {device} in continuo"),
|
|
19328
|
-
icon: "timer-off",
|
|
19329
|
-
args: { on: false }
|
|
19330
|
-
},
|
|
19331
|
-
{
|
|
19332
|
-
id: "petFountain.pumpOnMinutes",
|
|
19333
|
-
method: "setPumpOnMinutes",
|
|
19334
|
-
label: t("Set pump run time", "Imposta il tempo di lavoro della pompa"),
|
|
19335
|
-
phrase: t("Set the pump of {device} to run {minutes} minutes per cycle", "Imposta la pompa di {device} a lavorare {minutes} minuti per ciclo"),
|
|
19336
|
-
icon: "timer",
|
|
19337
|
-
openArgs: [{
|
|
19338
|
-
key: "minutes",
|
|
19339
|
-
label: t("Minutes", "Minuti"),
|
|
19340
|
-
offer: {
|
|
19341
|
-
kind: "number",
|
|
19342
|
-
min: 0,
|
|
19343
|
-
step: 1,
|
|
19344
|
-
unit: "min"
|
|
19345
|
-
}
|
|
19346
|
-
}]
|
|
19347
|
-
},
|
|
19348
|
-
{
|
|
19349
|
-
id: "petFountain.pumpOffMinutes",
|
|
19350
|
-
method: "setPumpOffMinutes",
|
|
19351
|
-
label: t("Set pump rest time", "Imposta il tempo di riposo della pompa"),
|
|
19352
|
-
phrase: t("Set the pump of {device} to rest {minutes} minutes per cycle", "Imposta la pompa di {device} a riposare {minutes} minuti per ciclo"),
|
|
19353
|
-
icon: "timer-off",
|
|
19354
|
-
openArgs: [{
|
|
19355
|
-
key: "minutes",
|
|
19356
|
-
label: t("Minutes", "Minuti"),
|
|
19357
|
-
offer: {
|
|
19358
|
-
kind: "number",
|
|
19359
|
-
min: 0,
|
|
19360
|
-
step: 1,
|
|
19361
|
-
unit: "min"
|
|
19362
|
-
}
|
|
19363
|
-
}]
|
|
19364
|
-
},
|
|
19365
19438
|
{
|
|
19366
19439
|
id: "petFountain.resetDailyConsumption",
|
|
19367
19440
|
method: "resetDailyConsumption",
|
|
@@ -19386,6 +19459,70 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
19386
19459
|
icon: "droplets"
|
|
19387
19460
|
}]
|
|
19388
19461
|
},
|
|
19462
|
+
"pump-cycle": {
|
|
19463
|
+
scope: "device",
|
|
19464
|
+
noun: t("Pump cycle", "Ciclo della pompa"),
|
|
19465
|
+
actions: [
|
|
19466
|
+
{
|
|
19467
|
+
id: "pumpCycle.on",
|
|
19468
|
+
method: "setEnabled",
|
|
19469
|
+
label: t("Pump cycle on", "Ciclo pompa attivo"),
|
|
19470
|
+
phrase: t("Run the pump of {device} on its on/off cycle", "Fai lavorare la pompa di {device} a ciclo acceso/spento"),
|
|
19471
|
+
icon: "timer",
|
|
19472
|
+
args: { on: true }
|
|
19473
|
+
},
|
|
19474
|
+
{
|
|
19475
|
+
id: "pumpCycle.off",
|
|
19476
|
+
method: "setEnabled",
|
|
19477
|
+
label: t("Pump cycle off", "Ciclo pompa spento"),
|
|
19478
|
+
phrase: t("Run the pump of {device} continuously", "Fai lavorare la pompa di {device} in continuo"),
|
|
19479
|
+
icon: "timer-off",
|
|
19480
|
+
args: { on: false }
|
|
19481
|
+
},
|
|
19482
|
+
{
|
|
19483
|
+
id: "pumpCycle.onMinutes",
|
|
19484
|
+
method: "setOnMinutes",
|
|
19485
|
+
label: t("Set pump run time", "Imposta il tempo di lavoro della pompa"),
|
|
19486
|
+
phrase: t("Set the pump of {device} to run {minutes} minutes per cycle", "Imposta la pompa di {device} a lavorare {minutes} minuti per ciclo"),
|
|
19487
|
+
icon: "timer",
|
|
19488
|
+
openArgs: [{
|
|
19489
|
+
key: "minutes",
|
|
19490
|
+
label: t("Minutes", "Minuti"),
|
|
19491
|
+
offer: {
|
|
19492
|
+
kind: "number",
|
|
19493
|
+
min: 0,
|
|
19494
|
+
step: 1,
|
|
19495
|
+
unit: "min"
|
|
19496
|
+
}
|
|
19497
|
+
}]
|
|
19498
|
+
},
|
|
19499
|
+
{
|
|
19500
|
+
id: "pumpCycle.offMinutes",
|
|
19501
|
+
method: "setOffMinutes",
|
|
19502
|
+
label: t("Set pump rest time", "Imposta il tempo di riposo della pompa"),
|
|
19503
|
+
phrase: t("Set the pump of {device} to rest {minutes} minutes per cycle", "Imposta la pompa di {device} a riposare {minutes} minuti per ciclo"),
|
|
19504
|
+
icon: "timer-off",
|
|
19505
|
+
openArgs: [{
|
|
19506
|
+
key: "minutes",
|
|
19507
|
+
label: t("Minutes", "Minuti"),
|
|
19508
|
+
offer: {
|
|
19509
|
+
kind: "number",
|
|
19510
|
+
min: 0,
|
|
19511
|
+
step: 1,
|
|
19512
|
+
unit: "min"
|
|
19513
|
+
}
|
|
19514
|
+
}]
|
|
19515
|
+
}
|
|
19516
|
+
],
|
|
19517
|
+
state: [{
|
|
19518
|
+
kind: "boolean",
|
|
19519
|
+
field: "enabled",
|
|
19520
|
+
label: t("Pump cycle", "Ciclo pompa"),
|
|
19521
|
+
whenTrue: t("When {device} starts running its pump on a cycle", "Quando {device} inizia a far lavorare la pompa a ciclo"),
|
|
19522
|
+
whenFalse: t("When {device} runs its pump continuously", "Quando {device} fa lavorare la pompa in continuo"),
|
|
19523
|
+
icon: "timer"
|
|
19524
|
+
}]
|
|
19525
|
+
},
|
|
19389
19526
|
"media-player": {
|
|
19390
19527
|
scope: "device",
|
|
19391
19528
|
noun: t("Media player", "Lettore multimediale"),
|
|
@@ -21276,6 +21413,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
21276
21413
|
"audio-analyzer": system(PIPELINE),
|
|
21277
21414
|
"audio-codec": system(INTERNAL),
|
|
21278
21415
|
"auth-provider": system(IDENTITY),
|
|
21416
|
+
"board-key-source": system(INTERNAL),
|
|
21279
21417
|
backup: system("system backups — run and restored from the Backups page"),
|
|
21280
21418
|
broker: system("message-broker connections — configured, not actuated"),
|
|
21281
21419
|
"calendar-source": system(INTERNAL),
|
|
@@ -21310,6 +21448,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
21310
21448
|
"load-contribution": system(INTERNAL),
|
|
21311
21449
|
"local-network": system(NETWORK),
|
|
21312
21450
|
"log-channels": system(INTERNAL),
|
|
21451
|
+
"integration-instances": system(INTERNAL),
|
|
21313
21452
|
"log-destination": system(INTERNAL),
|
|
21314
21453
|
"login-method": system(IDENTITY),
|
|
21315
21454
|
"mesh-network": system(NETWORK),
|
|
@@ -43516,7 +43655,7 @@ var TargetKindCapsSchema = object({
|
|
|
43516
43655
|
* the union is large and not meant for runtime validation here; the exported
|
|
43517
43656
|
* `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
|
|
43518
43657
|
*/
|
|
43519
|
-
var ConfigSchemaPassthrough$
|
|
43658
|
+
var ConfigSchemaPassthrough$4 = unknown();
|
|
43520
43659
|
var TargetKindSchema = object({
|
|
43521
43660
|
kind: string(),
|
|
43522
43661
|
label: string(),
|
|
@@ -43553,7 +43692,7 @@ var TargetKindSchema = object({
|
|
|
43553
43692
|
* its raster path, which is the safe default for an unknown image.
|
|
43554
43693
|
*/
|
|
43555
43694
|
iconMediaType: string().optional(),
|
|
43556
|
-
configSchema: ConfigSchemaPassthrough$
|
|
43695
|
+
configSchema: ConfigSchemaPassthrough$4,
|
|
43557
43696
|
/**
|
|
43558
43697
|
* The config keys that decide WHERE this kind's secrets are sent (server,
|
|
43559
43698
|
* base URL, instance, chat, recipient). A save that changes any of them
|
|
@@ -46225,6 +46364,49 @@ var binaryCapability = {
|
|
|
46225
46364
|
volatileStateFields: ["lastChangedAt"]
|
|
46226
46365
|
};
|
|
46227
46366
|
/**
|
|
46367
|
+
* Why a board key could not be read. Typed so a caller reports the cause and
|
|
46368
|
+
* never treats "could not read" as "has no key" (D49).
|
|
46369
|
+
*/
|
|
46370
|
+
var BoardKeyFailureReasonSchema = _enum([
|
|
46371
|
+
"unknown-source",
|
|
46372
|
+
"not-admin",
|
|
46373
|
+
"no-builder",
|
|
46374
|
+
"no-ingress-url",
|
|
46375
|
+
"unreachable",
|
|
46376
|
+
"unknown-board",
|
|
46377
|
+
"no-encryption-key",
|
|
46378
|
+
"unreadable-config"
|
|
46379
|
+
]);
|
|
46380
|
+
var BoardKeySourceSchema = object({
|
|
46381
|
+
sourceId: string(),
|
|
46382
|
+
name: string()
|
|
46383
|
+
});
|
|
46384
|
+
var BoardKeyBoardSchema = object({
|
|
46385
|
+
/** The builder's file name, e.g. `kitchen.yaml`: the handle `getBoardKey` takes. */
|
|
46386
|
+
configuration: string(),
|
|
46387
|
+
/** The node name the builder gives the board. */
|
|
46388
|
+
name: string(),
|
|
46389
|
+
/** The address the builder knows the board by, when it has one. */
|
|
46390
|
+
address: string().nullable()
|
|
46391
|
+
});
|
|
46392
|
+
var BoardKeyFailureSchema = object({
|
|
46393
|
+
ok: literal(false),
|
|
46394
|
+
reason: BoardKeyFailureReasonSchema,
|
|
46395
|
+
detail: string().optional()
|
|
46396
|
+
});
|
|
46397
|
+
var ListBoardsResultSchema = discriminatedUnion("ok", [object({
|
|
46398
|
+
ok: literal(true),
|
|
46399
|
+
boards: array(BoardKeyBoardSchema).readonly()
|
|
46400
|
+
}), BoardKeyFailureSchema]);
|
|
46401
|
+
var GetBoardKeyResultSchema = discriminatedUnion("ok", [object({
|
|
46402
|
+
ok: literal(true),
|
|
46403
|
+
key: string()
|
|
46404
|
+
}), BoardKeyFailureSchema]);
|
|
46405
|
+
method(_void(), array(BoardKeySourceSchema).readonly(), { auth: "admin" }), method(object({ sourceId: string().min(1) }), ListBoardsResultSchema, { auth: "admin" }), method(object({
|
|
46406
|
+
sourceId: string().min(1),
|
|
46407
|
+
configuration: string().min(1)
|
|
46408
|
+
}), GetBoardKeyResultSchema, { auth: "admin" });
|
|
46409
|
+
/**
|
|
46228
46410
|
* Dimmable-light brightness control. Co-exists with `switch` on the
|
|
46229
46411
|
* same device — the switch toggles on/off, this cap sets the level
|
|
46230
46412
|
* applied when the light is on. Drivers map their per-vendor dim
|
|
@@ -51258,6 +51440,45 @@ var deviceProviderCapability = {
|
|
|
51258
51440
|
}
|
|
51259
51441
|
};
|
|
51260
51442
|
/**
|
|
51443
|
+
* What the passive listener of `local-network` saw on the wire, before any
|
|
51444
|
+
* provider classified it. Device-manager turns an observation into the hits
|
|
51445
|
+
* of the providers whose declared discovery modes it matches.
|
|
51446
|
+
*/
|
|
51447
|
+
var DiscoveryObservationSchema = discriminatedUnion("kind", [object({
|
|
51448
|
+
kind: literal("mdns"),
|
|
51449
|
+
/** Normalised DNS-SD service type, e.g. `_esphomelib._tcp`. */
|
|
51450
|
+
serviceType: string(),
|
|
51451
|
+
instance: string(),
|
|
51452
|
+
host: string(),
|
|
51453
|
+
/** The A record address when the announcement carried one. */
|
|
51454
|
+
address: string().nullable(),
|
|
51455
|
+
port: number$1().int(),
|
|
51456
|
+
txt: record(string(), string())
|
|
51457
|
+
}), object({
|
|
51458
|
+
kind: literal("ssdp"),
|
|
51459
|
+
/** Sender address of the datagram. */
|
|
51460
|
+
host: string(),
|
|
51461
|
+
port: number$1().int(),
|
|
51462
|
+
/** `NT` of a NOTIFY, `ST` of a search response. */
|
|
51463
|
+
target: string(),
|
|
51464
|
+
headers: record(string(), string())
|
|
51465
|
+
})]);
|
|
51466
|
+
object({
|
|
51467
|
+
addonId: string(),
|
|
51468
|
+
candidate: DiscoveryCandidateSchema,
|
|
51469
|
+
firstSeenAt: number$1(),
|
|
51470
|
+
lastSeenAt: number$1(),
|
|
51471
|
+
dismissed: boolean()
|
|
51472
|
+
});
|
|
51473
|
+
var DiscoveryProposalSchema = object({
|
|
51474
|
+
id: string(),
|
|
51475
|
+
addonId: string(),
|
|
51476
|
+
candidate: DiscoveryCandidateSchema,
|
|
51477
|
+
firstSeenAt: number$1(),
|
|
51478
|
+
lastSeenAt: number$1(),
|
|
51479
|
+
dismissed: boolean()
|
|
51480
|
+
});
|
|
51481
|
+
/**
|
|
51261
51482
|
* Device Manager capability — hub-side singleton that unifies device persistence,
|
|
51262
51483
|
* live registry access, and all management operations into a single tRPC surface.
|
|
51263
51484
|
*
|
|
@@ -51986,6 +52207,19 @@ method(object({
|
|
|
51986
52207
|
}), object({ candidates: array(DiscoveryCandidateSchema).readonly() }), {
|
|
51987
52208
|
kind: "mutation",
|
|
51988
52209
|
auth: "admin"
|
|
52210
|
+
}), method(object({}), object({ proposals: array(DiscoveryProposalSchema).readonly() }), { auth: "admin" }), method(object({ id: string() }), object({ dismissed: boolean() }), {
|
|
52211
|
+
kind: "mutation",
|
|
52212
|
+
auth: "admin"
|
|
52213
|
+
}), method(object({ observations: array(DiscoveryObservationSchema).max(512) }), object({ proposed: number$1().int() }), {
|
|
52214
|
+
kind: "mutation",
|
|
52215
|
+
auth: "admin"
|
|
52216
|
+
}), method(object({}), object({
|
|
52217
|
+
providers: number$1().int(),
|
|
52218
|
+
proposed: number$1().int()
|
|
52219
|
+
}), {
|
|
52220
|
+
kind: "mutation",
|
|
52221
|
+
auth: "admin",
|
|
52222
|
+
timeoutMs: 12e4
|
|
51989
52223
|
}), method(object({ addonId: string() }), object({ deviceType: _enum(DeviceType).nullable() }), { auth: "admin" }), method(object({ addonId: string() }), unknown(), { auth: "admin" }), method(object({
|
|
51990
52224
|
deviceId: number$1(),
|
|
51991
52225
|
key: string(),
|
|
@@ -52842,7 +53076,7 @@ var DishwasherStatusSchema = object({
|
|
|
52842
53076
|
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
52843
53077
|
lastFetchedAt: number$1()
|
|
52844
53078
|
});
|
|
52845
|
-
var DeviceIdSchema$
|
|
53079
|
+
var DeviceIdSchema$2 = number$1().int().nonnegative();
|
|
52846
53080
|
/** A value a program option or setting can take. */
|
|
52847
53081
|
var DishwasherValueSchema = union([
|
|
52848
53082
|
boolean(),
|
|
@@ -52917,77 +53151,77 @@ var dishwasherCapability = {
|
|
|
52917
53151
|
* option feature keys; each is checked against the program's constraints.
|
|
52918
53152
|
*/
|
|
52919
53153
|
start: method(object({
|
|
52920
|
-
deviceId: DeviceIdSchema$
|
|
53154
|
+
deviceId: DeviceIdSchema$2,
|
|
52921
53155
|
program: string().min(1).optional(),
|
|
52922
53156
|
options: record(string(), DishwasherValueSchema).optional()
|
|
52923
53157
|
}), _void(), {
|
|
52924
53158
|
kind: "mutation",
|
|
52925
53159
|
auth: "protected"
|
|
52926
53160
|
}),
|
|
52927
|
-
pause: method(object({ deviceId: DeviceIdSchema$
|
|
53161
|
+
pause: method(object({ deviceId: DeviceIdSchema$2 }), _void(), {
|
|
52928
53162
|
kind: "mutation",
|
|
52929
53163
|
auth: "protected"
|
|
52930
53164
|
}),
|
|
52931
|
-
resume: method(object({ deviceId: DeviceIdSchema$
|
|
53165
|
+
resume: method(object({ deviceId: DeviceIdSchema$2 }), _void(), {
|
|
52932
53166
|
kind: "mutation",
|
|
52933
53167
|
auth: "protected"
|
|
52934
53168
|
}),
|
|
52935
|
-
stop: method(object({ deviceId: DeviceIdSchema$
|
|
53169
|
+
stop: method(object({ deviceId: DeviceIdSchema$2 }), _void(), {
|
|
52936
53170
|
kind: "mutation",
|
|
52937
53171
|
auth: "protected"
|
|
52938
53172
|
}),
|
|
52939
53173
|
/** Select (not start) a program; refused when the appliance does not offer it. */
|
|
52940
53174
|
setProgram: method(object({
|
|
52941
|
-
deviceId: DeviceIdSchema$
|
|
53175
|
+
deviceId: DeviceIdSchema$2,
|
|
52942
53176
|
program: string().min(1)
|
|
52943
53177
|
}), _void(), {
|
|
52944
53178
|
kind: "mutation",
|
|
52945
53179
|
auth: "protected"
|
|
52946
53180
|
}),
|
|
52947
53181
|
setPower: method(object({
|
|
52948
|
-
deviceId: DeviceIdSchema$
|
|
53182
|
+
deviceId: DeviceIdSchema$2,
|
|
52949
53183
|
on: boolean()
|
|
52950
53184
|
}), _void(), {
|
|
52951
53185
|
kind: "mutation",
|
|
52952
53186
|
auth: "protected"
|
|
52953
53187
|
}),
|
|
52954
53188
|
setHalfLoad: method(object({
|
|
52955
|
-
deviceId: DeviceIdSchema$
|
|
53189
|
+
deviceId: DeviceIdSchema$2,
|
|
52956
53190
|
on: boolean()
|
|
52957
53191
|
}), _void(), {
|
|
52958
53192
|
kind: "mutation",
|
|
52959
53193
|
auth: "protected"
|
|
52960
53194
|
}),
|
|
52961
53195
|
setHygienePlus: method(object({
|
|
52962
|
-
deviceId: DeviceIdSchema$
|
|
53196
|
+
deviceId: DeviceIdSchema$2,
|
|
52963
53197
|
on: boolean()
|
|
52964
53198
|
}), _void(), {
|
|
52965
53199
|
kind: "mutation",
|
|
52966
53200
|
auth: "protected"
|
|
52967
53201
|
}),
|
|
52968
53202
|
setExtraDry: method(object({
|
|
52969
|
-
deviceId: DeviceIdSchema$
|
|
53203
|
+
deviceId: DeviceIdSchema$2,
|
|
52970
53204
|
on: boolean()
|
|
52971
53205
|
}), _void(), {
|
|
52972
53206
|
kind: "mutation",
|
|
52973
53207
|
auth: "protected"
|
|
52974
53208
|
}),
|
|
52975
53209
|
setIntensiveZone: method(object({
|
|
52976
|
-
deviceId: DeviceIdSchema$
|
|
53210
|
+
deviceId: DeviceIdSchema$2,
|
|
52977
53211
|
on: boolean()
|
|
52978
53212
|
}), _void(), {
|
|
52979
53213
|
kind: "mutation",
|
|
52980
53214
|
auth: "protected"
|
|
52981
53215
|
}),
|
|
52982
53216
|
setVarioSpeedPlus: method(object({
|
|
52983
|
-
deviceId: DeviceIdSchema$
|
|
53217
|
+
deviceId: DeviceIdSchema$2,
|
|
52984
53218
|
on: boolean()
|
|
52985
53219
|
}), _void(), {
|
|
52986
53220
|
kind: "mutation",
|
|
52987
53221
|
auth: "protected"
|
|
52988
53222
|
}),
|
|
52989
53223
|
setChildLock: method(object({
|
|
52990
|
-
deviceId: DeviceIdSchema$
|
|
53224
|
+
deviceId: DeviceIdSchema$2,
|
|
52991
53225
|
on: boolean()
|
|
52992
53226
|
}), _void(), {
|
|
52993
53227
|
kind: "mutation",
|
|
@@ -52999,7 +53233,7 @@ var dishwasherCapability = {
|
|
|
52999
53233
|
* its declared range / members.
|
|
53000
53234
|
*/
|
|
53001
53235
|
setOption: method(object({
|
|
53002
|
-
deviceId: DeviceIdSchema$
|
|
53236
|
+
deviceId: DeviceIdSchema$2,
|
|
53003
53237
|
key: string().min(1),
|
|
53004
53238
|
value: DishwasherValueSchema
|
|
53005
53239
|
}), _void(), {
|
|
@@ -53007,7 +53241,7 @@ var dishwasherCapability = {
|
|
|
53007
53241
|
auth: "protected"
|
|
53008
53242
|
}),
|
|
53009
53243
|
/** What this appliance can do, from its own description — the UI is derived from it. */
|
|
53010
|
-
getOptions: method(object({ deviceId: DeviceIdSchema$
|
|
53244
|
+
getOptions: method(object({ deviceId: DeviceIdSchema$2 }), DishwasherOptionsSchema, { auth: "protected" })
|
|
53011
53245
|
},
|
|
53012
53246
|
status: {
|
|
53013
53247
|
schema: DishwasherStatusSchema,
|
|
@@ -55330,6 +55564,89 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
55330
55564
|
auth: "admin"
|
|
55331
55565
|
});
|
|
55332
55566
|
/**
|
|
55567
|
+
* `integration-instances` - the connection of an addon that holds ONE or SEVERAL
|
|
55568
|
+
* (an account, a relay, a destination) as typed records (D985, D986). The addon's
|
|
55569
|
+
* own function page reads and writes them (Logging for Loki); the Integrations
|
|
55570
|
+
* page lists only the integrations that bring devices (D996).
|
|
55571
|
+
*
|
|
55572
|
+
* A collection of providers: each addon that holds connections registers one and a
|
|
55573
|
+
* caller reaches a provider with the pinned `addonId`.
|
|
55574
|
+
*
|
|
55575
|
+
* Identity: the instance id is immutable and opaque to the caller. A record the
|
|
55576
|
+
* Loki migration made keeps the `integrations` registry id it was created under
|
|
55577
|
+
* (`int_NNNN`); a single instance made by its function page takes the addon id.
|
|
55578
|
+
* `name` is the editable label.
|
|
55579
|
+
*
|
|
55580
|
+
* Secrets: every field the instance kind marks `.meta({ secret: true })` reaches
|
|
55581
|
+
* the form as a `SecretFieldView`, never text (D789). A patch value omitted, `''`
|
|
55582
|
+
* or the redaction token KEEPS the stored secret; `{ $secretClear: true }`
|
|
55583
|
+
* clears it.
|
|
55584
|
+
*/
|
|
55585
|
+
var ConfigSchemaPassthrough$3 = custom();
|
|
55586
|
+
var IntegrationInstanceIdSchema = string().min(1);
|
|
55587
|
+
var IntegrationInstanceDescriptionSchema = object({
|
|
55588
|
+
/** `single`: at most one instance can exist (Loki). `multiple`: an account each. */
|
|
55589
|
+
instanceMode: _enum(["single", "multiple"]),
|
|
55590
|
+
/** What the instance is, for the UI (`destination`, `relay`, `account`). */
|
|
55591
|
+
kind: string(),
|
|
55592
|
+
/** True when `testInstance` really probes the remote. */
|
|
55593
|
+
canTest: boolean()
|
|
55594
|
+
});
|
|
55595
|
+
var IntegrationInstanceStatusSchema = object({
|
|
55596
|
+
state: _enum([
|
|
55597
|
+
"ok",
|
|
55598
|
+
"off",
|
|
55599
|
+
"error",
|
|
55600
|
+
"unknown"
|
|
55601
|
+
]),
|
|
55602
|
+
detail: string().optional()
|
|
55603
|
+
});
|
|
55604
|
+
var IntegrationInstanceSchema = object({
|
|
55605
|
+
id: IntegrationInstanceIdSchema,
|
|
55606
|
+
name: string(),
|
|
55607
|
+
/** The addon's own rule (an URL is present, a client id is present...). */
|
|
55608
|
+
configured: boolean(),
|
|
55609
|
+
/**
|
|
55610
|
+
* The instance's own on/off switch (D996): always present, derived from the record body
|
|
55611
|
+
* (`enabled !== false`, so a row written before the field existed is on).
|
|
55612
|
+
*/
|
|
55613
|
+
enabled: boolean(),
|
|
55614
|
+
/** Values for the instance form; a secret is a `SecretFieldView`, never text. */
|
|
55615
|
+
formValues: record(string(), unknown()),
|
|
55616
|
+
status: IntegrationInstanceStatusSchema.optional()
|
|
55617
|
+
});
|
|
55618
|
+
var IntegrationInstancePatchSchema = object({
|
|
55619
|
+
id: IntegrationInstanceIdSchema,
|
|
55620
|
+
name: string().min(1).optional(),
|
|
55621
|
+
/** Omitted / '' / redaction token keeps a secret; `{ $secretClear: true }` clears it. */
|
|
55622
|
+
values: record(string(), unknown())
|
|
55623
|
+
});
|
|
55624
|
+
method(_void(), IntegrationInstanceDescriptionSchema, { auth: "admin" }), method(object({ id: IntegrationInstanceIdSchema.nullable() }), ConfigSchemaPassthrough$3, { auth: "admin" }), method(_void(), array(IntegrationInstanceSchema).readonly(), { auth: "admin" }), method(object({ id: IntegrationInstanceIdSchema }), IntegrationInstanceSchema.nullable(), { auth: "admin" }), method(object({
|
|
55625
|
+
id: IntegrationInstanceIdSchema,
|
|
55626
|
+
name: string().min(1)
|
|
55627
|
+
}), object({ id: string() }), {
|
|
55628
|
+
kind: "mutation",
|
|
55629
|
+
auth: "admin"
|
|
55630
|
+
}), method(IntegrationInstancePatchSchema, object({ ok: literal(true) }), {
|
|
55631
|
+
kind: "mutation",
|
|
55632
|
+
auth: "admin"
|
|
55633
|
+
}), method(object({
|
|
55634
|
+
id: IntegrationInstanceIdSchema,
|
|
55635
|
+
enabled: boolean()
|
|
55636
|
+
}), object({ ok: literal(true) }), {
|
|
55637
|
+
kind: "mutation",
|
|
55638
|
+
auth: "admin"
|
|
55639
|
+
}), method(object({ id: IntegrationInstanceIdSchema }), object({ ok: literal(true) }), {
|
|
55640
|
+
kind: "mutation",
|
|
55641
|
+
auth: "admin"
|
|
55642
|
+
}), optionalMethod(object({
|
|
55643
|
+
id: IntegrationInstanceIdSchema.nullable(),
|
|
55644
|
+
values: record(string(), unknown())
|
|
55645
|
+
}), TestConnectionResultSchema$1, {
|
|
55646
|
+
kind: "mutation",
|
|
55647
|
+
auth: "admin"
|
|
55648
|
+
});
|
|
55649
|
+
/**
|
|
55333
55650
|
* Two-way audio / talk-back cap. Clients open a WebRTC audio-only
|
|
55334
55651
|
* session (server-initiated offer pattern, identical to the main
|
|
55335
55652
|
* video WebRTC flow) and the browser captures the mic; the server
|
|
@@ -66097,7 +66414,14 @@ var NcMediaPolicySchema = object({
|
|
|
66097
66414
|
*/
|
|
66098
66415
|
profile: CamProfileSchema.optional(),
|
|
66099
66416
|
/** See {@link NcLinkedCameraModeSchema}. */
|
|
66100
|
-
linkedCameras: NcLinkedCameraModeSchema.optional()
|
|
66417
|
+
linkedCameras: NcLinkedCameraModeSchema.optional(),
|
|
66418
|
+
/**
|
|
66419
|
+
* Sensor rules only: may this rule wake a SLEEPING battery camera to take
|
|
66420
|
+
* the linked still it attaches (D998)? Absent means yes, an explicit `false`
|
|
66421
|
+
* opts out. Deliberately not a Zod default: a rule that never chose keeps
|
|
66422
|
+
* following the hub's. One bounded wake per event; nothing is attached later.
|
|
66423
|
+
*/
|
|
66424
|
+
wakeSleepingCamera: boolean().optional()
|
|
66101
66425
|
});
|
|
66102
66426
|
/**
|
|
66103
66427
|
* Cooldown GRANULARITY over the subject's class — how much a fired
|
|
@@ -68240,7 +68564,7 @@ var petFeederCapability = {
|
|
|
68240
68564
|
/**
|
|
68241
68565
|
* Pet water-fountain cap. Models the telemetry and the control surface of a
|
|
68242
68566
|
* circulating drinking fountain: how much water is in the tank, how much the
|
|
68243
|
-
* pet drank, whether the pump runs
|
|
68567
|
+
* pet drank, whether the pump runs.
|
|
68244
68568
|
*
|
|
68245
68569
|
* It has no native vendor provider of its own: a fountain reaches CamStack as
|
|
68246
68570
|
* a container of loose entities (a pump switch, two number boxes, a "filter
|
|
@@ -68256,8 +68580,10 @@ var petFeederCapability = {
|
|
|
68256
68580
|
* never here. Every reading may be `null`: a source that is offline or does
|
|
68257
68581
|
* not report is unknown, never zero.
|
|
68258
68582
|
*
|
|
68259
|
-
* The
|
|
68260
|
-
* cap
|
|
68583
|
+
* The pump's on/off duty cycle is model-specific and lives in the optional
|
|
68584
|
+
* `pump-cycle` cap. The filter, the cleaning and the water change are not
|
|
68585
|
+
* fields of this cap: they are items of the `consumables` cap on the same
|
|
68586
|
+
* device (kind `wear`), reset by the same forward mechanism.
|
|
68261
68587
|
*/
|
|
68262
68588
|
var PetFountainStatusSchema = object({
|
|
68263
68589
|
/** Water in the tank, 0..100 (%). Null while the source has not reported. */
|
|
@@ -68268,27 +68594,20 @@ var PetFountainStatusSchema = object({
|
|
|
68268
68594
|
empty: boolean().nullable(),
|
|
68269
68595
|
/** True while the pump is running. Null while unknown. */
|
|
68270
68596
|
pumpRunning: boolean().nullable(),
|
|
68271
|
-
/** True when the pump works on an on/off duty cycle rather than continuously. */
|
|
68272
|
-
pumpIntervalEnabled: boolean().nullable(),
|
|
68273
|
-
/** How long the pump runs per cycle, in seconds. */
|
|
68274
|
-
pumpOnTime: number$1().min(0).nullable().meta(readingMeta("duration")),
|
|
68275
|
-
/** How long the pump rests per cycle, in seconds. */
|
|
68276
|
-
pumpOffTime: number$1().min(0).nullable().meta(readingMeta("duration")),
|
|
68277
68597
|
/** Water drunk in the last drink, in litres. */
|
|
68278
68598
|
lastDrink: number$1().min(0).nullable().meta(readingMeta("volume")),
|
|
68279
68599
|
/** Water drunk in the current hour, in litres. */
|
|
68280
68600
|
currentHourDrink: number$1().min(0).nullable().meta(readingMeta("volume")),
|
|
68281
68601
|
/** Water drunk over the last 24 hours (rolling), in litres. */
|
|
68282
68602
|
last24hDrink: number$1().min(0).nullable().meta(readingMeta("volume")),
|
|
68283
|
-
/** Water drunk since local midnight, in litres. */
|
|
68603
|
+
/** Water drunk since local midnight, in litres. Null when the fountain has no such sensor. */
|
|
68284
68604
|
todayDrink: number$1().min(0).nullable().meta(readingMeta("volume")),
|
|
68285
68605
|
/** Decoded fault message. Null means healthy; a non-null string is an active fault. */
|
|
68286
68606
|
error: string().nullable(),
|
|
68287
68607
|
/** Ms epoch when the slice was last refreshed. */
|
|
68288
68608
|
lastFetchedAt: number$1()
|
|
68289
68609
|
});
|
|
68290
|
-
var DeviceIdSchema = number$1().int().nonnegative();
|
|
68291
|
-
var MinutesSchema = number$1().int().min(0);
|
|
68610
|
+
var DeviceIdSchema$1 = number$1().int().nonnegative();
|
|
68292
68611
|
var petFountainCapability = {
|
|
68293
68612
|
name: "pet-fountain",
|
|
68294
68613
|
scope: "device",
|
|
@@ -68298,38 +68617,14 @@ var petFountainCapability = {
|
|
|
68298
68617
|
methods: {
|
|
68299
68618
|
/** Start or stop the pump. */
|
|
68300
68619
|
setPump: method(object({
|
|
68301
|
-
deviceId: DeviceIdSchema,
|
|
68302
|
-
on: boolean()
|
|
68303
|
-
}), _void(), {
|
|
68304
|
-
kind: "mutation",
|
|
68305
|
-
auth: "protected"
|
|
68306
|
-
}),
|
|
68307
|
-
/** Switch the on/off duty cycle on or off (off = the pump runs continuously). */
|
|
68308
|
-
setPumpInterval: method(object({
|
|
68309
|
-
deviceId: DeviceIdSchema,
|
|
68620
|
+
deviceId: DeviceIdSchema$1,
|
|
68310
68621
|
on: boolean()
|
|
68311
68622
|
}), _void(), {
|
|
68312
68623
|
kind: "mutation",
|
|
68313
68624
|
auth: "protected"
|
|
68314
68625
|
}),
|
|
68315
|
-
/** Set how many minutes the pump runs per cycle. */
|
|
68316
|
-
setPumpOnMinutes: method(object({
|
|
68317
|
-
deviceId: DeviceIdSchema,
|
|
68318
|
-
minutes: MinutesSchema
|
|
68319
|
-
}), _void(), {
|
|
68320
|
-
kind: "mutation",
|
|
68321
|
-
auth: "protected"
|
|
68322
|
-
}),
|
|
68323
|
-
/** Set how many minutes the pump rests per cycle. */
|
|
68324
|
-
setPumpOffMinutes: method(object({
|
|
68325
|
-
deviceId: DeviceIdSchema,
|
|
68326
|
-
minutes: MinutesSchema
|
|
68327
|
-
}), _void(), {
|
|
68328
|
-
kind: "mutation",
|
|
68329
|
-
auth: "protected"
|
|
68330
|
-
}),
|
|
68331
68626
|
/** Clear the rolling daily consumption counters on the device. */
|
|
68332
|
-
resetDailyConsumption: method(object({ deviceId: DeviceIdSchema }), _void(), {
|
|
68627
|
+
resetDailyConsumption: method(object({ deviceId: DeviceIdSchema$1 }), _void(), {
|
|
68333
68628
|
kind: "mutation",
|
|
68334
68629
|
auth: "protected"
|
|
68335
68630
|
})
|
|
@@ -70662,6 +70957,79 @@ var ptzAutotrackCapability = {
|
|
|
70662
70957
|
*/
|
|
70663
70958
|
history: "none"
|
|
70664
70959
|
};
|
|
70960
|
+
/**
|
|
70961
|
+
* The on/off duty cycle of a pet fountain's pump. Some models run the pump
|
|
70962
|
+
* continuously and have nothing to configure; others can alternate a run time
|
|
70963
|
+
* and a rest time. That is model-specific, so it is its own optional cap on the
|
|
70964
|
+
* fountain device: a fountain without cycle entities simply never composes it
|
|
70965
|
+
* (planning#366), and the `pet-fountain` cap stays the model-independent core.
|
|
70966
|
+
*
|
|
70967
|
+
* Like `pet-fountain` it has no native vendor provider: an operator BUILDS the
|
|
70968
|
+
* cycle from loose entities (a cycle switch and two number boxes) and every
|
|
70969
|
+
* method is a forward to one source entity (D659, D967). Durations are stored
|
|
70970
|
+
* in SECONDS (D944); a number box that cannot be read back leaves them `null`
|
|
70971
|
+
* — unknown, never zero (D393).
|
|
70972
|
+
*/
|
|
70973
|
+
var PumpCycleStatusSchema = object({
|
|
70974
|
+
/** True when the pump works on the on/off cycle, false when it runs continuously. Null while unknown. */
|
|
70975
|
+
enabled: boolean().nullable(),
|
|
70976
|
+
/** How long the pump runs per cycle, in seconds. Null while unknown. */
|
|
70977
|
+
onTime: number$1().min(0).nullable().meta(readingMeta("duration")),
|
|
70978
|
+
/** How long the pump rests per cycle, in seconds. Null while unknown. */
|
|
70979
|
+
offTime: number$1().min(0).nullable().meta(readingMeta("duration")),
|
|
70980
|
+
/** Ms epoch when the slice was last refreshed. */
|
|
70981
|
+
lastFetchedAt: number$1()
|
|
70982
|
+
});
|
|
70983
|
+
var DeviceIdSchema = number$1().int().nonnegative();
|
|
70984
|
+
var MinutesSchema = number$1().int().min(0);
|
|
70985
|
+
var pumpCycleCapability = {
|
|
70986
|
+
name: "pump-cycle",
|
|
70987
|
+
scope: "device",
|
|
70988
|
+
deviceNative: true,
|
|
70989
|
+
mode: "singleton",
|
|
70990
|
+
deviceTypes: [DeviceType.PetFountain],
|
|
70991
|
+
methods: {
|
|
70992
|
+
/** Switch the on/off duty cycle on or off (off = the pump runs continuously). */
|
|
70993
|
+
setEnabled: method(object({
|
|
70994
|
+
deviceId: DeviceIdSchema,
|
|
70995
|
+
on: boolean()
|
|
70996
|
+
}), _void(), {
|
|
70997
|
+
kind: "mutation",
|
|
70998
|
+
auth: "protected"
|
|
70999
|
+
}),
|
|
71000
|
+
/** Set how many minutes the pump runs per cycle. */
|
|
71001
|
+
setOnMinutes: method(object({
|
|
71002
|
+
deviceId: DeviceIdSchema,
|
|
71003
|
+
minutes: MinutesSchema
|
|
71004
|
+
}), _void(), {
|
|
71005
|
+
kind: "mutation",
|
|
71006
|
+
auth: "protected"
|
|
71007
|
+
}),
|
|
71008
|
+
/** Set how many minutes the pump rests per cycle. */
|
|
71009
|
+
setOffMinutes: method(object({
|
|
71010
|
+
deviceId: DeviceIdSchema,
|
|
71011
|
+
minutes: MinutesSchema
|
|
71012
|
+
}), _void(), {
|
|
71013
|
+
kind: "mutation",
|
|
71014
|
+
auth: "protected"
|
|
71015
|
+
})
|
|
71016
|
+
},
|
|
71017
|
+
status: {
|
|
71018
|
+
schema: PumpCycleStatusSchema,
|
|
71019
|
+
kind: "push"
|
|
71020
|
+
},
|
|
71021
|
+
/** Runtime-state slice — mirrored by the kernel; the hero card reads it whole. */
|
|
71022
|
+
runtimeState: PumpCycleStatusSchema,
|
|
71023
|
+
/**
|
|
71024
|
+
* Runtime-state durability: **session** — live appliance state re-published on connect.
|
|
71025
|
+
*
|
|
71026
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
71027
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
71028
|
+
*/
|
|
71029
|
+
durability: "session",
|
|
71030
|
+
/** History (D850): a duty-cycle setting is not a series worth recording. */
|
|
71031
|
+
history: "none"
|
|
71032
|
+
};
|
|
70665
71033
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, DeviceType.Gateway, method(object({ deviceId: number$1().int().nonnegative() }), object({ success: literal(true) }), {
|
|
70666
71034
|
kind: "mutation",
|
|
70667
71035
|
auth: "admin"
|
|
@@ -74654,7 +75022,16 @@ var smokeCapability = {
|
|
|
74654
75022
|
* future fields without breaking the existing call sites.
|
|
74655
75023
|
*/
|
|
74656
75024
|
var EmailAddressSchema = email();
|
|
75025
|
+
/**
|
|
75026
|
+
* Which relay of a multi-relay provider answers (D996). Absent = the provider's first / default
|
|
75027
|
+
* relay, so a caller written before relays existed keeps working unchanged. A provider with one
|
|
75028
|
+
* fixed relay ignores it. This is the integration instance id (`int_NNNN`), NOT the addon id: the
|
|
75029
|
+
* collection pin `addonId` still picks the provider, `instanceId` picks the relay inside it.
|
|
75030
|
+
*/
|
|
75031
|
+
var InstanceIdSchema = string().min(1).optional();
|
|
75032
|
+
var RelayPinSchema = object({ instanceId: InstanceIdSchema });
|
|
74657
75033
|
var SendEmailInputSchema = object({
|
|
75034
|
+
instanceId: InstanceIdSchema,
|
|
74658
75035
|
to: union([EmailAddressSchema, array(EmailAddressSchema).min(1)]),
|
|
74659
75036
|
cc: array(EmailAddressSchema).optional(),
|
|
74660
75037
|
bcc: array(EmailAddressSchema).optional(),
|
|
@@ -74690,11 +75067,11 @@ method(SendEmailInputSchema, SendEmailResultSchema, {
|
|
|
74690
75067
|
kind: "mutation",
|
|
74691
75068
|
auth: "admin",
|
|
74692
75069
|
access: "create"
|
|
74693
|
-
}), method(
|
|
75070
|
+
}), method(RelayPinSchema, SmtpStatusSchema, {
|
|
74694
75071
|
kind: "mutation",
|
|
74695
75072
|
auth: "admin",
|
|
74696
75073
|
access: "view"
|
|
74697
|
-
}), method(
|
|
75074
|
+
}), method(RelayPinSchema, SmtpStatusSchema, { auth: "admin" });
|
|
74698
75075
|
/**
|
|
74699
75076
|
* A single device snapshot returned as base64 JPEG/PNG.
|
|
74700
75077
|
*
|
|
@@ -74726,10 +75103,12 @@ DeviceType.Camera, method(object({
|
|
|
74726
75103
|
* even when the cache is well within the device's
|
|
74727
75104
|
* `snapshotMaxAgeS` window.
|
|
74728
75105
|
*
|
|
74729
|
-
* **`force` is
|
|
75106
|
+
* **`force` is a demand with a named principal, not a freshness
|
|
75107
|
+
* preference** — an operator button, the scheduled refresh (D847), or a
|
|
75108
|
+
* notification rule that left the camera's wake allowed (D998). On a
|
|
74730
75109
|
* battery camera it is the one thing that walks past the wrapper's
|
|
74731
|
-
* sleep gate and wakes the camera, so a
|
|
74732
|
-
*
|
|
75110
|
+
* sleep gate and wakes the camera, so a poller, a thumbnail or a
|
|
75111
|
+
* prestream must NEVER set it. Every such caller
|
|
74733
75112
|
* gets the cached frame, which on a sleeping battery camera is the
|
|
74734
75113
|
* correct answer: stale but honest beats woken.
|
|
74735
75114
|
*/
|
|
@@ -76299,6 +76678,40 @@ var LoggingSettingsStateSchema = object({
|
|
|
76299
76678
|
opsLogRetentionDays: number$1().int().min(0),
|
|
76300
76679
|
persisted: boolean()
|
|
76301
76680
|
});
|
|
76681
|
+
/**
|
|
76682
|
+
* Debug WATCH — a short, per-device window over `debug.<channel>` lines.
|
|
76683
|
+
*
|
|
76684
|
+
* `start` opens (or re-arms) a 10 minute window; `rearm` extends a LIVE one
|
|
76685
|
+
* and never revives a lapsed one; `stop` closes it; `list` only reads. No
|
|
76686
|
+
* chain of re-arms outlives 60 minutes from the first start. The hub holds the
|
|
76687
|
+
* watches in memory and pushes the interest to every node, so a watch lapses
|
|
76688
|
+
* by itself and survives nothing — a restart is a stop.
|
|
76689
|
+
*/
|
|
76690
|
+
var DebugWatchInputSchema = object({
|
|
76691
|
+
action: _enum([
|
|
76692
|
+
"list",
|
|
76693
|
+
"start",
|
|
76694
|
+
"rearm",
|
|
76695
|
+
"stop"
|
|
76696
|
+
]),
|
|
76697
|
+
/** Full channel names, `debug.<channel>`, each declared with `kind: 'debug'`. */
|
|
76698
|
+
channels: array(string().min(1)).readonly().default([]),
|
|
76699
|
+
/** Numeric device ids. Required (non-empty) for `start`. */
|
|
76700
|
+
deviceIds: array(number$1().int()).readonly().default([])
|
|
76701
|
+
});
|
|
76702
|
+
var DebugWatchStateSchema = object({
|
|
76703
|
+
channel: string(),
|
|
76704
|
+
deviceIds: array(number$1().int()).readonly(),
|
|
76705
|
+
startedAtMs: number$1(),
|
|
76706
|
+
untilMs: number$1(),
|
|
76707
|
+
capAtMs: number$1()
|
|
76708
|
+
});
|
|
76709
|
+
var DebugWatchResultSchema = object({
|
|
76710
|
+
nowMs: number$1(),
|
|
76711
|
+
watches: array(DebugWatchStateSchema).readonly(),
|
|
76712
|
+
/** Channels a `rearm` found already lapsed: nothing was revived. */
|
|
76713
|
+
lapsed: array(string()).readonly()
|
|
76714
|
+
});
|
|
76302
76715
|
method(_void(), SystemInfoSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
|
|
76303
76716
|
kind: "mutation",
|
|
76304
76717
|
auth: "admin"
|
|
@@ -76314,6 +76727,9 @@ method(_void(), SystemInfoSchema), method(_void(), HealthStatusSchema), method(_
|
|
|
76314
76727
|
}), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(_void(), array(ReportedFailureContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
|
|
76315
76728
|
kind: "mutation",
|
|
76316
76729
|
auth: "admin"
|
|
76730
|
+
}), method(DebugWatchInputSchema, DebugWatchResultSchema, {
|
|
76731
|
+
kind: "mutation",
|
|
76732
|
+
auth: "admin"
|
|
76317
76733
|
});
|
|
76318
76734
|
/**
|
|
76319
76735
|
* Tamper / case-open detection sensor. Drives Home Assistant
|
|
@@ -79379,7 +79795,7 @@ discriminatedUnion("kind", [object({
|
|
|
79379
79795
|
kind: literal("pronto"),
|
|
79380
79796
|
code: string()
|
|
79381
79797
|
})]);
|
|
79382
|
-
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
79798
|
+
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverStoppable, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
79383
79799
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
79384
79800
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
79385
79801
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
@@ -79739,6 +80155,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
79739
80155
|
pressureSensor: pressureSensorCapability,
|
|
79740
80156
|
privacyMask: privacyMaskCapability,
|
|
79741
80157
|
ptzAutotrack: ptzAutotrackCapability,
|
|
80158
|
+
pumpCycle: pumpCycleCapability,
|
|
79742
80159
|
recordingOnboard: recordingOnboardCapability,
|
|
79743
80160
|
recordingSignal: recordingSignalCapability,
|
|
79744
80161
|
runningState: runningStateCapability,
|
|
@@ -81923,6 +82340,27 @@ Object.freeze({
|
|
|
81923
82340
|
access: "view",
|
|
81924
82341
|
role: "viewer"
|
|
81925
82342
|
},
|
|
82343
|
+
"boardKeySource.getBoardKey": {
|
|
82344
|
+
capName: "board-key-source",
|
|
82345
|
+
capScope: "system",
|
|
82346
|
+
addonId: null,
|
|
82347
|
+
access: "view",
|
|
82348
|
+
role: "admin"
|
|
82349
|
+
},
|
|
82350
|
+
"boardKeySource.listBoards": {
|
|
82351
|
+
capName: "board-key-source",
|
|
82352
|
+
capScope: "system",
|
|
82353
|
+
addonId: null,
|
|
82354
|
+
access: "view",
|
|
82355
|
+
role: "admin"
|
|
82356
|
+
},
|
|
82357
|
+
"boardKeySource.listSources": {
|
|
82358
|
+
capName: "board-key-source",
|
|
82359
|
+
capScope: "system",
|
|
82360
|
+
addonId: null,
|
|
82361
|
+
access: "view",
|
|
82362
|
+
role: "admin"
|
|
82363
|
+
},
|
|
81926
82364
|
"brightness.getStatus": {
|
|
81927
82365
|
capName: "brightness",
|
|
81928
82366
|
capScope: "device",
|
|
@@ -83260,6 +83698,13 @@ Object.freeze({
|
|
|
83260
83698
|
access: "view",
|
|
83261
83699
|
role: "admin"
|
|
83262
83700
|
},
|
|
83701
|
+
"deviceManager.dismissDiscoveryProposal": {
|
|
83702
|
+
capName: "device-manager",
|
|
83703
|
+
capScope: "system",
|
|
83704
|
+
addonId: null,
|
|
83705
|
+
access: "create",
|
|
83706
|
+
role: "admin"
|
|
83707
|
+
},
|
|
83263
83708
|
"deviceManager.enable": {
|
|
83264
83709
|
capName: "device-manager",
|
|
83265
83710
|
capScope: "system",
|
|
@@ -83442,6 +83887,13 @@ Object.freeze({
|
|
|
83442
83887
|
access: "view",
|
|
83443
83888
|
role: "viewer"
|
|
83444
83889
|
},
|
|
83890
|
+
"deviceManager.listDiscoveryProposals": {
|
|
83891
|
+
capName: "device-manager",
|
|
83892
|
+
capScope: "system",
|
|
83893
|
+
addonId: null,
|
|
83894
|
+
access: "view",
|
|
83895
|
+
role: "admin"
|
|
83896
|
+
},
|
|
83445
83897
|
"deviceManager.listLocationDescriptions": {
|
|
83446
83898
|
capName: "device-manager",
|
|
83447
83899
|
capScope: "system",
|
|
@@ -83596,6 +84048,13 @@ Object.freeze({
|
|
|
83596
84048
|
access: "create",
|
|
83597
84049
|
role: "admin"
|
|
83598
84050
|
},
|
|
84051
|
+
"deviceManager.reportDiscoveryObservations": {
|
|
84052
|
+
capName: "device-manager",
|
|
84053
|
+
capScope: "system",
|
|
84054
|
+
addonId: null,
|
|
84055
|
+
access: "create",
|
|
84056
|
+
role: "admin"
|
|
84057
|
+
},
|
|
83599
84058
|
"deviceManager.runDeviceAction": {
|
|
83600
84059
|
capName: "device-manager",
|
|
83601
84060
|
capScope: "system",
|
|
@@ -83603,6 +84062,13 @@ Object.freeze({
|
|
|
83603
84062
|
access: "create",
|
|
83604
84063
|
role: "admin"
|
|
83605
84064
|
},
|
|
84065
|
+
"deviceManager.runDiscoverySweep": {
|
|
84066
|
+
capName: "device-manager",
|
|
84067
|
+
capScope: "system",
|
|
84068
|
+
addonId: null,
|
|
84069
|
+
access: "create",
|
|
84070
|
+
role: "admin"
|
|
84071
|
+
},
|
|
83606
84072
|
"deviceManager.setChildLayout": {
|
|
83607
84073
|
capName: "device-manager",
|
|
83608
84074
|
capScope: "system",
|
|
@@ -84534,6 +85000,69 @@ Object.freeze({
|
|
|
84534
85000
|
access: "create",
|
|
84535
85001
|
role: "admin"
|
|
84536
85002
|
},
|
|
85003
|
+
"integrationInstances.createInstance": {
|
|
85004
|
+
capName: "integration-instances",
|
|
85005
|
+
capScope: "system",
|
|
85006
|
+
addonId: null,
|
|
85007
|
+
access: "create",
|
|
85008
|
+
role: "admin"
|
|
85009
|
+
},
|
|
85010
|
+
"integrationInstances.deleteInstance": {
|
|
85011
|
+
capName: "integration-instances",
|
|
85012
|
+
capScope: "system",
|
|
85013
|
+
addonId: null,
|
|
85014
|
+
access: "delete",
|
|
85015
|
+
role: "admin"
|
|
85016
|
+
},
|
|
85017
|
+
"integrationInstances.describe": {
|
|
85018
|
+
capName: "integration-instances",
|
|
85019
|
+
capScope: "system",
|
|
85020
|
+
addonId: null,
|
|
85021
|
+
access: "view",
|
|
85022
|
+
role: "admin"
|
|
85023
|
+
},
|
|
85024
|
+
"integrationInstances.getInstance": {
|
|
85025
|
+
capName: "integration-instances",
|
|
85026
|
+
capScope: "system",
|
|
85027
|
+
addonId: null,
|
|
85028
|
+
access: "view",
|
|
85029
|
+
role: "admin"
|
|
85030
|
+
},
|
|
85031
|
+
"integrationInstances.instanceFormSchema": {
|
|
85032
|
+
capName: "integration-instances",
|
|
85033
|
+
capScope: "system",
|
|
85034
|
+
addonId: null,
|
|
85035
|
+
access: "view",
|
|
85036
|
+
role: "admin"
|
|
85037
|
+
},
|
|
85038
|
+
"integrationInstances.listInstances": {
|
|
85039
|
+
capName: "integration-instances",
|
|
85040
|
+
capScope: "system",
|
|
85041
|
+
addonId: null,
|
|
85042
|
+
access: "view",
|
|
85043
|
+
role: "admin"
|
|
85044
|
+
},
|
|
85045
|
+
"integrationInstances.setInstanceEnabled": {
|
|
85046
|
+
capName: "integration-instances",
|
|
85047
|
+
capScope: "system",
|
|
85048
|
+
addonId: null,
|
|
85049
|
+
access: "create",
|
|
85050
|
+
role: "admin"
|
|
85051
|
+
},
|
|
85052
|
+
"integrationInstances.testInstance": {
|
|
85053
|
+
capName: "integration-instances",
|
|
85054
|
+
capScope: "system",
|
|
85055
|
+
addonId: null,
|
|
85056
|
+
access: "create",
|
|
85057
|
+
role: "admin"
|
|
85058
|
+
},
|
|
85059
|
+
"integrationInstances.updateInstance": {
|
|
85060
|
+
capName: "integration-instances",
|
|
85061
|
+
capScope: "system",
|
|
85062
|
+
addonId: null,
|
|
85063
|
+
access: "create",
|
|
85064
|
+
role: "admin"
|
|
85065
|
+
},
|
|
84537
85066
|
"integrations.create": {
|
|
84538
85067
|
capName: "integrations",
|
|
84539
85068
|
capScope: "system",
|
|
@@ -86655,27 +87184,6 @@ Object.freeze({
|
|
|
86655
87184
|
access: "create",
|
|
86656
87185
|
role: "viewer"
|
|
86657
87186
|
},
|
|
86658
|
-
"petFountain.setPumpInterval": {
|
|
86659
|
-
capName: "pet-fountain",
|
|
86660
|
-
capScope: "device",
|
|
86661
|
-
addonId: null,
|
|
86662
|
-
access: "create",
|
|
86663
|
-
role: "viewer"
|
|
86664
|
-
},
|
|
86665
|
-
"petFountain.setPumpOffMinutes": {
|
|
86666
|
-
capName: "pet-fountain",
|
|
86667
|
-
capScope: "device",
|
|
86668
|
-
addonId: null,
|
|
86669
|
-
access: "create",
|
|
86670
|
-
role: "viewer"
|
|
86671
|
-
},
|
|
86672
|
-
"petFountain.setPumpOnMinutes": {
|
|
86673
|
-
capName: "pet-fountain",
|
|
86674
|
-
capScope: "device",
|
|
86675
|
-
addonId: null,
|
|
86676
|
-
access: "create",
|
|
86677
|
-
role: "viewer"
|
|
86678
|
-
},
|
|
86679
87187
|
"pipelineAnalytics.addRetrainFrameFromRecording": {
|
|
86680
87188
|
capName: "pipeline-analytics",
|
|
86681
87189
|
capScope: "device",
|
|
@@ -88454,6 +88962,34 @@ Object.freeze({
|
|
|
88454
88962
|
access: "create",
|
|
88455
88963
|
role: "admin"
|
|
88456
88964
|
},
|
|
88965
|
+
"pumpCycle.getStatus": {
|
|
88966
|
+
capName: "pump-cycle",
|
|
88967
|
+
capScope: "device",
|
|
88968
|
+
addonId: null,
|
|
88969
|
+
access: "view",
|
|
88970
|
+
role: "viewer"
|
|
88971
|
+
},
|
|
88972
|
+
"pumpCycle.setEnabled": {
|
|
88973
|
+
capName: "pump-cycle",
|
|
88974
|
+
capScope: "device",
|
|
88975
|
+
addonId: null,
|
|
88976
|
+
access: "create",
|
|
88977
|
+
role: "viewer"
|
|
88978
|
+
},
|
|
88979
|
+
"pumpCycle.setOffMinutes": {
|
|
88980
|
+
capName: "pump-cycle",
|
|
88981
|
+
capScope: "device",
|
|
88982
|
+
addonId: null,
|
|
88983
|
+
access: "create",
|
|
88984
|
+
role: "viewer"
|
|
88985
|
+
},
|
|
88986
|
+
"pumpCycle.setOnMinutes": {
|
|
88987
|
+
capName: "pump-cycle",
|
|
88988
|
+
capScope: "device",
|
|
88989
|
+
addonId: null,
|
|
88990
|
+
access: "create",
|
|
88991
|
+
role: "viewer"
|
|
88992
|
+
},
|
|
88457
88993
|
"reboot.reboot": {
|
|
88458
88994
|
capName: "reboot",
|
|
88459
88995
|
capScope: "device",
|
|
@@ -90190,6 +90726,13 @@ Object.freeze({
|
|
|
90190
90726
|
access: "create",
|
|
90191
90727
|
role: "viewer"
|
|
90192
90728
|
},
|
|
90729
|
+
"system.debugWatch": {
|
|
90730
|
+
capName: "system",
|
|
90731
|
+
capScope: "system",
|
|
90732
|
+
addonId: null,
|
|
90733
|
+
access: "create",
|
|
90734
|
+
role: "admin"
|
|
90735
|
+
},
|
|
90193
90736
|
"system.detectSiteLocation": {
|
|
90194
90737
|
capName: "system",
|
|
90195
90738
|
capScope: "system",
|
|
@@ -92991,21 +93534,6 @@ Object.freeze({
|
|
|
92991
93534
|
form: "single",
|
|
92992
93535
|
optional: false
|
|
92993
93536
|
}],
|
|
92994
|
-
"petFountain.setPumpInterval": [{
|
|
92995
|
-
name: "deviceId",
|
|
92996
|
-
form: "single",
|
|
92997
|
-
optional: false
|
|
92998
|
-
}],
|
|
92999
|
-
"petFountain.setPumpOffMinutes": [{
|
|
93000
|
-
name: "deviceId",
|
|
93001
|
-
form: "single",
|
|
93002
|
-
optional: false
|
|
93003
|
-
}],
|
|
93004
|
-
"petFountain.setPumpOnMinutes": [{
|
|
93005
|
-
name: "deviceId",
|
|
93006
|
-
form: "single",
|
|
93007
|
-
optional: false
|
|
93008
|
-
}],
|
|
93009
93537
|
"pipelineAnalytics.addRetrainFrameFromRecording": [{
|
|
93010
93538
|
name: "deviceId",
|
|
93011
93539
|
form: "single",
|
|
@@ -93641,6 +94169,26 @@ Object.freeze({
|
|
|
93641
94169
|
form: "single",
|
|
93642
94170
|
optional: false
|
|
93643
94171
|
}],
|
|
94172
|
+
"pumpCycle.getStatus": [{
|
|
94173
|
+
name: "deviceId",
|
|
94174
|
+
form: "single",
|
|
94175
|
+
optional: false
|
|
94176
|
+
}],
|
|
94177
|
+
"pumpCycle.setEnabled": [{
|
|
94178
|
+
name: "deviceId",
|
|
94179
|
+
form: "single",
|
|
94180
|
+
optional: false
|
|
94181
|
+
}],
|
|
94182
|
+
"pumpCycle.setOffMinutes": [{
|
|
94183
|
+
name: "deviceId",
|
|
94184
|
+
form: "single",
|
|
94185
|
+
optional: false
|
|
94186
|
+
}],
|
|
94187
|
+
"pumpCycle.setOnMinutes": [{
|
|
94188
|
+
name: "deviceId",
|
|
94189
|
+
form: "single",
|
|
94190
|
+
optional: false
|
|
94191
|
+
}],
|
|
93644
94192
|
"reboot.reboot": [{
|
|
93645
94193
|
name: "deviceId",
|
|
93646
94194
|
form: "single",
|
|
@@ -94108,6 +94656,11 @@ Object.freeze({
|
|
|
94108
94656
|
form: "single",
|
|
94109
94657
|
optional: false
|
|
94110
94658
|
}],
|
|
94659
|
+
"system.debugWatch": [{
|
|
94660
|
+
name: "deviceIds",
|
|
94661
|
+
form: "array",
|
|
94662
|
+
optional: true
|
|
94663
|
+
}],
|
|
94111
94664
|
"tamper.getStatus": [{
|
|
94112
94665
|
name: "deviceId",
|
|
94113
94666
|
form: "single",
|
|
@@ -140569,7 +141122,7 @@ function buildAlexaBrokerProvider(deps) {
|
|
|
140569
141122
|
label: "Alexa",
|
|
140570
141123
|
signIn: {
|
|
140571
141124
|
basePath: "/addon/import-alexa/login",
|
|
140572
|
-
methods: ["device-code"]
|
|
141125
|
+
methods: ["device-code", "proxy"]
|
|
140573
141126
|
}
|
|
140574
141127
|
}]
|
|
140575
141128
|
}],
|