@camstack/addon-provider-reolink 1.2.185 → 1.2.186
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon.js +1829 -107
- package/dist/addon.mjs +1829 -107
- package/i18n/en.json +273 -0
- package/i18n/it.json +273 -0
- package/package.json +2 -1
package/dist/addon.js
CHANGED
|
@@ -5424,7 +5424,7 @@ var ZodIssueCode = {
|
|
|
5424
5424
|
var ZodFirstPartyTypeKind;
|
|
5425
5425
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5426
5426
|
//#endregion
|
|
5427
|
-
//#region ../types/dist/sleep-
|
|
5427
|
+
//#region ../types/dist/sleep-DRqxtc0C.mjs
|
|
5428
5428
|
/**
|
|
5429
5429
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5430
5430
|
* window to float samples (D455).
|
|
@@ -8297,6 +8297,24 @@ function collectZodSecretPaths(schema, prefix = "") {
|
|
|
8297
8297
|
}
|
|
8298
8298
|
return [...new Set(paths)];
|
|
8299
8299
|
}
|
|
8300
|
+
object({
|
|
8301
|
+
code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
|
|
8302
|
+
params: record(string(), union([string(), number()])).optional()
|
|
8303
|
+
});
|
|
8304
|
+
var CamstackError = class extends Error {
|
|
8305
|
+
i18nCode;
|
|
8306
|
+
i18nParams;
|
|
8307
|
+
constructor(code, params, englishMessage) {
|
|
8308
|
+
super(englishMessage);
|
|
8309
|
+
this.name = "CamstackError";
|
|
8310
|
+
this.i18nCode = code;
|
|
8311
|
+
this.i18nParams = params;
|
|
8312
|
+
}
|
|
8313
|
+
};
|
|
8314
|
+
/** `throw userError('device.not-found', { id }, 'Device 12 not found')` */
|
|
8315
|
+
function userError(code, params, englishFallback) {
|
|
8316
|
+
return new CamstackError(code, params, englishFallback);
|
|
8317
|
+
}
|
|
8300
8318
|
/**
|
|
8301
8319
|
* Promise-based timer helpers — used everywhere the codebase needs to
|
|
8302
8320
|
* wait, back off, or schedule a retry. Before these helpers landed, each
|
|
@@ -8322,7 +8340,7 @@ function sleep$2(ms) {
|
|
|
8322
8340
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
8323
8341
|
}
|
|
8324
8342
|
//#endregion
|
|
8325
|
-
//#region ../types/dist/err-msg-
|
|
8343
|
+
//#region ../types/dist/err-msg-DLerKiVO.mjs
|
|
8326
8344
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
8327
8345
|
DeviceType["Camera"] = "camera";
|
|
8328
8346
|
DeviceType["Hub"] = "hub";
|
|
@@ -8572,6 +8590,22 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
8572
8590
|
DeviceRole["Nightvision"] = "nightvision";
|
|
8573
8591
|
DeviceRole["PrivacyMask"] = "privacy-mask";
|
|
8574
8592
|
DeviceRole["Doorbell"] = "doorbell";
|
|
8593
|
+
/** Interior blind / shade / roller blind. HA `device_class: blind|shade`. */
|
|
8594
|
+
DeviceRole["CoverBlind"] = "cover-blind";
|
|
8595
|
+
/** Exterior roller shutter. HA `device_class: shutter`; Homematic BROLL. */
|
|
8596
|
+
DeviceRole["CoverShutter"] = "cover-shutter";
|
|
8597
|
+
/** Exterior awning. HA `device_class: awning`. */
|
|
8598
|
+
DeviceRole["CoverAwning"] = "cover-awning";
|
|
8599
|
+
/** Curtain / drape. HA `device_class: curtain`. */
|
|
8600
|
+
DeviceRole["CoverCurtain"] = "cover-curtain";
|
|
8601
|
+
/** Garage door. HA `device_class: garage`. A security actuator: exports gate it. */
|
|
8602
|
+
DeviceRole["CoverGarage"] = "cover-garage";
|
|
8603
|
+
/** Gate. HA `device_class: gate`. A security actuator: exports gate it. */
|
|
8604
|
+
DeviceRole["CoverGate"] = "cover-gate";
|
|
8605
|
+
/** Door. HA `device_class: door`. A security actuator: exports gate it. */
|
|
8606
|
+
DeviceRole["CoverDoor"] = "cover-door";
|
|
8607
|
+
/** Window. HA `device_class: window`. */
|
|
8608
|
+
DeviceRole["CoverWindow"] = "cover-window";
|
|
8575
8609
|
/** Virtual HA toggle (input_boolean.*) — distinguishable from a
|
|
8576
8610
|
* real Switch device for UI rendering / export adapters. */
|
|
8577
8611
|
DeviceRole["BinaryHelper"] = "binary-helper";
|
|
@@ -8642,7 +8676,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
8642
8676
|
return DeviceRole;
|
|
8643
8677
|
}({});
|
|
8644
8678
|
//#endregion
|
|
8645
|
-
//#region ../types/dist/composition-
|
|
8679
|
+
//#region ../types/dist/composition-EQ9Ok0Ee.mjs
|
|
8646
8680
|
/**
|
|
8647
8681
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
8648
8682
|
*
|
|
@@ -12870,6 +12904,177 @@ var ConvertResultSchema = object({
|
|
|
12870
12904
|
files: array(string()).readonly()
|
|
12871
12905
|
})).readonly()
|
|
12872
12906
|
});
|
|
12907
|
+
_enum(["new-session", "step-up"]);
|
|
12908
|
+
/** The languages the hub's app landing pages are written in (D858). */
|
|
12909
|
+
var AppPageLangSchema = _enum(["en", "it"]);
|
|
12910
|
+
/** How a native app starts one login method (D858), as `auth.listLoginMethods` reports it. */
|
|
12911
|
+
var AppLoginPathSchema = discriminatedUnion("kind", [object({ kind: literal("native") }), object({
|
|
12912
|
+
kind: literal("browser"),
|
|
12913
|
+
startPath: string().startsWith("/")
|
|
12914
|
+
})]);
|
|
12915
|
+
/**
|
|
12916
|
+
* Device certificates (D855) — the wire contract shared by the hub, the admin
|
|
12917
|
+
* UI and the native viewer.
|
|
12918
|
+
*
|
|
12919
|
+
* A device (a phone) generates its OWN P-256 key pair in hardware (Secure
|
|
12920
|
+
* Enclave / Android Keystore / a non-extractable WebCrypto key). The private
|
|
12921
|
+
* key never travels. The hub signs the PUBLIC key into an X.509 leaf under a
|
|
12922
|
+
* dedicated device CA; the device later proves possession of the key by
|
|
12923
|
+
* signing a hub-issued nonce, and the hub answers with the same session a
|
|
12924
|
+
* password login opens.
|
|
12925
|
+
*
|
|
12926
|
+
* Everything on the wire is a small string (a PEM, a base64url signature):
|
|
12927
|
+
* D613 is about bulk bytes, and a certificate is ~600 bytes.
|
|
12928
|
+
*/
|
|
12929
|
+
/** Signature algorithm of every device credential: ECDSA, curve P-256, SHA-256. */
|
|
12930
|
+
var DEVICE_CERT_SIGNATURE = "ecdsa-p256-sha256";
|
|
12931
|
+
/** First line of every signed message; a change of format bumps the version. */
|
|
12932
|
+
var DEVICE_SIGNATURE_MESSAGE_VERSION = "camstack-device-cert-v1";
|
|
12933
|
+
_enum([
|
|
12934
|
+
"login",
|
|
12935
|
+
"renew",
|
|
12936
|
+
"revoke"
|
|
12937
|
+
]);
|
|
12938
|
+
var DevicePlatformSchema = _enum([
|
|
12939
|
+
"ios",
|
|
12940
|
+
"android",
|
|
12941
|
+
"web",
|
|
12942
|
+
"other"
|
|
12943
|
+
]);
|
|
12944
|
+
var Base64UrlSchema = string().min(1).max(4096).regex(/^[A-Za-z0-9_-]+$/);
|
|
12945
|
+
var PemSchema = string().min(1).max(16384);
|
|
12946
|
+
/**
|
|
12947
|
+
* Why a device-certificate endpoint said no. Distinct from a transport / 5xx
|
|
12948
|
+
* failure: those carry no reason and mean "try again", never "the credential is
|
|
12949
|
+
* dead". The viewer switches on this exhaustively.
|
|
12950
|
+
*/
|
|
12951
|
+
var DeviceRefusalReasonSchema = _enum([
|
|
12952
|
+
"revoked",
|
|
12953
|
+
"unknown-credential",
|
|
12954
|
+
"expired",
|
|
12955
|
+
"bad-signature",
|
|
12956
|
+
"nonce-invalid",
|
|
12957
|
+
"rate-limited",
|
|
12958
|
+
"invalid-certificate",
|
|
12959
|
+
"superseded",
|
|
12960
|
+
"user-gone",
|
|
12961
|
+
"unavailable",
|
|
12962
|
+
"code-invalid",
|
|
12963
|
+
"self-enrollment-disabled",
|
|
12964
|
+
"step-up-required",
|
|
12965
|
+
"bad-public-key"
|
|
12966
|
+
]);
|
|
12967
|
+
var DeviceRefusalSchema = object({
|
|
12968
|
+
ok: literal(false),
|
|
12969
|
+
reason: DeviceRefusalReasonSchema,
|
|
12970
|
+
definitive: boolean(),
|
|
12971
|
+
retryAfterSeconds: number().optional()
|
|
12972
|
+
});
|
|
12973
|
+
object({
|
|
12974
|
+
code: string().min(1).max(256),
|
|
12975
|
+
/** SubjectPublicKeyInfo DER of the device's P-256 public key, base64url. */
|
|
12976
|
+
publicKeySpki: Base64UrlSchema,
|
|
12977
|
+
deviceName: string().min(1).max(80).optional(),
|
|
12978
|
+
platform: DevicePlatformSchema
|
|
12979
|
+
});
|
|
12980
|
+
discriminatedUnion("ok", [object({
|
|
12981
|
+
credentialId: string(),
|
|
12982
|
+
certPem: PemSchema,
|
|
12983
|
+
/** The device CA certificate the leaf chains to. */
|
|
12984
|
+
chainPem: PemSchema,
|
|
12985
|
+
notAfter: number(),
|
|
12986
|
+
user: object({
|
|
12987
|
+
id: string(),
|
|
12988
|
+
username: string()
|
|
12989
|
+
})
|
|
12990
|
+
}).extend({ ok: literal(true) }), DeviceRefusalSchema]);
|
|
12991
|
+
object({
|
|
12992
|
+
/** The single-use step-up proof (`auth.deviceEnrollProofFrom…`). */
|
|
12993
|
+
proof: string().min(1).max(512),
|
|
12994
|
+
publicKeySpki: Base64UrlSchema,
|
|
12995
|
+
deviceName: string().min(1).max(80),
|
|
12996
|
+
platform: DevicePlatformSchema
|
|
12997
|
+
});
|
|
12998
|
+
object({
|
|
12999
|
+
proof: string(),
|
|
13000
|
+
expiresAt: number()
|
|
13001
|
+
});
|
|
13002
|
+
discriminatedUnion("ok", [object({
|
|
13003
|
+
nonce: string(),
|
|
13004
|
+
/** The origin to put in the signed message. The app compares it to the hub it dialled. */
|
|
13005
|
+
origin: string(),
|
|
13006
|
+
expiresAt: number(),
|
|
13007
|
+
signature: literal(DEVICE_CERT_SIGNATURE)
|
|
13008
|
+
}).extend({ ok: literal(true) }), DeviceRefusalSchema]);
|
|
13009
|
+
object({
|
|
13010
|
+
certPem: PemSchema,
|
|
13011
|
+
nonce: string().min(1).max(256),
|
|
13012
|
+
/** ECDSA P-256 SHA-256 over {@link buildDeviceSignatureMessage}; raw r||s or DER, base64url. */
|
|
13013
|
+
signature: Base64UrlSchema
|
|
13014
|
+
});
|
|
13015
|
+
discriminatedUnion("ok", [object({
|
|
13016
|
+
credentialId: string(),
|
|
13017
|
+
certPem: PemSchema,
|
|
13018
|
+
chainPem: PemSchema,
|
|
13019
|
+
notAfter: number()
|
|
13020
|
+
}).extend({ ok: literal(true) }), DeviceRefusalSchema]);
|
|
13021
|
+
discriminatedUnion("ok", [object({
|
|
13022
|
+
ok: literal(true),
|
|
13023
|
+
credentialId: string(),
|
|
13024
|
+
sessionsEnded: number().int()
|
|
13025
|
+
}), DeviceRefusalSchema]);
|
|
13026
|
+
var DeviceCredentialStatusSchema = _enum([
|
|
13027
|
+
"active",
|
|
13028
|
+
"expired",
|
|
13029
|
+
"revoked"
|
|
13030
|
+
]);
|
|
13031
|
+
var DeviceCredentialSchema = object({
|
|
13032
|
+
id: string(),
|
|
13033
|
+
userId: string(),
|
|
13034
|
+
username: string().nullable(),
|
|
13035
|
+
deviceName: string(),
|
|
13036
|
+
platform: DevicePlatformSchema,
|
|
13037
|
+
enrolledVia: _enum(["qr", "self"]),
|
|
13038
|
+
/** SHA-256 of the leaf certificate DER, colon-hex. */
|
|
13039
|
+
fingerprint: string(),
|
|
13040
|
+
issuedAt: number(),
|
|
13041
|
+
expiresAt: number(),
|
|
13042
|
+
lastUsedAt: number().nullable(),
|
|
13043
|
+
lastUsedFrom: string().nullable(),
|
|
13044
|
+
revokedAt: number().nullable(),
|
|
13045
|
+
/** `admin:<userId>` | `user:<userId>` | `device` | `user-deleted`. */
|
|
13046
|
+
revokedBy: string().nullable(),
|
|
13047
|
+
status: DeviceCredentialStatusSchema
|
|
13048
|
+
});
|
|
13049
|
+
var StartEnrollmentOutputSchema = object({
|
|
13050
|
+
/** Shown once; only its hash is kept. */
|
|
13051
|
+
code: string(),
|
|
13052
|
+
expiresAt: number(),
|
|
13053
|
+
/** `camstack://enroll?hub=…&code=…` — what the QR encodes. */
|
|
13054
|
+
enrollUrl: string(),
|
|
13055
|
+
/** The hub origin in the link, or `null` when the hub could not name one (the link then has no `hub`). */
|
|
13056
|
+
hubOrigin: string().nullable(),
|
|
13057
|
+
/** Every origin the apps may try (role `appConnections`). */
|
|
13058
|
+
hubOrigins: array(string())
|
|
13059
|
+
});
|
|
13060
|
+
object({
|
|
13061
|
+
kind: literal("device-certificate"),
|
|
13062
|
+
id: literal("device-certificate"),
|
|
13063
|
+
label: string(),
|
|
13064
|
+
stage: literal("primary"),
|
|
13065
|
+
/** tRPC paths under the hub's `auth` router, so a client names no literal. */
|
|
13066
|
+
challengePath: literal("auth.getDeviceChallenge"),
|
|
13067
|
+
revokePath: literal("auth.revokeOwnDeviceCertificate"),
|
|
13068
|
+
enrollSelfPath: literal("auth.enrollSelf"),
|
|
13069
|
+
loginPath: literal("auth.loginWithDeviceCertificate"),
|
|
13070
|
+
renewPath: literal("auth.renewDeviceCertificate"),
|
|
13071
|
+
signature: literal(DEVICE_CERT_SIGNATURE),
|
|
13072
|
+
messageVersion: literal(DEVICE_SIGNATURE_MESSAGE_VERSION),
|
|
13073
|
+
/** Which clients can execute it: a native app silently, a browser with a non-extractable WebCrypto key. */
|
|
13074
|
+
clients: array(_enum(["native", "web"])),
|
|
13075
|
+
/** The app executes it itself, silently (D858). */
|
|
13076
|
+
app: AppLoginPathSchema.nullable()
|
|
13077
|
+
});
|
|
12873
13078
|
var ExpressionBindingSourceSchema = union([
|
|
12874
13079
|
object({
|
|
12875
13080
|
kind: literal("field").optional(),
|
|
@@ -13198,7 +13403,9 @@ var ConfigTabDeclarationSchema = object({
|
|
|
13198
13403
|
var ConfigSectionWithValuesSchema = object({
|
|
13199
13404
|
id: string(),
|
|
13200
13405
|
title: string(),
|
|
13406
|
+
titleKey: string().optional(),
|
|
13201
13407
|
description: string().optional(),
|
|
13408
|
+
descriptionKey: string().optional(),
|
|
13202
13409
|
style: _enum(["card", "accordion"]).optional(),
|
|
13203
13410
|
defaultCollapsed: boolean().optional(),
|
|
13204
13411
|
columns: union([
|
|
@@ -15694,7 +15901,11 @@ var cameraStreamsCapability = {
|
|
|
15694
15901
|
* See `RuntimeStateDurability`. Enforced by
|
|
15695
15902
|
* `scripts/check-runtime-state-durability.ts`.
|
|
15696
15903
|
*/
|
|
15697
|
-
durability: "session"
|
|
15904
|
+
durability: "session",
|
|
15905
|
+
/**
|
|
15906
|
+
* History (D850): none — `online` duplicates device-status.online (one authority); slot data is nested enum/string.
|
|
15907
|
+
*/
|
|
15908
|
+
history: "none"
|
|
15698
15909
|
};
|
|
15699
15910
|
EventCategory.DoorbellOnPressed;
|
|
15700
15911
|
var CompositionEventPlanSchema = object({
|
|
@@ -16526,7 +16737,345 @@ method(object({
|
|
|
16526
16737
|
}), method(object({ refs: RefListSchema }), KeychainResolveResultSchema, { auth: "admin" }), method(object({ refs: RefListSchema }), object({ deleted: number().int() }), {
|
|
16527
16738
|
kind: "mutation",
|
|
16528
16739
|
auth: "admin"
|
|
16740
|
+
}), method(object({ deviceId: number().int() }), object({ refs: array(string()).readonly() }), {
|
|
16741
|
+
kind: "mutation",
|
|
16742
|
+
auth: "admin"
|
|
16529
16743
|
}), method(object({}), array(KeychainSecretMetaSchema).readonly(), { auth: "admin" }), method(object({}), KeychainStateSchema, { auth: "admin" });
|
|
16744
|
+
/**
|
|
16745
|
+
* device-history — the ONE mechanism for numeric history (D850).
|
|
16746
|
+
*
|
|
16747
|
+
* A device value is recorded because its capability says so (the `history`
|
|
16748
|
+
* block of a `*.cap.ts`, captured hub-side from `DeviceStateChanged`); any
|
|
16749
|
+
* other series is DECLARED by the addon that produces it and fed with points
|
|
16750
|
+
* (`record`) or closed five-minute buckets (`recordBuckets`). Rollups 5m / 1h /
|
|
16751
|
+
* 1d are computed here and nowhere else. Storage is `history.db` (D851).
|
|
16752
|
+
*
|
|
16753
|
+
* Who the PRODUCER is: `declareSeries`, `record` and `recordBuckets` are owner
|
|
16754
|
+
* checked against the `callerAddonId` the transport stamps into a call that
|
|
16755
|
+
* crossed a process (never in an input schema, so a session cannot supply it).
|
|
16756
|
+
* A call with no stamp is refused `not-owner`. The methods are `admin` so a
|
|
16757
|
+
* non-admin session never reaches them; an addon's `ctx.api` call bypasses the
|
|
16758
|
+
* tier by design.
|
|
16759
|
+
*/
|
|
16760
|
+
/** Whose history: a real device, or a cluster node (load, memory). */
|
|
16761
|
+
var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
|
|
16762
|
+
kind: literal("device"),
|
|
16763
|
+
deviceId: number().int()
|
|
16764
|
+
}), object({
|
|
16765
|
+
kind: literal("node"),
|
|
16766
|
+
nodeId: string().min(1)
|
|
16767
|
+
})]);
|
|
16768
|
+
var DeviceHistoryKindSchema = _enum([
|
|
16769
|
+
"gauge",
|
|
16770
|
+
"counter",
|
|
16771
|
+
"boolean"
|
|
16772
|
+
]);
|
|
16773
|
+
var DeviceHistoryResolutionSchema = _enum([
|
|
16774
|
+
"raw",
|
|
16775
|
+
"5m",
|
|
16776
|
+
"1h",
|
|
16777
|
+
"1d"
|
|
16778
|
+
]);
|
|
16779
|
+
/** Why a producer's point or bucket was not stored. Counted, never silent (D391). */
|
|
16780
|
+
var DeviceHistoryRefusalReasonSchema = _enum([
|
|
16781
|
+
"undeclared",
|
|
16782
|
+
"not-owner",
|
|
16783
|
+
"opted-out",
|
|
16784
|
+
"not-a-real-device",
|
|
16785
|
+
"rate",
|
|
16786
|
+
"ingest-mismatch",
|
|
16787
|
+
"out-of-range"
|
|
16788
|
+
]);
|
|
16789
|
+
var RefusalSchema = object({
|
|
16790
|
+
key: string(),
|
|
16791
|
+
reason: DeviceHistoryRefusalReasonSchema,
|
|
16792
|
+
count: number().int()
|
|
16793
|
+
});
|
|
16794
|
+
var IngestResultSchema = object({
|
|
16795
|
+
accepted: number().int(),
|
|
16796
|
+
refused: array(RefusalSchema).readonly()
|
|
16797
|
+
});
|
|
16798
|
+
var SeriesInfoSchema = object({
|
|
16799
|
+
key: string(),
|
|
16800
|
+
scope: string(),
|
|
16801
|
+
kind: DeviceHistoryKindSchema,
|
|
16802
|
+
/** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
|
|
16803
|
+
unit: string().nullable(),
|
|
16804
|
+
displayName: string(),
|
|
16805
|
+
source: _enum(["cap", "addon"]),
|
|
16806
|
+
firstTs: number(),
|
|
16807
|
+
lastTs: number()
|
|
16808
|
+
});
|
|
16809
|
+
var QueryPointSchema = object({
|
|
16810
|
+
/** Raw: the point's time. Rollup: the bucket start. */
|
|
16811
|
+
t: number(),
|
|
16812
|
+
samples: number().int(),
|
|
16813
|
+
/** `sum / samples`. */
|
|
16814
|
+
mean: number().nullable(),
|
|
16815
|
+
/** Time-weighted mean (`tw_sum / tw_ms`); `null` for bucket-ingested series. For a boolean: the fraction of time true. */
|
|
16816
|
+
twMean: number().nullable(),
|
|
16817
|
+
min: number(),
|
|
16818
|
+
max: number(),
|
|
16819
|
+
/** `null` is unknown, never zero (D393). */
|
|
16820
|
+
last: number().nullable()
|
|
16821
|
+
});
|
|
16822
|
+
var QuerySeriesSchema = object({
|
|
16823
|
+
scope: string(),
|
|
16824
|
+
/** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
|
|
16825
|
+
before: object({
|
|
16826
|
+
t: number(),
|
|
16827
|
+
value: number().nullable()
|
|
16828
|
+
}).nullable(),
|
|
16829
|
+
points: array(QueryPointSchema).readonly()
|
|
16830
|
+
});
|
|
16831
|
+
/** The window part of a query, shared by the device and node forms. */
|
|
16832
|
+
var QueryWindowShape = {
|
|
16833
|
+
key: string(),
|
|
16834
|
+
scope: string().optional(),
|
|
16835
|
+
from: number(),
|
|
16836
|
+
to: number(),
|
|
16837
|
+
resolution: union([DeviceHistoryResolutionSchema, literal("auto")]).default("auto"),
|
|
16838
|
+
maxPoints: number().int().positive().max(5e3).default(1e3)
|
|
16839
|
+
};
|
|
16840
|
+
var QueryResultSchema = object({
|
|
16841
|
+
resolution: DeviceHistoryResolutionSchema,
|
|
16842
|
+
series: array(QuerySeriesSchema).readonly(),
|
|
16843
|
+
truncated: boolean()
|
|
16844
|
+
});
|
|
16845
|
+
var TierStatusSchema = object({
|
|
16846
|
+
tier: DeviceHistoryResolutionSchema,
|
|
16847
|
+
/** `null` until the first background count answered. */
|
|
16848
|
+
rows: number().int().nullable(),
|
|
16849
|
+
/** `rows` times a fixed per-row estimate — approximate, labelled so. */
|
|
16850
|
+
approxBytes: number().nullable(),
|
|
16851
|
+
countedAt: number().nullable()
|
|
16852
|
+
});
|
|
16853
|
+
/** Operator/diagnostic view: rows per tier, last runs, refusals and drops since boot. */
|
|
16854
|
+
var DeviceHistoryStatusSchema = object({
|
|
16855
|
+
startedAt: number(),
|
|
16856
|
+
/** The store is declared, series loaded and the first reconcile has answered. */
|
|
16857
|
+
ready: boolean(),
|
|
16858
|
+
series: number().int(),
|
|
16859
|
+
metrics: number().int(),
|
|
16860
|
+
optedOutDevices: number().int(),
|
|
16861
|
+
tiers: array(TierStatusSchema).readonly(),
|
|
16862
|
+
capture: object({
|
|
16863
|
+
eventsSeen: number().int(),
|
|
16864
|
+
pointsEmitted: number().int(),
|
|
16865
|
+
pointsWritten: number().int(),
|
|
16866
|
+
pointsDropped: number().int(),
|
|
16867
|
+
bufferDepth: number().int(),
|
|
16868
|
+
trailingEmitted: number().int(),
|
|
16869
|
+
reconciledPoints: number().int(),
|
|
16870
|
+
reconcileRuns: number().int(),
|
|
16871
|
+
reconcileFailures: number().int(),
|
|
16872
|
+
lastReconcileAt: number().nullable(),
|
|
16873
|
+
lastFlushAt: number().nullable(),
|
|
16874
|
+
flushFailures: number().int(),
|
|
16875
|
+
skipped: record(string(), number().int())
|
|
16876
|
+
}),
|
|
16877
|
+
ingest: object({
|
|
16878
|
+
accepted: number().int(),
|
|
16879
|
+
refused: record(string(), number().int())
|
|
16880
|
+
}),
|
|
16881
|
+
rollup: object({
|
|
16882
|
+
last5mAt: number().nullable(),
|
|
16883
|
+
last1hAt: number().nullable(),
|
|
16884
|
+
last1dAt: number().nullable(),
|
|
16885
|
+
errors: number().int(),
|
|
16886
|
+
dirty5m: number().int(),
|
|
16887
|
+
dirty1h: number().int(),
|
|
16888
|
+
dirty1d: number().int()
|
|
16889
|
+
}),
|
|
16890
|
+
retention: object({
|
|
16891
|
+
lastRunAt: number().nullable(),
|
|
16892
|
+
deleted: record(string(), number().int()),
|
|
16893
|
+
purgedSeries: number().int()
|
|
16894
|
+
}),
|
|
16895
|
+
directory: object({
|
|
16896
|
+
devices: number().int(),
|
|
16897
|
+
lastRefreshAt: number().nullable()
|
|
16898
|
+
})
|
|
16899
|
+
});
|
|
16900
|
+
method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
|
|
16901
|
+
deviceId: number().int(),
|
|
16902
|
+
...QueryWindowShape
|
|
16903
|
+
}), QueryResultSchema), method(object({
|
|
16904
|
+
nodeId: string().min(1),
|
|
16905
|
+
...QueryWindowShape
|
|
16906
|
+
}), QueryResultSchema, { auth: "admin" }), method(object({
|
|
16907
|
+
name: string().regex(/^[a-z0-9-]+$/),
|
|
16908
|
+
subjectKind: _enum(["device", "node"]),
|
|
16909
|
+
kind: DeviceHistoryKindSchema,
|
|
16910
|
+
unit: string().optional(),
|
|
16911
|
+
displayName: string().min(1),
|
|
16912
|
+
ingest: _enum(["points", "buckets"])
|
|
16913
|
+
}), object({ key: string() }), {
|
|
16914
|
+
kind: "mutation",
|
|
16915
|
+
auth: "admin"
|
|
16916
|
+
}), method(object({ points: array(object({
|
|
16917
|
+
key: string(),
|
|
16918
|
+
subject: DeviceHistorySubjectSchema,
|
|
16919
|
+
scope: string().default(""),
|
|
16920
|
+
ts: number(),
|
|
16921
|
+
value: number()
|
|
16922
|
+
})).max(5e3) }), IngestResultSchema, {
|
|
16923
|
+
kind: "mutation",
|
|
16924
|
+
auth: "admin"
|
|
16925
|
+
}), method(object({ buckets: array(object({
|
|
16926
|
+
key: string(),
|
|
16927
|
+
subject: DeviceHistorySubjectSchema,
|
|
16928
|
+
scope: string().default(""),
|
|
16929
|
+
bucketStart: number(),
|
|
16930
|
+
samples: number().int().positive(),
|
|
16931
|
+
sum: number(),
|
|
16932
|
+
min: number(),
|
|
16933
|
+
max: number(),
|
|
16934
|
+
last: number().nullable(),
|
|
16935
|
+
lastTs: number().nullable()
|
|
16936
|
+
})).max(5e3) }), IngestResultSchema, {
|
|
16937
|
+
kind: "mutation",
|
|
16938
|
+
auth: "admin"
|
|
16939
|
+
}), method(object({ deviceId: number().int() }), object({ enabled: boolean() })), method(object({
|
|
16940
|
+
deviceId: number().int(),
|
|
16941
|
+
enabled: boolean()
|
|
16942
|
+
}), object({ enabled: boolean() }), {
|
|
16943
|
+
kind: "mutation",
|
|
16944
|
+
auth: "admin"
|
|
16945
|
+
}), method(object({}), DeviceHistoryStatusSchema, { auth: "admin" });
|
|
16946
|
+
var DeviceCaStatusSchema = discriminatedUnion("state", [
|
|
16947
|
+
object({ state: literal("absent") }),
|
|
16948
|
+
object({
|
|
16949
|
+
state: literal("ready"),
|
|
16950
|
+
subject: string(),
|
|
16951
|
+
fingerprintSha256: string(),
|
|
16952
|
+
validTo: string()
|
|
16953
|
+
}),
|
|
16954
|
+
object({
|
|
16955
|
+
state: literal("unavailable"),
|
|
16956
|
+
reason: string()
|
|
16957
|
+
})
|
|
16958
|
+
]);
|
|
16959
|
+
var DeviceCertificateSettingsSchema = object({ selfEnrollment: _enum(["allowed", "disabled"]) });
|
|
16960
|
+
method(object({
|
|
16961
|
+
userId: string().min(1).optional(),
|
|
16962
|
+
includeRevoked: boolean().default(false)
|
|
16963
|
+
}), array(DeviceCredentialSchema).readonly(), { auth: "admin" }), method(object({
|
|
16964
|
+
userId: string().min(1),
|
|
16965
|
+
deviceName: string().min(1).max(80)
|
|
16966
|
+
}), StartEnrollmentOutputSchema, {
|
|
16967
|
+
kind: "mutation",
|
|
16968
|
+
auth: "admin",
|
|
16969
|
+
caller: "required"
|
|
16970
|
+
}), method(object({ id: string().min(1) }), object({
|
|
16971
|
+
revoked: boolean(),
|
|
16972
|
+
sessionsEnded: number().int(),
|
|
16973
|
+
status: DeviceCredentialStatusSchema
|
|
16974
|
+
}), {
|
|
16975
|
+
kind: "mutation",
|
|
16976
|
+
auth: "admin",
|
|
16977
|
+
caller: "required"
|
|
16978
|
+
}), method(object({}), DeviceCertificateSettingsSchema, { auth: "admin" }), method(DeviceCertificateSettingsSchema, DeviceCertificateSettingsSchema, {
|
|
16979
|
+
kind: "mutation",
|
|
16980
|
+
auth: "admin"
|
|
16981
|
+
}), method(object({ id: string().min(1) }), object({ result: _enum([
|
|
16982
|
+
"deleted",
|
|
16983
|
+
"live",
|
|
16984
|
+
"unknown"
|
|
16985
|
+
]) }), {
|
|
16986
|
+
kind: "mutation",
|
|
16987
|
+
auth: "admin",
|
|
16988
|
+
caller: "required"
|
|
16989
|
+
}), method(object({}), DeviceCaStatusSchema, { auth: "admin" }), method(object({
|
|
16990
|
+
id: string().min(1),
|
|
16991
|
+
deviceName: string().min(1).max(80)
|
|
16992
|
+
}), object({ renamed: boolean() }), {
|
|
16993
|
+
kind: "mutation",
|
|
16994
|
+
auth: "admin"
|
|
16995
|
+
});
|
|
16996
|
+
/**
|
|
16997
|
+
* `node-certificates` - what a node holds and the two renewals the hub drives
|
|
16998
|
+
* (D856): the node's MESH leaf (mutual TLS to the hub) and its HTTPS leaf (issued
|
|
16999
|
+
* from the hub's local CA so a device that trusts the hub root trusts the node).
|
|
17000
|
+
*
|
|
17001
|
+
* Provided by the AGENT RUNTIME (the synthetic `agent-runtime` addon id, like
|
|
17002
|
+
* `server-management`): the hub reaches it through the ordinary node-pinned
|
|
17003
|
+
* capability call - no new Moleculer action. The hub's own certificates are
|
|
17004
|
+
* handled in-process by the hub (`certificates` router), so this cap has no hub
|
|
17005
|
+
* provider.
|
|
17006
|
+
*
|
|
17007
|
+
* No private key ever crosses the mesh: the node generates its key pair, sends a
|
|
17008
|
+
* CSR, and the hub returns only the signed certificate.
|
|
17009
|
+
*/
|
|
17010
|
+
var MeshLeafInfoSchema = object({
|
|
17011
|
+
cn: string(),
|
|
17012
|
+
serial: string(),
|
|
17013
|
+
fingerprintSha256: string(),
|
|
17014
|
+
notBefore: number(),
|
|
17015
|
+
notAfter: number()
|
|
17016
|
+
});
|
|
17017
|
+
var HttpsLeafInfoSchema = object({
|
|
17018
|
+
fingerprintSha256: string(),
|
|
17019
|
+
issuer: string(),
|
|
17020
|
+
sans: array(string()),
|
|
17021
|
+
notBefore: number(),
|
|
17022
|
+
notAfter: number()
|
|
17023
|
+
});
|
|
17024
|
+
var NodeHttpsStateSchema = discriminatedUnion("state", [object({
|
|
17025
|
+
state: literal("served"),
|
|
17026
|
+
leaf: HttpsLeafInfoSchema
|
|
17027
|
+
}), object({
|
|
17028
|
+
state: literal("not-issued"),
|
|
17029
|
+
reason: string()
|
|
17030
|
+
})]);
|
|
17031
|
+
method(object({}), object({
|
|
17032
|
+
nodeId: string(),
|
|
17033
|
+
mesh: MeshLeafInfoSchema.nullable(),
|
|
17034
|
+
https: NodeHttpsStateSchema
|
|
17035
|
+
}), { auth: "admin" }), method(object({}), object({ csrPem: string() }), {
|
|
17036
|
+
kind: "mutation",
|
|
17037
|
+
auth: "admin"
|
|
17038
|
+
}), method(object({
|
|
17039
|
+
certPem: string().min(1),
|
|
17040
|
+
caCertPem: string().min(1),
|
|
17041
|
+
confirmWithinMs: number().int().min(1e4).max(6e5)
|
|
17042
|
+
}), object({
|
|
17043
|
+
fingerprintSha256: string(),
|
|
17044
|
+
serial: string()
|
|
17045
|
+
}), {
|
|
17046
|
+
kind: "mutation",
|
|
17047
|
+
auth: "admin"
|
|
17048
|
+
}), method(object({ fingerprintSha256: string() }), object({ confirmed: boolean() }), {
|
|
17049
|
+
kind: "mutation",
|
|
17050
|
+
auth: "admin"
|
|
17051
|
+
}), method(object({}), object({ rolledBack: boolean() }), {
|
|
17052
|
+
kind: "mutation",
|
|
17053
|
+
auth: "admin"
|
|
17054
|
+
}), method(object({}), object({
|
|
17055
|
+
csrPem: string(),
|
|
17056
|
+
hostnames: array(string()),
|
|
17057
|
+
addresses: array(string()),
|
|
17058
|
+
/** SHA-256 of the hub local CA this node pinned at its first install; `null` before one. */
|
|
17059
|
+
pinnedCaFingerprintSha256: string().nullable()
|
|
17060
|
+
}), {
|
|
17061
|
+
kind: "mutation",
|
|
17062
|
+
auth: "admin"
|
|
17063
|
+
}), method(object({}), object({ ok: literal(true) }), {
|
|
17064
|
+
kind: "mutation",
|
|
17065
|
+
auth: "admin"
|
|
17066
|
+
}), method(object({
|
|
17067
|
+
certPem: string().min(1),
|
|
17068
|
+
caCertPem: string().min(1),
|
|
17069
|
+
/**
|
|
17070
|
+
* The hub signals that its local CA was rotated (D227) and this leaf chains to the NEW
|
|
17071
|
+
* one. Only the hub, over the authenticated mesh, can say so; a leaf with a different CA
|
|
17072
|
+
* and no signal is refused.
|
|
17073
|
+
*/
|
|
17074
|
+
caRotation: boolean().optional()
|
|
17075
|
+
}), HttpsLeafInfoSchema, {
|
|
17076
|
+
kind: "mutation",
|
|
17077
|
+
auth: "admin"
|
|
17078
|
+
});
|
|
16530
17079
|
var KeychainKeySourceSchema = object({
|
|
16531
17080
|
kind: _enum([
|
|
16532
17081
|
"config-file",
|
|
@@ -17114,6 +17663,10 @@ var deviceDiscoveryCapability = {
|
|
|
17114
17663
|
* `scripts/check-runtime-state-durability.ts`.
|
|
17115
17664
|
*/
|
|
17116
17665
|
durability: "session",
|
|
17666
|
+
/**
|
|
17667
|
+
* History (D850): none — inventory.
|
|
17668
|
+
*/
|
|
17669
|
+
history: "none",
|
|
17117
17670
|
methods: {
|
|
17118
17671
|
/**
|
|
17119
17672
|
* Snapshot of the current `discovered` list. Returns the
|
|
@@ -37895,6 +38448,38 @@ var DeviceRegisterPayloadSchema = object({
|
|
|
37895
38448
|
* omits it and the keyword backstop applies. */
|
|
37896
38449
|
secretConfigPaths: array(string()).optional()
|
|
37897
38450
|
});
|
|
38451
|
+
/** One deleted device, kept by device-manager so an addon that missed the
|
|
38452
|
+
* deletion can still learn of it (D865). Written by the delete path ONLY. */
|
|
38453
|
+
var DeviceTombstoneSchema = object({
|
|
38454
|
+
deviceId: number().int().positive(),
|
|
38455
|
+
/** Epoch ms the device was deleted. */
|
|
38456
|
+
deletedAt: number(),
|
|
38457
|
+
/** The addon that owned the device when it was deleted. */
|
|
38458
|
+
providerAddonId: string()
|
|
38459
|
+
});
|
|
38460
|
+
/** Data held for one device that device-manager no longer knows. */
|
|
38461
|
+
var OrphanDeviceDataSchema = object({
|
|
38462
|
+
deviceId: number().int().positive(),
|
|
38463
|
+
/** Rows/files per store (`<addonId>:<store>`). */
|
|
38464
|
+
stores: record(string(), number().int().nonnegative())
|
|
38465
|
+
});
|
|
38466
|
+
var CleanupDeletedDevicesResultSchema = object({
|
|
38467
|
+
/**
|
|
38468
|
+
* `skipped` — the absence check could not be trusted (a device-list read
|
|
38469
|
+
* failed or the two reads disagreed); nothing was listed or deleted.
|
|
38470
|
+
* `dry-run` — `devices` is what a confirmed run would delete.
|
|
38471
|
+
* `cleaned` — `devices` is what was deleted.
|
|
38472
|
+
*/
|
|
38473
|
+
status: _enum([
|
|
38474
|
+
"skipped",
|
|
38475
|
+
"dry-run",
|
|
38476
|
+
"cleaned"
|
|
38477
|
+
]),
|
|
38478
|
+
reason: string().nullable(),
|
|
38479
|
+
devices: array(OrphanDeviceDataSchema),
|
|
38480
|
+
/** Implementers that could not be asked (their stores are not in `devices`). */
|
|
38481
|
+
unreachable: array(string())
|
|
38482
|
+
});
|
|
37898
38483
|
var DeviceRemovePayloadSchema = object({ deviceId: number() });
|
|
37899
38484
|
var DevicePersistConfigPayloadSchema = object({
|
|
37900
38485
|
deviceId: number(),
|
|
@@ -38133,6 +38718,9 @@ method(object({
|
|
|
38133
38718
|
}), method(object({ deviceId: number() }), object({ success: literal(true) }), {
|
|
38134
38719
|
kind: "mutation",
|
|
38135
38720
|
auth: "admin"
|
|
38721
|
+
}), method(object({ sinceMs: number() }), array(DeviceTombstoneSchema).readonly(), { auth: "admin" }), method(object({ confirm: boolean() }), CleanupDeletedDevicesResultSchema, {
|
|
38722
|
+
kind: "mutation",
|
|
38723
|
+
auth: "admin"
|
|
38136
38724
|
}), method(object({ integrationId: string() }), object({ removed: number() }), {
|
|
38137
38725
|
kind: "mutation",
|
|
38138
38726
|
auth: "admin"
|
|
@@ -38595,6 +39183,72 @@ method(object({
|
|
|
38595
39183
|
auth: "admin"
|
|
38596
39184
|
});
|
|
38597
39185
|
/**
|
|
39186
|
+
* `device-removal-hook` — the reliable way an addon learns a device was DELETED,
|
|
39187
|
+
* so it can delete what it keeps for that device (D865).
|
|
39188
|
+
*
|
|
39189
|
+
* ## Why an event was not enough
|
|
39190
|
+
*
|
|
39191
|
+
* `DeviceUnregistered` is telemetry and may be dropped (D8, D11). An addon that
|
|
39192
|
+
* hung its per-device clean-up on it left durable garbage whenever the event was
|
|
39193
|
+
* lost, the addon was down, or it was restarting at that moment — footage,
|
|
39194
|
+
* analytics rows and settings of device 4483 outlived the device. Loss of this
|
|
39195
|
+
* signal corrupts durable state, so it travels by RPC with a recorded fact
|
|
39196
|
+
* behind it (D8: "if loss would corrupt durable state, use RPC plus a reconcile").
|
|
39197
|
+
*
|
|
39198
|
+
* ## The three pieces
|
|
39199
|
+
*
|
|
39200
|
+
* 1. device-manager records a TOMBSTONE per deleted device
|
|
39201
|
+
* (`deviceManager.listDeletedSince`). The tombstone is written by the delete
|
|
39202
|
+
* path only — a device that is unregistered, offline or whose provider is
|
|
39203
|
+
* restarting is NOT deleted and gets none.
|
|
39204
|
+
* 2. After a delete, device-manager calls `onDeviceRemoved` on EVERY provider of
|
|
39205
|
+
* this collection, one by one, with bounded retries, logged.
|
|
39206
|
+
* 3. An implementer that was down asks `deviceManager.listDeletedSince` at start
|
|
39207
|
+
* (and periodically) and runs its own `onDeviceRemoved` for each tombstone it
|
|
39208
|
+
* may have missed. Reconcile is driven by tombstones, never by "the device is
|
|
39209
|
+
* not in the current list": a failed or partial list read must not destroy data.
|
|
39210
|
+
*
|
|
39211
|
+
* ## Contract for an implementer
|
|
39212
|
+
*
|
|
39213
|
+
* - **Idempotent.** It is called again by a retry, by a reconcile and by the
|
|
39214
|
+
* admin cleanup of data that predates tombstones. A device with nothing left
|
|
39215
|
+
* answers zero counts.
|
|
39216
|
+
* - **One key per store** in `counts`, deleted rows/files per store, so the log
|
|
39217
|
+
* line and the admin dry run can say where the data was.
|
|
39218
|
+
* - **Training datasets are NOT device data** and are never deleted by a hook.
|
|
39219
|
+
* - **Per-device SETTINGS are not hooked.** Configuration lives in the standard
|
|
39220
|
+
* per-device store (`ctx.settings.*DeviceStore`), which device-manager clears
|
|
39221
|
+
* for every addon centrally at delete time. This hook is for device DATA
|
|
39222
|
+
* that is not settings: footage, event media, analytics rows, history.
|
|
39223
|
+
* - A provider that cannot tell is allowed to throw; the caller retries it.
|
|
39224
|
+
*
|
|
39225
|
+
* `listDeviceData` is the read side of the admin "Clean data of deleted devices"
|
|
39226
|
+
* action: which device ids this addon holds data for, and how much per store. It
|
|
39227
|
+
* never deletes. device-manager decides which of those ids are absent from the
|
|
39228
|
+
* fleet, from TWO consistent reads of the device list (D49).
|
|
39229
|
+
*/
|
|
39230
|
+
/** What a hook is told about the deletion. */
|
|
39231
|
+
var DeviceRemovedInputSchema = object({
|
|
39232
|
+
deviceId: number().int().positive(),
|
|
39233
|
+
/** Epoch ms the device was deleted (the tombstone's `deletedAt`). */
|
|
39234
|
+
deletedAt: number(),
|
|
39235
|
+
/** The addon that owned the device, as device-manager last knew it. */
|
|
39236
|
+
providerAddonId: string()
|
|
39237
|
+
});
|
|
39238
|
+
/** Rows/files/refs deleted, per store this implementer owns. */
|
|
39239
|
+
var DeviceRemovedResultSchema = object({ counts: record(string(), number().int().nonnegative()) });
|
|
39240
|
+
/** One (store, device) pair an implementer holds data for. */
|
|
39241
|
+
var DeviceDataEntrySchema = object({
|
|
39242
|
+
store: string(),
|
|
39243
|
+
deviceId: number().int().positive(),
|
|
39244
|
+
/** Rows (or files) held for the device in the store. */
|
|
39245
|
+
count: number().int().nonnegative()
|
|
39246
|
+
});
|
|
39247
|
+
method(DeviceRemovedInputSchema, DeviceRemovedResultSchema, {
|
|
39248
|
+
kind: "mutation",
|
|
39249
|
+
auth: "admin"
|
|
39250
|
+
}), method(_void(), array(DeviceDataEntrySchema).readonly(), { auth: "admin" });
|
|
39251
|
+
/**
|
|
38598
39252
|
* `failure-contribution` — the capability an addon reports its OWN losses
|
|
38599
39253
|
* through, per camera, with the denominator attached. It stores nothing.
|
|
38600
39254
|
*
|
|
@@ -39602,7 +40256,13 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
|
|
|
39602
40256
|
* `beginExternalLink` offer exactly the redirect methods that set this,
|
|
39603
40257
|
* whatever their id. Absent / false — a login button only.
|
|
39604
40258
|
*/
|
|
39605
|
-
linkable: boolean().optional()
|
|
40259
|
+
linkable: boolean().optional(),
|
|
40260
|
+
/**
|
|
40261
|
+
* How a NATIVE app starts this method (D858): `{ kind: 'browser', startPath }`
|
|
40262
|
+
* when the route understands the app flow query (`app=1&code_challenge=…`),
|
|
40263
|
+
* `null`/absent when there is no app path - the app hides the method.
|
|
40264
|
+
*/
|
|
40265
|
+
app: AppLoginPathSchema.nullable().optional()
|
|
39606
40266
|
}),
|
|
39607
40267
|
object({
|
|
39608
40268
|
kind: literal("widget"),
|
|
@@ -39614,7 +40274,9 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
|
|
|
39614
40274
|
bundle: string(),
|
|
39615
40275
|
/** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
|
|
39616
40276
|
remote: WidgetRemoteSchema,
|
|
39617
|
-
stage: LoginStageEnum
|
|
40277
|
+
stage: LoginStageEnum,
|
|
40278
|
+
/** Widgets are web ceremonies: no native app path (D858). Absent reads as `null`. */
|
|
40279
|
+
app: AppLoginPathSchema.nullable().optional()
|
|
39618
40280
|
}),
|
|
39619
40281
|
object({
|
|
39620
40282
|
kind: literal("passkey"),
|
|
@@ -39626,7 +40288,9 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
|
|
|
39626
40288
|
/** Effective WebAuthn RP ID (`resolveRpID()`) — the shell gates visibility on it. */
|
|
39627
40289
|
rpId: string(),
|
|
39628
40290
|
/** Effective expected origin (`resolveOrigin()`), null when unconfigured. */
|
|
39629
|
-
origin: string().nullable()
|
|
40291
|
+
origin: string().nullable(),
|
|
40292
|
+
/** Set by the hub for the primary arm; a second-factor passkey has no app path (D858). */
|
|
40293
|
+
app: AppLoginPathSchema.nullable().optional()
|
|
39630
40294
|
})
|
|
39631
40295
|
]);
|
|
39632
40296
|
method(_void(), array(LoginMethodContributionSchema).readonly());
|
|
@@ -40136,7 +40800,21 @@ var NetworkEndpointSchema = object({
|
|
|
40136
40800
|
url: string(),
|
|
40137
40801
|
hostname: string(),
|
|
40138
40802
|
port: number(),
|
|
40139
|
-
protocol: _enum(["http", "https"])
|
|
40803
|
+
protocol: _enum(["http", "https"]),
|
|
40804
|
+
/**
|
|
40805
|
+
* Whether this address survives a restart of its provider. `false` = it is
|
|
40806
|
+
* re-issued every time (a Quick tunnel's random `*.trycloudflare.com`); the
|
|
40807
|
+
* hub never selects such an address AUTOMATICALLY for a role (D860), though
|
|
40808
|
+
* it stays visible and an operator may still flag it. Absent = stable: every
|
|
40809
|
+
* provider except a Quick tunnel owns a name that does not change.
|
|
40810
|
+
*/
|
|
40811
|
+
stable: boolean().optional()
|
|
40812
|
+
});
|
|
40813
|
+
object({
|
|
40814
|
+
url: string(),
|
|
40815
|
+
/** Mirrors {@link NetworkEndpointSchema} `stable`; absent = stable. */
|
|
40816
|
+
stable: boolean().optional(),
|
|
40817
|
+
updated: boolean().optional()
|
|
40140
40818
|
});
|
|
40141
40819
|
var NetworkAccessStatusSchema = object({
|
|
40142
40820
|
connected: boolean(),
|
|
@@ -41233,6 +41911,10 @@ var alarmPanelCapability = {
|
|
|
41233
41911
|
* `scripts/check-runtime-state-durability.ts`.
|
|
41234
41912
|
*/
|
|
41235
41913
|
durability: "restored",
|
|
41914
|
+
/**
|
|
41915
|
+
* History (D850): none — enum state; arm/disarm history belongs in the events ledger.
|
|
41916
|
+
*/
|
|
41917
|
+
history: "none",
|
|
41236
41918
|
/** Clock fields: written, but excluded from the compare that decides
|
|
41237
41919
|
* whether persisting is worth a SQLite commit. */
|
|
41238
41920
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -47884,7 +48566,11 @@ var zonesCapability = {
|
|
|
47884
48566
|
* See `RuntimeStateDurability`. Enforced by
|
|
47885
48567
|
* `scripts/check-runtime-state-durability.ts`.
|
|
47886
48568
|
*/
|
|
47887
|
-
durability: "restored"
|
|
48569
|
+
durability: "restored",
|
|
48570
|
+
/**
|
|
48571
|
+
* History (D850): none — configuration arrays.
|
|
48572
|
+
*/
|
|
48573
|
+
history: "none"
|
|
47888
48574
|
};
|
|
47889
48575
|
/**
|
|
47890
48576
|
* A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
|
|
@@ -50341,7 +51027,22 @@ var SsoBridgeClaimsSchema = object({
|
|
|
50341
51027
|
* request to present the matching cookie — a login bridge is useless in
|
|
50342
51028
|
* any other browser.
|
|
50343
51029
|
*/
|
|
50344
|
-
browserBinding: string().optional()
|
|
51030
|
+
browserBinding: string().optional(),
|
|
51031
|
+
/**
|
|
51032
|
+
* The native app that started this sign-in (D858): its PKCE challenge,
|
|
51033
|
+
* `state`, purpose and allow-listed return URL, copied from the server-side
|
|
51034
|
+
* pending OIDC state. A bridge carrying it is finished ONLY at
|
|
51035
|
+
* `/api/auth/sso/finish-app` (which mints a handoff code, never a web
|
|
51036
|
+
* session); `/api/auth/sso/finish` refuses it.
|
|
51037
|
+
*/
|
|
51038
|
+
app: object({
|
|
51039
|
+
codeChallenge: string(),
|
|
51040
|
+
state: string(),
|
|
51041
|
+
purpose: _enum(["new-session", "step-up"]),
|
|
51042
|
+
redirect: string(),
|
|
51043
|
+
/** The page language the app asked for (D858); the confirm page speaks it. */
|
|
51044
|
+
lang: _enum(["en", "it"]).optional()
|
|
51045
|
+
}).optional()
|
|
50345
51046
|
});
|
|
50346
51047
|
method(object({
|
|
50347
51048
|
claims: SsoBridgeClaimsSchema,
|
|
@@ -50728,6 +51429,10 @@ var streamSignalsCapability = {
|
|
|
50728
51429
|
* `scripts/check-runtime-state-durability.ts`.
|
|
50729
51430
|
*/
|
|
50730
51431
|
durability: "session",
|
|
51432
|
+
/**
|
|
51433
|
+
* History (D850): none — array state.
|
|
51434
|
+
*/
|
|
51435
|
+
history: "none",
|
|
50731
51436
|
methods: {
|
|
50732
51437
|
/**
|
|
50733
51438
|
* What this device can emit. Empty is a valid and common answer — most
|
|
@@ -52994,7 +53699,12 @@ var SearchResultSchema = object({
|
|
|
52994
53699
|
publishedAt: string(),
|
|
52995
53700
|
author: string(),
|
|
52996
53701
|
installed: boolean(),
|
|
52997
|
-
installedVersion: string().optional()
|
|
53702
|
+
installedVersion: string().optional(),
|
|
53703
|
+
/**
|
|
53704
|
+
* Capability names the package's addons declare (from its published
|
|
53705
|
+
* manifest). `null` = the registry lookup failed — unknown, never `[]` (D393).
|
|
53706
|
+
*/
|
|
53707
|
+
capabilities: array(string()).readonly().nullable()
|
|
52998
53708
|
});
|
|
52999
53709
|
var AutoUpdateSettingsSchema = object({
|
|
53000
53710
|
channel: ChannelSchema,
|
|
@@ -53156,7 +53866,11 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
53156
53866
|
}), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
|
|
53157
53867
|
kind: "mutation",
|
|
53158
53868
|
auth: "admin"
|
|
53159
|
-
}), method(object({
|
|
53869
|
+
}), method(object({
|
|
53870
|
+
query: string().optional(),
|
|
53871
|
+
/** Only packages whose addons declare this capability (unknown ones excluded). */
|
|
53872
|
+
capability: string().optional()
|
|
53873
|
+
}), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
|
|
53160
53874
|
name: string().min(1),
|
|
53161
53875
|
version: string().optional(),
|
|
53162
53876
|
nodeId: string().optional()
|
|
@@ -53292,6 +54006,36 @@ var airQualitySensorCapability = {
|
|
|
53292
54006
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53293
54007
|
*/
|
|
53294
54008
|
durability: "restored",
|
|
54009
|
+
/**
|
|
54010
|
+
* History (D850): recorded series.
|
|
54011
|
+
*/
|
|
54012
|
+
history: { fields: {
|
|
54013
|
+
co2Ppm: {
|
|
54014
|
+
kind: "gauge",
|
|
54015
|
+
unit: "ppm",
|
|
54016
|
+
deadband: 5
|
|
54017
|
+
},
|
|
54018
|
+
vocPpb: {
|
|
54019
|
+
kind: "gauge",
|
|
54020
|
+
unit: "ppb",
|
|
54021
|
+
deadband: 5
|
|
54022
|
+
},
|
|
54023
|
+
pm25: {
|
|
54024
|
+
kind: "gauge",
|
|
54025
|
+
unit: "ug/m3",
|
|
54026
|
+
deadband: 1
|
|
54027
|
+
},
|
|
54028
|
+
pm10: {
|
|
54029
|
+
kind: "gauge",
|
|
54030
|
+
unit: "ug/m3",
|
|
54031
|
+
deadband: 1
|
|
54032
|
+
},
|
|
54033
|
+
aqi: {
|
|
54034
|
+
kind: "gauge",
|
|
54035
|
+
unit: "count",
|
|
54036
|
+
deadband: 1
|
|
54037
|
+
}
|
|
54038
|
+
} },
|
|
53295
54039
|
/** Clock fields: written, but excluded from the compare that decides
|
|
53296
54040
|
* whether persisting is worth a SQLite commit. */
|
|
53297
54041
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -53334,6 +54078,15 @@ var ambientLightSensorCapability = {
|
|
|
53334
54078
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53335
54079
|
*/
|
|
53336
54080
|
durability: "restored",
|
|
54081
|
+
/**
|
|
54082
|
+
* History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
|
|
54083
|
+
*/
|
|
54084
|
+
history: { fields: { lux: {
|
|
54085
|
+
kind: "gauge",
|
|
54086
|
+
unit: "lx",
|
|
54087
|
+
deadbandPct: 10,
|
|
54088
|
+
minIntervalMs: 6e4
|
|
54089
|
+
} } },
|
|
53337
54090
|
/** Clock fields: written, but excluded from the compare that decides
|
|
53338
54091
|
* whether persisting is worth a SQLite commit. */
|
|
53339
54092
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -53461,7 +54214,11 @@ var audioMetricsCapability = {
|
|
|
53461
54214
|
* See `RuntimeStateDurability`. Enforced by
|
|
53462
54215
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53463
54216
|
*/
|
|
53464
|
-
durability: "session"
|
|
54217
|
+
durability: "session",
|
|
54218
|
+
/**
|
|
54219
|
+
* History (D850): none — the level is the addon series `pipeline-analytics/audio-level` (producer `record`); the other numbers move every inference window and duplicate it.
|
|
54220
|
+
*/
|
|
54221
|
+
history: "none"
|
|
53465
54222
|
};
|
|
53466
54223
|
/**
|
|
53467
54224
|
* Automation-control cap. Models HA `automation.*` entities on
|
|
@@ -53530,7 +54287,11 @@ var automationControlCapability = {
|
|
|
53530
54287
|
* See `RuntimeStateDurability`. Enforced by
|
|
53531
54288
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53532
54289
|
*/
|
|
53533
|
-
durability: "session"
|
|
54290
|
+
durability: "session",
|
|
54291
|
+
/**
|
|
54292
|
+
* History (D850): none — configuration and transient run state.
|
|
54293
|
+
*/
|
|
54294
|
+
history: "none"
|
|
53534
54295
|
};
|
|
53535
54296
|
/**
|
|
53536
54297
|
* Battery status snapshot. Emitted by providers whose device is
|
|
@@ -53711,6 +54472,13 @@ onStatusChanged: { data: object({
|
|
|
53711
54472
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53712
54473
|
*/
|
|
53713
54474
|
durability: "restored",
|
|
54475
|
+
/**
|
|
54476
|
+
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
54477
|
+
*/
|
|
54478
|
+
history: { fields: { percentage: {
|
|
54479
|
+
kind: "gauge",
|
|
54480
|
+
unit: "%"
|
|
54481
|
+
} } },
|
|
53714
54482
|
/** Clock fields: written, but excluded from the compare that decides
|
|
53715
54483
|
* whether persisting is worth a SQLite commit. */
|
|
53716
54484
|
volatileStateFields: ["lastUpdated"]
|
|
@@ -53750,6 +54518,10 @@ var binaryCapability = {
|
|
|
53750
54518
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53751
54519
|
*/
|
|
53752
54520
|
durability: "restored",
|
|
54521
|
+
/**
|
|
54522
|
+
* History (D850): recorded series.
|
|
54523
|
+
*/
|
|
54524
|
+
history: { fields: { on: { kind: "boolean" } } },
|
|
53753
54525
|
/** Clock fields: written, but excluded from the compare that decides
|
|
53754
54526
|
* whether persisting is worth a SQLite commit. */
|
|
53755
54527
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -53812,7 +54584,15 @@ onBrightnessChanged: { data: object({
|
|
|
53812
54584
|
* See `RuntimeStateDurability`. Enforced by
|
|
53813
54585
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53814
54586
|
*/
|
|
53815
|
-
durability: "session"
|
|
54587
|
+
durability: "session",
|
|
54588
|
+
/**
|
|
54589
|
+
* History (D850): recorded series. Actuator tier: level keeps every change.
|
|
54590
|
+
*/
|
|
54591
|
+
history: { fields: { percentage: {
|
|
54592
|
+
kind: "gauge",
|
|
54593
|
+
unit: "%",
|
|
54594
|
+
minIntervalMs: 0
|
|
54595
|
+
} } }
|
|
53816
54596
|
};
|
|
53817
54597
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
53818
54598
|
kind: "mutation",
|
|
@@ -54146,6 +54926,10 @@ var carbonMonoxideCapability = {
|
|
|
54146
54926
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54147
54927
|
*/
|
|
54148
54928
|
durability: "restored",
|
|
54929
|
+
/**
|
|
54930
|
+
* History (D850): recorded series.
|
|
54931
|
+
*/
|
|
54932
|
+
history: { fields: { detected: { kind: "boolean" } } },
|
|
54149
54933
|
/** Clock fields: written, but excluded from the compare that decides
|
|
54150
54934
|
* whether persisting is worth a SQLite commit. */
|
|
54151
54935
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -54315,7 +55099,37 @@ var climateControlCapability = {
|
|
|
54315
55099
|
* See `RuntimeStateDurability`. Enforced by
|
|
54316
55100
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54317
55101
|
*/
|
|
54318
|
-
durability: "session"
|
|
55102
|
+
durability: "session",
|
|
55103
|
+
/**
|
|
55104
|
+
* History (D850): recorded series. Celsius by contract; setpoints keep every change (`minIntervalMs: 0`).
|
|
55105
|
+
*/
|
|
55106
|
+
history: { fields: {
|
|
55107
|
+
currentTemp: {
|
|
55108
|
+
kind: "gauge",
|
|
55109
|
+
unit: "°C",
|
|
55110
|
+
deadband: .1
|
|
55111
|
+
},
|
|
55112
|
+
currentHumidity: {
|
|
55113
|
+
kind: "gauge",
|
|
55114
|
+
unit: "%",
|
|
55115
|
+
deadband: .5
|
|
55116
|
+
},
|
|
55117
|
+
target: {
|
|
55118
|
+
kind: "gauge",
|
|
55119
|
+
unit: "°C",
|
|
55120
|
+
minIntervalMs: 0
|
|
55121
|
+
},
|
|
55122
|
+
targetHigh: {
|
|
55123
|
+
kind: "gauge",
|
|
55124
|
+
unit: "°C",
|
|
55125
|
+
minIntervalMs: 0
|
|
55126
|
+
},
|
|
55127
|
+
targetLow: {
|
|
55128
|
+
kind: "gauge",
|
|
55129
|
+
unit: "°C",
|
|
55130
|
+
minIntervalMs: 0
|
|
55131
|
+
}
|
|
55132
|
+
} }
|
|
54319
55133
|
};
|
|
54320
55134
|
/**
|
|
54321
55135
|
* Color-light cap. Coexists with `switch` (on/off) and `brightness`
|
|
@@ -54432,7 +55246,11 @@ onColorChanged: { data: object({
|
|
|
54432
55246
|
* See `RuntimeStateDurability`. Enforced by
|
|
54433
55247
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54434
55248
|
*/
|
|
54435
|
-
durability: "session"
|
|
55249
|
+
durability: "session",
|
|
55250
|
+
/**
|
|
55251
|
+
* History (D850): none — nested and cosmetic.
|
|
55252
|
+
*/
|
|
55253
|
+
history: "none"
|
|
54436
55254
|
};
|
|
54437
55255
|
var ConnectionTestOutcomeSchema = discriminatedUnion("outcome", [
|
|
54438
55256
|
object({
|
|
@@ -54498,6 +55316,10 @@ var connectivityCapability = {
|
|
|
54498
55316
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54499
55317
|
*/
|
|
54500
55318
|
durability: "restored",
|
|
55319
|
+
/**
|
|
55320
|
+
* History (D850): none — duplicates device-status.online (one authority for availability).
|
|
55321
|
+
*/
|
|
55322
|
+
history: "none",
|
|
54501
55323
|
/** Clock fields: written, but excluded from the compare that decides
|
|
54502
55324
|
* whether persisting is worth a SQLite commit. */
|
|
54503
55325
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -54622,6 +55444,10 @@ reset: method(object({
|
|
|
54622
55444
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54623
55445
|
*/
|
|
54624
55446
|
durability: "restored",
|
|
55447
|
+
/**
|
|
55448
|
+
* History (D850): none — `items` is an array keyed by runtime ids; a history path never enters it.
|
|
55449
|
+
*/
|
|
55450
|
+
history: "none",
|
|
54625
55451
|
/** Clocks, not content: a re-read that changed no item costs no commit. */
|
|
54626
55452
|
volatileStateFields: ["lastChangedAt", "lastFetchedAt"]
|
|
54627
55453
|
};
|
|
@@ -54662,6 +55488,10 @@ var contactCapability = {
|
|
|
54662
55488
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54663
55489
|
*/
|
|
54664
55490
|
durability: "restored",
|
|
55491
|
+
/**
|
|
55492
|
+
* History (D850): recorded series.
|
|
55493
|
+
*/
|
|
55494
|
+
history: { fields: { entryOpen: { kind: "boolean" } } },
|
|
54665
55495
|
/** Clock fields: written, but excluded from the compare that decides
|
|
54666
55496
|
* whether persisting is worth a SQLite commit. */
|
|
54667
55497
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -54777,7 +55607,11 @@ var controlCapability = {
|
|
|
54777
55607
|
* See `RuntimeStateDurability`. Enforced by
|
|
54778
55608
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54779
55609
|
*/
|
|
54780
|
-
durability: "session"
|
|
55610
|
+
durability: "session",
|
|
55611
|
+
/**
|
|
55612
|
+
* History (D850): none — `value` is a number/string union; configuration entity.
|
|
55613
|
+
*/
|
|
55614
|
+
history: "none"
|
|
54781
55615
|
};
|
|
54782
55616
|
var CoverStatusSchema = object({
|
|
54783
55617
|
/** Lifecycle state of the cover. */
|
|
@@ -54846,6 +55680,14 @@ var coverCapability = {
|
|
|
54846
55680
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54847
55681
|
*/
|
|
54848
55682
|
durability: "restored",
|
|
55683
|
+
/**
|
|
55684
|
+
* History (D850): recorded series. Actuator tier: position keeps every tick of a movement.
|
|
55685
|
+
*/
|
|
55686
|
+
history: { fields: { position: {
|
|
55687
|
+
kind: "gauge",
|
|
55688
|
+
unit: "%",
|
|
55689
|
+
minIntervalMs: 0
|
|
55690
|
+
} } },
|
|
54849
55691
|
/** Clock fields: written, but excluded from the compare that decides
|
|
54850
55692
|
* whether persisting is worth a SQLite commit. */
|
|
54851
55693
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -54950,6 +55792,10 @@ var dayNightCapability = {
|
|
|
54950
55792
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54951
55793
|
*/
|
|
54952
55794
|
durability: "restored",
|
|
55795
|
+
/**
|
|
55796
|
+
* History (D850): none — firmware configuration, not a measurement.
|
|
55797
|
+
*/
|
|
55798
|
+
history: "none",
|
|
54953
55799
|
/** Clock fields: written, but excluded from the compare that decides
|
|
54954
55800
|
* whether persisting is worth a SQLite commit. */
|
|
54955
55801
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -55007,6 +55853,10 @@ onStatusChanged: { data: object({
|
|
|
55007
55853
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55008
55854
|
*/
|
|
55009
55855
|
durability: "restored",
|
|
55856
|
+
/**
|
|
55857
|
+
* History (D850): recorded series. The ONE availability series.
|
|
55858
|
+
*/
|
|
55859
|
+
history: { fields: { online: { kind: "boolean" } } },
|
|
55010
55860
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55011
55861
|
* whether persisting is worth a SQLite commit. */
|
|
55012
55862
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -55073,7 +55923,11 @@ onPressed: {
|
|
|
55073
55923
|
* See `RuntimeStateDurability`. Enforced by
|
|
55074
55924
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55075
55925
|
*/
|
|
55076
|
-
durability: "restored"
|
|
55926
|
+
durability: "restored",
|
|
55927
|
+
/**
|
|
55928
|
+
* History (D850): none — `pressCountSinceStart` resets with the addon, so it is not a monotonic meter; presses live in the events ledger.
|
|
55929
|
+
*/
|
|
55930
|
+
history: "none"
|
|
55077
55931
|
};
|
|
55078
55932
|
/**
|
|
55079
55933
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
@@ -55121,6 +55975,10 @@ var enumSensorCapability = {
|
|
|
55121
55975
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55122
55976
|
*/
|
|
55123
55977
|
durability: "restored",
|
|
55978
|
+
/**
|
|
55979
|
+
* History (D850): none — text/enum state has no history (non-goal).
|
|
55980
|
+
*/
|
|
55981
|
+
history: "none",
|
|
55124
55982
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55125
55983
|
* whether persisting is worth a SQLite commit. */
|
|
55126
55984
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -55166,7 +56024,11 @@ var eventEmitterCapability = {
|
|
|
55166
56024
|
* See `RuntimeStateDurability`. Enforced by
|
|
55167
56025
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55168
56026
|
*/
|
|
55169
|
-
durability: "session"
|
|
56027
|
+
durability: "session",
|
|
56028
|
+
/**
|
|
56029
|
+
* History (D850): none — `eventCountSinceStart` resets with the addon; events live in ledgers.
|
|
56030
|
+
*/
|
|
56031
|
+
history: "none"
|
|
55170
56032
|
};
|
|
55171
56033
|
var IdentitySchema = object({
|
|
55172
56034
|
id: string(),
|
|
@@ -55623,7 +56485,18 @@ var fanControlCapability = {
|
|
|
55623
56485
|
* See `RuntimeStateDurability`. Enforced by
|
|
55624
56486
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55625
56487
|
*/
|
|
55626
|
-
durability: "session"
|
|
56488
|
+
durability: "session",
|
|
56489
|
+
/**
|
|
56490
|
+
* History (D850): recorded series. Actuator tier: speed keeps every change.
|
|
56491
|
+
*/
|
|
56492
|
+
history: { fields: {
|
|
56493
|
+
percentage: {
|
|
56494
|
+
kind: "gauge",
|
|
56495
|
+
unit: "%",
|
|
56496
|
+
minIntervalMs: 0
|
|
56497
|
+
},
|
|
56498
|
+
oscillating: { kind: "boolean" }
|
|
56499
|
+
} }
|
|
55627
56500
|
};
|
|
55628
56501
|
/**
|
|
55629
56502
|
* Per-device feature/identity probe slice. Holds the runtime-resolved
|
|
@@ -55706,7 +56579,11 @@ onProbeChanged: { data: object({
|
|
|
55706
56579
|
* See `RuntimeStateDurability`. Enforced by
|
|
55707
56580
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55708
56581
|
*/
|
|
55709
|
-
durability: "session"
|
|
56582
|
+
durability: "session",
|
|
56583
|
+
/**
|
|
56584
|
+
* History (D850): none — static identity and capability probe.
|
|
56585
|
+
*/
|
|
56586
|
+
history: "none"
|
|
55710
56587
|
};
|
|
55711
56588
|
/**
|
|
55712
56589
|
* Water leak / moisture sensor. Boolean "is liquid currently
|
|
@@ -55741,6 +56618,10 @@ var floodCapability = {
|
|
|
55741
56618
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55742
56619
|
*/
|
|
55743
56620
|
durability: "restored",
|
|
56621
|
+
/**
|
|
56622
|
+
* History (D850): recorded series.
|
|
56623
|
+
*/
|
|
56624
|
+
history: { fields: { flooded: { kind: "boolean" } } },
|
|
55744
56625
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55745
56626
|
* whether persisting is worth a SQLite commit. */
|
|
55746
56627
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -55774,6 +56655,10 @@ var gasCapability = {
|
|
|
55774
56655
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55775
56656
|
*/
|
|
55776
56657
|
durability: "restored",
|
|
56658
|
+
/**
|
|
56659
|
+
* History (D850): recorded series.
|
|
56660
|
+
*/
|
|
56661
|
+
history: { fields: { detected: { kind: "boolean" } } },
|
|
55777
56662
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55778
56663
|
* whether persisting is worth a SQLite commit. */
|
|
55779
56664
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -55859,7 +56744,18 @@ var humidifierCapability = {
|
|
|
55859
56744
|
* See `RuntimeStateDurability`. Enforced by
|
|
55860
56745
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55861
56746
|
*/
|
|
55862
|
-
durability: "session"
|
|
56747
|
+
durability: "session",
|
|
56748
|
+
/**
|
|
56749
|
+
* History (D850): recorded series.
|
|
56750
|
+
*/
|
|
56751
|
+
history: { fields: {
|
|
56752
|
+
currentHumidity: {
|
|
56753
|
+
kind: "gauge",
|
|
56754
|
+
unit: "%",
|
|
56755
|
+
deadband: .5
|
|
56756
|
+
},
|
|
56757
|
+
on: { kind: "boolean" }
|
|
56758
|
+
} }
|
|
55863
56759
|
};
|
|
55864
56760
|
/**
|
|
55865
56761
|
* Single-metric humidity reading. Drives Home Assistant `sensor`
|
|
@@ -55903,6 +56799,14 @@ var humiditySensorCapability = {
|
|
|
55903
56799
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55904
56800
|
*/
|
|
55905
56801
|
durability: "restored",
|
|
56802
|
+
/**
|
|
56803
|
+
* History (D850): recorded series.
|
|
56804
|
+
*/
|
|
56805
|
+
history: { fields: { percent: {
|
|
56806
|
+
kind: "gauge",
|
|
56807
|
+
unit: "%",
|
|
56808
|
+
deadband: .5
|
|
56809
|
+
} } },
|
|
55906
56810
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55907
56811
|
* whether persisting is worth a SQLite commit. */
|
|
55908
56812
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -55950,7 +56854,11 @@ var imageCapability = {
|
|
|
55950
56854
|
* See `RuntimeStateDurability`. Enforced by
|
|
55951
56855
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55952
56856
|
*/
|
|
55953
|
-
durability: "session"
|
|
56857
|
+
durability: "session",
|
|
56858
|
+
/**
|
|
56859
|
+
* History (D850): none — not numeric.
|
|
56860
|
+
*/
|
|
56861
|
+
history: "none"
|
|
55954
56862
|
};
|
|
55955
56863
|
/**
|
|
55956
56864
|
* Vendor-neutral image / picture-adjustment cap — the per-camera config
|
|
@@ -56107,6 +57015,10 @@ var imageSettingsCapability = {
|
|
|
56107
57015
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56108
57016
|
*/
|
|
56109
57017
|
durability: "restored",
|
|
57018
|
+
/**
|
|
57019
|
+
* History (D850): none — camera image configuration (operator intent), not a trend.
|
|
57020
|
+
*/
|
|
57021
|
+
history: "none",
|
|
56110
57022
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56111
57023
|
* whether persisting is worth a SQLite commit. */
|
|
56112
57024
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -56492,7 +57404,11 @@ var intercomCapability = {
|
|
|
56492
57404
|
* See `RuntimeStateDurability`. Enforced by
|
|
56493
57405
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56494
57406
|
*/
|
|
56495
|
-
durability: "session"
|
|
57407
|
+
durability: "session",
|
|
57408
|
+
/**
|
|
57409
|
+
* History (D850): none — talk sessions are a ledger concern, not a trend.
|
|
57410
|
+
*/
|
|
57411
|
+
history: "none"
|
|
56496
57412
|
};
|
|
56497
57413
|
/**
|
|
56498
57414
|
* Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
|
|
@@ -56573,7 +57489,15 @@ var lawnMowerControlCapability = {
|
|
|
56573
57489
|
* See `RuntimeStateDurability`. Enforced by
|
|
56574
57490
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56575
57491
|
*/
|
|
56576
|
-
durability: "session"
|
|
57492
|
+
durability: "session",
|
|
57493
|
+
/**
|
|
57494
|
+
* History (D850): recorded series.
|
|
57495
|
+
*/
|
|
57496
|
+
history: { fields: { batteryLevel: {
|
|
57497
|
+
kind: "gauge",
|
|
57498
|
+
unit: "%",
|
|
57499
|
+
deadband: 2
|
|
57500
|
+
} } }
|
|
56577
57501
|
};
|
|
56578
57502
|
/**
|
|
56579
57503
|
* local-network — hub-only singleton.
|
|
@@ -56700,7 +57624,13 @@ var ConnectionEndpointSchema = object({
|
|
|
56700
57624
|
* calls so the client can sort even if the cap returns a new
|
|
56701
57625
|
* ordering between polls.
|
|
56702
57626
|
*/
|
|
56703
|
-
priority: number()
|
|
57627
|
+
priority: number(),
|
|
57628
|
+
/**
|
|
57629
|
+
* `false` = the address changes on its own (a Quick tunnel, re-issued on
|
|
57630
|
+
* every respawn). Automatic role resolution skips it (D860); an explicit
|
|
57631
|
+
* operator flag still honours it. Absent = stable.
|
|
57632
|
+
*/
|
|
57633
|
+
stable: boolean().optional()
|
|
56704
57634
|
});
|
|
56705
57635
|
/**
|
|
56706
57636
|
* Where the advertised local port came from. Ordered most → least
|
|
@@ -56980,6 +57910,10 @@ var lockControlCapability = {
|
|
|
56980
57910
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56981
57911
|
*/
|
|
56982
57912
|
durability: "restored",
|
|
57913
|
+
/**
|
|
57914
|
+
* History (D850): none — enum state; lock events belong in the events ledger.
|
|
57915
|
+
*/
|
|
57916
|
+
history: "none",
|
|
56983
57917
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56984
57918
|
* whether persisting is worth a SQLite commit. */
|
|
56985
57919
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -57151,7 +58085,11 @@ var mediaPlayerCapability = {
|
|
|
57151
58085
|
* See `RuntimeStateDurability`. Enforced by
|
|
57152
58086
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57153
58087
|
*/
|
|
57154
|
-
durability: "session"
|
|
58088
|
+
durability: "session",
|
|
58089
|
+
/**
|
|
58090
|
+
* History (D850): none — `positionMs` moves continuously while playing; volume is transient.
|
|
58091
|
+
*/
|
|
58092
|
+
history: "none"
|
|
57155
58093
|
};
|
|
57156
58094
|
/**
|
|
57157
58095
|
* mesh-network — collection cap for mesh-VPN providers.
|
|
@@ -57460,7 +58398,14 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
|
|
|
57460
58398
|
* See `RuntimeStateDurability`. Enforced by
|
|
57461
58399
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57462
58400
|
*/
|
|
57463
|
-
durability: "session"
|
|
58401
|
+
durability: "session",
|
|
58402
|
+
/**
|
|
58403
|
+
* History (D850): recorded series. A PIR sensor is a series; a camera is not (its motion is an addon series and a ledger).
|
|
58404
|
+
*/
|
|
58405
|
+
history: { fields: { detected: {
|
|
58406
|
+
kind: "boolean",
|
|
58407
|
+
excludeDeviceTypes: [DeviceType.Camera]
|
|
58408
|
+
} } }
|
|
57464
58409
|
};
|
|
57465
58410
|
/**
|
|
57466
58411
|
* Motion-trigger toggle for accessory devices.
|
|
@@ -57532,7 +58477,11 @@ var motionTriggerCapability = {
|
|
|
57532
58477
|
* See `RuntimeStateDurability`. Enforced by
|
|
57533
58478
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57534
58479
|
*/
|
|
57535
|
-
durability: "session"
|
|
58480
|
+
durability: "session",
|
|
58481
|
+
/**
|
|
58482
|
+
* History (D850): none — configuration switch.
|
|
58483
|
+
*/
|
|
58484
|
+
history: "none"
|
|
57536
58485
|
};
|
|
57537
58486
|
/**
|
|
57538
58487
|
* Motion-zones share the same MaskShape vocabulary as privacy-mask — the
|
|
@@ -57607,6 +58556,10 @@ var motionZonesCapability = {
|
|
|
57607
58556
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57608
58557
|
*/
|
|
57609
58558
|
durability: "restored",
|
|
58559
|
+
/**
|
|
58560
|
+
* History (D850): none — configuration.
|
|
58561
|
+
*/
|
|
58562
|
+
history: "none",
|
|
57610
58563
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57611
58564
|
* whether persisting is worth a SQLite commit. */
|
|
57612
58565
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -57736,6 +58689,10 @@ var nativeObjectDetectionCapability = {
|
|
|
57736
58689
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57737
58690
|
*/
|
|
57738
58691
|
durability: "restored",
|
|
58692
|
+
/**
|
|
58693
|
+
* History (D850): none — event-like and nested per class; detections live in the objects ledger.
|
|
58694
|
+
*/
|
|
58695
|
+
history: "none",
|
|
57739
58696
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57740
58697
|
* whether persisting is worth a SQLite commit. */
|
|
57741
58698
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -58019,7 +58976,11 @@ var navigationCapability = {
|
|
|
58019
58976
|
* See `RuntimeStateDurability`. Enforced by
|
|
58020
58977
|
* `scripts/check-runtime-state-durability.ts`.
|
|
58021
58978
|
*/
|
|
58022
|
-
durability: "session"
|
|
58979
|
+
durability: "session",
|
|
58980
|
+
/**
|
|
58981
|
+
* History (D850): none — control state of a robotic camera, configuration-like.
|
|
58982
|
+
*/
|
|
58983
|
+
history: "none"
|
|
58023
58984
|
};
|
|
58024
58985
|
/**
|
|
58025
58986
|
* Network-link snapshot. Same shape for every provider (a Reolink wifi
|
|
@@ -58119,6 +59080,23 @@ onStatusChanged: { data: object({
|
|
|
58119
59080
|
* `scripts/check-runtime-state-durability.ts`.
|
|
58120
59081
|
*/
|
|
58121
59082
|
durability: "restored",
|
|
59083
|
+
/**
|
|
59084
|
+
* History (D850): recorded series.
|
|
59085
|
+
*/
|
|
59086
|
+
history: { fields: {
|
|
59087
|
+
signalPercent: {
|
|
59088
|
+
kind: "gauge",
|
|
59089
|
+
unit: "%",
|
|
59090
|
+
deadband: 3,
|
|
59091
|
+
minIntervalMs: 6e4
|
|
59092
|
+
},
|
|
59093
|
+
rssiDbm: {
|
|
59094
|
+
kind: "gauge",
|
|
59095
|
+
unit: "dBm",
|
|
59096
|
+
deadband: 2,
|
|
59097
|
+
minIntervalMs: 6e4
|
|
59098
|
+
}
|
|
59099
|
+
} },
|
|
58122
59100
|
/** Clock fields: written, but excluded from the compare that decides
|
|
58123
59101
|
* whether persisting is worth a SQLite commit. */
|
|
58124
59102
|
volatileStateFields: ["lastUpdated"]
|
|
@@ -58507,7 +59485,11 @@ onSent: { data: object({
|
|
|
58507
59485
|
* See `RuntimeStateDurability`. Enforced by
|
|
58508
59486
|
* `scripts/check-runtime-state-durability.ts`.
|
|
58509
59487
|
*/
|
|
58510
|
-
durability: "session"
|
|
59488
|
+
durability: "session",
|
|
59489
|
+
/**
|
|
59490
|
+
* History (D850): none — `queueDepth` is outbox operational state, not a device trend.
|
|
59491
|
+
*/
|
|
59492
|
+
history: "none"
|
|
58511
59493
|
};
|
|
58512
59494
|
/**
|
|
58513
59495
|
* Generic numeric sensor — last-resort fallback when no typed numeric
|
|
@@ -58558,6 +59540,14 @@ var numericSensorCapability = {
|
|
|
58558
59540
|
* `scripts/check-runtime-state-durability.ts`.
|
|
58559
59541
|
*/
|
|
58560
59542
|
durability: "restored",
|
|
59543
|
+
/**
|
|
59544
|
+
* History (D850): recorded series. The unit is per device, read from the sibling `unit` field.
|
|
59545
|
+
*/
|
|
59546
|
+
history: { fields: { value: {
|
|
59547
|
+
kind: "gauge",
|
|
59548
|
+
unitFrom: "unit",
|
|
59549
|
+
minIntervalMs: 3e4
|
|
59550
|
+
} } },
|
|
58561
59551
|
/** Clock fields: written, but excluded from the compare that decides
|
|
58562
59552
|
* whether persisting is worth a SQLite commit. */
|
|
58563
59553
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -59034,7 +60024,24 @@ var petFeederCapability = {
|
|
|
59034
60024
|
* See `RuntimeStateDurability`. Enforced by
|
|
59035
60025
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59036
60026
|
*/
|
|
59037
|
-
durability: "session"
|
|
60027
|
+
durability: "session",
|
|
60028
|
+
/**
|
|
60029
|
+
* History (D850): recorded series.
|
|
60030
|
+
*/
|
|
60031
|
+
history: { fields: {
|
|
60032
|
+
foodLevel: { kind: "gauge" },
|
|
60033
|
+
food1: { kind: "gauge" },
|
|
60034
|
+
food2: { kind: "gauge" },
|
|
60035
|
+
batteryPower: {
|
|
60036
|
+
kind: "gauge",
|
|
60037
|
+
unit: "%",
|
|
60038
|
+
deadband: 2
|
|
60039
|
+
},
|
|
60040
|
+
desiccantLeftDays: {
|
|
60041
|
+
kind: "gauge",
|
|
60042
|
+
unit: "days"
|
|
60043
|
+
}
|
|
60044
|
+
} }
|
|
59038
60045
|
};
|
|
59039
60046
|
var VehicleSchema = object({
|
|
59040
60047
|
id: string(),
|
|
@@ -59412,6 +60419,47 @@ var powerMeterCapability = {
|
|
|
59412
60419
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59413
60420
|
*/
|
|
59414
60421
|
durability: "restored",
|
|
60422
|
+
/**
|
|
60423
|
+
* History (D850): recorded series. Gauges are floored at 30 s; `kwhTotal` is the one monotonic meter (counter).
|
|
60424
|
+
*/
|
|
60425
|
+
history: { fields: {
|
|
60426
|
+
watts: {
|
|
60427
|
+
kind: "gauge",
|
|
60428
|
+
unit: "W",
|
|
60429
|
+
deadband: 1,
|
|
60430
|
+
minIntervalMs: 3e4
|
|
60431
|
+
},
|
|
60432
|
+
kwhTotal: {
|
|
60433
|
+
kind: "counter",
|
|
60434
|
+
unit: "kWh",
|
|
60435
|
+
deadband: .01,
|
|
60436
|
+
minIntervalMs: 6e4
|
|
60437
|
+
},
|
|
60438
|
+
volts: {
|
|
60439
|
+
kind: "gauge",
|
|
60440
|
+
unit: "V",
|
|
60441
|
+
deadband: 1,
|
|
60442
|
+
minIntervalMs: 3e4
|
|
60443
|
+
},
|
|
60444
|
+
amps: {
|
|
60445
|
+
kind: "gauge",
|
|
60446
|
+
unit: "A",
|
|
60447
|
+
deadband: .05,
|
|
60448
|
+
minIntervalMs: 3e4
|
|
60449
|
+
},
|
|
60450
|
+
va: {
|
|
60451
|
+
kind: "gauge",
|
|
60452
|
+
unit: "VA",
|
|
60453
|
+
deadband: 1,
|
|
60454
|
+
minIntervalMs: 3e4
|
|
60455
|
+
},
|
|
60456
|
+
powerFactor: {
|
|
60457
|
+
kind: "gauge",
|
|
60458
|
+
unit: "ratio",
|
|
60459
|
+
deadband: .01,
|
|
60460
|
+
minIntervalMs: 6e4
|
|
60461
|
+
}
|
|
60462
|
+
} },
|
|
59415
60463
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59416
60464
|
* whether persisting is worth a SQLite commit. */
|
|
59417
60465
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -59479,6 +60527,14 @@ var presenceCapability = {
|
|
|
59479
60527
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59480
60528
|
*/
|
|
59481
60529
|
durability: "restored",
|
|
60530
|
+
/**
|
|
60531
|
+
* History (D850): recorded series.
|
|
60532
|
+
*/
|
|
60533
|
+
history: { fields: { batteryPercent: {
|
|
60534
|
+
kind: "gauge",
|
|
60535
|
+
unit: "%",
|
|
60536
|
+
deadband: 1
|
|
60537
|
+
} } },
|
|
59482
60538
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59483
60539
|
* whether persisting is worth a SQLite commit. */
|
|
59484
60540
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -59525,6 +60581,14 @@ var pressureSensorCapability = {
|
|
|
59525
60581
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59526
60582
|
*/
|
|
59527
60583
|
durability: "restored",
|
|
60584
|
+
/**
|
|
60585
|
+
* History (D850): recorded series.
|
|
60586
|
+
*/
|
|
60587
|
+
history: { fields: { hpa: {
|
|
60588
|
+
kind: "gauge",
|
|
60589
|
+
unit: "hPa",
|
|
60590
|
+
deadband: .1
|
|
60591
|
+
} } },
|
|
59528
60592
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59529
60593
|
* whether persisting is worth a SQLite commit. */
|
|
59530
60594
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -59684,6 +60748,10 @@ var privacyMaskCapability = {
|
|
|
59684
60748
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59685
60749
|
*/
|
|
59686
60750
|
durability: "restored",
|
|
60751
|
+
/**
|
|
60752
|
+
* History (D850): none — configuration.
|
|
60753
|
+
*/
|
|
60754
|
+
history: "none",
|
|
59687
60755
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59688
60756
|
* whether persisting is worth a SQLite commit. */
|
|
59689
60757
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -60157,7 +61225,11 @@ var ptzAutotrackCapability = {
|
|
|
60157
61225
|
* See `RuntimeStateDurability`. Enforced by
|
|
60158
61226
|
* `scripts/check-runtime-state-durability.ts`.
|
|
60159
61227
|
*/
|
|
60160
|
-
durability: "session"
|
|
61228
|
+
durability: "session",
|
|
61229
|
+
/**
|
|
61230
|
+
* History (D850): none — configuration and capability.
|
|
61231
|
+
*/
|
|
61232
|
+
history: "none"
|
|
60161
61233
|
};
|
|
60162
61234
|
/**
|
|
60163
61235
|
* reboot — device-scoped capability for "soft" device reboots (firmware
|
|
@@ -61612,6 +62684,10 @@ var recordingOnboardCapability = {
|
|
|
61612
62684
|
* `scripts/check-runtime-state-durability.ts`.
|
|
61613
62685
|
*/
|
|
61614
62686
|
durability: "restored",
|
|
62687
|
+
/**
|
|
62688
|
+
* History (D850): none — SD-card configuration and window inventory; arrays.
|
|
62689
|
+
*/
|
|
62690
|
+
history: "none",
|
|
61615
62691
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61616
62692
|
* whether persisting is worth a SQLite commit. */
|
|
61617
62693
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -61850,7 +62926,11 @@ getStatus: method(object({ deviceId: number() }), RecordingSignalStatusSchema) }
|
|
|
61850
62926
|
* See `RuntimeStateDurability`. Enforced by
|
|
61851
62927
|
* `scripts/check-runtime-state-durability.ts`.
|
|
61852
62928
|
*/
|
|
61853
|
-
durability: "session"
|
|
62929
|
+
durability: "session",
|
|
62930
|
+
/**
|
|
62931
|
+
* History (D850): none — recording intent is already in the recordings ledger.
|
|
62932
|
+
*/
|
|
62933
|
+
history: "none"
|
|
61854
62934
|
};
|
|
61855
62935
|
/**
|
|
61856
62936
|
* scene-monitor — device-scoped reference-region state cap. An operator marks
|
|
@@ -62223,7 +63303,11 @@ var sceneMonitorCapability = {
|
|
|
62223
63303
|
* See `RuntimeStateDurability`. Enforced by
|
|
62224
63304
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62225
63305
|
*/
|
|
62226
|
-
durability: "session"
|
|
63306
|
+
durability: "session",
|
|
63307
|
+
/**
|
|
63308
|
+
* History (D850): none — nested configuration.
|
|
63309
|
+
*/
|
|
63310
|
+
history: "none"
|
|
62227
63311
|
};
|
|
62228
63312
|
/**
|
|
62229
63313
|
* Per-stage gating mode applied to the zones a rule references.
|
|
@@ -62374,7 +63458,11 @@ var scriptRunnerCapability = {
|
|
|
62374
63458
|
* See `RuntimeStateDurability`. Enforced by
|
|
62375
63459
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62376
63460
|
*/
|
|
62377
|
-
durability: "session"
|
|
63461
|
+
durability: "session",
|
|
63462
|
+
/**
|
|
63463
|
+
* History (D850): none — transient; run results belong in a ledger.
|
|
63464
|
+
*/
|
|
63465
|
+
history: "none"
|
|
62378
63466
|
};
|
|
62379
63467
|
/**
|
|
62380
63468
|
* Smoke alarm sensor — boolean "is smoke currently detected" with
|
|
@@ -62409,6 +63497,10 @@ var smokeCapability = {
|
|
|
62409
63497
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62410
63498
|
*/
|
|
62411
63499
|
durability: "restored",
|
|
63500
|
+
/**
|
|
63501
|
+
* History (D850): recorded series.
|
|
63502
|
+
*/
|
|
63503
|
+
history: { fields: { detected: { kind: "boolean" } } },
|
|
62412
63504
|
/** Clock fields: written, but excluded from the compare that decides
|
|
62413
63505
|
* whether persisting is worth a SQLite commit. */
|
|
62414
63506
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -62508,6 +63600,10 @@ var streamCatalogCapability = {
|
|
|
62508
63600
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62509
63601
|
*/
|
|
62510
63602
|
durability: "restored",
|
|
63603
|
+
/**
|
|
63604
|
+
* History (D850): none — stream inventory.
|
|
63605
|
+
*/
|
|
63606
|
+
history: "none",
|
|
62511
63607
|
/** Clock field: written, but excluded from the compare that decides whether
|
|
62512
63608
|
* persisting is worth a SQLite commit — the descriptors are the value. */
|
|
62513
63609
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -62657,6 +63753,10 @@ var streamParamsCapability = {
|
|
|
62657
63753
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62658
63754
|
*/
|
|
62659
63755
|
durability: "restored",
|
|
63756
|
+
/**
|
|
63757
|
+
* History (D850): none — encoder configuration.
|
|
63758
|
+
*/
|
|
63759
|
+
history: "none",
|
|
62660
63760
|
/** Clock fields: written, but excluded from the compare that decides
|
|
62661
63761
|
* whether persisting is worth a SQLite commit. */
|
|
62662
63762
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -62910,6 +64010,10 @@ var switchCapability = {
|
|
|
62910
64010
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62911
64011
|
*/
|
|
62912
64012
|
durability: "restored",
|
|
64013
|
+
/**
|
|
64014
|
+
* History (D850): recorded series.
|
|
64015
|
+
*/
|
|
64016
|
+
history: { fields: { on: { kind: "boolean" } } },
|
|
62913
64017
|
/** Clock fields: written, but excluded from the compare that decides
|
|
62914
64018
|
* whether persisting is worth a SQLite commit. */
|
|
62915
64019
|
volatileStateFields: ["lastChangedAt"],
|
|
@@ -62924,6 +64028,21 @@ var switchCapability = {
|
|
|
62924
64028
|
}
|
|
62925
64029
|
}] }
|
|
62926
64030
|
};
|
|
64031
|
+
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
64032
|
+
function hasControlCharacter(value) {
|
|
64033
|
+
for (const char of value) {
|
|
64034
|
+
const code = char.codePointAt(0) ?? 0;
|
|
64035
|
+
if (code <= 31 || code >= 127 && code <= 159) return true;
|
|
64036
|
+
}
|
|
64037
|
+
return false;
|
|
64038
|
+
}
|
|
64039
|
+
string().transform((value) => value.trim()).pipe(string().min(1, "The server name cannot be empty").max(48, `The server name is at most 48 characters`).refine((value) => !hasControlCharacter(value), { message: "The server name cannot contain control characters" }));
|
|
64040
|
+
/** What every reader gets: the name to show, and whether the hub chose it itself. */
|
|
64041
|
+
var ServerNameInfoSchema = object({
|
|
64042
|
+
name: string(),
|
|
64043
|
+
/** `true` when nobody named the hub: `name` is the machine hostname. */
|
|
64044
|
+
isDefault: boolean()
|
|
64045
|
+
});
|
|
62927
64046
|
/**
|
|
62928
64047
|
* system — system-scoped singleton capability exposing hub-level
|
|
62929
64048
|
* health, feature flags, network interface enumeration, and the
|
|
@@ -62953,6 +64072,12 @@ var FeatureManifestSchema = object({
|
|
|
62953
64072
|
backup: boolean(),
|
|
62954
64073
|
repl: boolean()
|
|
62955
64074
|
});
|
|
64075
|
+
/**
|
|
64076
|
+
* `system.info`: the feature flags plus the hub's human name (D861). The name is
|
|
64077
|
+
* `{ name, isDefault }` — `isDefault: true` means nobody named the hub and `name`
|
|
64078
|
+
* is the machine hostname.
|
|
64079
|
+
*/
|
|
64080
|
+
var SystemInfoSchema = FeatureManifestSchema.extend({ serverName: ServerNameInfoSchema });
|
|
62956
64081
|
var HealthStatusSchema = object({
|
|
62957
64082
|
status: literal("ok"),
|
|
62958
64083
|
uptime: number()
|
|
@@ -63425,7 +64550,7 @@ var LoggingSettingsStateSchema = object({
|
|
|
63425
64550
|
opsLogRetentionDays: number().int().min(0),
|
|
63426
64551
|
persisted: boolean()
|
|
63427
64552
|
});
|
|
63428
|
-
method(_void(),
|
|
64553
|
+
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(), {
|
|
63429
64554
|
kind: "mutation",
|
|
63430
64555
|
auth: "admin"
|
|
63431
64556
|
}), method(_void(), _void(), {
|
|
@@ -63471,6 +64596,10 @@ var tamperCapability = {
|
|
|
63471
64596
|
* `scripts/check-runtime-state-durability.ts`.
|
|
63472
64597
|
*/
|
|
63473
64598
|
durability: "restored",
|
|
64599
|
+
/**
|
|
64600
|
+
* History (D850): recorded series.
|
|
64601
|
+
*/
|
|
64602
|
+
history: { fields: { tampered: { kind: "boolean" } } },
|
|
63474
64603
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63475
64604
|
* whether persisting is worth a SQLite commit. */
|
|
63476
64605
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -63526,6 +64655,14 @@ var temperatureSensorCapability = {
|
|
|
63526
64655
|
* `scripts/check-runtime-state-durability.ts`.
|
|
63527
64656
|
*/
|
|
63528
64657
|
durability: "restored",
|
|
64658
|
+
/**
|
|
64659
|
+
* History (D850): recorded series.
|
|
64660
|
+
*/
|
|
64661
|
+
history: { fields: { celsius: {
|
|
64662
|
+
kind: "gauge",
|
|
64663
|
+
unit: "°C",
|
|
64664
|
+
deadband: .1
|
|
64665
|
+
} } },
|
|
63529
64666
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63530
64667
|
* whether persisting is worth a SQLite commit. */
|
|
63531
64668
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -63604,7 +64741,11 @@ var updateCapability = {
|
|
|
63604
64741
|
* See `RuntimeStateDurability`. Enforced by
|
|
63605
64742
|
* `scripts/check-runtime-state-durability.ts`.
|
|
63606
64743
|
*/
|
|
63607
|
-
durability: "session"
|
|
64744
|
+
durability: "session",
|
|
64745
|
+
/**
|
|
64746
|
+
* History (D850): none — text and state.
|
|
64747
|
+
*/
|
|
64748
|
+
history: "none"
|
|
63608
64749
|
};
|
|
63609
64750
|
var UserSummarySchema = object({
|
|
63610
64751
|
id: string(),
|
|
@@ -63961,7 +65102,37 @@ var vacuumControlCapability = {
|
|
|
63961
65102
|
* See `RuntimeStateDurability`. Enforced by
|
|
63962
65103
|
* `scripts/check-runtime-state-durability.ts`.
|
|
63963
65104
|
*/
|
|
63964
|
-
durability: "session"
|
|
65105
|
+
durability: "session",
|
|
65106
|
+
/**
|
|
65107
|
+
* History (D850): recorded series. Tank levels are fixed-object paths (`cleanWater.level`, ...).
|
|
65108
|
+
*/
|
|
65109
|
+
history: { fields: {
|
|
65110
|
+
batteryLevel: {
|
|
65111
|
+
kind: "gauge",
|
|
65112
|
+
unit: "%",
|
|
65113
|
+
deadband: 2
|
|
65114
|
+
},
|
|
65115
|
+
"cleanWater.level": {
|
|
65116
|
+
kind: "gauge",
|
|
65117
|
+
unit: "%",
|
|
65118
|
+
deadband: 2
|
|
65119
|
+
},
|
|
65120
|
+
"dirtyWater.level": {
|
|
65121
|
+
kind: "gauge",
|
|
65122
|
+
unit: "%",
|
|
65123
|
+
deadband: 2
|
|
65124
|
+
},
|
|
65125
|
+
"detergent.level": {
|
|
65126
|
+
kind: "gauge",
|
|
65127
|
+
unit: "%",
|
|
65128
|
+
deadband: 2
|
|
65129
|
+
},
|
|
65130
|
+
"dustBin.level": {
|
|
65131
|
+
kind: "gauge",
|
|
65132
|
+
unit: "%",
|
|
65133
|
+
deadband: 2
|
|
65134
|
+
}
|
|
65135
|
+
} }
|
|
63965
65136
|
};
|
|
63966
65137
|
var ValveStatusSchema = object({
|
|
63967
65138
|
/** Lifecycle state of the valve. */
|
|
@@ -64020,7 +65191,15 @@ var valveCapability = {
|
|
|
64020
65191
|
* See `RuntimeStateDurability`. Enforced by
|
|
64021
65192
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64022
65193
|
*/
|
|
64023
|
-
durability: "session"
|
|
65194
|
+
durability: "session",
|
|
65195
|
+
/**
|
|
65196
|
+
* History (D850): recorded series. Actuator tier: position keeps every change.
|
|
65197
|
+
*/
|
|
65198
|
+
history: { fields: { position: {
|
|
65199
|
+
kind: "gauge",
|
|
65200
|
+
unit: "%",
|
|
65201
|
+
minIntervalMs: 0
|
|
65202
|
+
} } }
|
|
64024
65203
|
};
|
|
64025
65204
|
/**
|
|
64026
65205
|
* Vibration / shake / impact sensor. Drives Home Assistant
|
|
@@ -64050,6 +65229,10 @@ var vibrationCapability = {
|
|
|
64050
65229
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64051
65230
|
*/
|
|
64052
65231
|
durability: "restored",
|
|
65232
|
+
/**
|
|
65233
|
+
* History (D850): recorded series.
|
|
65234
|
+
*/
|
|
65235
|
+
history: { fields: { detected: { kind: "boolean" } } },
|
|
64053
65236
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64054
65237
|
* whether persisting is worth a SQLite commit. */
|
|
64055
65238
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -64133,7 +65316,22 @@ var waterHeaterCapability = {
|
|
|
64133
65316
|
* See `RuntimeStateDurability`. Enforced by
|
|
64134
65317
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64135
65318
|
*/
|
|
64136
|
-
durability: "session"
|
|
65319
|
+
durability: "session",
|
|
65320
|
+
/**
|
|
65321
|
+
* History (D850): recorded series. The schema carries no unit; providers publish Celsius. Setpoint keeps every change.
|
|
65322
|
+
*/
|
|
65323
|
+
history: { fields: {
|
|
65324
|
+
currentTemp: {
|
|
65325
|
+
kind: "gauge",
|
|
65326
|
+
unit: "°C",
|
|
65327
|
+
deadband: .5
|
|
65328
|
+
},
|
|
65329
|
+
targetTemp: {
|
|
65330
|
+
kind: "gauge",
|
|
65331
|
+
unit: "°C",
|
|
65332
|
+
minIntervalMs: 0
|
|
65333
|
+
}
|
|
65334
|
+
} }
|
|
64137
65335
|
};
|
|
64138
65336
|
/**
|
|
64139
65337
|
* Weather provider cap. Models HA `weather.*` entities — a read-only
|
|
@@ -64199,7 +65397,32 @@ var weatherCapability = {
|
|
|
64199
65397
|
* See `RuntimeStateDurability`. Enforced by
|
|
64200
65398
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64201
65399
|
*/
|
|
64202
|
-
durability: "session"
|
|
65400
|
+
durability: "session",
|
|
65401
|
+
/**
|
|
65402
|
+
* History (D850): recorded series. Units follow the sibling `*Unit` fields.
|
|
65403
|
+
*/
|
|
65404
|
+
history: { fields: {
|
|
65405
|
+
temperature: {
|
|
65406
|
+
kind: "gauge",
|
|
65407
|
+
unitFrom: "temperatureUnit",
|
|
65408
|
+
deadband: .2
|
|
65409
|
+
},
|
|
65410
|
+
humidity: {
|
|
65411
|
+
kind: "gauge",
|
|
65412
|
+
unit: "%",
|
|
65413
|
+
deadband: 1
|
|
65414
|
+
},
|
|
65415
|
+
pressure: {
|
|
65416
|
+
kind: "gauge",
|
|
65417
|
+
unitFrom: "pressureUnit",
|
|
65418
|
+
deadband: .5
|
|
65419
|
+
},
|
|
65420
|
+
windSpeed: {
|
|
65421
|
+
kind: "gauge",
|
|
65422
|
+
unitFrom: "windSpeedUnit",
|
|
65423
|
+
deadband: .5
|
|
65424
|
+
}
|
|
65425
|
+
} }
|
|
64203
65426
|
};
|
|
64204
65427
|
/**
|
|
64205
65428
|
* Per-zone occupancy aggregation produced by the analytics frame
|
|
@@ -64441,7 +65664,11 @@ var zoneAnalyticsCapability = {
|
|
|
64441
65664
|
* See `RuntimeStateDurability`. Enforced by
|
|
64442
65665
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64443
65666
|
*/
|
|
64444
|
-
durability: "session"
|
|
65667
|
+
durability: "session",
|
|
65668
|
+
/**
|
|
65669
|
+
* History (D850): none — occupancy is the addon series `pipeline-analytics/occupancy`; the rest is per-zone arrays keyed by runtime ids.
|
|
65670
|
+
*/
|
|
65671
|
+
history: "none"
|
|
64445
65672
|
};
|
|
64446
65673
|
/**
|
|
64447
65674
|
* Stages a {@link ZoneRule} can apply to. Discriminator on the rules
|
|
@@ -64526,7 +65753,11 @@ var zoneRulesCapability = {
|
|
|
64526
65753
|
* See `RuntimeStateDurability`. Enforced by
|
|
64527
65754
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64528
65755
|
*/
|
|
64529
|
-
durability: "restored"
|
|
65756
|
+
durability: "restored",
|
|
65757
|
+
/**
|
|
65758
|
+
* History (D850): none — configuration arrays.
|
|
65759
|
+
*/
|
|
65760
|
+
history: "none"
|
|
64530
65761
|
};
|
|
64531
65762
|
/**
|
|
64532
65763
|
* `training-provider` — ONE cloud that can run the CamStack trainer.
|
|
@@ -68130,6 +69361,54 @@ Object.freeze({
|
|
|
68130
69361
|
addonId: null,
|
|
68131
69362
|
access: "create"
|
|
68132
69363
|
},
|
|
69364
|
+
"deviceCredentials.deleteDeviceCredential": {
|
|
69365
|
+
capName: "device-credentials",
|
|
69366
|
+
capScope: "system",
|
|
69367
|
+
addonId: null,
|
|
69368
|
+
access: "delete"
|
|
69369
|
+
},
|
|
69370
|
+
"deviceCredentials.getDeviceCaStatus": {
|
|
69371
|
+
capName: "device-credentials",
|
|
69372
|
+
capScope: "system",
|
|
69373
|
+
addonId: null,
|
|
69374
|
+
access: "view"
|
|
69375
|
+
},
|
|
69376
|
+
"deviceCredentials.getDeviceCertificateSettings": {
|
|
69377
|
+
capName: "device-credentials",
|
|
69378
|
+
capScope: "system",
|
|
69379
|
+
addonId: null,
|
|
69380
|
+
access: "view"
|
|
69381
|
+
},
|
|
69382
|
+
"deviceCredentials.listDeviceCredentials": {
|
|
69383
|
+
capName: "device-credentials",
|
|
69384
|
+
capScope: "system",
|
|
69385
|
+
addonId: null,
|
|
69386
|
+
access: "view"
|
|
69387
|
+
},
|
|
69388
|
+
"deviceCredentials.renameDeviceCredential": {
|
|
69389
|
+
capName: "device-credentials",
|
|
69390
|
+
capScope: "system",
|
|
69391
|
+
addonId: null,
|
|
69392
|
+
access: "create"
|
|
69393
|
+
},
|
|
69394
|
+
"deviceCredentials.revokeDeviceCredential": {
|
|
69395
|
+
capName: "device-credentials",
|
|
69396
|
+
capScope: "system",
|
|
69397
|
+
addonId: null,
|
|
69398
|
+
access: "delete"
|
|
69399
|
+
},
|
|
69400
|
+
"deviceCredentials.setDeviceCertificateSettings": {
|
|
69401
|
+
capName: "device-credentials",
|
|
69402
|
+
capScope: "system",
|
|
69403
|
+
addonId: null,
|
|
69404
|
+
access: "create"
|
|
69405
|
+
},
|
|
69406
|
+
"deviceCredentials.startEnrollment": {
|
|
69407
|
+
capName: "device-credentials",
|
|
69408
|
+
capScope: "system",
|
|
69409
|
+
addonId: null,
|
|
69410
|
+
access: "create"
|
|
69411
|
+
},
|
|
68133
69412
|
"deviceDiscovery.adoptDevice": {
|
|
68134
69413
|
capName: "device-discovery",
|
|
68135
69414
|
capScope: "device",
|
|
@@ -68232,6 +69511,66 @@ Object.freeze({
|
|
|
68232
69511
|
addonId: null,
|
|
68233
69512
|
access: "create"
|
|
68234
69513
|
},
|
|
69514
|
+
"deviceHistory.declareSeries": {
|
|
69515
|
+
capName: "device-history",
|
|
69516
|
+
capScope: "system",
|
|
69517
|
+
addonId: null,
|
|
69518
|
+
access: "create"
|
|
69519
|
+
},
|
|
69520
|
+
"deviceHistory.getDeviceEnabled": {
|
|
69521
|
+
capName: "device-history",
|
|
69522
|
+
capScope: "system",
|
|
69523
|
+
addonId: null,
|
|
69524
|
+
access: "view"
|
|
69525
|
+
},
|
|
69526
|
+
"deviceHistory.getStatus": {
|
|
69527
|
+
capName: "device-history",
|
|
69528
|
+
capScope: "system",
|
|
69529
|
+
addonId: null,
|
|
69530
|
+
access: "view"
|
|
69531
|
+
},
|
|
69532
|
+
"deviceHistory.listNodeSeries": {
|
|
69533
|
+
capName: "device-history",
|
|
69534
|
+
capScope: "system",
|
|
69535
|
+
addonId: null,
|
|
69536
|
+
access: "view"
|
|
69537
|
+
},
|
|
69538
|
+
"deviceHistory.listSeries": {
|
|
69539
|
+
capName: "device-history",
|
|
69540
|
+
capScope: "system",
|
|
69541
|
+
addonId: null,
|
|
69542
|
+
access: "view"
|
|
69543
|
+
},
|
|
69544
|
+
"deviceHistory.query": {
|
|
69545
|
+
capName: "device-history",
|
|
69546
|
+
capScope: "system",
|
|
69547
|
+
addonId: null,
|
|
69548
|
+
access: "view"
|
|
69549
|
+
},
|
|
69550
|
+
"deviceHistory.queryNode": {
|
|
69551
|
+
capName: "device-history",
|
|
69552
|
+
capScope: "system",
|
|
69553
|
+
addonId: null,
|
|
69554
|
+
access: "view"
|
|
69555
|
+
},
|
|
69556
|
+
"deviceHistory.record": {
|
|
69557
|
+
capName: "device-history",
|
|
69558
|
+
capScope: "system",
|
|
69559
|
+
addonId: null,
|
|
69560
|
+
access: "create"
|
|
69561
|
+
},
|
|
69562
|
+
"deviceHistory.recordBuckets": {
|
|
69563
|
+
capName: "device-history",
|
|
69564
|
+
capScope: "system",
|
|
69565
|
+
addonId: null,
|
|
69566
|
+
access: "create"
|
|
69567
|
+
},
|
|
69568
|
+
"deviceHistory.setDeviceEnabled": {
|
|
69569
|
+
capName: "device-history",
|
|
69570
|
+
capScope: "system",
|
|
69571
|
+
addonId: null,
|
|
69572
|
+
access: "create"
|
|
69573
|
+
},
|
|
68235
69574
|
"deviceManager.addLocation": {
|
|
68236
69575
|
capName: "device-manager",
|
|
68237
69576
|
capScope: "system",
|
|
@@ -68310,6 +69649,12 @@ Object.freeze({
|
|
|
68310
69649
|
addonId: null,
|
|
68311
69650
|
access: "create"
|
|
68312
69651
|
},
|
|
69652
|
+
"deviceManager.cleanupDeletedDevicesData": {
|
|
69653
|
+
capName: "device-manager",
|
|
69654
|
+
capScope: "system",
|
|
69655
|
+
addonId: null,
|
|
69656
|
+
access: "create"
|
|
69657
|
+
},
|
|
68313
69658
|
"deviceManager.createDevice": {
|
|
68314
69659
|
capName: "device-manager",
|
|
68315
69660
|
capScope: "system",
|
|
@@ -68490,6 +69835,12 @@ Object.freeze({
|
|
|
68490
69835
|
addonId: null,
|
|
68491
69836
|
access: "view"
|
|
68492
69837
|
},
|
|
69838
|
+
"deviceManager.listDeletedSince": {
|
|
69839
|
+
capName: "device-manager",
|
|
69840
|
+
capScope: "system",
|
|
69841
|
+
addonId: null,
|
|
69842
|
+
access: "view"
|
|
69843
|
+
},
|
|
68493
69844
|
"deviceManager.listDeviceIdsByCaps": {
|
|
68494
69845
|
capName: "device-manager",
|
|
68495
69846
|
capScope: "system",
|
|
@@ -68898,6 +70249,18 @@ Object.freeze({
|
|
|
68898
70249
|
addonId: null,
|
|
68899
70250
|
access: "create"
|
|
68900
70251
|
},
|
|
70252
|
+
"deviceRemovalHook.listDeviceData": {
|
|
70253
|
+
capName: "device-removal-hook",
|
|
70254
|
+
capScope: "system",
|
|
70255
|
+
addonId: null,
|
|
70256
|
+
access: "view"
|
|
70257
|
+
},
|
|
70258
|
+
"deviceRemovalHook.onDeviceRemoved": {
|
|
70259
|
+
capName: "device-removal-hook",
|
|
70260
|
+
capScope: "system",
|
|
70261
|
+
addonId: null,
|
|
70262
|
+
access: "create"
|
|
70263
|
+
},
|
|
68901
70264
|
"deviceState.claimFields": {
|
|
68902
70265
|
capName: "device-state",
|
|
68903
70266
|
capScope: "system",
|
|
@@ -69330,6 +70693,12 @@ Object.freeze({
|
|
|
69330
70693
|
addonId: null,
|
|
69331
70694
|
access: "delete"
|
|
69332
70695
|
},
|
|
70696
|
+
"keychain.deleteDeviceScope": {
|
|
70697
|
+
capName: "keychain",
|
|
70698
|
+
capScope: "system",
|
|
70699
|
+
addonId: null,
|
|
70700
|
+
access: "delete"
|
|
70701
|
+
},
|
|
69333
70702
|
"keychain.getState": {
|
|
69334
70703
|
capName: "keychain",
|
|
69335
70704
|
capScope: "system",
|
|
@@ -70290,6 +71659,54 @@ Object.freeze({
|
|
|
70290
71659
|
addonId: null,
|
|
70291
71660
|
access: "create"
|
|
70292
71661
|
},
|
|
71662
|
+
"nodeCertificates.confirmMeshLeaf": {
|
|
71663
|
+
capName: "node-certificates",
|
|
71664
|
+
capScope: "system",
|
|
71665
|
+
addonId: null,
|
|
71666
|
+
access: "create"
|
|
71667
|
+
},
|
|
71668
|
+
"nodeCertificates.forgetHub": {
|
|
71669
|
+
capName: "node-certificates",
|
|
71670
|
+
capScope: "system",
|
|
71671
|
+
addonId: null,
|
|
71672
|
+
access: "delete"
|
|
71673
|
+
},
|
|
71674
|
+
"nodeCertificates.getCertificates": {
|
|
71675
|
+
capName: "node-certificates",
|
|
71676
|
+
capScope: "system",
|
|
71677
|
+
addonId: null,
|
|
71678
|
+
access: "view"
|
|
71679
|
+
},
|
|
71680
|
+
"nodeCertificates.installHttpsCertificate": {
|
|
71681
|
+
capName: "node-certificates",
|
|
71682
|
+
capScope: "system",
|
|
71683
|
+
addonId: null,
|
|
71684
|
+
access: "create"
|
|
71685
|
+
},
|
|
71686
|
+
"nodeCertificates.installMeshLeaf": {
|
|
71687
|
+
capName: "node-certificates",
|
|
71688
|
+
capScope: "system",
|
|
71689
|
+
addonId: null,
|
|
71690
|
+
access: "create"
|
|
71691
|
+
},
|
|
71692
|
+
"nodeCertificates.prepareHttpsCertificate": {
|
|
71693
|
+
capName: "node-certificates",
|
|
71694
|
+
capScope: "system",
|
|
71695
|
+
addonId: null,
|
|
71696
|
+
access: "create"
|
|
71697
|
+
},
|
|
71698
|
+
"nodeCertificates.prepareMeshRenewal": {
|
|
71699
|
+
capName: "node-certificates",
|
|
71700
|
+
capScope: "system",
|
|
71701
|
+
addonId: null,
|
|
71702
|
+
access: "create"
|
|
71703
|
+
},
|
|
71704
|
+
"nodeCertificates.rollbackMeshLeaf": {
|
|
71705
|
+
capName: "node-certificates",
|
|
71706
|
+
capScope: "system",
|
|
71707
|
+
addonId: null,
|
|
71708
|
+
access: "create"
|
|
71709
|
+
},
|
|
70293
71710
|
"nodes.clusterAddonStatus": {
|
|
70294
71711
|
capName: "nodes",
|
|
70295
71712
|
capScope: "system",
|
|
@@ -75133,6 +76550,26 @@ Object.freeze({
|
|
|
75133
76550
|
form: "single",
|
|
75134
76551
|
optional: false
|
|
75135
76552
|
}],
|
|
76553
|
+
"deviceHistory.getDeviceEnabled": [{
|
|
76554
|
+
name: "deviceId",
|
|
76555
|
+
form: "single",
|
|
76556
|
+
optional: false
|
|
76557
|
+
}],
|
|
76558
|
+
"deviceHistory.listSeries": [{
|
|
76559
|
+
name: "deviceId",
|
|
76560
|
+
form: "single",
|
|
76561
|
+
optional: false
|
|
76562
|
+
}],
|
|
76563
|
+
"deviceHistory.query": [{
|
|
76564
|
+
name: "deviceId",
|
|
76565
|
+
form: "single",
|
|
76566
|
+
optional: false
|
|
76567
|
+
}],
|
|
76568
|
+
"deviceHistory.setDeviceEnabled": [{
|
|
76569
|
+
name: "deviceId",
|
|
76570
|
+
form: "single",
|
|
76571
|
+
optional: false
|
|
76572
|
+
}],
|
|
75136
76573
|
"deviceManager.adoptionRelease": [{
|
|
75137
76574
|
name: "camDeviceId",
|
|
75138
76575
|
form: "single",
|
|
@@ -75426,6 +76863,11 @@ Object.freeze({
|
|
|
75426
76863
|
form: "single",
|
|
75427
76864
|
optional: false
|
|
75428
76865
|
}],
|
|
76866
|
+
"deviceRemovalHook.onDeviceRemoved": [{
|
|
76867
|
+
name: "deviceId",
|
|
76868
|
+
form: "single",
|
|
76869
|
+
optional: false
|
|
76870
|
+
}],
|
|
75429
76871
|
"deviceState.claimFields": [{
|
|
75430
76872
|
name: "deviceId",
|
|
75431
76873
|
form: "single",
|
|
@@ -75615,6 +77057,11 @@ Object.freeze({
|
|
|
75615
77057
|
form: "single",
|
|
75616
77058
|
optional: false
|
|
75617
77059
|
}],
|
|
77060
|
+
"keychain.deleteDeviceScope": [{
|
|
77061
|
+
name: "deviceId",
|
|
77062
|
+
form: "single",
|
|
77063
|
+
optional: false
|
|
77064
|
+
}],
|
|
75618
77065
|
"lawnMowerControl.dock": [{
|
|
75619
77066
|
name: "deviceId",
|
|
75620
77067
|
form: "single",
|
|
@@ -77311,6 +78758,7 @@ Object.freeze({
|
|
|
77311
78758
|
"network-access": "ingress",
|
|
77312
78759
|
"smtp-provider": "email"
|
|
77313
78760
|
});
|
|
78761
|
+
DeviceType.Camera;
|
|
77314
78762
|
var G711_SCALE_CORRECTION_DB = {
|
|
77315
78763
|
PCMU: 20 * Math.log10(4),
|
|
77316
78764
|
PCMA: 20 * Math.log10(8)
|
|
@@ -77962,6 +79410,8 @@ new Set([
|
|
|
77962
79410
|
"audio-tools",
|
|
77963
79411
|
"audio-silence"
|
|
77964
79412
|
]);
|
|
79413
|
+
AppPageLangSchema.options;
|
|
79414
|
+
record(string().min(1), string());
|
|
77965
79415
|
/**
|
|
77966
79416
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
77967
79417
|
*
|
|
@@ -185281,71 +186731,88 @@ var intercomFailureReport = new IntercomFailureReport();
|
|
|
185281
186731
|
var SNAPSHOT_GROUPS = [
|
|
185282
186732
|
{
|
|
185283
186733
|
key: "imageSnapshot",
|
|
185284
|
-
label: "Image (getVideoInput)"
|
|
186734
|
+
label: "Image (getVideoInput)",
|
|
186735
|
+
labelKey: "provider-reolink:snapshot_groups.imageSnapshot.label"
|
|
185285
186736
|
},
|
|
185286
186737
|
{
|
|
185287
186738
|
key: "motionSnapshot",
|
|
185288
|
-
label: "Motion (getMotionAlarm)"
|
|
186739
|
+
label: "Motion (getMotionAlarm)",
|
|
186740
|
+
labelKey: "provider-reolink:snapshot_groups.motionSnapshot.label"
|
|
185289
186741
|
},
|
|
185290
186742
|
{
|
|
185291
186743
|
key: "aiSensitivitySnapshot",
|
|
185292
|
-
label: "AI sensitivity (getAiDetectionFull)"
|
|
186744
|
+
label: "AI sensitivity (getAiDetectionFull)",
|
|
186745
|
+
labelKey: "provider-reolink:snapshot_groups.aiSensitivitySnapshot.label"
|
|
185293
186746
|
},
|
|
185294
186747
|
{
|
|
185295
186748
|
key: "encSnapshot",
|
|
185296
|
-
label: "Encoder (getEnc)"
|
|
186749
|
+
label: "Encoder (getEnc)",
|
|
186750
|
+
labelKey: "provider-reolink:snapshot_groups.encSnapshot.label"
|
|
185297
186751
|
},
|
|
185298
186752
|
{
|
|
185299
186753
|
key: "encOptionsSnapshot",
|
|
185300
|
-
label: "Encoder options (getEncOptions)"
|
|
186754
|
+
label: "Encoder options (getEncOptions)",
|
|
186755
|
+
labelKey: "provider-reolink:snapshot_groups.encOptionsSnapshot.label"
|
|
185301
186756
|
},
|
|
185302
186757
|
{
|
|
185303
186758
|
key: "maskSnapshot",
|
|
185304
|
-
label: "Privacy mask (getMask)"
|
|
186759
|
+
label: "Privacy mask (getMask)",
|
|
186760
|
+
labelKey: "provider-reolink:snapshot_groups.maskSnapshot.label"
|
|
185305
186761
|
},
|
|
185306
186762
|
{
|
|
185307
186763
|
key: "audioNoiseSnapshot",
|
|
185308
|
-
label: "Audio noise (getAudioNoise)"
|
|
186764
|
+
label: "Audio noise (getAudioNoise)",
|
|
186765
|
+
labelKey: "provider-reolink:snapshot_groups.audioNoiseSnapshot.label"
|
|
185309
186766
|
},
|
|
185310
186767
|
{
|
|
185311
186768
|
key: "autoFocusSnapshot",
|
|
185312
|
-
label: "Auto-focus (getAutoFocus)"
|
|
186769
|
+
label: "Auto-focus (getAutoFocus)",
|
|
186770
|
+
labelKey: "provider-reolink:snapshot_groups.autoFocusSnapshot.label"
|
|
185313
186771
|
},
|
|
185314
186772
|
{
|
|
185315
186773
|
key: "netPortSnapshot",
|
|
185316
|
-
label: "Network ports (getNetPort)"
|
|
186774
|
+
label: "Network ports (getNetPort)",
|
|
186775
|
+
labelKey: "provider-reolink:snapshot_groups.netPortSnapshot.label"
|
|
185317
186776
|
},
|
|
185318
186777
|
{
|
|
185319
186778
|
key: "ntpSnapshot",
|
|
185320
|
-
label: "NTP (getNtp)"
|
|
186779
|
+
label: "NTP (getNtp)",
|
|
186780
|
+
labelKey: "provider-reolink:snapshot_groups.ntpSnapshot.label"
|
|
185321
186781
|
},
|
|
185322
186782
|
{
|
|
185323
186783
|
key: "systemGeneralSnapshot",
|
|
185324
|
-
label: "System general (getSystemGeneral)"
|
|
186784
|
+
label: "System general (getSystemGeneral)",
|
|
186785
|
+
labelKey: "provider-reolink:snapshot_groups.systemGeneralSnapshot.label"
|
|
185325
186786
|
},
|
|
185326
186787
|
{
|
|
185327
186788
|
key: "osdSnapshot",
|
|
185328
|
-
label: "OSD overlay (getOsd)"
|
|
186789
|
+
label: "OSD overlay (getOsd)",
|
|
186790
|
+
labelKey: "provider-reolink:snapshot_groups.osdSnapshot.label"
|
|
185329
186791
|
},
|
|
185330
186792
|
{
|
|
185331
186793
|
key: "ledSnapshot",
|
|
185332
|
-
label: "LEDs (getIrLights)"
|
|
186794
|
+
label: "LEDs (getIrLights)",
|
|
186795
|
+
labelKey: "provider-reolink:snapshot_groups.ledSnapshot.label"
|
|
185333
186796
|
},
|
|
185334
186797
|
{
|
|
185335
186798
|
key: "pirSnapshot",
|
|
185336
|
-
label: "PIR (getPirInfo)"
|
|
186799
|
+
label: "PIR (getPirInfo)",
|
|
186800
|
+
labelKey: "provider-reolink:snapshot_groups.pirSnapshot.label"
|
|
185337
186801
|
},
|
|
185338
186802
|
{
|
|
185339
186803
|
key: "autoRebootSnapshot",
|
|
185340
|
-
label: "Auto reboot (getAutoReboot)"
|
|
186804
|
+
label: "Auto reboot (getAutoReboot)",
|
|
186805
|
+
labelKey: "provider-reolink:snapshot_groups.autoRebootSnapshot.label"
|
|
185341
186806
|
},
|
|
185342
186807
|
{
|
|
185343
186808
|
key: "emailConfigSnapshot",
|
|
185344
|
-
label: "Email/SMTP (getEmail)"
|
|
186809
|
+
label: "Email/SMTP (getEmail)",
|
|
186810
|
+
labelKey: "provider-reolink:snapshot_groups.emailConfigSnapshot.label"
|
|
185345
186811
|
},
|
|
185346
186812
|
{
|
|
185347
186813
|
key: "capOptionsSnapshot",
|
|
185348
|
-
label: "Cap option probes (getOptions)"
|
|
186814
|
+
label: "Cap option probes (getOptions)",
|
|
186815
|
+
labelKey: "provider-reolink:snapshot_groups.capOptionsSnapshot.label"
|
|
185349
186816
|
}
|
|
185350
186817
|
];
|
|
185351
186818
|
/**
|
|
@@ -185429,12 +186896,15 @@ function buildSnapshotFreshnessSection(cache, opts) {
|
|
|
185429
186896
|
id: "snapshotFreshness",
|
|
185430
186897
|
tab: "advanced",
|
|
185431
186898
|
title: "Snapshot freshness",
|
|
186899
|
+
titleKey: "provider-reolink:snapshotFreshnessSection.s_snapshotFreshness.title",
|
|
185432
186900
|
description: "When each cached camera reading was last fetched. Groups without a stamp were persisted before per-snapshot tracking — their age is unknown, not fresh. Use \"Refresh from camera\" (General) to re-read an awake camera.",
|
|
186901
|
+
descriptionKey: "provider-reolink:snapshotFreshnessSection.s_snapshotFreshness.description",
|
|
185433
186902
|
columns: 1,
|
|
185434
186903
|
fields: [{
|
|
185435
186904
|
type: "info",
|
|
185436
186905
|
key: "snapshotFreshness",
|
|
185437
186906
|
label: "Per-snapshot read times",
|
|
186907
|
+
labelKey: "provider-reolink:field.snapshotFreshness.label",
|
|
185438
186908
|
content: `${opts.sleeping ? "Camera is asleep — no group can refresh until it wakes; a sleeping battery camera is never woken to read settings.\n" : ""}${header}\n${lines.join("\n")}`
|
|
185439
186909
|
}]
|
|
185440
186910
|
};
|
|
@@ -186630,7 +188100,7 @@ function capDayNightModeToReolink(mode) {
|
|
|
186630
188100
|
case "auto": return "auto";
|
|
186631
188101
|
case "day": return "color";
|
|
186632
188102
|
case "night": return "blackAndWhite";
|
|
186633
|
-
case "schedule": throw
|
|
188103
|
+
case "schedule": throw userError("reolink.day-night-schedule-unsupported", void 0, "Reolink cameras do not support a scheduled day/night mode");
|
|
186634
188104
|
}
|
|
186635
188105
|
}
|
|
186636
188106
|
//#endregion
|
|
@@ -186925,6 +188395,7 @@ function buildOsdStateBanner(snapshot, opts) {
|
|
|
186925
188395
|
type: "info",
|
|
186926
188396
|
key: "osdSnapshotState",
|
|
186927
188397
|
label: "OSD state",
|
|
188398
|
+
labelKey: "provider-reolink:osdStateBanner.osdSnapshotState.label",
|
|
186928
188399
|
variant: "warning",
|
|
186929
188400
|
content: snapshot === void 0 ? `Camera is asleep and its OSD state has never been read — the toggles below are unknown until it wakes; ${NEVER_WOKEN_SUFFIX}` : snapshot.fetchedAt !== void 0 ? `Camera is asleep — showing the OSD state last read ${new Date(snapshot.fetchedAt).toLocaleString()}. It refreshes when the camera wakes; ${NEVER_WOKEN_SUFFIX}` : `Camera is asleep — showing the last known OSD state (age unknown). It refreshes when the camera wakes; ${NEVER_WOKEN_SUFFIX}`
|
|
186930
188401
|
};
|
|
@@ -186932,6 +188403,7 @@ function buildOsdStateBanner(snapshot, opts) {
|
|
|
186932
188403
|
type: "info",
|
|
186933
188404
|
key: "osdSnapshotState",
|
|
186934
188405
|
label: "OSD state",
|
|
188406
|
+
labelKey: "provider-reolink:osdStateBanner.osdSnapshotState.label",
|
|
186935
188407
|
variant: "warning",
|
|
186936
188408
|
content: "OSD state has not been read from this camera yet — unknown toggles are disabled until a read succeeds."
|
|
186937
188409
|
};
|
|
@@ -186981,7 +188453,9 @@ function buildOsdSection(snapshot, values, opts) {
|
|
|
186981
188453
|
id: "osd",
|
|
186982
188454
|
tab: "image",
|
|
186983
188455
|
title: "OSD overlay",
|
|
188456
|
+
titleKey: "provider-reolink:osdSection.s_osd.title",
|
|
186984
188457
|
description: "On-screen overlays burned into the video by the camera. Read with `GetOsdDatetime` (cmd_id 44) and pushed with `SetOsdDatetime` (cmd_id 45). Positions are the four frame corners; an overlay the camera holds somewhere else keeps that placement unless a corner is chosen.",
|
|
188458
|
+
descriptionKey: "provider-reolink:osdSection.s_osd.description",
|
|
186985
188459
|
columns: 2,
|
|
186986
188460
|
fields: [
|
|
186987
188461
|
...banner ? [banner] : [],
|
|
@@ -186991,7 +188465,9 @@ function buildOsdSection(snapshot, values, opts) {
|
|
|
186991
188465
|
type: "text",
|
|
186992
188466
|
key: "osdChannelName",
|
|
186993
188467
|
label: "Channel name",
|
|
188468
|
+
labelKey: "provider-reolink:fields.osdChannelName.label",
|
|
186994
188469
|
description: "Text shown in the channel-name overlay.",
|
|
188470
|
+
descriptionKey: "provider-reolink:fields.osdChannelName.description",
|
|
186995
188471
|
default: values.osdChannelName,
|
|
186996
188472
|
placeholder: "Front door"
|
|
186997
188473
|
},
|
|
@@ -187474,13 +188950,17 @@ var SirenAccessory = class extends BaseDevice {
|
|
|
187474
188950
|
return hydrateSchema({ sections: [{
|
|
187475
188951
|
id: "siren",
|
|
187476
188952
|
title: "Siren",
|
|
188953
|
+
titleKey: "provider-reolink:schema.s_siren.title",
|
|
187477
188954
|
description: "Tone duration when triggered. Set to 0 for \"play until turned off\"; positive values pulse for that many seconds.",
|
|
188955
|
+
descriptionKey: "provider-reolink:schema.s_siren.description",
|
|
187478
188956
|
columns: 1,
|
|
187479
188957
|
fields: [{
|
|
187480
188958
|
type: "number",
|
|
187481
188959
|
key: "sirenDurationS",
|
|
187482
188960
|
label: "Default duration (seconds)",
|
|
188961
|
+
labelKey: "provider-reolink:schema.s_siren.sirenDurationS.label",
|
|
187483
188962
|
description: "Forwarded to `setSiren(on=true, duration)` (cmd_id 30) when the operator flips the switch.",
|
|
188963
|
+
descriptionKey: "provider-reolink:schema.s_siren.sirenDurationS.description",
|
|
187484
188964
|
default: 0,
|
|
187485
188965
|
min: 0,
|
|
187486
188966
|
max: 300,
|
|
@@ -187489,13 +188969,17 @@ var SirenAccessory = class extends BaseDevice {
|
|
|
187489
188969
|
}, {
|
|
187490
188970
|
id: "motion-siren",
|
|
187491
188971
|
title: "Motion-triggered siren",
|
|
188972
|
+
titleKey: "provider-reolink:schema.s_motion-siren.title",
|
|
187492
188973
|
description: "Detection classes that fire the siren when \"Trigger on motion\" is armed. Forwarded as a `typeScheduleList` to `setSirenOnMotion` (cmd_id 231). Saved values re-apply on every motion-trigger flip.",
|
|
188974
|
+
descriptionKey: "provider-reolink:schema.s_motion-siren.description",
|
|
187493
188975
|
columns: 1,
|
|
187494
188976
|
fields: [{
|
|
187495
188977
|
type: "select",
|
|
187496
188978
|
key: "motionSirenDetectType",
|
|
187497
188979
|
label: "Detection classes",
|
|
188980
|
+
labelKey: "provider-reolink:schema.s_motion-siren.motionSirenDetectType.label",
|
|
187498
188981
|
description: "Object/motion classes that arm the siren. `MD` = generic motion detection.",
|
|
188982
|
+
descriptionKey: "provider-reolink:schema.s_motion-siren.motionSirenDetectType.description",
|
|
187499
188983
|
options: SIREN_DETECT_TYPE_CHOICES.map((v) => ({
|
|
187500
188984
|
value: v,
|
|
187501
188985
|
label: v.replace(/,/g, " + ").replace(/_/g, "+")
|
|
@@ -187958,13 +189442,17 @@ var FloodlightAccessory = class extends BaseDevice {
|
|
|
187958
189442
|
return hydrateSchema({ sections: [{
|
|
187959
189443
|
id: "motion-floodlight",
|
|
187960
189444
|
title: "Motion-triggered floodlight",
|
|
189445
|
+
titleKey: "provider-reolink:schema.s_motion-floodlight.title",
|
|
187961
189446
|
description: "Pushed to the camera (`FloodlightTask`) when the \"Trigger on motion\" toggle is armed. Saved values also re-apply on every motion-trigger flip so the firmware always honours your preference.",
|
|
189447
|
+
descriptionKey: "provider-reolink:schema.s_motion-floodlight.description",
|
|
187962
189448
|
columns: 2,
|
|
187963
189449
|
fields: [{
|
|
187964
189450
|
type: "number",
|
|
187965
189451
|
key: "motionLightDurationS",
|
|
187966
189452
|
label: "Light duration (s)",
|
|
189453
|
+
labelKey: "provider-reolink:schema.s_motion-floodlight.motionLightDurationS.label",
|
|
187967
189454
|
description: "Seconds the floodlight stays lit after a motion event. Reolink range 1..600s.",
|
|
189455
|
+
descriptionKey: "provider-reolink:schema.s_motion-floodlight.motionLightDurationS.description",
|
|
187968
189456
|
min: 1,
|
|
187969
189457
|
max: 600,
|
|
187970
189458
|
step: 1,
|
|
@@ -187973,7 +189461,9 @@ var FloodlightAccessory = class extends BaseDevice {
|
|
|
187973
189461
|
type: "select",
|
|
187974
189462
|
key: "motionLightDetectType",
|
|
187975
189463
|
label: "Detection classes",
|
|
189464
|
+
labelKey: "provider-reolink:schema.s_motion-floodlight.motionLightDetectType.label",
|
|
187976
189465
|
description: "Object classes that turn the floodlight on. Composed values (e.g. \"people,vehicle\") fire when ANY listed class detects.",
|
|
189466
|
+
descriptionKey: "provider-reolink:schema.s_motion-floodlight.motionLightDetectType.description",
|
|
187977
189467
|
options: FLOODLIGHT_DETECT_TYPE_CHOICES.map((v) => ({
|
|
187978
189468
|
value: v,
|
|
187979
189469
|
label: v.replace(/,/g, " + ").replace(/_/g, "+")
|
|
@@ -188212,14 +189702,18 @@ var PirAccessory = class extends BaseDevice {
|
|
|
188212
189702
|
return hydrateSchema({ sections: [{
|
|
188213
189703
|
id: "pir",
|
|
188214
189704
|
title: "PIR sensor",
|
|
189705
|
+
titleKey: "provider-reolink:schema.s_pir.title",
|
|
188215
189706
|
description: "Hardware passive-infrared trigger configuration. Pushed via cmd_id 153 (SetPirInfo).",
|
|
189707
|
+
descriptionKey: "provider-reolink:schema.s_pir.description",
|
|
188216
189708
|
columns: 2,
|
|
188217
189709
|
fields: [
|
|
188218
189710
|
{
|
|
188219
189711
|
type: "slider",
|
|
188220
189712
|
key: "pirSensitive",
|
|
188221
189713
|
label: "Sensitivity",
|
|
189714
|
+
labelKey: "provider-reolink:schema.s_pir.pirSensitive.label",
|
|
188222
189715
|
description: "Higher value → triggers on smaller motion. Most cameras max at 100.",
|
|
189716
|
+
descriptionKey: "provider-reolink:schema.s_pir.pirSensitive.description",
|
|
188223
189717
|
min: 1,
|
|
188224
189718
|
max: 100,
|
|
188225
189719
|
step: 1,
|
|
@@ -188230,6 +189724,7 @@ var PirAccessory = class extends BaseDevice {
|
|
|
188230
189724
|
type: "slider",
|
|
188231
189725
|
key: "pirIntervalS",
|
|
188232
189726
|
label: "Cooldown (seconds)",
|
|
189727
|
+
labelKey: "provider-reolink:schema.s_pir.pirIntervalS.label",
|
|
188233
189728
|
description: `Minimum delay between consecutive PIR triggers. Reolink app range 5..${intervalMax}s; firmware clamps on push.`,
|
|
188234
189729
|
min: 5,
|
|
188235
189730
|
max: intervalMax,
|
|
@@ -188242,7 +189737,9 @@ var PirAccessory = class extends BaseDevice {
|
|
|
188242
189737
|
type: "boolean",
|
|
188243
189738
|
key: "pirReduceAlarm",
|
|
188244
189739
|
label: "Reduce false alarms",
|
|
189740
|
+
labelKey: "provider-reolink:schema.s_pir.pirReduceAlarm.label",
|
|
188245
189741
|
description: "Trades detection range for fewer false positives. Maps to firmware `reduceAlarm` flag.",
|
|
189742
|
+
descriptionKey: "provider-reolink:schema.s_pir.pirReduceAlarm.description",
|
|
188246
189743
|
...typeof reduceAlarm === "boolean" ? { default: reduceAlarm } : {},
|
|
188247
189744
|
style: "switch",
|
|
188248
189745
|
span: 2
|
|
@@ -189770,6 +191267,7 @@ function buildSessionsTabSections(snap, opts) {
|
|
|
189770
191267
|
type: "info",
|
|
189771
191268
|
key: "sessionsError",
|
|
189772
191269
|
label: "Refresh error",
|
|
191270
|
+
labelKey: "provider-reolink:errorBanner.sessionsError.label",
|
|
189773
191271
|
content: snap.error,
|
|
189774
191272
|
variant: "danger"
|
|
189775
191273
|
}] : [];
|
|
@@ -189791,6 +191289,7 @@ function buildSessionsTabSections(snap, opts) {
|
|
|
189791
191289
|
id: "sessions-status",
|
|
189792
191290
|
title: opts.title ?? "Sessions",
|
|
189793
191291
|
description: "Diagnostics for the Baichuan control channel. Auto-refreshes when older than 1 minute; click Refresh to force.",
|
|
191292
|
+
descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.description",
|
|
189794
191293
|
tab: opts.tabId,
|
|
189795
191294
|
order: 0,
|
|
189796
191295
|
columns: 1,
|
|
@@ -189800,38 +191299,46 @@ function buildSessionsTabSections(snap, opts) {
|
|
|
189800
191299
|
type: "info",
|
|
189801
191300
|
key: "sessionsLastRefreshed",
|
|
189802
191301
|
label: "Last refreshed",
|
|
191302
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsLastRefreshed.label",
|
|
189803
191303
|
content: ageInfo
|
|
189804
191304
|
},
|
|
189805
191305
|
{
|
|
189806
191306
|
type: "object-array",
|
|
189807
191307
|
key: "sessionsOnlineUsers",
|
|
189808
191308
|
label: "Online users (firmware)",
|
|
191309
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.label",
|
|
189809
191310
|
description: "Active user sessions reported by the device (cmd_id 145). Includes other admins, mobile app, NVR linkups.",
|
|
191311
|
+
descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.description",
|
|
189810
191312
|
columns: [
|
|
189811
191313
|
{
|
|
189812
191314
|
key: "userName",
|
|
189813
|
-
label: "User"
|
|
191315
|
+
label: "User",
|
|
191316
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.userName.label"
|
|
189814
191317
|
},
|
|
189815
191318
|
{
|
|
189816
191319
|
key: "ip",
|
|
189817
191320
|
label: "IP",
|
|
191321
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.ip.label",
|
|
189818
191322
|
kind: "monospace",
|
|
189819
191323
|
width: "160px"
|
|
189820
191324
|
},
|
|
189821
191325
|
{
|
|
189822
191326
|
key: "sessionId",
|
|
189823
191327
|
label: "Session",
|
|
191328
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.sessionId.label",
|
|
189824
191329
|
kind: "monospace",
|
|
189825
191330
|
width: "90px"
|
|
189826
191331
|
},
|
|
189827
191332
|
{
|
|
189828
191333
|
key: "level",
|
|
189829
191334
|
label: "Level",
|
|
191335
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.level.label",
|
|
189830
191336
|
width: "80px"
|
|
189831
191337
|
},
|
|
189832
191338
|
{
|
|
189833
191339
|
key: "status",
|
|
189834
191340
|
label: "State",
|
|
191341
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.status.label",
|
|
189835
191342
|
kind: "status",
|
|
189836
191343
|
width: "100px"
|
|
189837
191344
|
}
|
|
@@ -189843,14 +191350,18 @@ function buildSessionsTabSections(snap, opts) {
|
|
|
189843
191350
|
type: "object-array",
|
|
189844
191351
|
key: "sessionsSocketPool",
|
|
189845
191352
|
label: "Our socket pool",
|
|
191353
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsSocketPool.label",
|
|
189846
191354
|
description: "Open Baichuan TCP/UDP sockets this process holds for the device. One row per pool tag.",
|
|
191355
|
+
descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsSocketPool.description",
|
|
189847
191356
|
columns: [{
|
|
189848
191357
|
key: "tag",
|
|
189849
191358
|
label: "Tag",
|
|
191359
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsSocketPool.tag.label",
|
|
189850
191360
|
kind: "monospace"
|
|
189851
191361
|
}, {
|
|
189852
191362
|
key: "state",
|
|
189853
191363
|
label: "State",
|
|
191364
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsSocketPool.state.label",
|
|
189854
191365
|
kind: "status",
|
|
189855
191366
|
width: "100px"
|
|
189856
191367
|
}],
|
|
@@ -189861,10 +191372,13 @@ function buildSessionsTabSections(snap, opts) {
|
|
|
189861
191372
|
type: "object-array",
|
|
189862
191373
|
key: "sessionsDedicated",
|
|
189863
191374
|
label: "Dedicated lib sessions",
|
|
191375
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsDedicated.label",
|
|
189864
191376
|
description: "Internal lib-side dedicated sessions (streaming/talk channels). Older lib versions leave this list empty.",
|
|
191377
|
+
descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsDedicated.description",
|
|
189865
191378
|
columns: [{
|
|
189866
191379
|
key: "key",
|
|
189867
191380
|
label: "Session key",
|
|
191381
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsDedicated.key.label",
|
|
189868
191382
|
kind: "monospace"
|
|
189869
191383
|
}],
|
|
189870
191384
|
value: dedicatedRows,
|
|
@@ -189874,12 +191388,14 @@ function buildSessionsTabSections(snap, opts) {
|
|
|
189874
191388
|
type: "info",
|
|
189875
191389
|
key: "sessionsCooldown",
|
|
189876
191390
|
label: "Reconnect cooldown",
|
|
191391
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsCooldown.label",
|
|
189877
191392
|
content: cooldownText
|
|
189878
191393
|
},
|
|
189879
191394
|
{
|
|
189880
191395
|
type: "device-action-button",
|
|
189881
191396
|
key: "_refreshSessions",
|
|
189882
191397
|
label: "Refresh sessions",
|
|
191398
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status._refreshSessions.label",
|
|
189883
191399
|
buttonLabel: "Refresh now",
|
|
189884
191400
|
action: "refresh-sessions",
|
|
189885
191401
|
variant: "default"
|
|
@@ -191351,11 +192867,11 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
191351
192867
|
});
|
|
191352
192868
|
if (!this.isEmailPushEligible) {
|
|
191353
192869
|
this.ctx.logger.warn("email-push: not eligible (hub-attached camera)", { tags: { deviceId: this.id } });
|
|
191354
|
-
throw
|
|
192870
|
+
throw userError("reolink.email-push-hub-attached", void 0, "Email push is not available for hub-attached cameras");
|
|
191355
192871
|
}
|
|
191356
192872
|
if (!this.emailPushParamsResolver) {
|
|
191357
192873
|
this.ctx.logger.warn("email-push: resolver not wired — restart the Reolink addon", { tags: { deviceId: this.id } });
|
|
191358
|
-
throw
|
|
192874
|
+
throw userError("reolink.email-push-not-wired", void 0, "Email Push Server is not wired — restart the Reolink addon");
|
|
191359
192875
|
}
|
|
191360
192876
|
const params = await this.emailPushParamsResolver();
|
|
191361
192877
|
if (!params) {
|
|
@@ -191414,14 +192930,14 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
191414
192930
|
this.ctx.logger.warn("baichuan-webhook: not eligible", { tags: { deviceId: this.id } });
|
|
191415
192931
|
throw new Error("HaCfg webhook Auto-configure is only available on standalone battery cameras");
|
|
191416
192932
|
}
|
|
191417
|
-
if (!this.baichuanWebhookParamsResolver) throw
|
|
192933
|
+
if (!this.baichuanWebhookParamsResolver) throw userError("reolink.webhook-not-wired", void 0, "HaCfg Webhook Server is not wired — restart the Reolink addon");
|
|
191418
192934
|
const params = await this.baichuanWebhookParamsResolver();
|
|
191419
192935
|
if (!params) throw new Error("Enable the HaCfg Webhook Server in the Reolink addon settings, and ensure this host has a reachable LAN address.");
|
|
191420
192936
|
await this.wakeIfSleeping();
|
|
191421
192937
|
const api = await this.ensureApi();
|
|
191422
192938
|
const supported = await api.probeBaichuanWebhookSupport();
|
|
191423
192939
|
this.baichuanWebhookSupportedCached = supported;
|
|
191424
|
-
if (!supported) throw
|
|
192940
|
+
if (!supported) throw userError("reolink.webhook-unsupported", void 0, "Camera firmware does not support Baichuan HaCfg webhook (cmd 806)");
|
|
191425
192941
|
this.ctx.logger.info("baichuan-webhook: auto-configuring camera", {
|
|
191426
192942
|
tags: { deviceId: this.id },
|
|
191427
192943
|
meta: { url: params.url }
|
|
@@ -192100,26 +193616,32 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192100
193616
|
id: "sleep-push",
|
|
192101
193617
|
tab: "motion",
|
|
192102
193618
|
title: "Battery motion (sleep push)",
|
|
193619
|
+
titleKey: "provider-reolink:emailPushSection.s_sleep-push.title",
|
|
192103
193620
|
description: "Battery cameras sleep and can't be polled for motion. Prefer HaCfg webhook when the firmware supports it (cmd 806); otherwise use Email/SMTP. Enable the matching server under Integrations → Reolink, then Auto-configure. Only one path should be armed — the preference below gates which inbound source is accepted.",
|
|
193621
|
+
descriptionKey: "provider-reolink:emailPushSection.s_sleep-push.description",
|
|
192104
193622
|
columns: 1,
|
|
192105
193623
|
fields: [
|
|
192106
193624
|
{
|
|
192107
193625
|
type: "select",
|
|
192108
193626
|
key: "batterySleepPushMethod",
|
|
192109
193627
|
label: "Preferred sleep-push path",
|
|
193628
|
+
labelKey: "provider-reolink:emailPushSection.s_sleep-push.batterySleepPushMethod.label",
|
|
192110
193629
|
default: "auto",
|
|
192111
193630
|
options: [
|
|
192112
193631
|
{
|
|
192113
193632
|
value: "auto",
|
|
192114
|
-
label: "Auto (webhook if supported, else email)"
|
|
193633
|
+
label: "Auto (webhook if supported, else email)",
|
|
193634
|
+
labelKey: "provider-reolink:emailPushSection.s_sleep-push.batterySleepPushMethod.o_auto.label"
|
|
192115
193635
|
},
|
|
192116
193636
|
{
|
|
192117
193637
|
value: "webhook",
|
|
192118
|
-
label: "HaCfg webhook only"
|
|
193638
|
+
label: "HaCfg webhook only",
|
|
193639
|
+
labelKey: "provider-reolink:emailPushSection.s_sleep-push.batterySleepPushMethod.o_webhook.label"
|
|
192119
193640
|
},
|
|
192120
193641
|
{
|
|
192121
193642
|
value: "email",
|
|
192122
|
-
label: "Email/SMTP only"
|
|
193643
|
+
label: "Email/SMTP only",
|
|
193644
|
+
labelKey: "provider-reolink:emailPushSection.s_sleep-push.batterySleepPushMethod.o_email.label"
|
|
192123
193645
|
}
|
|
192124
193646
|
]
|
|
192125
193647
|
},
|
|
@@ -192127,6 +193649,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192127
193649
|
type: "device-action-button",
|
|
192128
193650
|
key: "_autoConfigureBaichuanWebhook",
|
|
192129
193651
|
label: "HaCfg webhook",
|
|
193652
|
+
labelKey: "provider-reolink:emailPushSection.s_sleep-push._autoConfigureBaichuanWebhook.label",
|
|
192130
193653
|
buttonLabel: "Auto-configure HaCfg webhook",
|
|
192131
193654
|
action: "auto-configure-baichuan-webhook",
|
|
192132
193655
|
variant: "default"
|
|
@@ -192135,6 +193658,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192135
193658
|
type: "device-action-button",
|
|
192136
193659
|
key: "_autoConfigureEmailPush",
|
|
192137
193660
|
label: "Email push",
|
|
193661
|
+
labelKey: "provider-reolink:emailPushSection.s_sleep-push._autoConfigureEmailPush.label",
|
|
192138
193662
|
buttonLabel: "Auto-configure email push",
|
|
192139
193663
|
action: "auto-configure-email-push",
|
|
192140
193664
|
variant: "default"
|
|
@@ -192158,19 +193682,23 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192158
193682
|
id: "email-smtp",
|
|
192159
193683
|
tab: "email",
|
|
192160
193684
|
title: "SMTP server",
|
|
193685
|
+
titleKey: "provider-reolink:emailTabSections.s_email-smtp.title",
|
|
192161
193686
|
description: "The camera's own outgoing-mail (SMTP) settings. Edit and save to write them to the camera, or use \"Auto-configure email push\" under Motion to point it at the built-in server. Leave the password blank to keep the current one.",
|
|
193687
|
+
descriptionKey: "provider-reolink:emailTabSections.s_email-smtp.description",
|
|
192162
193688
|
columns: 2,
|
|
192163
193689
|
fields: [
|
|
192164
193690
|
{
|
|
192165
193691
|
type: "text",
|
|
192166
193692
|
key: "emailSmtpServer",
|
|
192167
193693
|
label: "SMTP server",
|
|
193694
|
+
labelKey: "provider-reolink:emailTabSections.s_email-smtp.emailSmtpServer.label",
|
|
192168
193695
|
placeholder: "smtp.example.com"
|
|
192169
193696
|
},
|
|
192170
193697
|
{
|
|
192171
193698
|
type: "number",
|
|
192172
193699
|
key: "emailSmtpPort",
|
|
192173
193700
|
label: "SMTP port",
|
|
193701
|
+
labelKey: "provider-reolink:emailTabSections.s_email-smtp.emailSmtpPort.label",
|
|
192174
193702
|
min: 1,
|
|
192175
193703
|
max: 65535,
|
|
192176
193704
|
step: 1
|
|
@@ -192179,12 +193707,14 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192179
193707
|
type: "text",
|
|
192180
193708
|
key: "emailUserName",
|
|
192181
193709
|
label: "Username / sender",
|
|
193710
|
+
labelKey: "provider-reolink:emailTabSections.s_email-smtp.emailUserName.label",
|
|
192182
193711
|
placeholder: "cam@example.com"
|
|
192183
193712
|
},
|
|
192184
193713
|
{
|
|
192185
193714
|
type: "password",
|
|
192186
193715
|
key: "emailPassword",
|
|
192187
193716
|
label: "Password",
|
|
193717
|
+
labelKey: "provider-reolink:emailTabSections.s_email-smtp.emailPassword.label",
|
|
192188
193718
|
showToggle: true,
|
|
192189
193719
|
placeholder: "leave blank to keep"
|
|
192190
193720
|
},
|
|
@@ -192192,12 +193722,14 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192192
193722
|
type: "boolean",
|
|
192193
193723
|
key: "emailSsl",
|
|
192194
193724
|
label: "SSL/TLS",
|
|
193725
|
+
labelKey: "provider-reolink:emailTabSections.s_email-smtp.emailSsl.label",
|
|
192195
193726
|
style: "switch"
|
|
192196
193727
|
},
|
|
192197
193728
|
{
|
|
192198
193729
|
type: "text",
|
|
192199
193730
|
key: "emailSendNickname",
|
|
192200
|
-
label: "Sender name"
|
|
193731
|
+
label: "Sender name",
|
|
193732
|
+
labelKey: "provider-reolink:emailTabSections.s_email-smtp.emailSendNickname.label"
|
|
192201
193733
|
}
|
|
192202
193734
|
]
|
|
192203
193735
|
},
|
|
@@ -192205,24 +193737,29 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192205
193737
|
id: "email-recipients",
|
|
192206
193738
|
tab: "email",
|
|
192207
193739
|
title: "Recipients",
|
|
193740
|
+
titleKey: "provider-reolink:emailTabSections.s_email-recipients.title",
|
|
192208
193741
|
description: "Up to three recipient addresses the camera sends motion mail to.",
|
|
193742
|
+
descriptionKey: "provider-reolink:emailTabSections.s_email-recipients.description",
|
|
192209
193743
|
columns: 1,
|
|
192210
193744
|
fields: [
|
|
192211
193745
|
{
|
|
192212
193746
|
type: "text",
|
|
192213
193747
|
key: "emailRecipient1",
|
|
192214
193748
|
label: "Recipient 1",
|
|
193749
|
+
labelKey: "provider-reolink:emailTabSections.s_email-recipients.emailRecipient1.label",
|
|
192215
193750
|
placeholder: "alerts@example.com"
|
|
192216
193751
|
},
|
|
192217
193752
|
{
|
|
192218
193753
|
type: "text",
|
|
192219
193754
|
key: "emailRecipient2",
|
|
192220
|
-
label: "Recipient 2"
|
|
193755
|
+
label: "Recipient 2",
|
|
193756
|
+
labelKey: "provider-reolink:emailTabSections.s_email-recipients.emailRecipient2.label"
|
|
192221
193757
|
},
|
|
192222
193758
|
{
|
|
192223
193759
|
type: "text",
|
|
192224
193760
|
key: "emailRecipient3",
|
|
192225
|
-
label: "Recipient 3"
|
|
193761
|
+
label: "Recipient 3",
|
|
193762
|
+
labelKey: "provider-reolink:emailTabSections.s_email-recipients.emailRecipient3.label"
|
|
192226
193763
|
}
|
|
192227
193764
|
]
|
|
192228
193765
|
},
|
|
@@ -192230,12 +193767,15 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192230
193767
|
id: "email-schedule",
|
|
192231
193768
|
tab: "email",
|
|
192232
193769
|
title: "Alarm schedule",
|
|
193770
|
+
titleKey: "provider-reolink:emailTabSections.s_email-schedule.title",
|
|
192233
193771
|
description: "Master enable for the camera's email alarm schedule (EmailTask).",
|
|
193772
|
+
descriptionKey: "provider-reolink:emailTabSections.s_email-schedule.description",
|
|
192234
193773
|
columns: 1,
|
|
192235
193774
|
fields: [{
|
|
192236
193775
|
type: "boolean",
|
|
192237
193776
|
key: "emailScheduleEnabled",
|
|
192238
193777
|
label: "Email alarm schedule enabled",
|
|
193778
|
+
labelKey: "provider-reolink:emailTabSections.s_email-schedule.emailScheduleEnabled.label",
|
|
192239
193779
|
style: "switch"
|
|
192240
193780
|
}]
|
|
192241
193781
|
}
|
|
@@ -194463,7 +196003,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
194463
196003
|
const api = await this.ensureApi();
|
|
194464
196004
|
const channel = this.getChannel();
|
|
194465
196005
|
const id = Number(presetId);
|
|
194466
|
-
if (!Number.isFinite(id)) throw
|
|
196006
|
+
if (!Number.isFinite(id)) throw userError("reolink.preset-invalid", { presetId: String(presetId) }, `Invalid presetId: ${presetId}`);
|
|
194467
196007
|
await api.moveToPtzPreset(channel, id);
|
|
194468
196008
|
},
|
|
194469
196009
|
savePreset: async ({ deviceId, presetId, name }) => {
|
|
@@ -194471,7 +196011,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
194471
196011
|
const api = await this.ensureApi();
|
|
194472
196012
|
const channel = this.getChannel();
|
|
194473
196013
|
const id = Number(presetId);
|
|
194474
|
-
if (!Number.isFinite(id)) throw
|
|
196014
|
+
if (!Number.isFinite(id)) throw userError("reolink.preset-invalid", { presetId: String(presetId) }, `Invalid presetId: ${presetId}`);
|
|
194475
196015
|
await api.setPtzPreset(channel, id, name);
|
|
194476
196016
|
},
|
|
194477
196017
|
deletePreset: async ({ deviceId, presetId }) => {
|
|
@@ -194479,7 +196019,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
194479
196019
|
const api = await this.ensureApi();
|
|
194480
196020
|
const channel = this.getChannel();
|
|
194481
196021
|
const id = Number(presetId);
|
|
194482
|
-
if (!Number.isFinite(id)) throw
|
|
196022
|
+
if (!Number.isFinite(id)) throw userError("reolink.preset-invalid", { presetId: String(presetId) }, `Invalid presetId: ${presetId}`);
|
|
194483
196023
|
await api.deletePtzPreset(channel, id);
|
|
194484
196024
|
},
|
|
194485
196025
|
getOptions: async ({ deviceId }) => {
|
|
@@ -194531,7 +196071,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
194531
196071
|
}
|
|
194532
196072
|
if (home.source === "none" || home.presetId === null) throw new Error("No home preset configured for this camera, and it has no guard point set — set one in the PTZ settings, or place a guard point on the camera");
|
|
194533
196073
|
const id = Number(home.presetId);
|
|
194534
|
-
if (!Number.isFinite(id)) throw
|
|
196074
|
+
if (!Number.isFinite(id)) throw userError("reolink.home-preset-not-baichuan", { presetId: String(home.presetId) }, `Configured home preset is not a Baichuan id: ${home.presetId}`);
|
|
194535
196075
|
const api = await this.ensureApi();
|
|
194536
196076
|
const channel = this.getChannel();
|
|
194537
196077
|
await api.moveToPtzPreset(channel, id);
|
|
@@ -196103,12 +197643,15 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196103
197643
|
id: "driver-refresh",
|
|
196104
197644
|
tab: "general",
|
|
196105
197645
|
title: "Camera data",
|
|
197646
|
+
titleKey: "provider-reolink:schema.s_driver-refresh.title",
|
|
196106
197647
|
description: "Go and ask the camera now. Every other read here is deliberately cheap about a battery camera — it serves what it already knows and refreshes quietly behind you, and never wakes a sleeping camera just because you opened this tab. This button is the exception: it wakes the camera, re-reads everything, and tells you what it got. Use it after changing settings from the Reolink app, or whenever you want to be sure the form is showing the camera and not a memory of it.",
|
|
197648
|
+
descriptionKey: "provider-reolink:schema.s_driver-refresh.description",
|
|
196107
197649
|
columns: 1,
|
|
196108
197650
|
fields: [{
|
|
196109
197651
|
type: "device-action-button",
|
|
196110
197652
|
key: "_refreshSettings",
|
|
196111
197653
|
label: "Refresh from camera",
|
|
197654
|
+
labelKey: "provider-reolink:schema.s_driver-refresh._refreshSettings.label",
|
|
196112
197655
|
buttonLabel: "Refresh now",
|
|
196113
197656
|
action: "refresh-settings",
|
|
196114
197657
|
variant: "default",
|
|
@@ -196119,13 +197662,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196119
197662
|
id: "connection",
|
|
196120
197663
|
tab: "general",
|
|
196121
197664
|
title: "Connection",
|
|
197665
|
+
titleKey: "provider-reolink:schema.s_connection.title",
|
|
196122
197666
|
description: "Baichuan protocol connection settings.",
|
|
197667
|
+
descriptionKey: "provider-reolink:schema.s_connection.description",
|
|
196123
197668
|
columns: 2,
|
|
196124
197669
|
fields: [
|
|
196125
197670
|
{
|
|
196126
197671
|
type: "text",
|
|
196127
197672
|
key: "host",
|
|
196128
197673
|
label: "Camera IP",
|
|
197674
|
+
labelKey: "provider-reolink:schema.s_connection.host.label",
|
|
196129
197675
|
required: true,
|
|
196130
197676
|
placeholder: "192.168.10.100"
|
|
196131
197677
|
},
|
|
@@ -196133,6 +197679,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196133
197679
|
type: "number",
|
|
196134
197680
|
key: "port",
|
|
196135
197681
|
label: "Port",
|
|
197682
|
+
labelKey: "provider-reolink:schema.s_connection.port.label",
|
|
196136
197683
|
default: 9e3,
|
|
196137
197684
|
min: 1,
|
|
196138
197685
|
max: 65535,
|
|
@@ -196142,12 +197689,14 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196142
197689
|
type: "text",
|
|
196143
197690
|
key: "username",
|
|
196144
197691
|
label: "Username",
|
|
197692
|
+
labelKey: "provider-reolink:schema.s_connection.username.label",
|
|
196145
197693
|
default: "admin"
|
|
196146
197694
|
},
|
|
196147
197695
|
{
|
|
196148
197696
|
type: "password",
|
|
196149
197697
|
key: "password",
|
|
196150
197698
|
label: "Password",
|
|
197699
|
+
labelKey: "provider-reolink:schema.s_connection.password.label",
|
|
196151
197700
|
required: true,
|
|
196152
197701
|
showToggle: true
|
|
196153
197702
|
}
|
|
@@ -196157,13 +197706,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196157
197706
|
id: "network-ports",
|
|
196158
197707
|
tab: "network",
|
|
196159
197708
|
title: "Service ports",
|
|
197709
|
+
titleKey: "provider-reolink:schema.s_network-ports.title",
|
|
196160
197710
|
description: "Per-protocol enable toggle + port number, pushed via Baichuan `SetNetPort` (cmd_id 36). The Baichuan control port is the Connection → Port field. Changing a port number breaks existing URLs for that protocol until consumers are reconfigured.",
|
|
197711
|
+
descriptionKey: "provider-reolink:schema.s_network-ports.description",
|
|
196161
197712
|
columns: 2,
|
|
196162
197713
|
fields: [
|
|
196163
197714
|
{
|
|
196164
197715
|
type: "boolean",
|
|
196165
197716
|
key: "netHttpEnable",
|
|
196166
197717
|
label: "HTTP enabled",
|
|
197718
|
+
labelKey: "provider-reolink:schema.s_network-ports.netHttpEnable.label",
|
|
196167
197719
|
default: netSnap.http?.enable ?? true,
|
|
196168
197720
|
style: "switch"
|
|
196169
197721
|
},
|
|
@@ -196171,6 +197723,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196171
197723
|
type: "number",
|
|
196172
197724
|
key: "netHttpPort",
|
|
196173
197725
|
label: "HTTP port",
|
|
197726
|
+
labelKey: "provider-reolink:schema.s_network-ports.netHttpPort.label",
|
|
196174
197727
|
default: netSnap.http?.port ?? 80,
|
|
196175
197728
|
min: 1,
|
|
196176
197729
|
max: 65535,
|
|
@@ -196180,6 +197733,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196180
197733
|
type: "boolean",
|
|
196181
197734
|
key: "netHttpsEnable",
|
|
196182
197735
|
label: "HTTPS enabled",
|
|
197736
|
+
labelKey: "provider-reolink:schema.s_network-ports.netHttpsEnable.label",
|
|
196183
197737
|
default: netSnap.https?.enable ?? false,
|
|
196184
197738
|
style: "switch"
|
|
196185
197739
|
},
|
|
@@ -196187,6 +197741,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196187
197741
|
type: "number",
|
|
196188
197742
|
key: "netHttpsPort",
|
|
196189
197743
|
label: "HTTPS port",
|
|
197744
|
+
labelKey: "provider-reolink:schema.s_network-ports.netHttpsPort.label",
|
|
196190
197745
|
default: netSnap.https?.port ?? 443,
|
|
196191
197746
|
min: 1,
|
|
196192
197747
|
max: 65535,
|
|
@@ -196196,6 +197751,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196196
197751
|
type: "boolean",
|
|
196197
197752
|
key: "netRtspEnable",
|
|
196198
197753
|
label: "RTSP enabled",
|
|
197754
|
+
labelKey: "provider-reolink:schema.s_network-ports.netRtspEnable.label",
|
|
196199
197755
|
default: netSnap.rtsp?.enable ?? true,
|
|
196200
197756
|
style: "switch"
|
|
196201
197757
|
},
|
|
@@ -196203,6 +197759,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196203
197759
|
type: "number",
|
|
196204
197760
|
key: "netRtspPort",
|
|
196205
197761
|
label: "RTSP port",
|
|
197762
|
+
labelKey: "provider-reolink:schema.s_network-ports.netRtspPort.label",
|
|
196206
197763
|
default: netSnap.rtsp?.port ?? 554,
|
|
196207
197764
|
min: 1,
|
|
196208
197765
|
max: 65535,
|
|
@@ -196212,6 +197769,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196212
197769
|
type: "boolean",
|
|
196213
197770
|
key: "netRtmpEnable",
|
|
196214
197771
|
label: "RTMP enabled",
|
|
197772
|
+
labelKey: "provider-reolink:schema.s_network-ports.netRtmpEnable.label",
|
|
196215
197773
|
default: netSnap.rtmp?.enable ?? true,
|
|
196216
197774
|
style: "switch"
|
|
196217
197775
|
},
|
|
@@ -196219,6 +197777,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196219
197777
|
type: "number",
|
|
196220
197778
|
key: "netRtmpPort",
|
|
196221
197779
|
label: "RTMP port",
|
|
197780
|
+
labelKey: "provider-reolink:schema.s_network-ports.netRtmpPort.label",
|
|
196222
197781
|
default: netSnap.rtmp?.port ?? 1935,
|
|
196223
197782
|
min: 1,
|
|
196224
197783
|
max: 65535,
|
|
@@ -196228,6 +197787,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196228
197787
|
type: "boolean",
|
|
196229
197788
|
key: "netOnvifEnable",
|
|
196230
197789
|
label: "ONVIF enabled",
|
|
197790
|
+
labelKey: "provider-reolink:schema.s_network-ports.netOnvifEnable.label",
|
|
196231
197791
|
default: netSnap.onvif?.enable ?? true,
|
|
196232
197792
|
style: "switch"
|
|
196233
197793
|
},
|
|
@@ -196235,6 +197795,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196235
197795
|
type: "number",
|
|
196236
197796
|
key: "netOnvifPort",
|
|
196237
197797
|
label: "ONVIF port",
|
|
197798
|
+
labelKey: "provider-reolink:schema.s_network-ports.netOnvifPort.label",
|
|
196238
197799
|
default: netSnap.onvif?.port ?? 8e3,
|
|
196239
197800
|
min: 1,
|
|
196240
197801
|
max: 65535,
|
|
@@ -196246,14 +197807,18 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196246
197807
|
id: "time-ntp",
|
|
196247
197808
|
tab: "network",
|
|
196248
197809
|
title: "Time / NTP",
|
|
197810
|
+
titleKey: "provider-reolink:schema.s_time-ntp.title",
|
|
196249
197811
|
description: "Network time synchronisation. The camera-side push goes through the native Baichuan NTP commands; until those land in the driver lib the values persist to the driver config and apply on the next lib update.",
|
|
197812
|
+
descriptionKey: "provider-reolink:schema.s_time-ntp.description",
|
|
196250
197813
|
columns: 2,
|
|
196251
197814
|
fields: [
|
|
196252
197815
|
{
|
|
196253
197816
|
type: "timezone",
|
|
196254
197817
|
key: "timeZoneId",
|
|
196255
197818
|
label: "Timezone",
|
|
197819
|
+
labelKey: "provider-reolink:schema.s_time-ntp.timeZoneId.label",
|
|
196256
197820
|
description: "Camera timezone. Selecting a zone pushes its standard UTC offset (Baichuan `SetSystemGeneral`, cmd 105) and DST rule (`SetDst`, cmd 107) to the camera — DST is handled automatically by the chosen zone, so summer/winter clocks track correctly without a separate toggle.",
|
|
197821
|
+
descriptionKey: "provider-reolink:schema.s_time-ntp.timeZoneId.description",
|
|
196257
197822
|
default: this.config.get("timeZoneId") ?? reolinkTimeZoneToIana(this.config.get("deviceCache")?.systemGeneralSnapshot?.timeZone) ?? "",
|
|
196258
197823
|
span: 2
|
|
196259
197824
|
},
|
|
@@ -196261,6 +197826,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196261
197826
|
type: "boolean",
|
|
196262
197827
|
key: "ntpEnabled",
|
|
196263
197828
|
label: "NTP sync",
|
|
197829
|
+
labelKey: "provider-reolink:schema.s_time-ntp.ntpEnabled.label",
|
|
196264
197830
|
default: ntpSnap.enabled ?? true,
|
|
196265
197831
|
style: "switch",
|
|
196266
197832
|
span: 2
|
|
@@ -196269,6 +197835,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196269
197835
|
type: "text",
|
|
196270
197836
|
key: "ntpServer",
|
|
196271
197837
|
label: "NTP server",
|
|
197838
|
+
labelKey: "provider-reolink:schema.s_time-ntp.ntpServer.label",
|
|
196272
197839
|
default: ntpSnap.server ?? "pool.ntp.org",
|
|
196273
197840
|
placeholder: "pool.ntp.org",
|
|
196274
197841
|
span: 2
|
|
@@ -196277,6 +197844,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196277
197844
|
type: "number",
|
|
196278
197845
|
key: "ntpPort",
|
|
196279
197846
|
label: "NTP port",
|
|
197847
|
+
labelKey: "provider-reolink:schema.s_time-ntp.ntpPort.label",
|
|
196280
197848
|
default: ntpSnap.port ?? 123,
|
|
196281
197849
|
min: 1,
|
|
196282
197850
|
max: 65535,
|
|
@@ -196286,6 +197854,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196286
197854
|
type: "number",
|
|
196287
197855
|
key: "ntpInterval",
|
|
196288
197856
|
label: "Sync interval (min)",
|
|
197857
|
+
labelKey: "provider-reolink:schema.s_time-ntp.ntpInterval.label",
|
|
196289
197858
|
default: ntpSnap.interval ?? 1440,
|
|
196290
197859
|
min: 1,
|
|
196291
197860
|
max: 10080,
|
|
@@ -196297,13 +197866,17 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196297
197866
|
id: "motion",
|
|
196298
197867
|
tab: "motion",
|
|
196299
197868
|
title: "On-camera motion (MdAlarm)",
|
|
197869
|
+
titleKey: "provider-reolink:schema.s_motion.title",
|
|
196300
197870
|
description: "Camera-side motion detection master switch + sensitivity. Pushed via Baichuan `SetMdAlarm` (cmd_id 47). Range 1..50 matches the Reolink mobile app + web UI; the driver inverts to the camera-side raw value (`51 - value`) before push.",
|
|
197871
|
+
descriptionKey: "provider-reolink:schema.s_motion.description",
|
|
196301
197872
|
columns: 2,
|
|
196302
197873
|
fields: [{
|
|
196303
197874
|
type: "boolean",
|
|
196304
197875
|
key: "motionEnabled",
|
|
196305
197876
|
label: "Motion detection",
|
|
197877
|
+
labelKey: "provider-reolink:schema.s_motion.motionEnabled.label",
|
|
196306
197878
|
description: "Master switch for the camera's on-board motion detector. Disabling stops the camera from emitting motion events on the alarm channel.",
|
|
197879
|
+
descriptionKey: "provider-reolink:schema.s_motion.motionEnabled.description",
|
|
196307
197880
|
default: motionSnap.enabled ?? true,
|
|
196308
197881
|
style: "switch",
|
|
196309
197882
|
span: 2
|
|
@@ -196311,7 +197884,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196311
197884
|
type: "slider",
|
|
196312
197885
|
key: "motionSensitivity",
|
|
196313
197886
|
label: "Sensitivity",
|
|
197887
|
+
labelKey: "provider-reolink:schema.s_motion.motionSensitivity.label",
|
|
196314
197888
|
description: "Higher = triggers on smaller motion. Reolink user-facing range 1..50.",
|
|
197889
|
+
descriptionKey: "provider-reolink:schema.s_motion.motionSensitivity.description",
|
|
196315
197890
|
min: 1,
|
|
196316
197891
|
max: 50,
|
|
196317
197892
|
step: 1,
|
|
@@ -196325,7 +197900,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196325
197900
|
id: "ai-sensitivity",
|
|
196326
197901
|
tab: "motion",
|
|
196327
197902
|
title: "AI detection sensitivity",
|
|
197903
|
+
titleKey: "provider-reolink:schema.s_ai-sensitivity.title",
|
|
196328
197904
|
description: "Per-class on-camera AI sensitivity, stay time (dwell) + min/max target-size gates. Pushed via `SetAiAlarm` (cmd_id 343) in one consolidated write. Sensitivity range 0..100; stay time is the seconds the camera keeps the alarm asserted after the object leaves; target-size gates are the fraction of the frame (0..1) an object must occupy to be considered. Each group appears only when the camera advertises the corresponding detector.",
|
|
197905
|
+
descriptionKey: "provider-reolink:schema.s_ai-sensitivity.description",
|
|
196329
197906
|
columns: 2,
|
|
196330
197907
|
fields: [
|
|
196331
197908
|
[
|
|
@@ -196456,13 +198033,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196456
198033
|
id: "image",
|
|
196457
198034
|
tab: "image",
|
|
196458
198035
|
title: "Image",
|
|
198036
|
+
titleKey: "provider-reolink:schema.s_image.title",
|
|
196459
198037
|
description: "Core image settings pushed via Baichuan `SetImage` (cmd_id 25). Each slider rearms the camera on save; defaults seed from a `GetVideoInput` probe at boot (refreshed on every `applySettingsPatch`). Range 0..255 — most Reolink models clamp to 0..100 internally.",
|
|
198038
|
+
descriptionKey: "provider-reolink:schema.s_image.description",
|
|
196460
198039
|
columns: 2,
|
|
196461
198040
|
fields: [
|
|
196462
198041
|
{
|
|
196463
198042
|
type: "slider",
|
|
196464
198043
|
key: "imgBright",
|
|
196465
198044
|
label: "Brightness",
|
|
198045
|
+
labelKey: "provider-reolink:schema.s_image.imgBright.label",
|
|
196466
198046
|
min: 0,
|
|
196467
198047
|
max: 255,
|
|
196468
198048
|
step: 1,
|
|
@@ -196474,6 +198054,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196474
198054
|
type: "slider",
|
|
196475
198055
|
key: "imgContrast",
|
|
196476
198056
|
label: "Contrast",
|
|
198057
|
+
labelKey: "provider-reolink:schema.s_image.imgContrast.label",
|
|
196477
198058
|
min: 0,
|
|
196478
198059
|
max: 255,
|
|
196479
198060
|
step: 1,
|
|
@@ -196485,6 +198066,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196485
198066
|
type: "slider",
|
|
196486
198067
|
key: "imgSaturation",
|
|
196487
198068
|
label: "Saturation",
|
|
198069
|
+
labelKey: "provider-reolink:schema.s_image.imgSaturation.label",
|
|
196488
198070
|
min: 0,
|
|
196489
198071
|
max: 255,
|
|
196490
198072
|
step: 1,
|
|
@@ -196496,6 +198078,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196496
198078
|
type: "slider",
|
|
196497
198079
|
key: "imgHue",
|
|
196498
198080
|
label: "Hue",
|
|
198081
|
+
labelKey: "provider-reolink:schema.s_image.imgHue.label",
|
|
196499
198082
|
min: 0,
|
|
196500
198083
|
max: 255,
|
|
196501
198084
|
step: 1,
|
|
@@ -196507,6 +198090,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196507
198090
|
type: "slider",
|
|
196508
198091
|
key: "imgSharpen",
|
|
196509
198092
|
label: "Sharpness",
|
|
198093
|
+
labelKey: "provider-reolink:schema.s_image.imgSharpen.label",
|
|
196510
198094
|
min: 0,
|
|
196511
198095
|
max: 255,
|
|
196512
198096
|
step: 1,
|
|
@@ -196521,19 +198105,25 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196521
198105
|
id: "isp",
|
|
196522
198106
|
tab: "image",
|
|
196523
198107
|
title: "Advanced (ISP)",
|
|
198108
|
+
titleKey: "provider-reolink:schema.s_isp.title",
|
|
196524
198109
|
description: "Day/Night + exposure + HDR. Pushed via `SetIsp` (cmd_id 25). The day/night threshold uses cmd_id 297 (DayNightThreshold).",
|
|
198110
|
+
descriptionKey: "provider-reolink:schema.s_isp.description",
|
|
196525
198111
|
columns: 2,
|
|
196526
198112
|
fields: [{
|
|
196527
198113
|
type: "text",
|
|
196528
198114
|
key: "ispDayNight",
|
|
196529
198115
|
label: "Day/Night mode",
|
|
198116
|
+
labelKey: "provider-reolink:schema.s_isp.ispDayNight.label",
|
|
196530
198117
|
description: "Camera-specific values — common: `auto`, `color`, `blackAndWhite`. The driver normalizes case before push.",
|
|
198118
|
+
descriptionKey: "provider-reolink:schema.s_isp.ispDayNight.description",
|
|
196531
198119
|
default: imgSnap.dayNight ?? "auto"
|
|
196532
198120
|
}, {
|
|
196533
198121
|
type: "text",
|
|
196534
198122
|
key: "ispExposure",
|
|
196535
198123
|
label: "Exposure",
|
|
198124
|
+
labelKey: "provider-reolink:schema.s_isp.ispExposure.label",
|
|
196536
198125
|
description: "Common values: `auto`, `manual`. Lowercased before push.",
|
|
198126
|
+
descriptionKey: "provider-reolink:schema.s_isp.ispExposure.description",
|
|
196537
198127
|
default: "auto"
|
|
196538
198128
|
}]
|
|
196539
198129
|
}] : [],
|
|
@@ -196541,26 +198131,32 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196541
198131
|
id: "ir-lights",
|
|
196542
198132
|
tab: "image",
|
|
196543
198133
|
title: "IR + status LED",
|
|
198134
|
+
titleKey: "provider-reolink:schema.s_ir-lights.title",
|
|
196544
198135
|
description: "IR LED control + per-camera IR brightness. Pushed via `SetIrLights` (cmd_id 209). State `Auto` lets the camera switch IR on automatically at low light; `Off` forces colour-only mode.",
|
|
198136
|
+
descriptionKey: "provider-reolink:schema.s_ir-lights.description",
|
|
196545
198137
|
columns: 2,
|
|
196546
198138
|
fields: [
|
|
196547
198139
|
{
|
|
196548
198140
|
type: "select",
|
|
196549
198141
|
key: "irLightsState",
|
|
196550
198142
|
label: "IR LED",
|
|
198143
|
+
labelKey: "provider-reolink:schema.s_ir-lights.irLightsState.label",
|
|
196551
198144
|
default: "Auto",
|
|
196552
198145
|
options: [
|
|
196553
198146
|
{
|
|
196554
198147
|
value: "Auto",
|
|
196555
|
-
label: "Auto (camera decides)"
|
|
198148
|
+
label: "Auto (camera decides)",
|
|
198149
|
+
labelKey: "provider-reolink:schema.s_ir-lights.irLightsState.o_Auto.label"
|
|
196556
198150
|
},
|
|
196557
198151
|
{
|
|
196558
198152
|
value: "On",
|
|
196559
|
-
label: "Always on"
|
|
198153
|
+
label: "Always on",
|
|
198154
|
+
labelKey: "provider-reolink:schema.s_ir-lights.irLightsState.o_On.label"
|
|
196560
198155
|
},
|
|
196561
198156
|
{
|
|
196562
198157
|
value: "Off",
|
|
196563
|
-
label: "Always off"
|
|
198158
|
+
label: "Always off",
|
|
198159
|
+
labelKey: "provider-reolink:schema.s_ir-lights.irLightsState.o_Off.label"
|
|
196564
198160
|
}
|
|
196565
198161
|
]
|
|
196566
198162
|
},
|
|
@@ -196568,7 +198164,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196568
198164
|
type: "slider",
|
|
196569
198165
|
key: "irLightsBrightness",
|
|
196570
198166
|
label: "IR brightness",
|
|
198167
|
+
labelKey: "provider-reolink:schema.s_ir-lights.irLightsBrightness.label",
|
|
196571
198168
|
description: "Only applied when the camera advertises programmable IR brightness. 0..255 raw range; many models clamp to 0..100.",
|
|
198169
|
+
descriptionKey: "provider-reolink:schema.s_ir-lights.irLightsBrightness.description",
|
|
196572
198170
|
min: 0,
|
|
196573
198171
|
max: 255,
|
|
196574
198172
|
step: 5,
|
|
@@ -196580,7 +198178,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196580
198178
|
type: "boolean",
|
|
196581
198179
|
key: "statusLedEnabled",
|
|
196582
198180
|
label: "Status LED",
|
|
198181
|
+
labelKey: "provider-reolink:schema.s_ir-lights.statusLedEnabled.label",
|
|
196583
198182
|
description: "The visible status/power LED on the camera body. Pushed via `SetIrLights` (cmd_id 209) as `lightState`.",
|
|
198183
|
+
descriptionKey: "provider-reolink:schema.s_ir-lights.statusLedEnabled.description",
|
|
196584
198184
|
default: cache?.ledSnapshot?.statusEnabled ?? true,
|
|
196585
198185
|
style: "switch",
|
|
196586
198186
|
span: cache?.ledSnapshot?.doorbellSupported === true ? 1 : 2
|
|
@@ -196589,7 +198189,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196589
198189
|
type: "boolean",
|
|
196590
198190
|
key: "doorbellLedEnabled",
|
|
196591
198191
|
label: "Doorbell LED",
|
|
198192
|
+
labelKey: "provider-reolink:schema.s_ir-lights.doorbellLedEnabled.label",
|
|
196592
198193
|
description: "The doorbell button ring LED. Pushed via `SetIrLights` (cmd_id 209) as `doorbellLightState`.",
|
|
198194
|
+
descriptionKey: "provider-reolink:schema.s_ir-lights.doorbellLedEnabled.description",
|
|
196593
198195
|
default: cache?.ledSnapshot?.doorbellEnabled ?? true,
|
|
196594
198196
|
style: "switch"
|
|
196595
198197
|
}] : []
|
|
@@ -196603,12 +198205,15 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196603
198205
|
id: "auto-focus",
|
|
196604
198206
|
tab: "image",
|
|
196605
198207
|
title: "Auto focus",
|
|
198208
|
+
titleKey: "provider-reolink:schema.s_auto-focus.title",
|
|
196606
198209
|
description: "Toggles the lens auto-focus subsystem. Pushed via `SetAutoFocus` (cmd_id 225). Disabling locks the lens at its current focal position — useful for fixed-distance scenes where AF would hunt.",
|
|
198210
|
+
descriptionKey: "provider-reolink:schema.s_auto-focus.description",
|
|
196607
198211
|
columns: 1,
|
|
196608
198212
|
fields: [{
|
|
196609
198213
|
type: "boolean",
|
|
196610
198214
|
key: "autoFocusEnabled",
|
|
196611
198215
|
label: "Auto focus",
|
|
198216
|
+
labelKey: "provider-reolink:schema.s_auto-focus.autoFocusEnabled.label",
|
|
196612
198217
|
default: cache.autoFocusSnapshot?.enabled ?? true,
|
|
196613
198218
|
style: "switch"
|
|
196614
198219
|
}]
|
|
@@ -196617,13 +198222,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196617
198222
|
id: "audio",
|
|
196618
198223
|
tab: "audio",
|
|
196619
198224
|
title: "Audio output",
|
|
198225
|
+
titleKey: "provider-reolink:schema.s_audio.title",
|
|
196620
198226
|
description: "Speaker volumes pushed via `SetAudioCfg` (cmd_id 265). All ranges 0..100. Doorbell models expose the visitor / talkAndReply channels — non-doorbell cameras ignore those without erroring.",
|
|
198227
|
+
descriptionKey: "provider-reolink:schema.s_audio.description",
|
|
196621
198228
|
columns: 2,
|
|
196622
198229
|
fields: [
|
|
196623
198230
|
{
|
|
196624
198231
|
type: "slider",
|
|
196625
198232
|
key: "audioVolume",
|
|
196626
198233
|
label: "Speaker volume",
|
|
198234
|
+
labelKey: "provider-reolink:schema.s_audio.audioVolume.label",
|
|
196627
198235
|
min: 0,
|
|
196628
198236
|
max: 100,
|
|
196629
198237
|
step: 5,
|
|
@@ -196635,7 +198243,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196635
198243
|
type: "slider",
|
|
196636
198244
|
key: "audioTalkAndReplyVolume",
|
|
196637
198245
|
label: "Talk + reply volume",
|
|
198246
|
+
labelKey: "provider-reolink:schema.s_audio.audioTalkAndReplyVolume.label",
|
|
196638
198247
|
description: "Two-way audio + canned reply playback. Doorbell-only on most firmwares.",
|
|
198248
|
+
descriptionKey: "provider-reolink:schema.s_audio.audioTalkAndReplyVolume.description",
|
|
196639
198249
|
min: 0,
|
|
196640
198250
|
max: 100,
|
|
196641
198251
|
step: 5,
|
|
@@ -196647,7 +198257,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196647
198257
|
type: "slider",
|
|
196648
198258
|
key: "audioVisitorVolume",
|
|
196649
198259
|
label: "Visitor volume",
|
|
198260
|
+
labelKey: "provider-reolink:schema.s_audio.audioVisitorVolume.label",
|
|
196650
198261
|
description: "Visitor / chime playback channel. Doorbell-only on most firmwares.",
|
|
198262
|
+
descriptionKey: "provider-reolink:schema.s_audio.audioVisitorVolume.description",
|
|
196651
198263
|
min: 0,
|
|
196652
198264
|
max: 100,
|
|
196653
198265
|
step: 5,
|
|
@@ -196662,13 +198274,17 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196662
198274
|
id: "audio-noise",
|
|
196663
198275
|
tab: "audio",
|
|
196664
198276
|
title: "Audio noise reduction",
|
|
198277
|
+
titleKey: "provider-reolink:schema.s_audio-noise.title",
|
|
196665
198278
|
description: "On-camera AI denoise applied to the encoded audio track. Pushed via `SetAudioNoise` (cmd_id 440). 0 disables; 1..3 maps to the Reolink mobile app levels (low / mid / high).",
|
|
198279
|
+
descriptionKey: "provider-reolink:schema.s_audio-noise.description",
|
|
196666
198280
|
columns: 1,
|
|
196667
198281
|
fields: [{
|
|
196668
198282
|
type: "slider",
|
|
196669
198283
|
key: "audioNoiseLevel",
|
|
196670
198284
|
label: "Noise reduction level",
|
|
198285
|
+
labelKey: "provider-reolink:schema.s_audio-noise.audioNoiseLevel.label",
|
|
196671
198286
|
description: "0 = off · 1 = low · 2 = medium · 3 = high.",
|
|
198287
|
+
descriptionKey: "provider-reolink:schema.s_audio-noise.audioNoiseLevel.description",
|
|
196672
198288
|
min: 0,
|
|
196673
198289
|
max: 3,
|
|
196674
198290
|
step: 1,
|
|
@@ -196681,14 +198297,18 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196681
198297
|
id: "intercom",
|
|
196682
198298
|
tab: "audio",
|
|
196683
198299
|
title: "Intercom",
|
|
198300
|
+
titleKey: "provider-reolink:schema.s_intercom.title",
|
|
196684
198301
|
description: "Push-to-talk pipeline tuning. Settings take effect on the next talk session — restart any active session for changes to apply.",
|
|
198302
|
+
descriptionKey: "provider-reolink:schema.s_intercom.description",
|
|
196685
198303
|
columns: 2,
|
|
196686
198304
|
fields: [
|
|
196687
198305
|
{
|
|
196688
198306
|
type: "slider",
|
|
196689
198307
|
key: "intercomBlocksPerPayload",
|
|
196690
198308
|
label: "Blocks per payload",
|
|
198309
|
+
labelKey: "provider-reolink:schema.s_intercom.intercomBlocksPerPayload.label",
|
|
196691
198310
|
description: "Lower = lower latency (more sendAudio calls/sec). Higher = fewer calls, less per-call socket overhead. Range 1..8. Default 1 (lowest latency).",
|
|
198311
|
+
descriptionKey: "provider-reolink:schema.s_intercom.intercomBlocksPerPayload.description",
|
|
196692
198312
|
min: 1,
|
|
196693
198313
|
max: 8,
|
|
196694
198314
|
step: 1,
|
|
@@ -196700,7 +198320,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196700
198320
|
type: "slider",
|
|
196701
198321
|
key: "intercomMaxBacklogMs",
|
|
196702
198322
|
label: "Max backlog (ms)",
|
|
198323
|
+
labelKey: "provider-reolink:schema.s_intercom.intercomMaxBacklogMs.label",
|
|
196703
198324
|
description: "Maximum PCM backlog before dropping oldest samples to cap latency. Higher = more stable on slow systems but more latency. Range 20..5000. Default 120.",
|
|
198325
|
+
descriptionKey: "provider-reolink:schema.s_intercom.intercomMaxBacklogMs.description",
|
|
196704
198326
|
min: 20,
|
|
196705
198327
|
max: 5e3,
|
|
196706
198328
|
step: 20,
|
|
@@ -196712,7 +198334,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196712
198334
|
type: "slider",
|
|
196713
198335
|
key: "intercomGain",
|
|
196714
198336
|
label: "Output gain",
|
|
198337
|
+
labelKey: "provider-reolink:schema.s_intercom.intercomGain.label",
|
|
196715
198338
|
description: "Multiplier applied to PCM samples before IMA-ADPCM encode. 1.0 = neutral, 2.0 ≈ +6dB, 0.5 ≈ -6dB. Hard-clipped at int16 bounds.",
|
|
198339
|
+
descriptionKey: "provider-reolink:schema.s_intercom.intercomGain.description",
|
|
196716
198340
|
min: .1,
|
|
196717
198341
|
max: 10,
|
|
196718
198342
|
step: .1,
|
|
@@ -196727,12 +198351,15 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196727
198351
|
id: "keyframe-gop",
|
|
196728
198352
|
tab: "advanced",
|
|
196729
198353
|
title: "Keyframe interval (GOP)",
|
|
198354
|
+
titleKey: "provider-reolink:schema.s_keyframe-gop.title",
|
|
196730
198355
|
description: "Main-stream keyframe interval in seconds. Pushed via `SetEnc` (cmd_id 57) as `<gop><cur>`. Lower = more keyframes (faster seek/recovery, higher bitrate); higher = fewer keyframes (lower bitrate). The camera clamps to its supported range.",
|
|
198356
|
+
descriptionKey: "provider-reolink:schema.s_keyframe-gop.description",
|
|
196731
198357
|
columns: 1,
|
|
196732
198358
|
fields: [{
|
|
196733
198359
|
type: "slider",
|
|
196734
198360
|
key: "gop",
|
|
196735
198361
|
label: "Keyframe interval (s)",
|
|
198362
|
+
labelKey: "provider-reolink:schema.s_keyframe-gop.gop.label",
|
|
196736
198363
|
min: 1,
|
|
196737
198364
|
max: 10,
|
|
196738
198365
|
step: 1,
|
|
@@ -196745,12 +198372,15 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196745
198372
|
id: "pir-reduce-alarm",
|
|
196746
198373
|
tab: "advanced",
|
|
196747
198374
|
title: "PIR detection",
|
|
198375
|
+
titleKey: "provider-reolink:schema.s_pir-reduce-alarm.title",
|
|
196748
198376
|
description: "Passive-infrared false-alarm filter. Pushed via `SetPirInfo` (cmd_id 213) as `reduceAlarm`. Enabling makes the camera require a stronger/longer PIR signal before triggering, cutting false motion alerts from heat/light flicker.",
|
|
198377
|
+
descriptionKey: "provider-reolink:schema.s_pir-reduce-alarm.description",
|
|
196749
198378
|
columns: 1,
|
|
196750
198379
|
fields: [{
|
|
196751
198380
|
type: "boolean",
|
|
196752
198381
|
key: "pirReduceFalseAlarm",
|
|
196753
198382
|
label: "Reduce false alarms",
|
|
198383
|
+
labelKey: "provider-reolink:schema.s_pir-reduce-alarm.pirReduceFalseAlarm.label",
|
|
196754
198384
|
default: cache.pirSnapshot.reduceFalseAlarm ?? false,
|
|
196755
198385
|
style: "switch"
|
|
196756
198386
|
}]
|
|
@@ -196759,13 +198389,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196759
198389
|
id: "auto-reboot",
|
|
196760
198390
|
tab: "advanced",
|
|
196761
198391
|
title: "Auto reboot",
|
|
198392
|
+
titleKey: "provider-reolink:schema.s_auto-reboot.title",
|
|
196762
198393
|
description: "Scheduled automatic reboot. Pushed via `SetAutoReboot` (cmd_id 100). Useful for long-uptime stability. Choose a day (or every day) + time; the camera reboots once per matching window.",
|
|
198394
|
+
descriptionKey: "provider-reolink:schema.s_auto-reboot.description",
|
|
196763
198395
|
columns: 2,
|
|
196764
198396
|
fields: [
|
|
196765
198397
|
{
|
|
196766
198398
|
type: "boolean",
|
|
196767
198399
|
key: "autoRebootEnabled",
|
|
196768
198400
|
label: "Auto reboot",
|
|
198401
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootEnabled.label",
|
|
196769
198402
|
default: cache.autoRebootSnapshot.enabled ?? false,
|
|
196770
198403
|
style: "switch",
|
|
196771
198404
|
span: 2
|
|
@@ -196774,40 +198407,49 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196774
198407
|
type: "select",
|
|
196775
198408
|
key: "autoRebootWeekDay",
|
|
196776
198409
|
label: "Day",
|
|
198410
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.label",
|
|
196777
198411
|
default: cache.autoRebootSnapshot.weekDay ?? "everyday",
|
|
196778
198412
|
span: 2,
|
|
196779
198413
|
options: [
|
|
196780
198414
|
{
|
|
196781
198415
|
value: "everyday",
|
|
196782
|
-
label: "Every day"
|
|
198416
|
+
label: "Every day",
|
|
198417
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_everyday.label"
|
|
196783
198418
|
},
|
|
196784
198419
|
{
|
|
196785
198420
|
value: "Sunday",
|
|
196786
|
-
label: "Sunday"
|
|
198421
|
+
label: "Sunday",
|
|
198422
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Sunday.label"
|
|
196787
198423
|
},
|
|
196788
198424
|
{
|
|
196789
198425
|
value: "Monday",
|
|
196790
|
-
label: "Monday"
|
|
198426
|
+
label: "Monday",
|
|
198427
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Monday.label"
|
|
196791
198428
|
},
|
|
196792
198429
|
{
|
|
196793
198430
|
value: "Tuesday",
|
|
196794
|
-
label: "Tuesday"
|
|
198431
|
+
label: "Tuesday",
|
|
198432
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Tuesday.label"
|
|
196795
198433
|
},
|
|
196796
198434
|
{
|
|
196797
198435
|
value: "Wednesday",
|
|
196798
|
-
label: "Wednesday"
|
|
198436
|
+
label: "Wednesday",
|
|
198437
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Wednesday.label"
|
|
196799
198438
|
},
|
|
196800
198439
|
{
|
|
196801
198440
|
value: "Thursday",
|
|
196802
|
-
label: "Thursday"
|
|
198441
|
+
label: "Thursday",
|
|
198442
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Thursday.label"
|
|
196803
198443
|
},
|
|
196804
198444
|
{
|
|
196805
198445
|
value: "Friday",
|
|
196806
|
-
label: "Friday"
|
|
198446
|
+
label: "Friday",
|
|
198447
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Friday.label"
|
|
196807
198448
|
},
|
|
196808
198449
|
{
|
|
196809
198450
|
value: "Saturday",
|
|
196810
|
-
label: "Saturday"
|
|
198451
|
+
label: "Saturday",
|
|
198452
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Saturday.label"
|
|
196811
198453
|
}
|
|
196812
198454
|
]
|
|
196813
198455
|
},
|
|
@@ -196815,6 +198457,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196815
198457
|
type: "number",
|
|
196816
198458
|
key: "autoRebootHour",
|
|
196817
198459
|
label: "Hour (0-23)",
|
|
198460
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootHour.label",
|
|
196818
198461
|
default: cache.autoRebootSnapshot.hour ?? 3,
|
|
196819
198462
|
min: 0,
|
|
196820
198463
|
max: 23,
|
|
@@ -196824,6 +198467,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196824
198467
|
type: "number",
|
|
196825
198468
|
key: "autoRebootMinute",
|
|
196826
198469
|
label: "Minute (0-59)",
|
|
198470
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootMinute.label",
|
|
196827
198471
|
default: cache.autoRebootSnapshot.minute ?? 0,
|
|
196828
198472
|
min: 0,
|
|
196829
198473
|
max: 59,
|
|
@@ -196835,41 +198479,52 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196835
198479
|
id: "debug",
|
|
196836
198480
|
tab: "advanced",
|
|
196837
198481
|
title: "Debug",
|
|
198482
|
+
titleKey: "provider-reolink:schema.s_debug.title",
|
|
196838
198483
|
description: "Lib-side Baichuan tracing. Changing these resets the control-channel client (active streams keep running) so new debug options take effect on the next dial.",
|
|
198484
|
+
descriptionKey: "provider-reolink:schema.s_debug.description",
|
|
196839
198485
|
columns: 1,
|
|
196840
198486
|
fields: [{
|
|
196841
198487
|
type: "boolean",
|
|
196842
198488
|
key: "debugGeneral",
|
|
196843
198489
|
label: "General debug logs",
|
|
198490
|
+
labelKey: "provider-reolink:schema.s_debug.debugGeneral.label",
|
|
196844
198491
|
description: "Forwards `DebugOptions.general=true` — verbose lib protocol logs.",
|
|
198492
|
+
descriptionKey: "provider-reolink:schema.s_debug.debugGeneral.description",
|
|
196845
198493
|
default: false,
|
|
196846
198494
|
style: "switch"
|
|
196847
198495
|
}, {
|
|
196848
198496
|
type: "multiselect",
|
|
196849
198497
|
key: "debugSocketLogs",
|
|
196850
198498
|
label: "Socket trace categories",
|
|
198499
|
+
labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.label",
|
|
196851
198500
|
description: "Per-area lib tracing. Pick only what you need; each adds log volume.",
|
|
198501
|
+
descriptionKey: "provider-reolink:schema.s_debug.debugSocketLogs.description",
|
|
196852
198502
|
default: [],
|
|
196853
198503
|
options: [
|
|
196854
198504
|
{
|
|
196855
198505
|
value: "debugRtsp",
|
|
196856
|
-
label: "RTSP (proxy/server traffic)"
|
|
198506
|
+
label: "RTSP (proxy/server traffic)",
|
|
198507
|
+
labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.o_debugRtsp.label"
|
|
196857
198508
|
},
|
|
196858
198509
|
{
|
|
196859
198510
|
value: "traceNativeStream",
|
|
196860
|
-
label: "Native stream (cmd 3/4 + H.264/H.265 + param sets)"
|
|
198511
|
+
label: "Native stream (cmd 3/4 + H.264/H.265 + param sets)",
|
|
198512
|
+
labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.o_traceNativeStream.label"
|
|
196861
198513
|
},
|
|
196862
198514
|
{
|
|
196863
198515
|
value: "traceRecordings",
|
|
196864
|
-
label: "Recordings (FileInfoList, findAlarmVideo, download)"
|
|
198516
|
+
label: "Recordings (FileInfoList, findAlarmVideo, download)",
|
|
198517
|
+
labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.o_traceRecordings.label"
|
|
196865
198518
|
},
|
|
196866
198519
|
{
|
|
196867
198520
|
value: "traceTalk",
|
|
196868
|
-
label: "Talkback (cmd 10/11/201/202)"
|
|
198521
|
+
label: "Talkback (cmd 10/11/201/202)",
|
|
198522
|
+
labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.o_traceTalk.label"
|
|
196869
198523
|
},
|
|
196870
198524
|
{
|
|
196871
198525
|
value: "traceEvents",
|
|
196872
|
-
label: "Events (cmd 33 — AlarmEventList push)"
|
|
198526
|
+
label: "Events (cmd 33 — AlarmEventList push)",
|
|
198527
|
+
labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.o_traceEvents.label"
|
|
196873
198528
|
}
|
|
196874
198529
|
]
|
|
196875
198530
|
}]
|
|
@@ -198344,13 +199999,16 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
198344
199999
|
id: "connection",
|
|
198345
200000
|
tab: "general",
|
|
198346
200001
|
title: "Connection",
|
|
200002
|
+
titleKey: "provider-reolink:hub.s_connection.title",
|
|
198347
200003
|
description: "Baichuan protocol connection settings for the hub. The same socket fronts every adopted channel — child cameras inherit these credentials, no per-channel login needed.",
|
|
200004
|
+
descriptionKey: "provider-reolink:hub.s_connection.description",
|
|
198348
200005
|
columns: 2,
|
|
198349
200006
|
fields: [
|
|
198350
200007
|
{
|
|
198351
200008
|
type: "text",
|
|
198352
200009
|
key: "host",
|
|
198353
200010
|
label: "Hub IP",
|
|
200011
|
+
labelKey: "provider-reolink:hub.s_connection.host.label",
|
|
198354
200012
|
required: true,
|
|
198355
200013
|
placeholder: "192.168.10.100"
|
|
198356
200014
|
},
|
|
@@ -198358,6 +200016,7 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
198358
200016
|
type: "number",
|
|
198359
200017
|
key: "port",
|
|
198360
200018
|
label: "Port",
|
|
200019
|
+
labelKey: "provider-reolink:hub.s_connection.port.label",
|
|
198361
200020
|
default: 9e3,
|
|
198362
200021
|
min: 1,
|
|
198363
200022
|
max: 65535,
|
|
@@ -198367,12 +200026,14 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
198367
200026
|
type: "text",
|
|
198368
200027
|
key: "username",
|
|
198369
200028
|
label: "Username",
|
|
200029
|
+
labelKey: "provider-reolink:hub.s_connection.username.label",
|
|
198370
200030
|
default: "admin"
|
|
198371
200031
|
},
|
|
198372
200032
|
{
|
|
198373
200033
|
type: "password",
|
|
198374
200034
|
key: "password",
|
|
198375
200035
|
label: "Password",
|
|
200036
|
+
labelKey: "provider-reolink:hub.s_connection.password.label",
|
|
198376
200037
|
required: true,
|
|
198377
200038
|
showToggle: true
|
|
198378
200039
|
}
|
|
@@ -198382,18 +200043,22 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
198382
200043
|
id: "identity",
|
|
198383
200044
|
tab: "general",
|
|
198384
200045
|
title: "Hub identity",
|
|
200046
|
+
titleKey: "provider-reolink:hub.s_identity.title",
|
|
198385
200047
|
description: "Read-only summary from the autodetect probe. Channel count and model are persisted at first contact so the panel renders without re-probing.",
|
|
200048
|
+
descriptionKey: "provider-reolink:hub.s_identity.description",
|
|
198386
200049
|
columns: 2,
|
|
198387
200050
|
fields: [{
|
|
198388
200051
|
type: "text",
|
|
198389
200052
|
key: "_model",
|
|
198390
200053
|
label: "Model",
|
|
200054
|
+
labelKey: "provider-reolink:hub.s_identity._model.label",
|
|
198391
200055
|
default: cache?.model ?? "unknown",
|
|
198392
200056
|
disabled: true
|
|
198393
200057
|
}, {
|
|
198394
200058
|
type: "text",
|
|
198395
200059
|
key: "_channelCount",
|
|
198396
200060
|
label: "Total channels",
|
|
200061
|
+
labelKey: "provider-reolink:hub.s_identity._channelCount.label",
|
|
198397
200062
|
default: String(cache?.channelCount ?? 0),
|
|
198398
200063
|
disabled: true
|
|
198399
200064
|
}]
|
|
@@ -198402,41 +200067,52 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
198402
200067
|
id: "debug",
|
|
198403
200068
|
tab: "advanced",
|
|
198404
200069
|
title: "Debug",
|
|
200070
|
+
titleKey: "provider-reolink:hub.s_debug.title",
|
|
198405
200071
|
description: "Lib-side Baichuan tracing. Changing these resets the control-channel client (active streams keep running) so new debug options take effect on the next dial.",
|
|
200072
|
+
descriptionKey: "provider-reolink:hub.s_debug.description",
|
|
198406
200073
|
columns: 1,
|
|
198407
200074
|
fields: [{
|
|
198408
200075
|
type: "boolean",
|
|
198409
200076
|
key: "debugGeneral",
|
|
198410
200077
|
label: "General debug logs",
|
|
200078
|
+
labelKey: "provider-reolink:hub.s_debug.debugGeneral.label",
|
|
198411
200079
|
description: "Forwards `DebugOptions.general=true` — verbose lib protocol logs.",
|
|
200080
|
+
descriptionKey: "provider-reolink:hub.s_debug.debugGeneral.description",
|
|
198412
200081
|
default: false,
|
|
198413
200082
|
style: "switch"
|
|
198414
200083
|
}, {
|
|
198415
200084
|
type: "multiselect",
|
|
198416
200085
|
key: "debugSocketLogs",
|
|
198417
200086
|
label: "Socket trace categories",
|
|
200087
|
+
labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.label",
|
|
198418
200088
|
description: "Per-area lib tracing. Pick only what you need; each adds log volume.",
|
|
200089
|
+
descriptionKey: "provider-reolink:hub.s_debug.debugSocketLogs.description",
|
|
198419
200090
|
default: [],
|
|
198420
200091
|
options: [
|
|
198421
200092
|
{
|
|
198422
200093
|
value: "debugRtsp",
|
|
198423
|
-
label: "RTSP (proxy/server traffic)"
|
|
200094
|
+
label: "RTSP (proxy/server traffic)",
|
|
200095
|
+
labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.o_debugRtsp.label"
|
|
198424
200096
|
},
|
|
198425
200097
|
{
|
|
198426
200098
|
value: "traceNativeStream",
|
|
198427
|
-
label: "Native stream (cmd 3/4 + H.264/H.265 + param sets)"
|
|
200099
|
+
label: "Native stream (cmd 3/4 + H.264/H.265 + param sets)",
|
|
200100
|
+
labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.o_traceNativeStream.label"
|
|
198428
200101
|
},
|
|
198429
200102
|
{
|
|
198430
200103
|
value: "traceRecordings",
|
|
198431
|
-
label: "Recordings (FileInfoList, findAlarmVideo, download)"
|
|
200104
|
+
label: "Recordings (FileInfoList, findAlarmVideo, download)",
|
|
200105
|
+
labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.o_traceRecordings.label"
|
|
198432
200106
|
},
|
|
198433
200107
|
{
|
|
198434
200108
|
value: "traceTalk",
|
|
198435
|
-
label: "Talkback (cmd 10/11/201/202)"
|
|
200109
|
+
label: "Talkback (cmd 10/11/201/202)",
|
|
200110
|
+
labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.o_traceTalk.label"
|
|
198436
200111
|
},
|
|
198437
200112
|
{
|
|
198438
200113
|
value: "traceEvents",
|
|
198439
|
-
label: "Events (cmd 33 — AlarmEventList push)"
|
|
200114
|
+
label: "Events (cmd 33 — AlarmEventList push)",
|
|
200115
|
+
labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.o_traceEvents.label"
|
|
198440
200116
|
}
|
|
198441
200117
|
]
|
|
198442
200118
|
}]
|
|
@@ -199018,8 +200694,8 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
199018
200694
|
this.api = null;
|
|
199019
200695
|
}
|
|
199020
200696
|
const cfg = this.config.values;
|
|
199021
|
-
if (!cfg.host) throw
|
|
199022
|
-
if (!cfg.password) throw
|
|
200697
|
+
if (!cfg.host) throw userError("reolink.hub-host-missing", void 0, "Reolink Hub: host not configured");
|
|
200698
|
+
if (!cfg.password) throw userError("reolink.hub-password-missing", void 0, "Reolink Hub: password not configured");
|
|
199023
200699
|
const api = new ReolinkBaichuanApi({
|
|
199024
200700
|
host: cfg.host,
|
|
199025
200701
|
port: cfg.port,
|
|
@@ -199171,31 +200847,38 @@ function buildDiscoveryParamsFormSchema() {
|
|
|
199171
200847
|
return { sections: [{
|
|
199172
200848
|
id: "credentials",
|
|
199173
200849
|
title: "Credentials",
|
|
200850
|
+
titleKey: "provider-reolink:discoveryParams.s_credentials.title",
|
|
199174
200851
|
description: "Used to probe the cameras and pre-filled into each result so you can add it in one click. Assumes all cameras share these credentials.",
|
|
200852
|
+
descriptionKey: "provider-reolink:discoveryParams.s_credentials.description",
|
|
199175
200853
|
columns: 2,
|
|
199176
200854
|
fields: [{
|
|
199177
200855
|
type: "text",
|
|
199178
200856
|
key: "username",
|
|
199179
200857
|
label: "Username",
|
|
200858
|
+
labelKey: "provider-reolink:discoveryParams.s_credentials.username.label",
|
|
199180
200859
|
default: "admin",
|
|
199181
200860
|
required: true
|
|
199182
200861
|
}, {
|
|
199183
200862
|
type: "password",
|
|
199184
200863
|
key: "password",
|
|
199185
200864
|
label: "Password",
|
|
200865
|
+
labelKey: "provider-reolink:discoveryParams.s_credentials.password.label",
|
|
199186
200866
|
required: true,
|
|
199187
200867
|
showToggle: true
|
|
199188
200868
|
}]
|
|
199189
200869
|
}, {
|
|
199190
200870
|
id: "scan",
|
|
199191
200871
|
title: "Scan options",
|
|
200872
|
+
titleKey: "provider-reolink:discoveryParams.s_scan.title",
|
|
199192
200873
|
description: "Leave the network blank to scan the local subnet. To find cameras on a different subnet, enter its CIDR (e.g. 192.168.20.0/24).",
|
|
200874
|
+
descriptionKey: "provider-reolink:discoveryParams.s_scan.description",
|
|
199193
200875
|
columns: 1,
|
|
199194
200876
|
fields: [
|
|
199195
200877
|
{
|
|
199196
200878
|
type: "text",
|
|
199197
200879
|
key: "networkCidr",
|
|
199198
200880
|
label: "Network (CIDR)",
|
|
200881
|
+
labelKey: "provider-reolink:discoveryParams.s_scan.networkCidr.label",
|
|
199199
200882
|
required: false,
|
|
199200
200883
|
placeholder: "192.168.20.0/24"
|
|
199201
200884
|
},
|
|
@@ -199203,12 +200886,14 @@ function buildDiscoveryParamsFormSchema() {
|
|
|
199203
200886
|
type: "boolean",
|
|
199204
200887
|
key: "enableOnvif",
|
|
199205
200888
|
label: "Include ONVIF discovery",
|
|
200889
|
+
labelKey: "provider-reolink:discoveryParams.s_scan.enableOnvif.label",
|
|
199206
200890
|
default: true
|
|
199207
200891
|
},
|
|
199208
200892
|
{
|
|
199209
200893
|
type: "number",
|
|
199210
200894
|
key: "timeoutMs",
|
|
199211
200895
|
label: "Scan timeout (ms)",
|
|
200896
|
+
labelKey: "provider-reolink:discoveryParams.s_scan.timeoutMs.label",
|
|
199212
200897
|
min: 1e3,
|
|
199213
200898
|
max: 3e4,
|
|
199214
200899
|
default: 5e3
|
|
@@ -199221,11 +200906,13 @@ function buildCreationFormSchema() {
|
|
|
199221
200906
|
{
|
|
199222
200907
|
id: "identity",
|
|
199223
200908
|
title: "Camera",
|
|
200909
|
+
titleKey: "provider-reolink:creation.s_identity.title",
|
|
199224
200910
|
columns: 1,
|
|
199225
200911
|
fields: [{
|
|
199226
200912
|
type: "text",
|
|
199227
200913
|
key: "name",
|
|
199228
200914
|
label: "Name",
|
|
200915
|
+
labelKey: "provider-reolink:creation.s_identity.name.label",
|
|
199229
200916
|
required: true,
|
|
199230
200917
|
placeholder: "Front Door"
|
|
199231
200918
|
}]
|
|
@@ -199233,18 +200920,22 @@ function buildCreationFormSchema() {
|
|
|
199233
200920
|
{
|
|
199234
200921
|
id: "credentials",
|
|
199235
200922
|
title: "Credentials",
|
|
200923
|
+
titleKey: "provider-reolink:creation.s_credentials.title",
|
|
199236
200924
|
description: "Required for the autodetect probe — entered before the host so Test can run immediately.",
|
|
200925
|
+
descriptionKey: "provider-reolink:creation.s_credentials.description",
|
|
199237
200926
|
columns: 2,
|
|
199238
200927
|
fields: [{
|
|
199239
200928
|
type: "text",
|
|
199240
200929
|
key: "username",
|
|
199241
200930
|
label: "Username",
|
|
200931
|
+
labelKey: "provider-reolink:creation.s_credentials.username.label",
|
|
199242
200932
|
default: "admin",
|
|
199243
200933
|
required: true
|
|
199244
200934
|
}, {
|
|
199245
200935
|
type: "password",
|
|
199246
200936
|
key: "password",
|
|
199247
200937
|
label: "Password",
|
|
200938
|
+
labelKey: "provider-reolink:creation.s_credentials.password.label",
|
|
199248
200939
|
required: true,
|
|
199249
200940
|
showToggle: true
|
|
199250
200941
|
}]
|
|
@@ -199252,27 +200943,34 @@ function buildCreationFormSchema() {
|
|
|
199252
200943
|
{
|
|
199253
200944
|
id: "connection",
|
|
199254
200945
|
title: "Connection",
|
|
200946
|
+
titleKey: "provider-reolink:creation.s_connection.title",
|
|
199255
200947
|
description: "Click Test to auto-detect the device type (regular camera / NVR / battery / UDP-only). The detected type is then used at save time.",
|
|
200948
|
+
descriptionKey: "provider-reolink:creation.s_connection.description",
|
|
199256
200949
|
columns: 2,
|
|
199257
200950
|
fields: [
|
|
199258
200951
|
{
|
|
199259
200952
|
type: "select",
|
|
199260
200953
|
key: "transport",
|
|
199261
200954
|
label: "Connection mode",
|
|
200955
|
+
labelKey: "provider-reolink:creation.s_connection.transport.label",
|
|
199262
200956
|
default: "auto",
|
|
199263
200957
|
description: "Auto: try TCP first, fall back to UDP — best for unknown devices. UDP is required for battery cameras behind NAT.",
|
|
200958
|
+
descriptionKey: "provider-reolink:creation.s_connection.transport.description",
|
|
199264
200959
|
options: [
|
|
199265
200960
|
{
|
|
199266
200961
|
value: "auto",
|
|
199267
|
-
label: "Auto (recommended)"
|
|
200962
|
+
label: "Auto (recommended)",
|
|
200963
|
+
labelKey: "provider-reolink:creation.s_connection.transport.o_auto.label"
|
|
199268
200964
|
},
|
|
199269
200965
|
{
|
|
199270
200966
|
value: "tcp",
|
|
199271
|
-
label: "TCP only"
|
|
200967
|
+
label: "TCP only",
|
|
200968
|
+
labelKey: "provider-reolink:creation.s_connection.transport.o_tcp.label"
|
|
199272
200969
|
},
|
|
199273
200970
|
{
|
|
199274
200971
|
value: "udp",
|
|
199275
|
-
label: "UDP only (battery / cloud)"
|
|
200972
|
+
label: "UDP only (battery / cloud)",
|
|
200973
|
+
labelKey: "provider-reolink:creation.s_connection.transport.o_udp.label"
|
|
199276
200974
|
}
|
|
199277
200975
|
]
|
|
199278
200976
|
},
|
|
@@ -199280,20 +200978,24 @@ function buildCreationFormSchema() {
|
|
|
199280
200978
|
type: "probe",
|
|
199281
200979
|
key: "host",
|
|
199282
200980
|
label: "Host (IP / hostname / UID)",
|
|
200981
|
+
labelKey: "provider-reolink:creation.s_connection.host.label",
|
|
199283
200982
|
required: true,
|
|
199284
200983
|
placeholder: "192.168.10.100",
|
|
199285
200984
|
description: "For UDP-only mode you can leave the host blank and supply the camera UID below — the library will discover it on the network.",
|
|
200985
|
+
descriptionKey: "provider-reolink:creation.s_connection.host.description",
|
|
199286
200986
|
inputType: "text"
|
|
199287
200987
|
},
|
|
199288
200988
|
{
|
|
199289
200989
|
type: "number",
|
|
199290
200990
|
key: "port",
|
|
199291
200991
|
label: "Port",
|
|
200992
|
+
labelKey: "provider-reolink:creation.s_connection.port.label",
|
|
199292
200993
|
default: 9e3,
|
|
199293
200994
|
min: 1,
|
|
199294
200995
|
max: 65535,
|
|
199295
200996
|
step: 1,
|
|
199296
200997
|
description: "Baichuan port. Default 9000 — applies to TCP. Ignored for UDP transport.",
|
|
200998
|
+
descriptionKey: "provider-reolink:creation.s_connection.port.description",
|
|
199297
200999
|
showWhen: {
|
|
199298
201000
|
field: "transport",
|
|
199299
201001
|
notEquals: "udp"
|
|
@@ -199303,8 +201005,10 @@ function buildCreationFormSchema() {
|
|
|
199303
201005
|
type: "text",
|
|
199304
201006
|
key: "uid",
|
|
199305
201007
|
label: "Device UID",
|
|
201008
|
+
labelKey: "provider-reolink:creation.s_connection.uid.label",
|
|
199306
201009
|
placeholder: "9527000XXXXXXXX",
|
|
199307
201010
|
description: "Required for battery / UDP cameras when not on the same LAN. Optional for local-direct UDP discovery and ignored for pure TCP.",
|
|
201011
|
+
descriptionKey: "provider-reolink:creation.s_connection.uid.description",
|
|
199308
201012
|
showWhen: {
|
|
199309
201013
|
field: "transport",
|
|
199310
201014
|
notEquals: "tcp"
|
|
@@ -199843,25 +201547,30 @@ function buildEmailPushSettingsSchema(recommendedHost) {
|
|
|
199843
201547
|
return { sections: [{
|
|
199844
201548
|
id: "email-push",
|
|
199845
201549
|
title: "Battery-cam Motion (Email/SMTP Push)",
|
|
201550
|
+
titleKey: "provider-reolink:emailPushSettings.s_email-push.title",
|
|
199846
201551
|
description: "Emulate an SMTP server that battery Reolink cameras push to on motion. Lets you capture motion from sleeping battery cams without polling them awake. Enable, then use \"Auto-configure email push\" on each battery camera.",
|
|
201552
|
+
descriptionKey: "provider-reolink:emailPushSettings.s_email-push.description",
|
|
199847
201553
|
columns: 2,
|
|
199848
201554
|
fields: [
|
|
199849
201555
|
{
|
|
199850
201556
|
type: "boolean",
|
|
199851
201557
|
key: "emailPushEnabled",
|
|
199852
201558
|
label: "Enable Email Push Server",
|
|
201559
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push.emailPushEnabled.label",
|
|
199853
201560
|
default: true
|
|
199854
201561
|
},
|
|
199855
201562
|
{
|
|
199856
201563
|
type: "info",
|
|
199857
201564
|
key: "emailPushRecommendedHost",
|
|
199858
201565
|
label: "Camera-facing host",
|
|
201566
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push.emailPushRecommendedHost.label",
|
|
199859
201567
|
content: `Point cameras at this host: ${recommendedHost}`
|
|
199860
201568
|
},
|
|
199861
201569
|
{
|
|
199862
201570
|
type: "number",
|
|
199863
201571
|
key: "emailPushPort",
|
|
199864
201572
|
label: "SMTP Port",
|
|
201573
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push.emailPushPort.label",
|
|
199865
201574
|
default: DEFAULT_EMAIL_PUSH_PORT,
|
|
199866
201575
|
min: 1,
|
|
199867
201576
|
max: 65535
|
|
@@ -199870,6 +201579,7 @@ function buildEmailPushSettingsSchema(recommendedHost) {
|
|
|
199870
201579
|
type: "text",
|
|
199871
201580
|
key: "emailPushDomain",
|
|
199872
201581
|
label: "Virtual Domain",
|
|
201582
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push.emailPushDomain.label",
|
|
199873
201583
|
default: DEFAULT_EMAIL_PUSH_DOMAIN,
|
|
199874
201584
|
placeholder: DEFAULT_EMAIL_PUSH_DOMAIN
|
|
199875
201585
|
}
|
|
@@ -199877,24 +201587,29 @@ function buildEmailPushSettingsSchema(recommendedHost) {
|
|
|
199877
201587
|
}, {
|
|
199878
201588
|
id: "email-push-auth",
|
|
199879
201589
|
title: "Email Push Authentication",
|
|
201590
|
+
titleKey: "provider-reolink:emailPushSettings.s_email-push-auth.title",
|
|
199880
201591
|
description: "AUTH credentials the camera must present. Reolink firmwares are more reliable with AUTH on. Random values are generated on first boot — re-run Auto-configure on cameras after changing them.",
|
|
201592
|
+
descriptionKey: "provider-reolink:emailPushSettings.s_email-push-auth.description",
|
|
199881
201593
|
columns: 2,
|
|
199882
201594
|
fields: [
|
|
199883
201595
|
{
|
|
199884
201596
|
type: "boolean",
|
|
199885
201597
|
key: "emailPushRequireAuth",
|
|
199886
201598
|
label: "Require AUTH",
|
|
201599
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push-auth.emailPushRequireAuth.label",
|
|
199887
201600
|
default: true
|
|
199888
201601
|
},
|
|
199889
201602
|
{
|
|
199890
201603
|
type: "text",
|
|
199891
201604
|
key: "emailPushAuthUsername",
|
|
199892
|
-
label: "Auth Username"
|
|
201605
|
+
label: "Auth Username",
|
|
201606
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push-auth.emailPushAuthUsername.label"
|
|
199893
201607
|
},
|
|
199894
201608
|
{
|
|
199895
201609
|
type: "password",
|
|
199896
201610
|
key: "emailPushAuthPassword",
|
|
199897
201611
|
label: "Auth Password",
|
|
201612
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push-auth.emailPushAuthPassword.label",
|
|
199898
201613
|
showToggle: true
|
|
199899
201614
|
}
|
|
199900
201615
|
]
|
|
@@ -200081,25 +201796,30 @@ function buildBaichuanWebhookSettingsSchema(recommendedHost) {
|
|
|
200081
201796
|
return { sections: [{
|
|
200082
201797
|
id: "baichuan-webhook",
|
|
200083
201798
|
title: "Battery-cam Motion (HaCfg Webhook)",
|
|
201799
|
+
titleKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.title",
|
|
200084
201800
|
description: "HTTP intake for Baichuan HaCfg wake/sleep push (cmd 806/807). Prefer this over SMTP when the camera firmware supports it — lower latency, no AUTH dance. Enable, then use \"Auto-configure HaCfg webhook\" on each battery camera (or set preference to Auto).",
|
|
201801
|
+
descriptionKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.description",
|
|
200085
201802
|
columns: 2,
|
|
200086
201803
|
fields: [
|
|
200087
201804
|
{
|
|
200088
201805
|
type: "boolean",
|
|
200089
201806
|
key: "baichuanWebhookEnabled",
|
|
200090
201807
|
label: "Enable HaCfg Webhook Server",
|
|
201808
|
+
labelKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.baichuanWebhookEnabled.label",
|
|
200091
201809
|
default: true
|
|
200092
201810
|
},
|
|
200093
201811
|
{
|
|
200094
201812
|
type: "info",
|
|
200095
201813
|
key: "baichuanWebhookRecommendedHost",
|
|
200096
201814
|
label: "Camera-facing host",
|
|
201815
|
+
labelKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.baichuanWebhookRecommendedHost.label",
|
|
200097
201816
|
content: `Point cameras at this host: ${recommendedHost}`
|
|
200098
201817
|
},
|
|
200099
201818
|
{
|
|
200100
201819
|
type: "number",
|
|
200101
201820
|
key: "baichuanWebhookPort",
|
|
200102
201821
|
label: "HTTP Port",
|
|
201822
|
+
labelKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.baichuanWebhookPort.label",
|
|
200103
201823
|
default: DEFAULT_BAICHUAN_WEBHOOK_PORT,
|
|
200104
201824
|
min: 1,
|
|
200105
201825
|
max: 65535
|
|
@@ -200108,8 +201828,10 @@ function buildBaichuanWebhookSettingsSchema(recommendedHost) {
|
|
|
200108
201828
|
type: "text",
|
|
200109
201829
|
key: "baichuanWebhookBindHost",
|
|
200110
201830
|
label: "Bind host",
|
|
201831
|
+
labelKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.baichuanWebhookBindHost.label",
|
|
200111
201832
|
default: "0.0.0.0",
|
|
200112
|
-
description: "0.0.0.0 accepts on every interface (cameras on LAN)."
|
|
201833
|
+
description: "0.0.0.0 accepts on every interface (cameras on LAN).",
|
|
201834
|
+
descriptionKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.baichuanWebhookBindHost.description"
|
|
200113
201835
|
}
|
|
200114
201836
|
]
|
|
200115
201837
|
}] };
|
|
@@ -200665,7 +202387,7 @@ var ReolinkProviderAddon = class extends BaseDeviceProvider {
|
|
|
200665
202387
|
},
|
|
200666
202388
|
wake: async (deviceId) => {
|
|
200667
202389
|
const device = this.ctx.kernel.deviceRegistry?.getById(deviceId);
|
|
200668
|
-
if (!(device instanceof ReolinkCamera)) throw
|
|
202390
|
+
if (!(device instanceof ReolinkCamera)) throw userError("reolink.clip-device-not-reolink", { deviceId: String(deviceId) }, `clip refresh: device ${String(deviceId)} is not a Reolink camera here`);
|
|
200669
202391
|
await device.wakeForClipCatalogRefresh();
|
|
200670
202392
|
},
|
|
200671
202393
|
prefetchStills: async (deviceId) => service.prefetchThumbnails(deviceId),
|