@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.mjs CHANGED
@@ -28,7 +28,7 @@ import { URL as URL$1 } from "url";
28
28
  import { spawn as spawn$1 } from "node:child_process";
29
29
  import os, { tmpdir } from "node:os";
30
30
  import { createReadStream } from "node:fs";
31
- //#region ../types/dist/event-category-7pZEBmVg.mjs
31
+ //#region ../types/dist/event-category-BfJwUd2S.mjs
32
32
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
33
33
  EventCategory["SystemBoot"] = "system.boot";
34
34
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -345,6 +345,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
345
345
  */
346
346
  EventCategory["PipelineDetectionBlind"] = "pipeline.detection-blind";
347
347
  /**
348
+ * A camera's motion source has fired constantly with no subject for an hour
349
+ * (motion duty or session count over the bar, zero detections) — it is not
350
+ * blind, its motion zones or sensitivity want tuning (D907). Paired with
351
+ * {@link PipelineMotionCalm}.
352
+ */
353
+ EventCategory["PipelineMotionNoisy"] = "pipeline.motion-noisy";
354
+ /** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
355
+ EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
356
+ /**
348
357
  * Per-camera pipeline config was mutated by the orchestrator
349
358
  * (3-level settings change via `setAgentAddonDefaults` /
350
359
  * `setCameraStepToggle` / `setCameraPipelineForAgent` or a
@@ -5451,7 +5460,7 @@ var ZodIssueCode = {
5451
5460
  var ZodFirstPartyTypeKind;
5452
5461
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5453
5462
  //#endregion
5454
- //#region ../types/dist/sleep-CueztlR1.mjs
5463
+ //#region ../types/dist/sleep-DJFUfKvA.mjs
5455
5464
  /**
5456
5465
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5457
5466
  * window to float samples (D455).
@@ -7984,7 +7993,7 @@ var EntryDescriptorSchema = object({
7984
7993
  /** JSON Schema of the entry body; `secret: true` marks a password field. */
7985
7994
  fields: record(string(), unknown())
7986
7995
  }).strict();
7987
- /** What crosses the wire and sits in the engine's catalog: JSON only, no Zod. */
7996
+ /** What crosses the wire from an addon: JSON only, no Zod. An unknown key is refused. */
7988
7997
  var RecordKindDeclarationSchema = object({
7989
7998
  database: _enum(RECORD_DATABASES).default("settings"),
7990
7999
  class: _enum(RECORD_CLASSES),
@@ -8003,14 +8012,6 @@ var RecordKindDeclarationSchema = object({
8003
8012
  secretPaths: array(string().min(1)).default([]),
8004
8013
  /** The id key of each array that carries a secret (`{ headers: 'name' }`). */
8005
8014
  secretArrayKeys: record(string(), string()).default({}),
8006
- /**
8007
- * RETIRED (D900): the legacy table a kind adopted from during the records
8008
- * migration. Nothing declares it any more and nothing reads it; the schema
8009
- * still ACCEPTS it because the catalog rows the migration wrote carry it
8010
- * (an orphaned kind is never redeclared) and an addon built before the
8011
- * removal still sends it. Never set it.
8012
- */
8013
- adoptsFrom: string().min(1).optional(),
8014
8015
  /** Kinds that must agree through `transact` sit in one file under one family name. */
8015
8016
  transactFamily: string().min(1).optional(),
8016
8017
  entry: EntryDescriptorSchema.optional()
@@ -13302,17 +13303,6 @@ object({
13302
13303
  createdAt: number(),
13303
13304
  updatedAt: number()
13304
13305
  });
13305
- object({
13306
- id: string(),
13307
- label: string(),
13308
- isAdmin: boolean().default(false),
13309
- allowedProviders: AllowedProviderSchema,
13310
- allowedDevices: AllowedDevicesSchema,
13311
- tokenHash: string(),
13312
- tokenPrefix: string(),
13313
- createdAt: number(),
13314
- lastUsedAt: number().optional()
13315
- });
13316
13306
  object({
13317
13307
  id: string(),
13318
13308
  userId: string(),
@@ -17294,16 +17284,36 @@ var RecordKindStateSchema = _enum([
17294
17284
  var DeclareKindResultSchema = object({
17295
17285
  kindId: number().int(),
17296
17286
  state: RecordKindStateSchema,
17297
- createdIndexes: array(string()),
17298
- /**
17299
- * RETIRED (D900): always `null`. It carried the records-migration boot guard;
17300
- * it stays on the wire, null, because an addon built before the removal reads
17301
- * an ABSENT field as "adoption pending" and refuses to start.
17302
- */
17303
- adoptionPending: _null()
17287
+ createdIndexes: array(string())
17304
17288
  });
17305
17289
  /** Keychain refs a write released (the old marker is gone from the row): the owner deletes the values. */
17306
17290
  var SecretRefsList = array(string());
17291
+ /**
17292
+ * One op of a `transact`: the single-row writes, each on a kind of the caller.
17293
+ * All ops of one call share ONE database file and ONE `transactFamily`.
17294
+ */
17295
+ var RecordTransactOpSchema = discriminatedUnion("op", [
17296
+ object({
17297
+ op: literal("put"),
17298
+ kind: RecordKindNameSchema,
17299
+ record: RecordInputSchema,
17300
+ ifRev: number().int().min(0).optional()
17301
+ }),
17302
+ object({
17303
+ op: literal("patch"),
17304
+ kind: RecordKindNameSchema,
17305
+ id: RecordIdSchema,
17306
+ data: RecordBodySchema,
17307
+ at: number().int().nullable().optional(),
17308
+ expiresAt: number().int().nullable().optional(),
17309
+ ifRev: number().int().min(1).optional()
17310
+ }),
17311
+ object({
17312
+ op: literal("delete"),
17313
+ kind: RecordKindNameSchema,
17314
+ id: RecordIdSchema
17315
+ })
17316
+ ]);
17307
17317
  var RecordSecretRefsSchema = record(string(), record(string(), string()));
17308
17318
  method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema) }), object({ kinds: record(string(), DeclareKindResultSchema) }), {
17309
17319
  kind: "mutation",
@@ -17410,6 +17420,16 @@ method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema)
17410
17420
  }), {
17411
17421
  kind: "mutation",
17412
17422
  auth: "admin"
17423
+ }), method(object({ ops: array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), object({
17424
+ results: array(object({
17425
+ rev: number().int().nullable(),
17426
+ deleted: boolean()
17427
+ })),
17428
+ releasedRefs: SecretRefsList,
17429
+ secretRefs: SecretRefsList
17430
+ }), {
17431
+ kind: "mutation",
17432
+ auth: "admin"
17413
17433
  }), method(object({
17414
17434
  deviceId: number().int(),
17415
17435
  kinds: array(RecordKindNameSchema).optional()
@@ -43157,9 +43177,13 @@ var NcSystemEventKindSchema = _enum([
43157
43177
  "node-updating",
43158
43178
  "node-inference-unavailable",
43159
43179
  "detection-blind",
43180
+ "motion-noisy",
43181
+ "motion-calm",
43160
43182
  "recording-stalled",
43161
43183
  "recording-healthy",
43162
43184
  "recording-degraded",
43185
+ "device-attention-required",
43186
+ "device-attention-resolved",
43163
43187
  "storage-location-low",
43164
43188
  "storage-location-critical",
43165
43189
  "storage-location-ok",
@@ -57005,6 +57029,16 @@ var DishwasherStatusSchema = object({
57005
57029
  powerState: string().nullable(),
57006
57030
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
57007
57031
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
57032
+ /**
57033
+ * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
57034
+ * combined care-and-filter reminder raised); false when every such reminder reads clear; null
57035
+ * when none is reported. A cleared reminder is not an unknown one.
57036
+ */
57037
+ filterCleaningDue: boolean().nullable(),
57038
+ /** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
57039
+ machineCareDue: boolean().nullable(),
57040
+ /** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
57041
+ machineCareRemainingRuns: number().int().nonnegative().nullable(),
57008
57042
  /** Option states: null when the appliance does not expose the option or has not said. */
57009
57043
  halfLoad: boolean().nullable(),
57010
57044
  hygienePlus: boolean().nullable(),
@@ -66225,16 +66259,6 @@ var UpdateUserInputSchema = object({
66225
66259
  allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
66226
66260
  scopes: array(TokenScopeSchema).optional()
66227
66261
  });
66228
- var ApiKeySummarySchema = object({
66229
- id: string(),
66230
- label: string(),
66231
- isAdmin: boolean().default(false),
66232
- allowedProviders: union([array(string()), literal("*")]).optional(),
66233
- allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
66234
- tokenPrefix: string(),
66235
- createdAt: number(),
66236
- lastUsedAt: number().optional()
66237
- });
66238
66262
  var OauthSessionSummarySchema = object({
66239
66263
  id: string(),
66240
66264
  userId: string(),
@@ -66256,8 +66280,7 @@ var TotpStatusSchema = object({
66256
66280
  confirmedAt: number().nullable()
66257
66281
  });
66258
66282
  /**
66259
- * user-management — singleton capability for user accounts and the
66260
- * legacy API-key rows.
66283
+ * user-management — singleton capability for user accounts.
66261
66284
  *
66262
66285
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
66263
66286
  * — the subset check on `setUserScopes` is moot
@@ -66313,10 +66336,6 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
66313
66336
  }), UserSummarySchema.extend({ passwordHash: string() }).nullable(), {
66314
66337
  kind: "mutation",
66315
66338
  access: "view"
66316
- }), method(_void(), array(ApiKeySummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: literal(true) }), {
66317
- kind: "mutation",
66318
- auth: "admin",
66319
- access: "delete"
66320
66339
  }), method(object({ userId: string() }), TotpSetupResultSchema, {
66321
66340
  kind: "mutation",
66322
66341
  auth: "admin",
@@ -75787,6 +75806,12 @@ Object.freeze({
75787
75806
  addonId: null,
75788
75807
  access: "view"
75789
75808
  },
75809
+ "records.transact": {
75810
+ capName: "records",
75811
+ capScope: "system",
75812
+ addonId: null,
75813
+ access: "create"
75814
+ },
75790
75815
  "sceneMonitor.captureReference": {
75791
75816
  capName: "scene-monitor",
75792
75817
  capScope: "device",
@@ -77119,12 +77144,6 @@ Object.freeze({
77119
77144
  addonId: null,
77120
77145
  access: "view"
77121
77146
  },
77122
- "userManagement.listApiKeys": {
77123
- capName: "user-management",
77124
- capScope: "system",
77125
- addonId: null,
77126
- access: "view"
77127
- },
77128
77147
  "userManagement.listExternalIdentities": {
77129
77148
  capName: "user-management",
77130
77149
  capScope: "system",
@@ -77179,12 +77198,6 @@ Object.freeze({
77179
77198
  addonId: null,
77180
77199
  access: "create"
77181
77200
  },
77182
- "userManagement.revokeApiKey": {
77183
- capName: "user-management",
77184
- capScope: "system",
77185
- addonId: null,
77186
- access: "delete"
77187
- },
77188
77201
  "userManagement.revokeOauthSession": {
77189
77202
  capName: "user-management",
77190
77203
  capScope: "system",
@@ -80701,9 +80714,13 @@ new Map(Object.entries({
80701
80714
  "stream-online": "device-events",
80702
80715
  "stream-offline": "device-events",
80703
80716
  "detection-blind": "device-events",
80717
+ "motion-noisy": "device-events",
80718
+ "motion-calm": "device-events",
80704
80719
  "recording-stalled": "device-events",
80705
80720
  "recording-healthy": "device-events",
80706
80721
  "recording-degraded": "device-events",
80722
+ "device-attention-required": "device-events",
80723
+ "device-attention-resolved": "device-events",
80707
80724
  "node-online": "system",
80708
80725
  "node-offline": "system",
80709
80726
  "node-restarting": "system",
@@ -80786,6 +80803,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
80786
80803
  label: "Detecting nothing",
80787
80804
  kinds: ["detection-blind"]
80788
80805
  },
80806
+ {
80807
+ id: "motion-noise",
80808
+ family: "device-events",
80809
+ label: "Motion without a subject",
80810
+ kinds: ["motion-noisy", "motion-calm"]
80811
+ },
80789
80812
  {
80790
80813
  id: "recording",
80791
80814
  family: "device-events",
@@ -80796,6 +80819,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
80796
80819
  "recording-degraded"
80797
80820
  ]
80798
80821
  },
80822
+ {
80823
+ id: "device-attention",
80824
+ family: "device-events",
80825
+ label: "Needs attention",
80826
+ kinds: ["device-attention-required", "device-attention-resolved"]
80827
+ },
80799
80828
  {
80800
80829
  id: "nodes",
80801
80830
  family: "system",
@@ -80935,6 +80964,7 @@ var ALERT_EPISODE = [
80935
80964
  "alert-error",
80936
80965
  "alert-critical-resolved"
80937
80966
  ];
80967
+ var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
80938
80968
  var UPDATES = [
80939
80969
  "addon-update-available",
80940
80970
  "server-update-available",
@@ -80964,9 +80994,12 @@ var DEVICE_EVENTS = [
80964
80994
  "stream-online",
80965
80995
  "stream-offline",
80966
80996
  "detection-blind",
80997
+ "motion-noisy",
80998
+ "motion-calm",
80967
80999
  "recording-stalled",
80968
81000
  "recording-healthy",
80969
81001
  "recording-degraded",
81002
+ ...DEVICE_ATTENTION,
80970
81003
  ...ALARM
80971
81004
  ];
80972
81005
  /** Every kind a summary may speak about — the two summarisable families. */
@@ -81134,7 +81167,9 @@ var STATE_SUMMARY_VARS = [
81134
81167
  [...RULE_TEXT],
81135
81168
  [...RULE_TEXT],
81136
81169
  [...RULE_TEXT],
81137
- ([...RULE_TEXT], [...ALERT_EPISODE]),
81170
+ [...RULE_TEXT],
81171
+ [...RULE_TEXT],
81172
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
81138
81173
  [...RULE_TEXT],
81139
81174
  [...RULE_TEXT],
81140
81175
  [...RULE_TEXT],
@@ -81156,11 +81191,11 @@ var STATE_SUMMARY_VARS = [
81156
81191
  [...RULE_TEXT],
81157
81192
  [...RULE_TEXT],
81158
81193
  [...RULE_TEXT],
81194
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
81159
81195
  ([...RULE_TEXT], [...ALERT_EPISODE]),
81196
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
81160
81197
  ([...RULE_TEXT], [...ALERT_EPISODE]),
81161
- ([...RULE_TEXT], [...ALERT_EPISODE]),
81162
- ([...RULE_TEXT], [...ALERT_EPISODE]),
81163
- ([...RULE_TEXT], [...ALERT_EPISODE]),
81198
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
81164
81199
  [...RULE_TEXT],
81165
81200
  [...RULE_TEXT],
81166
81201
  [...RULE_TEXT],
@@ -81236,6 +81271,15 @@ new Map([
81236
81271
  snapshotLabel: "Tanks low or full now",
81237
81272
  snapshotSection: "tanks"
81238
81273
  },
81274
+ {
81275
+ id: "motion-noise",
81276
+ family: "device-events",
81277
+ label: "Motion without a subject (constant / calm again)",
81278
+ bad: ["motion-noisy"],
81279
+ recovery: ["motion-calm"],
81280
+ snapshotLabel: "Cameras with constant motion now",
81281
+ snapshotSection: null
81282
+ },
81239
81283
  {
81240
81284
  id: "recording-health",
81241
81285
  family: "device-events",
@@ -81245,6 +81289,15 @@ new Map([
81245
81289
  snapshotLabel: "Recordings stalled now",
81246
81290
  snapshotSection: null
81247
81291
  },
81292
+ {
81293
+ id: "device-attention",
81294
+ family: "device-events",
81295
+ label: "Device needs attention (raised / resolved)",
81296
+ bad: ["device-attention-required"],
81297
+ recovery: ["device-attention-resolved"],
81298
+ snapshotLabel: "Devices needing attention now",
81299
+ snapshotSection: null
81300
+ },
81248
81301
  {
81249
81302
  id: "node-connectivity",
81250
81303
  family: "system",
@@ -188569,8 +188622,8 @@ var CLIP_REFRESH_SECTION_ID = "clip-catalog-refresh";
188569
188622
  * settings nobody could reason about. So the difference is in the operator's
188570
188623
  * own text, at both levels, not only in a record.
188571
188624
  */
188572
- 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.";
188573
- 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.";
188625
+ 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.";
188626
+ 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.";
188574
188627
  /**
188575
188628
  * The addon-level (global) default. Per-camera overrides live on the device,
188576
188629
  * under the SAME key, and a device that sets nothing — or resets — resolves to
@@ -188580,7 +188633,7 @@ function buildClipRefreshSettingsSchema() {
188580
188633
  return { sections: [{
188581
188634
  id: CLIP_REFRESH_SECTION_ID,
188582
188635
  title: "Clip catalog refresh",
188583
- 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.",
188636
+ description: "Default for every camera; a camera can override it in its Recording settings.",
188584
188637
  columns: 1,
188585
188638
  fields: [{
188586
188639
  type: "number",
@@ -188610,7 +188663,7 @@ function buildClipRefreshDeviceSection(input) {
188610
188663
  id: CLIP_REFRESH_SECTION_ID,
188611
188664
  tab: "recording",
188612
188665
  title: "Clip catalog refresh",
188613
- 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.",
188666
+ description: "Leave the interval empty to use the default from the Reolink addon settings.",
188614
188667
  columns: 1,
188615
188668
  fields: [{
188616
188669
  type: "number",
@@ -188889,7 +188942,7 @@ function buildSnapshotFreshnessSection(cache, opts) {
188889
188942
  tab: "advanced",
188890
188943
  title: "Snapshot freshness",
188891
188944
  titleKey: "provider-reolink:snapshotFreshnessSection.s_snapshotFreshness.title",
188892
- 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.",
188945
+ description: "Groups without a stamp are of unknown age, not fresh.",
188893
188946
  descriptionKey: "provider-reolink:snapshotFreshnessSection.s_snapshotFreshness.description",
188894
188947
  columns: 1,
188895
188948
  fields: [{
@@ -189920,7 +189973,7 @@ var BatteryHourlyRefresh = class {
189920
189973
  //#endregion
189921
189974
  //#region src/battery-refresh-settings.ts
189922
189975
  var BATTERY_REFRESH_SECTION_ID = "battery-refresh";
189923
- 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).`;
189976
+ var BATTERY_REFRESH_MINUTES_DESCRIPTION = "A camera that slept the whole window is woken once to refresh. 0 turns the scheduled refresh off.";
189924
189977
  /** Battery cameras only: a mains camera keeps its facts fresh on its own socket. */
189925
189978
  function buildBatteryRefreshDeviceSection(input) {
189926
189979
  if (!input.isBattery) return [];
@@ -189928,7 +189981,6 @@ function buildBatteryRefreshDeviceSection(input) {
189928
189981
  id: BATTERY_REFRESH_SECTION_ID,
189929
189982
  tab: "general",
189930
189983
  title: "Scheduled refresh",
189931
- description: "How often this battery camera is guaranteed to have been read, so a battery level never goes stale unseen.",
189932
189984
  columns: 1,
189933
189985
  fields: [{
189934
189986
  type: "number",
@@ -190022,7 +190074,7 @@ async function refreshSnapshotCacheOnce(input) {
190022
190074
  */
190023
190075
  var CH_BAICHUAN = declareLogChannel({
190024
190076
  name: "provider-reolink.baichuan",
190025
- 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.",
190077
+ description: "Every Baichuan protocol frame this camera sends and receives. Loud: arm it for one camera and a short window.",
190026
190078
  defaultLevel: "info",
190027
190079
  perDevice: true
190028
190080
  });
@@ -190037,7 +190089,7 @@ var CH_BAICHUAN = declareLogChannel({
190037
190089
  */
190038
190090
  var CH_HANDSHAKE = declareLogChannel({
190039
190091
  name: "provider-reolink.handshake",
190040
- 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.",
190092
+ description: "Login and socket lifecycle for this camera. Arm it when a camera looks present but answers nothing.",
190041
190093
  defaultLevel: "info",
190042
190094
  perDevice: true
190043
190095
  });
@@ -190446,7 +190498,7 @@ function buildOsdSection(snapshot, values, opts) {
190446
190498
  tab: "image",
190447
190499
  title: "OSD overlay",
190448
190500
  titleKey: "provider-reolink:osdSection.s_osd.title",
190449
- 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.",
190501
+ description: "An overlay the camera holds somewhere else keeps that placement unless a corner is chosen.",
190450
190502
  descriptionKey: "provider-reolink:osdSection.s_osd.description",
190451
190503
  columns: 2,
190452
190504
  fields: [
@@ -190458,8 +190510,6 @@ function buildOsdSection(snapshot, values, opts) {
190458
190510
  key: "osdChannelName",
190459
190511
  label: "Channel name",
190460
190512
  labelKey: "provider-reolink:fields.osdChannelName.label",
190461
- description: "Text shown in the channel-name overlay.",
190462
- descriptionKey: "provider-reolink:fields.osdChannelName.description",
190463
190513
  default: values.osdChannelName,
190464
190514
  placeholder: "Front door"
190465
190515
  },
@@ -190943,7 +190993,7 @@ var SirenAccessory = class extends BaseDevice {
190943
190993
  id: "siren",
190944
190994
  title: "Siren",
190945
190995
  titleKey: "provider-reolink:schema.s_siren.title",
190946
- description: "Tone duration when triggered. Set to 0 for \"play until turned off\"; positive values pulse for that many seconds.",
190996
+ description: "0 = play until turned off.",
190947
190997
  descriptionKey: "provider-reolink:schema.s_siren.description",
190948
190998
  columns: 1,
190949
190999
  fields: [{
@@ -190951,8 +191001,6 @@ var SirenAccessory = class extends BaseDevice {
190951
191001
  key: "sirenDurationS",
190952
191002
  label: "Default duration (seconds)",
190953
191003
  labelKey: "provider-reolink:schema.s_siren.sirenDurationS.label",
190954
- description: "Forwarded to `setSiren(on=true, duration)` (cmd_id 30) when the operator flips the switch.",
190955
- descriptionKey: "provider-reolink:schema.s_siren.sirenDurationS.description",
190956
191004
  default: 0,
190957
191005
  min: 0,
190958
191006
  max: 300,
@@ -190962,16 +191010,12 @@ var SirenAccessory = class extends BaseDevice {
190962
191010
  id: "motion-siren",
190963
191011
  title: "Motion-triggered siren",
190964
191012
  titleKey: "provider-reolink:schema.s_motion-siren.title",
190965
- 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.",
190966
- descriptionKey: "provider-reolink:schema.s_motion-siren.description",
190967
191013
  columns: 1,
190968
191014
  fields: [{
190969
191015
  type: "select",
190970
191016
  key: "motionSirenDetectType",
190971
191017
  label: "Detection classes",
190972
191018
  labelKey: "provider-reolink:schema.s_motion-siren.motionSirenDetectType.label",
190973
- description: "Object/motion classes that arm the siren. `MD` = generic motion detection.",
190974
- descriptionKey: "provider-reolink:schema.s_motion-siren.motionSirenDetectType.description",
190975
191019
  options: SIREN_DETECT_TYPE_CHOICES.map((v) => ({
190976
191020
  value: v,
190977
191021
  label: v.replace(/,/g, " + ").replace(/_/g, "+")
@@ -191435,16 +191479,12 @@ var FloodlightAccessory = class extends BaseDevice {
191435
191479
  id: "motion-floodlight",
191436
191480
  title: "Motion-triggered floodlight",
191437
191481
  titleKey: "provider-reolink:schema.s_motion-floodlight.title",
191438
- 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.",
191439
- descriptionKey: "provider-reolink:schema.s_motion-floodlight.description",
191440
191482
  columns: 2,
191441
191483
  fields: [{
191442
191484
  type: "number",
191443
191485
  key: "motionLightDurationS",
191444
191486
  label: "Light duration (s)",
191445
191487
  labelKey: "provider-reolink:schema.s_motion-floodlight.motionLightDurationS.label",
191446
- description: "Seconds the floodlight stays lit after a motion event. Reolink range 1..600s.",
191447
- descriptionKey: "provider-reolink:schema.s_motion-floodlight.motionLightDurationS.description",
191448
191488
  min: 1,
191449
191489
  max: 600,
191450
191490
  step: 1,
@@ -191454,8 +191494,6 @@ var FloodlightAccessory = class extends BaseDevice {
191454
191494
  key: "motionLightDetectType",
191455
191495
  label: "Detection classes",
191456
191496
  labelKey: "provider-reolink:schema.s_motion-floodlight.motionLightDetectType.label",
191457
- description: "Object classes that turn the floodlight on. Composed values (e.g. \"people,vehicle\") fire when ANY listed class detects.",
191458
- descriptionKey: "provider-reolink:schema.s_motion-floodlight.motionLightDetectType.description",
191459
191497
  options: FLOODLIGHT_DETECT_TYPE_CHOICES.map((v) => ({
191460
191498
  value: v,
191461
191499
  label: v.replace(/,/g, " + ").replace(/_/g, "+")
@@ -191695,8 +191733,6 @@ var PirAccessory = class extends BaseDevice {
191695
191733
  id: "pir",
191696
191734
  title: "PIR sensor",
191697
191735
  titleKey: "provider-reolink:schema.s_pir.title",
191698
- description: "Hardware passive-infrared trigger configuration. Pushed via cmd_id 153 (SetPirInfo).",
191699
- descriptionKey: "provider-reolink:schema.s_pir.description",
191700
191736
  columns: 2,
191701
191737
  fields: [
191702
191738
  {
@@ -191704,8 +191740,6 @@ var PirAccessory = class extends BaseDevice {
191704
191740
  key: "pirSensitive",
191705
191741
  label: "Sensitivity",
191706
191742
  labelKey: "provider-reolink:schema.s_pir.pirSensitive.label",
191707
- description: "Higher value → triggers on smaller motion. Most cameras max at 100.",
191708
- descriptionKey: "provider-reolink:schema.s_pir.pirSensitive.description",
191709
191743
  min: 1,
191710
191744
  max: 100,
191711
191745
  step: 1,
@@ -191717,7 +191751,6 @@ var PirAccessory = class extends BaseDevice {
191717
191751
  key: "pirIntervalS",
191718
191752
  label: "Cooldown (seconds)",
191719
191753
  labelKey: "provider-reolink:schema.s_pir.pirIntervalS.label",
191720
- description: `Minimum delay between consecutive PIR triggers. Reolink app range 5..${intervalMax}s; firmware clamps on push.`,
191721
191754
  min: 5,
191722
191755
  max: intervalMax,
191723
191756
  step: 1,
@@ -191730,8 +191763,6 @@ var PirAccessory = class extends BaseDevice {
191730
191763
  key: "pirReduceAlarm",
191731
191764
  label: "Reduce false alarms",
191732
191765
  labelKey: "provider-reolink:schema.s_pir.pirReduceAlarm.label",
191733
- description: "Trades detection range for fewer false positives. Maps to firmware `reduceAlarm` flag.",
191734
- descriptionKey: "provider-reolink:schema.s_pir.pirReduceAlarm.description",
191735
191766
  ...typeof reduceAlarm === "boolean" ? { default: reduceAlarm } : {},
191736
191767
  style: "switch",
191737
191768
  span: 2
@@ -193280,8 +193311,6 @@ function buildSessionsTabSections(snap, opts) {
193280
193311
  return [{
193281
193312
  id: "sessions-status",
193282
193313
  title: opts.title ?? "Sessions",
193283
- description: "Diagnostics for the Baichuan control channel. Auto-refreshes when older than 1 minute; click Refresh to force.",
193284
- descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.description",
193285
193314
  tab: opts.tabId,
193286
193315
  order: 0,
193287
193316
  columns: 1,
@@ -193299,8 +193328,6 @@ function buildSessionsTabSections(snap, opts) {
193299
193328
  key: "sessionsOnlineUsers",
193300
193329
  label: "Online users (firmware)",
193301
193330
  labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.label",
193302
- description: "Active user sessions reported by the device (cmd_id 145). Includes other admins, mobile app, NVR linkups.",
193303
- descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsOnlineUsers.description",
193304
193331
  columns: [
193305
193332
  {
193306
193333
  key: "userName",
@@ -193343,8 +193370,6 @@ function buildSessionsTabSections(snap, opts) {
193343
193370
  key: "sessionsSocketPool",
193344
193371
  label: "Our socket pool",
193345
193372
  labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsSocketPool.label",
193346
- description: "Open Baichuan TCP/UDP sockets this process holds for the device. One row per pool tag.",
193347
- descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsSocketPool.description",
193348
193373
  columns: [{
193349
193374
  key: "tag",
193350
193375
  label: "Tag",
@@ -193365,8 +193390,6 @@ function buildSessionsTabSections(snap, opts) {
193365
193390
  key: "sessionsDedicated",
193366
193391
  label: "Dedicated lib sessions",
193367
193392
  labelKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsDedicated.label",
193368
- description: "Internal lib-side dedicated sessions (streaming/talk channels). Older lib versions leave this list empty.",
193369
- descriptionKey: "provider-reolink:sessionsTabSections.s_sessions-status.sessionsDedicated.description",
193370
193393
  columns: [{
193371
193394
  key: "key",
193372
193395
  label: "Session key",
@@ -195751,7 +195774,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
195751
195774
  tab: "motion",
195752
195775
  title: "Battery motion (sleep push)",
195753
195776
  titleKey: "provider-reolink:emailPushSection.s_sleep-push.title",
195754
- 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.",
195777
+ description: "Prefer the HaCfg webhook when the firmware supports it; arm only one path.",
195755
195778
  descriptionKey: "provider-reolink:emailPushSection.s_sleep-push.description",
195756
195779
  columns: 1,
195757
195780
  fields: [
@@ -195817,7 +195840,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
195817
195840
  tab: "email",
195818
195841
  title: "SMTP server",
195819
195842
  titleKey: "provider-reolink:emailTabSections.s_email-smtp.title",
195820
- 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.",
195843
+ description: "Leave the password blank to keep the current one.",
195821
195844
  descriptionKey: "provider-reolink:emailTabSections.s_email-smtp.description",
195822
195845
  columns: 2,
195823
195846
  fields: [
@@ -195872,8 +195895,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
195872
195895
  tab: "email",
195873
195896
  title: "Recipients",
195874
195897
  titleKey: "provider-reolink:emailTabSections.s_email-recipients.title",
195875
- description: "Up to three recipient addresses the camera sends motion mail to.",
195876
- descriptionKey: "provider-reolink:emailTabSections.s_email-recipients.description",
195877
195898
  columns: 1,
195878
195899
  fields: [
195879
195900
  {
@@ -195902,8 +195923,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
195902
195923
  tab: "email",
195903
195924
  title: "Alarm schedule",
195904
195925
  titleKey: "provider-reolink:emailTabSections.s_email-schedule.title",
195905
- description: "Master enable for the camera's email alarm schedule (EmailTask).",
195906
- descriptionKey: "provider-reolink:emailTabSections.s_email-schedule.description",
195907
195926
  columns: 1,
195908
195927
  fields: [{
195909
195928
  type: "boolean",
@@ -199779,7 +199798,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
199779
199798
  tab: "general",
199780
199799
  title: "Camera data",
199781
199800
  titleKey: "provider-reolink:schema.s_driver-refresh.title",
199782
- 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.",
199801
+ description: "Wakes a sleeping camera and re-reads everything; no other read here wakes it.",
199783
199802
  descriptionKey: "provider-reolink:schema.s_driver-refresh.description",
199784
199803
  columns: 1,
199785
199804
  fields: [{
@@ -199798,8 +199817,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
199798
199817
  tab: "general",
199799
199818
  title: "Connection",
199800
199819
  titleKey: "provider-reolink:schema.s_connection.title",
199801
- description: "Baichuan protocol connection settings.",
199802
- descriptionKey: "provider-reolink:schema.s_connection.description",
199803
199820
  columns: 2,
199804
199821
  fields: [
199805
199822
  {
@@ -199842,7 +199859,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
199842
199859
  tab: "network",
199843
199860
  title: "Service ports",
199844
199861
  titleKey: "provider-reolink:schema.s_network-ports.title",
199845
- 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.",
199862
+ description: "Changing a port breaks existing URLs for that protocol.",
199846
199863
  descriptionKey: "provider-reolink:schema.s_network-ports.description",
199847
199864
  columns: 2,
199848
199865
  fields: [
@@ -199943,8 +199960,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
199943
199960
  tab: "network",
199944
199961
  title: "Time / NTP",
199945
199962
  titleKey: "provider-reolink:schema.s_time-ntp.title",
199946
- 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.",
199947
- descriptionKey: "provider-reolink:schema.s_time-ntp.description",
199948
199963
  columns: 2,
199949
199964
  fields: [
199950
199965
  {
@@ -199952,8 +199967,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
199952
199967
  key: "timeZoneId",
199953
199968
  label: "Timezone",
199954
199969
  labelKey: "provider-reolink:schema.s_time-ntp.timeZoneId.label",
199955
- 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.",
199956
- descriptionKey: "provider-reolink:schema.s_time-ntp.timeZoneId.description",
199957
199970
  default: this.config.get("timeZoneId") ?? reolinkTimeZoneToIana(this.config.get("deviceCache")?.systemGeneralSnapshot?.timeZone) ?? "",
199958
199971
  span: 2
199959
199972
  },
@@ -200002,16 +200015,12 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200002
200015
  tab: "motion",
200003
200016
  title: "On-camera motion (MdAlarm)",
200004
200017
  titleKey: "provider-reolink:schema.s_motion.title",
200005
- 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.",
200006
- descriptionKey: "provider-reolink:schema.s_motion.description",
200007
200018
  columns: 2,
200008
200019
  fields: [{
200009
200020
  type: "boolean",
200010
200021
  key: "motionEnabled",
200011
200022
  label: "Motion detection",
200012
200023
  labelKey: "provider-reolink:schema.s_motion.motionEnabled.label",
200013
- description: "Master switch for the camera's on-board motion detector. Disabling stops the camera from emitting motion events on the alarm channel.",
200014
- descriptionKey: "provider-reolink:schema.s_motion.motionEnabled.description",
200015
200024
  default: motionSnap.enabled ?? true,
200016
200025
  style: "switch",
200017
200026
  span: 2
@@ -200020,8 +200029,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200020
200029
  key: "motionSensitivity",
200021
200030
  label: "Sensitivity",
200022
200031
  labelKey: "provider-reolink:schema.s_motion.motionSensitivity.label",
200023
- description: "Higher = triggers on smaller motion. Reolink user-facing range 1..50.",
200024
- descriptionKey: "provider-reolink:schema.s_motion.motionSensitivity.description",
200025
200032
  min: 1,
200026
200033
  max: 50,
200027
200034
  step: 1,
@@ -200036,8 +200043,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200036
200043
  tab: "motion",
200037
200044
  title: "AI detection sensitivity",
200038
200045
  titleKey: "provider-reolink:schema.s_ai-sensitivity.title",
200039
- 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.",
200040
- descriptionKey: "provider-reolink:schema.s_ai-sensitivity.description",
200041
200046
  columns: 2,
200042
200047
  fields: [
200043
200048
  [
@@ -200106,7 +200111,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200106
200111
  type: "slider",
200107
200112
  key: stayKey,
200108
200113
  label: `${label} stay time (s)`,
200109
- description: "Seconds the camera keeps the AI alarm asserted after the object leaves frame.",
200110
200114
  min: 0,
200111
200115
  max: 600,
200112
200116
  step: 1,
@@ -200169,8 +200173,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200169
200173
  tab: "image",
200170
200174
  title: "Image",
200171
200175
  titleKey: "provider-reolink:schema.s_image.title",
200172
- 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.",
200173
- descriptionKey: "provider-reolink:schema.s_image.description",
200174
200176
  columns: 2,
200175
200177
  fields: [
200176
200178
  {
@@ -200241,24 +200243,18 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200241
200243
  tab: "image",
200242
200244
  title: "Advanced (ISP)",
200243
200245
  titleKey: "provider-reolink:schema.s_isp.title",
200244
- description: "Day/Night + exposure + HDR. Pushed via `SetIsp` (cmd_id 25). The day/night threshold uses cmd_id 297 (DayNightThreshold).",
200245
- descriptionKey: "provider-reolink:schema.s_isp.description",
200246
200246
  columns: 2,
200247
200247
  fields: [{
200248
200248
  type: "text",
200249
200249
  key: "ispDayNight",
200250
200250
  label: "Day/Night mode",
200251
200251
  labelKey: "provider-reolink:schema.s_isp.ispDayNight.label",
200252
- description: "Camera-specific values — common: `auto`, `color`, `blackAndWhite`. The driver normalizes case before push.",
200253
- descriptionKey: "provider-reolink:schema.s_isp.ispDayNight.description",
200254
200252
  default: imgSnap.dayNight ?? "auto"
200255
200253
  }, {
200256
200254
  type: "text",
200257
200255
  key: "ispExposure",
200258
200256
  label: "Exposure",
200259
200257
  labelKey: "provider-reolink:schema.s_isp.ispExposure.label",
200260
- description: "Common values: `auto`, `manual`. Lowercased before push.",
200261
- descriptionKey: "provider-reolink:schema.s_isp.ispExposure.description",
200262
200258
  default: "auto"
200263
200259
  }]
200264
200260
  }] : [],
@@ -200267,8 +200263,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200267
200263
  tab: "image",
200268
200264
  title: "IR + status LED",
200269
200265
  titleKey: "provider-reolink:schema.s_ir-lights.title",
200270
- 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.",
200271
- descriptionKey: "provider-reolink:schema.s_ir-lights.description",
200272
200266
  columns: 2,
200273
200267
  fields: [
200274
200268
  {
@@ -200300,7 +200294,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200300
200294
  key: "irLightsBrightness",
200301
200295
  label: "IR brightness",
200302
200296
  labelKey: "provider-reolink:schema.s_ir-lights.irLightsBrightness.label",
200303
- description: "Only applied when the camera advertises programmable IR brightness. 0..255 raw range; many models clamp to 0..100.",
200297
+ description: "Only applied when the camera supports adjustable IR brightness.",
200304
200298
  descriptionKey: "provider-reolink:schema.s_ir-lights.irLightsBrightness.description",
200305
200299
  min: 0,
200306
200300
  max: 255,
@@ -200314,8 +200308,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200314
200308
  key: "statusLedEnabled",
200315
200309
  label: "Status LED",
200316
200310
  labelKey: "provider-reolink:schema.s_ir-lights.statusLedEnabled.label",
200317
- description: "The visible status/power LED on the camera body. Pushed via `SetIrLights` (cmd_id 209) as `lightState`.",
200318
- descriptionKey: "provider-reolink:schema.s_ir-lights.statusLedEnabled.description",
200319
200311
  default: cache?.ledSnapshot?.statusEnabled ?? true,
200320
200312
  style: "switch",
200321
200313
  span: cache?.ledSnapshot?.doorbellSupported === true ? 1 : 2
@@ -200325,8 +200317,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200325
200317
  key: "doorbellLedEnabled",
200326
200318
  label: "Doorbell LED",
200327
200319
  labelKey: "provider-reolink:schema.s_ir-lights.doorbellLedEnabled.label",
200328
- description: "The doorbell button ring LED. Pushed via `SetIrLights` (cmd_id 209) as `doorbellLightState`.",
200329
- descriptionKey: "provider-reolink:schema.s_ir-lights.doorbellLedEnabled.description",
200330
200320
  default: cache?.ledSnapshot?.doorbellEnabled ?? true,
200331
200321
  style: "switch"
200332
200322
  }] : []
@@ -200341,7 +200331,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200341
200331
  tab: "image",
200342
200332
  title: "Auto focus",
200343
200333
  titleKey: "provider-reolink:schema.s_auto-focus.title",
200344
- 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.",
200334
+ description: "Disabling locks the lens at its current focus.",
200345
200335
  descriptionKey: "provider-reolink:schema.s_auto-focus.description",
200346
200336
  columns: 1,
200347
200337
  fields: [{
@@ -200358,8 +200348,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200358
200348
  tab: "audio",
200359
200349
  title: "Audio output",
200360
200350
  titleKey: "provider-reolink:schema.s_audio.title",
200361
- 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.",
200362
- descriptionKey: "provider-reolink:schema.s_audio.description",
200363
200351
  columns: 2,
200364
200352
  fields: [
200365
200353
  {
@@ -200379,7 +200367,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200379
200367
  key: "audioTalkAndReplyVolume",
200380
200368
  label: "Talk + reply volume",
200381
200369
  labelKey: "provider-reolink:schema.s_audio.audioTalkAndReplyVolume.label",
200382
- description: "Two-way audio + canned reply playback. Doorbell-only on most firmwares.",
200370
+ description: "Doorbell models only.",
200383
200371
  descriptionKey: "provider-reolink:schema.s_audio.audioTalkAndReplyVolume.description",
200384
200372
  min: 0,
200385
200373
  max: 100,
@@ -200393,7 +200381,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200393
200381
  key: "audioVisitorVolume",
200394
200382
  label: "Visitor volume",
200395
200383
  labelKey: "provider-reolink:schema.s_audio.audioVisitorVolume.label",
200396
- description: "Visitor / chime playback channel. Doorbell-only on most firmwares.",
200384
+ description: "Doorbell models only.",
200397
200385
  descriptionKey: "provider-reolink:schema.s_audio.audioVisitorVolume.description",
200398
200386
  min: 0,
200399
200387
  max: 100,
@@ -200410,8 +200398,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200410
200398
  tab: "audio",
200411
200399
  title: "Audio noise reduction",
200412
200400
  titleKey: "provider-reolink:schema.s_audio-noise.title",
200413
- 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).",
200414
- descriptionKey: "provider-reolink:schema.s_audio-noise.description",
200415
200401
  columns: 1,
200416
200402
  fields: [{
200417
200403
  type: "slider",
@@ -200433,7 +200419,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200433
200419
  tab: "audio",
200434
200420
  title: "Intercom",
200435
200421
  titleKey: "provider-reolink:schema.s_intercom.title",
200436
- description: "Push-to-talk pipeline tuning. Settings take effect on the next talk session — restart any active session for changes to apply.",
200422
+ description: "Changes apply to the next talk session.",
200437
200423
  descriptionKey: "provider-reolink:schema.s_intercom.description",
200438
200424
  columns: 2,
200439
200425
  fields: [
@@ -200442,7 +200428,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200442
200428
  key: "intercomBlocksPerPayload",
200443
200429
  label: "Blocks per payload",
200444
200430
  labelKey: "provider-reolink:schema.s_intercom.intercomBlocksPerPayload.label",
200445
- description: "Lower = lower latency (more sendAudio calls/sec). Higher = fewer calls, less per-call socket overhead. Range 1..8. Default 1 (lowest latency).",
200431
+ description: "Lower is lower latency, higher is fewer calls. Range 1..8.",
200446
200432
  descriptionKey: "provider-reolink:schema.s_intercom.intercomBlocksPerPayload.description",
200447
200433
  min: 1,
200448
200434
  max: 8,
@@ -200456,7 +200442,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200456
200442
  key: "intercomMaxBacklogMs",
200457
200443
  label: "Max backlog (ms)",
200458
200444
  labelKey: "provider-reolink:schema.s_intercom.intercomMaxBacklogMs.label",
200459
- 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.",
200445
+ description: "Higher is more stable on slow systems but adds latency. Range 20..5000.",
200460
200446
  descriptionKey: "provider-reolink:schema.s_intercom.intercomMaxBacklogMs.description",
200461
200447
  min: 20,
200462
200448
  max: 5e3,
@@ -200470,7 +200456,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200470
200456
  key: "intercomGain",
200471
200457
  label: "Output gain",
200472
200458
  labelKey: "provider-reolink:schema.s_intercom.intercomGain.label",
200473
- description: "Multiplier applied to PCM samples before IMA-ADPCM encode. 1.0 = neutral, 2.0 ≈ +6dB, 0.5 ≈ -6dB. Hard-clipped at int16 bounds.",
200459
+ description: "1.0 = neutral, 2.0 ≈ +6 dB, 0.5 ≈ -6 dB.",
200474
200460
  descriptionKey: "provider-reolink:schema.s_intercom.intercomGain.description",
200475
200461
  min: .1,
200476
200462
  max: 10,
@@ -200487,7 +200473,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200487
200473
  tab: "advanced",
200488
200474
  title: "Keyframe interval (GOP)",
200489
200475
  titleKey: "provider-reolink:schema.s_keyframe-gop.title",
200490
- 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.",
200476
+ description: "Lower = more keyframes (faster recovery, higher bitrate).",
200491
200477
  descriptionKey: "provider-reolink:schema.s_keyframe-gop.description",
200492
200478
  columns: 1,
200493
200479
  fields: [{
@@ -200508,8 +200494,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200508
200494
  tab: "advanced",
200509
200495
  title: "PIR detection",
200510
200496
  titleKey: "provider-reolink:schema.s_pir-reduce-alarm.title",
200511
- 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.",
200512
- descriptionKey: "provider-reolink:schema.s_pir-reduce-alarm.description",
200513
200497
  columns: 1,
200514
200498
  fields: [{
200515
200499
  type: "boolean",
@@ -200525,8 +200509,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200525
200509
  tab: "advanced",
200526
200510
  title: "Auto reboot",
200527
200511
  titleKey: "provider-reolink:schema.s_auto-reboot.title",
200528
- 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.",
200529
- descriptionKey: "provider-reolink:schema.s_auto-reboot.description",
200530
200512
  columns: 2,
200531
200513
  fields: [
200532
200514
  {
@@ -200615,7 +200597,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200615
200597
  tab: "advanced",
200616
200598
  title: "Debug",
200617
200599
  titleKey: "provider-reolink:schema.s_debug.title",
200618
- 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.",
200600
+ description: "Debug logging adds log volume; use it temporarily.",
200619
200601
  descriptionKey: "provider-reolink:schema.s_debug.description",
200620
200602
  columns: 1,
200621
200603
  fields: [{
@@ -200623,8 +200605,6 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200623
200605
  key: "debugGeneral",
200624
200606
  label: "General debug logs",
200625
200607
  labelKey: "provider-reolink:schema.s_debug.debugGeneral.label",
200626
- description: "Forwards `DebugOptions.general=true` — verbose lib protocol logs.",
200627
- descriptionKey: "provider-reolink:schema.s_debug.debugGeneral.description",
200628
200608
  default: false,
200629
200609
  style: "switch"
200630
200610
  }, {
@@ -200632,7 +200612,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
200632
200612
  key: "debugSocketLogs",
200633
200613
  label: "Socket trace categories",
200634
200614
  labelKey: "provider-reolink:schema.s_debug.debugSocketLogs.label",
200635
- description: "Per-area lib tracing. Pick only what you need; each adds log volume.",
200615
+ description: "Each area adds log volume.",
200636
200616
  descriptionKey: "provider-reolink:schema.s_debug.debugSocketLogs.description",
200637
200617
  default: [],
200638
200618
  options: [
@@ -202203,7 +202183,7 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
202203
202183
  tab: "general",
202204
202184
  title: "Connection",
202205
202185
  titleKey: "provider-reolink:hub.s_connection.title",
202206
- 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.",
202186
+ description: "Child cameras inherit these credentials.",
202207
202187
  descriptionKey: "provider-reolink:hub.s_connection.description",
202208
202188
  columns: 2,
202209
202189
  fields: [
@@ -202247,8 +202227,6 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
202247
202227
  tab: "general",
202248
202228
  title: "Hub identity",
202249
202229
  titleKey: "provider-reolink:hub.s_identity.title",
202250
- description: "Read-only summary from the autodetect probe. Channel count and model are persisted at first contact so the panel renders without re-probing.",
202251
- descriptionKey: "provider-reolink:hub.s_identity.description",
202252
202230
  columns: 2,
202253
202231
  fields: [{
202254
202232
  type: "text",
@@ -202271,7 +202249,7 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
202271
202249
  tab: "advanced",
202272
202250
  title: "Debug",
202273
202251
  titleKey: "provider-reolink:hub.s_debug.title",
202274
- 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.",
202252
+ description: "Debug logging adds log volume; use it temporarily.",
202275
202253
  descriptionKey: "provider-reolink:hub.s_debug.description",
202276
202254
  columns: 1,
202277
202255
  fields: [{
@@ -202279,8 +202257,6 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
202279
202257
  key: "debugGeneral",
202280
202258
  label: "General debug logs",
202281
202259
  labelKey: "provider-reolink:hub.s_debug.debugGeneral.label",
202282
- description: "Forwards `DebugOptions.general=true` — verbose lib protocol logs.",
202283
- descriptionKey: "provider-reolink:hub.s_debug.debugGeneral.description",
202284
202260
  default: false,
202285
202261
  style: "switch"
202286
202262
  }, {
@@ -202288,7 +202264,7 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
202288
202264
  key: "debugSocketLogs",
202289
202265
  label: "Socket trace categories",
202290
202266
  labelKey: "provider-reolink:hub.s_debug.debugSocketLogs.label",
202291
- description: "Per-area lib tracing. Pick only what you need; each adds log volume.",
202267
+ description: "Each area adds log volume.",
202292
202268
  descriptionKey: "provider-reolink:hub.s_debug.debugSocketLogs.description",
202293
202269
  default: [],
202294
202270
  options: [
@@ -203051,7 +203027,7 @@ function buildDiscoveryParamsFormSchema() {
203051
203027
  id: "credentials",
203052
203028
  title: "Credentials",
203053
203029
  titleKey: "provider-reolink:discoveryParams.s_credentials.title",
203054
- 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.",
203030
+ description: "Assumes all cameras share these credentials.",
203055
203031
  descriptionKey: "provider-reolink:discoveryParams.s_credentials.description",
203056
203032
  columns: 2,
203057
203033
  fields: [{
@@ -203073,7 +203049,7 @@ function buildDiscoveryParamsFormSchema() {
203073
203049
  id: "scan",
203074
203050
  title: "Scan options",
203075
203051
  titleKey: "provider-reolink:discoveryParams.s_scan.title",
203076
- 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).",
203052
+ description: "Leave blank to scan the local subnet; for another subnet enter its CIDR (e.g. 192.168.20.0/24).",
203077
203053
  descriptionKey: "provider-reolink:discoveryParams.s_scan.description",
203078
203054
  columns: 1,
203079
203055
  fields: [
@@ -203124,8 +203100,6 @@ function buildCreationFormSchema() {
203124
203100
  id: "credentials",
203125
203101
  title: "Credentials",
203126
203102
  titleKey: "provider-reolink:creation.s_credentials.title",
203127
- description: "Required for the autodetect probe — entered before the host so Test can run immediately.",
203128
- descriptionKey: "provider-reolink:creation.s_credentials.description",
203129
203103
  columns: 2,
203130
203104
  fields: [{
203131
203105
  type: "text",
@@ -203147,8 +203121,6 @@ function buildCreationFormSchema() {
203147
203121
  id: "connection",
203148
203122
  title: "Connection",
203149
203123
  titleKey: "provider-reolink:creation.s_connection.title",
203150
- description: "Click Test to auto-detect the device type (regular camera / NVR / battery / UDP-only). The detected type is then used at save time.",
203151
- descriptionKey: "provider-reolink:creation.s_connection.description",
203152
203124
  columns: 2,
203153
203125
  fields: [
203154
203126
  {
@@ -203157,7 +203129,7 @@ function buildCreationFormSchema() {
203157
203129
  label: "Connection mode",
203158
203130
  labelKey: "provider-reolink:creation.s_connection.transport.label",
203159
203131
  default: "auto",
203160
- description: "Auto: try TCP first, fall back to UDP — best for unknown devices. UDP is required for battery cameras behind NAT.",
203132
+ description: "Auto tries TCP, then UDP. Battery cameras behind NAT need UDP.",
203161
203133
  descriptionKey: "provider-reolink:creation.s_connection.transport.description",
203162
203134
  options: [
203163
203135
  {
@@ -203184,7 +203156,7 @@ function buildCreationFormSchema() {
203184
203156
  labelKey: "provider-reolink:creation.s_connection.host.label",
203185
203157
  required: true,
203186
203158
  placeholder: "192.168.10.100",
203187
- 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.",
203159
+ description: "In UDP-only mode leave blank and use the UID below.",
203188
203160
  descriptionKey: "provider-reolink:creation.s_connection.host.description",
203189
203161
  inputType: "text"
203190
203162
  },
@@ -203197,8 +203169,6 @@ function buildCreationFormSchema() {
203197
203169
  min: 1,
203198
203170
  max: 65535,
203199
203171
  step: 1,
203200
- description: "Baichuan port. Default 9000 — applies to TCP. Ignored for UDP transport.",
203201
- descriptionKey: "provider-reolink:creation.s_connection.port.description",
203202
203172
  showWhen: {
203203
203173
  field: "transport",
203204
203174
  notEquals: "udp"
@@ -203210,7 +203180,7 @@ function buildCreationFormSchema() {
203210
203180
  label: "Device UID",
203211
203181
  labelKey: "provider-reolink:creation.s_connection.uid.label",
203212
203182
  placeholder: "9527000XXXXXXXX",
203213
- description: "Required for battery / UDP cameras when not on the same LAN. Optional for local-direct UDP discovery and ignored for pure TCP.",
203183
+ description: "Needed for battery / UDP cameras that are not on the same LAN.",
203214
203184
  descriptionKey: "provider-reolink:creation.s_connection.uid.description",
203215
203185
  showWhen: {
203216
203186
  field: "transport",
@@ -203751,7 +203721,7 @@ function buildEmailPushSettingsSchema(recommendedHost) {
203751
203721
  id: "email-push",
203752
203722
  title: "Battery-cam Motion (Email/SMTP Push)",
203753
203723
  titleKey: "provider-reolink:emailPushSettings.s_email-push.title",
203754
- 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.",
203724
+ description: "Lets battery cameras report motion by email without being woken.",
203755
203725
  descriptionKey: "provider-reolink:emailPushSettings.s_email-push.description",
203756
203726
  columns: 2,
203757
203727
  fields: [
@@ -203791,7 +203761,7 @@ function buildEmailPushSettingsSchema(recommendedHost) {
203791
203761
  id: "email-push-auth",
203792
203762
  title: "Email Push Authentication",
203793
203763
  titleKey: "provider-reolink:emailPushSettings.s_email-push-auth.title",
203794
- 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.",
203764
+ description: "Random values are generated on first boot; re-run Auto-configure on cameras after changing them.",
203795
203765
  descriptionKey: "provider-reolink:emailPushSettings.s_email-push-auth.description",
203796
203766
  columns: 2,
203797
203767
  fields: [
@@ -204000,7 +203970,7 @@ function buildBaichuanWebhookSettingsSchema(recommendedHost) {
204000
203970
  id: "baichuan-webhook",
204001
203971
  title: "Battery-cam Motion (HaCfg Webhook)",
204002
203972
  titleKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.title",
204003
- 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).",
203973
+ description: "Preferred over email push when the camera firmware supports it.",
204004
203974
  descriptionKey: "provider-reolink:baichuanWebhookSettings.s_baichuan-webhook.description",
204005
203975
  columns: 2,
204006
203976
  fields: [