@camstack/addon-provider-dreo 0.1.11 → 0.1.13

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
@@ -4664,7 +4664,7 @@ function _instanceof(cls, params = {}) {
4664
4664
  return inst;
4665
4665
  }
4666
4666
  //#endregion
4667
- //#region ../types/dist/sleep-BiDFW0E7.mjs
4667
+ //#region ../types/dist/sleep-CZDdRBua.mjs
4668
4668
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4669
4669
  EventCategory["SystemBoot"] = "system.boot";
4670
4670
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -7275,7 +7275,16 @@ var DecoderStatsSchema = object({
7275
7275
  inputFps: number(),
7276
7276
  outputFps: number(),
7277
7277
  avgDecodeTimeMs: number(),
7278
- droppedFrames: number()
7278
+ droppedFrames: number(),
7279
+ /**
7280
+ * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
7281
+ * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
7282
+ * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
7283
+ * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
7284
+ */
7285
+ lagMs: number().optional(),
7286
+ effectiveFps: number().optional(),
7287
+ adaptiveFps: number().optional()
7279
7288
  });
7280
7289
  var DecoderSessionConfigSchema = object({
7281
7290
  codec: string(),
@@ -7316,7 +7325,15 @@ var DecoderSessionConfigSchema = object({
7316
7325
  * other — `pullFrames` returns nothing for an `'shm'` session and
7317
7326
  * `pullHandles` returns nothing for a `'callback'` session.
7318
7327
  */
7319
- frameSink: _enum(["callback", "shm"]).default("callback")
7328
+ frameSink: _enum(["callback", "shm"]).default("callback"),
7329
+ /**
7330
+ * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
7331
+ * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
7332
+ * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
7333
+ * stream-broker's `streamingDebug` gate — off by default so production logs
7334
+ * stay quiet and the emit path pays zero per-frame cost when disabled.
7335
+ */
7336
+ debug: boolean().optional()
7320
7337
  });
7321
7338
  var EncodeProfileSchema = object({
7322
7339
  video: object({
@@ -10341,6 +10358,100 @@ var coverCapability = {
10341
10358
  runtimeState: CoverStatusSchema
10342
10359
  };
10343
10360
  /**
10361
+ * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
10362
+ * shared by reolink / hikvision / amcrest. Models the common firmware
10363
+ * surface: the IR-cut switching MODE plus the two knobs that gate it
10364
+ * (photocell `sensitivity` + `switchDelaySec`). Each vendor maps these
10365
+ * onto its own ISAPI / Baichuan / Dahua-CGI fields; the cap standardises
10366
+ * the shape so ONE derived-form renders every camera.
10367
+ *
10368
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
10369
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
10370
+ * injected from `status`) reports the live values, and a single
10371
+ * `setSettings` mutation applies a partial change. No hand-written
10372
+ * settings-contribution methods — the framework derives the UI + save
10373
+ * routing from this surface.
10374
+ */
10375
+ /** IR-cut switching mode. `schedule` = time-of-day table configured on the camera. */
10376
+ var DayNightModeSchema = _enum([
10377
+ "auto",
10378
+ "day",
10379
+ "night",
10380
+ "schedule"
10381
+ ]);
10382
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
10383
+ * getOptions availability convention. Normalized values are 0–100. */
10384
+ var NormalizedRangeSchema$1 = object({
10385
+ min: number(),
10386
+ max: number(),
10387
+ step: number()
10388
+ });
10389
+ /**
10390
+ * Current day/night state. Optional fields are absent when the camera
10391
+ * does not expose that knob (a photocell-less model reports no
10392
+ * `sensitivity`). `lastFetchedAt` feeds the runtime-state bridge.
10393
+ */
10394
+ var DayNightStatusSchema = object({
10395
+ mode: DayNightModeSchema,
10396
+ /** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
10397
+ sensitivity: number().optional(),
10398
+ /** Delay before the IR-cut filter flips, in seconds. */
10399
+ switchDelaySec: number().optional(),
10400
+ lastFetchedAt: number()
10401
+ });
10402
+ /**
10403
+ * Per-camera availability descriptor — drives which controls the admin UI
10404
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
10405
+ * (normalized 0–100); the mode choice-set as an array. A provider returns
10406
+ * honest, camera-probed values — never hardcoded.
10407
+ */
10408
+ var DayNightOptionsSchema = object({
10409
+ /** Modes this camera accepts. Empty → the camera has no configurable day/night mode. */
10410
+ modes: array(DayNightModeSchema),
10411
+ supportsSensitivity: boolean(),
10412
+ /** Present when `supportsSensitivity` — the normalized 0–100 range. */
10413
+ sensitivity: NormalizedRangeSchema$1.optional(),
10414
+ supportsSwitchDelay: boolean(),
10415
+ /** Present when `supportsSwitchDelay` — the allowed delay range in seconds. */
10416
+ switchDelaySec: NormalizedRangeSchema$1.optional()
10417
+ });
10418
+ /**
10419
+ * Partial change to the day/night config — every field optional. A
10420
+ * provider ignores fields it does not support.
10421
+ */
10422
+ var DayNightSettingsPatchSchema = object({
10423
+ mode: DayNightModeSchema.optional(),
10424
+ sensitivity: number().optional(),
10425
+ switchDelaySec: number().optional()
10426
+ });
10427
+ var dayNightCapability = {
10428
+ name: "day-night",
10429
+ scope: "device",
10430
+ deviceNative: true,
10431
+ mode: "singleton",
10432
+ deviceTypes: [DeviceType.Camera],
10433
+ deviceConfig: { ui: {
10434
+ kind: "derived-form",
10435
+ builderId: "day-night",
10436
+ tab: "image"
10437
+ } },
10438
+ methods: {
10439
+ getOptions: method(object({ deviceId: number() }), DayNightOptionsSchema),
10440
+ setSettings: method(object({
10441
+ deviceId: number(),
10442
+ settings: DayNightSettingsPatchSchema
10443
+ }), _void(), {
10444
+ kind: "mutation",
10445
+ auth: "admin"
10446
+ })
10447
+ },
10448
+ status: {
10449
+ schema: DayNightStatusSchema,
10450
+ kind: "poll"
10451
+ },
10452
+ runtimeState: DayNightStatusSchema
10453
+ };
10454
+ /**
10344
10455
  * Identity envelope for a device's upstream-system metadata.
10345
10456
  *
10346
10457
  * Two jobs:
@@ -10999,6 +11110,155 @@ var imageCapability = {
10999
11110
  runtimeState: ImageStatusSchema
11000
11111
  };
11001
11112
  /**
11113
+ * Vendor-neutral image / picture-adjustment cap — the per-camera config
11114
+ * cap shared by reolink / hikvision / amcrest. Models the common ISP
11115
+ * surface: the four picture sliders (brightness / contrast / saturation /
11116
+ * sharpness), orientation (mirror / flip / rotate), white-balance,
11117
+ * exposure and backlight-compensation modes.
11118
+ *
11119
+ * NORMALIZATION: every slider is a normalized int 0–100. Vendors expose
11120
+ * these natively as 0–100 or 0–255 (or other ranges); each provider maps
11121
+ * its native range to/from this normalized 0–100 space so the cap surface
11122
+ * (and the derived form) is identical across cameras. `warmth` (manual
11123
+ * white-balance) is likewise normalized 0–100.
11124
+ *
11125
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
11126
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
11127
+ * injected from `status`) reports the live values, and a single
11128
+ * `setSettings` mutation applies a partial change. No hand-written
11129
+ * settings-contribution methods — the framework derives the UI + save
11130
+ * routing from this surface.
11131
+ */
11132
+ /** Sensor/image rotation, degrees clockwise. */
11133
+ var ImageRotateSchema = _enum([
11134
+ "0",
11135
+ "90",
11136
+ "180",
11137
+ "270"
11138
+ ]);
11139
+ /** White-balance mode. `manual` unlocks the normalized `warmth` knob. */
11140
+ var WhiteBalanceModeSchema = _enum(["auto", "manual"]);
11141
+ /** Exposure mode. */
11142
+ var ExposureModeSchema = _enum(["auto", "manual"]);
11143
+ /**
11144
+ * Backlight-compensation mode:
11145
+ * - `off` — disabled
11146
+ * - `blc` — backlight compensation
11147
+ * - `wdr` — wide dynamic range
11148
+ * - `hlc` — highlight compensation
11149
+ */
11150
+ var BacklightModeSchema = _enum([
11151
+ "off",
11152
+ "blc",
11153
+ "wdr",
11154
+ "hlc"
11155
+ ]);
11156
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
11157
+ * getOptions availability convention. Slider values are normalized 0–100. */
11158
+ var NormalizedRangeSchema = object({
11159
+ min: number(),
11160
+ max: number(),
11161
+ step: number()
11162
+ });
11163
+ /**
11164
+ * Current image-adjustment state. Every field optional — absent when the
11165
+ * camera does not expose that control. Slider values are NORMALIZED 0–100.
11166
+ * `lastFetchedAt` feeds the runtime-state bridge.
11167
+ */
11168
+ var ImageSettingsStatusSchema = object({
11169
+ /** Normalized 0–100. */
11170
+ brightness: number().optional(),
11171
+ /** Normalized 0–100. */
11172
+ contrast: number().optional(),
11173
+ /** Normalized 0–100. */
11174
+ saturation: number().optional(),
11175
+ /** Normalized 0–100. */
11176
+ sharpness: number().optional(),
11177
+ mirror: boolean().optional(),
11178
+ flip: boolean().optional(),
11179
+ rotate: ImageRotateSchema.optional(),
11180
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11181
+ /** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
11182
+ warmth: number().optional(),
11183
+ exposureMode: ExposureModeSchema.optional(),
11184
+ backlightMode: BacklightModeSchema.optional(),
11185
+ lastFetchedAt: number()
11186
+ });
11187
+ /**
11188
+ * Per-camera availability descriptor — drives which controls the admin UI
11189
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
11190
+ * (the normalized 0–100 range); enums as arrays of supported values (empty
11191
+ * array → control hidden). A provider returns honest, camera-probed values
11192
+ * — never hardcoded.
11193
+ */
11194
+ var ImageSettingsOptionsSchema = object({
11195
+ supportsBrightness: boolean(),
11196
+ brightness: NormalizedRangeSchema.optional(),
11197
+ supportsContrast: boolean(),
11198
+ contrast: NormalizedRangeSchema.optional(),
11199
+ supportsSaturation: boolean(),
11200
+ saturation: NormalizedRangeSchema.optional(),
11201
+ supportsSharpness: boolean(),
11202
+ sharpness: NormalizedRangeSchema.optional(),
11203
+ supportsMirror: boolean(),
11204
+ supportsFlip: boolean(),
11205
+ /** Supported rotation values. Empty → rotation not configurable. */
11206
+ rotateOptions: array(ImageRotateSchema),
11207
+ /** Supported white-balance modes. Empty → white-balance not configurable. */
11208
+ whiteBalanceModes: array(WhiteBalanceModeSchema),
11209
+ supportsWarmth: boolean(),
11210
+ /** Present when `supportsWarmth` — the normalized 0–100 range. */
11211
+ warmth: NormalizedRangeSchema.optional(),
11212
+ /** Supported exposure modes. Empty → exposure not configurable. */
11213
+ exposureModes: array(ExposureModeSchema),
11214
+ /** Supported backlight modes. Empty → backlight-compensation not configurable. */
11215
+ backlightModes: array(BacklightModeSchema)
11216
+ });
11217
+ /**
11218
+ * Partial change to the image config — every field optional. Slider values
11219
+ * are normalized 0–100. A provider ignores fields it does not support.
11220
+ */
11221
+ var ImageSettingsPatchSchema = object({
11222
+ brightness: number().optional(),
11223
+ contrast: number().optional(),
11224
+ saturation: number().optional(),
11225
+ sharpness: number().optional(),
11226
+ mirror: boolean().optional(),
11227
+ flip: boolean().optional(),
11228
+ rotate: ImageRotateSchema.optional(),
11229
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11230
+ warmth: number().optional(),
11231
+ exposureMode: ExposureModeSchema.optional(),
11232
+ backlightMode: BacklightModeSchema.optional()
11233
+ });
11234
+ var imageSettingsCapability = {
11235
+ name: "image-settings",
11236
+ scope: "device",
11237
+ deviceNative: true,
11238
+ mode: "singleton",
11239
+ deviceTypes: [DeviceType.Camera],
11240
+ deviceConfig: { ui: {
11241
+ kind: "derived-form",
11242
+ builderId: "image-settings",
11243
+ tab: "image"
11244
+ } },
11245
+ methods: {
11246
+ getOptions: method(object({ deviceId: number() }), ImageSettingsOptionsSchema),
11247
+ setSettings: method(object({
11248
+ deviceId: number(),
11249
+ settings: ImageSettingsPatchSchema
11250
+ }), _void(), {
11251
+ kind: "mutation",
11252
+ auth: "admin"
11253
+ })
11254
+ },
11255
+ status: {
11256
+ schema: ImageSettingsStatusSchema,
11257
+ kind: "poll"
11258
+ },
11259
+ runtimeState: ImageSettingsStatusSchema
11260
+ };
11261
+ /**
11002
11262
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
11003
11263
  * with a mowing lifecycle plus a dock action.
11004
11264
  *
@@ -11997,6 +12257,16 @@ var RunnerCameraConfigSchema = object({
11997
12257
  * this gate is bypassed.
11998
12258
  */
11999
12259
  onboardMotionDrivesAnalyzer: boolean().default(true),
12260
+ /**
12261
+ * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
12262
+ * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
12263
+ * this is off by default because the recheck re-subscribes a detection session
12264
+ * every N seconds while `watching`, a major source of pull-decoder re-dial
12265
+ * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
12266
+ * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
12267
+ * (and only render) when this is enabled.
12268
+ */
12269
+ occupancyRecheckEnabled: boolean().default(false),
12000
12270
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
12001
12271
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
12002
12272
  /**
@@ -14002,6 +14272,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14002
14272
  contact: contactCapability,
14003
14273
  control: controlCapability,
14004
14274
  cover: coverCapability,
14275
+ dayNight: dayNightCapability,
14005
14276
  deviceDiscovery: deviceDiscoveryCapability,
14006
14277
  deviceStatus: deviceStatusCapability,
14007
14278
  doorbell: doorbellCapability,
@@ -14014,6 +14285,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14014
14285
  humidifier: humidifierCapability,
14015
14286
  humiditySensor: humiditySensorCapability,
14016
14287
  image: imageCapability,
14288
+ imageSettings: imageSettingsCapability,
14017
14289
  lawnMowerControl: lawnMowerControlCapability,
14018
14290
  lockControl: lockControlCapability,
14019
14291
  mediaPlayer: mediaPlayerCapability,
@@ -15928,7 +16200,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
15928
16200
  id: string(),
15929
16201
  name: string(),
15930
16202
  isPullMode: boolean().optional(),
15931
- priority: number().optional()
16203
+ priority: number().optional(),
16204
+ hwaccel: string().optional(),
16205
+ probedBestHwaccel: string().optional()
15932
16206
  })), method(DecoderSessionConfigSchema, object({
15933
16207
  sessionId: string(),
15934
16208
  nodeId: string()
@@ -17859,7 +18133,17 @@ var AgentAddonConfigSchema = object({
17859
18133
  });
17860
18134
  var AgentPipelineSettingsSchema = object({
17861
18135
  addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
17862
- maxCameras: number().int().nonnegative().nullable().default(null)
18136
+ maxCameras: number().int().nonnegative().nullable().default(null),
18137
+ /** Per-node detection weight (relative share for the quota balancer). */
18138
+ detectWeight: number().positive().optional(),
18139
+ /** Node is eligible to run the detection pipeline (decode + inference). */
18140
+ detect: boolean().optional(),
18141
+ /** Node is eligible to host decoder sessions. */
18142
+ decode: boolean().optional(),
18143
+ /** Node is eligible to run audio-analyzer sessions. */
18144
+ audio: boolean().optional(),
18145
+ /** Node is eligible to be the ingest / source-owner (serve the restream). */
18146
+ ingest: boolean().optional()
17863
18147
  });
17864
18148
  var CameraPipelineForAgentSchema = object({
17865
18149
  steps: array(PipelineStepInputSchema).readonly(),
@@ -18165,6 +18449,21 @@ method(object({
18165
18449
  }), object({ success: literal(true) }), {
18166
18450
  kind: "mutation",
18167
18451
  auth: "admin"
18452
+ }), method(object({
18453
+ agentNodeId: string(),
18454
+ detectWeight: number().positive().nullable()
18455
+ }), object({ success: literal(true) }), {
18456
+ kind: "mutation",
18457
+ auth: "admin"
18458
+ }), method(object({
18459
+ agentNodeId: string(),
18460
+ detect: boolean().nullable().optional(),
18461
+ decode: boolean().nullable().optional(),
18462
+ audio: boolean().nullable().optional(),
18463
+ ingest: boolean().nullable().optional()
18464
+ }), object({ success: literal(true) }), {
18465
+ kind: "mutation",
18466
+ auth: "admin"
18168
18467
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
18169
18468
  deviceId: number(),
18170
18469
  addonId: string(),
@@ -21912,6 +22211,18 @@ Object.freeze({
21912
22211
  addonId: null,
21913
22212
  access: "view"
21914
22213
  },
22214
+ "dayNight.getOptions": {
22215
+ capName: "day-night",
22216
+ capScope: "device",
22217
+ addonId: null,
22218
+ access: "view"
22219
+ },
22220
+ "dayNight.setSettings": {
22221
+ capName: "day-night",
22222
+ capScope: "device",
22223
+ addonId: null,
22224
+ access: "create"
22225
+ },
21915
22226
  "decoder.createSession": {
21916
22227
  capName: "decoder",
21917
22228
  capScope: "system",
@@ -22842,6 +23153,18 @@ Object.freeze({
22842
23153
  addonId: null,
22843
23154
  access: "create"
22844
23155
  },
23156
+ "imageSettings.getOptions": {
23157
+ capName: "image-settings",
23158
+ capScope: "device",
23159
+ addonId: null,
23160
+ access: "view"
23161
+ },
23162
+ "imageSettings.setSettings": {
23163
+ capName: "image-settings",
23164
+ capScope: "device",
23165
+ addonId: null,
23166
+ access: "create"
23167
+ },
22845
23168
  "integrations.create": {
22846
23169
  capName: "integrations",
22847
23170
  capScope: "system",
@@ -24024,6 +24347,18 @@ Object.freeze({
24024
24347
  addonId: null,
24025
24348
  access: "create"
24026
24349
  },
24350
+ "pipelineOrchestrator.setAgentCapabilities": {
24351
+ capName: "pipeline-orchestrator",
24352
+ capScope: "system",
24353
+ addonId: null,
24354
+ access: "create"
24355
+ },
24356
+ "pipelineOrchestrator.setAgentDetectWeight": {
24357
+ capName: "pipeline-orchestrator",
24358
+ capScope: "system",
24359
+ addonId: null,
24360
+ access: "create"
24361
+ },
24027
24362
  "pipelineOrchestrator.setAgentMaxCameras": {
24028
24363
  capName: "pipeline-orchestrator",
24029
24364
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -4665,7 +4665,7 @@ function _instanceof(cls, params = {}) {
4665
4665
  return inst;
4666
4666
  }
4667
4667
  //#endregion
4668
- //#region ../types/dist/sleep-BiDFW0E7.mjs
4668
+ //#region ../types/dist/sleep-CZDdRBua.mjs
4669
4669
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4670
4670
  EventCategory["SystemBoot"] = "system.boot";
4671
4671
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -7276,7 +7276,16 @@ var DecoderStatsSchema = object({
7276
7276
  inputFps: number(),
7277
7277
  outputFps: number(),
7278
7278
  avgDecodeTimeMs: number(),
7279
- droppedFrames: number()
7279
+ droppedFrames: number(),
7280
+ /**
7281
+ * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
7282
+ * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
7283
+ * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
7284
+ * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
7285
+ */
7286
+ lagMs: number().optional(),
7287
+ effectiveFps: number().optional(),
7288
+ adaptiveFps: number().optional()
7280
7289
  });
7281
7290
  var DecoderSessionConfigSchema = object({
7282
7291
  codec: string(),
@@ -7317,7 +7326,15 @@ var DecoderSessionConfigSchema = object({
7317
7326
  * other — `pullFrames` returns nothing for an `'shm'` session and
7318
7327
  * `pullHandles` returns nothing for a `'callback'` session.
7319
7328
  */
7320
- frameSink: _enum(["callback", "shm"]).default("callback")
7329
+ frameSink: _enum(["callback", "shm"]).default("callback"),
7330
+ /**
7331
+ * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
7332
+ * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
7333
+ * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
7334
+ * stream-broker's `streamingDebug` gate — off by default so production logs
7335
+ * stay quiet and the emit path pays zero per-frame cost when disabled.
7336
+ */
7337
+ debug: boolean().optional()
7321
7338
  });
7322
7339
  var EncodeProfileSchema = object({
7323
7340
  video: object({
@@ -10342,6 +10359,100 @@ var coverCapability = {
10342
10359
  runtimeState: CoverStatusSchema
10343
10360
  };
10344
10361
  /**
10362
+ * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
10363
+ * shared by reolink / hikvision / amcrest. Models the common firmware
10364
+ * surface: the IR-cut switching MODE plus the two knobs that gate it
10365
+ * (photocell `sensitivity` + `switchDelaySec`). Each vendor maps these
10366
+ * onto its own ISAPI / Baichuan / Dahua-CGI fields; the cap standardises
10367
+ * the shape so ONE derived-form renders every camera.
10368
+ *
10369
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
10370
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
10371
+ * injected from `status`) reports the live values, and a single
10372
+ * `setSettings` mutation applies a partial change. No hand-written
10373
+ * settings-contribution methods — the framework derives the UI + save
10374
+ * routing from this surface.
10375
+ */
10376
+ /** IR-cut switching mode. `schedule` = time-of-day table configured on the camera. */
10377
+ var DayNightModeSchema = _enum([
10378
+ "auto",
10379
+ "day",
10380
+ "night",
10381
+ "schedule"
10382
+ ]);
10383
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
10384
+ * getOptions availability convention. Normalized values are 0–100. */
10385
+ var NormalizedRangeSchema$1 = object({
10386
+ min: number(),
10387
+ max: number(),
10388
+ step: number()
10389
+ });
10390
+ /**
10391
+ * Current day/night state. Optional fields are absent when the camera
10392
+ * does not expose that knob (a photocell-less model reports no
10393
+ * `sensitivity`). `lastFetchedAt` feeds the runtime-state bridge.
10394
+ */
10395
+ var DayNightStatusSchema = object({
10396
+ mode: DayNightModeSchema,
10397
+ /** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
10398
+ sensitivity: number().optional(),
10399
+ /** Delay before the IR-cut filter flips, in seconds. */
10400
+ switchDelaySec: number().optional(),
10401
+ lastFetchedAt: number()
10402
+ });
10403
+ /**
10404
+ * Per-camera availability descriptor — drives which controls the admin UI
10405
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
10406
+ * (normalized 0–100); the mode choice-set as an array. A provider returns
10407
+ * honest, camera-probed values — never hardcoded.
10408
+ */
10409
+ var DayNightOptionsSchema = object({
10410
+ /** Modes this camera accepts. Empty → the camera has no configurable day/night mode. */
10411
+ modes: array(DayNightModeSchema),
10412
+ supportsSensitivity: boolean(),
10413
+ /** Present when `supportsSensitivity` — the normalized 0–100 range. */
10414
+ sensitivity: NormalizedRangeSchema$1.optional(),
10415
+ supportsSwitchDelay: boolean(),
10416
+ /** Present when `supportsSwitchDelay` — the allowed delay range in seconds. */
10417
+ switchDelaySec: NormalizedRangeSchema$1.optional()
10418
+ });
10419
+ /**
10420
+ * Partial change to the day/night config — every field optional. A
10421
+ * provider ignores fields it does not support.
10422
+ */
10423
+ var DayNightSettingsPatchSchema = object({
10424
+ mode: DayNightModeSchema.optional(),
10425
+ sensitivity: number().optional(),
10426
+ switchDelaySec: number().optional()
10427
+ });
10428
+ var dayNightCapability = {
10429
+ name: "day-night",
10430
+ scope: "device",
10431
+ deviceNative: true,
10432
+ mode: "singleton",
10433
+ deviceTypes: [DeviceType.Camera],
10434
+ deviceConfig: { ui: {
10435
+ kind: "derived-form",
10436
+ builderId: "day-night",
10437
+ tab: "image"
10438
+ } },
10439
+ methods: {
10440
+ getOptions: method(object({ deviceId: number() }), DayNightOptionsSchema),
10441
+ setSettings: method(object({
10442
+ deviceId: number(),
10443
+ settings: DayNightSettingsPatchSchema
10444
+ }), _void(), {
10445
+ kind: "mutation",
10446
+ auth: "admin"
10447
+ })
10448
+ },
10449
+ status: {
10450
+ schema: DayNightStatusSchema,
10451
+ kind: "poll"
10452
+ },
10453
+ runtimeState: DayNightStatusSchema
10454
+ };
10455
+ /**
10345
10456
  * Identity envelope for a device's upstream-system metadata.
10346
10457
  *
10347
10458
  * Two jobs:
@@ -11000,6 +11111,155 @@ var imageCapability = {
11000
11111
  runtimeState: ImageStatusSchema
11001
11112
  };
11002
11113
  /**
11114
+ * Vendor-neutral image / picture-adjustment cap — the per-camera config
11115
+ * cap shared by reolink / hikvision / amcrest. Models the common ISP
11116
+ * surface: the four picture sliders (brightness / contrast / saturation /
11117
+ * sharpness), orientation (mirror / flip / rotate), white-balance,
11118
+ * exposure and backlight-compensation modes.
11119
+ *
11120
+ * NORMALIZATION: every slider is a normalized int 0–100. Vendors expose
11121
+ * these natively as 0–100 or 0–255 (or other ranges); each provider maps
11122
+ * its native range to/from this normalized 0–100 space so the cap surface
11123
+ * (and the derived form) is identical across cameras. `warmth` (manual
11124
+ * white-balance) is likewise normalized 0–100.
11125
+ *
11126
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
11127
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
11128
+ * injected from `status`) reports the live values, and a single
11129
+ * `setSettings` mutation applies a partial change. No hand-written
11130
+ * settings-contribution methods — the framework derives the UI + save
11131
+ * routing from this surface.
11132
+ */
11133
+ /** Sensor/image rotation, degrees clockwise. */
11134
+ var ImageRotateSchema = _enum([
11135
+ "0",
11136
+ "90",
11137
+ "180",
11138
+ "270"
11139
+ ]);
11140
+ /** White-balance mode. `manual` unlocks the normalized `warmth` knob. */
11141
+ var WhiteBalanceModeSchema = _enum(["auto", "manual"]);
11142
+ /** Exposure mode. */
11143
+ var ExposureModeSchema = _enum(["auto", "manual"]);
11144
+ /**
11145
+ * Backlight-compensation mode:
11146
+ * - `off` — disabled
11147
+ * - `blc` — backlight compensation
11148
+ * - `wdr` — wide dynamic range
11149
+ * - `hlc` — highlight compensation
11150
+ */
11151
+ var BacklightModeSchema = _enum([
11152
+ "off",
11153
+ "blc",
11154
+ "wdr",
11155
+ "hlc"
11156
+ ]);
11157
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
11158
+ * getOptions availability convention. Slider values are normalized 0–100. */
11159
+ var NormalizedRangeSchema = object({
11160
+ min: number(),
11161
+ max: number(),
11162
+ step: number()
11163
+ });
11164
+ /**
11165
+ * Current image-adjustment state. Every field optional — absent when the
11166
+ * camera does not expose that control. Slider values are NORMALIZED 0–100.
11167
+ * `lastFetchedAt` feeds the runtime-state bridge.
11168
+ */
11169
+ var ImageSettingsStatusSchema = object({
11170
+ /** Normalized 0–100. */
11171
+ brightness: number().optional(),
11172
+ /** Normalized 0–100. */
11173
+ contrast: number().optional(),
11174
+ /** Normalized 0–100. */
11175
+ saturation: number().optional(),
11176
+ /** Normalized 0–100. */
11177
+ sharpness: number().optional(),
11178
+ mirror: boolean().optional(),
11179
+ flip: boolean().optional(),
11180
+ rotate: ImageRotateSchema.optional(),
11181
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11182
+ /** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
11183
+ warmth: number().optional(),
11184
+ exposureMode: ExposureModeSchema.optional(),
11185
+ backlightMode: BacklightModeSchema.optional(),
11186
+ lastFetchedAt: number()
11187
+ });
11188
+ /**
11189
+ * Per-camera availability descriptor — drives which controls the admin UI
11190
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
11191
+ * (the normalized 0–100 range); enums as arrays of supported values (empty
11192
+ * array → control hidden). A provider returns honest, camera-probed values
11193
+ * — never hardcoded.
11194
+ */
11195
+ var ImageSettingsOptionsSchema = object({
11196
+ supportsBrightness: boolean(),
11197
+ brightness: NormalizedRangeSchema.optional(),
11198
+ supportsContrast: boolean(),
11199
+ contrast: NormalizedRangeSchema.optional(),
11200
+ supportsSaturation: boolean(),
11201
+ saturation: NormalizedRangeSchema.optional(),
11202
+ supportsSharpness: boolean(),
11203
+ sharpness: NormalizedRangeSchema.optional(),
11204
+ supportsMirror: boolean(),
11205
+ supportsFlip: boolean(),
11206
+ /** Supported rotation values. Empty → rotation not configurable. */
11207
+ rotateOptions: array(ImageRotateSchema),
11208
+ /** Supported white-balance modes. Empty → white-balance not configurable. */
11209
+ whiteBalanceModes: array(WhiteBalanceModeSchema),
11210
+ supportsWarmth: boolean(),
11211
+ /** Present when `supportsWarmth` — the normalized 0–100 range. */
11212
+ warmth: NormalizedRangeSchema.optional(),
11213
+ /** Supported exposure modes. Empty → exposure not configurable. */
11214
+ exposureModes: array(ExposureModeSchema),
11215
+ /** Supported backlight modes. Empty → backlight-compensation not configurable. */
11216
+ backlightModes: array(BacklightModeSchema)
11217
+ });
11218
+ /**
11219
+ * Partial change to the image config — every field optional. Slider values
11220
+ * are normalized 0–100. A provider ignores fields it does not support.
11221
+ */
11222
+ var ImageSettingsPatchSchema = object({
11223
+ brightness: number().optional(),
11224
+ contrast: number().optional(),
11225
+ saturation: number().optional(),
11226
+ sharpness: number().optional(),
11227
+ mirror: boolean().optional(),
11228
+ flip: boolean().optional(),
11229
+ rotate: ImageRotateSchema.optional(),
11230
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11231
+ warmth: number().optional(),
11232
+ exposureMode: ExposureModeSchema.optional(),
11233
+ backlightMode: BacklightModeSchema.optional()
11234
+ });
11235
+ var imageSettingsCapability = {
11236
+ name: "image-settings",
11237
+ scope: "device",
11238
+ deviceNative: true,
11239
+ mode: "singleton",
11240
+ deviceTypes: [DeviceType.Camera],
11241
+ deviceConfig: { ui: {
11242
+ kind: "derived-form",
11243
+ builderId: "image-settings",
11244
+ tab: "image"
11245
+ } },
11246
+ methods: {
11247
+ getOptions: method(object({ deviceId: number() }), ImageSettingsOptionsSchema),
11248
+ setSettings: method(object({
11249
+ deviceId: number(),
11250
+ settings: ImageSettingsPatchSchema
11251
+ }), _void(), {
11252
+ kind: "mutation",
11253
+ auth: "admin"
11254
+ })
11255
+ },
11256
+ status: {
11257
+ schema: ImageSettingsStatusSchema,
11258
+ kind: "poll"
11259
+ },
11260
+ runtimeState: ImageSettingsStatusSchema
11261
+ };
11262
+ /**
11003
11263
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
11004
11264
  * with a mowing lifecycle plus a dock action.
11005
11265
  *
@@ -11998,6 +12258,16 @@ var RunnerCameraConfigSchema = object({
11998
12258
  * this gate is bypassed.
11999
12259
  */
12000
12260
  onboardMotionDrivesAnalyzer: boolean().default(true),
12261
+ /**
12262
+ * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
12263
+ * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
12264
+ * this is off by default because the recheck re-subscribes a detection session
12265
+ * every N seconds while `watching`, a major source of pull-decoder re-dial
12266
+ * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
12267
+ * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
12268
+ * (and only render) when this is enabled.
12269
+ */
12270
+ occupancyRecheckEnabled: boolean().default(false),
12001
12271
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
12002
12272
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
12003
12273
  /**
@@ -14003,6 +14273,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14003
14273
  contact: contactCapability,
14004
14274
  control: controlCapability,
14005
14275
  cover: coverCapability,
14276
+ dayNight: dayNightCapability,
14006
14277
  deviceDiscovery: deviceDiscoveryCapability,
14007
14278
  deviceStatus: deviceStatusCapability,
14008
14279
  doorbell: doorbellCapability,
@@ -14015,6 +14286,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14015
14286
  humidifier: humidifierCapability,
14016
14287
  humiditySensor: humiditySensorCapability,
14017
14288
  image: imageCapability,
14289
+ imageSettings: imageSettingsCapability,
14018
14290
  lawnMowerControl: lawnMowerControlCapability,
14019
14291
  lockControl: lockControlCapability,
14020
14292
  mediaPlayer: mediaPlayerCapability,
@@ -15929,7 +16201,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
15929
16201
  id: string(),
15930
16202
  name: string(),
15931
16203
  isPullMode: boolean().optional(),
15932
- priority: number().optional()
16204
+ priority: number().optional(),
16205
+ hwaccel: string().optional(),
16206
+ probedBestHwaccel: string().optional()
15933
16207
  })), method(DecoderSessionConfigSchema, object({
15934
16208
  sessionId: string(),
15935
16209
  nodeId: string()
@@ -17860,7 +18134,17 @@ var AgentAddonConfigSchema = object({
17860
18134
  });
17861
18135
  var AgentPipelineSettingsSchema = object({
17862
18136
  addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
17863
- maxCameras: number().int().nonnegative().nullable().default(null)
18137
+ maxCameras: number().int().nonnegative().nullable().default(null),
18138
+ /** Per-node detection weight (relative share for the quota balancer). */
18139
+ detectWeight: number().positive().optional(),
18140
+ /** Node is eligible to run the detection pipeline (decode + inference). */
18141
+ detect: boolean().optional(),
18142
+ /** Node is eligible to host decoder sessions. */
18143
+ decode: boolean().optional(),
18144
+ /** Node is eligible to run audio-analyzer sessions. */
18145
+ audio: boolean().optional(),
18146
+ /** Node is eligible to be the ingest / source-owner (serve the restream). */
18147
+ ingest: boolean().optional()
17864
18148
  });
17865
18149
  var CameraPipelineForAgentSchema = object({
17866
18150
  steps: array(PipelineStepInputSchema).readonly(),
@@ -18166,6 +18450,21 @@ method(object({
18166
18450
  }), object({ success: literal(true) }), {
18167
18451
  kind: "mutation",
18168
18452
  auth: "admin"
18453
+ }), method(object({
18454
+ agentNodeId: string(),
18455
+ detectWeight: number().positive().nullable()
18456
+ }), object({ success: literal(true) }), {
18457
+ kind: "mutation",
18458
+ auth: "admin"
18459
+ }), method(object({
18460
+ agentNodeId: string(),
18461
+ detect: boolean().nullable().optional(),
18462
+ decode: boolean().nullable().optional(),
18463
+ audio: boolean().nullable().optional(),
18464
+ ingest: boolean().nullable().optional()
18465
+ }), object({ success: literal(true) }), {
18466
+ kind: "mutation",
18467
+ auth: "admin"
18169
18468
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
18170
18469
  deviceId: number(),
18171
18470
  addonId: string(),
@@ -21913,6 +22212,18 @@ Object.freeze({
21913
22212
  addonId: null,
21914
22213
  access: "view"
21915
22214
  },
22215
+ "dayNight.getOptions": {
22216
+ capName: "day-night",
22217
+ capScope: "device",
22218
+ addonId: null,
22219
+ access: "view"
22220
+ },
22221
+ "dayNight.setSettings": {
22222
+ capName: "day-night",
22223
+ capScope: "device",
22224
+ addonId: null,
22225
+ access: "create"
22226
+ },
21916
22227
  "decoder.createSession": {
21917
22228
  capName: "decoder",
21918
22229
  capScope: "system",
@@ -22843,6 +23154,18 @@ Object.freeze({
22843
23154
  addonId: null,
22844
23155
  access: "create"
22845
23156
  },
23157
+ "imageSettings.getOptions": {
23158
+ capName: "image-settings",
23159
+ capScope: "device",
23160
+ addonId: null,
23161
+ access: "view"
23162
+ },
23163
+ "imageSettings.setSettings": {
23164
+ capName: "image-settings",
23165
+ capScope: "device",
23166
+ addonId: null,
23167
+ access: "create"
23168
+ },
22846
23169
  "integrations.create": {
22847
23170
  capName: "integrations",
22848
23171
  capScope: "system",
@@ -24025,6 +24348,18 @@ Object.freeze({
24025
24348
  addonId: null,
24026
24349
  access: "create"
24027
24350
  },
24351
+ "pipelineOrchestrator.setAgentCapabilities": {
24352
+ capName: "pipeline-orchestrator",
24353
+ capScope: "system",
24354
+ addonId: null,
24355
+ access: "create"
24356
+ },
24357
+ "pipelineOrchestrator.setAgentDetectWeight": {
24358
+ capName: "pipeline-orchestrator",
24359
+ capScope: "system",
24360
+ addonId: null,
24361
+ access: "create"
24362
+ },
24028
24363
  "pipelineOrchestrator.setAgentMaxCameras": {
24029
24364
  capName: "pipeline-orchestrator",
24030
24365
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-dreo",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "Dreo smart-device (fan / air-circulator / purifier / heater / humidifier) device-provider addon for CamStack — wraps the @apocaliss92/nodedreo Dreo cloud client (REST + WebSocket)",
5
5
  "keywords": [
6
6
  "camstack",