@camstack/addon-provider-reolink 1.2.202 → 1.2.203

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 CHANGED
@@ -36,7 +36,7 @@ let node_os = require("node:os");
36
36
  node_os = require_chunk.__toESM(node_os, 1);
37
37
  let node_fs = require("node:fs");
38
38
  node_fs = require_chunk.__toESM(node_fs, 1);
39
- //#region ../types/dist/event-category-7pZEBmVg.mjs
39
+ //#region ../types/dist/event-category-BfJwUd2S.mjs
40
40
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
41
41
  EventCategory["SystemBoot"] = "system.boot";
42
42
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -353,6 +353,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
353
353
  */
354
354
  EventCategory["PipelineDetectionBlind"] = "pipeline.detection-blind";
355
355
  /**
356
+ * A camera's motion source has fired constantly with no subject for an hour
357
+ * (motion duty or session count over the bar, zero detections) — it is not
358
+ * blind, its motion zones or sensitivity want tuning (D907). Paired with
359
+ * {@link PipelineMotionCalm}.
360
+ */
361
+ EventCategory["PipelineMotionNoisy"] = "pipeline.motion-noisy";
362
+ /** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
363
+ EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
364
+ /**
356
365
  * Per-camera pipeline config was mutated by the orchestrator
357
366
  * (3-level settings change via `setAgentAddonDefaults` /
358
367
  * `setCameraStepToggle` / `setCameraPipelineForAgent` or a
@@ -5459,7 +5468,7 @@ var ZodIssueCode = {
5459
5468
  var ZodFirstPartyTypeKind;
5460
5469
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5461
5470
  //#endregion
5462
- //#region ../types/dist/sleep-CueztlR1.mjs
5471
+ //#region ../types/dist/sleep-DJFUfKvA.mjs
5463
5472
  /**
5464
5473
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5465
5474
  * window to float samples (D455).
@@ -7992,7 +8001,7 @@ var EntryDescriptorSchema = object({
7992
8001
  /** JSON Schema of the entry body; `secret: true` marks a password field. */
7993
8002
  fields: record(string(), unknown())
7994
8003
  }).strict();
7995
- /** What crosses the wire and sits in the engine's catalog: JSON only, no Zod. */
8004
+ /** What crosses the wire from an addon: JSON only, no Zod. An unknown key is refused. */
7996
8005
  var RecordKindDeclarationSchema = object({
7997
8006
  database: _enum(RECORD_DATABASES).default("settings"),
7998
8007
  class: _enum(RECORD_CLASSES),
@@ -8011,14 +8020,6 @@ var RecordKindDeclarationSchema = object({
8011
8020
  secretPaths: array(string().min(1)).default([]),
8012
8021
  /** The id key of each array that carries a secret (`{ headers: 'name' }`). */
8013
8022
  secretArrayKeys: record(string(), string()).default({}),
8014
- /**
8015
- * RETIRED (D900): the legacy table a kind adopted from during the records
8016
- * migration. Nothing declares it any more and nothing reads it; the schema
8017
- * still ACCEPTS it because the catalog rows the migration wrote carry it
8018
- * (an orphaned kind is never redeclared) and an addon built before the
8019
- * removal still sends it. Never set it.
8020
- */
8021
- adoptsFrom: string().min(1).optional(),
8022
8023
  /** Kinds that must agree through `transact` sit in one file under one family name. */
8023
8024
  transactFamily: string().min(1).optional(),
8024
8025
  entry: EntryDescriptorSchema.optional()
@@ -13310,17 +13311,6 @@ object({
13310
13311
  createdAt: number(),
13311
13312
  updatedAt: number()
13312
13313
  });
13313
- object({
13314
- id: string(),
13315
- label: string(),
13316
- isAdmin: boolean().default(false),
13317
- allowedProviders: AllowedProviderSchema,
13318
- allowedDevices: AllowedDevicesSchema,
13319
- tokenHash: string(),
13320
- tokenPrefix: string(),
13321
- createdAt: number(),
13322
- lastUsedAt: number().optional()
13323
- });
13324
13314
  object({
13325
13315
  id: string(),
13326
13316
  userId: string(),
@@ -17302,16 +17292,36 @@ var RecordKindStateSchema = _enum([
17302
17292
  var DeclareKindResultSchema = object({
17303
17293
  kindId: number().int(),
17304
17294
  state: RecordKindStateSchema,
17305
- createdIndexes: array(string()),
17306
- /**
17307
- * RETIRED (D900): always `null`. It carried the records-migration boot guard;
17308
- * it stays on the wire, null, because an addon built before the removal reads
17309
- * an ABSENT field as "adoption pending" and refuses to start.
17310
- */
17311
- adoptionPending: _null()
17295
+ createdIndexes: array(string())
17312
17296
  });
17313
17297
  /** Keychain refs a write released (the old marker is gone from the row): the owner deletes the values. */
17314
17298
  var SecretRefsList = array(string());
17299
+ /**
17300
+ * One op of a `transact`: the single-row writes, each on a kind of the caller.
17301
+ * All ops of one call share ONE database file and ONE `transactFamily`.
17302
+ */
17303
+ var RecordTransactOpSchema = discriminatedUnion("op", [
17304
+ object({
17305
+ op: literal("put"),
17306
+ kind: RecordKindNameSchema,
17307
+ record: RecordInputSchema,
17308
+ ifRev: number().int().min(0).optional()
17309
+ }),
17310
+ object({
17311
+ op: literal("patch"),
17312
+ kind: RecordKindNameSchema,
17313
+ id: RecordIdSchema,
17314
+ data: RecordBodySchema,
17315
+ at: number().int().nullable().optional(),
17316
+ expiresAt: number().int().nullable().optional(),
17317
+ ifRev: number().int().min(1).optional()
17318
+ }),
17319
+ object({
17320
+ op: literal("delete"),
17321
+ kind: RecordKindNameSchema,
17322
+ id: RecordIdSchema
17323
+ })
17324
+ ]);
17315
17325
  var RecordSecretRefsSchema = record(string(), record(string(), string()));
17316
17326
  method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema) }), object({ kinds: record(string(), DeclareKindResultSchema) }), {
17317
17327
  kind: "mutation",
@@ -17418,6 +17428,16 @@ method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema)
17418
17428
  }), {
17419
17429
  kind: "mutation",
17420
17430
  auth: "admin"
17431
+ }), method(object({ ops: array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), object({
17432
+ results: array(object({
17433
+ rev: number().int().nullable(),
17434
+ deleted: boolean()
17435
+ })),
17436
+ releasedRefs: SecretRefsList,
17437
+ secretRefs: SecretRefsList
17438
+ }), {
17439
+ kind: "mutation",
17440
+ auth: "admin"
17421
17441
  }), method(object({
17422
17442
  deviceId: number().int(),
17423
17443
  kinds: array(RecordKindNameSchema).optional()
@@ -43165,9 +43185,13 @@ var NcSystemEventKindSchema = _enum([
43165
43185
  "node-updating",
43166
43186
  "node-inference-unavailable",
43167
43187
  "detection-blind",
43188
+ "motion-noisy",
43189
+ "motion-calm",
43168
43190
  "recording-stalled",
43169
43191
  "recording-healthy",
43170
43192
  "recording-degraded",
43193
+ "device-attention-required",
43194
+ "device-attention-resolved",
43171
43195
  "storage-location-low",
43172
43196
  "storage-location-critical",
43173
43197
  "storage-location-ok",
@@ -57013,6 +57037,16 @@ var DishwasherStatusSchema = object({
57013
57037
  powerState: string().nullable(),
57014
57038
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
57015
57039
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
57040
+ /**
57041
+ * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
57042
+ * combined care-and-filter reminder raised); false when every such reminder reads clear; null
57043
+ * when none is reported. A cleared reminder is not an unknown one.
57044
+ */
57045
+ filterCleaningDue: boolean().nullable(),
57046
+ /** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
57047
+ machineCareDue: boolean().nullable(),
57048
+ /** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
57049
+ machineCareRemainingRuns: number().int().nonnegative().nullable(),
57016
57050
  /** Option states: null when the appliance does not expose the option or has not said. */
57017
57051
  halfLoad: boolean().nullable(),
57018
57052
  hygienePlus: boolean().nullable(),
@@ -66233,16 +66267,6 @@ var UpdateUserInputSchema = object({
66233
66267
  allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
66234
66268
  scopes: array(TokenScopeSchema).optional()
66235
66269
  });
66236
- var ApiKeySummarySchema = object({
66237
- id: string(),
66238
- label: string(),
66239
- isAdmin: boolean().default(false),
66240
- allowedProviders: union([array(string()), literal("*")]).optional(),
66241
- allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
66242
- tokenPrefix: string(),
66243
- createdAt: number(),
66244
- lastUsedAt: number().optional()
66245
- });
66246
66270
  var OauthSessionSummarySchema = object({
66247
66271
  id: string(),
66248
66272
  userId: string(),
@@ -66264,8 +66288,7 @@ var TotpStatusSchema = object({
66264
66288
  confirmedAt: number().nullable()
66265
66289
  });
66266
66290
  /**
66267
- * user-management — singleton capability for user accounts and the
66268
- * legacy API-key rows.
66291
+ * user-management — singleton capability for user accounts.
66269
66292
  *
66270
66293
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
66271
66294
  * — the subset check on `setUserScopes` is moot
@@ -66321,10 +66344,6 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
66321
66344
  }), UserSummarySchema.extend({ passwordHash: string() }).nullable(), {
66322
66345
  kind: "mutation",
66323
66346
  access: "view"
66324
- }), method(_void(), array(ApiKeySummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: literal(true) }), {
66325
- kind: "mutation",
66326
- auth: "admin",
66327
- access: "delete"
66328
66347
  }), method(object({ userId: string() }), TotpSetupResultSchema, {
66329
66348
  kind: "mutation",
66330
66349
  auth: "admin",
@@ -75795,6 +75814,12 @@ Object.freeze({
75795
75814
  addonId: null,
75796
75815
  access: "view"
75797
75816
  },
75817
+ "records.transact": {
75818
+ capName: "records",
75819
+ capScope: "system",
75820
+ addonId: null,
75821
+ access: "create"
75822
+ },
75798
75823
  "sceneMonitor.captureReference": {
75799
75824
  capName: "scene-monitor",
75800
75825
  capScope: "device",
@@ -77127,12 +77152,6 @@ Object.freeze({
77127
77152
  addonId: null,
77128
77153
  access: "view"
77129
77154
  },
77130
- "userManagement.listApiKeys": {
77131
- capName: "user-management",
77132
- capScope: "system",
77133
- addonId: null,
77134
- access: "view"
77135
- },
77136
77155
  "userManagement.listExternalIdentities": {
77137
77156
  capName: "user-management",
77138
77157
  capScope: "system",
@@ -77187,12 +77206,6 @@ Object.freeze({
77187
77206
  addonId: null,
77188
77207
  access: "create"
77189
77208
  },
77190
- "userManagement.revokeApiKey": {
77191
- capName: "user-management",
77192
- capScope: "system",
77193
- addonId: null,
77194
- access: "delete"
77195
- },
77196
77209
  "userManagement.revokeOauthSession": {
77197
77210
  capName: "user-management",
77198
77211
  capScope: "system",
@@ -80709,9 +80722,13 @@ new Map(Object.entries({
80709
80722
  "stream-online": "device-events",
80710
80723
  "stream-offline": "device-events",
80711
80724
  "detection-blind": "device-events",
80725
+ "motion-noisy": "device-events",
80726
+ "motion-calm": "device-events",
80712
80727
  "recording-stalled": "device-events",
80713
80728
  "recording-healthy": "device-events",
80714
80729
  "recording-degraded": "device-events",
80730
+ "device-attention-required": "device-events",
80731
+ "device-attention-resolved": "device-events",
80715
80732
  "node-online": "system",
80716
80733
  "node-offline": "system",
80717
80734
  "node-restarting": "system",
@@ -80794,6 +80811,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
80794
80811
  label: "Detecting nothing",
80795
80812
  kinds: ["detection-blind"]
80796
80813
  },
80814
+ {
80815
+ id: "motion-noise",
80816
+ family: "device-events",
80817
+ label: "Motion without a subject",
80818
+ kinds: ["motion-noisy", "motion-calm"]
80819
+ },
80797
80820
  {
80798
80821
  id: "recording",
80799
80822
  family: "device-events",
@@ -80804,6 +80827,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
80804
80827
  "recording-degraded"
80805
80828
  ]
80806
80829
  },
80830
+ {
80831
+ id: "device-attention",
80832
+ family: "device-events",
80833
+ label: "Needs attention",
80834
+ kinds: ["device-attention-required", "device-attention-resolved"]
80835
+ },
80807
80836
  {
80808
80837
  id: "nodes",
80809
80838
  family: "system",
@@ -80943,6 +80972,7 @@ var ALERT_EPISODE = [
80943
80972
  "alert-error",
80944
80973
  "alert-critical-resolved"
80945
80974
  ];
80975
+ var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
80946
80976
  var UPDATES = [
80947
80977
  "addon-update-available",
80948
80978
  "server-update-available",
@@ -80972,9 +81002,12 @@ var DEVICE_EVENTS = [
80972
81002
  "stream-online",
80973
81003
  "stream-offline",
80974
81004
  "detection-blind",
81005
+ "motion-noisy",
81006
+ "motion-calm",
80975
81007
  "recording-stalled",
80976
81008
  "recording-healthy",
80977
81009
  "recording-degraded",
81010
+ ...DEVICE_ATTENTION,
80978
81011
  ...ALARM
80979
81012
  ];
80980
81013
  /** Every kind a summary may speak about — the two summarisable families. */
@@ -81142,7 +81175,9 @@ var STATE_SUMMARY_VARS = [
81142
81175
  [...RULE_TEXT],
81143
81176
  [...RULE_TEXT],
81144
81177
  [...RULE_TEXT],
81145
- ([...RULE_TEXT], [...ALERT_EPISODE]),
81178
+ [...RULE_TEXT],
81179
+ [...RULE_TEXT],
81180
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
81146
81181
  [...RULE_TEXT],
81147
81182
  [...RULE_TEXT],
81148
81183
  [...RULE_TEXT],
@@ -81164,11 +81199,11 @@ var STATE_SUMMARY_VARS = [
81164
81199
  [...RULE_TEXT],
81165
81200
  [...RULE_TEXT],
81166
81201
  [...RULE_TEXT],
81202
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
81167
81203
  ([...RULE_TEXT], [...ALERT_EPISODE]),
81204
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
81168
81205
  ([...RULE_TEXT], [...ALERT_EPISODE]),
81169
- ([...RULE_TEXT], [...ALERT_EPISODE]),
81170
- ([...RULE_TEXT], [...ALERT_EPISODE]),
81171
- ([...RULE_TEXT], [...ALERT_EPISODE]),
81206
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
81172
81207
  [...RULE_TEXT],
81173
81208
  [...RULE_TEXT],
81174
81209
  [...RULE_TEXT],
@@ -81244,6 +81279,15 @@ new Map([
81244
81279
  snapshotLabel: "Tanks low or full now",
81245
81280
  snapshotSection: "tanks"
81246
81281
  },
81282
+ {
81283
+ id: "motion-noise",
81284
+ family: "device-events",
81285
+ label: "Motion without a subject (constant / calm again)",
81286
+ bad: ["motion-noisy"],
81287
+ recovery: ["motion-calm"],
81288
+ snapshotLabel: "Cameras with constant motion now",
81289
+ snapshotSection: null
81290
+ },
81247
81291
  {
81248
81292
  id: "recording-health",
81249
81293
  family: "device-events",
@@ -81253,6 +81297,15 @@ new Map([
81253
81297
  snapshotLabel: "Recordings stalled now",
81254
81298
  snapshotSection: null
81255
81299
  },
81300
+ {
81301
+ id: "device-attention",
81302
+ family: "device-events",
81303
+ label: "Device needs attention (raised / resolved)",
81304
+ bad: ["device-attention-required"],
81305
+ recovery: ["device-attention-resolved"],
81306
+ snapshotLabel: "Devices needing attention now",
81307
+ snapshotSection: null
81308
+ },
81256
81309
  {
81257
81310
  id: "node-connectivity",
81258
81311
  family: "system",
@@ -188577,8 +188630,8 @@ var CLIP_REFRESH_SECTION_ID = "clip-catalog-refresh";
188577
188630
  * settings nobody could reason about. So the difference is in the operator's
188578
188631
  * own text, at both levels, not only in a record.
188579
188632
  */
188580
- var CLIP_CATALOG_REFRESH_MINUTES_DESCRIPTION = "How often CamStack re-reads what a Reolink camera holds on its own storage. It costs almost nothing on a camera it can reach: a hub child is read through the hub on the session that is already open (measured 65 ms, and the camera itself never hears it), and a mains camera is read on its own socket. On a STANDALONE BATTERY camera the timer cannot read anything at all — logging in is what wakes such a camera — so there it only marks the catalog as ageing, and the real re-read happens the next time the camera wakes up for its own reasons (motion, a stream, something you did). Set 0 to switch the timer off.";
188581
- var CLIP_CATALOG_FORCED_WAKE_DESCRIPTION = "Let the refresh timer WAKE this camera. Off unless you mean it: on a standalone battery camera every read is a login and every login is a wake, so a 15-minute timer is 96 wakes a day (24 at 60 minutes) against the 1–20 clips a day these cameras actually record — five to a hundred times their normal wake count, and the battery pays for all of it. One interval buys exactly one wake, successful or not. It has no effect on a hub child or a mains camera, which are never woken by this timer.";
188633
+ var CLIP_CATALOG_REFRESH_MINUTES_DESCRIPTION = "On a standalone battery camera the timer only marks the catalog as ageing; it never wakes the camera. 0 turns it off.";
188634
+ var CLIP_CATALOG_FORCED_WAKE_DESCRIPTION = "Let the timer wake a standalone battery camera: one wake per interval, at the battery’s cost. No effect on hub children or mains cameras.";
188582
188635
  /**
188583
188636
  * The addon-level (global) default. Per-camera overrides live on the device,
188584
188637
  * under the SAME key, and a device that sets nothing — or resets — resolves to
@@ -188588,7 +188641,7 @@ function buildClipRefreshSettingsSchema() {
188588
188641
  return { sections: [{
188589
188642
  id: CLIP_REFRESH_SECTION_ID,
188590
188643
  title: "Clip catalog refresh",
188591
- description: "The default for every Reolink camera. Each camera can override it in its own Recording settings; a camera that overrides nothing uses this value.",
188644
+ description: "Default for every camera; a camera can override it in its Recording settings.",
188592
188645
  columns: 1,
188593
188646
  fields: [{
188594
188647
  type: "number",
@@ -188618,7 +188671,7 @@ function buildClipRefreshDeviceSection(input) {
188618
188671
  id: CLIP_REFRESH_SECTION_ID,
188619
188672
  tab: "recording",
188620
188673
  title: "Clip catalog refresh",
188621
- description: "How often this camera’s own clip list is re-read. Leave the interval empty to use the default from the Reolink addon settings.",
188674
+ description: "Leave the interval empty to use the default from the Reolink addon settings.",
188622
188675
  columns: 1,
188623
188676
  fields: [{
188624
188677
  type: "number",
@@ -188897,7 +188950,7 @@ function buildSnapshotFreshnessSection(cache, opts) {
188897
188950
  tab: "advanced",
188898
188951
  title: "Snapshot freshness",
188899
188952
  titleKey: "provider-reolink:snapshotFreshnessSection.s_snapshotFreshness.title",
188900
- 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.",
188953
+ description: "Groups without a stamp are of unknown age, not fresh.",
188901
188954
  descriptionKey: "provider-reolink:snapshotFreshnessSection.s_snapshotFreshness.description",
188902
188955
  columns: 1,
188903
188956
  fields: [{
@@ -189928,7 +189981,7 @@ var BatteryHourlyRefresh = class {
189928
189981
  //#endregion
189929
189982
  //#region src/battery-refresh-settings.ts
189930
189983
  var BATTERY_REFRESH_SECTION_ID = "battery-refresh";
189931
- var BATTERY_REFRESH_MINUTES_DESCRIPTION = `Once per window this camera refreshes everything CamStack knows about it — battery level and charging, signal, device info, every state panel and the cached snapshot. If the camera is awake at some point in the window (a motion event, a live view, anything that woke it) it is refreshed then and not woken again; if the whole window passes with the camera asleep, it is woken ONCE near the end of the window, refreshed, and left to go back to sleep. A camera that does not answer is retried at most twice per window. 15–240 minutes, default 60; 0 turns the scheduled refresh off (the battery level then ages until the camera next wakes by itself).`;
189984
+ var BATTERY_REFRESH_MINUTES_DESCRIPTION = "A camera that slept the whole window is woken once to refresh. 0 turns the scheduled refresh off.";
189932
189985
  /** Battery cameras only: a mains camera keeps its facts fresh on its own socket. */
189933
189986
  function buildBatteryRefreshDeviceSection(input) {
189934
189987
  if (!input.isBattery) return [];
@@ -189936,7 +189989,6 @@ function buildBatteryRefreshDeviceSection(input) {
189936
189989
  id: BATTERY_REFRESH_SECTION_ID,
189937
189990
  tab: "general",
189938
189991
  title: "Scheduled refresh",
189939
- description: "How often this battery camera is guaranteed to have been read, so a battery level never goes stale unseen.",
189940
189992
  columns: 1,
189941
189993
  fields: [{
189942
189994
  type: "number",
@@ -190030,7 +190082,7 @@ async function refreshSnapshotCacheOnce(input) {
190030
190082
  */
190031
190083
  var CH_BAICHUAN = declareLogChannel({
190032
190084
  name: "provider-reolink.baichuan",
190033
- description: "Every Baichuan protocol frame this camera sends and receives, plus UDP keepalives and battery-camera sleep inference. Loud on an active camera — arm it for one camera and a short window.",
190085
+ description: "Every Baichuan protocol frame this camera sends and receives. Loud: arm it for one camera and a short window.",
190034
190086
  defaultLevel: "info",
190035
190087
  perDevice: true
190036
190088
  });
@@ -190045,7 +190097,7 @@ var CH_BAICHUAN = declareLogChannel({
190045
190097
  */
190046
190098
  var CH_HANDSHAKE = declareLogChannel({
190047
190099
  name: "provider-reolink.handshake",
190048
- description: "Login and socket lifecycle for this camera: the pre-login dial, the battery-camera wake a login causes, login failures and the reconnects that follow. The channel to arm when a camera looks present but answers nothing.",
190100
+ description: "Login and socket lifecycle for this camera. Arm it when a camera looks present but answers nothing.",
190049
190101
  defaultLevel: "info",
190050
190102
  perDevice: true
190051
190103
  });
@@ -190454,7 +190506,7 @@ function buildOsdSection(snapshot, values, opts) {
190454
190506
  tab: "image",
190455
190507
  title: "OSD overlay",
190456
190508
  titleKey: "provider-reolink:osdSection.s_osd.title",
190457
- 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.",
190509
+ description: "An overlay the camera holds somewhere else keeps that placement unless a corner is chosen.",
190458
190510
  descriptionKey: "provider-reolink:osdSection.s_osd.description",
190459
190511
  columns: 2,
190460
190512
  fields: [
@@ -190466,8 +190518,6 @@ function buildOsdSection(snapshot, values, opts) {
190466
190518
  key: "osdChannelName",
190467
190519
  label: "Channel name",
190468
190520
  labelKey: "provider-reolink:fields.osdChannelName.label",
190469
- description: "Text shown in the channel-name overlay.",
190470
- descriptionKey: "provider-reolink:fields.osdChannelName.description",
190471
190521
  default: values.osdChannelName,
190472
190522
  placeholder: "Front door"
190473
190523
  },
@@ -190951,7 +191001,7 @@ var SirenAccessory = class extends BaseDevice {
190951
191001
  id: "siren",
190952
191002
  title: "Siren",
190953
191003
  titleKey: "provider-reolink:schema.s_siren.title",
190954
- description: "Tone duration when triggered. Set to 0 for \"play until turned off\"; positive values pulse for that many seconds.",
191004
+ description: "0 = play until turned off.",
190955
191005
  descriptionKey: "provider-reolink:schema.s_siren.description",
190956
191006
  columns: 1,
190957
191007
  fields: [{
@@ -190959,8 +191009,6 @@ var SirenAccessory = class extends BaseDevice {
190959
191009
  key: "sirenDurationS",
190960
191010
  label: "Default duration (seconds)",
190961
191011
  labelKey: "provider-reolink:schema.s_siren.sirenDurationS.label",
190962
- description: "Forwarded to `setSiren(on=true, duration)` (cmd_id 30) when the operator flips the switch.",
190963
- descriptionKey: "provider-reolink:schema.s_siren.sirenDurationS.description",
190964
191012
  default: 0,
190965
191013
  min: 0,
190966
191014
  max: 300,
@@ -190970,16 +191018,12 @@ var SirenAccessory = class extends BaseDevice {
190970
191018
  id: "motion-siren",
190971
191019
  title: "Motion-triggered siren",
190972
191020
  titleKey: "provider-reolink:schema.s_motion-siren.title",
190973
- 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.",
190974
- descriptionKey: "provider-reolink:schema.s_motion-siren.description",
190975
191021
  columns: 1,
190976
191022
  fields: [{
190977
191023
  type: "select",
190978
191024
  key: "motionSirenDetectType",
190979
191025
  label: "Detection classes",
190980
191026
  labelKey: "provider-reolink:schema.s_motion-siren.motionSirenDetectType.label",
190981
- description: "Object/motion classes that arm the siren. `MD` = generic motion detection.",
190982
- descriptionKey: "provider-reolink:schema.s_motion-siren.motionSirenDetectType.description",
190983
191027
  options: SIREN_DETECT_TYPE_CHOICES.map((v) => ({
190984
191028
  value: v,
190985
191029
  label: v.replace(/,/g, " + ").replace(/_/g, "+")
@@ -191443,16 +191487,12 @@ var FloodlightAccessory = class extends BaseDevice {
191443
191487
  id: "motion-floodlight",
191444
191488
  title: "Motion-triggered floodlight",
191445
191489
  titleKey: "provider-reolink:schema.s_motion-floodlight.title",
191446
- 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.",
191447
- descriptionKey: "provider-reolink:schema.s_motion-floodlight.description",
191448
191490
  columns: 2,
191449
191491
  fields: [{
191450
191492
  type: "number",
191451
191493
  key: "motionLightDurationS",
191452
191494
  label: "Light duration (s)",
191453
191495
  labelKey: "provider-reolink:schema.s_motion-floodlight.motionLightDurationS.label",
191454
- description: "Seconds the floodlight stays lit after a motion event. Reolink range 1..600s.",
191455
- descriptionKey: "provider-reolink:schema.s_motion-floodlight.motionLightDurationS.description",
191456
191496
  min: 1,
191457
191497
  max: 600,
191458
191498
  step: 1,
@@ -191462,8 +191502,6 @@ var FloodlightAccessory = class extends BaseDevice {
191462
191502
  key: "motionLightDetectType",
191463
191503
  label: "Detection classes",
191464
191504
  labelKey: "provider-reolink:schema.s_motion-floodlight.motionLightDetectType.label",
191465
- description: "Object classes that turn the floodlight on. Composed values (e.g. \"people,vehicle\") fire when ANY listed class detects.",
191466
- descriptionKey: "provider-reolink:schema.s_motion-floodlight.motionLightDetectType.description",
191467
191505
  options: FLOODLIGHT_DETECT_TYPE_CHOICES.map((v) => ({
191468
191506
  value: v,
191469
191507
  label: v.replace(/,/g, " + ").replace(/_/g, "+")
@@ -191703,8 +191741,6 @@ var PirAccessory = class extends BaseDevice {
191703
191741
  id: "pir",
191704
191742
  title: "PIR sensor",
191705
191743
  titleKey: "provider-reolink:schema.s_pir.title",
191706
- description: "Hardware passive-infrared trigger configuration. Pushed via cmd_id 153 (SetPirInfo).",
191707
- descriptionKey: "provider-reolink:schema.s_pir.description",
191708
191744
  columns: 2,
191709
191745
  fields: [
191710
191746
  {
@@ -191712,8 +191748,6 @@ var PirAccessory = class extends BaseDevice {
191712
191748
  key: "pirSensitive",
191713
191749
  label: "Sensitivity",
191714
191750
  labelKey: "provider-reolink:schema.s_pir.pirSensitive.label",
191715
- description: "Higher value → triggers on smaller motion. Most cameras max at 100.",
191716
- descriptionKey: "provider-reolink:schema.s_pir.pirSensitive.description",
191717
191751
  min: 1,
191718
191752
  max: 100,
191719
191753
  step: 1,
@@ -191725,7 +191759,6 @@ var PirAccessory = class extends BaseDevice {
191725
191759
  key: "pirIntervalS",
191726
191760
  label: "Cooldown (seconds)",
191727
191761
  labelKey: "provider-reolink:schema.s_pir.pirIntervalS.label",
191728
- description: `Minimum delay between consecutive PIR triggers. Reolink app range 5..${intervalMax}s; firmware clamps on push.`,
191729
191762
  min: 5,
191730
191763
  max: intervalMax,
191731
191764
  step: 1,
@@ -191738,8 +191771,6 @@ var PirAccessory = class extends BaseDevice {
191738
191771
  key: "pirReduceAlarm",
191739
191772
  label: "Reduce false alarms",
191740
191773
  labelKey: "provider-reolink:schema.s_pir.pirReduceAlarm.label",
191741
- description: "Trades detection range for fewer false positives. Maps to firmware `reduceAlarm` flag.",
191742
- descriptionKey: "provider-reolink:schema.s_pir.pirReduceAlarm.description",
191743
191774
  ...typeof reduceAlarm === "boolean" ? { default: reduceAlarm } : {},
191744
191775
  style: "switch",
191745
191776
  span: 2
@@ -193288,8 +193319,6 @@ function buildSessionsTabSections(snap, opts) {
193288
193319
  return [{
193289
193320
  id: "sessions-status",
193290
193321
  title: opts.title ?? "Sessions",
193291
- description: "Diagnostics for the Baichuan control channel. Auto-refreshes when older than 1 minute; click Refresh to force.",
193292
- descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.description",
193293
193322
  tab: opts.tabId,
193294
193323
  order: 0,
193295
193324
  columns: 1,
@@ -193307,8 +193336,6 @@ function buildSessionsTabSections(snap, opts) {
193307
193336
  key: "sessionsOnlineUsers",
193308
193337
  label: "Online users (firmware)",
193309
193338
  labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.label",
193310
- description: "Active user sessions reported by the device (cmd_id 145). Includes other admins, mobile app, NVR linkups.",
193311
- descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.description",
193312
193339
  columns: [
193313
193340
  {
193314
193341
  key: "userName",
@@ -193351,8 +193378,6 @@ function buildSessionsTabSections(snap, opts) {
193351
193378
  key: "sessionsSocketPool",
193352
193379
  label: "Our socket pool",
193353
193380
  labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsSocketPool.label",
193354
- description: "Open Baichuan TCP/UDP sockets this process holds for the device. One row per pool tag.",
193355
- descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsSocketPool.description",
193356
193381
  columns: [{
193357
193382
  key: "tag",
193358
193383
  label: "Tag",
@@ -193373,8 +193398,6 @@ function buildSessionsTabSections(snap, opts) {
193373
193398
  key: "sessionsDedicated",
193374
193399
  label: "Dedicated lib sessions",
193375
193400
  labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsDedicated.label",
193376
- description: "Internal lib-side dedicated sessions (streaming/talk channels). Older lib versions leave this list empty.",
193377
- descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsDedicated.description",
193378
193401
  columns: [{
193379
193402
  key: "key",
193380
193403
  label: "Session key",
@@ -195759,7 +195782,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
195759
195782
  tab: "motion",
195760
195783
  title: "Battery motion (sleep push)",
195761
195784
  titleKey: "provider-reolink:emailPushSection.s_sleep-push.title",
195762
- 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.",
195785
+ description: "Prefer the HaCfg webhook when the firmware supports it; arm only one path.",
195763
195786
  descriptionKey: "provider-reolink:emailPushSection.s_sleep-push.description",
195764
195787
  columns: 1,
195765
195788
  fields: [
@@ -195825,7 +195848,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
195825
195848
  tab: "email",
195826
195849
  title: "SMTP server",
195827
195850
  titleKey: "provider-reolink:emailTabSections.s_email-smtp.title",
195828
- 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.",
195851
+ description: "Leave the password blank to keep the current one.",
195829
195852
  descriptionKey: "provider-reolink:emailTabSections.s_email-smtp.description",
195830
195853
  columns: 2,
195831
195854
  fields: [
@@ -195880,8 +195903,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
195880
195903
  tab: "email",
195881
195904
  title: "Recipients",
195882
195905
  titleKey: "provider-reolink:emailTabSections.s_email-recipients.title",
195883
- description: "Up to three recipient addresses the camera sends motion mail to.",
195884
- descriptionKey: "provider-reolink:emailTabSections.s_email-recipients.description",
195885
195906
  columns: 1,
195886
195907
  fields: [
195887
195908
  {
@@ -195910,8 +195931,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
195910
195931
  tab: "email",
195911
195932
  title: "Alarm schedule",
195912
195933
  titleKey: "provider-reolink:emailTabSections.s_email-schedule.title",
195913
- description: "Master enable for the camera's email alarm schedule (EmailTask).",
195914
- descriptionKey: "provider-reolink:emailTabSections.s_email-schedule.description",
195915
195934
  columns: 1,
195916
195935
  fields: [{
195917
195936
  type: "boolean",
@@ -199787,7 +199806,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
199787
199806
  tab: "general",
199788
199807
  title: "Camera data",
199789
199808
  titleKey: "provider-reolink:schema.s_driver-refresh.title",
199790
- 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.",
199809
+ description: "Wakes a sleeping camera and re-reads everything; no other read here wakes it.",
199791
199810
  descriptionKey: "provider-reolink:schema.s_driver-refresh.description",
199792
199811
  columns: 1,
199793
199812
  fields: [{
@@ -199806,8 +199825,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
199806
199825
  tab: "general",
199807
199826
  title: "Connection",
199808
199827
  titleKey: "provider-reolink:schema.s_connection.title",
199809
- description: "Baichuan protocol connection settings.",
199810
- descriptionKey: "provider-reolink:schema.s_connection.description",
199811
199828
  columns: 2,
199812
199829
  fields: [
199813
199830
  {
@@ -199850,7 +199867,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
199850
199867
  tab: "network",
199851
199868
  title: "Service ports",
199852
199869
  titleKey: "provider-reolink:schema.s_network-ports.title",
199853
- 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.",
199870
+ description: "Changing a port breaks existing URLs for that protocol.",
199854
199871
  descriptionKey: "provider-reolink:schema.s_network-ports.description",
199855
199872
  columns: 2,
199856
199873
  fields: [
@@ -199951,8 +199968,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
199951
199968
  tab: "network",
199952
199969
  title: "Time / NTP",
199953
199970
  titleKey: "provider-reolink:schema.s_time-ntp.title",
199954
- 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.",
199955
- descriptionKey: "provider-reolink:schema.s_time-ntp.description",
199956
199971
  columns: 2,
199957
199972
  fields: [
199958
199973
  {
@@ -199960,8 +199975,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
199960
199975
  key: "timeZoneId",
199961
199976
  label: "Timezone",
199962
199977
  labelKey: "provider-reolink:schema.s_time-ntp.timeZoneId.label",
199963
- 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.",
199964
- descriptionKey: "provider-reolink:schema.s_time-ntp.timeZoneId.description",
199965
199978
  default: this.config.get("timeZoneId") ?? reolinkTimeZoneToIana(this.config.get("deviceCache")?.systemGeneralSnapshot?.timeZone) ?? "",
199966
199979
  span: 2
199967
199980
  },
@@ -200010,16 +200023,12 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200010
200023
  tab: "motion",
200011
200024
  title: "On-camera motion (MdAlarm)",
200012
200025
  titleKey: "provider-reolink:schema.s_motion.title",
200013
- 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.",
200014
- descriptionKey: "provider-reolink:schema.s_motion.description",
200015
200026
  columns: 2,
200016
200027
  fields: [{
200017
200028
  type: "boolean",
200018
200029
  key: "motionEnabled",
200019
200030
  label: "Motion detection",
200020
200031
  labelKey: "provider-reolink:schema.s_motion.motionEnabled.label",
200021
- description: "Master switch for the camera's on-board motion detector. Disabling stops the camera from emitting motion events on the alarm channel.",
200022
- descriptionKey: "provider-reolink:schema.s_motion.motionEnabled.description",
200023
200032
  default: motionSnap.enabled ?? true,
200024
200033
  style: "switch",
200025
200034
  span: 2
@@ -200028,8 +200037,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200028
200037
  key: "motionSensitivity",
200029
200038
  label: "Sensitivity",
200030
200039
  labelKey: "provider-reolink:schema.s_motion.motionSensitivity.label",
200031
- description: "Higher = triggers on smaller motion. Reolink user-facing range 1..50.",
200032
- descriptionKey: "provider-reolink:schema.s_motion.motionSensitivity.description",
200033
200040
  min: 1,
200034
200041
  max: 50,
200035
200042
  step: 1,
@@ -200044,8 +200051,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200044
200051
  tab: "motion",
200045
200052
  title: "AI detection sensitivity",
200046
200053
  titleKey: "provider-reolink:schema.s_ai-sensitivity.title",
200047
- 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.",
200048
- descriptionKey: "provider-reolink:schema.s_ai-sensitivity.description",
200049
200054
  columns: 2,
200050
200055
  fields: [
200051
200056
  [
@@ -200114,7 +200119,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200114
200119
  type: "slider",
200115
200120
  key: stayKey,
200116
200121
  label: `${label} stay time (s)`,
200117
- description: "Seconds the camera keeps the AI alarm asserted after the object leaves frame.",
200118
200122
  min: 0,
200119
200123
  max: 600,
200120
200124
  step: 1,
@@ -200177,8 +200181,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200177
200181
  tab: "image",
200178
200182
  title: "Image",
200179
200183
  titleKey: "provider-reolink:schema.s_image.title",
200180
- 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.",
200181
- descriptionKey: "provider-reolink:schema.s_image.description",
200182
200184
  columns: 2,
200183
200185
  fields: [
200184
200186
  {
@@ -200249,24 +200251,18 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200249
200251
  tab: "image",
200250
200252
  title: "Advanced (ISP)",
200251
200253
  titleKey: "provider-reolink:schema.s_isp.title",
200252
- description: "Day/Night + exposure + HDR. Pushed via `SetIsp` (cmd_id 25). The day/night threshold uses cmd_id 297 (DayNightThreshold).",
200253
- descriptionKey: "provider-reolink:schema.s_isp.description",
200254
200254
  columns: 2,
200255
200255
  fields: [{
200256
200256
  type: "text",
200257
200257
  key: "ispDayNight",
200258
200258
  label: "Day/Night mode",
200259
200259
  labelKey: "provider-reolink:schema.s_isp.ispDayNight.label",
200260
- description: "Camera-specific values — common: `auto`, `color`, `blackAndWhite`. The driver normalizes case before push.",
200261
- descriptionKey: "provider-reolink:schema.s_isp.ispDayNight.description",
200262
200260
  default: imgSnap.dayNight ?? "auto"
200263
200261
  }, {
200264
200262
  type: "text",
200265
200263
  key: "ispExposure",
200266
200264
  label: "Exposure",
200267
200265
  labelKey: "provider-reolink:schema.s_isp.ispExposure.label",
200268
- description: "Common values: `auto`, `manual`. Lowercased before push.",
200269
- descriptionKey: "provider-reolink:schema.s_isp.ispExposure.description",
200270
200266
  default: "auto"
200271
200267
  }]
200272
200268
  }] : [],
@@ -200275,8 +200271,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200275
200271
  tab: "image",
200276
200272
  title: "IR + status LED",
200277
200273
  titleKey: "provider-reolink:schema.s_ir-lights.title",
200278
- 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.",
200279
- descriptionKey: "provider-reolink:schema.s_ir-lights.description",
200280
200274
  columns: 2,
200281
200275
  fields: [
200282
200276
  {
@@ -200308,7 +200302,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200308
200302
  key: "irLightsBrightness",
200309
200303
  label: "IR brightness",
200310
200304
  labelKey: "provider-reolink:schema.s_ir-lights.irLightsBrightness.label",
200311
- description: "Only applied when the camera advertises programmable IR brightness. 0..255 raw range; many models clamp to 0..100.",
200305
+ description: "Only applied when the camera supports adjustable IR brightness.",
200312
200306
  descriptionKey: "provider-reolink:schema.s_ir-lights.irLightsBrightness.description",
200313
200307
  min: 0,
200314
200308
  max: 255,
@@ -200322,8 +200316,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200322
200316
  key: "statusLedEnabled",
200323
200317
  label: "Status LED",
200324
200318
  labelKey: "provider-reolink:schema.s_ir-lights.statusLedEnabled.label",
200325
- description: "The visible status/power LED on the camera body. Pushed via `SetIrLights` (cmd_id 209) as `lightState`.",
200326
- descriptionKey: "provider-reolink:schema.s_ir-lights.statusLedEnabled.description",
200327
200319
  default: cache?.ledSnapshot?.statusEnabled ?? true,
200328
200320
  style: "switch",
200329
200321
  span: cache?.ledSnapshot?.doorbellSupported === true ? 1 : 2
@@ -200333,8 +200325,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200333
200325
  key: "doorbellLedEnabled",
200334
200326
  label: "Doorbell LED",
200335
200327
  labelKey: "provider-reolink:schema.s_ir-lights.doorbellLedEnabled.label",
200336
- description: "The doorbell button ring LED. Pushed via `SetIrLights` (cmd_id 209) as `doorbellLightState`.",
200337
- descriptionKey: "provider-reolink:schema.s_ir-lights.doorbellLedEnabled.description",
200338
200328
  default: cache?.ledSnapshot?.doorbellEnabled ?? true,
200339
200329
  style: "switch"
200340
200330
  }] : []
@@ -200349,7 +200339,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200349
200339
  tab: "image",
200350
200340
  title: "Auto focus",
200351
200341
  titleKey: "provider-reolink:schema.s_auto-focus.title",
200352
- 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.",
200342
+ description: "Disabling locks the lens at its current focus.",
200353
200343
  descriptionKey: "provider-reolink:schema.s_auto-focus.description",
200354
200344
  columns: 1,
200355
200345
  fields: [{
@@ -200366,8 +200356,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200366
200356
  tab: "audio",
200367
200357
  title: "Audio output",
200368
200358
  titleKey: "provider-reolink:schema.s_audio.title",
200369
- 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.",
200370
- descriptionKey: "provider-reolink:schema.s_audio.description",
200371
200359
  columns: 2,
200372
200360
  fields: [
200373
200361
  {
@@ -200387,7 +200375,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200387
200375
  key: "audioTalkAndReplyVolume",
200388
200376
  label: "Talk + reply volume",
200389
200377
  labelKey: "provider-reolink:schema.s_audio.audioTalkAndReplyVolume.label",
200390
- description: "Two-way audio + canned reply playback. Doorbell-only on most firmwares.",
200378
+ description: "Doorbell models only.",
200391
200379
  descriptionKey: "provider-reolink:schema.s_audio.audioTalkAndReplyVolume.description",
200392
200380
  min: 0,
200393
200381
  max: 100,
@@ -200401,7 +200389,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200401
200389
  key: "audioVisitorVolume",
200402
200390
  label: "Visitor volume",
200403
200391
  labelKey: "provider-reolink:schema.s_audio.audioVisitorVolume.label",
200404
- description: "Visitor / chime playback channel. Doorbell-only on most firmwares.",
200392
+ description: "Doorbell models only.",
200405
200393
  descriptionKey: "provider-reolink:schema.s_audio.audioVisitorVolume.description",
200406
200394
  min: 0,
200407
200395
  max: 100,
@@ -200418,8 +200406,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200418
200406
  tab: "audio",
200419
200407
  title: "Audio noise reduction",
200420
200408
  titleKey: "provider-reolink:schema.s_audio-noise.title",
200421
- 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).",
200422
- descriptionKey: "provider-reolink:schema.s_audio-noise.description",
200423
200409
  columns: 1,
200424
200410
  fields: [{
200425
200411
  type: "slider",
@@ -200441,7 +200427,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200441
200427
  tab: "audio",
200442
200428
  title: "Intercom",
200443
200429
  titleKey: "provider-reolink:schema.s_intercom.title",
200444
- description: "Push-to-talk pipeline tuning. Settings take effect on the next talk session — restart any active session for changes to apply.",
200430
+ description: "Changes apply to the next talk session.",
200445
200431
  descriptionKey: "provider-reolink:schema.s_intercom.description",
200446
200432
  columns: 2,
200447
200433
  fields: [
@@ -200450,7 +200436,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200450
200436
  key: "intercomBlocksPerPayload",
200451
200437
  label: "Blocks per payload",
200452
200438
  labelKey: "provider-reolink:schema.s_intercom.intercomBlocksPerPayload.label",
200453
- description: "Lower = lower latency (more sendAudio calls/sec). Higher = fewer calls, less per-call socket overhead. Range 1..8. Default 1 (lowest latency).",
200439
+ description: "Lower is lower latency, higher is fewer calls. Range 1..8.",
200454
200440
  descriptionKey: "provider-reolink:schema.s_intercom.intercomBlocksPerPayload.description",
200455
200441
  min: 1,
200456
200442
  max: 8,
@@ -200464,7 +200450,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200464
200450
  key: "intercomMaxBacklogMs",
200465
200451
  label: "Max backlog (ms)",
200466
200452
  labelKey: "provider-reolink:schema.s_intercom.intercomMaxBacklogMs.label",
200467
- 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.",
200453
+ description: "Higher is more stable on slow systems but adds latency. Range 20..5000.",
200468
200454
  descriptionKey: "provider-reolink:schema.s_intercom.intercomMaxBacklogMs.description",
200469
200455
  min: 20,
200470
200456
  max: 5e3,
@@ -200478,7 +200464,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200478
200464
  key: "intercomGain",
200479
200465
  label: "Output gain",
200480
200466
  labelKey: "provider-reolink:schema.s_intercom.intercomGain.label",
200481
- description: "Multiplier applied to PCM samples before IMA-ADPCM encode. 1.0 = neutral, 2.0 ≈ +6dB, 0.5 ≈ -6dB. Hard-clipped at int16 bounds.",
200467
+ description: "1.0 = neutral, 2.0 ≈ +6 dB, 0.5 ≈ -6 dB.",
200482
200468
  descriptionKey: "provider-reolink:schema.s_intercom.intercomGain.description",
200483
200469
  min: .1,
200484
200470
  max: 10,
@@ -200495,7 +200481,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200495
200481
  tab: "advanced",
200496
200482
  title: "Keyframe interval (GOP)",
200497
200483
  titleKey: "provider-reolink:schema.s_keyframe-gop.title",
200498
- 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.",
200484
+ description: "Lower = more keyframes (faster recovery, higher bitrate).",
200499
200485
  descriptionKey: "provider-reolink:schema.s_keyframe-gop.description",
200500
200486
  columns: 1,
200501
200487
  fields: [{
@@ -200516,8 +200502,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200516
200502
  tab: "advanced",
200517
200503
  title: "PIR detection",
200518
200504
  titleKey: "provider-reolink:schema.s_pir-reduce-alarm.title",
200519
- 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.",
200520
- descriptionKey: "provider-reolink:schema.s_pir-reduce-alarm.description",
200521
200505
  columns: 1,
200522
200506
  fields: [{
200523
200507
  type: "boolean",
@@ -200533,8 +200517,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200533
200517
  tab: "advanced",
200534
200518
  title: "Auto reboot",
200535
200519
  titleKey: "provider-reolink:schema.s_auto-reboot.title",
200536
- 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.",
200537
- descriptionKey: "provider-reolink:schema.s_auto-reboot.description",
200538
200520
  columns: 2,
200539
200521
  fields: [
200540
200522
  {
@@ -200623,7 +200605,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200623
200605
  tab: "advanced",
200624
200606
  title: "Debug",
200625
200607
  titleKey: "provider-reolink:schema.s_debug.title",
200626
- 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.",
200608
+ description: "Debug logging adds log volume; use it temporarily.",
200627
200609
  descriptionKey: "provider-reolink:schema.s_debug.description",
200628
200610
  columns: 1,
200629
200611
  fields: [{
@@ -200631,8 +200613,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200631
200613
  key: "debugGeneral",
200632
200614
  label: "General debug logs",
200633
200615
  labelKey: "provider-reolink:schema.s_debug.debugGeneral.label",
200634
- description: "Forwards `DebugOptions.general=true` — verbose lib protocol logs.",
200635
- descriptionKey: "provider-reolink:schema.s_debug.debugGeneral.description",
200636
200616
  default: false,
200637
200617
  style: "switch"
200638
200618
  }, {
@@ -200640,7 +200620,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200640
200620
  key: "debugSocketLogs",
200641
200621
  label: "Socket trace categories",
200642
200622
  labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.label",
200643
- description: "Per-area lib tracing. Pick only what you need; each adds log volume.",
200623
+ description: "Each area adds log volume.",
200644
200624
  descriptionKey: "provider-reolink:schema.s_debug.debugSocketLogs.description",
200645
200625
  default: [],
200646
200626
  options: [
@@ -202211,7 +202191,7 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
202211
202191
  tab: "general",
202212
202192
  title: "Connection",
202213
202193
  titleKey: "provider-reolink:hub.s_connection.title",
202214
- 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.",
202194
+ description: "Child cameras inherit these credentials.",
202215
202195
  descriptionKey: "provider-reolink:hub.s_connection.description",
202216
202196
  columns: 2,
202217
202197
  fields: [
@@ -202255,8 +202235,6 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
202255
202235
  tab: "general",
202256
202236
  title: "Hub identity",
202257
202237
  titleKey: "provider-reolink:hub.s_identity.title",
202258
- description: "Read-only summary from the autodetect probe. Channel count and model are persisted at first contact so the panel renders without re-probing.",
202259
- descriptionKey: "provider-reolink:hub.s_identity.description",
202260
202238
  columns: 2,
202261
202239
  fields: [{
202262
202240
  type: "text",
@@ -202279,7 +202257,7 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
202279
202257
  tab: "advanced",
202280
202258
  title: "Debug",
202281
202259
  titleKey: "provider-reolink:hub.s_debug.title",
202282
- 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.",
202260
+ description: "Debug logging adds log volume; use it temporarily.",
202283
202261
  descriptionKey: "provider-reolink:hub.s_debug.description",
202284
202262
  columns: 1,
202285
202263
  fields: [{
@@ -202287,8 +202265,6 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
202287
202265
  key: "debugGeneral",
202288
202266
  label: "General debug logs",
202289
202267
  labelKey: "provider-reolink:hub.s_debug.debugGeneral.label",
202290
- description: "Forwards `DebugOptions.general=true` — verbose lib protocol logs.",
202291
- descriptionKey: "provider-reolink:hub.s_debug.debugGeneral.description",
202292
202268
  default: false,
202293
202269
  style: "switch"
202294
202270
  }, {
@@ -202296,7 +202272,7 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
202296
202272
  key: "debugSocketLogs",
202297
202273
  label: "Socket trace categories",
202298
202274
  labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.label",
202299
- description: "Per-area lib tracing. Pick only what you need; each adds log volume.",
202275
+ description: "Each area adds log volume.",
202300
202276
  descriptionKey: "provider-reolink:hub.s_debug.debugSocketLogs.description",
202301
202277
  default: [],
202302
202278
  options: [
@@ -203059,7 +203035,7 @@ function buildDiscoveryParamsFormSchema() {
203059
203035
  id: "credentials",
203060
203036
  title: "Credentials",
203061
203037
  titleKey: "provider-reolink:discoveryParams.s_credentials.title",
203062
- 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.",
203038
+ description: "Assumes all cameras share these credentials.",
203063
203039
  descriptionKey: "provider-reolink:discoveryParams.s_credentials.description",
203064
203040
  columns: 2,
203065
203041
  fields: [{
@@ -203081,7 +203057,7 @@ function buildDiscoveryParamsFormSchema() {
203081
203057
  id: "scan",
203082
203058
  title: "Scan options",
203083
203059
  titleKey: "provider-reolink:discoveryParams.s_scan.title",
203084
- 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).",
203060
+ description: "Leave blank to scan the local subnet; for another subnet enter its CIDR (e.g. 192.168.20.0/24).",
203085
203061
  descriptionKey: "provider-reolink:discoveryParams.s_scan.description",
203086
203062
  columns: 1,
203087
203063
  fields: [
@@ -203132,8 +203108,6 @@ function buildCreationFormSchema() {
203132
203108
  id: "credentials",
203133
203109
  title: "Credentials",
203134
203110
  titleKey: "provider-reolink:creation.s_credentials.title",
203135
- description: "Required for the autodetect probe — entered before the host so Test can run immediately.",
203136
- descriptionKey: "provider-reolink:creation.s_credentials.description",
203137
203111
  columns: 2,
203138
203112
  fields: [{
203139
203113
  type: "text",
@@ -203155,8 +203129,6 @@ function buildCreationFormSchema() {
203155
203129
  id: "connection",
203156
203130
  title: "Connection",
203157
203131
  titleKey: "provider-reolink:creation.s_connection.title",
203158
- description: "Click Test to auto-detect the device type (regular camera / NVR / battery / UDP-only). The detected type is then used at save time.",
203159
- descriptionKey: "provider-reolink:creation.s_connection.description",
203160
203132
  columns: 2,
203161
203133
  fields: [
203162
203134
  {
@@ -203165,7 +203137,7 @@ function buildCreationFormSchema() {
203165
203137
  label: "Connection mode",
203166
203138
  labelKey: "provider-reolink:creation.s_connection.transport.label",
203167
203139
  default: "auto",
203168
- description: "Auto: try TCP first, fall back to UDP — best for unknown devices. UDP is required for battery cameras behind NAT.",
203140
+ description: "Auto tries TCP, then UDP. Battery cameras behind NAT need UDP.",
203169
203141
  descriptionKey: "provider-reolink:creation.s_connection.transport.description",
203170
203142
  options: [
203171
203143
  {
@@ -203192,7 +203164,7 @@ function buildCreationFormSchema() {
203192
203164
  labelKey: "provider-reolink:creation.s_connection.host.label",
203193
203165
  required: true,
203194
203166
  placeholder: "192.168.10.100",
203195
- 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.",
203167
+ description: "In UDP-only mode leave blank and use the UID below.",
203196
203168
  descriptionKey: "provider-reolink:creation.s_connection.host.description",
203197
203169
  inputType: "text"
203198
203170
  },
@@ -203205,8 +203177,6 @@ function buildCreationFormSchema() {
203205
203177
  min: 1,
203206
203178
  max: 65535,
203207
203179
  step: 1,
203208
- description: "Baichuan port. Default 9000 — applies to TCP. Ignored for UDP transport.",
203209
- descriptionKey: "provider-reolink:creation.s_connection.port.description",
203210
203180
  showWhen: {
203211
203181
  field: "transport",
203212
203182
  notEquals: "udp"
@@ -203218,7 +203188,7 @@ function buildCreationFormSchema() {
203218
203188
  label: "Device UID",
203219
203189
  labelKey: "provider-reolink:creation.s_connection.uid.label",
203220
203190
  placeholder: "9527000XXXXXXXX",
203221
- description: "Required for battery / UDP cameras when not on the same LAN. Optional for local-direct UDP discovery and ignored for pure TCP.",
203191
+ description: "Needed for battery / UDP cameras that are not on the same LAN.",
203222
203192
  descriptionKey: "provider-reolink:creation.s_connection.uid.description",
203223
203193
  showWhen: {
203224
203194
  field: "transport",
@@ -203759,7 +203729,7 @@ function buildEmailPushSettingsSchema(recommendedHost) {
203759
203729
  id: "email-push",
203760
203730
  title: "Battery-cam Motion (Email/SMTP Push)",
203761
203731
  titleKey: "provider-reolink:emailPushSettings.s_email-push.title",
203762
- 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.",
203732
+ description: "Lets battery cameras report motion by email without being woken.",
203763
203733
  descriptionKey: "provider-reolink:emailPushSettings.s_email-push.description",
203764
203734
  columns: 2,
203765
203735
  fields: [
@@ -203799,7 +203769,7 @@ function buildEmailPushSettingsSchema(recommendedHost) {
203799
203769
  id: "email-push-auth",
203800
203770
  title: "Email Push Authentication",
203801
203771
  titleKey: "provider-reolink:emailPushSettings.s_email-push-auth.title",
203802
- 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.",
203772
+ description: "Random values are generated on first boot; re-run Auto-configure on cameras after changing them.",
203803
203773
  descriptionKey: "provider-reolink:emailPushSettings.s_email-push-auth.description",
203804
203774
  columns: 2,
203805
203775
  fields: [
@@ -204008,7 +203978,7 @@ function buildBaichuanWebhookSettingsSchema(recommendedHost) {
204008
203978
  id: "baichuan-webhook",
204009
203979
  title: "Battery-cam Motion (HaCfg Webhook)",
204010
203980
  titleKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.title",
204011
- 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).",
203981
+ description: "Preferred over email push when the camera firmware supports it.",
204012
203982
  descriptionKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.description",
204013
203983
  columns: 2,
204014
203984
  fields: [