@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.mjs
CHANGED
|
@@ -5416,7 +5416,7 @@ var ZodIssueCode = {
|
|
|
5416
5416
|
var ZodFirstPartyTypeKind;
|
|
5417
5417
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5418
5418
|
//#endregion
|
|
5419
|
-
//#region ../types/dist/sleep-
|
|
5419
|
+
//#region ../types/dist/sleep-DRqxtc0C.mjs
|
|
5420
5420
|
/**
|
|
5421
5421
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5422
5422
|
* window to float samples (D455).
|
|
@@ -8289,6 +8289,24 @@ function collectZodSecretPaths(schema, prefix = "") {
|
|
|
8289
8289
|
}
|
|
8290
8290
|
return [...new Set(paths)];
|
|
8291
8291
|
}
|
|
8292
|
+
object({
|
|
8293
|
+
code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
|
|
8294
|
+
params: record(string(), union([string(), number()])).optional()
|
|
8295
|
+
});
|
|
8296
|
+
var CamstackError = class extends Error {
|
|
8297
|
+
i18nCode;
|
|
8298
|
+
i18nParams;
|
|
8299
|
+
constructor(code, params, englishMessage) {
|
|
8300
|
+
super(englishMessage);
|
|
8301
|
+
this.name = "CamstackError";
|
|
8302
|
+
this.i18nCode = code;
|
|
8303
|
+
this.i18nParams = params;
|
|
8304
|
+
}
|
|
8305
|
+
};
|
|
8306
|
+
/** `throw userError('device.not-found', { id }, 'Device 12 not found')` */
|
|
8307
|
+
function userError(code, params, englishFallback) {
|
|
8308
|
+
return new CamstackError(code, params, englishFallback);
|
|
8309
|
+
}
|
|
8292
8310
|
/**
|
|
8293
8311
|
* Promise-based timer helpers — used everywhere the codebase needs to
|
|
8294
8312
|
* wait, back off, or schedule a retry. Before these helpers landed, each
|
|
@@ -8314,7 +8332,7 @@ function sleep$2(ms) {
|
|
|
8314
8332
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
8315
8333
|
}
|
|
8316
8334
|
//#endregion
|
|
8317
|
-
//#region ../types/dist/err-msg-
|
|
8335
|
+
//#region ../types/dist/err-msg-DLerKiVO.mjs
|
|
8318
8336
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
8319
8337
|
DeviceType["Camera"] = "camera";
|
|
8320
8338
|
DeviceType["Hub"] = "hub";
|
|
@@ -8564,6 +8582,22 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
8564
8582
|
DeviceRole["Nightvision"] = "nightvision";
|
|
8565
8583
|
DeviceRole["PrivacyMask"] = "privacy-mask";
|
|
8566
8584
|
DeviceRole["Doorbell"] = "doorbell";
|
|
8585
|
+
/** Interior blind / shade / roller blind. HA `device_class: blind|shade`. */
|
|
8586
|
+
DeviceRole["CoverBlind"] = "cover-blind";
|
|
8587
|
+
/** Exterior roller shutter. HA `device_class: shutter`; Homematic BROLL. */
|
|
8588
|
+
DeviceRole["CoverShutter"] = "cover-shutter";
|
|
8589
|
+
/** Exterior awning. HA `device_class: awning`. */
|
|
8590
|
+
DeviceRole["CoverAwning"] = "cover-awning";
|
|
8591
|
+
/** Curtain / drape. HA `device_class: curtain`. */
|
|
8592
|
+
DeviceRole["CoverCurtain"] = "cover-curtain";
|
|
8593
|
+
/** Garage door. HA `device_class: garage`. A security actuator: exports gate it. */
|
|
8594
|
+
DeviceRole["CoverGarage"] = "cover-garage";
|
|
8595
|
+
/** Gate. HA `device_class: gate`. A security actuator: exports gate it. */
|
|
8596
|
+
DeviceRole["CoverGate"] = "cover-gate";
|
|
8597
|
+
/** Door. HA `device_class: door`. A security actuator: exports gate it. */
|
|
8598
|
+
DeviceRole["CoverDoor"] = "cover-door";
|
|
8599
|
+
/** Window. HA `device_class: window`. */
|
|
8600
|
+
DeviceRole["CoverWindow"] = "cover-window";
|
|
8567
8601
|
/** Virtual HA toggle (input_boolean.*) — distinguishable from a
|
|
8568
8602
|
* real Switch device for UI rendering / export adapters. */
|
|
8569
8603
|
DeviceRole["BinaryHelper"] = "binary-helper";
|
|
@@ -8634,7 +8668,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
8634
8668
|
return DeviceRole;
|
|
8635
8669
|
}({});
|
|
8636
8670
|
//#endregion
|
|
8637
|
-
//#region ../types/dist/composition-
|
|
8671
|
+
//#region ../types/dist/composition-EQ9Ok0Ee.mjs
|
|
8638
8672
|
/**
|
|
8639
8673
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
8640
8674
|
*
|
|
@@ -12862,6 +12896,177 @@ var ConvertResultSchema = object({
|
|
|
12862
12896
|
files: array(string()).readonly()
|
|
12863
12897
|
})).readonly()
|
|
12864
12898
|
});
|
|
12899
|
+
_enum(["new-session", "step-up"]);
|
|
12900
|
+
/** The languages the hub's app landing pages are written in (D858). */
|
|
12901
|
+
var AppPageLangSchema = _enum(["en", "it"]);
|
|
12902
|
+
/** How a native app starts one login method (D858), as `auth.listLoginMethods` reports it. */
|
|
12903
|
+
var AppLoginPathSchema = discriminatedUnion("kind", [object({ kind: literal("native") }), object({
|
|
12904
|
+
kind: literal("browser"),
|
|
12905
|
+
startPath: string().startsWith("/")
|
|
12906
|
+
})]);
|
|
12907
|
+
/**
|
|
12908
|
+
* Device certificates (D855) — the wire contract shared by the hub, the admin
|
|
12909
|
+
* UI and the native viewer.
|
|
12910
|
+
*
|
|
12911
|
+
* A device (a phone) generates its OWN P-256 key pair in hardware (Secure
|
|
12912
|
+
* Enclave / Android Keystore / a non-extractable WebCrypto key). The private
|
|
12913
|
+
* key never travels. The hub signs the PUBLIC key into an X.509 leaf under a
|
|
12914
|
+
* dedicated device CA; the device later proves possession of the key by
|
|
12915
|
+
* signing a hub-issued nonce, and the hub answers with the same session a
|
|
12916
|
+
* password login opens.
|
|
12917
|
+
*
|
|
12918
|
+
* Everything on the wire is a small string (a PEM, a base64url signature):
|
|
12919
|
+
* D613 is about bulk bytes, and a certificate is ~600 bytes.
|
|
12920
|
+
*/
|
|
12921
|
+
/** Signature algorithm of every device credential: ECDSA, curve P-256, SHA-256. */
|
|
12922
|
+
var DEVICE_CERT_SIGNATURE = "ecdsa-p256-sha256";
|
|
12923
|
+
/** First line of every signed message; a change of format bumps the version. */
|
|
12924
|
+
var DEVICE_SIGNATURE_MESSAGE_VERSION = "camstack-device-cert-v1";
|
|
12925
|
+
_enum([
|
|
12926
|
+
"login",
|
|
12927
|
+
"renew",
|
|
12928
|
+
"revoke"
|
|
12929
|
+
]);
|
|
12930
|
+
var DevicePlatformSchema = _enum([
|
|
12931
|
+
"ios",
|
|
12932
|
+
"android",
|
|
12933
|
+
"web",
|
|
12934
|
+
"other"
|
|
12935
|
+
]);
|
|
12936
|
+
var Base64UrlSchema = string().min(1).max(4096).regex(/^[A-Za-z0-9_-]+$/);
|
|
12937
|
+
var PemSchema = string().min(1).max(16384);
|
|
12938
|
+
/**
|
|
12939
|
+
* Why a device-certificate endpoint said no. Distinct from a transport / 5xx
|
|
12940
|
+
* failure: those carry no reason and mean "try again", never "the credential is
|
|
12941
|
+
* dead". The viewer switches on this exhaustively.
|
|
12942
|
+
*/
|
|
12943
|
+
var DeviceRefusalReasonSchema = _enum([
|
|
12944
|
+
"revoked",
|
|
12945
|
+
"unknown-credential",
|
|
12946
|
+
"expired",
|
|
12947
|
+
"bad-signature",
|
|
12948
|
+
"nonce-invalid",
|
|
12949
|
+
"rate-limited",
|
|
12950
|
+
"invalid-certificate",
|
|
12951
|
+
"superseded",
|
|
12952
|
+
"user-gone",
|
|
12953
|
+
"unavailable",
|
|
12954
|
+
"code-invalid",
|
|
12955
|
+
"self-enrollment-disabled",
|
|
12956
|
+
"step-up-required",
|
|
12957
|
+
"bad-public-key"
|
|
12958
|
+
]);
|
|
12959
|
+
var DeviceRefusalSchema = object({
|
|
12960
|
+
ok: literal(false),
|
|
12961
|
+
reason: DeviceRefusalReasonSchema,
|
|
12962
|
+
definitive: boolean(),
|
|
12963
|
+
retryAfterSeconds: number().optional()
|
|
12964
|
+
});
|
|
12965
|
+
object({
|
|
12966
|
+
code: string().min(1).max(256),
|
|
12967
|
+
/** SubjectPublicKeyInfo DER of the device's P-256 public key, base64url. */
|
|
12968
|
+
publicKeySpki: Base64UrlSchema,
|
|
12969
|
+
deviceName: string().min(1).max(80).optional(),
|
|
12970
|
+
platform: DevicePlatformSchema
|
|
12971
|
+
});
|
|
12972
|
+
discriminatedUnion("ok", [object({
|
|
12973
|
+
credentialId: string(),
|
|
12974
|
+
certPem: PemSchema,
|
|
12975
|
+
/** The device CA certificate the leaf chains to. */
|
|
12976
|
+
chainPem: PemSchema,
|
|
12977
|
+
notAfter: number(),
|
|
12978
|
+
user: object({
|
|
12979
|
+
id: string(),
|
|
12980
|
+
username: string()
|
|
12981
|
+
})
|
|
12982
|
+
}).extend({ ok: literal(true) }), DeviceRefusalSchema]);
|
|
12983
|
+
object({
|
|
12984
|
+
/** The single-use step-up proof (`auth.deviceEnrollProofFrom…`). */
|
|
12985
|
+
proof: string().min(1).max(512),
|
|
12986
|
+
publicKeySpki: Base64UrlSchema,
|
|
12987
|
+
deviceName: string().min(1).max(80),
|
|
12988
|
+
platform: DevicePlatformSchema
|
|
12989
|
+
});
|
|
12990
|
+
object({
|
|
12991
|
+
proof: string(),
|
|
12992
|
+
expiresAt: number()
|
|
12993
|
+
});
|
|
12994
|
+
discriminatedUnion("ok", [object({
|
|
12995
|
+
nonce: string(),
|
|
12996
|
+
/** The origin to put in the signed message. The app compares it to the hub it dialled. */
|
|
12997
|
+
origin: string(),
|
|
12998
|
+
expiresAt: number(),
|
|
12999
|
+
signature: literal(DEVICE_CERT_SIGNATURE)
|
|
13000
|
+
}).extend({ ok: literal(true) }), DeviceRefusalSchema]);
|
|
13001
|
+
object({
|
|
13002
|
+
certPem: PemSchema,
|
|
13003
|
+
nonce: string().min(1).max(256),
|
|
13004
|
+
/** ECDSA P-256 SHA-256 over {@link buildDeviceSignatureMessage}; raw r||s or DER, base64url. */
|
|
13005
|
+
signature: Base64UrlSchema
|
|
13006
|
+
});
|
|
13007
|
+
discriminatedUnion("ok", [object({
|
|
13008
|
+
credentialId: string(),
|
|
13009
|
+
certPem: PemSchema,
|
|
13010
|
+
chainPem: PemSchema,
|
|
13011
|
+
notAfter: number()
|
|
13012
|
+
}).extend({ ok: literal(true) }), DeviceRefusalSchema]);
|
|
13013
|
+
discriminatedUnion("ok", [object({
|
|
13014
|
+
ok: literal(true),
|
|
13015
|
+
credentialId: string(),
|
|
13016
|
+
sessionsEnded: number().int()
|
|
13017
|
+
}), DeviceRefusalSchema]);
|
|
13018
|
+
var DeviceCredentialStatusSchema = _enum([
|
|
13019
|
+
"active",
|
|
13020
|
+
"expired",
|
|
13021
|
+
"revoked"
|
|
13022
|
+
]);
|
|
13023
|
+
var DeviceCredentialSchema = object({
|
|
13024
|
+
id: string(),
|
|
13025
|
+
userId: string(),
|
|
13026
|
+
username: string().nullable(),
|
|
13027
|
+
deviceName: string(),
|
|
13028
|
+
platform: DevicePlatformSchema,
|
|
13029
|
+
enrolledVia: _enum(["qr", "self"]),
|
|
13030
|
+
/** SHA-256 of the leaf certificate DER, colon-hex. */
|
|
13031
|
+
fingerprint: string(),
|
|
13032
|
+
issuedAt: number(),
|
|
13033
|
+
expiresAt: number(),
|
|
13034
|
+
lastUsedAt: number().nullable(),
|
|
13035
|
+
lastUsedFrom: string().nullable(),
|
|
13036
|
+
revokedAt: number().nullable(),
|
|
13037
|
+
/** `admin:<userId>` | `user:<userId>` | `device` | `user-deleted`. */
|
|
13038
|
+
revokedBy: string().nullable(),
|
|
13039
|
+
status: DeviceCredentialStatusSchema
|
|
13040
|
+
});
|
|
13041
|
+
var StartEnrollmentOutputSchema = object({
|
|
13042
|
+
/** Shown once; only its hash is kept. */
|
|
13043
|
+
code: string(),
|
|
13044
|
+
expiresAt: number(),
|
|
13045
|
+
/** `camstack://enroll?hub=…&code=…` — what the QR encodes. */
|
|
13046
|
+
enrollUrl: string(),
|
|
13047
|
+
/** The hub origin in the link, or `null` when the hub could not name one (the link then has no `hub`). */
|
|
13048
|
+
hubOrigin: string().nullable(),
|
|
13049
|
+
/** Every origin the apps may try (role `appConnections`). */
|
|
13050
|
+
hubOrigins: array(string())
|
|
13051
|
+
});
|
|
13052
|
+
object({
|
|
13053
|
+
kind: literal("device-certificate"),
|
|
13054
|
+
id: literal("device-certificate"),
|
|
13055
|
+
label: string(),
|
|
13056
|
+
stage: literal("primary"),
|
|
13057
|
+
/** tRPC paths under the hub's `auth` router, so a client names no literal. */
|
|
13058
|
+
challengePath: literal("auth.getDeviceChallenge"),
|
|
13059
|
+
revokePath: literal("auth.revokeOwnDeviceCertificate"),
|
|
13060
|
+
enrollSelfPath: literal("auth.enrollSelf"),
|
|
13061
|
+
loginPath: literal("auth.loginWithDeviceCertificate"),
|
|
13062
|
+
renewPath: literal("auth.renewDeviceCertificate"),
|
|
13063
|
+
signature: literal(DEVICE_CERT_SIGNATURE),
|
|
13064
|
+
messageVersion: literal(DEVICE_SIGNATURE_MESSAGE_VERSION),
|
|
13065
|
+
/** Which clients can execute it: a native app silently, a browser with a non-extractable WebCrypto key. */
|
|
13066
|
+
clients: array(_enum(["native", "web"])),
|
|
13067
|
+
/** The app executes it itself, silently (D858). */
|
|
13068
|
+
app: AppLoginPathSchema.nullable()
|
|
13069
|
+
});
|
|
12865
13070
|
var ExpressionBindingSourceSchema = union([
|
|
12866
13071
|
object({
|
|
12867
13072
|
kind: literal("field").optional(),
|
|
@@ -13190,7 +13395,9 @@ var ConfigTabDeclarationSchema = object({
|
|
|
13190
13395
|
var ConfigSectionWithValuesSchema = object({
|
|
13191
13396
|
id: string(),
|
|
13192
13397
|
title: string(),
|
|
13398
|
+
titleKey: string().optional(),
|
|
13193
13399
|
description: string().optional(),
|
|
13400
|
+
descriptionKey: string().optional(),
|
|
13194
13401
|
style: _enum(["card", "accordion"]).optional(),
|
|
13195
13402
|
defaultCollapsed: boolean().optional(),
|
|
13196
13403
|
columns: union([
|
|
@@ -15686,7 +15893,11 @@ var cameraStreamsCapability = {
|
|
|
15686
15893
|
* See `RuntimeStateDurability`. Enforced by
|
|
15687
15894
|
* `scripts/check-runtime-state-durability.ts`.
|
|
15688
15895
|
*/
|
|
15689
|
-
durability: "session"
|
|
15896
|
+
durability: "session",
|
|
15897
|
+
/**
|
|
15898
|
+
* History (D850): none — `online` duplicates device-status.online (one authority); slot data is nested enum/string.
|
|
15899
|
+
*/
|
|
15900
|
+
history: "none"
|
|
15690
15901
|
};
|
|
15691
15902
|
EventCategory.DoorbellOnPressed;
|
|
15692
15903
|
var CompositionEventPlanSchema = object({
|
|
@@ -16518,7 +16729,345 @@ method(object({
|
|
|
16518
16729
|
}), method(object({ refs: RefListSchema }), KeychainResolveResultSchema, { auth: "admin" }), method(object({ refs: RefListSchema }), object({ deleted: number().int() }), {
|
|
16519
16730
|
kind: "mutation",
|
|
16520
16731
|
auth: "admin"
|
|
16732
|
+
}), method(object({ deviceId: number().int() }), object({ refs: array(string()).readonly() }), {
|
|
16733
|
+
kind: "mutation",
|
|
16734
|
+
auth: "admin"
|
|
16521
16735
|
}), method(object({}), array(KeychainSecretMetaSchema).readonly(), { auth: "admin" }), method(object({}), KeychainStateSchema, { auth: "admin" });
|
|
16736
|
+
/**
|
|
16737
|
+
* device-history — the ONE mechanism for numeric history (D850).
|
|
16738
|
+
*
|
|
16739
|
+
* A device value is recorded because its capability says so (the `history`
|
|
16740
|
+
* block of a `*.cap.ts`, captured hub-side from `DeviceStateChanged`); any
|
|
16741
|
+
* other series is DECLARED by the addon that produces it and fed with points
|
|
16742
|
+
* (`record`) or closed five-minute buckets (`recordBuckets`). Rollups 5m / 1h /
|
|
16743
|
+
* 1d are computed here and nowhere else. Storage is `history.db` (D851).
|
|
16744
|
+
*
|
|
16745
|
+
* Who the PRODUCER is: `declareSeries`, `record` and `recordBuckets` are owner
|
|
16746
|
+
* checked against the `callerAddonId` the transport stamps into a call that
|
|
16747
|
+
* crossed a process (never in an input schema, so a session cannot supply it).
|
|
16748
|
+
* A call with no stamp is refused `not-owner`. The methods are `admin` so a
|
|
16749
|
+
* non-admin session never reaches them; an addon's `ctx.api` call bypasses the
|
|
16750
|
+
* tier by design.
|
|
16751
|
+
*/
|
|
16752
|
+
/** Whose history: a real device, or a cluster node (load, memory). */
|
|
16753
|
+
var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
|
|
16754
|
+
kind: literal("device"),
|
|
16755
|
+
deviceId: number().int()
|
|
16756
|
+
}), object({
|
|
16757
|
+
kind: literal("node"),
|
|
16758
|
+
nodeId: string().min(1)
|
|
16759
|
+
})]);
|
|
16760
|
+
var DeviceHistoryKindSchema = _enum([
|
|
16761
|
+
"gauge",
|
|
16762
|
+
"counter",
|
|
16763
|
+
"boolean"
|
|
16764
|
+
]);
|
|
16765
|
+
var DeviceHistoryResolutionSchema = _enum([
|
|
16766
|
+
"raw",
|
|
16767
|
+
"5m",
|
|
16768
|
+
"1h",
|
|
16769
|
+
"1d"
|
|
16770
|
+
]);
|
|
16771
|
+
/** Why a producer's point or bucket was not stored. Counted, never silent (D391). */
|
|
16772
|
+
var DeviceHistoryRefusalReasonSchema = _enum([
|
|
16773
|
+
"undeclared",
|
|
16774
|
+
"not-owner",
|
|
16775
|
+
"opted-out",
|
|
16776
|
+
"not-a-real-device",
|
|
16777
|
+
"rate",
|
|
16778
|
+
"ingest-mismatch",
|
|
16779
|
+
"out-of-range"
|
|
16780
|
+
]);
|
|
16781
|
+
var RefusalSchema = object({
|
|
16782
|
+
key: string(),
|
|
16783
|
+
reason: DeviceHistoryRefusalReasonSchema,
|
|
16784
|
+
count: number().int()
|
|
16785
|
+
});
|
|
16786
|
+
var IngestResultSchema = object({
|
|
16787
|
+
accepted: number().int(),
|
|
16788
|
+
refused: array(RefusalSchema).readonly()
|
|
16789
|
+
});
|
|
16790
|
+
var SeriesInfoSchema = object({
|
|
16791
|
+
key: string(),
|
|
16792
|
+
scope: string(),
|
|
16793
|
+
kind: DeviceHistoryKindSchema,
|
|
16794
|
+
/** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
|
|
16795
|
+
unit: string().nullable(),
|
|
16796
|
+
displayName: string(),
|
|
16797
|
+
source: _enum(["cap", "addon"]),
|
|
16798
|
+
firstTs: number(),
|
|
16799
|
+
lastTs: number()
|
|
16800
|
+
});
|
|
16801
|
+
var QueryPointSchema = object({
|
|
16802
|
+
/** Raw: the point's time. Rollup: the bucket start. */
|
|
16803
|
+
t: number(),
|
|
16804
|
+
samples: number().int(),
|
|
16805
|
+
/** `sum / samples`. */
|
|
16806
|
+
mean: number().nullable(),
|
|
16807
|
+
/** Time-weighted mean (`tw_sum / tw_ms`); `null` for bucket-ingested series. For a boolean: the fraction of time true. */
|
|
16808
|
+
twMean: number().nullable(),
|
|
16809
|
+
min: number(),
|
|
16810
|
+
max: number(),
|
|
16811
|
+
/** `null` is unknown, never zero (D393). */
|
|
16812
|
+
last: number().nullable()
|
|
16813
|
+
});
|
|
16814
|
+
var QuerySeriesSchema = object({
|
|
16815
|
+
scope: string(),
|
|
16816
|
+
/** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
|
|
16817
|
+
before: object({
|
|
16818
|
+
t: number(),
|
|
16819
|
+
value: number().nullable()
|
|
16820
|
+
}).nullable(),
|
|
16821
|
+
points: array(QueryPointSchema).readonly()
|
|
16822
|
+
});
|
|
16823
|
+
/** The window part of a query, shared by the device and node forms. */
|
|
16824
|
+
var QueryWindowShape = {
|
|
16825
|
+
key: string(),
|
|
16826
|
+
scope: string().optional(),
|
|
16827
|
+
from: number(),
|
|
16828
|
+
to: number(),
|
|
16829
|
+
resolution: union([DeviceHistoryResolutionSchema, literal("auto")]).default("auto"),
|
|
16830
|
+
maxPoints: number().int().positive().max(5e3).default(1e3)
|
|
16831
|
+
};
|
|
16832
|
+
var QueryResultSchema = object({
|
|
16833
|
+
resolution: DeviceHistoryResolutionSchema,
|
|
16834
|
+
series: array(QuerySeriesSchema).readonly(),
|
|
16835
|
+
truncated: boolean()
|
|
16836
|
+
});
|
|
16837
|
+
var TierStatusSchema = object({
|
|
16838
|
+
tier: DeviceHistoryResolutionSchema,
|
|
16839
|
+
/** `null` until the first background count answered. */
|
|
16840
|
+
rows: number().int().nullable(),
|
|
16841
|
+
/** `rows` times a fixed per-row estimate — approximate, labelled so. */
|
|
16842
|
+
approxBytes: number().nullable(),
|
|
16843
|
+
countedAt: number().nullable()
|
|
16844
|
+
});
|
|
16845
|
+
/** Operator/diagnostic view: rows per tier, last runs, refusals and drops since boot. */
|
|
16846
|
+
var DeviceHistoryStatusSchema = object({
|
|
16847
|
+
startedAt: number(),
|
|
16848
|
+
/** The store is declared, series loaded and the first reconcile has answered. */
|
|
16849
|
+
ready: boolean(),
|
|
16850
|
+
series: number().int(),
|
|
16851
|
+
metrics: number().int(),
|
|
16852
|
+
optedOutDevices: number().int(),
|
|
16853
|
+
tiers: array(TierStatusSchema).readonly(),
|
|
16854
|
+
capture: object({
|
|
16855
|
+
eventsSeen: number().int(),
|
|
16856
|
+
pointsEmitted: number().int(),
|
|
16857
|
+
pointsWritten: number().int(),
|
|
16858
|
+
pointsDropped: number().int(),
|
|
16859
|
+
bufferDepth: number().int(),
|
|
16860
|
+
trailingEmitted: number().int(),
|
|
16861
|
+
reconciledPoints: number().int(),
|
|
16862
|
+
reconcileRuns: number().int(),
|
|
16863
|
+
reconcileFailures: number().int(),
|
|
16864
|
+
lastReconcileAt: number().nullable(),
|
|
16865
|
+
lastFlushAt: number().nullable(),
|
|
16866
|
+
flushFailures: number().int(),
|
|
16867
|
+
skipped: record(string(), number().int())
|
|
16868
|
+
}),
|
|
16869
|
+
ingest: object({
|
|
16870
|
+
accepted: number().int(),
|
|
16871
|
+
refused: record(string(), number().int())
|
|
16872
|
+
}),
|
|
16873
|
+
rollup: object({
|
|
16874
|
+
last5mAt: number().nullable(),
|
|
16875
|
+
last1hAt: number().nullable(),
|
|
16876
|
+
last1dAt: number().nullable(),
|
|
16877
|
+
errors: number().int(),
|
|
16878
|
+
dirty5m: number().int(),
|
|
16879
|
+
dirty1h: number().int(),
|
|
16880
|
+
dirty1d: number().int()
|
|
16881
|
+
}),
|
|
16882
|
+
retention: object({
|
|
16883
|
+
lastRunAt: number().nullable(),
|
|
16884
|
+
deleted: record(string(), number().int()),
|
|
16885
|
+
purgedSeries: number().int()
|
|
16886
|
+
}),
|
|
16887
|
+
directory: object({
|
|
16888
|
+
devices: number().int(),
|
|
16889
|
+
lastRefreshAt: number().nullable()
|
|
16890
|
+
})
|
|
16891
|
+
});
|
|
16892
|
+
method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
|
|
16893
|
+
deviceId: number().int(),
|
|
16894
|
+
...QueryWindowShape
|
|
16895
|
+
}), QueryResultSchema), method(object({
|
|
16896
|
+
nodeId: string().min(1),
|
|
16897
|
+
...QueryWindowShape
|
|
16898
|
+
}), QueryResultSchema, { auth: "admin" }), method(object({
|
|
16899
|
+
name: string().regex(/^[a-z0-9-]+$/),
|
|
16900
|
+
subjectKind: _enum(["device", "node"]),
|
|
16901
|
+
kind: DeviceHistoryKindSchema,
|
|
16902
|
+
unit: string().optional(),
|
|
16903
|
+
displayName: string().min(1),
|
|
16904
|
+
ingest: _enum(["points", "buckets"])
|
|
16905
|
+
}), object({ key: string() }), {
|
|
16906
|
+
kind: "mutation",
|
|
16907
|
+
auth: "admin"
|
|
16908
|
+
}), method(object({ points: array(object({
|
|
16909
|
+
key: string(),
|
|
16910
|
+
subject: DeviceHistorySubjectSchema,
|
|
16911
|
+
scope: string().default(""),
|
|
16912
|
+
ts: number(),
|
|
16913
|
+
value: number()
|
|
16914
|
+
})).max(5e3) }), IngestResultSchema, {
|
|
16915
|
+
kind: "mutation",
|
|
16916
|
+
auth: "admin"
|
|
16917
|
+
}), method(object({ buckets: array(object({
|
|
16918
|
+
key: string(),
|
|
16919
|
+
subject: DeviceHistorySubjectSchema,
|
|
16920
|
+
scope: string().default(""),
|
|
16921
|
+
bucketStart: number(),
|
|
16922
|
+
samples: number().int().positive(),
|
|
16923
|
+
sum: number(),
|
|
16924
|
+
min: number(),
|
|
16925
|
+
max: number(),
|
|
16926
|
+
last: number().nullable(),
|
|
16927
|
+
lastTs: number().nullable()
|
|
16928
|
+
})).max(5e3) }), IngestResultSchema, {
|
|
16929
|
+
kind: "mutation",
|
|
16930
|
+
auth: "admin"
|
|
16931
|
+
}), method(object({ deviceId: number().int() }), object({ enabled: boolean() })), method(object({
|
|
16932
|
+
deviceId: number().int(),
|
|
16933
|
+
enabled: boolean()
|
|
16934
|
+
}), object({ enabled: boolean() }), {
|
|
16935
|
+
kind: "mutation",
|
|
16936
|
+
auth: "admin"
|
|
16937
|
+
}), method(object({}), DeviceHistoryStatusSchema, { auth: "admin" });
|
|
16938
|
+
var DeviceCaStatusSchema = discriminatedUnion("state", [
|
|
16939
|
+
object({ state: literal("absent") }),
|
|
16940
|
+
object({
|
|
16941
|
+
state: literal("ready"),
|
|
16942
|
+
subject: string(),
|
|
16943
|
+
fingerprintSha256: string(),
|
|
16944
|
+
validTo: string()
|
|
16945
|
+
}),
|
|
16946
|
+
object({
|
|
16947
|
+
state: literal("unavailable"),
|
|
16948
|
+
reason: string()
|
|
16949
|
+
})
|
|
16950
|
+
]);
|
|
16951
|
+
var DeviceCertificateSettingsSchema = object({ selfEnrollment: _enum(["allowed", "disabled"]) });
|
|
16952
|
+
method(object({
|
|
16953
|
+
userId: string().min(1).optional(),
|
|
16954
|
+
includeRevoked: boolean().default(false)
|
|
16955
|
+
}), array(DeviceCredentialSchema).readonly(), { auth: "admin" }), method(object({
|
|
16956
|
+
userId: string().min(1),
|
|
16957
|
+
deviceName: string().min(1).max(80)
|
|
16958
|
+
}), StartEnrollmentOutputSchema, {
|
|
16959
|
+
kind: "mutation",
|
|
16960
|
+
auth: "admin",
|
|
16961
|
+
caller: "required"
|
|
16962
|
+
}), method(object({ id: string().min(1) }), object({
|
|
16963
|
+
revoked: boolean(),
|
|
16964
|
+
sessionsEnded: number().int(),
|
|
16965
|
+
status: DeviceCredentialStatusSchema
|
|
16966
|
+
}), {
|
|
16967
|
+
kind: "mutation",
|
|
16968
|
+
auth: "admin",
|
|
16969
|
+
caller: "required"
|
|
16970
|
+
}), method(object({}), DeviceCertificateSettingsSchema, { auth: "admin" }), method(DeviceCertificateSettingsSchema, DeviceCertificateSettingsSchema, {
|
|
16971
|
+
kind: "mutation",
|
|
16972
|
+
auth: "admin"
|
|
16973
|
+
}), method(object({ id: string().min(1) }), object({ result: _enum([
|
|
16974
|
+
"deleted",
|
|
16975
|
+
"live",
|
|
16976
|
+
"unknown"
|
|
16977
|
+
]) }), {
|
|
16978
|
+
kind: "mutation",
|
|
16979
|
+
auth: "admin",
|
|
16980
|
+
caller: "required"
|
|
16981
|
+
}), method(object({}), DeviceCaStatusSchema, { auth: "admin" }), method(object({
|
|
16982
|
+
id: string().min(1),
|
|
16983
|
+
deviceName: string().min(1).max(80)
|
|
16984
|
+
}), object({ renamed: boolean() }), {
|
|
16985
|
+
kind: "mutation",
|
|
16986
|
+
auth: "admin"
|
|
16987
|
+
});
|
|
16988
|
+
/**
|
|
16989
|
+
* `node-certificates` - what a node holds and the two renewals the hub drives
|
|
16990
|
+
* (D856): the node's MESH leaf (mutual TLS to the hub) and its HTTPS leaf (issued
|
|
16991
|
+
* from the hub's local CA so a device that trusts the hub root trusts the node).
|
|
16992
|
+
*
|
|
16993
|
+
* Provided by the AGENT RUNTIME (the synthetic `agent-runtime` addon id, like
|
|
16994
|
+
* `server-management`): the hub reaches it through the ordinary node-pinned
|
|
16995
|
+
* capability call - no new Moleculer action. The hub's own certificates are
|
|
16996
|
+
* handled in-process by the hub (`certificates` router), so this cap has no hub
|
|
16997
|
+
* provider.
|
|
16998
|
+
*
|
|
16999
|
+
* No private key ever crosses the mesh: the node generates its key pair, sends a
|
|
17000
|
+
* CSR, and the hub returns only the signed certificate.
|
|
17001
|
+
*/
|
|
17002
|
+
var MeshLeafInfoSchema = object({
|
|
17003
|
+
cn: string(),
|
|
17004
|
+
serial: string(),
|
|
17005
|
+
fingerprintSha256: string(),
|
|
17006
|
+
notBefore: number(),
|
|
17007
|
+
notAfter: number()
|
|
17008
|
+
});
|
|
17009
|
+
var HttpsLeafInfoSchema = object({
|
|
17010
|
+
fingerprintSha256: string(),
|
|
17011
|
+
issuer: string(),
|
|
17012
|
+
sans: array(string()),
|
|
17013
|
+
notBefore: number(),
|
|
17014
|
+
notAfter: number()
|
|
17015
|
+
});
|
|
17016
|
+
var NodeHttpsStateSchema = discriminatedUnion("state", [object({
|
|
17017
|
+
state: literal("served"),
|
|
17018
|
+
leaf: HttpsLeafInfoSchema
|
|
17019
|
+
}), object({
|
|
17020
|
+
state: literal("not-issued"),
|
|
17021
|
+
reason: string()
|
|
17022
|
+
})]);
|
|
17023
|
+
method(object({}), object({
|
|
17024
|
+
nodeId: string(),
|
|
17025
|
+
mesh: MeshLeafInfoSchema.nullable(),
|
|
17026
|
+
https: NodeHttpsStateSchema
|
|
17027
|
+
}), { auth: "admin" }), method(object({}), object({ csrPem: string() }), {
|
|
17028
|
+
kind: "mutation",
|
|
17029
|
+
auth: "admin"
|
|
17030
|
+
}), method(object({
|
|
17031
|
+
certPem: string().min(1),
|
|
17032
|
+
caCertPem: string().min(1),
|
|
17033
|
+
confirmWithinMs: number().int().min(1e4).max(6e5)
|
|
17034
|
+
}), object({
|
|
17035
|
+
fingerprintSha256: string(),
|
|
17036
|
+
serial: string()
|
|
17037
|
+
}), {
|
|
17038
|
+
kind: "mutation",
|
|
17039
|
+
auth: "admin"
|
|
17040
|
+
}), method(object({ fingerprintSha256: string() }), object({ confirmed: boolean() }), {
|
|
17041
|
+
kind: "mutation",
|
|
17042
|
+
auth: "admin"
|
|
17043
|
+
}), method(object({}), object({ rolledBack: boolean() }), {
|
|
17044
|
+
kind: "mutation",
|
|
17045
|
+
auth: "admin"
|
|
17046
|
+
}), method(object({}), object({
|
|
17047
|
+
csrPem: string(),
|
|
17048
|
+
hostnames: array(string()),
|
|
17049
|
+
addresses: array(string()),
|
|
17050
|
+
/** SHA-256 of the hub local CA this node pinned at its first install; `null` before one. */
|
|
17051
|
+
pinnedCaFingerprintSha256: string().nullable()
|
|
17052
|
+
}), {
|
|
17053
|
+
kind: "mutation",
|
|
17054
|
+
auth: "admin"
|
|
17055
|
+
}), method(object({}), object({ ok: literal(true) }), {
|
|
17056
|
+
kind: "mutation",
|
|
17057
|
+
auth: "admin"
|
|
17058
|
+
}), method(object({
|
|
17059
|
+
certPem: string().min(1),
|
|
17060
|
+
caCertPem: string().min(1),
|
|
17061
|
+
/**
|
|
17062
|
+
* The hub signals that its local CA was rotated (D227) and this leaf chains to the NEW
|
|
17063
|
+
* one. Only the hub, over the authenticated mesh, can say so; a leaf with a different CA
|
|
17064
|
+
* and no signal is refused.
|
|
17065
|
+
*/
|
|
17066
|
+
caRotation: boolean().optional()
|
|
17067
|
+
}), HttpsLeafInfoSchema, {
|
|
17068
|
+
kind: "mutation",
|
|
17069
|
+
auth: "admin"
|
|
17070
|
+
});
|
|
16522
17071
|
var KeychainKeySourceSchema = object({
|
|
16523
17072
|
kind: _enum([
|
|
16524
17073
|
"config-file",
|
|
@@ -17106,6 +17655,10 @@ var deviceDiscoveryCapability = {
|
|
|
17106
17655
|
* `scripts/check-runtime-state-durability.ts`.
|
|
17107
17656
|
*/
|
|
17108
17657
|
durability: "session",
|
|
17658
|
+
/**
|
|
17659
|
+
* History (D850): none — inventory.
|
|
17660
|
+
*/
|
|
17661
|
+
history: "none",
|
|
17109
17662
|
methods: {
|
|
17110
17663
|
/**
|
|
17111
17664
|
* Snapshot of the current `discovered` list. Returns the
|
|
@@ -37887,6 +38440,38 @@ var DeviceRegisterPayloadSchema = object({
|
|
|
37887
38440
|
* omits it and the keyword backstop applies. */
|
|
37888
38441
|
secretConfigPaths: array(string()).optional()
|
|
37889
38442
|
});
|
|
38443
|
+
/** One deleted device, kept by device-manager so an addon that missed the
|
|
38444
|
+
* deletion can still learn of it (D865). Written by the delete path ONLY. */
|
|
38445
|
+
var DeviceTombstoneSchema = object({
|
|
38446
|
+
deviceId: number().int().positive(),
|
|
38447
|
+
/** Epoch ms the device was deleted. */
|
|
38448
|
+
deletedAt: number(),
|
|
38449
|
+
/** The addon that owned the device when it was deleted. */
|
|
38450
|
+
providerAddonId: string()
|
|
38451
|
+
});
|
|
38452
|
+
/** Data held for one device that device-manager no longer knows. */
|
|
38453
|
+
var OrphanDeviceDataSchema = object({
|
|
38454
|
+
deviceId: number().int().positive(),
|
|
38455
|
+
/** Rows/files per store (`<addonId>:<store>`). */
|
|
38456
|
+
stores: record(string(), number().int().nonnegative())
|
|
38457
|
+
});
|
|
38458
|
+
var CleanupDeletedDevicesResultSchema = object({
|
|
38459
|
+
/**
|
|
38460
|
+
* `skipped` — the absence check could not be trusted (a device-list read
|
|
38461
|
+
* failed or the two reads disagreed); nothing was listed or deleted.
|
|
38462
|
+
* `dry-run` — `devices` is what a confirmed run would delete.
|
|
38463
|
+
* `cleaned` — `devices` is what was deleted.
|
|
38464
|
+
*/
|
|
38465
|
+
status: _enum([
|
|
38466
|
+
"skipped",
|
|
38467
|
+
"dry-run",
|
|
38468
|
+
"cleaned"
|
|
38469
|
+
]),
|
|
38470
|
+
reason: string().nullable(),
|
|
38471
|
+
devices: array(OrphanDeviceDataSchema),
|
|
38472
|
+
/** Implementers that could not be asked (their stores are not in `devices`). */
|
|
38473
|
+
unreachable: array(string())
|
|
38474
|
+
});
|
|
37890
38475
|
var DeviceRemovePayloadSchema = object({ deviceId: number() });
|
|
37891
38476
|
var DevicePersistConfigPayloadSchema = object({
|
|
37892
38477
|
deviceId: number(),
|
|
@@ -38125,6 +38710,9 @@ method(object({
|
|
|
38125
38710
|
}), method(object({ deviceId: number() }), object({ success: literal(true) }), {
|
|
38126
38711
|
kind: "mutation",
|
|
38127
38712
|
auth: "admin"
|
|
38713
|
+
}), method(object({ sinceMs: number() }), array(DeviceTombstoneSchema).readonly(), { auth: "admin" }), method(object({ confirm: boolean() }), CleanupDeletedDevicesResultSchema, {
|
|
38714
|
+
kind: "mutation",
|
|
38715
|
+
auth: "admin"
|
|
38128
38716
|
}), method(object({ integrationId: string() }), object({ removed: number() }), {
|
|
38129
38717
|
kind: "mutation",
|
|
38130
38718
|
auth: "admin"
|
|
@@ -38587,6 +39175,72 @@ method(object({
|
|
|
38587
39175
|
auth: "admin"
|
|
38588
39176
|
});
|
|
38589
39177
|
/**
|
|
39178
|
+
* `device-removal-hook` — the reliable way an addon learns a device was DELETED,
|
|
39179
|
+
* so it can delete what it keeps for that device (D865).
|
|
39180
|
+
*
|
|
39181
|
+
* ## Why an event was not enough
|
|
39182
|
+
*
|
|
39183
|
+
* `DeviceUnregistered` is telemetry and may be dropped (D8, D11). An addon that
|
|
39184
|
+
* hung its per-device clean-up on it left durable garbage whenever the event was
|
|
39185
|
+
* lost, the addon was down, or it was restarting at that moment — footage,
|
|
39186
|
+
* analytics rows and settings of device 4483 outlived the device. Loss of this
|
|
39187
|
+
* signal corrupts durable state, so it travels by RPC with a recorded fact
|
|
39188
|
+
* behind it (D8: "if loss would corrupt durable state, use RPC plus a reconcile").
|
|
39189
|
+
*
|
|
39190
|
+
* ## The three pieces
|
|
39191
|
+
*
|
|
39192
|
+
* 1. device-manager records a TOMBSTONE per deleted device
|
|
39193
|
+
* (`deviceManager.listDeletedSince`). The tombstone is written by the delete
|
|
39194
|
+
* path only — a device that is unregistered, offline or whose provider is
|
|
39195
|
+
* restarting is NOT deleted and gets none.
|
|
39196
|
+
* 2. After a delete, device-manager calls `onDeviceRemoved` on EVERY provider of
|
|
39197
|
+
* this collection, one by one, with bounded retries, logged.
|
|
39198
|
+
* 3. An implementer that was down asks `deviceManager.listDeletedSince` at start
|
|
39199
|
+
* (and periodically) and runs its own `onDeviceRemoved` for each tombstone it
|
|
39200
|
+
* may have missed. Reconcile is driven by tombstones, never by "the device is
|
|
39201
|
+
* not in the current list": a failed or partial list read must not destroy data.
|
|
39202
|
+
*
|
|
39203
|
+
* ## Contract for an implementer
|
|
39204
|
+
*
|
|
39205
|
+
* - **Idempotent.** It is called again by a retry, by a reconcile and by the
|
|
39206
|
+
* admin cleanup of data that predates tombstones. A device with nothing left
|
|
39207
|
+
* answers zero counts.
|
|
39208
|
+
* - **One key per store** in `counts`, deleted rows/files per store, so the log
|
|
39209
|
+
* line and the admin dry run can say where the data was.
|
|
39210
|
+
* - **Training datasets are NOT device data** and are never deleted by a hook.
|
|
39211
|
+
* - **Per-device SETTINGS are not hooked.** Configuration lives in the standard
|
|
39212
|
+
* per-device store (`ctx.settings.*DeviceStore`), which device-manager clears
|
|
39213
|
+
* for every addon centrally at delete time. This hook is for device DATA
|
|
39214
|
+
* that is not settings: footage, event media, analytics rows, history.
|
|
39215
|
+
* - A provider that cannot tell is allowed to throw; the caller retries it.
|
|
39216
|
+
*
|
|
39217
|
+
* `listDeviceData` is the read side of the admin "Clean data of deleted devices"
|
|
39218
|
+
* action: which device ids this addon holds data for, and how much per store. It
|
|
39219
|
+
* never deletes. device-manager decides which of those ids are absent from the
|
|
39220
|
+
* fleet, from TWO consistent reads of the device list (D49).
|
|
39221
|
+
*/
|
|
39222
|
+
/** What a hook is told about the deletion. */
|
|
39223
|
+
var DeviceRemovedInputSchema = object({
|
|
39224
|
+
deviceId: number().int().positive(),
|
|
39225
|
+
/** Epoch ms the device was deleted (the tombstone's `deletedAt`). */
|
|
39226
|
+
deletedAt: number(),
|
|
39227
|
+
/** The addon that owned the device, as device-manager last knew it. */
|
|
39228
|
+
providerAddonId: string()
|
|
39229
|
+
});
|
|
39230
|
+
/** Rows/files/refs deleted, per store this implementer owns. */
|
|
39231
|
+
var DeviceRemovedResultSchema = object({ counts: record(string(), number().int().nonnegative()) });
|
|
39232
|
+
/** One (store, device) pair an implementer holds data for. */
|
|
39233
|
+
var DeviceDataEntrySchema = object({
|
|
39234
|
+
store: string(),
|
|
39235
|
+
deviceId: number().int().positive(),
|
|
39236
|
+
/** Rows (or files) held for the device in the store. */
|
|
39237
|
+
count: number().int().nonnegative()
|
|
39238
|
+
});
|
|
39239
|
+
method(DeviceRemovedInputSchema, DeviceRemovedResultSchema, {
|
|
39240
|
+
kind: "mutation",
|
|
39241
|
+
auth: "admin"
|
|
39242
|
+
}), method(_void(), array(DeviceDataEntrySchema).readonly(), { auth: "admin" });
|
|
39243
|
+
/**
|
|
38590
39244
|
* `failure-contribution` — the capability an addon reports its OWN losses
|
|
38591
39245
|
* through, per camera, with the denominator attached. It stores nothing.
|
|
38592
39246
|
*
|
|
@@ -39594,7 +40248,13 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
|
|
|
39594
40248
|
* `beginExternalLink` offer exactly the redirect methods that set this,
|
|
39595
40249
|
* whatever their id. Absent / false — a login button only.
|
|
39596
40250
|
*/
|
|
39597
|
-
linkable: boolean().optional()
|
|
40251
|
+
linkable: boolean().optional(),
|
|
40252
|
+
/**
|
|
40253
|
+
* How a NATIVE app starts this method (D858): `{ kind: 'browser', startPath }`
|
|
40254
|
+
* when the route understands the app flow query (`app=1&code_challenge=…`),
|
|
40255
|
+
* `null`/absent when there is no app path - the app hides the method.
|
|
40256
|
+
*/
|
|
40257
|
+
app: AppLoginPathSchema.nullable().optional()
|
|
39598
40258
|
}),
|
|
39599
40259
|
object({
|
|
39600
40260
|
kind: literal("widget"),
|
|
@@ -39606,7 +40266,9 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
|
|
|
39606
40266
|
bundle: string(),
|
|
39607
40267
|
/** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
|
|
39608
40268
|
remote: WidgetRemoteSchema,
|
|
39609
|
-
stage: LoginStageEnum
|
|
40269
|
+
stage: LoginStageEnum,
|
|
40270
|
+
/** Widgets are web ceremonies: no native app path (D858). Absent reads as `null`. */
|
|
40271
|
+
app: AppLoginPathSchema.nullable().optional()
|
|
39610
40272
|
}),
|
|
39611
40273
|
object({
|
|
39612
40274
|
kind: literal("passkey"),
|
|
@@ -39618,7 +40280,9 @@ var LoginMethodContributionSchema = discriminatedUnion("kind", [
|
|
|
39618
40280
|
/** Effective WebAuthn RP ID (`resolveRpID()`) — the shell gates visibility on it. */
|
|
39619
40281
|
rpId: string(),
|
|
39620
40282
|
/** Effective expected origin (`resolveOrigin()`), null when unconfigured. */
|
|
39621
|
-
origin: string().nullable()
|
|
40283
|
+
origin: string().nullable(),
|
|
40284
|
+
/** Set by the hub for the primary arm; a second-factor passkey has no app path (D858). */
|
|
40285
|
+
app: AppLoginPathSchema.nullable().optional()
|
|
39622
40286
|
})
|
|
39623
40287
|
]);
|
|
39624
40288
|
method(_void(), array(LoginMethodContributionSchema).readonly());
|
|
@@ -40128,7 +40792,21 @@ var NetworkEndpointSchema = object({
|
|
|
40128
40792
|
url: string(),
|
|
40129
40793
|
hostname: string(),
|
|
40130
40794
|
port: number(),
|
|
40131
|
-
protocol: _enum(["http", "https"])
|
|
40795
|
+
protocol: _enum(["http", "https"]),
|
|
40796
|
+
/**
|
|
40797
|
+
* Whether this address survives a restart of its provider. `false` = it is
|
|
40798
|
+
* re-issued every time (a Quick tunnel's random `*.trycloudflare.com`); the
|
|
40799
|
+
* hub never selects such an address AUTOMATICALLY for a role (D860), though
|
|
40800
|
+
* it stays visible and an operator may still flag it. Absent = stable: every
|
|
40801
|
+
* provider except a Quick tunnel owns a name that does not change.
|
|
40802
|
+
*/
|
|
40803
|
+
stable: boolean().optional()
|
|
40804
|
+
});
|
|
40805
|
+
object({
|
|
40806
|
+
url: string(),
|
|
40807
|
+
/** Mirrors {@link NetworkEndpointSchema} `stable`; absent = stable. */
|
|
40808
|
+
stable: boolean().optional(),
|
|
40809
|
+
updated: boolean().optional()
|
|
40132
40810
|
});
|
|
40133
40811
|
var NetworkAccessStatusSchema = object({
|
|
40134
40812
|
connected: boolean(),
|
|
@@ -41225,6 +41903,10 @@ var alarmPanelCapability = {
|
|
|
41225
41903
|
* `scripts/check-runtime-state-durability.ts`.
|
|
41226
41904
|
*/
|
|
41227
41905
|
durability: "restored",
|
|
41906
|
+
/**
|
|
41907
|
+
* History (D850): none — enum state; arm/disarm history belongs in the events ledger.
|
|
41908
|
+
*/
|
|
41909
|
+
history: "none",
|
|
41228
41910
|
/** Clock fields: written, but excluded from the compare that decides
|
|
41229
41911
|
* whether persisting is worth a SQLite commit. */
|
|
41230
41912
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -47876,7 +48558,11 @@ var zonesCapability = {
|
|
|
47876
48558
|
* See `RuntimeStateDurability`. Enforced by
|
|
47877
48559
|
* `scripts/check-runtime-state-durability.ts`.
|
|
47878
48560
|
*/
|
|
47879
|
-
durability: "restored"
|
|
48561
|
+
durability: "restored",
|
|
48562
|
+
/**
|
|
48563
|
+
* History (D850): none — configuration arrays.
|
|
48564
|
+
*/
|
|
48565
|
+
history: "none"
|
|
47880
48566
|
};
|
|
47881
48567
|
/**
|
|
47882
48568
|
* A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
|
|
@@ -50333,7 +51019,22 @@ var SsoBridgeClaimsSchema = object({
|
|
|
50333
51019
|
* request to present the matching cookie — a login bridge is useless in
|
|
50334
51020
|
* any other browser.
|
|
50335
51021
|
*/
|
|
50336
|
-
browserBinding: string().optional()
|
|
51022
|
+
browserBinding: string().optional(),
|
|
51023
|
+
/**
|
|
51024
|
+
* The native app that started this sign-in (D858): its PKCE challenge,
|
|
51025
|
+
* `state`, purpose and allow-listed return URL, copied from the server-side
|
|
51026
|
+
* pending OIDC state. A bridge carrying it is finished ONLY at
|
|
51027
|
+
* `/api/auth/sso/finish-app` (which mints a handoff code, never a web
|
|
51028
|
+
* session); `/api/auth/sso/finish` refuses it.
|
|
51029
|
+
*/
|
|
51030
|
+
app: object({
|
|
51031
|
+
codeChallenge: string(),
|
|
51032
|
+
state: string(),
|
|
51033
|
+
purpose: _enum(["new-session", "step-up"]),
|
|
51034
|
+
redirect: string(),
|
|
51035
|
+
/** The page language the app asked for (D858); the confirm page speaks it. */
|
|
51036
|
+
lang: _enum(["en", "it"]).optional()
|
|
51037
|
+
}).optional()
|
|
50337
51038
|
});
|
|
50338
51039
|
method(object({
|
|
50339
51040
|
claims: SsoBridgeClaimsSchema,
|
|
@@ -50720,6 +51421,10 @@ var streamSignalsCapability = {
|
|
|
50720
51421
|
* `scripts/check-runtime-state-durability.ts`.
|
|
50721
51422
|
*/
|
|
50722
51423
|
durability: "session",
|
|
51424
|
+
/**
|
|
51425
|
+
* History (D850): none — array state.
|
|
51426
|
+
*/
|
|
51427
|
+
history: "none",
|
|
50723
51428
|
methods: {
|
|
50724
51429
|
/**
|
|
50725
51430
|
* What this device can emit. Empty is a valid and common answer — most
|
|
@@ -52986,7 +53691,12 @@ var SearchResultSchema = object({
|
|
|
52986
53691
|
publishedAt: string(),
|
|
52987
53692
|
author: string(),
|
|
52988
53693
|
installed: boolean(),
|
|
52989
|
-
installedVersion: string().optional()
|
|
53694
|
+
installedVersion: string().optional(),
|
|
53695
|
+
/**
|
|
53696
|
+
* Capability names the package's addons declare (from its published
|
|
53697
|
+
* manifest). `null` = the registry lookup failed — unknown, never `[]` (D393).
|
|
53698
|
+
*/
|
|
53699
|
+
capabilities: array(string()).readonly().nullable()
|
|
52990
53700
|
});
|
|
52991
53701
|
var AutoUpdateSettingsSchema = object({
|
|
52992
53702
|
channel: ChannelSchema,
|
|
@@ -53148,7 +53858,11 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
53148
53858
|
}), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
|
|
53149
53859
|
kind: "mutation",
|
|
53150
53860
|
auth: "admin"
|
|
53151
|
-
}), method(object({
|
|
53861
|
+
}), method(object({
|
|
53862
|
+
query: string().optional(),
|
|
53863
|
+
/** Only packages whose addons declare this capability (unknown ones excluded). */
|
|
53864
|
+
capability: string().optional()
|
|
53865
|
+
}), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
|
|
53152
53866
|
name: string().min(1),
|
|
53153
53867
|
version: string().optional(),
|
|
53154
53868
|
nodeId: string().optional()
|
|
@@ -53284,6 +53998,36 @@ var airQualitySensorCapability = {
|
|
|
53284
53998
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53285
53999
|
*/
|
|
53286
54000
|
durability: "restored",
|
|
54001
|
+
/**
|
|
54002
|
+
* History (D850): recorded series.
|
|
54003
|
+
*/
|
|
54004
|
+
history: { fields: {
|
|
54005
|
+
co2Ppm: {
|
|
54006
|
+
kind: "gauge",
|
|
54007
|
+
unit: "ppm",
|
|
54008
|
+
deadband: 5
|
|
54009
|
+
},
|
|
54010
|
+
vocPpb: {
|
|
54011
|
+
kind: "gauge",
|
|
54012
|
+
unit: "ppb",
|
|
54013
|
+
deadband: 5
|
|
54014
|
+
},
|
|
54015
|
+
pm25: {
|
|
54016
|
+
kind: "gauge",
|
|
54017
|
+
unit: "ug/m3",
|
|
54018
|
+
deadband: 1
|
|
54019
|
+
},
|
|
54020
|
+
pm10: {
|
|
54021
|
+
kind: "gauge",
|
|
54022
|
+
unit: "ug/m3",
|
|
54023
|
+
deadband: 1
|
|
54024
|
+
},
|
|
54025
|
+
aqi: {
|
|
54026
|
+
kind: "gauge",
|
|
54027
|
+
unit: "count",
|
|
54028
|
+
deadband: 1
|
|
54029
|
+
}
|
|
54030
|
+
} },
|
|
53287
54031
|
/** Clock fields: written, but excluded from the compare that decides
|
|
53288
54032
|
* whether persisting is worth a SQLite commit. */
|
|
53289
54033
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -53326,6 +54070,15 @@ var ambientLightSensorCapability = {
|
|
|
53326
54070
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53327
54071
|
*/
|
|
53328
54072
|
durability: "restored",
|
|
54073
|
+
/**
|
|
54074
|
+
* History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
|
|
54075
|
+
*/
|
|
54076
|
+
history: { fields: { lux: {
|
|
54077
|
+
kind: "gauge",
|
|
54078
|
+
unit: "lx",
|
|
54079
|
+
deadbandPct: 10,
|
|
54080
|
+
minIntervalMs: 6e4
|
|
54081
|
+
} } },
|
|
53329
54082
|
/** Clock fields: written, but excluded from the compare that decides
|
|
53330
54083
|
* whether persisting is worth a SQLite commit. */
|
|
53331
54084
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -53453,7 +54206,11 @@ var audioMetricsCapability = {
|
|
|
53453
54206
|
* See `RuntimeStateDurability`. Enforced by
|
|
53454
54207
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53455
54208
|
*/
|
|
53456
|
-
durability: "session"
|
|
54209
|
+
durability: "session",
|
|
54210
|
+
/**
|
|
54211
|
+
* 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.
|
|
54212
|
+
*/
|
|
54213
|
+
history: "none"
|
|
53457
54214
|
};
|
|
53458
54215
|
/**
|
|
53459
54216
|
* Automation-control cap. Models HA `automation.*` entities on
|
|
@@ -53522,7 +54279,11 @@ var automationControlCapability = {
|
|
|
53522
54279
|
* See `RuntimeStateDurability`. Enforced by
|
|
53523
54280
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53524
54281
|
*/
|
|
53525
|
-
durability: "session"
|
|
54282
|
+
durability: "session",
|
|
54283
|
+
/**
|
|
54284
|
+
* History (D850): none — configuration and transient run state.
|
|
54285
|
+
*/
|
|
54286
|
+
history: "none"
|
|
53526
54287
|
};
|
|
53527
54288
|
/**
|
|
53528
54289
|
* Battery status snapshot. Emitted by providers whose device is
|
|
@@ -53703,6 +54464,13 @@ onStatusChanged: { data: object({
|
|
|
53703
54464
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53704
54465
|
*/
|
|
53705
54466
|
durability: "restored",
|
|
54467
|
+
/**
|
|
54468
|
+
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
54469
|
+
*/
|
|
54470
|
+
history: { fields: { percentage: {
|
|
54471
|
+
kind: "gauge",
|
|
54472
|
+
unit: "%"
|
|
54473
|
+
} } },
|
|
53706
54474
|
/** Clock fields: written, but excluded from the compare that decides
|
|
53707
54475
|
* whether persisting is worth a SQLite commit. */
|
|
53708
54476
|
volatileStateFields: ["lastUpdated"]
|
|
@@ -53742,6 +54510,10 @@ var binaryCapability = {
|
|
|
53742
54510
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53743
54511
|
*/
|
|
53744
54512
|
durability: "restored",
|
|
54513
|
+
/**
|
|
54514
|
+
* History (D850): recorded series.
|
|
54515
|
+
*/
|
|
54516
|
+
history: { fields: { on: { kind: "boolean" } } },
|
|
53745
54517
|
/** Clock fields: written, but excluded from the compare that decides
|
|
53746
54518
|
* whether persisting is worth a SQLite commit. */
|
|
53747
54519
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -53804,7 +54576,15 @@ onBrightnessChanged: { data: object({
|
|
|
53804
54576
|
* See `RuntimeStateDurability`. Enforced by
|
|
53805
54577
|
* `scripts/check-runtime-state-durability.ts`.
|
|
53806
54578
|
*/
|
|
53807
|
-
durability: "session"
|
|
54579
|
+
durability: "session",
|
|
54580
|
+
/**
|
|
54581
|
+
* History (D850): recorded series. Actuator tier: level keeps every change.
|
|
54582
|
+
*/
|
|
54583
|
+
history: { fields: { percentage: {
|
|
54584
|
+
kind: "gauge",
|
|
54585
|
+
unit: "%",
|
|
54586
|
+
minIntervalMs: 0
|
|
54587
|
+
} } }
|
|
53808
54588
|
};
|
|
53809
54589
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
53810
54590
|
kind: "mutation",
|
|
@@ -54138,6 +54918,10 @@ var carbonMonoxideCapability = {
|
|
|
54138
54918
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54139
54919
|
*/
|
|
54140
54920
|
durability: "restored",
|
|
54921
|
+
/**
|
|
54922
|
+
* History (D850): recorded series.
|
|
54923
|
+
*/
|
|
54924
|
+
history: { fields: { detected: { kind: "boolean" } } },
|
|
54141
54925
|
/** Clock fields: written, but excluded from the compare that decides
|
|
54142
54926
|
* whether persisting is worth a SQLite commit. */
|
|
54143
54927
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -54307,7 +55091,37 @@ var climateControlCapability = {
|
|
|
54307
55091
|
* See `RuntimeStateDurability`. Enforced by
|
|
54308
55092
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54309
55093
|
*/
|
|
54310
|
-
durability: "session"
|
|
55094
|
+
durability: "session",
|
|
55095
|
+
/**
|
|
55096
|
+
* History (D850): recorded series. Celsius by contract; setpoints keep every change (`minIntervalMs: 0`).
|
|
55097
|
+
*/
|
|
55098
|
+
history: { fields: {
|
|
55099
|
+
currentTemp: {
|
|
55100
|
+
kind: "gauge",
|
|
55101
|
+
unit: "°C",
|
|
55102
|
+
deadband: .1
|
|
55103
|
+
},
|
|
55104
|
+
currentHumidity: {
|
|
55105
|
+
kind: "gauge",
|
|
55106
|
+
unit: "%",
|
|
55107
|
+
deadband: .5
|
|
55108
|
+
},
|
|
55109
|
+
target: {
|
|
55110
|
+
kind: "gauge",
|
|
55111
|
+
unit: "°C",
|
|
55112
|
+
minIntervalMs: 0
|
|
55113
|
+
},
|
|
55114
|
+
targetHigh: {
|
|
55115
|
+
kind: "gauge",
|
|
55116
|
+
unit: "°C",
|
|
55117
|
+
minIntervalMs: 0
|
|
55118
|
+
},
|
|
55119
|
+
targetLow: {
|
|
55120
|
+
kind: "gauge",
|
|
55121
|
+
unit: "°C",
|
|
55122
|
+
minIntervalMs: 0
|
|
55123
|
+
}
|
|
55124
|
+
} }
|
|
54311
55125
|
};
|
|
54312
55126
|
/**
|
|
54313
55127
|
* Color-light cap. Coexists with `switch` (on/off) and `brightness`
|
|
@@ -54424,7 +55238,11 @@ onColorChanged: { data: object({
|
|
|
54424
55238
|
* See `RuntimeStateDurability`. Enforced by
|
|
54425
55239
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54426
55240
|
*/
|
|
54427
|
-
durability: "session"
|
|
55241
|
+
durability: "session",
|
|
55242
|
+
/**
|
|
55243
|
+
* History (D850): none — nested and cosmetic.
|
|
55244
|
+
*/
|
|
55245
|
+
history: "none"
|
|
54428
55246
|
};
|
|
54429
55247
|
var ConnectionTestOutcomeSchema = discriminatedUnion("outcome", [
|
|
54430
55248
|
object({
|
|
@@ -54490,6 +55308,10 @@ var connectivityCapability = {
|
|
|
54490
55308
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54491
55309
|
*/
|
|
54492
55310
|
durability: "restored",
|
|
55311
|
+
/**
|
|
55312
|
+
* History (D850): none — duplicates device-status.online (one authority for availability).
|
|
55313
|
+
*/
|
|
55314
|
+
history: "none",
|
|
54493
55315
|
/** Clock fields: written, but excluded from the compare that decides
|
|
54494
55316
|
* whether persisting is worth a SQLite commit. */
|
|
54495
55317
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -54614,6 +55436,10 @@ reset: method(object({
|
|
|
54614
55436
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54615
55437
|
*/
|
|
54616
55438
|
durability: "restored",
|
|
55439
|
+
/**
|
|
55440
|
+
* History (D850): none — `items` is an array keyed by runtime ids; a history path never enters it.
|
|
55441
|
+
*/
|
|
55442
|
+
history: "none",
|
|
54617
55443
|
/** Clocks, not content: a re-read that changed no item costs no commit. */
|
|
54618
55444
|
volatileStateFields: ["lastChangedAt", "lastFetchedAt"]
|
|
54619
55445
|
};
|
|
@@ -54654,6 +55480,10 @@ var contactCapability = {
|
|
|
54654
55480
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54655
55481
|
*/
|
|
54656
55482
|
durability: "restored",
|
|
55483
|
+
/**
|
|
55484
|
+
* History (D850): recorded series.
|
|
55485
|
+
*/
|
|
55486
|
+
history: { fields: { entryOpen: { kind: "boolean" } } },
|
|
54657
55487
|
/** Clock fields: written, but excluded from the compare that decides
|
|
54658
55488
|
* whether persisting is worth a SQLite commit. */
|
|
54659
55489
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -54769,7 +55599,11 @@ var controlCapability = {
|
|
|
54769
55599
|
* See `RuntimeStateDurability`. Enforced by
|
|
54770
55600
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54771
55601
|
*/
|
|
54772
|
-
durability: "session"
|
|
55602
|
+
durability: "session",
|
|
55603
|
+
/**
|
|
55604
|
+
* History (D850): none — `value` is a number/string union; configuration entity.
|
|
55605
|
+
*/
|
|
55606
|
+
history: "none"
|
|
54773
55607
|
};
|
|
54774
55608
|
var CoverStatusSchema = object({
|
|
54775
55609
|
/** Lifecycle state of the cover. */
|
|
@@ -54838,6 +55672,14 @@ var coverCapability = {
|
|
|
54838
55672
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54839
55673
|
*/
|
|
54840
55674
|
durability: "restored",
|
|
55675
|
+
/**
|
|
55676
|
+
* History (D850): recorded series. Actuator tier: position keeps every tick of a movement.
|
|
55677
|
+
*/
|
|
55678
|
+
history: { fields: { position: {
|
|
55679
|
+
kind: "gauge",
|
|
55680
|
+
unit: "%",
|
|
55681
|
+
minIntervalMs: 0
|
|
55682
|
+
} } },
|
|
54841
55683
|
/** Clock fields: written, but excluded from the compare that decides
|
|
54842
55684
|
* whether persisting is worth a SQLite commit. */
|
|
54843
55685
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -54942,6 +55784,10 @@ var dayNightCapability = {
|
|
|
54942
55784
|
* `scripts/check-runtime-state-durability.ts`.
|
|
54943
55785
|
*/
|
|
54944
55786
|
durability: "restored",
|
|
55787
|
+
/**
|
|
55788
|
+
* History (D850): none — firmware configuration, not a measurement.
|
|
55789
|
+
*/
|
|
55790
|
+
history: "none",
|
|
54945
55791
|
/** Clock fields: written, but excluded from the compare that decides
|
|
54946
55792
|
* whether persisting is worth a SQLite commit. */
|
|
54947
55793
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -54999,6 +55845,10 @@ onStatusChanged: { data: object({
|
|
|
54999
55845
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55000
55846
|
*/
|
|
55001
55847
|
durability: "restored",
|
|
55848
|
+
/**
|
|
55849
|
+
* History (D850): recorded series. The ONE availability series.
|
|
55850
|
+
*/
|
|
55851
|
+
history: { fields: { online: { kind: "boolean" } } },
|
|
55002
55852
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55003
55853
|
* whether persisting is worth a SQLite commit. */
|
|
55004
55854
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -55065,7 +55915,11 @@ onPressed: {
|
|
|
55065
55915
|
* See `RuntimeStateDurability`. Enforced by
|
|
55066
55916
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55067
55917
|
*/
|
|
55068
|
-
durability: "restored"
|
|
55918
|
+
durability: "restored",
|
|
55919
|
+
/**
|
|
55920
|
+
* History (D850): none — `pressCountSinceStart` resets with the addon, so it is not a monotonic meter; presses live in the events ledger.
|
|
55921
|
+
*/
|
|
55922
|
+
history: "none"
|
|
55069
55923
|
};
|
|
55070
55924
|
/**
|
|
55071
55925
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
@@ -55113,6 +55967,10 @@ var enumSensorCapability = {
|
|
|
55113
55967
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55114
55968
|
*/
|
|
55115
55969
|
durability: "restored",
|
|
55970
|
+
/**
|
|
55971
|
+
* History (D850): none — text/enum state has no history (non-goal).
|
|
55972
|
+
*/
|
|
55973
|
+
history: "none",
|
|
55116
55974
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55117
55975
|
* whether persisting is worth a SQLite commit. */
|
|
55118
55976
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -55158,7 +56016,11 @@ var eventEmitterCapability = {
|
|
|
55158
56016
|
* See `RuntimeStateDurability`. Enforced by
|
|
55159
56017
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55160
56018
|
*/
|
|
55161
|
-
durability: "session"
|
|
56019
|
+
durability: "session",
|
|
56020
|
+
/**
|
|
56021
|
+
* History (D850): none — `eventCountSinceStart` resets with the addon; events live in ledgers.
|
|
56022
|
+
*/
|
|
56023
|
+
history: "none"
|
|
55162
56024
|
};
|
|
55163
56025
|
var IdentitySchema = object({
|
|
55164
56026
|
id: string(),
|
|
@@ -55615,7 +56477,18 @@ var fanControlCapability = {
|
|
|
55615
56477
|
* See `RuntimeStateDurability`. Enforced by
|
|
55616
56478
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55617
56479
|
*/
|
|
55618
|
-
durability: "session"
|
|
56480
|
+
durability: "session",
|
|
56481
|
+
/**
|
|
56482
|
+
* History (D850): recorded series. Actuator tier: speed keeps every change.
|
|
56483
|
+
*/
|
|
56484
|
+
history: { fields: {
|
|
56485
|
+
percentage: {
|
|
56486
|
+
kind: "gauge",
|
|
56487
|
+
unit: "%",
|
|
56488
|
+
minIntervalMs: 0
|
|
56489
|
+
},
|
|
56490
|
+
oscillating: { kind: "boolean" }
|
|
56491
|
+
} }
|
|
55619
56492
|
};
|
|
55620
56493
|
/**
|
|
55621
56494
|
* Per-device feature/identity probe slice. Holds the runtime-resolved
|
|
@@ -55698,7 +56571,11 @@ onProbeChanged: { data: object({
|
|
|
55698
56571
|
* See `RuntimeStateDurability`. Enforced by
|
|
55699
56572
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55700
56573
|
*/
|
|
55701
|
-
durability: "session"
|
|
56574
|
+
durability: "session",
|
|
56575
|
+
/**
|
|
56576
|
+
* History (D850): none — static identity and capability probe.
|
|
56577
|
+
*/
|
|
56578
|
+
history: "none"
|
|
55702
56579
|
};
|
|
55703
56580
|
/**
|
|
55704
56581
|
* Water leak / moisture sensor. Boolean "is liquid currently
|
|
@@ -55733,6 +56610,10 @@ var floodCapability = {
|
|
|
55733
56610
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55734
56611
|
*/
|
|
55735
56612
|
durability: "restored",
|
|
56613
|
+
/**
|
|
56614
|
+
* History (D850): recorded series.
|
|
56615
|
+
*/
|
|
56616
|
+
history: { fields: { flooded: { kind: "boolean" } } },
|
|
55736
56617
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55737
56618
|
* whether persisting is worth a SQLite commit. */
|
|
55738
56619
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -55766,6 +56647,10 @@ var gasCapability = {
|
|
|
55766
56647
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55767
56648
|
*/
|
|
55768
56649
|
durability: "restored",
|
|
56650
|
+
/**
|
|
56651
|
+
* History (D850): recorded series.
|
|
56652
|
+
*/
|
|
56653
|
+
history: { fields: { detected: { kind: "boolean" } } },
|
|
55769
56654
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55770
56655
|
* whether persisting is worth a SQLite commit. */
|
|
55771
56656
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -55851,7 +56736,18 @@ var humidifierCapability = {
|
|
|
55851
56736
|
* See `RuntimeStateDurability`. Enforced by
|
|
55852
56737
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55853
56738
|
*/
|
|
55854
|
-
durability: "session"
|
|
56739
|
+
durability: "session",
|
|
56740
|
+
/**
|
|
56741
|
+
* History (D850): recorded series.
|
|
56742
|
+
*/
|
|
56743
|
+
history: { fields: {
|
|
56744
|
+
currentHumidity: {
|
|
56745
|
+
kind: "gauge",
|
|
56746
|
+
unit: "%",
|
|
56747
|
+
deadband: .5
|
|
56748
|
+
},
|
|
56749
|
+
on: { kind: "boolean" }
|
|
56750
|
+
} }
|
|
55855
56751
|
};
|
|
55856
56752
|
/**
|
|
55857
56753
|
* Single-metric humidity reading. Drives Home Assistant `sensor`
|
|
@@ -55895,6 +56791,14 @@ var humiditySensorCapability = {
|
|
|
55895
56791
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55896
56792
|
*/
|
|
55897
56793
|
durability: "restored",
|
|
56794
|
+
/**
|
|
56795
|
+
* History (D850): recorded series.
|
|
56796
|
+
*/
|
|
56797
|
+
history: { fields: { percent: {
|
|
56798
|
+
kind: "gauge",
|
|
56799
|
+
unit: "%",
|
|
56800
|
+
deadband: .5
|
|
56801
|
+
} } },
|
|
55898
56802
|
/** Clock fields: written, but excluded from the compare that decides
|
|
55899
56803
|
* whether persisting is worth a SQLite commit. */
|
|
55900
56804
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -55942,7 +56846,11 @@ var imageCapability = {
|
|
|
55942
56846
|
* See `RuntimeStateDurability`. Enforced by
|
|
55943
56847
|
* `scripts/check-runtime-state-durability.ts`.
|
|
55944
56848
|
*/
|
|
55945
|
-
durability: "session"
|
|
56849
|
+
durability: "session",
|
|
56850
|
+
/**
|
|
56851
|
+
* History (D850): none — not numeric.
|
|
56852
|
+
*/
|
|
56853
|
+
history: "none"
|
|
55946
56854
|
};
|
|
55947
56855
|
/**
|
|
55948
56856
|
* Vendor-neutral image / picture-adjustment cap — the per-camera config
|
|
@@ -56099,6 +57007,10 @@ var imageSettingsCapability = {
|
|
|
56099
57007
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56100
57008
|
*/
|
|
56101
57009
|
durability: "restored",
|
|
57010
|
+
/**
|
|
57011
|
+
* History (D850): none — camera image configuration (operator intent), not a trend.
|
|
57012
|
+
*/
|
|
57013
|
+
history: "none",
|
|
56102
57014
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56103
57015
|
* whether persisting is worth a SQLite commit. */
|
|
56104
57016
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -56484,7 +57396,11 @@ var intercomCapability = {
|
|
|
56484
57396
|
* See `RuntimeStateDurability`. Enforced by
|
|
56485
57397
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56486
57398
|
*/
|
|
56487
|
-
durability: "session"
|
|
57399
|
+
durability: "session",
|
|
57400
|
+
/**
|
|
57401
|
+
* History (D850): none — talk sessions are a ledger concern, not a trend.
|
|
57402
|
+
*/
|
|
57403
|
+
history: "none"
|
|
56488
57404
|
};
|
|
56489
57405
|
/**
|
|
56490
57406
|
* Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
|
|
@@ -56565,7 +57481,15 @@ var lawnMowerControlCapability = {
|
|
|
56565
57481
|
* See `RuntimeStateDurability`. Enforced by
|
|
56566
57482
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56567
57483
|
*/
|
|
56568
|
-
durability: "session"
|
|
57484
|
+
durability: "session",
|
|
57485
|
+
/**
|
|
57486
|
+
* History (D850): recorded series.
|
|
57487
|
+
*/
|
|
57488
|
+
history: { fields: { batteryLevel: {
|
|
57489
|
+
kind: "gauge",
|
|
57490
|
+
unit: "%",
|
|
57491
|
+
deadband: 2
|
|
57492
|
+
} } }
|
|
56569
57493
|
};
|
|
56570
57494
|
/**
|
|
56571
57495
|
* local-network — hub-only singleton.
|
|
@@ -56692,7 +57616,13 @@ var ConnectionEndpointSchema = object({
|
|
|
56692
57616
|
* calls so the client can sort even if the cap returns a new
|
|
56693
57617
|
* ordering between polls.
|
|
56694
57618
|
*/
|
|
56695
|
-
priority: number()
|
|
57619
|
+
priority: number(),
|
|
57620
|
+
/**
|
|
57621
|
+
* `false` = the address changes on its own (a Quick tunnel, re-issued on
|
|
57622
|
+
* every respawn). Automatic role resolution skips it (D860); an explicit
|
|
57623
|
+
* operator flag still honours it. Absent = stable.
|
|
57624
|
+
*/
|
|
57625
|
+
stable: boolean().optional()
|
|
56696
57626
|
});
|
|
56697
57627
|
/**
|
|
56698
57628
|
* Where the advertised local port came from. Ordered most → least
|
|
@@ -56972,6 +57902,10 @@ var lockControlCapability = {
|
|
|
56972
57902
|
* `scripts/check-runtime-state-durability.ts`.
|
|
56973
57903
|
*/
|
|
56974
57904
|
durability: "restored",
|
|
57905
|
+
/**
|
|
57906
|
+
* History (D850): none — enum state; lock events belong in the events ledger.
|
|
57907
|
+
*/
|
|
57908
|
+
history: "none",
|
|
56975
57909
|
/** Clock fields: written, but excluded from the compare that decides
|
|
56976
57910
|
* whether persisting is worth a SQLite commit. */
|
|
56977
57911
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -57143,7 +58077,11 @@ var mediaPlayerCapability = {
|
|
|
57143
58077
|
* See `RuntimeStateDurability`. Enforced by
|
|
57144
58078
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57145
58079
|
*/
|
|
57146
|
-
durability: "session"
|
|
58080
|
+
durability: "session",
|
|
58081
|
+
/**
|
|
58082
|
+
* History (D850): none — `positionMs` moves continuously while playing; volume is transient.
|
|
58083
|
+
*/
|
|
58084
|
+
history: "none"
|
|
57147
58085
|
};
|
|
57148
58086
|
/**
|
|
57149
58087
|
* mesh-network — collection cap for mesh-VPN providers.
|
|
@@ -57452,7 +58390,14 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
|
|
|
57452
58390
|
* See `RuntimeStateDurability`. Enforced by
|
|
57453
58391
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57454
58392
|
*/
|
|
57455
|
-
durability: "session"
|
|
58393
|
+
durability: "session",
|
|
58394
|
+
/**
|
|
58395
|
+
* History (D850): recorded series. A PIR sensor is a series; a camera is not (its motion is an addon series and a ledger).
|
|
58396
|
+
*/
|
|
58397
|
+
history: { fields: { detected: {
|
|
58398
|
+
kind: "boolean",
|
|
58399
|
+
excludeDeviceTypes: [DeviceType.Camera]
|
|
58400
|
+
} } }
|
|
57456
58401
|
};
|
|
57457
58402
|
/**
|
|
57458
58403
|
* Motion-trigger toggle for accessory devices.
|
|
@@ -57524,7 +58469,11 @@ var motionTriggerCapability = {
|
|
|
57524
58469
|
* See `RuntimeStateDurability`. Enforced by
|
|
57525
58470
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57526
58471
|
*/
|
|
57527
|
-
durability: "session"
|
|
58472
|
+
durability: "session",
|
|
58473
|
+
/**
|
|
58474
|
+
* History (D850): none — configuration switch.
|
|
58475
|
+
*/
|
|
58476
|
+
history: "none"
|
|
57528
58477
|
};
|
|
57529
58478
|
/**
|
|
57530
58479
|
* Motion-zones share the same MaskShape vocabulary as privacy-mask — the
|
|
@@ -57599,6 +58548,10 @@ var motionZonesCapability = {
|
|
|
57599
58548
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57600
58549
|
*/
|
|
57601
58550
|
durability: "restored",
|
|
58551
|
+
/**
|
|
58552
|
+
* History (D850): none — configuration.
|
|
58553
|
+
*/
|
|
58554
|
+
history: "none",
|
|
57602
58555
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57603
58556
|
* whether persisting is worth a SQLite commit. */
|
|
57604
58557
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -57728,6 +58681,10 @@ var nativeObjectDetectionCapability = {
|
|
|
57728
58681
|
* `scripts/check-runtime-state-durability.ts`.
|
|
57729
58682
|
*/
|
|
57730
58683
|
durability: "restored",
|
|
58684
|
+
/**
|
|
58685
|
+
* History (D850): none — event-like and nested per class; detections live in the objects ledger.
|
|
58686
|
+
*/
|
|
58687
|
+
history: "none",
|
|
57731
58688
|
/** Clock fields: written, but excluded from the compare that decides
|
|
57732
58689
|
* whether persisting is worth a SQLite commit. */
|
|
57733
58690
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -58011,7 +58968,11 @@ var navigationCapability = {
|
|
|
58011
58968
|
* See `RuntimeStateDurability`. Enforced by
|
|
58012
58969
|
* `scripts/check-runtime-state-durability.ts`.
|
|
58013
58970
|
*/
|
|
58014
|
-
durability: "session"
|
|
58971
|
+
durability: "session",
|
|
58972
|
+
/**
|
|
58973
|
+
* History (D850): none — control state of a robotic camera, configuration-like.
|
|
58974
|
+
*/
|
|
58975
|
+
history: "none"
|
|
58015
58976
|
};
|
|
58016
58977
|
/**
|
|
58017
58978
|
* Network-link snapshot. Same shape for every provider (a Reolink wifi
|
|
@@ -58111,6 +59072,23 @@ onStatusChanged: { data: object({
|
|
|
58111
59072
|
* `scripts/check-runtime-state-durability.ts`.
|
|
58112
59073
|
*/
|
|
58113
59074
|
durability: "restored",
|
|
59075
|
+
/**
|
|
59076
|
+
* History (D850): recorded series.
|
|
59077
|
+
*/
|
|
59078
|
+
history: { fields: {
|
|
59079
|
+
signalPercent: {
|
|
59080
|
+
kind: "gauge",
|
|
59081
|
+
unit: "%",
|
|
59082
|
+
deadband: 3,
|
|
59083
|
+
minIntervalMs: 6e4
|
|
59084
|
+
},
|
|
59085
|
+
rssiDbm: {
|
|
59086
|
+
kind: "gauge",
|
|
59087
|
+
unit: "dBm",
|
|
59088
|
+
deadband: 2,
|
|
59089
|
+
minIntervalMs: 6e4
|
|
59090
|
+
}
|
|
59091
|
+
} },
|
|
58114
59092
|
/** Clock fields: written, but excluded from the compare that decides
|
|
58115
59093
|
* whether persisting is worth a SQLite commit. */
|
|
58116
59094
|
volatileStateFields: ["lastUpdated"]
|
|
@@ -58499,7 +59477,11 @@ onSent: { data: object({
|
|
|
58499
59477
|
* See `RuntimeStateDurability`. Enforced by
|
|
58500
59478
|
* `scripts/check-runtime-state-durability.ts`.
|
|
58501
59479
|
*/
|
|
58502
|
-
durability: "session"
|
|
59480
|
+
durability: "session",
|
|
59481
|
+
/**
|
|
59482
|
+
* History (D850): none — `queueDepth` is outbox operational state, not a device trend.
|
|
59483
|
+
*/
|
|
59484
|
+
history: "none"
|
|
58503
59485
|
};
|
|
58504
59486
|
/**
|
|
58505
59487
|
* Generic numeric sensor — last-resort fallback when no typed numeric
|
|
@@ -58550,6 +59532,14 @@ var numericSensorCapability = {
|
|
|
58550
59532
|
* `scripts/check-runtime-state-durability.ts`.
|
|
58551
59533
|
*/
|
|
58552
59534
|
durability: "restored",
|
|
59535
|
+
/**
|
|
59536
|
+
* History (D850): recorded series. The unit is per device, read from the sibling `unit` field.
|
|
59537
|
+
*/
|
|
59538
|
+
history: { fields: { value: {
|
|
59539
|
+
kind: "gauge",
|
|
59540
|
+
unitFrom: "unit",
|
|
59541
|
+
minIntervalMs: 3e4
|
|
59542
|
+
} } },
|
|
58553
59543
|
/** Clock fields: written, but excluded from the compare that decides
|
|
58554
59544
|
* whether persisting is worth a SQLite commit. */
|
|
58555
59545
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -59026,7 +60016,24 @@ var petFeederCapability = {
|
|
|
59026
60016
|
* See `RuntimeStateDurability`. Enforced by
|
|
59027
60017
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59028
60018
|
*/
|
|
59029
|
-
durability: "session"
|
|
60019
|
+
durability: "session",
|
|
60020
|
+
/**
|
|
60021
|
+
* History (D850): recorded series.
|
|
60022
|
+
*/
|
|
60023
|
+
history: { fields: {
|
|
60024
|
+
foodLevel: { kind: "gauge" },
|
|
60025
|
+
food1: { kind: "gauge" },
|
|
60026
|
+
food2: { kind: "gauge" },
|
|
60027
|
+
batteryPower: {
|
|
60028
|
+
kind: "gauge",
|
|
60029
|
+
unit: "%",
|
|
60030
|
+
deadband: 2
|
|
60031
|
+
},
|
|
60032
|
+
desiccantLeftDays: {
|
|
60033
|
+
kind: "gauge",
|
|
60034
|
+
unit: "days"
|
|
60035
|
+
}
|
|
60036
|
+
} }
|
|
59030
60037
|
};
|
|
59031
60038
|
var VehicleSchema = object({
|
|
59032
60039
|
id: string(),
|
|
@@ -59404,6 +60411,47 @@ var powerMeterCapability = {
|
|
|
59404
60411
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59405
60412
|
*/
|
|
59406
60413
|
durability: "restored",
|
|
60414
|
+
/**
|
|
60415
|
+
* History (D850): recorded series. Gauges are floored at 30 s; `kwhTotal` is the one monotonic meter (counter).
|
|
60416
|
+
*/
|
|
60417
|
+
history: { fields: {
|
|
60418
|
+
watts: {
|
|
60419
|
+
kind: "gauge",
|
|
60420
|
+
unit: "W",
|
|
60421
|
+
deadband: 1,
|
|
60422
|
+
minIntervalMs: 3e4
|
|
60423
|
+
},
|
|
60424
|
+
kwhTotal: {
|
|
60425
|
+
kind: "counter",
|
|
60426
|
+
unit: "kWh",
|
|
60427
|
+
deadband: .01,
|
|
60428
|
+
minIntervalMs: 6e4
|
|
60429
|
+
},
|
|
60430
|
+
volts: {
|
|
60431
|
+
kind: "gauge",
|
|
60432
|
+
unit: "V",
|
|
60433
|
+
deadband: 1,
|
|
60434
|
+
minIntervalMs: 3e4
|
|
60435
|
+
},
|
|
60436
|
+
amps: {
|
|
60437
|
+
kind: "gauge",
|
|
60438
|
+
unit: "A",
|
|
60439
|
+
deadband: .05,
|
|
60440
|
+
minIntervalMs: 3e4
|
|
60441
|
+
},
|
|
60442
|
+
va: {
|
|
60443
|
+
kind: "gauge",
|
|
60444
|
+
unit: "VA",
|
|
60445
|
+
deadband: 1,
|
|
60446
|
+
minIntervalMs: 3e4
|
|
60447
|
+
},
|
|
60448
|
+
powerFactor: {
|
|
60449
|
+
kind: "gauge",
|
|
60450
|
+
unit: "ratio",
|
|
60451
|
+
deadband: .01,
|
|
60452
|
+
minIntervalMs: 6e4
|
|
60453
|
+
}
|
|
60454
|
+
} },
|
|
59407
60455
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59408
60456
|
* whether persisting is worth a SQLite commit. */
|
|
59409
60457
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -59471,6 +60519,14 @@ var presenceCapability = {
|
|
|
59471
60519
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59472
60520
|
*/
|
|
59473
60521
|
durability: "restored",
|
|
60522
|
+
/**
|
|
60523
|
+
* History (D850): recorded series.
|
|
60524
|
+
*/
|
|
60525
|
+
history: { fields: { batteryPercent: {
|
|
60526
|
+
kind: "gauge",
|
|
60527
|
+
unit: "%",
|
|
60528
|
+
deadband: 1
|
|
60529
|
+
} } },
|
|
59474
60530
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59475
60531
|
* whether persisting is worth a SQLite commit. */
|
|
59476
60532
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -59517,6 +60573,14 @@ var pressureSensorCapability = {
|
|
|
59517
60573
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59518
60574
|
*/
|
|
59519
60575
|
durability: "restored",
|
|
60576
|
+
/**
|
|
60577
|
+
* History (D850): recorded series.
|
|
60578
|
+
*/
|
|
60579
|
+
history: { fields: { hpa: {
|
|
60580
|
+
kind: "gauge",
|
|
60581
|
+
unit: "hPa",
|
|
60582
|
+
deadband: .1
|
|
60583
|
+
} } },
|
|
59520
60584
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59521
60585
|
* whether persisting is worth a SQLite commit. */
|
|
59522
60586
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -59676,6 +60740,10 @@ var privacyMaskCapability = {
|
|
|
59676
60740
|
* `scripts/check-runtime-state-durability.ts`.
|
|
59677
60741
|
*/
|
|
59678
60742
|
durability: "restored",
|
|
60743
|
+
/**
|
|
60744
|
+
* History (D850): none — configuration.
|
|
60745
|
+
*/
|
|
60746
|
+
history: "none",
|
|
59679
60747
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59680
60748
|
* whether persisting is worth a SQLite commit. */
|
|
59681
60749
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -60149,7 +61217,11 @@ var ptzAutotrackCapability = {
|
|
|
60149
61217
|
* See `RuntimeStateDurability`. Enforced by
|
|
60150
61218
|
* `scripts/check-runtime-state-durability.ts`.
|
|
60151
61219
|
*/
|
|
60152
|
-
durability: "session"
|
|
61220
|
+
durability: "session",
|
|
61221
|
+
/**
|
|
61222
|
+
* History (D850): none — configuration and capability.
|
|
61223
|
+
*/
|
|
61224
|
+
history: "none"
|
|
60153
61225
|
};
|
|
60154
61226
|
/**
|
|
60155
61227
|
* reboot — device-scoped capability for "soft" device reboots (firmware
|
|
@@ -61604,6 +62676,10 @@ var recordingOnboardCapability = {
|
|
|
61604
62676
|
* `scripts/check-runtime-state-durability.ts`.
|
|
61605
62677
|
*/
|
|
61606
62678
|
durability: "restored",
|
|
62679
|
+
/**
|
|
62680
|
+
* History (D850): none — SD-card configuration and window inventory; arrays.
|
|
62681
|
+
*/
|
|
62682
|
+
history: "none",
|
|
61607
62683
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61608
62684
|
* whether persisting is worth a SQLite commit. */
|
|
61609
62685
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -61842,7 +62918,11 @@ getStatus: method(object({ deviceId: number() }), RecordingSignalStatusSchema) }
|
|
|
61842
62918
|
* See `RuntimeStateDurability`. Enforced by
|
|
61843
62919
|
* `scripts/check-runtime-state-durability.ts`.
|
|
61844
62920
|
*/
|
|
61845
|
-
durability: "session"
|
|
62921
|
+
durability: "session",
|
|
62922
|
+
/**
|
|
62923
|
+
* History (D850): none — recording intent is already in the recordings ledger.
|
|
62924
|
+
*/
|
|
62925
|
+
history: "none"
|
|
61846
62926
|
};
|
|
61847
62927
|
/**
|
|
61848
62928
|
* scene-monitor — device-scoped reference-region state cap. An operator marks
|
|
@@ -62215,7 +63295,11 @@ var sceneMonitorCapability = {
|
|
|
62215
63295
|
* See `RuntimeStateDurability`. Enforced by
|
|
62216
63296
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62217
63297
|
*/
|
|
62218
|
-
durability: "session"
|
|
63298
|
+
durability: "session",
|
|
63299
|
+
/**
|
|
63300
|
+
* History (D850): none — nested configuration.
|
|
63301
|
+
*/
|
|
63302
|
+
history: "none"
|
|
62219
63303
|
};
|
|
62220
63304
|
/**
|
|
62221
63305
|
* Per-stage gating mode applied to the zones a rule references.
|
|
@@ -62366,7 +63450,11 @@ var scriptRunnerCapability = {
|
|
|
62366
63450
|
* See `RuntimeStateDurability`. Enforced by
|
|
62367
63451
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62368
63452
|
*/
|
|
62369
|
-
durability: "session"
|
|
63453
|
+
durability: "session",
|
|
63454
|
+
/**
|
|
63455
|
+
* History (D850): none — transient; run results belong in a ledger.
|
|
63456
|
+
*/
|
|
63457
|
+
history: "none"
|
|
62370
63458
|
};
|
|
62371
63459
|
/**
|
|
62372
63460
|
* Smoke alarm sensor — boolean "is smoke currently detected" with
|
|
@@ -62401,6 +63489,10 @@ var smokeCapability = {
|
|
|
62401
63489
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62402
63490
|
*/
|
|
62403
63491
|
durability: "restored",
|
|
63492
|
+
/**
|
|
63493
|
+
* History (D850): recorded series.
|
|
63494
|
+
*/
|
|
63495
|
+
history: { fields: { detected: { kind: "boolean" } } },
|
|
62404
63496
|
/** Clock fields: written, but excluded from the compare that decides
|
|
62405
63497
|
* whether persisting is worth a SQLite commit. */
|
|
62406
63498
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -62500,6 +63592,10 @@ var streamCatalogCapability = {
|
|
|
62500
63592
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62501
63593
|
*/
|
|
62502
63594
|
durability: "restored",
|
|
63595
|
+
/**
|
|
63596
|
+
* History (D850): none — stream inventory.
|
|
63597
|
+
*/
|
|
63598
|
+
history: "none",
|
|
62503
63599
|
/** Clock field: written, but excluded from the compare that decides whether
|
|
62504
63600
|
* persisting is worth a SQLite commit — the descriptors are the value. */
|
|
62505
63601
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -62649,6 +63745,10 @@ var streamParamsCapability = {
|
|
|
62649
63745
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62650
63746
|
*/
|
|
62651
63747
|
durability: "restored",
|
|
63748
|
+
/**
|
|
63749
|
+
* History (D850): none — encoder configuration.
|
|
63750
|
+
*/
|
|
63751
|
+
history: "none",
|
|
62652
63752
|
/** Clock fields: written, but excluded from the compare that decides
|
|
62653
63753
|
* whether persisting is worth a SQLite commit. */
|
|
62654
63754
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -62902,6 +64002,10 @@ var switchCapability = {
|
|
|
62902
64002
|
* `scripts/check-runtime-state-durability.ts`.
|
|
62903
64003
|
*/
|
|
62904
64004
|
durability: "restored",
|
|
64005
|
+
/**
|
|
64006
|
+
* History (D850): recorded series.
|
|
64007
|
+
*/
|
|
64008
|
+
history: { fields: { on: { kind: "boolean" } } },
|
|
62905
64009
|
/** Clock fields: written, but excluded from the compare that decides
|
|
62906
64010
|
* whether persisting is worth a SQLite commit. */
|
|
62907
64011
|
volatileStateFields: ["lastChangedAt"],
|
|
@@ -62916,6 +64020,21 @@ var switchCapability = {
|
|
|
62916
64020
|
}
|
|
62917
64021
|
}] }
|
|
62918
64022
|
};
|
|
64023
|
+
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
64024
|
+
function hasControlCharacter(value) {
|
|
64025
|
+
for (const char of value) {
|
|
64026
|
+
const code = char.codePointAt(0) ?? 0;
|
|
64027
|
+
if (code <= 31 || code >= 127 && code <= 159) return true;
|
|
64028
|
+
}
|
|
64029
|
+
return false;
|
|
64030
|
+
}
|
|
64031
|
+
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" }));
|
|
64032
|
+
/** What every reader gets: the name to show, and whether the hub chose it itself. */
|
|
64033
|
+
var ServerNameInfoSchema = object({
|
|
64034
|
+
name: string(),
|
|
64035
|
+
/** `true` when nobody named the hub: `name` is the machine hostname. */
|
|
64036
|
+
isDefault: boolean()
|
|
64037
|
+
});
|
|
62919
64038
|
/**
|
|
62920
64039
|
* system — system-scoped singleton capability exposing hub-level
|
|
62921
64040
|
* health, feature flags, network interface enumeration, and the
|
|
@@ -62945,6 +64064,12 @@ var FeatureManifestSchema = object({
|
|
|
62945
64064
|
backup: boolean(),
|
|
62946
64065
|
repl: boolean()
|
|
62947
64066
|
});
|
|
64067
|
+
/**
|
|
64068
|
+
* `system.info`: the feature flags plus the hub's human name (D861). The name is
|
|
64069
|
+
* `{ name, isDefault }` — `isDefault: true` means nobody named the hub and `name`
|
|
64070
|
+
* is the machine hostname.
|
|
64071
|
+
*/
|
|
64072
|
+
var SystemInfoSchema = FeatureManifestSchema.extend({ serverName: ServerNameInfoSchema });
|
|
62948
64073
|
var HealthStatusSchema = object({
|
|
62949
64074
|
status: literal("ok"),
|
|
62950
64075
|
uptime: number()
|
|
@@ -63417,7 +64542,7 @@ var LoggingSettingsStateSchema = object({
|
|
|
63417
64542
|
opsLogRetentionDays: number().int().min(0),
|
|
63418
64543
|
persisted: boolean()
|
|
63419
64544
|
});
|
|
63420
|
-
method(_void(),
|
|
64545
|
+
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(), {
|
|
63421
64546
|
kind: "mutation",
|
|
63422
64547
|
auth: "admin"
|
|
63423
64548
|
}), method(_void(), _void(), {
|
|
@@ -63463,6 +64588,10 @@ var tamperCapability = {
|
|
|
63463
64588
|
* `scripts/check-runtime-state-durability.ts`.
|
|
63464
64589
|
*/
|
|
63465
64590
|
durability: "restored",
|
|
64591
|
+
/**
|
|
64592
|
+
* History (D850): recorded series.
|
|
64593
|
+
*/
|
|
64594
|
+
history: { fields: { tampered: { kind: "boolean" } } },
|
|
63466
64595
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63467
64596
|
* whether persisting is worth a SQLite commit. */
|
|
63468
64597
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -63518,6 +64647,14 @@ var temperatureSensorCapability = {
|
|
|
63518
64647
|
* `scripts/check-runtime-state-durability.ts`.
|
|
63519
64648
|
*/
|
|
63520
64649
|
durability: "restored",
|
|
64650
|
+
/**
|
|
64651
|
+
* History (D850): recorded series.
|
|
64652
|
+
*/
|
|
64653
|
+
history: { fields: { celsius: {
|
|
64654
|
+
kind: "gauge",
|
|
64655
|
+
unit: "°C",
|
|
64656
|
+
deadband: .1
|
|
64657
|
+
} } },
|
|
63521
64658
|
/** Clock fields: written, but excluded from the compare that decides
|
|
63522
64659
|
* whether persisting is worth a SQLite commit. */
|
|
63523
64660
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -63596,7 +64733,11 @@ var updateCapability = {
|
|
|
63596
64733
|
* See `RuntimeStateDurability`. Enforced by
|
|
63597
64734
|
* `scripts/check-runtime-state-durability.ts`.
|
|
63598
64735
|
*/
|
|
63599
|
-
durability: "session"
|
|
64736
|
+
durability: "session",
|
|
64737
|
+
/**
|
|
64738
|
+
* History (D850): none — text and state.
|
|
64739
|
+
*/
|
|
64740
|
+
history: "none"
|
|
63600
64741
|
};
|
|
63601
64742
|
var UserSummarySchema = object({
|
|
63602
64743
|
id: string(),
|
|
@@ -63953,7 +65094,37 @@ var vacuumControlCapability = {
|
|
|
63953
65094
|
* See `RuntimeStateDurability`. Enforced by
|
|
63954
65095
|
* `scripts/check-runtime-state-durability.ts`.
|
|
63955
65096
|
*/
|
|
63956
|
-
durability: "session"
|
|
65097
|
+
durability: "session",
|
|
65098
|
+
/**
|
|
65099
|
+
* History (D850): recorded series. Tank levels are fixed-object paths (`cleanWater.level`, ...).
|
|
65100
|
+
*/
|
|
65101
|
+
history: { fields: {
|
|
65102
|
+
batteryLevel: {
|
|
65103
|
+
kind: "gauge",
|
|
65104
|
+
unit: "%",
|
|
65105
|
+
deadband: 2
|
|
65106
|
+
},
|
|
65107
|
+
"cleanWater.level": {
|
|
65108
|
+
kind: "gauge",
|
|
65109
|
+
unit: "%",
|
|
65110
|
+
deadband: 2
|
|
65111
|
+
},
|
|
65112
|
+
"dirtyWater.level": {
|
|
65113
|
+
kind: "gauge",
|
|
65114
|
+
unit: "%",
|
|
65115
|
+
deadband: 2
|
|
65116
|
+
},
|
|
65117
|
+
"detergent.level": {
|
|
65118
|
+
kind: "gauge",
|
|
65119
|
+
unit: "%",
|
|
65120
|
+
deadband: 2
|
|
65121
|
+
},
|
|
65122
|
+
"dustBin.level": {
|
|
65123
|
+
kind: "gauge",
|
|
65124
|
+
unit: "%",
|
|
65125
|
+
deadband: 2
|
|
65126
|
+
}
|
|
65127
|
+
} }
|
|
63957
65128
|
};
|
|
63958
65129
|
var ValveStatusSchema = object({
|
|
63959
65130
|
/** Lifecycle state of the valve. */
|
|
@@ -64012,7 +65183,15 @@ var valveCapability = {
|
|
|
64012
65183
|
* See `RuntimeStateDurability`. Enforced by
|
|
64013
65184
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64014
65185
|
*/
|
|
64015
|
-
durability: "session"
|
|
65186
|
+
durability: "session",
|
|
65187
|
+
/**
|
|
65188
|
+
* History (D850): recorded series. Actuator tier: position keeps every change.
|
|
65189
|
+
*/
|
|
65190
|
+
history: { fields: { position: {
|
|
65191
|
+
kind: "gauge",
|
|
65192
|
+
unit: "%",
|
|
65193
|
+
minIntervalMs: 0
|
|
65194
|
+
} } }
|
|
64016
65195
|
};
|
|
64017
65196
|
/**
|
|
64018
65197
|
* Vibration / shake / impact sensor. Drives Home Assistant
|
|
@@ -64042,6 +65221,10 @@ var vibrationCapability = {
|
|
|
64042
65221
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64043
65222
|
*/
|
|
64044
65223
|
durability: "restored",
|
|
65224
|
+
/**
|
|
65225
|
+
* History (D850): recorded series.
|
|
65226
|
+
*/
|
|
65227
|
+
history: { fields: { detected: { kind: "boolean" } } },
|
|
64045
65228
|
/** Clock fields: written, but excluded from the compare that decides
|
|
64046
65229
|
* whether persisting is worth a SQLite commit. */
|
|
64047
65230
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -64125,7 +65308,22 @@ var waterHeaterCapability = {
|
|
|
64125
65308
|
* See `RuntimeStateDurability`. Enforced by
|
|
64126
65309
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64127
65310
|
*/
|
|
64128
|
-
durability: "session"
|
|
65311
|
+
durability: "session",
|
|
65312
|
+
/**
|
|
65313
|
+
* History (D850): recorded series. The schema carries no unit; providers publish Celsius. Setpoint keeps every change.
|
|
65314
|
+
*/
|
|
65315
|
+
history: { fields: {
|
|
65316
|
+
currentTemp: {
|
|
65317
|
+
kind: "gauge",
|
|
65318
|
+
unit: "°C",
|
|
65319
|
+
deadband: .5
|
|
65320
|
+
},
|
|
65321
|
+
targetTemp: {
|
|
65322
|
+
kind: "gauge",
|
|
65323
|
+
unit: "°C",
|
|
65324
|
+
minIntervalMs: 0
|
|
65325
|
+
}
|
|
65326
|
+
} }
|
|
64129
65327
|
};
|
|
64130
65328
|
/**
|
|
64131
65329
|
* Weather provider cap. Models HA `weather.*` entities — a read-only
|
|
@@ -64191,7 +65389,32 @@ var weatherCapability = {
|
|
|
64191
65389
|
* See `RuntimeStateDurability`. Enforced by
|
|
64192
65390
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64193
65391
|
*/
|
|
64194
|
-
durability: "session"
|
|
65392
|
+
durability: "session",
|
|
65393
|
+
/**
|
|
65394
|
+
* History (D850): recorded series. Units follow the sibling `*Unit` fields.
|
|
65395
|
+
*/
|
|
65396
|
+
history: { fields: {
|
|
65397
|
+
temperature: {
|
|
65398
|
+
kind: "gauge",
|
|
65399
|
+
unitFrom: "temperatureUnit",
|
|
65400
|
+
deadband: .2
|
|
65401
|
+
},
|
|
65402
|
+
humidity: {
|
|
65403
|
+
kind: "gauge",
|
|
65404
|
+
unit: "%",
|
|
65405
|
+
deadband: 1
|
|
65406
|
+
},
|
|
65407
|
+
pressure: {
|
|
65408
|
+
kind: "gauge",
|
|
65409
|
+
unitFrom: "pressureUnit",
|
|
65410
|
+
deadband: .5
|
|
65411
|
+
},
|
|
65412
|
+
windSpeed: {
|
|
65413
|
+
kind: "gauge",
|
|
65414
|
+
unitFrom: "windSpeedUnit",
|
|
65415
|
+
deadband: .5
|
|
65416
|
+
}
|
|
65417
|
+
} }
|
|
64195
65418
|
};
|
|
64196
65419
|
/**
|
|
64197
65420
|
* Per-zone occupancy aggregation produced by the analytics frame
|
|
@@ -64433,7 +65656,11 @@ var zoneAnalyticsCapability = {
|
|
|
64433
65656
|
* See `RuntimeStateDurability`. Enforced by
|
|
64434
65657
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64435
65658
|
*/
|
|
64436
|
-
durability: "session"
|
|
65659
|
+
durability: "session",
|
|
65660
|
+
/**
|
|
65661
|
+
* History (D850): none — occupancy is the addon series `pipeline-analytics/occupancy`; the rest is per-zone arrays keyed by runtime ids.
|
|
65662
|
+
*/
|
|
65663
|
+
history: "none"
|
|
64437
65664
|
};
|
|
64438
65665
|
/**
|
|
64439
65666
|
* Stages a {@link ZoneRule} can apply to. Discriminator on the rules
|
|
@@ -64518,7 +65745,11 @@ var zoneRulesCapability = {
|
|
|
64518
65745
|
* See `RuntimeStateDurability`. Enforced by
|
|
64519
65746
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64520
65747
|
*/
|
|
64521
|
-
durability: "restored"
|
|
65748
|
+
durability: "restored",
|
|
65749
|
+
/**
|
|
65750
|
+
* History (D850): none — configuration arrays.
|
|
65751
|
+
*/
|
|
65752
|
+
history: "none"
|
|
64522
65753
|
};
|
|
64523
65754
|
/**
|
|
64524
65755
|
* `training-provider` — ONE cloud that can run the CamStack trainer.
|
|
@@ -68122,6 +69353,54 @@ Object.freeze({
|
|
|
68122
69353
|
addonId: null,
|
|
68123
69354
|
access: "create"
|
|
68124
69355
|
},
|
|
69356
|
+
"deviceCredentials.deleteDeviceCredential": {
|
|
69357
|
+
capName: "device-credentials",
|
|
69358
|
+
capScope: "system",
|
|
69359
|
+
addonId: null,
|
|
69360
|
+
access: "delete"
|
|
69361
|
+
},
|
|
69362
|
+
"deviceCredentials.getDeviceCaStatus": {
|
|
69363
|
+
capName: "device-credentials",
|
|
69364
|
+
capScope: "system",
|
|
69365
|
+
addonId: null,
|
|
69366
|
+
access: "view"
|
|
69367
|
+
},
|
|
69368
|
+
"deviceCredentials.getDeviceCertificateSettings": {
|
|
69369
|
+
capName: "device-credentials",
|
|
69370
|
+
capScope: "system",
|
|
69371
|
+
addonId: null,
|
|
69372
|
+
access: "view"
|
|
69373
|
+
},
|
|
69374
|
+
"deviceCredentials.listDeviceCredentials": {
|
|
69375
|
+
capName: "device-credentials",
|
|
69376
|
+
capScope: "system",
|
|
69377
|
+
addonId: null,
|
|
69378
|
+
access: "view"
|
|
69379
|
+
},
|
|
69380
|
+
"deviceCredentials.renameDeviceCredential": {
|
|
69381
|
+
capName: "device-credentials",
|
|
69382
|
+
capScope: "system",
|
|
69383
|
+
addonId: null,
|
|
69384
|
+
access: "create"
|
|
69385
|
+
},
|
|
69386
|
+
"deviceCredentials.revokeDeviceCredential": {
|
|
69387
|
+
capName: "device-credentials",
|
|
69388
|
+
capScope: "system",
|
|
69389
|
+
addonId: null,
|
|
69390
|
+
access: "delete"
|
|
69391
|
+
},
|
|
69392
|
+
"deviceCredentials.setDeviceCertificateSettings": {
|
|
69393
|
+
capName: "device-credentials",
|
|
69394
|
+
capScope: "system",
|
|
69395
|
+
addonId: null,
|
|
69396
|
+
access: "create"
|
|
69397
|
+
},
|
|
69398
|
+
"deviceCredentials.startEnrollment": {
|
|
69399
|
+
capName: "device-credentials",
|
|
69400
|
+
capScope: "system",
|
|
69401
|
+
addonId: null,
|
|
69402
|
+
access: "create"
|
|
69403
|
+
},
|
|
68125
69404
|
"deviceDiscovery.adoptDevice": {
|
|
68126
69405
|
capName: "device-discovery",
|
|
68127
69406
|
capScope: "device",
|
|
@@ -68224,6 +69503,66 @@ Object.freeze({
|
|
|
68224
69503
|
addonId: null,
|
|
68225
69504
|
access: "create"
|
|
68226
69505
|
},
|
|
69506
|
+
"deviceHistory.declareSeries": {
|
|
69507
|
+
capName: "device-history",
|
|
69508
|
+
capScope: "system",
|
|
69509
|
+
addonId: null,
|
|
69510
|
+
access: "create"
|
|
69511
|
+
},
|
|
69512
|
+
"deviceHistory.getDeviceEnabled": {
|
|
69513
|
+
capName: "device-history",
|
|
69514
|
+
capScope: "system",
|
|
69515
|
+
addonId: null,
|
|
69516
|
+
access: "view"
|
|
69517
|
+
},
|
|
69518
|
+
"deviceHistory.getStatus": {
|
|
69519
|
+
capName: "device-history",
|
|
69520
|
+
capScope: "system",
|
|
69521
|
+
addonId: null,
|
|
69522
|
+
access: "view"
|
|
69523
|
+
},
|
|
69524
|
+
"deviceHistory.listNodeSeries": {
|
|
69525
|
+
capName: "device-history",
|
|
69526
|
+
capScope: "system",
|
|
69527
|
+
addonId: null,
|
|
69528
|
+
access: "view"
|
|
69529
|
+
},
|
|
69530
|
+
"deviceHistory.listSeries": {
|
|
69531
|
+
capName: "device-history",
|
|
69532
|
+
capScope: "system",
|
|
69533
|
+
addonId: null,
|
|
69534
|
+
access: "view"
|
|
69535
|
+
},
|
|
69536
|
+
"deviceHistory.query": {
|
|
69537
|
+
capName: "device-history",
|
|
69538
|
+
capScope: "system",
|
|
69539
|
+
addonId: null,
|
|
69540
|
+
access: "view"
|
|
69541
|
+
},
|
|
69542
|
+
"deviceHistory.queryNode": {
|
|
69543
|
+
capName: "device-history",
|
|
69544
|
+
capScope: "system",
|
|
69545
|
+
addonId: null,
|
|
69546
|
+
access: "view"
|
|
69547
|
+
},
|
|
69548
|
+
"deviceHistory.record": {
|
|
69549
|
+
capName: "device-history",
|
|
69550
|
+
capScope: "system",
|
|
69551
|
+
addonId: null,
|
|
69552
|
+
access: "create"
|
|
69553
|
+
},
|
|
69554
|
+
"deviceHistory.recordBuckets": {
|
|
69555
|
+
capName: "device-history",
|
|
69556
|
+
capScope: "system",
|
|
69557
|
+
addonId: null,
|
|
69558
|
+
access: "create"
|
|
69559
|
+
},
|
|
69560
|
+
"deviceHistory.setDeviceEnabled": {
|
|
69561
|
+
capName: "device-history",
|
|
69562
|
+
capScope: "system",
|
|
69563
|
+
addonId: null,
|
|
69564
|
+
access: "create"
|
|
69565
|
+
},
|
|
68227
69566
|
"deviceManager.addLocation": {
|
|
68228
69567
|
capName: "device-manager",
|
|
68229
69568
|
capScope: "system",
|
|
@@ -68302,6 +69641,12 @@ Object.freeze({
|
|
|
68302
69641
|
addonId: null,
|
|
68303
69642
|
access: "create"
|
|
68304
69643
|
},
|
|
69644
|
+
"deviceManager.cleanupDeletedDevicesData": {
|
|
69645
|
+
capName: "device-manager",
|
|
69646
|
+
capScope: "system",
|
|
69647
|
+
addonId: null,
|
|
69648
|
+
access: "create"
|
|
69649
|
+
},
|
|
68305
69650
|
"deviceManager.createDevice": {
|
|
68306
69651
|
capName: "device-manager",
|
|
68307
69652
|
capScope: "system",
|
|
@@ -68482,6 +69827,12 @@ Object.freeze({
|
|
|
68482
69827
|
addonId: null,
|
|
68483
69828
|
access: "view"
|
|
68484
69829
|
},
|
|
69830
|
+
"deviceManager.listDeletedSince": {
|
|
69831
|
+
capName: "device-manager",
|
|
69832
|
+
capScope: "system",
|
|
69833
|
+
addonId: null,
|
|
69834
|
+
access: "view"
|
|
69835
|
+
},
|
|
68485
69836
|
"deviceManager.listDeviceIdsByCaps": {
|
|
68486
69837
|
capName: "device-manager",
|
|
68487
69838
|
capScope: "system",
|
|
@@ -68890,6 +70241,18 @@ Object.freeze({
|
|
|
68890
70241
|
addonId: null,
|
|
68891
70242
|
access: "create"
|
|
68892
70243
|
},
|
|
70244
|
+
"deviceRemovalHook.listDeviceData": {
|
|
70245
|
+
capName: "device-removal-hook",
|
|
70246
|
+
capScope: "system",
|
|
70247
|
+
addonId: null,
|
|
70248
|
+
access: "view"
|
|
70249
|
+
},
|
|
70250
|
+
"deviceRemovalHook.onDeviceRemoved": {
|
|
70251
|
+
capName: "device-removal-hook",
|
|
70252
|
+
capScope: "system",
|
|
70253
|
+
addonId: null,
|
|
70254
|
+
access: "create"
|
|
70255
|
+
},
|
|
68893
70256
|
"deviceState.claimFields": {
|
|
68894
70257
|
capName: "device-state",
|
|
68895
70258
|
capScope: "system",
|
|
@@ -69322,6 +70685,12 @@ Object.freeze({
|
|
|
69322
70685
|
addonId: null,
|
|
69323
70686
|
access: "delete"
|
|
69324
70687
|
},
|
|
70688
|
+
"keychain.deleteDeviceScope": {
|
|
70689
|
+
capName: "keychain",
|
|
70690
|
+
capScope: "system",
|
|
70691
|
+
addonId: null,
|
|
70692
|
+
access: "delete"
|
|
70693
|
+
},
|
|
69325
70694
|
"keychain.getState": {
|
|
69326
70695
|
capName: "keychain",
|
|
69327
70696
|
capScope: "system",
|
|
@@ -70282,6 +71651,54 @@ Object.freeze({
|
|
|
70282
71651
|
addonId: null,
|
|
70283
71652
|
access: "create"
|
|
70284
71653
|
},
|
|
71654
|
+
"nodeCertificates.confirmMeshLeaf": {
|
|
71655
|
+
capName: "node-certificates",
|
|
71656
|
+
capScope: "system",
|
|
71657
|
+
addonId: null,
|
|
71658
|
+
access: "create"
|
|
71659
|
+
},
|
|
71660
|
+
"nodeCertificates.forgetHub": {
|
|
71661
|
+
capName: "node-certificates",
|
|
71662
|
+
capScope: "system",
|
|
71663
|
+
addonId: null,
|
|
71664
|
+
access: "delete"
|
|
71665
|
+
},
|
|
71666
|
+
"nodeCertificates.getCertificates": {
|
|
71667
|
+
capName: "node-certificates",
|
|
71668
|
+
capScope: "system",
|
|
71669
|
+
addonId: null,
|
|
71670
|
+
access: "view"
|
|
71671
|
+
},
|
|
71672
|
+
"nodeCertificates.installHttpsCertificate": {
|
|
71673
|
+
capName: "node-certificates",
|
|
71674
|
+
capScope: "system",
|
|
71675
|
+
addonId: null,
|
|
71676
|
+
access: "create"
|
|
71677
|
+
},
|
|
71678
|
+
"nodeCertificates.installMeshLeaf": {
|
|
71679
|
+
capName: "node-certificates",
|
|
71680
|
+
capScope: "system",
|
|
71681
|
+
addonId: null,
|
|
71682
|
+
access: "create"
|
|
71683
|
+
},
|
|
71684
|
+
"nodeCertificates.prepareHttpsCertificate": {
|
|
71685
|
+
capName: "node-certificates",
|
|
71686
|
+
capScope: "system",
|
|
71687
|
+
addonId: null,
|
|
71688
|
+
access: "create"
|
|
71689
|
+
},
|
|
71690
|
+
"nodeCertificates.prepareMeshRenewal": {
|
|
71691
|
+
capName: "node-certificates",
|
|
71692
|
+
capScope: "system",
|
|
71693
|
+
addonId: null,
|
|
71694
|
+
access: "create"
|
|
71695
|
+
},
|
|
71696
|
+
"nodeCertificates.rollbackMeshLeaf": {
|
|
71697
|
+
capName: "node-certificates",
|
|
71698
|
+
capScope: "system",
|
|
71699
|
+
addonId: null,
|
|
71700
|
+
access: "create"
|
|
71701
|
+
},
|
|
70285
71702
|
"nodes.clusterAddonStatus": {
|
|
70286
71703
|
capName: "nodes",
|
|
70287
71704
|
capScope: "system",
|
|
@@ -75125,6 +76542,26 @@ Object.freeze({
|
|
|
75125
76542
|
form: "single",
|
|
75126
76543
|
optional: false
|
|
75127
76544
|
}],
|
|
76545
|
+
"deviceHistory.getDeviceEnabled": [{
|
|
76546
|
+
name: "deviceId",
|
|
76547
|
+
form: "single",
|
|
76548
|
+
optional: false
|
|
76549
|
+
}],
|
|
76550
|
+
"deviceHistory.listSeries": [{
|
|
76551
|
+
name: "deviceId",
|
|
76552
|
+
form: "single",
|
|
76553
|
+
optional: false
|
|
76554
|
+
}],
|
|
76555
|
+
"deviceHistory.query": [{
|
|
76556
|
+
name: "deviceId",
|
|
76557
|
+
form: "single",
|
|
76558
|
+
optional: false
|
|
76559
|
+
}],
|
|
76560
|
+
"deviceHistory.setDeviceEnabled": [{
|
|
76561
|
+
name: "deviceId",
|
|
76562
|
+
form: "single",
|
|
76563
|
+
optional: false
|
|
76564
|
+
}],
|
|
75128
76565
|
"deviceManager.adoptionRelease": [{
|
|
75129
76566
|
name: "camDeviceId",
|
|
75130
76567
|
form: "single",
|
|
@@ -75418,6 +76855,11 @@ Object.freeze({
|
|
|
75418
76855
|
form: "single",
|
|
75419
76856
|
optional: false
|
|
75420
76857
|
}],
|
|
76858
|
+
"deviceRemovalHook.onDeviceRemoved": [{
|
|
76859
|
+
name: "deviceId",
|
|
76860
|
+
form: "single",
|
|
76861
|
+
optional: false
|
|
76862
|
+
}],
|
|
75421
76863
|
"deviceState.claimFields": [{
|
|
75422
76864
|
name: "deviceId",
|
|
75423
76865
|
form: "single",
|
|
@@ -75607,6 +77049,11 @@ Object.freeze({
|
|
|
75607
77049
|
form: "single",
|
|
75608
77050
|
optional: false
|
|
75609
77051
|
}],
|
|
77052
|
+
"keychain.deleteDeviceScope": [{
|
|
77053
|
+
name: "deviceId",
|
|
77054
|
+
form: "single",
|
|
77055
|
+
optional: false
|
|
77056
|
+
}],
|
|
75610
77057
|
"lawnMowerControl.dock": [{
|
|
75611
77058
|
name: "deviceId",
|
|
75612
77059
|
form: "single",
|
|
@@ -77303,6 +78750,7 @@ Object.freeze({
|
|
|
77303
78750
|
"network-access": "ingress",
|
|
77304
78751
|
"smtp-provider": "email"
|
|
77305
78752
|
});
|
|
78753
|
+
DeviceType.Camera;
|
|
77306
78754
|
var G711_SCALE_CORRECTION_DB = {
|
|
77307
78755
|
PCMU: 20 * Math.log10(4),
|
|
77308
78756
|
PCMA: 20 * Math.log10(8)
|
|
@@ -77954,6 +79402,8 @@ new Set([
|
|
|
77954
79402
|
"audio-tools",
|
|
77955
79403
|
"audio-silence"
|
|
77956
79404
|
]);
|
|
79405
|
+
AppPageLangSchema.options;
|
|
79406
|
+
record(string().min(1), string());
|
|
77957
79407
|
/**
|
|
77958
79408
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
77959
79409
|
*
|
|
@@ -185273,71 +186723,88 @@ var intercomFailureReport = new IntercomFailureReport();
|
|
|
185273
186723
|
var SNAPSHOT_GROUPS = [
|
|
185274
186724
|
{
|
|
185275
186725
|
key: "imageSnapshot",
|
|
185276
|
-
label: "Image (getVideoInput)"
|
|
186726
|
+
label: "Image (getVideoInput)",
|
|
186727
|
+
labelKey: "provider-reolink:snapshot_groups.imageSnapshot.label"
|
|
185277
186728
|
},
|
|
185278
186729
|
{
|
|
185279
186730
|
key: "motionSnapshot",
|
|
185280
|
-
label: "Motion (getMotionAlarm)"
|
|
186731
|
+
label: "Motion (getMotionAlarm)",
|
|
186732
|
+
labelKey: "provider-reolink:snapshot_groups.motionSnapshot.label"
|
|
185281
186733
|
},
|
|
185282
186734
|
{
|
|
185283
186735
|
key: "aiSensitivitySnapshot",
|
|
185284
|
-
label: "AI sensitivity (getAiDetectionFull)"
|
|
186736
|
+
label: "AI sensitivity (getAiDetectionFull)",
|
|
186737
|
+
labelKey: "provider-reolink:snapshot_groups.aiSensitivitySnapshot.label"
|
|
185285
186738
|
},
|
|
185286
186739
|
{
|
|
185287
186740
|
key: "encSnapshot",
|
|
185288
|
-
label: "Encoder (getEnc)"
|
|
186741
|
+
label: "Encoder (getEnc)",
|
|
186742
|
+
labelKey: "provider-reolink:snapshot_groups.encSnapshot.label"
|
|
185289
186743
|
},
|
|
185290
186744
|
{
|
|
185291
186745
|
key: "encOptionsSnapshot",
|
|
185292
|
-
label: "Encoder options (getEncOptions)"
|
|
186746
|
+
label: "Encoder options (getEncOptions)",
|
|
186747
|
+
labelKey: "provider-reolink:snapshot_groups.encOptionsSnapshot.label"
|
|
185293
186748
|
},
|
|
185294
186749
|
{
|
|
185295
186750
|
key: "maskSnapshot",
|
|
185296
|
-
label: "Privacy mask (getMask)"
|
|
186751
|
+
label: "Privacy mask (getMask)",
|
|
186752
|
+
labelKey: "provider-reolink:snapshot_groups.maskSnapshot.label"
|
|
185297
186753
|
},
|
|
185298
186754
|
{
|
|
185299
186755
|
key: "audioNoiseSnapshot",
|
|
185300
|
-
label: "Audio noise (getAudioNoise)"
|
|
186756
|
+
label: "Audio noise (getAudioNoise)",
|
|
186757
|
+
labelKey: "provider-reolink:snapshot_groups.audioNoiseSnapshot.label"
|
|
185301
186758
|
},
|
|
185302
186759
|
{
|
|
185303
186760
|
key: "autoFocusSnapshot",
|
|
185304
|
-
label: "Auto-focus (getAutoFocus)"
|
|
186761
|
+
label: "Auto-focus (getAutoFocus)",
|
|
186762
|
+
labelKey: "provider-reolink:snapshot_groups.autoFocusSnapshot.label"
|
|
185305
186763
|
},
|
|
185306
186764
|
{
|
|
185307
186765
|
key: "netPortSnapshot",
|
|
185308
|
-
label: "Network ports (getNetPort)"
|
|
186766
|
+
label: "Network ports (getNetPort)",
|
|
186767
|
+
labelKey: "provider-reolink:snapshot_groups.netPortSnapshot.label"
|
|
185309
186768
|
},
|
|
185310
186769
|
{
|
|
185311
186770
|
key: "ntpSnapshot",
|
|
185312
|
-
label: "NTP (getNtp)"
|
|
186771
|
+
label: "NTP (getNtp)",
|
|
186772
|
+
labelKey: "provider-reolink:snapshot_groups.ntpSnapshot.label"
|
|
185313
186773
|
},
|
|
185314
186774
|
{
|
|
185315
186775
|
key: "systemGeneralSnapshot",
|
|
185316
|
-
label: "System general (getSystemGeneral)"
|
|
186776
|
+
label: "System general (getSystemGeneral)",
|
|
186777
|
+
labelKey: "provider-reolink:snapshot_groups.systemGeneralSnapshot.label"
|
|
185317
186778
|
},
|
|
185318
186779
|
{
|
|
185319
186780
|
key: "osdSnapshot",
|
|
185320
|
-
label: "OSD overlay (getOsd)"
|
|
186781
|
+
label: "OSD overlay (getOsd)",
|
|
186782
|
+
labelKey: "provider-reolink:snapshot_groups.osdSnapshot.label"
|
|
185321
186783
|
},
|
|
185322
186784
|
{
|
|
185323
186785
|
key: "ledSnapshot",
|
|
185324
|
-
label: "LEDs (getIrLights)"
|
|
186786
|
+
label: "LEDs (getIrLights)",
|
|
186787
|
+
labelKey: "provider-reolink:snapshot_groups.ledSnapshot.label"
|
|
185325
186788
|
},
|
|
185326
186789
|
{
|
|
185327
186790
|
key: "pirSnapshot",
|
|
185328
|
-
label: "PIR (getPirInfo)"
|
|
186791
|
+
label: "PIR (getPirInfo)",
|
|
186792
|
+
labelKey: "provider-reolink:snapshot_groups.pirSnapshot.label"
|
|
185329
186793
|
},
|
|
185330
186794
|
{
|
|
185331
186795
|
key: "autoRebootSnapshot",
|
|
185332
|
-
label: "Auto reboot (getAutoReboot)"
|
|
186796
|
+
label: "Auto reboot (getAutoReboot)",
|
|
186797
|
+
labelKey: "provider-reolink:snapshot_groups.autoRebootSnapshot.label"
|
|
185333
186798
|
},
|
|
185334
186799
|
{
|
|
185335
186800
|
key: "emailConfigSnapshot",
|
|
185336
|
-
label: "Email/SMTP (getEmail)"
|
|
186801
|
+
label: "Email/SMTP (getEmail)",
|
|
186802
|
+
labelKey: "provider-reolink:snapshot_groups.emailConfigSnapshot.label"
|
|
185337
186803
|
},
|
|
185338
186804
|
{
|
|
185339
186805
|
key: "capOptionsSnapshot",
|
|
185340
|
-
label: "Cap option probes (getOptions)"
|
|
186806
|
+
label: "Cap option probes (getOptions)",
|
|
186807
|
+
labelKey: "provider-reolink:snapshot_groups.capOptionsSnapshot.label"
|
|
185341
186808
|
}
|
|
185342
186809
|
];
|
|
185343
186810
|
/**
|
|
@@ -185421,12 +186888,15 @@ function buildSnapshotFreshnessSection(cache, opts) {
|
|
|
185421
186888
|
id: "snapshotFreshness",
|
|
185422
186889
|
tab: "advanced",
|
|
185423
186890
|
title: "Snapshot freshness",
|
|
186891
|
+
titleKey: "provider-reolink:snapshotFreshnessSection.s_snapshotFreshness.title",
|
|
185424
186892
|
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.",
|
|
186893
|
+
descriptionKey: "provider-reolink:snapshotFreshnessSection.s_snapshotFreshness.description",
|
|
185425
186894
|
columns: 1,
|
|
185426
186895
|
fields: [{
|
|
185427
186896
|
type: "info",
|
|
185428
186897
|
key: "snapshotFreshness",
|
|
185429
186898
|
label: "Per-snapshot read times",
|
|
186899
|
+
labelKey: "provider-reolink:field.snapshotFreshness.label",
|
|
185430
186900
|
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")}`
|
|
185431
186901
|
}]
|
|
185432
186902
|
};
|
|
@@ -186622,7 +188092,7 @@ function capDayNightModeToReolink(mode) {
|
|
|
186622
188092
|
case "auto": return "auto";
|
|
186623
188093
|
case "day": return "color";
|
|
186624
188094
|
case "night": return "blackAndWhite";
|
|
186625
|
-
case "schedule": throw
|
|
188095
|
+
case "schedule": throw userError("reolink.day-night-schedule-unsupported", void 0, "Reolink cameras do not support a scheduled day/night mode");
|
|
186626
188096
|
}
|
|
186627
188097
|
}
|
|
186628
188098
|
//#endregion
|
|
@@ -186917,6 +188387,7 @@ function buildOsdStateBanner(snapshot, opts) {
|
|
|
186917
188387
|
type: "info",
|
|
186918
188388
|
key: "osdSnapshotState",
|
|
186919
188389
|
label: "OSD state",
|
|
188390
|
+
labelKey: "provider-reolink:osdStateBanner.osdSnapshotState.label",
|
|
186920
188391
|
variant: "warning",
|
|
186921
188392
|
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}`
|
|
186922
188393
|
};
|
|
@@ -186924,6 +188395,7 @@ function buildOsdStateBanner(snapshot, opts) {
|
|
|
186924
188395
|
type: "info",
|
|
186925
188396
|
key: "osdSnapshotState",
|
|
186926
188397
|
label: "OSD state",
|
|
188398
|
+
labelKey: "provider-reolink:osdStateBanner.osdSnapshotState.label",
|
|
186927
188399
|
variant: "warning",
|
|
186928
188400
|
content: "OSD state has not been read from this camera yet — unknown toggles are disabled until a read succeeds."
|
|
186929
188401
|
};
|
|
@@ -186973,7 +188445,9 @@ function buildOsdSection(snapshot, values, opts) {
|
|
|
186973
188445
|
id: "osd",
|
|
186974
188446
|
tab: "image",
|
|
186975
188447
|
title: "OSD overlay",
|
|
188448
|
+
titleKey: "provider-reolink:osdSection.s_osd.title",
|
|
186976
188449
|
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.",
|
|
188450
|
+
descriptionKey: "provider-reolink:osdSection.s_osd.description",
|
|
186977
188451
|
columns: 2,
|
|
186978
188452
|
fields: [
|
|
186979
188453
|
...banner ? [banner] : [],
|
|
@@ -186983,7 +188457,9 @@ function buildOsdSection(snapshot, values, opts) {
|
|
|
186983
188457
|
type: "text",
|
|
186984
188458
|
key: "osdChannelName",
|
|
186985
188459
|
label: "Channel name",
|
|
188460
|
+
labelKey: "provider-reolink:fields.osdChannelName.label",
|
|
186986
188461
|
description: "Text shown in the channel-name overlay.",
|
|
188462
|
+
descriptionKey: "provider-reolink:fields.osdChannelName.description",
|
|
186987
188463
|
default: values.osdChannelName,
|
|
186988
188464
|
placeholder: "Front door"
|
|
186989
188465
|
},
|
|
@@ -187466,13 +188942,17 @@ var SirenAccessory = class extends BaseDevice {
|
|
|
187466
188942
|
return hydrateSchema({ sections: [{
|
|
187467
188943
|
id: "siren",
|
|
187468
188944
|
title: "Siren",
|
|
188945
|
+
titleKey: "provider-reolink:schema.s_siren.title",
|
|
187469
188946
|
description: "Tone duration when triggered. Set to 0 for \"play until turned off\"; positive values pulse for that many seconds.",
|
|
188947
|
+
descriptionKey: "provider-reolink:schema.s_siren.description",
|
|
187470
188948
|
columns: 1,
|
|
187471
188949
|
fields: [{
|
|
187472
188950
|
type: "number",
|
|
187473
188951
|
key: "sirenDurationS",
|
|
187474
188952
|
label: "Default duration (seconds)",
|
|
188953
|
+
labelKey: "provider-reolink:schema.s_siren.sirenDurationS.label",
|
|
187475
188954
|
description: "Forwarded to `setSiren(on=true, duration)` (cmd_id 30) when the operator flips the switch.",
|
|
188955
|
+
descriptionKey: "provider-reolink:schema.s_siren.sirenDurationS.description",
|
|
187476
188956
|
default: 0,
|
|
187477
188957
|
min: 0,
|
|
187478
188958
|
max: 300,
|
|
@@ -187481,13 +188961,17 @@ var SirenAccessory = class extends BaseDevice {
|
|
|
187481
188961
|
}, {
|
|
187482
188962
|
id: "motion-siren",
|
|
187483
188963
|
title: "Motion-triggered siren",
|
|
188964
|
+
titleKey: "provider-reolink:schema.s_motion-siren.title",
|
|
187484
188965
|
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.",
|
|
188966
|
+
descriptionKey: "provider-reolink:schema.s_motion-siren.description",
|
|
187485
188967
|
columns: 1,
|
|
187486
188968
|
fields: [{
|
|
187487
188969
|
type: "select",
|
|
187488
188970
|
key: "motionSirenDetectType",
|
|
187489
188971
|
label: "Detection classes",
|
|
188972
|
+
labelKey: "provider-reolink:schema.s_motion-siren.motionSirenDetectType.label",
|
|
187490
188973
|
description: "Object/motion classes that arm the siren. `MD` = generic motion detection.",
|
|
188974
|
+
descriptionKey: "provider-reolink:schema.s_motion-siren.motionSirenDetectType.description",
|
|
187491
188975
|
options: SIREN_DETECT_TYPE_CHOICES.map((v) => ({
|
|
187492
188976
|
value: v,
|
|
187493
188977
|
label: v.replace(/,/g, " + ").replace(/_/g, "+")
|
|
@@ -187950,13 +189434,17 @@ var FloodlightAccessory = class extends BaseDevice {
|
|
|
187950
189434
|
return hydrateSchema({ sections: [{
|
|
187951
189435
|
id: "motion-floodlight",
|
|
187952
189436
|
title: "Motion-triggered floodlight",
|
|
189437
|
+
titleKey: "provider-reolink:schema.s_motion-floodlight.title",
|
|
187953
189438
|
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.",
|
|
189439
|
+
descriptionKey: "provider-reolink:schema.s_motion-floodlight.description",
|
|
187954
189440
|
columns: 2,
|
|
187955
189441
|
fields: [{
|
|
187956
189442
|
type: "number",
|
|
187957
189443
|
key: "motionLightDurationS",
|
|
187958
189444
|
label: "Light duration (s)",
|
|
189445
|
+
labelKey: "provider-reolink:schema.s_motion-floodlight.motionLightDurationS.label",
|
|
187959
189446
|
description: "Seconds the floodlight stays lit after a motion event. Reolink range 1..600s.",
|
|
189447
|
+
descriptionKey: "provider-reolink:schema.s_motion-floodlight.motionLightDurationS.description",
|
|
187960
189448
|
min: 1,
|
|
187961
189449
|
max: 600,
|
|
187962
189450
|
step: 1,
|
|
@@ -187965,7 +189453,9 @@ var FloodlightAccessory = class extends BaseDevice {
|
|
|
187965
189453
|
type: "select",
|
|
187966
189454
|
key: "motionLightDetectType",
|
|
187967
189455
|
label: "Detection classes",
|
|
189456
|
+
labelKey: "provider-reolink:schema.s_motion-floodlight.motionLightDetectType.label",
|
|
187968
189457
|
description: "Object classes that turn the floodlight on. Composed values (e.g. \"people,vehicle\") fire when ANY listed class detects.",
|
|
189458
|
+
descriptionKey: "provider-reolink:schema.s_motion-floodlight.motionLightDetectType.description",
|
|
187969
189459
|
options: FLOODLIGHT_DETECT_TYPE_CHOICES.map((v) => ({
|
|
187970
189460
|
value: v,
|
|
187971
189461
|
label: v.replace(/,/g, " + ").replace(/_/g, "+")
|
|
@@ -188204,14 +189694,18 @@ var PirAccessory = class extends BaseDevice {
|
|
|
188204
189694
|
return hydrateSchema({ sections: [{
|
|
188205
189695
|
id: "pir",
|
|
188206
189696
|
title: "PIR sensor",
|
|
189697
|
+
titleKey: "provider-reolink:schema.s_pir.title",
|
|
188207
189698
|
description: "Hardware passive-infrared trigger configuration. Pushed via cmd_id 153 (SetPirInfo).",
|
|
189699
|
+
descriptionKey: "provider-reolink:schema.s_pir.description",
|
|
188208
189700
|
columns: 2,
|
|
188209
189701
|
fields: [
|
|
188210
189702
|
{
|
|
188211
189703
|
type: "slider",
|
|
188212
189704
|
key: "pirSensitive",
|
|
188213
189705
|
label: "Sensitivity",
|
|
189706
|
+
labelKey: "provider-reolink:schema.s_pir.pirSensitive.label",
|
|
188214
189707
|
description: "Higher value → triggers on smaller motion. Most cameras max at 100.",
|
|
189708
|
+
descriptionKey: "provider-reolink:schema.s_pir.pirSensitive.description",
|
|
188215
189709
|
min: 1,
|
|
188216
189710
|
max: 100,
|
|
188217
189711
|
step: 1,
|
|
@@ -188222,6 +189716,7 @@ var PirAccessory = class extends BaseDevice {
|
|
|
188222
189716
|
type: "slider",
|
|
188223
189717
|
key: "pirIntervalS",
|
|
188224
189718
|
label: "Cooldown (seconds)",
|
|
189719
|
+
labelKey: "provider-reolink:schema.s_pir.pirIntervalS.label",
|
|
188225
189720
|
description: `Minimum delay between consecutive PIR triggers. Reolink app range 5..${intervalMax}s; firmware clamps on push.`,
|
|
188226
189721
|
min: 5,
|
|
188227
189722
|
max: intervalMax,
|
|
@@ -188234,7 +189729,9 @@ var PirAccessory = class extends BaseDevice {
|
|
|
188234
189729
|
type: "boolean",
|
|
188235
189730
|
key: "pirReduceAlarm",
|
|
188236
189731
|
label: "Reduce false alarms",
|
|
189732
|
+
labelKey: "provider-reolink:schema.s_pir.pirReduceAlarm.label",
|
|
188237
189733
|
description: "Trades detection range for fewer false positives. Maps to firmware `reduceAlarm` flag.",
|
|
189734
|
+
descriptionKey: "provider-reolink:schema.s_pir.pirReduceAlarm.description",
|
|
188238
189735
|
...typeof reduceAlarm === "boolean" ? { default: reduceAlarm } : {},
|
|
188239
189736
|
style: "switch",
|
|
188240
189737
|
span: 2
|
|
@@ -189762,6 +191259,7 @@ function buildSessionsTabSections(snap, opts) {
|
|
|
189762
191259
|
type: "info",
|
|
189763
191260
|
key: "sessionsError",
|
|
189764
191261
|
label: "Refresh error",
|
|
191262
|
+
labelKey: "provider-reolink:errorBanner.sessionsError.label",
|
|
189765
191263
|
content: snap.error,
|
|
189766
191264
|
variant: "danger"
|
|
189767
191265
|
}] : [];
|
|
@@ -189783,6 +191281,7 @@ function buildSessionsTabSections(snap, opts) {
|
|
|
189783
191281
|
id: "sessions-status",
|
|
189784
191282
|
title: opts.title ?? "Sessions",
|
|
189785
191283
|
description: "Diagnostics for the Baichuan control channel. Auto-refreshes when older than 1 minute; click Refresh to force.",
|
|
191284
|
+
descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.description",
|
|
189786
191285
|
tab: opts.tabId,
|
|
189787
191286
|
order: 0,
|
|
189788
191287
|
columns: 1,
|
|
@@ -189792,38 +191291,46 @@ function buildSessionsTabSections(snap, opts) {
|
|
|
189792
191291
|
type: "info",
|
|
189793
191292
|
key: "sessionsLastRefreshed",
|
|
189794
191293
|
label: "Last refreshed",
|
|
191294
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsLastRefreshed.label",
|
|
189795
191295
|
content: ageInfo
|
|
189796
191296
|
},
|
|
189797
191297
|
{
|
|
189798
191298
|
type: "object-array",
|
|
189799
191299
|
key: "sessionsOnlineUsers",
|
|
189800
191300
|
label: "Online users (firmware)",
|
|
191301
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.label",
|
|
189801
191302
|
description: "Active user sessions reported by the device (cmd_id 145). Includes other admins, mobile app, NVR linkups.",
|
|
191303
|
+
descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.description",
|
|
189802
191304
|
columns: [
|
|
189803
191305
|
{
|
|
189804
191306
|
key: "userName",
|
|
189805
|
-
label: "User"
|
|
191307
|
+
label: "User",
|
|
191308
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.userName.label"
|
|
189806
191309
|
},
|
|
189807
191310
|
{
|
|
189808
191311
|
key: "ip",
|
|
189809
191312
|
label: "IP",
|
|
191313
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.ip.label",
|
|
189810
191314
|
kind: "monospace",
|
|
189811
191315
|
width: "160px"
|
|
189812
191316
|
},
|
|
189813
191317
|
{
|
|
189814
191318
|
key: "sessionId",
|
|
189815
191319
|
label: "Session",
|
|
191320
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.sessionId.label",
|
|
189816
191321
|
kind: "monospace",
|
|
189817
191322
|
width: "90px"
|
|
189818
191323
|
},
|
|
189819
191324
|
{
|
|
189820
191325
|
key: "level",
|
|
189821
191326
|
label: "Level",
|
|
191327
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.level.label",
|
|
189822
191328
|
width: "80px"
|
|
189823
191329
|
},
|
|
189824
191330
|
{
|
|
189825
191331
|
key: "status",
|
|
189826
191332
|
label: "State",
|
|
191333
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.status.label",
|
|
189827
191334
|
kind: "status",
|
|
189828
191335
|
width: "100px"
|
|
189829
191336
|
}
|
|
@@ -189835,14 +191342,18 @@ function buildSessionsTabSections(snap, opts) {
|
|
|
189835
191342
|
type: "object-array",
|
|
189836
191343
|
key: "sessionsSocketPool",
|
|
189837
191344
|
label: "Our socket pool",
|
|
191345
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsSocketPool.label",
|
|
189838
191346
|
description: "Open Baichuan TCP/UDP sockets this process holds for the device. One row per pool tag.",
|
|
191347
|
+
descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsSocketPool.description",
|
|
189839
191348
|
columns: [{
|
|
189840
191349
|
key: "tag",
|
|
189841
191350
|
label: "Tag",
|
|
191351
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsSocketPool.tag.label",
|
|
189842
191352
|
kind: "monospace"
|
|
189843
191353
|
}, {
|
|
189844
191354
|
key: "state",
|
|
189845
191355
|
label: "State",
|
|
191356
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsSocketPool.state.label",
|
|
189846
191357
|
kind: "status",
|
|
189847
191358
|
width: "100px"
|
|
189848
191359
|
}],
|
|
@@ -189853,10 +191364,13 @@ function buildSessionsTabSections(snap, opts) {
|
|
|
189853
191364
|
type: "object-array",
|
|
189854
191365
|
key: "sessionsDedicated",
|
|
189855
191366
|
label: "Dedicated lib sessions",
|
|
191367
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsDedicated.label",
|
|
189856
191368
|
description: "Internal lib-side dedicated sessions (streaming/talk channels). Older lib versions leave this list empty.",
|
|
191369
|
+
descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsDedicated.description",
|
|
189857
191370
|
columns: [{
|
|
189858
191371
|
key: "key",
|
|
189859
191372
|
label: "Session key",
|
|
191373
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsDedicated.key.label",
|
|
189860
191374
|
kind: "monospace"
|
|
189861
191375
|
}],
|
|
189862
191376
|
value: dedicatedRows,
|
|
@@ -189866,12 +191380,14 @@ function buildSessionsTabSections(snap, opts) {
|
|
|
189866
191380
|
type: "info",
|
|
189867
191381
|
key: "sessionsCooldown",
|
|
189868
191382
|
label: "Reconnect cooldown",
|
|
191383
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsCooldown.label",
|
|
189869
191384
|
content: cooldownText
|
|
189870
191385
|
},
|
|
189871
191386
|
{
|
|
189872
191387
|
type: "device-action-button",
|
|
189873
191388
|
key: "_refreshSessions",
|
|
189874
191389
|
label: "Refresh sessions",
|
|
191390
|
+
labelKey: "provider-reolink:sessionsTabSections.s_sessions-status._refreshSessions.label",
|
|
189875
191391
|
buttonLabel: "Refresh now",
|
|
189876
191392
|
action: "refresh-sessions",
|
|
189877
191393
|
variant: "default"
|
|
@@ -191343,11 +192859,11 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
191343
192859
|
});
|
|
191344
192860
|
if (!this.isEmailPushEligible) {
|
|
191345
192861
|
this.ctx.logger.warn("email-push: not eligible (hub-attached camera)", { tags: { deviceId: this.id } });
|
|
191346
|
-
throw
|
|
192862
|
+
throw userError("reolink.email-push-hub-attached", void 0, "Email push is not available for hub-attached cameras");
|
|
191347
192863
|
}
|
|
191348
192864
|
if (!this.emailPushParamsResolver) {
|
|
191349
192865
|
this.ctx.logger.warn("email-push: resolver not wired — restart the Reolink addon", { tags: { deviceId: this.id } });
|
|
191350
|
-
throw
|
|
192866
|
+
throw userError("reolink.email-push-not-wired", void 0, "Email Push Server is not wired — restart the Reolink addon");
|
|
191351
192867
|
}
|
|
191352
192868
|
const params = await this.emailPushParamsResolver();
|
|
191353
192869
|
if (!params) {
|
|
@@ -191406,14 +192922,14 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
191406
192922
|
this.ctx.logger.warn("baichuan-webhook: not eligible", { tags: { deviceId: this.id } });
|
|
191407
192923
|
throw new Error("HaCfg webhook Auto-configure is only available on standalone battery cameras");
|
|
191408
192924
|
}
|
|
191409
|
-
if (!this.baichuanWebhookParamsResolver) throw
|
|
192925
|
+
if (!this.baichuanWebhookParamsResolver) throw userError("reolink.webhook-not-wired", void 0, "HaCfg Webhook Server is not wired — restart the Reolink addon");
|
|
191410
192926
|
const params = await this.baichuanWebhookParamsResolver();
|
|
191411
192927
|
if (!params) throw new Error("Enable the HaCfg Webhook Server in the Reolink addon settings, and ensure this host has a reachable LAN address.");
|
|
191412
192928
|
await this.wakeIfSleeping();
|
|
191413
192929
|
const api = await this.ensureApi();
|
|
191414
192930
|
const supported = await api.probeBaichuanWebhookSupport();
|
|
191415
192931
|
this.baichuanWebhookSupportedCached = supported;
|
|
191416
|
-
if (!supported) throw
|
|
192932
|
+
if (!supported) throw userError("reolink.webhook-unsupported", void 0, "Camera firmware does not support Baichuan HaCfg webhook (cmd 806)");
|
|
191417
192933
|
this.ctx.logger.info("baichuan-webhook: auto-configuring camera", {
|
|
191418
192934
|
tags: { deviceId: this.id },
|
|
191419
192935
|
meta: { url: params.url }
|
|
@@ -192092,26 +193608,32 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192092
193608
|
id: "sleep-push",
|
|
192093
193609
|
tab: "motion",
|
|
192094
193610
|
title: "Battery motion (sleep push)",
|
|
193611
|
+
titleKey: "provider-reolink:emailPushSection.s_sleep-push.title",
|
|
192095
193612
|
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.",
|
|
193613
|
+
descriptionKey: "provider-reolink:emailPushSection.s_sleep-push.description",
|
|
192096
193614
|
columns: 1,
|
|
192097
193615
|
fields: [
|
|
192098
193616
|
{
|
|
192099
193617
|
type: "select",
|
|
192100
193618
|
key: "batterySleepPushMethod",
|
|
192101
193619
|
label: "Preferred sleep-push path",
|
|
193620
|
+
labelKey: "provider-reolink:emailPushSection.s_sleep-push.batterySleepPushMethod.label",
|
|
192102
193621
|
default: "auto",
|
|
192103
193622
|
options: [
|
|
192104
193623
|
{
|
|
192105
193624
|
value: "auto",
|
|
192106
|
-
label: "Auto (webhook if supported, else email)"
|
|
193625
|
+
label: "Auto (webhook if supported, else email)",
|
|
193626
|
+
labelKey: "provider-reolink:emailPushSection.s_sleep-push.batterySleepPushMethod.o_auto.label"
|
|
192107
193627
|
},
|
|
192108
193628
|
{
|
|
192109
193629
|
value: "webhook",
|
|
192110
|
-
label: "HaCfg webhook only"
|
|
193630
|
+
label: "HaCfg webhook only",
|
|
193631
|
+
labelKey: "provider-reolink:emailPushSection.s_sleep-push.batterySleepPushMethod.o_webhook.label"
|
|
192111
193632
|
},
|
|
192112
193633
|
{
|
|
192113
193634
|
value: "email",
|
|
192114
|
-
label: "Email/SMTP only"
|
|
193635
|
+
label: "Email/SMTP only",
|
|
193636
|
+
labelKey: "provider-reolink:emailPushSection.s_sleep-push.batterySleepPushMethod.o_email.label"
|
|
192115
193637
|
}
|
|
192116
193638
|
]
|
|
192117
193639
|
},
|
|
@@ -192119,6 +193641,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192119
193641
|
type: "device-action-button",
|
|
192120
193642
|
key: "_autoConfigureBaichuanWebhook",
|
|
192121
193643
|
label: "HaCfg webhook",
|
|
193644
|
+
labelKey: "provider-reolink:emailPushSection.s_sleep-push._autoConfigureBaichuanWebhook.label",
|
|
192122
193645
|
buttonLabel: "Auto-configure HaCfg webhook",
|
|
192123
193646
|
action: "auto-configure-baichuan-webhook",
|
|
192124
193647
|
variant: "default"
|
|
@@ -192127,6 +193650,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192127
193650
|
type: "device-action-button",
|
|
192128
193651
|
key: "_autoConfigureEmailPush",
|
|
192129
193652
|
label: "Email push",
|
|
193653
|
+
labelKey: "provider-reolink:emailPushSection.s_sleep-push._autoConfigureEmailPush.label",
|
|
192130
193654
|
buttonLabel: "Auto-configure email push",
|
|
192131
193655
|
action: "auto-configure-email-push",
|
|
192132
193656
|
variant: "default"
|
|
@@ -192150,19 +193674,23 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192150
193674
|
id: "email-smtp",
|
|
192151
193675
|
tab: "email",
|
|
192152
193676
|
title: "SMTP server",
|
|
193677
|
+
titleKey: "provider-reolink:emailTabSections.s_email-smtp.title",
|
|
192153
193678
|
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.",
|
|
193679
|
+
descriptionKey: "provider-reolink:emailTabSections.s_email-smtp.description",
|
|
192154
193680
|
columns: 2,
|
|
192155
193681
|
fields: [
|
|
192156
193682
|
{
|
|
192157
193683
|
type: "text",
|
|
192158
193684
|
key: "emailSmtpServer",
|
|
192159
193685
|
label: "SMTP server",
|
|
193686
|
+
labelKey: "provider-reolink:emailTabSections.s_email-smtp.emailSmtpServer.label",
|
|
192160
193687
|
placeholder: "smtp.example.com"
|
|
192161
193688
|
},
|
|
192162
193689
|
{
|
|
192163
193690
|
type: "number",
|
|
192164
193691
|
key: "emailSmtpPort",
|
|
192165
193692
|
label: "SMTP port",
|
|
193693
|
+
labelKey: "provider-reolink:emailTabSections.s_email-smtp.emailSmtpPort.label",
|
|
192166
193694
|
min: 1,
|
|
192167
193695
|
max: 65535,
|
|
192168
193696
|
step: 1
|
|
@@ -192171,12 +193699,14 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192171
193699
|
type: "text",
|
|
192172
193700
|
key: "emailUserName",
|
|
192173
193701
|
label: "Username / sender",
|
|
193702
|
+
labelKey: "provider-reolink:emailTabSections.s_email-smtp.emailUserName.label",
|
|
192174
193703
|
placeholder: "cam@example.com"
|
|
192175
193704
|
},
|
|
192176
193705
|
{
|
|
192177
193706
|
type: "password",
|
|
192178
193707
|
key: "emailPassword",
|
|
192179
193708
|
label: "Password",
|
|
193709
|
+
labelKey: "provider-reolink:emailTabSections.s_email-smtp.emailPassword.label",
|
|
192180
193710
|
showToggle: true,
|
|
192181
193711
|
placeholder: "leave blank to keep"
|
|
192182
193712
|
},
|
|
@@ -192184,12 +193714,14 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192184
193714
|
type: "boolean",
|
|
192185
193715
|
key: "emailSsl",
|
|
192186
193716
|
label: "SSL/TLS",
|
|
193717
|
+
labelKey: "provider-reolink:emailTabSections.s_email-smtp.emailSsl.label",
|
|
192187
193718
|
style: "switch"
|
|
192188
193719
|
},
|
|
192189
193720
|
{
|
|
192190
193721
|
type: "text",
|
|
192191
193722
|
key: "emailSendNickname",
|
|
192192
|
-
label: "Sender name"
|
|
193723
|
+
label: "Sender name",
|
|
193724
|
+
labelKey: "provider-reolink:emailTabSections.s_email-smtp.emailSendNickname.label"
|
|
192193
193725
|
}
|
|
192194
193726
|
]
|
|
192195
193727
|
},
|
|
@@ -192197,24 +193729,29 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192197
193729
|
id: "email-recipients",
|
|
192198
193730
|
tab: "email",
|
|
192199
193731
|
title: "Recipients",
|
|
193732
|
+
titleKey: "provider-reolink:emailTabSections.s_email-recipients.title",
|
|
192200
193733
|
description: "Up to three recipient addresses the camera sends motion mail to.",
|
|
193734
|
+
descriptionKey: "provider-reolink:emailTabSections.s_email-recipients.description",
|
|
192201
193735
|
columns: 1,
|
|
192202
193736
|
fields: [
|
|
192203
193737
|
{
|
|
192204
193738
|
type: "text",
|
|
192205
193739
|
key: "emailRecipient1",
|
|
192206
193740
|
label: "Recipient 1",
|
|
193741
|
+
labelKey: "provider-reolink:emailTabSections.s_email-recipients.emailRecipient1.label",
|
|
192207
193742
|
placeholder: "alerts@example.com"
|
|
192208
193743
|
},
|
|
192209
193744
|
{
|
|
192210
193745
|
type: "text",
|
|
192211
193746
|
key: "emailRecipient2",
|
|
192212
|
-
label: "Recipient 2"
|
|
193747
|
+
label: "Recipient 2",
|
|
193748
|
+
labelKey: "provider-reolink:emailTabSections.s_email-recipients.emailRecipient2.label"
|
|
192213
193749
|
},
|
|
192214
193750
|
{
|
|
192215
193751
|
type: "text",
|
|
192216
193752
|
key: "emailRecipient3",
|
|
192217
|
-
label: "Recipient 3"
|
|
193753
|
+
label: "Recipient 3",
|
|
193754
|
+
labelKey: "provider-reolink:emailTabSections.s_email-recipients.emailRecipient3.label"
|
|
192218
193755
|
}
|
|
192219
193756
|
]
|
|
192220
193757
|
},
|
|
@@ -192222,12 +193759,15 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
192222
193759
|
id: "email-schedule",
|
|
192223
193760
|
tab: "email",
|
|
192224
193761
|
title: "Alarm schedule",
|
|
193762
|
+
titleKey: "provider-reolink:emailTabSections.s_email-schedule.title",
|
|
192225
193763
|
description: "Master enable for the camera's email alarm schedule (EmailTask).",
|
|
193764
|
+
descriptionKey: "provider-reolink:emailTabSections.s_email-schedule.description",
|
|
192226
193765
|
columns: 1,
|
|
192227
193766
|
fields: [{
|
|
192228
193767
|
type: "boolean",
|
|
192229
193768
|
key: "emailScheduleEnabled",
|
|
192230
193769
|
label: "Email alarm schedule enabled",
|
|
193770
|
+
labelKey: "provider-reolink:emailTabSections.s_email-schedule.emailScheduleEnabled.label",
|
|
192231
193771
|
style: "switch"
|
|
192232
193772
|
}]
|
|
192233
193773
|
}
|
|
@@ -194455,7 +195995,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
194455
195995
|
const api = await this.ensureApi();
|
|
194456
195996
|
const channel = this.getChannel();
|
|
194457
195997
|
const id = Number(presetId);
|
|
194458
|
-
if (!Number.isFinite(id)) throw
|
|
195998
|
+
if (!Number.isFinite(id)) throw userError("reolink.preset-invalid", { presetId: String(presetId) }, `Invalid presetId: ${presetId}`);
|
|
194459
195999
|
await api.moveToPtzPreset(channel, id);
|
|
194460
196000
|
},
|
|
194461
196001
|
savePreset: async ({ deviceId, presetId, name }) => {
|
|
@@ -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.setPtzPreset(channel, id, name);
|
|
194468
196008
|
},
|
|
194469
196009
|
deletePreset: async ({ deviceId, presetId }) => {
|
|
@@ -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.deletePtzPreset(channel, id);
|
|
194476
196016
|
},
|
|
194477
196017
|
getOptions: async ({ deviceId }) => {
|
|
@@ -194523,7 +196063,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
194523
196063
|
}
|
|
194524
196064
|
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");
|
|
194525
196065
|
const id = Number(home.presetId);
|
|
194526
|
-
if (!Number.isFinite(id)) throw
|
|
196066
|
+
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}`);
|
|
194527
196067
|
const api = await this.ensureApi();
|
|
194528
196068
|
const channel = this.getChannel();
|
|
194529
196069
|
await api.moveToPtzPreset(channel, id);
|
|
@@ -196095,12 +197635,15 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196095
197635
|
id: "driver-refresh",
|
|
196096
197636
|
tab: "general",
|
|
196097
197637
|
title: "Camera data",
|
|
197638
|
+
titleKey: "provider-reolink:schema.s_driver-refresh.title",
|
|
196098
197639
|
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.",
|
|
197640
|
+
descriptionKey: "provider-reolink:schema.s_driver-refresh.description",
|
|
196099
197641
|
columns: 1,
|
|
196100
197642
|
fields: [{
|
|
196101
197643
|
type: "device-action-button",
|
|
196102
197644
|
key: "_refreshSettings",
|
|
196103
197645
|
label: "Refresh from camera",
|
|
197646
|
+
labelKey: "provider-reolink:schema.s_driver-refresh._refreshSettings.label",
|
|
196104
197647
|
buttonLabel: "Refresh now",
|
|
196105
197648
|
action: "refresh-settings",
|
|
196106
197649
|
variant: "default",
|
|
@@ -196111,13 +197654,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196111
197654
|
id: "connection",
|
|
196112
197655
|
tab: "general",
|
|
196113
197656
|
title: "Connection",
|
|
197657
|
+
titleKey: "provider-reolink:schema.s_connection.title",
|
|
196114
197658
|
description: "Baichuan protocol connection settings.",
|
|
197659
|
+
descriptionKey: "provider-reolink:schema.s_connection.description",
|
|
196115
197660
|
columns: 2,
|
|
196116
197661
|
fields: [
|
|
196117
197662
|
{
|
|
196118
197663
|
type: "text",
|
|
196119
197664
|
key: "host",
|
|
196120
197665
|
label: "Camera IP",
|
|
197666
|
+
labelKey: "provider-reolink:schema.s_connection.host.label",
|
|
196121
197667
|
required: true,
|
|
196122
197668
|
placeholder: "192.168.10.100"
|
|
196123
197669
|
},
|
|
@@ -196125,6 +197671,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196125
197671
|
type: "number",
|
|
196126
197672
|
key: "port",
|
|
196127
197673
|
label: "Port",
|
|
197674
|
+
labelKey: "provider-reolink:schema.s_connection.port.label",
|
|
196128
197675
|
default: 9e3,
|
|
196129
197676
|
min: 1,
|
|
196130
197677
|
max: 65535,
|
|
@@ -196134,12 +197681,14 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196134
197681
|
type: "text",
|
|
196135
197682
|
key: "username",
|
|
196136
197683
|
label: "Username",
|
|
197684
|
+
labelKey: "provider-reolink:schema.s_connection.username.label",
|
|
196137
197685
|
default: "admin"
|
|
196138
197686
|
},
|
|
196139
197687
|
{
|
|
196140
197688
|
type: "password",
|
|
196141
197689
|
key: "password",
|
|
196142
197690
|
label: "Password",
|
|
197691
|
+
labelKey: "provider-reolink:schema.s_connection.password.label",
|
|
196143
197692
|
required: true,
|
|
196144
197693
|
showToggle: true
|
|
196145
197694
|
}
|
|
@@ -196149,13 +197698,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196149
197698
|
id: "network-ports",
|
|
196150
197699
|
tab: "network",
|
|
196151
197700
|
title: "Service ports",
|
|
197701
|
+
titleKey: "provider-reolink:schema.s_network-ports.title",
|
|
196152
197702
|
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.",
|
|
197703
|
+
descriptionKey: "provider-reolink:schema.s_network-ports.description",
|
|
196153
197704
|
columns: 2,
|
|
196154
197705
|
fields: [
|
|
196155
197706
|
{
|
|
196156
197707
|
type: "boolean",
|
|
196157
197708
|
key: "netHttpEnable",
|
|
196158
197709
|
label: "HTTP enabled",
|
|
197710
|
+
labelKey: "provider-reolink:schema.s_network-ports.netHttpEnable.label",
|
|
196159
197711
|
default: netSnap.http?.enable ?? true,
|
|
196160
197712
|
style: "switch"
|
|
196161
197713
|
},
|
|
@@ -196163,6 +197715,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196163
197715
|
type: "number",
|
|
196164
197716
|
key: "netHttpPort",
|
|
196165
197717
|
label: "HTTP port",
|
|
197718
|
+
labelKey: "provider-reolink:schema.s_network-ports.netHttpPort.label",
|
|
196166
197719
|
default: netSnap.http?.port ?? 80,
|
|
196167
197720
|
min: 1,
|
|
196168
197721
|
max: 65535,
|
|
@@ -196172,6 +197725,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196172
197725
|
type: "boolean",
|
|
196173
197726
|
key: "netHttpsEnable",
|
|
196174
197727
|
label: "HTTPS enabled",
|
|
197728
|
+
labelKey: "provider-reolink:schema.s_network-ports.netHttpsEnable.label",
|
|
196175
197729
|
default: netSnap.https?.enable ?? false,
|
|
196176
197730
|
style: "switch"
|
|
196177
197731
|
},
|
|
@@ -196179,6 +197733,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196179
197733
|
type: "number",
|
|
196180
197734
|
key: "netHttpsPort",
|
|
196181
197735
|
label: "HTTPS port",
|
|
197736
|
+
labelKey: "provider-reolink:schema.s_network-ports.netHttpsPort.label",
|
|
196182
197737
|
default: netSnap.https?.port ?? 443,
|
|
196183
197738
|
min: 1,
|
|
196184
197739
|
max: 65535,
|
|
@@ -196188,6 +197743,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196188
197743
|
type: "boolean",
|
|
196189
197744
|
key: "netRtspEnable",
|
|
196190
197745
|
label: "RTSP enabled",
|
|
197746
|
+
labelKey: "provider-reolink:schema.s_network-ports.netRtspEnable.label",
|
|
196191
197747
|
default: netSnap.rtsp?.enable ?? true,
|
|
196192
197748
|
style: "switch"
|
|
196193
197749
|
},
|
|
@@ -196195,6 +197751,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196195
197751
|
type: "number",
|
|
196196
197752
|
key: "netRtspPort",
|
|
196197
197753
|
label: "RTSP port",
|
|
197754
|
+
labelKey: "provider-reolink:schema.s_network-ports.netRtspPort.label",
|
|
196198
197755
|
default: netSnap.rtsp?.port ?? 554,
|
|
196199
197756
|
min: 1,
|
|
196200
197757
|
max: 65535,
|
|
@@ -196204,6 +197761,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196204
197761
|
type: "boolean",
|
|
196205
197762
|
key: "netRtmpEnable",
|
|
196206
197763
|
label: "RTMP enabled",
|
|
197764
|
+
labelKey: "provider-reolink:schema.s_network-ports.netRtmpEnable.label",
|
|
196207
197765
|
default: netSnap.rtmp?.enable ?? true,
|
|
196208
197766
|
style: "switch"
|
|
196209
197767
|
},
|
|
@@ -196211,6 +197769,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196211
197769
|
type: "number",
|
|
196212
197770
|
key: "netRtmpPort",
|
|
196213
197771
|
label: "RTMP port",
|
|
197772
|
+
labelKey: "provider-reolink:schema.s_network-ports.netRtmpPort.label",
|
|
196214
197773
|
default: netSnap.rtmp?.port ?? 1935,
|
|
196215
197774
|
min: 1,
|
|
196216
197775
|
max: 65535,
|
|
@@ -196220,6 +197779,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196220
197779
|
type: "boolean",
|
|
196221
197780
|
key: "netOnvifEnable",
|
|
196222
197781
|
label: "ONVIF enabled",
|
|
197782
|
+
labelKey: "provider-reolink:schema.s_network-ports.netOnvifEnable.label",
|
|
196223
197783
|
default: netSnap.onvif?.enable ?? true,
|
|
196224
197784
|
style: "switch"
|
|
196225
197785
|
},
|
|
@@ -196227,6 +197787,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196227
197787
|
type: "number",
|
|
196228
197788
|
key: "netOnvifPort",
|
|
196229
197789
|
label: "ONVIF port",
|
|
197790
|
+
labelKey: "provider-reolink:schema.s_network-ports.netOnvifPort.label",
|
|
196230
197791
|
default: netSnap.onvif?.port ?? 8e3,
|
|
196231
197792
|
min: 1,
|
|
196232
197793
|
max: 65535,
|
|
@@ -196238,14 +197799,18 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196238
197799
|
id: "time-ntp",
|
|
196239
197800
|
tab: "network",
|
|
196240
197801
|
title: "Time / NTP",
|
|
197802
|
+
titleKey: "provider-reolink:schema.s_time-ntp.title",
|
|
196241
197803
|
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.",
|
|
197804
|
+
descriptionKey: "provider-reolink:schema.s_time-ntp.description",
|
|
196242
197805
|
columns: 2,
|
|
196243
197806
|
fields: [
|
|
196244
197807
|
{
|
|
196245
197808
|
type: "timezone",
|
|
196246
197809
|
key: "timeZoneId",
|
|
196247
197810
|
label: "Timezone",
|
|
197811
|
+
labelKey: "provider-reolink:schema.s_time-ntp.timeZoneId.label",
|
|
196248
197812
|
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.",
|
|
197813
|
+
descriptionKey: "provider-reolink:schema.s_time-ntp.timeZoneId.description",
|
|
196249
197814
|
default: this.config.get("timeZoneId") ?? reolinkTimeZoneToIana(this.config.get("deviceCache")?.systemGeneralSnapshot?.timeZone) ?? "",
|
|
196250
197815
|
span: 2
|
|
196251
197816
|
},
|
|
@@ -196253,6 +197818,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196253
197818
|
type: "boolean",
|
|
196254
197819
|
key: "ntpEnabled",
|
|
196255
197820
|
label: "NTP sync",
|
|
197821
|
+
labelKey: "provider-reolink:schema.s_time-ntp.ntpEnabled.label",
|
|
196256
197822
|
default: ntpSnap.enabled ?? true,
|
|
196257
197823
|
style: "switch",
|
|
196258
197824
|
span: 2
|
|
@@ -196261,6 +197827,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196261
197827
|
type: "text",
|
|
196262
197828
|
key: "ntpServer",
|
|
196263
197829
|
label: "NTP server",
|
|
197830
|
+
labelKey: "provider-reolink:schema.s_time-ntp.ntpServer.label",
|
|
196264
197831
|
default: ntpSnap.server ?? "pool.ntp.org",
|
|
196265
197832
|
placeholder: "pool.ntp.org",
|
|
196266
197833
|
span: 2
|
|
@@ -196269,6 +197836,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196269
197836
|
type: "number",
|
|
196270
197837
|
key: "ntpPort",
|
|
196271
197838
|
label: "NTP port",
|
|
197839
|
+
labelKey: "provider-reolink:schema.s_time-ntp.ntpPort.label",
|
|
196272
197840
|
default: ntpSnap.port ?? 123,
|
|
196273
197841
|
min: 1,
|
|
196274
197842
|
max: 65535,
|
|
@@ -196278,6 +197846,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196278
197846
|
type: "number",
|
|
196279
197847
|
key: "ntpInterval",
|
|
196280
197848
|
label: "Sync interval (min)",
|
|
197849
|
+
labelKey: "provider-reolink:schema.s_time-ntp.ntpInterval.label",
|
|
196281
197850
|
default: ntpSnap.interval ?? 1440,
|
|
196282
197851
|
min: 1,
|
|
196283
197852
|
max: 10080,
|
|
@@ -196289,13 +197858,17 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196289
197858
|
id: "motion",
|
|
196290
197859
|
tab: "motion",
|
|
196291
197860
|
title: "On-camera motion (MdAlarm)",
|
|
197861
|
+
titleKey: "provider-reolink:schema.s_motion.title",
|
|
196292
197862
|
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.",
|
|
197863
|
+
descriptionKey: "provider-reolink:schema.s_motion.description",
|
|
196293
197864
|
columns: 2,
|
|
196294
197865
|
fields: [{
|
|
196295
197866
|
type: "boolean",
|
|
196296
197867
|
key: "motionEnabled",
|
|
196297
197868
|
label: "Motion detection",
|
|
197869
|
+
labelKey: "provider-reolink:schema.s_motion.motionEnabled.label",
|
|
196298
197870
|
description: "Master switch for the camera's on-board motion detector. Disabling stops the camera from emitting motion events on the alarm channel.",
|
|
197871
|
+
descriptionKey: "provider-reolink:schema.s_motion.motionEnabled.description",
|
|
196299
197872
|
default: motionSnap.enabled ?? true,
|
|
196300
197873
|
style: "switch",
|
|
196301
197874
|
span: 2
|
|
@@ -196303,7 +197876,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196303
197876
|
type: "slider",
|
|
196304
197877
|
key: "motionSensitivity",
|
|
196305
197878
|
label: "Sensitivity",
|
|
197879
|
+
labelKey: "provider-reolink:schema.s_motion.motionSensitivity.label",
|
|
196306
197880
|
description: "Higher = triggers on smaller motion. Reolink user-facing range 1..50.",
|
|
197881
|
+
descriptionKey: "provider-reolink:schema.s_motion.motionSensitivity.description",
|
|
196307
197882
|
min: 1,
|
|
196308
197883
|
max: 50,
|
|
196309
197884
|
step: 1,
|
|
@@ -196317,7 +197892,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196317
197892
|
id: "ai-sensitivity",
|
|
196318
197893
|
tab: "motion",
|
|
196319
197894
|
title: "AI detection sensitivity",
|
|
197895
|
+
titleKey: "provider-reolink:schema.s_ai-sensitivity.title",
|
|
196320
197896
|
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.",
|
|
197897
|
+
descriptionKey: "provider-reolink:schema.s_ai-sensitivity.description",
|
|
196321
197898
|
columns: 2,
|
|
196322
197899
|
fields: [
|
|
196323
197900
|
[
|
|
@@ -196448,13 +198025,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196448
198025
|
id: "image",
|
|
196449
198026
|
tab: "image",
|
|
196450
198027
|
title: "Image",
|
|
198028
|
+
titleKey: "provider-reolink:schema.s_image.title",
|
|
196451
198029
|
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.",
|
|
198030
|
+
descriptionKey: "provider-reolink:schema.s_image.description",
|
|
196452
198031
|
columns: 2,
|
|
196453
198032
|
fields: [
|
|
196454
198033
|
{
|
|
196455
198034
|
type: "slider",
|
|
196456
198035
|
key: "imgBright",
|
|
196457
198036
|
label: "Brightness",
|
|
198037
|
+
labelKey: "provider-reolink:schema.s_image.imgBright.label",
|
|
196458
198038
|
min: 0,
|
|
196459
198039
|
max: 255,
|
|
196460
198040
|
step: 1,
|
|
@@ -196466,6 +198046,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196466
198046
|
type: "slider",
|
|
196467
198047
|
key: "imgContrast",
|
|
196468
198048
|
label: "Contrast",
|
|
198049
|
+
labelKey: "provider-reolink:schema.s_image.imgContrast.label",
|
|
196469
198050
|
min: 0,
|
|
196470
198051
|
max: 255,
|
|
196471
198052
|
step: 1,
|
|
@@ -196477,6 +198058,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196477
198058
|
type: "slider",
|
|
196478
198059
|
key: "imgSaturation",
|
|
196479
198060
|
label: "Saturation",
|
|
198061
|
+
labelKey: "provider-reolink:schema.s_image.imgSaturation.label",
|
|
196480
198062
|
min: 0,
|
|
196481
198063
|
max: 255,
|
|
196482
198064
|
step: 1,
|
|
@@ -196488,6 +198070,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196488
198070
|
type: "slider",
|
|
196489
198071
|
key: "imgHue",
|
|
196490
198072
|
label: "Hue",
|
|
198073
|
+
labelKey: "provider-reolink:schema.s_image.imgHue.label",
|
|
196491
198074
|
min: 0,
|
|
196492
198075
|
max: 255,
|
|
196493
198076
|
step: 1,
|
|
@@ -196499,6 +198082,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196499
198082
|
type: "slider",
|
|
196500
198083
|
key: "imgSharpen",
|
|
196501
198084
|
label: "Sharpness",
|
|
198085
|
+
labelKey: "provider-reolink:schema.s_image.imgSharpen.label",
|
|
196502
198086
|
min: 0,
|
|
196503
198087
|
max: 255,
|
|
196504
198088
|
step: 1,
|
|
@@ -196513,19 +198097,25 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196513
198097
|
id: "isp",
|
|
196514
198098
|
tab: "image",
|
|
196515
198099
|
title: "Advanced (ISP)",
|
|
198100
|
+
titleKey: "provider-reolink:schema.s_isp.title",
|
|
196516
198101
|
description: "Day/Night + exposure + HDR. Pushed via `SetIsp` (cmd_id 25). The day/night threshold uses cmd_id 297 (DayNightThreshold).",
|
|
198102
|
+
descriptionKey: "provider-reolink:schema.s_isp.description",
|
|
196517
198103
|
columns: 2,
|
|
196518
198104
|
fields: [{
|
|
196519
198105
|
type: "text",
|
|
196520
198106
|
key: "ispDayNight",
|
|
196521
198107
|
label: "Day/Night mode",
|
|
198108
|
+
labelKey: "provider-reolink:schema.s_isp.ispDayNight.label",
|
|
196522
198109
|
description: "Camera-specific values — common: `auto`, `color`, `blackAndWhite`. The driver normalizes case before push.",
|
|
198110
|
+
descriptionKey: "provider-reolink:schema.s_isp.ispDayNight.description",
|
|
196523
198111
|
default: imgSnap.dayNight ?? "auto"
|
|
196524
198112
|
}, {
|
|
196525
198113
|
type: "text",
|
|
196526
198114
|
key: "ispExposure",
|
|
196527
198115
|
label: "Exposure",
|
|
198116
|
+
labelKey: "provider-reolink:schema.s_isp.ispExposure.label",
|
|
196528
198117
|
description: "Common values: `auto`, `manual`. Lowercased before push.",
|
|
198118
|
+
descriptionKey: "provider-reolink:schema.s_isp.ispExposure.description",
|
|
196529
198119
|
default: "auto"
|
|
196530
198120
|
}]
|
|
196531
198121
|
}] : [],
|
|
@@ -196533,26 +198123,32 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196533
198123
|
id: "ir-lights",
|
|
196534
198124
|
tab: "image",
|
|
196535
198125
|
title: "IR + status LED",
|
|
198126
|
+
titleKey: "provider-reolink:schema.s_ir-lights.title",
|
|
196536
198127
|
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.",
|
|
198128
|
+
descriptionKey: "provider-reolink:schema.s_ir-lights.description",
|
|
196537
198129
|
columns: 2,
|
|
196538
198130
|
fields: [
|
|
196539
198131
|
{
|
|
196540
198132
|
type: "select",
|
|
196541
198133
|
key: "irLightsState",
|
|
196542
198134
|
label: "IR LED",
|
|
198135
|
+
labelKey: "provider-reolink:schema.s_ir-lights.irLightsState.label",
|
|
196543
198136
|
default: "Auto",
|
|
196544
198137
|
options: [
|
|
196545
198138
|
{
|
|
196546
198139
|
value: "Auto",
|
|
196547
|
-
label: "Auto (camera decides)"
|
|
198140
|
+
label: "Auto (camera decides)",
|
|
198141
|
+
labelKey: "provider-reolink:schema.s_ir-lights.irLightsState.o_Auto.label"
|
|
196548
198142
|
},
|
|
196549
198143
|
{
|
|
196550
198144
|
value: "On",
|
|
196551
|
-
label: "Always on"
|
|
198145
|
+
label: "Always on",
|
|
198146
|
+
labelKey: "provider-reolink:schema.s_ir-lights.irLightsState.o_On.label"
|
|
196552
198147
|
},
|
|
196553
198148
|
{
|
|
196554
198149
|
value: "Off",
|
|
196555
|
-
label: "Always off"
|
|
198150
|
+
label: "Always off",
|
|
198151
|
+
labelKey: "provider-reolink:schema.s_ir-lights.irLightsState.o_Off.label"
|
|
196556
198152
|
}
|
|
196557
198153
|
]
|
|
196558
198154
|
},
|
|
@@ -196560,7 +198156,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196560
198156
|
type: "slider",
|
|
196561
198157
|
key: "irLightsBrightness",
|
|
196562
198158
|
label: "IR brightness",
|
|
198159
|
+
labelKey: "provider-reolink:schema.s_ir-lights.irLightsBrightness.label",
|
|
196563
198160
|
description: "Only applied when the camera advertises programmable IR brightness. 0..255 raw range; many models clamp to 0..100.",
|
|
198161
|
+
descriptionKey: "provider-reolink:schema.s_ir-lights.irLightsBrightness.description",
|
|
196564
198162
|
min: 0,
|
|
196565
198163
|
max: 255,
|
|
196566
198164
|
step: 5,
|
|
@@ -196572,7 +198170,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196572
198170
|
type: "boolean",
|
|
196573
198171
|
key: "statusLedEnabled",
|
|
196574
198172
|
label: "Status LED",
|
|
198173
|
+
labelKey: "provider-reolink:schema.s_ir-lights.statusLedEnabled.label",
|
|
196575
198174
|
description: "The visible status/power LED on the camera body. Pushed via `SetIrLights` (cmd_id 209) as `lightState`.",
|
|
198175
|
+
descriptionKey: "provider-reolink:schema.s_ir-lights.statusLedEnabled.description",
|
|
196576
198176
|
default: cache?.ledSnapshot?.statusEnabled ?? true,
|
|
196577
198177
|
style: "switch",
|
|
196578
198178
|
span: cache?.ledSnapshot?.doorbellSupported === true ? 1 : 2
|
|
@@ -196581,7 +198181,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196581
198181
|
type: "boolean",
|
|
196582
198182
|
key: "doorbellLedEnabled",
|
|
196583
198183
|
label: "Doorbell LED",
|
|
198184
|
+
labelKey: "provider-reolink:schema.s_ir-lights.doorbellLedEnabled.label",
|
|
196584
198185
|
description: "The doorbell button ring LED. Pushed via `SetIrLights` (cmd_id 209) as `doorbellLightState`.",
|
|
198186
|
+
descriptionKey: "provider-reolink:schema.s_ir-lights.doorbellLedEnabled.description",
|
|
196585
198187
|
default: cache?.ledSnapshot?.doorbellEnabled ?? true,
|
|
196586
198188
|
style: "switch"
|
|
196587
198189
|
}] : []
|
|
@@ -196595,12 +198197,15 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196595
198197
|
id: "auto-focus",
|
|
196596
198198
|
tab: "image",
|
|
196597
198199
|
title: "Auto focus",
|
|
198200
|
+
titleKey: "provider-reolink:schema.s_auto-focus.title",
|
|
196598
198201
|
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.",
|
|
198202
|
+
descriptionKey: "provider-reolink:schema.s_auto-focus.description",
|
|
196599
198203
|
columns: 1,
|
|
196600
198204
|
fields: [{
|
|
196601
198205
|
type: "boolean",
|
|
196602
198206
|
key: "autoFocusEnabled",
|
|
196603
198207
|
label: "Auto focus",
|
|
198208
|
+
labelKey: "provider-reolink:schema.s_auto-focus.autoFocusEnabled.label",
|
|
196604
198209
|
default: cache.autoFocusSnapshot?.enabled ?? true,
|
|
196605
198210
|
style: "switch"
|
|
196606
198211
|
}]
|
|
@@ -196609,13 +198214,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196609
198214
|
id: "audio",
|
|
196610
198215
|
tab: "audio",
|
|
196611
198216
|
title: "Audio output",
|
|
198217
|
+
titleKey: "provider-reolink:schema.s_audio.title",
|
|
196612
198218
|
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.",
|
|
198219
|
+
descriptionKey: "provider-reolink:schema.s_audio.description",
|
|
196613
198220
|
columns: 2,
|
|
196614
198221
|
fields: [
|
|
196615
198222
|
{
|
|
196616
198223
|
type: "slider",
|
|
196617
198224
|
key: "audioVolume",
|
|
196618
198225
|
label: "Speaker volume",
|
|
198226
|
+
labelKey: "provider-reolink:schema.s_audio.audioVolume.label",
|
|
196619
198227
|
min: 0,
|
|
196620
198228
|
max: 100,
|
|
196621
198229
|
step: 5,
|
|
@@ -196627,7 +198235,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196627
198235
|
type: "slider",
|
|
196628
198236
|
key: "audioTalkAndReplyVolume",
|
|
196629
198237
|
label: "Talk + reply volume",
|
|
198238
|
+
labelKey: "provider-reolink:schema.s_audio.audioTalkAndReplyVolume.label",
|
|
196630
198239
|
description: "Two-way audio + canned reply playback. Doorbell-only on most firmwares.",
|
|
198240
|
+
descriptionKey: "provider-reolink:schema.s_audio.audioTalkAndReplyVolume.description",
|
|
196631
198241
|
min: 0,
|
|
196632
198242
|
max: 100,
|
|
196633
198243
|
step: 5,
|
|
@@ -196639,7 +198249,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196639
198249
|
type: "slider",
|
|
196640
198250
|
key: "audioVisitorVolume",
|
|
196641
198251
|
label: "Visitor volume",
|
|
198252
|
+
labelKey: "provider-reolink:schema.s_audio.audioVisitorVolume.label",
|
|
196642
198253
|
description: "Visitor / chime playback channel. Doorbell-only on most firmwares.",
|
|
198254
|
+
descriptionKey: "provider-reolink:schema.s_audio.audioVisitorVolume.description",
|
|
196643
198255
|
min: 0,
|
|
196644
198256
|
max: 100,
|
|
196645
198257
|
step: 5,
|
|
@@ -196654,13 +198266,17 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196654
198266
|
id: "audio-noise",
|
|
196655
198267
|
tab: "audio",
|
|
196656
198268
|
title: "Audio noise reduction",
|
|
198269
|
+
titleKey: "provider-reolink:schema.s_audio-noise.title",
|
|
196657
198270
|
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).",
|
|
198271
|
+
descriptionKey: "provider-reolink:schema.s_audio-noise.description",
|
|
196658
198272
|
columns: 1,
|
|
196659
198273
|
fields: [{
|
|
196660
198274
|
type: "slider",
|
|
196661
198275
|
key: "audioNoiseLevel",
|
|
196662
198276
|
label: "Noise reduction level",
|
|
198277
|
+
labelKey: "provider-reolink:schema.s_audio-noise.audioNoiseLevel.label",
|
|
196663
198278
|
description: "0 = off · 1 = low · 2 = medium · 3 = high.",
|
|
198279
|
+
descriptionKey: "provider-reolink:schema.s_audio-noise.audioNoiseLevel.description",
|
|
196664
198280
|
min: 0,
|
|
196665
198281
|
max: 3,
|
|
196666
198282
|
step: 1,
|
|
@@ -196673,14 +198289,18 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196673
198289
|
id: "intercom",
|
|
196674
198290
|
tab: "audio",
|
|
196675
198291
|
title: "Intercom",
|
|
198292
|
+
titleKey: "provider-reolink:schema.s_intercom.title",
|
|
196676
198293
|
description: "Push-to-talk pipeline tuning. Settings take effect on the next talk session — restart any active session for changes to apply.",
|
|
198294
|
+
descriptionKey: "provider-reolink:schema.s_intercom.description",
|
|
196677
198295
|
columns: 2,
|
|
196678
198296
|
fields: [
|
|
196679
198297
|
{
|
|
196680
198298
|
type: "slider",
|
|
196681
198299
|
key: "intercomBlocksPerPayload",
|
|
196682
198300
|
label: "Blocks per payload",
|
|
198301
|
+
labelKey: "provider-reolink:schema.s_intercom.intercomBlocksPerPayload.label",
|
|
196683
198302
|
description: "Lower = lower latency (more sendAudio calls/sec). Higher = fewer calls, less per-call socket overhead. Range 1..8. Default 1 (lowest latency).",
|
|
198303
|
+
descriptionKey: "provider-reolink:schema.s_intercom.intercomBlocksPerPayload.description",
|
|
196684
198304
|
min: 1,
|
|
196685
198305
|
max: 8,
|
|
196686
198306
|
step: 1,
|
|
@@ -196692,7 +198312,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196692
198312
|
type: "slider",
|
|
196693
198313
|
key: "intercomMaxBacklogMs",
|
|
196694
198314
|
label: "Max backlog (ms)",
|
|
198315
|
+
labelKey: "provider-reolink:schema.s_intercom.intercomMaxBacklogMs.label",
|
|
196695
198316
|
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.",
|
|
198317
|
+
descriptionKey: "provider-reolink:schema.s_intercom.intercomMaxBacklogMs.description",
|
|
196696
198318
|
min: 20,
|
|
196697
198319
|
max: 5e3,
|
|
196698
198320
|
step: 20,
|
|
@@ -196704,7 +198326,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196704
198326
|
type: "slider",
|
|
196705
198327
|
key: "intercomGain",
|
|
196706
198328
|
label: "Output gain",
|
|
198329
|
+
labelKey: "provider-reolink:schema.s_intercom.intercomGain.label",
|
|
196707
198330
|
description: "Multiplier applied to PCM samples before IMA-ADPCM encode. 1.0 = neutral, 2.0 ≈ +6dB, 0.5 ≈ -6dB. Hard-clipped at int16 bounds.",
|
|
198331
|
+
descriptionKey: "provider-reolink:schema.s_intercom.intercomGain.description",
|
|
196708
198332
|
min: .1,
|
|
196709
198333
|
max: 10,
|
|
196710
198334
|
step: .1,
|
|
@@ -196719,12 +198343,15 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196719
198343
|
id: "keyframe-gop",
|
|
196720
198344
|
tab: "advanced",
|
|
196721
198345
|
title: "Keyframe interval (GOP)",
|
|
198346
|
+
titleKey: "provider-reolink:schema.s_keyframe-gop.title",
|
|
196722
198347
|
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.",
|
|
198348
|
+
descriptionKey: "provider-reolink:schema.s_keyframe-gop.description",
|
|
196723
198349
|
columns: 1,
|
|
196724
198350
|
fields: [{
|
|
196725
198351
|
type: "slider",
|
|
196726
198352
|
key: "gop",
|
|
196727
198353
|
label: "Keyframe interval (s)",
|
|
198354
|
+
labelKey: "provider-reolink:schema.s_keyframe-gop.gop.label",
|
|
196728
198355
|
min: 1,
|
|
196729
198356
|
max: 10,
|
|
196730
198357
|
step: 1,
|
|
@@ -196737,12 +198364,15 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196737
198364
|
id: "pir-reduce-alarm",
|
|
196738
198365
|
tab: "advanced",
|
|
196739
198366
|
title: "PIR detection",
|
|
198367
|
+
titleKey: "provider-reolink:schema.s_pir-reduce-alarm.title",
|
|
196740
198368
|
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.",
|
|
198369
|
+
descriptionKey: "provider-reolink:schema.s_pir-reduce-alarm.description",
|
|
196741
198370
|
columns: 1,
|
|
196742
198371
|
fields: [{
|
|
196743
198372
|
type: "boolean",
|
|
196744
198373
|
key: "pirReduceFalseAlarm",
|
|
196745
198374
|
label: "Reduce false alarms",
|
|
198375
|
+
labelKey: "provider-reolink:schema.s_pir-reduce-alarm.pirReduceFalseAlarm.label",
|
|
196746
198376
|
default: cache.pirSnapshot.reduceFalseAlarm ?? false,
|
|
196747
198377
|
style: "switch"
|
|
196748
198378
|
}]
|
|
@@ -196751,13 +198381,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196751
198381
|
id: "auto-reboot",
|
|
196752
198382
|
tab: "advanced",
|
|
196753
198383
|
title: "Auto reboot",
|
|
198384
|
+
titleKey: "provider-reolink:schema.s_auto-reboot.title",
|
|
196754
198385
|
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.",
|
|
198386
|
+
descriptionKey: "provider-reolink:schema.s_auto-reboot.description",
|
|
196755
198387
|
columns: 2,
|
|
196756
198388
|
fields: [
|
|
196757
198389
|
{
|
|
196758
198390
|
type: "boolean",
|
|
196759
198391
|
key: "autoRebootEnabled",
|
|
196760
198392
|
label: "Auto reboot",
|
|
198393
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootEnabled.label",
|
|
196761
198394
|
default: cache.autoRebootSnapshot.enabled ?? false,
|
|
196762
198395
|
style: "switch",
|
|
196763
198396
|
span: 2
|
|
@@ -196766,40 +198399,49 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196766
198399
|
type: "select",
|
|
196767
198400
|
key: "autoRebootWeekDay",
|
|
196768
198401
|
label: "Day",
|
|
198402
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.label",
|
|
196769
198403
|
default: cache.autoRebootSnapshot.weekDay ?? "everyday",
|
|
196770
198404
|
span: 2,
|
|
196771
198405
|
options: [
|
|
196772
198406
|
{
|
|
196773
198407
|
value: "everyday",
|
|
196774
|
-
label: "Every day"
|
|
198408
|
+
label: "Every day",
|
|
198409
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_everyday.label"
|
|
196775
198410
|
},
|
|
196776
198411
|
{
|
|
196777
198412
|
value: "Sunday",
|
|
196778
|
-
label: "Sunday"
|
|
198413
|
+
label: "Sunday",
|
|
198414
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Sunday.label"
|
|
196779
198415
|
},
|
|
196780
198416
|
{
|
|
196781
198417
|
value: "Monday",
|
|
196782
|
-
label: "Monday"
|
|
198418
|
+
label: "Monday",
|
|
198419
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Monday.label"
|
|
196783
198420
|
},
|
|
196784
198421
|
{
|
|
196785
198422
|
value: "Tuesday",
|
|
196786
|
-
label: "Tuesday"
|
|
198423
|
+
label: "Tuesday",
|
|
198424
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Tuesday.label"
|
|
196787
198425
|
},
|
|
196788
198426
|
{
|
|
196789
198427
|
value: "Wednesday",
|
|
196790
|
-
label: "Wednesday"
|
|
198428
|
+
label: "Wednesday",
|
|
198429
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Wednesday.label"
|
|
196791
198430
|
},
|
|
196792
198431
|
{
|
|
196793
198432
|
value: "Thursday",
|
|
196794
|
-
label: "Thursday"
|
|
198433
|
+
label: "Thursday",
|
|
198434
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Thursday.label"
|
|
196795
198435
|
},
|
|
196796
198436
|
{
|
|
196797
198437
|
value: "Friday",
|
|
196798
|
-
label: "Friday"
|
|
198438
|
+
label: "Friday",
|
|
198439
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Friday.label"
|
|
196799
198440
|
},
|
|
196800
198441
|
{
|
|
196801
198442
|
value: "Saturday",
|
|
196802
|
-
label: "Saturday"
|
|
198443
|
+
label: "Saturday",
|
|
198444
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootWeekDay.o_Saturday.label"
|
|
196803
198445
|
}
|
|
196804
198446
|
]
|
|
196805
198447
|
},
|
|
@@ -196807,6 +198449,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196807
198449
|
type: "number",
|
|
196808
198450
|
key: "autoRebootHour",
|
|
196809
198451
|
label: "Hour (0-23)",
|
|
198452
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootHour.label",
|
|
196810
198453
|
default: cache.autoRebootSnapshot.hour ?? 3,
|
|
196811
198454
|
min: 0,
|
|
196812
198455
|
max: 23,
|
|
@@ -196816,6 +198459,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196816
198459
|
type: "number",
|
|
196817
198460
|
key: "autoRebootMinute",
|
|
196818
198461
|
label: "Minute (0-59)",
|
|
198462
|
+
labelKey: "provider-reolink:schema.s_auto-reboot.autoRebootMinute.label",
|
|
196819
198463
|
default: cache.autoRebootSnapshot.minute ?? 0,
|
|
196820
198464
|
min: 0,
|
|
196821
198465
|
max: 59,
|
|
@@ -196827,41 +198471,52 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
196827
198471
|
id: "debug",
|
|
196828
198472
|
tab: "advanced",
|
|
196829
198473
|
title: "Debug",
|
|
198474
|
+
titleKey: "provider-reolink:schema.s_debug.title",
|
|
196830
198475
|
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.",
|
|
198476
|
+
descriptionKey: "provider-reolink:schema.s_debug.description",
|
|
196831
198477
|
columns: 1,
|
|
196832
198478
|
fields: [{
|
|
196833
198479
|
type: "boolean",
|
|
196834
198480
|
key: "debugGeneral",
|
|
196835
198481
|
label: "General debug logs",
|
|
198482
|
+
labelKey: "provider-reolink:schema.s_debug.debugGeneral.label",
|
|
196836
198483
|
description: "Forwards `DebugOptions.general=true` — verbose lib protocol logs.",
|
|
198484
|
+
descriptionKey: "provider-reolink:schema.s_debug.debugGeneral.description",
|
|
196837
198485
|
default: false,
|
|
196838
198486
|
style: "switch"
|
|
196839
198487
|
}, {
|
|
196840
198488
|
type: "multiselect",
|
|
196841
198489
|
key: "debugSocketLogs",
|
|
196842
198490
|
label: "Socket trace categories",
|
|
198491
|
+
labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.label",
|
|
196843
198492
|
description: "Per-area lib tracing. Pick only what you need; each adds log volume.",
|
|
198493
|
+
descriptionKey: "provider-reolink:schema.s_debug.debugSocketLogs.description",
|
|
196844
198494
|
default: [],
|
|
196845
198495
|
options: [
|
|
196846
198496
|
{
|
|
196847
198497
|
value: "debugRtsp",
|
|
196848
|
-
label: "RTSP (proxy/server traffic)"
|
|
198498
|
+
label: "RTSP (proxy/server traffic)",
|
|
198499
|
+
labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.o_debugRtsp.label"
|
|
196849
198500
|
},
|
|
196850
198501
|
{
|
|
196851
198502
|
value: "traceNativeStream",
|
|
196852
|
-
label: "Native stream (cmd 3/4 + H.264/H.265 + param sets)"
|
|
198503
|
+
label: "Native stream (cmd 3/4 + H.264/H.265 + param sets)",
|
|
198504
|
+
labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.o_traceNativeStream.label"
|
|
196853
198505
|
},
|
|
196854
198506
|
{
|
|
196855
198507
|
value: "traceRecordings",
|
|
196856
|
-
label: "Recordings (FileInfoList, findAlarmVideo, download)"
|
|
198508
|
+
label: "Recordings (FileInfoList, findAlarmVideo, download)",
|
|
198509
|
+
labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.o_traceRecordings.label"
|
|
196857
198510
|
},
|
|
196858
198511
|
{
|
|
196859
198512
|
value: "traceTalk",
|
|
196860
|
-
label: "Talkback (cmd 10/11/201/202)"
|
|
198513
|
+
label: "Talkback (cmd 10/11/201/202)",
|
|
198514
|
+
labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.o_traceTalk.label"
|
|
196861
198515
|
},
|
|
196862
198516
|
{
|
|
196863
198517
|
value: "traceEvents",
|
|
196864
|
-
label: "Events (cmd 33 — AlarmEventList push)"
|
|
198518
|
+
label: "Events (cmd 33 — AlarmEventList push)",
|
|
198519
|
+
labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.o_traceEvents.label"
|
|
196865
198520
|
}
|
|
196866
198521
|
]
|
|
196867
198522
|
}]
|
|
@@ -198336,13 +199991,16 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
198336
199991
|
id: "connection",
|
|
198337
199992
|
tab: "general",
|
|
198338
199993
|
title: "Connection",
|
|
199994
|
+
titleKey: "provider-reolink:hub.s_connection.title",
|
|
198339
199995
|
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.",
|
|
199996
|
+
descriptionKey: "provider-reolink:hub.s_connection.description",
|
|
198340
199997
|
columns: 2,
|
|
198341
199998
|
fields: [
|
|
198342
199999
|
{
|
|
198343
200000
|
type: "text",
|
|
198344
200001
|
key: "host",
|
|
198345
200002
|
label: "Hub IP",
|
|
200003
|
+
labelKey: "provider-reolink:hub.s_connection.host.label",
|
|
198346
200004
|
required: true,
|
|
198347
200005
|
placeholder: "192.168.10.100"
|
|
198348
200006
|
},
|
|
@@ -198350,6 +200008,7 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
198350
200008
|
type: "number",
|
|
198351
200009
|
key: "port",
|
|
198352
200010
|
label: "Port",
|
|
200011
|
+
labelKey: "provider-reolink:hub.s_connection.port.label",
|
|
198353
200012
|
default: 9e3,
|
|
198354
200013
|
min: 1,
|
|
198355
200014
|
max: 65535,
|
|
@@ -198359,12 +200018,14 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
198359
200018
|
type: "text",
|
|
198360
200019
|
key: "username",
|
|
198361
200020
|
label: "Username",
|
|
200021
|
+
labelKey: "provider-reolink:hub.s_connection.username.label",
|
|
198362
200022
|
default: "admin"
|
|
198363
200023
|
},
|
|
198364
200024
|
{
|
|
198365
200025
|
type: "password",
|
|
198366
200026
|
key: "password",
|
|
198367
200027
|
label: "Password",
|
|
200028
|
+
labelKey: "provider-reolink:hub.s_connection.password.label",
|
|
198368
200029
|
required: true,
|
|
198369
200030
|
showToggle: true
|
|
198370
200031
|
}
|
|
@@ -198374,18 +200035,22 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
198374
200035
|
id: "identity",
|
|
198375
200036
|
tab: "general",
|
|
198376
200037
|
title: "Hub identity",
|
|
200038
|
+
titleKey: "provider-reolink:hub.s_identity.title",
|
|
198377
200039
|
description: "Read-only summary from the autodetect probe. Channel count and model are persisted at first contact so the panel renders without re-probing.",
|
|
200040
|
+
descriptionKey: "provider-reolink:hub.s_identity.description",
|
|
198378
200041
|
columns: 2,
|
|
198379
200042
|
fields: [{
|
|
198380
200043
|
type: "text",
|
|
198381
200044
|
key: "_model",
|
|
198382
200045
|
label: "Model",
|
|
200046
|
+
labelKey: "provider-reolink:hub.s_identity._model.label",
|
|
198383
200047
|
default: cache?.model ?? "unknown",
|
|
198384
200048
|
disabled: true
|
|
198385
200049
|
}, {
|
|
198386
200050
|
type: "text",
|
|
198387
200051
|
key: "_channelCount",
|
|
198388
200052
|
label: "Total channels",
|
|
200053
|
+
labelKey: "provider-reolink:hub.s_identity._channelCount.label",
|
|
198389
200054
|
default: String(cache?.channelCount ?? 0),
|
|
198390
200055
|
disabled: true
|
|
198391
200056
|
}]
|
|
@@ -198394,41 +200059,52 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
198394
200059
|
id: "debug",
|
|
198395
200060
|
tab: "advanced",
|
|
198396
200061
|
title: "Debug",
|
|
200062
|
+
titleKey: "provider-reolink:hub.s_debug.title",
|
|
198397
200063
|
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.",
|
|
200064
|
+
descriptionKey: "provider-reolink:hub.s_debug.description",
|
|
198398
200065
|
columns: 1,
|
|
198399
200066
|
fields: [{
|
|
198400
200067
|
type: "boolean",
|
|
198401
200068
|
key: "debugGeneral",
|
|
198402
200069
|
label: "General debug logs",
|
|
200070
|
+
labelKey: "provider-reolink:hub.s_debug.debugGeneral.label",
|
|
198403
200071
|
description: "Forwards `DebugOptions.general=true` — verbose lib protocol logs.",
|
|
200072
|
+
descriptionKey: "provider-reolink:hub.s_debug.debugGeneral.description",
|
|
198404
200073
|
default: false,
|
|
198405
200074
|
style: "switch"
|
|
198406
200075
|
}, {
|
|
198407
200076
|
type: "multiselect",
|
|
198408
200077
|
key: "debugSocketLogs",
|
|
198409
200078
|
label: "Socket trace categories",
|
|
200079
|
+
labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.label",
|
|
198410
200080
|
description: "Per-area lib tracing. Pick only what you need; each adds log volume.",
|
|
200081
|
+
descriptionKey: "provider-reolink:hub.s_debug.debugSocketLogs.description",
|
|
198411
200082
|
default: [],
|
|
198412
200083
|
options: [
|
|
198413
200084
|
{
|
|
198414
200085
|
value: "debugRtsp",
|
|
198415
|
-
label: "RTSP (proxy/server traffic)"
|
|
200086
|
+
label: "RTSP (proxy/server traffic)",
|
|
200087
|
+
labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.o_debugRtsp.label"
|
|
198416
200088
|
},
|
|
198417
200089
|
{
|
|
198418
200090
|
value: "traceNativeStream",
|
|
198419
|
-
label: "Native stream (cmd 3/4 + H.264/H.265 + param sets)"
|
|
200091
|
+
label: "Native stream (cmd 3/4 + H.264/H.265 + param sets)",
|
|
200092
|
+
labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.o_traceNativeStream.label"
|
|
198420
200093
|
},
|
|
198421
200094
|
{
|
|
198422
200095
|
value: "traceRecordings",
|
|
198423
|
-
label: "Recordings (FileInfoList, findAlarmVideo, download)"
|
|
200096
|
+
label: "Recordings (FileInfoList, findAlarmVideo, download)",
|
|
200097
|
+
labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.o_traceRecordings.label"
|
|
198424
200098
|
},
|
|
198425
200099
|
{
|
|
198426
200100
|
value: "traceTalk",
|
|
198427
|
-
label: "Talkback (cmd 10/11/201/202)"
|
|
200101
|
+
label: "Talkback (cmd 10/11/201/202)",
|
|
200102
|
+
labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.o_traceTalk.label"
|
|
198428
200103
|
},
|
|
198429
200104
|
{
|
|
198430
200105
|
value: "traceEvents",
|
|
198431
|
-
label: "Events (cmd 33 — AlarmEventList push)"
|
|
200106
|
+
label: "Events (cmd 33 — AlarmEventList push)",
|
|
200107
|
+
labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.o_traceEvents.label"
|
|
198432
200108
|
}
|
|
198433
200109
|
]
|
|
198434
200110
|
}]
|
|
@@ -199010,8 +200686,8 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
199010
200686
|
this.api = null;
|
|
199011
200687
|
}
|
|
199012
200688
|
const cfg = this.config.values;
|
|
199013
|
-
if (!cfg.host) throw
|
|
199014
|
-
if (!cfg.password) throw
|
|
200689
|
+
if (!cfg.host) throw userError("reolink.hub-host-missing", void 0, "Reolink Hub: host not configured");
|
|
200690
|
+
if (!cfg.password) throw userError("reolink.hub-password-missing", void 0, "Reolink Hub: password not configured");
|
|
199015
200691
|
const api = new ReolinkBaichuanApi({
|
|
199016
200692
|
host: cfg.host,
|
|
199017
200693
|
port: cfg.port,
|
|
@@ -199163,31 +200839,38 @@ function buildDiscoveryParamsFormSchema() {
|
|
|
199163
200839
|
return { sections: [{
|
|
199164
200840
|
id: "credentials",
|
|
199165
200841
|
title: "Credentials",
|
|
200842
|
+
titleKey: "provider-reolink:discoveryParams.s_credentials.title",
|
|
199166
200843
|
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.",
|
|
200844
|
+
descriptionKey: "provider-reolink:discoveryParams.s_credentials.description",
|
|
199167
200845
|
columns: 2,
|
|
199168
200846
|
fields: [{
|
|
199169
200847
|
type: "text",
|
|
199170
200848
|
key: "username",
|
|
199171
200849
|
label: "Username",
|
|
200850
|
+
labelKey: "provider-reolink:discoveryParams.s_credentials.username.label",
|
|
199172
200851
|
default: "admin",
|
|
199173
200852
|
required: true
|
|
199174
200853
|
}, {
|
|
199175
200854
|
type: "password",
|
|
199176
200855
|
key: "password",
|
|
199177
200856
|
label: "Password",
|
|
200857
|
+
labelKey: "provider-reolink:discoveryParams.s_credentials.password.label",
|
|
199178
200858
|
required: true,
|
|
199179
200859
|
showToggle: true
|
|
199180
200860
|
}]
|
|
199181
200861
|
}, {
|
|
199182
200862
|
id: "scan",
|
|
199183
200863
|
title: "Scan options",
|
|
200864
|
+
titleKey: "provider-reolink:discoveryParams.s_scan.title",
|
|
199184
200865
|
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).",
|
|
200866
|
+
descriptionKey: "provider-reolink:discoveryParams.s_scan.description",
|
|
199185
200867
|
columns: 1,
|
|
199186
200868
|
fields: [
|
|
199187
200869
|
{
|
|
199188
200870
|
type: "text",
|
|
199189
200871
|
key: "networkCidr",
|
|
199190
200872
|
label: "Network (CIDR)",
|
|
200873
|
+
labelKey: "provider-reolink:discoveryParams.s_scan.networkCidr.label",
|
|
199191
200874
|
required: false,
|
|
199192
200875
|
placeholder: "192.168.20.0/24"
|
|
199193
200876
|
},
|
|
@@ -199195,12 +200878,14 @@ function buildDiscoveryParamsFormSchema() {
|
|
|
199195
200878
|
type: "boolean",
|
|
199196
200879
|
key: "enableOnvif",
|
|
199197
200880
|
label: "Include ONVIF discovery",
|
|
200881
|
+
labelKey: "provider-reolink:discoveryParams.s_scan.enableOnvif.label",
|
|
199198
200882
|
default: true
|
|
199199
200883
|
},
|
|
199200
200884
|
{
|
|
199201
200885
|
type: "number",
|
|
199202
200886
|
key: "timeoutMs",
|
|
199203
200887
|
label: "Scan timeout (ms)",
|
|
200888
|
+
labelKey: "provider-reolink:discoveryParams.s_scan.timeoutMs.label",
|
|
199204
200889
|
min: 1e3,
|
|
199205
200890
|
max: 3e4,
|
|
199206
200891
|
default: 5e3
|
|
@@ -199213,11 +200898,13 @@ function buildCreationFormSchema() {
|
|
|
199213
200898
|
{
|
|
199214
200899
|
id: "identity",
|
|
199215
200900
|
title: "Camera",
|
|
200901
|
+
titleKey: "provider-reolink:creation.s_identity.title",
|
|
199216
200902
|
columns: 1,
|
|
199217
200903
|
fields: [{
|
|
199218
200904
|
type: "text",
|
|
199219
200905
|
key: "name",
|
|
199220
200906
|
label: "Name",
|
|
200907
|
+
labelKey: "provider-reolink:creation.s_identity.name.label",
|
|
199221
200908
|
required: true,
|
|
199222
200909
|
placeholder: "Front Door"
|
|
199223
200910
|
}]
|
|
@@ -199225,18 +200912,22 @@ function buildCreationFormSchema() {
|
|
|
199225
200912
|
{
|
|
199226
200913
|
id: "credentials",
|
|
199227
200914
|
title: "Credentials",
|
|
200915
|
+
titleKey: "provider-reolink:creation.s_credentials.title",
|
|
199228
200916
|
description: "Required for the autodetect probe — entered before the host so Test can run immediately.",
|
|
200917
|
+
descriptionKey: "provider-reolink:creation.s_credentials.description",
|
|
199229
200918
|
columns: 2,
|
|
199230
200919
|
fields: [{
|
|
199231
200920
|
type: "text",
|
|
199232
200921
|
key: "username",
|
|
199233
200922
|
label: "Username",
|
|
200923
|
+
labelKey: "provider-reolink:creation.s_credentials.username.label",
|
|
199234
200924
|
default: "admin",
|
|
199235
200925
|
required: true
|
|
199236
200926
|
}, {
|
|
199237
200927
|
type: "password",
|
|
199238
200928
|
key: "password",
|
|
199239
200929
|
label: "Password",
|
|
200930
|
+
labelKey: "provider-reolink:creation.s_credentials.password.label",
|
|
199240
200931
|
required: true,
|
|
199241
200932
|
showToggle: true
|
|
199242
200933
|
}]
|
|
@@ -199244,27 +200935,34 @@ function buildCreationFormSchema() {
|
|
|
199244
200935
|
{
|
|
199245
200936
|
id: "connection",
|
|
199246
200937
|
title: "Connection",
|
|
200938
|
+
titleKey: "provider-reolink:creation.s_connection.title",
|
|
199247
200939
|
description: "Click Test to auto-detect the device type (regular camera / NVR / battery / UDP-only). The detected type is then used at save time.",
|
|
200940
|
+
descriptionKey: "provider-reolink:creation.s_connection.description",
|
|
199248
200941
|
columns: 2,
|
|
199249
200942
|
fields: [
|
|
199250
200943
|
{
|
|
199251
200944
|
type: "select",
|
|
199252
200945
|
key: "transport",
|
|
199253
200946
|
label: "Connection mode",
|
|
200947
|
+
labelKey: "provider-reolink:creation.s_connection.transport.label",
|
|
199254
200948
|
default: "auto",
|
|
199255
200949
|
description: "Auto: try TCP first, fall back to UDP — best for unknown devices. UDP is required for battery cameras behind NAT.",
|
|
200950
|
+
descriptionKey: "provider-reolink:creation.s_connection.transport.description",
|
|
199256
200951
|
options: [
|
|
199257
200952
|
{
|
|
199258
200953
|
value: "auto",
|
|
199259
|
-
label: "Auto (recommended)"
|
|
200954
|
+
label: "Auto (recommended)",
|
|
200955
|
+
labelKey: "provider-reolink:creation.s_connection.transport.o_auto.label"
|
|
199260
200956
|
},
|
|
199261
200957
|
{
|
|
199262
200958
|
value: "tcp",
|
|
199263
|
-
label: "TCP only"
|
|
200959
|
+
label: "TCP only",
|
|
200960
|
+
labelKey: "provider-reolink:creation.s_connection.transport.o_tcp.label"
|
|
199264
200961
|
},
|
|
199265
200962
|
{
|
|
199266
200963
|
value: "udp",
|
|
199267
|
-
label: "UDP only (battery / cloud)"
|
|
200964
|
+
label: "UDP only (battery / cloud)",
|
|
200965
|
+
labelKey: "provider-reolink:creation.s_connection.transport.o_udp.label"
|
|
199268
200966
|
}
|
|
199269
200967
|
]
|
|
199270
200968
|
},
|
|
@@ -199272,20 +200970,24 @@ function buildCreationFormSchema() {
|
|
|
199272
200970
|
type: "probe",
|
|
199273
200971
|
key: "host",
|
|
199274
200972
|
label: "Host (IP / hostname / UID)",
|
|
200973
|
+
labelKey: "provider-reolink:creation.s_connection.host.label",
|
|
199275
200974
|
required: true,
|
|
199276
200975
|
placeholder: "192.168.10.100",
|
|
199277
200976
|
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.",
|
|
200977
|
+
descriptionKey: "provider-reolink:creation.s_connection.host.description",
|
|
199278
200978
|
inputType: "text"
|
|
199279
200979
|
},
|
|
199280
200980
|
{
|
|
199281
200981
|
type: "number",
|
|
199282
200982
|
key: "port",
|
|
199283
200983
|
label: "Port",
|
|
200984
|
+
labelKey: "provider-reolink:creation.s_connection.port.label",
|
|
199284
200985
|
default: 9e3,
|
|
199285
200986
|
min: 1,
|
|
199286
200987
|
max: 65535,
|
|
199287
200988
|
step: 1,
|
|
199288
200989
|
description: "Baichuan port. Default 9000 — applies to TCP. Ignored for UDP transport.",
|
|
200990
|
+
descriptionKey: "provider-reolink:creation.s_connection.port.description",
|
|
199289
200991
|
showWhen: {
|
|
199290
200992
|
field: "transport",
|
|
199291
200993
|
notEquals: "udp"
|
|
@@ -199295,8 +200997,10 @@ function buildCreationFormSchema() {
|
|
|
199295
200997
|
type: "text",
|
|
199296
200998
|
key: "uid",
|
|
199297
200999
|
label: "Device UID",
|
|
201000
|
+
labelKey: "provider-reolink:creation.s_connection.uid.label",
|
|
199298
201001
|
placeholder: "9527000XXXXXXXX",
|
|
199299
201002
|
description: "Required for battery / UDP cameras when not on the same LAN. Optional for local-direct UDP discovery and ignored for pure TCP.",
|
|
201003
|
+
descriptionKey: "provider-reolink:creation.s_connection.uid.description",
|
|
199300
201004
|
showWhen: {
|
|
199301
201005
|
field: "transport",
|
|
199302
201006
|
notEquals: "tcp"
|
|
@@ -199835,25 +201539,30 @@ function buildEmailPushSettingsSchema(recommendedHost) {
|
|
|
199835
201539
|
return { sections: [{
|
|
199836
201540
|
id: "email-push",
|
|
199837
201541
|
title: "Battery-cam Motion (Email/SMTP Push)",
|
|
201542
|
+
titleKey: "provider-reolink:emailPushSettings.s_email-push.title",
|
|
199838
201543
|
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.",
|
|
201544
|
+
descriptionKey: "provider-reolink:emailPushSettings.s_email-push.description",
|
|
199839
201545
|
columns: 2,
|
|
199840
201546
|
fields: [
|
|
199841
201547
|
{
|
|
199842
201548
|
type: "boolean",
|
|
199843
201549
|
key: "emailPushEnabled",
|
|
199844
201550
|
label: "Enable Email Push Server",
|
|
201551
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push.emailPushEnabled.label",
|
|
199845
201552
|
default: true
|
|
199846
201553
|
},
|
|
199847
201554
|
{
|
|
199848
201555
|
type: "info",
|
|
199849
201556
|
key: "emailPushRecommendedHost",
|
|
199850
201557
|
label: "Camera-facing host",
|
|
201558
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push.emailPushRecommendedHost.label",
|
|
199851
201559
|
content: `Point cameras at this host: ${recommendedHost}`
|
|
199852
201560
|
},
|
|
199853
201561
|
{
|
|
199854
201562
|
type: "number",
|
|
199855
201563
|
key: "emailPushPort",
|
|
199856
201564
|
label: "SMTP Port",
|
|
201565
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push.emailPushPort.label",
|
|
199857
201566
|
default: DEFAULT_EMAIL_PUSH_PORT,
|
|
199858
201567
|
min: 1,
|
|
199859
201568
|
max: 65535
|
|
@@ -199862,6 +201571,7 @@ function buildEmailPushSettingsSchema(recommendedHost) {
|
|
|
199862
201571
|
type: "text",
|
|
199863
201572
|
key: "emailPushDomain",
|
|
199864
201573
|
label: "Virtual Domain",
|
|
201574
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push.emailPushDomain.label",
|
|
199865
201575
|
default: DEFAULT_EMAIL_PUSH_DOMAIN,
|
|
199866
201576
|
placeholder: DEFAULT_EMAIL_PUSH_DOMAIN
|
|
199867
201577
|
}
|
|
@@ -199869,24 +201579,29 @@ function buildEmailPushSettingsSchema(recommendedHost) {
|
|
|
199869
201579
|
}, {
|
|
199870
201580
|
id: "email-push-auth",
|
|
199871
201581
|
title: "Email Push Authentication",
|
|
201582
|
+
titleKey: "provider-reolink:emailPushSettings.s_email-push-auth.title",
|
|
199872
201583
|
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.",
|
|
201584
|
+
descriptionKey: "provider-reolink:emailPushSettings.s_email-push-auth.description",
|
|
199873
201585
|
columns: 2,
|
|
199874
201586
|
fields: [
|
|
199875
201587
|
{
|
|
199876
201588
|
type: "boolean",
|
|
199877
201589
|
key: "emailPushRequireAuth",
|
|
199878
201590
|
label: "Require AUTH",
|
|
201591
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push-auth.emailPushRequireAuth.label",
|
|
199879
201592
|
default: true
|
|
199880
201593
|
},
|
|
199881
201594
|
{
|
|
199882
201595
|
type: "text",
|
|
199883
201596
|
key: "emailPushAuthUsername",
|
|
199884
|
-
label: "Auth Username"
|
|
201597
|
+
label: "Auth Username",
|
|
201598
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push-auth.emailPushAuthUsername.label"
|
|
199885
201599
|
},
|
|
199886
201600
|
{
|
|
199887
201601
|
type: "password",
|
|
199888
201602
|
key: "emailPushAuthPassword",
|
|
199889
201603
|
label: "Auth Password",
|
|
201604
|
+
labelKey: "provider-reolink:emailPushSettings.s_email-push-auth.emailPushAuthPassword.label",
|
|
199890
201605
|
showToggle: true
|
|
199891
201606
|
}
|
|
199892
201607
|
]
|
|
@@ -200073,25 +201788,30 @@ function buildBaichuanWebhookSettingsSchema(recommendedHost) {
|
|
|
200073
201788
|
return { sections: [{
|
|
200074
201789
|
id: "baichuan-webhook",
|
|
200075
201790
|
title: "Battery-cam Motion (HaCfg Webhook)",
|
|
201791
|
+
titleKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.title",
|
|
200076
201792
|
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).",
|
|
201793
|
+
descriptionKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.description",
|
|
200077
201794
|
columns: 2,
|
|
200078
201795
|
fields: [
|
|
200079
201796
|
{
|
|
200080
201797
|
type: "boolean",
|
|
200081
201798
|
key: "baichuanWebhookEnabled",
|
|
200082
201799
|
label: "Enable HaCfg Webhook Server",
|
|
201800
|
+
labelKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.baichuanWebhookEnabled.label",
|
|
200083
201801
|
default: true
|
|
200084
201802
|
},
|
|
200085
201803
|
{
|
|
200086
201804
|
type: "info",
|
|
200087
201805
|
key: "baichuanWebhookRecommendedHost",
|
|
200088
201806
|
label: "Camera-facing host",
|
|
201807
|
+
labelKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.baichuanWebhookRecommendedHost.label",
|
|
200089
201808
|
content: `Point cameras at this host: ${recommendedHost}`
|
|
200090
201809
|
},
|
|
200091
201810
|
{
|
|
200092
201811
|
type: "number",
|
|
200093
201812
|
key: "baichuanWebhookPort",
|
|
200094
201813
|
label: "HTTP Port",
|
|
201814
|
+
labelKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.baichuanWebhookPort.label",
|
|
200095
201815
|
default: DEFAULT_BAICHUAN_WEBHOOK_PORT,
|
|
200096
201816
|
min: 1,
|
|
200097
201817
|
max: 65535
|
|
@@ -200100,8 +201820,10 @@ function buildBaichuanWebhookSettingsSchema(recommendedHost) {
|
|
|
200100
201820
|
type: "text",
|
|
200101
201821
|
key: "baichuanWebhookBindHost",
|
|
200102
201822
|
label: "Bind host",
|
|
201823
|
+
labelKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.baichuanWebhookBindHost.label",
|
|
200103
201824
|
default: "0.0.0.0",
|
|
200104
|
-
description: "0.0.0.0 accepts on every interface (cameras on LAN)."
|
|
201825
|
+
description: "0.0.0.0 accepts on every interface (cameras on LAN).",
|
|
201826
|
+
descriptionKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.baichuanWebhookBindHost.description"
|
|
200105
201827
|
}
|
|
200106
201828
|
]
|
|
200107
201829
|
}] };
|
|
@@ -200657,7 +202379,7 @@ var ReolinkProviderAddon = class extends BaseDeviceProvider {
|
|
|
200657
202379
|
},
|
|
200658
202380
|
wake: async (deviceId) => {
|
|
200659
202381
|
const device = this.ctx.kernel.deviceRegistry?.getById(deviceId);
|
|
200660
|
-
if (!(device instanceof ReolinkCamera)) throw
|
|
202382
|
+
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`);
|
|
200661
202383
|
await device.wakeForClipCatalogRefresh();
|
|
200662
202384
|
},
|
|
200663
202385
|
prefetchStills: async (deviceId) => service.prefetchThumbnails(deviceId),
|