@camstack/addon-provider-wyze 0.1.13 → 0.1.15

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
@@ -4659,7 +4659,7 @@ function _instanceof(cls, params = {}) {
4659
4659
  return inst;
4660
4660
  }
4661
4661
  //#endregion
4662
- //#region ../types/dist/sleep-BiDFW0E7.mjs
4662
+ //#region ../types/dist/sleep-CZDdRBua.mjs
4663
4663
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4664
4664
  EventCategory["SystemBoot"] = "system.boot";
4665
4665
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -7270,7 +7270,16 @@ var DecoderStatsSchema = object({
7270
7270
  inputFps: number(),
7271
7271
  outputFps: number(),
7272
7272
  avgDecodeTimeMs: number(),
7273
- droppedFrames: number()
7273
+ droppedFrames: number(),
7274
+ /**
7275
+ * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
7276
+ * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
7277
+ * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
7278
+ * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
7279
+ */
7280
+ lagMs: number().optional(),
7281
+ effectiveFps: number().optional(),
7282
+ adaptiveFps: number().optional()
7274
7283
  });
7275
7284
  var DecoderSessionConfigSchema = object({
7276
7285
  codec: string(),
@@ -7311,7 +7320,15 @@ var DecoderSessionConfigSchema = object({
7311
7320
  * other — `pullFrames` returns nothing for an `'shm'` session and
7312
7321
  * `pullHandles` returns nothing for a `'callback'` session.
7313
7322
  */
7314
- frameSink: _enum(["callback", "shm"]).default("callback")
7323
+ frameSink: _enum(["callback", "shm"]).default("callback"),
7324
+ /**
7325
+ * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
7326
+ * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
7327
+ * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
7328
+ * stream-broker's `streamingDebug` gate — off by default so production logs
7329
+ * stay quiet and the emit path pays zero per-frame cost when disabled.
7330
+ */
7331
+ debug: boolean().optional()
7315
7332
  });
7316
7333
  var EncodeProfileSchema = object({
7317
7334
  video: object({
@@ -10336,6 +10353,100 @@ var coverCapability = {
10336
10353
  runtimeState: CoverStatusSchema
10337
10354
  };
10338
10355
  /**
10356
+ * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
10357
+ * shared by reolink / hikvision / amcrest. Models the common firmware
10358
+ * surface: the IR-cut switching MODE plus the two knobs that gate it
10359
+ * (photocell `sensitivity` + `switchDelaySec`). Each vendor maps these
10360
+ * onto its own ISAPI / Baichuan / Dahua-CGI fields; the cap standardises
10361
+ * the shape so ONE derived-form renders every camera.
10362
+ *
10363
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
10364
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
10365
+ * injected from `status`) reports the live values, and a single
10366
+ * `setSettings` mutation applies a partial change. No hand-written
10367
+ * settings-contribution methods — the framework derives the UI + save
10368
+ * routing from this surface.
10369
+ */
10370
+ /** IR-cut switching mode. `schedule` = time-of-day table configured on the camera. */
10371
+ var DayNightModeSchema = _enum([
10372
+ "auto",
10373
+ "day",
10374
+ "night",
10375
+ "schedule"
10376
+ ]);
10377
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
10378
+ * getOptions availability convention. Normalized values are 0–100. */
10379
+ var NormalizedRangeSchema$1 = object({
10380
+ min: number(),
10381
+ max: number(),
10382
+ step: number()
10383
+ });
10384
+ /**
10385
+ * Current day/night state. Optional fields are absent when the camera
10386
+ * does not expose that knob (a photocell-less model reports no
10387
+ * `sensitivity`). `lastFetchedAt` feeds the runtime-state bridge.
10388
+ */
10389
+ var DayNightStatusSchema = object({
10390
+ mode: DayNightModeSchema,
10391
+ /** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
10392
+ sensitivity: number().optional(),
10393
+ /** Delay before the IR-cut filter flips, in seconds. */
10394
+ switchDelaySec: number().optional(),
10395
+ lastFetchedAt: number()
10396
+ });
10397
+ /**
10398
+ * Per-camera availability descriptor — drives which controls the admin UI
10399
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
10400
+ * (normalized 0–100); the mode choice-set as an array. A provider returns
10401
+ * honest, camera-probed values — never hardcoded.
10402
+ */
10403
+ var DayNightOptionsSchema = object({
10404
+ /** Modes this camera accepts. Empty → the camera has no configurable day/night mode. */
10405
+ modes: array(DayNightModeSchema),
10406
+ supportsSensitivity: boolean(),
10407
+ /** Present when `supportsSensitivity` — the normalized 0–100 range. */
10408
+ sensitivity: NormalizedRangeSchema$1.optional(),
10409
+ supportsSwitchDelay: boolean(),
10410
+ /** Present when `supportsSwitchDelay` — the allowed delay range in seconds. */
10411
+ switchDelaySec: NormalizedRangeSchema$1.optional()
10412
+ });
10413
+ /**
10414
+ * Partial change to the day/night config — every field optional. A
10415
+ * provider ignores fields it does not support.
10416
+ */
10417
+ var DayNightSettingsPatchSchema = object({
10418
+ mode: DayNightModeSchema.optional(),
10419
+ sensitivity: number().optional(),
10420
+ switchDelaySec: number().optional()
10421
+ });
10422
+ var dayNightCapability = {
10423
+ name: "day-night",
10424
+ scope: "device",
10425
+ deviceNative: true,
10426
+ mode: "singleton",
10427
+ deviceTypes: [DeviceType.Camera],
10428
+ deviceConfig: { ui: {
10429
+ kind: "derived-form",
10430
+ builderId: "day-night",
10431
+ tab: "image"
10432
+ } },
10433
+ methods: {
10434
+ getOptions: method(object({ deviceId: number() }), DayNightOptionsSchema),
10435
+ setSettings: method(object({
10436
+ deviceId: number(),
10437
+ settings: DayNightSettingsPatchSchema
10438
+ }), _void(), {
10439
+ kind: "mutation",
10440
+ auth: "admin"
10441
+ })
10442
+ },
10443
+ status: {
10444
+ schema: DayNightStatusSchema,
10445
+ kind: "poll"
10446
+ },
10447
+ runtimeState: DayNightStatusSchema
10448
+ };
10449
+ /**
10339
10450
  * Identity envelope for a device's upstream-system metadata.
10340
10451
  *
10341
10452
  * Two jobs:
@@ -10994,6 +11105,155 @@ var imageCapability = {
10994
11105
  runtimeState: ImageStatusSchema
10995
11106
  };
10996
11107
  /**
11108
+ * Vendor-neutral image / picture-adjustment cap — the per-camera config
11109
+ * cap shared by reolink / hikvision / amcrest. Models the common ISP
11110
+ * surface: the four picture sliders (brightness / contrast / saturation /
11111
+ * sharpness), orientation (mirror / flip / rotate), white-balance,
11112
+ * exposure and backlight-compensation modes.
11113
+ *
11114
+ * NORMALIZATION: every slider is a normalized int 0–100. Vendors expose
11115
+ * these natively as 0–100 or 0–255 (or other ranges); each provider maps
11116
+ * its native range to/from this normalized 0–100 space so the cap surface
11117
+ * (and the derived form) is identical across cameras. `warmth` (manual
11118
+ * white-balance) is likewise normalized 0–100.
11119
+ *
11120
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
11121
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
11122
+ * injected from `status`) reports the live values, and a single
11123
+ * `setSettings` mutation applies a partial change. No hand-written
11124
+ * settings-contribution methods — the framework derives the UI + save
11125
+ * routing from this surface.
11126
+ */
11127
+ /** Sensor/image rotation, degrees clockwise. */
11128
+ var ImageRotateSchema = _enum([
11129
+ "0",
11130
+ "90",
11131
+ "180",
11132
+ "270"
11133
+ ]);
11134
+ /** White-balance mode. `manual` unlocks the normalized `warmth` knob. */
11135
+ var WhiteBalanceModeSchema = _enum(["auto", "manual"]);
11136
+ /** Exposure mode. */
11137
+ var ExposureModeSchema = _enum(["auto", "manual"]);
11138
+ /**
11139
+ * Backlight-compensation mode:
11140
+ * - `off` — disabled
11141
+ * - `blc` — backlight compensation
11142
+ * - `wdr` — wide dynamic range
11143
+ * - `hlc` — highlight compensation
11144
+ */
11145
+ var BacklightModeSchema = _enum([
11146
+ "off",
11147
+ "blc",
11148
+ "wdr",
11149
+ "hlc"
11150
+ ]);
11151
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
11152
+ * getOptions availability convention. Slider values are normalized 0–100. */
11153
+ var NormalizedRangeSchema = object({
11154
+ min: number(),
11155
+ max: number(),
11156
+ step: number()
11157
+ });
11158
+ /**
11159
+ * Current image-adjustment state. Every field optional — absent when the
11160
+ * camera does not expose that control. Slider values are NORMALIZED 0–100.
11161
+ * `lastFetchedAt` feeds the runtime-state bridge.
11162
+ */
11163
+ var ImageSettingsStatusSchema = object({
11164
+ /** Normalized 0–100. */
11165
+ brightness: number().optional(),
11166
+ /** Normalized 0–100. */
11167
+ contrast: number().optional(),
11168
+ /** Normalized 0–100. */
11169
+ saturation: number().optional(),
11170
+ /** Normalized 0–100. */
11171
+ sharpness: number().optional(),
11172
+ mirror: boolean().optional(),
11173
+ flip: boolean().optional(),
11174
+ rotate: ImageRotateSchema.optional(),
11175
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11176
+ /** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
11177
+ warmth: number().optional(),
11178
+ exposureMode: ExposureModeSchema.optional(),
11179
+ backlightMode: BacklightModeSchema.optional(),
11180
+ lastFetchedAt: number()
11181
+ });
11182
+ /**
11183
+ * Per-camera availability descriptor — drives which controls the admin UI
11184
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
11185
+ * (the normalized 0–100 range); enums as arrays of supported values (empty
11186
+ * array → control hidden). A provider returns honest, camera-probed values
11187
+ * — never hardcoded.
11188
+ */
11189
+ var ImageSettingsOptionsSchema = object({
11190
+ supportsBrightness: boolean(),
11191
+ brightness: NormalizedRangeSchema.optional(),
11192
+ supportsContrast: boolean(),
11193
+ contrast: NormalizedRangeSchema.optional(),
11194
+ supportsSaturation: boolean(),
11195
+ saturation: NormalizedRangeSchema.optional(),
11196
+ supportsSharpness: boolean(),
11197
+ sharpness: NormalizedRangeSchema.optional(),
11198
+ supportsMirror: boolean(),
11199
+ supportsFlip: boolean(),
11200
+ /** Supported rotation values. Empty → rotation not configurable. */
11201
+ rotateOptions: array(ImageRotateSchema),
11202
+ /** Supported white-balance modes. Empty → white-balance not configurable. */
11203
+ whiteBalanceModes: array(WhiteBalanceModeSchema),
11204
+ supportsWarmth: boolean(),
11205
+ /** Present when `supportsWarmth` — the normalized 0–100 range. */
11206
+ warmth: NormalizedRangeSchema.optional(),
11207
+ /** Supported exposure modes. Empty → exposure not configurable. */
11208
+ exposureModes: array(ExposureModeSchema),
11209
+ /** Supported backlight modes. Empty → backlight-compensation not configurable. */
11210
+ backlightModes: array(BacklightModeSchema)
11211
+ });
11212
+ /**
11213
+ * Partial change to the image config — every field optional. Slider values
11214
+ * are normalized 0–100. A provider ignores fields it does not support.
11215
+ */
11216
+ var ImageSettingsPatchSchema = object({
11217
+ brightness: number().optional(),
11218
+ contrast: number().optional(),
11219
+ saturation: number().optional(),
11220
+ sharpness: number().optional(),
11221
+ mirror: boolean().optional(),
11222
+ flip: boolean().optional(),
11223
+ rotate: ImageRotateSchema.optional(),
11224
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11225
+ warmth: number().optional(),
11226
+ exposureMode: ExposureModeSchema.optional(),
11227
+ backlightMode: BacklightModeSchema.optional()
11228
+ });
11229
+ var imageSettingsCapability = {
11230
+ name: "image-settings",
11231
+ scope: "device",
11232
+ deviceNative: true,
11233
+ mode: "singleton",
11234
+ deviceTypes: [DeviceType.Camera],
11235
+ deviceConfig: { ui: {
11236
+ kind: "derived-form",
11237
+ builderId: "image-settings",
11238
+ tab: "image"
11239
+ } },
11240
+ methods: {
11241
+ getOptions: method(object({ deviceId: number() }), ImageSettingsOptionsSchema),
11242
+ setSettings: method(object({
11243
+ deviceId: number(),
11244
+ settings: ImageSettingsPatchSchema
11245
+ }), _void(), {
11246
+ kind: "mutation",
11247
+ auth: "admin"
11248
+ })
11249
+ },
11250
+ status: {
11251
+ schema: ImageSettingsStatusSchema,
11252
+ kind: "poll"
11253
+ },
11254
+ runtimeState: ImageSettingsStatusSchema
11255
+ };
11256
+ /**
10997
11257
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10998
11258
  * with a mowing lifecycle plus a dock action.
10999
11259
  *
@@ -11992,6 +12252,16 @@ var RunnerCameraConfigSchema = object({
11992
12252
  * this gate is bypassed.
11993
12253
  */
11994
12254
  onboardMotionDrivesAnalyzer: boolean().default(true),
12255
+ /**
12256
+ * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
12257
+ * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
12258
+ * this is off by default because the recheck re-subscribes a detection session
12259
+ * every N seconds while `watching`, a major source of pull-decoder re-dial
12260
+ * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
12261
+ * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
12262
+ * (and only render) when this is enabled.
12263
+ */
12264
+ occupancyRecheckEnabled: boolean().default(false),
11995
12265
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
11996
12266
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
11997
12267
  /**
@@ -13997,6 +14267,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
13997
14267
  contact: contactCapability,
13998
14268
  control: controlCapability,
13999
14269
  cover: coverCapability,
14270
+ dayNight: dayNightCapability,
14000
14271
  deviceDiscovery: deviceDiscoveryCapability,
14001
14272
  deviceStatus: deviceStatusCapability,
14002
14273
  doorbell: doorbellCapability,
@@ -14009,6 +14280,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14009
14280
  humidifier: humidifierCapability,
14010
14281
  humiditySensor: humiditySensorCapability,
14011
14282
  image: imageCapability,
14283
+ imageSettings: imageSettingsCapability,
14012
14284
  lawnMowerControl: lawnMowerControlCapability,
14013
14285
  lockControl: lockControlCapability,
14014
14286
  mediaPlayer: mediaPlayerCapability,
@@ -15923,7 +16195,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
15923
16195
  id: string(),
15924
16196
  name: string(),
15925
16197
  isPullMode: boolean().optional(),
15926
- priority: number().optional()
16198
+ priority: number().optional(),
16199
+ hwaccel: string().optional(),
16200
+ probedBestHwaccel: string().optional()
15927
16201
  })), method(DecoderSessionConfigSchema, object({
15928
16202
  sessionId: string(),
15929
16203
  nodeId: string()
@@ -17854,7 +18128,17 @@ var AgentAddonConfigSchema = object({
17854
18128
  });
17855
18129
  var AgentPipelineSettingsSchema = object({
17856
18130
  addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
17857
- maxCameras: number().int().nonnegative().nullable().default(null)
18131
+ maxCameras: number().int().nonnegative().nullable().default(null),
18132
+ /** Per-node detection weight (relative share for the quota balancer). */
18133
+ detectWeight: number().positive().optional(),
18134
+ /** Node is eligible to run the detection pipeline (decode + inference). */
18135
+ detect: boolean().optional(),
18136
+ /** Node is eligible to host decoder sessions. */
18137
+ decode: boolean().optional(),
18138
+ /** Node is eligible to run audio-analyzer sessions. */
18139
+ audio: boolean().optional(),
18140
+ /** Node is eligible to be the ingest / source-owner (serve the restream). */
18141
+ ingest: boolean().optional()
17858
18142
  });
17859
18143
  var CameraPipelineForAgentSchema = object({
17860
18144
  steps: array(PipelineStepInputSchema).readonly(),
@@ -18160,6 +18444,21 @@ method(object({
18160
18444
  }), object({ success: literal(true) }), {
18161
18445
  kind: "mutation",
18162
18446
  auth: "admin"
18447
+ }), method(object({
18448
+ agentNodeId: string(),
18449
+ detectWeight: number().positive().nullable()
18450
+ }), object({ success: literal(true) }), {
18451
+ kind: "mutation",
18452
+ auth: "admin"
18453
+ }), method(object({
18454
+ agentNodeId: string(),
18455
+ detect: boolean().nullable().optional(),
18456
+ decode: boolean().nullable().optional(),
18457
+ audio: boolean().nullable().optional(),
18458
+ ingest: boolean().nullable().optional()
18459
+ }), object({ success: literal(true) }), {
18460
+ kind: "mutation",
18461
+ auth: "admin"
18163
18462
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
18164
18463
  deviceId: number(),
18165
18464
  addonId: string(),
@@ -22014,6 +22313,18 @@ Object.freeze({
22014
22313
  addonId: null,
22015
22314
  access: "view"
22016
22315
  },
22316
+ "dayNight.getOptions": {
22317
+ capName: "day-night",
22318
+ capScope: "device",
22319
+ addonId: null,
22320
+ access: "view"
22321
+ },
22322
+ "dayNight.setSettings": {
22323
+ capName: "day-night",
22324
+ capScope: "device",
22325
+ addonId: null,
22326
+ access: "create"
22327
+ },
22017
22328
  "decoder.createSession": {
22018
22329
  capName: "decoder",
22019
22330
  capScope: "system",
@@ -22944,6 +23255,18 @@ Object.freeze({
22944
23255
  addonId: null,
22945
23256
  access: "create"
22946
23257
  },
23258
+ "imageSettings.getOptions": {
23259
+ capName: "image-settings",
23260
+ capScope: "device",
23261
+ addonId: null,
23262
+ access: "view"
23263
+ },
23264
+ "imageSettings.setSettings": {
23265
+ capName: "image-settings",
23266
+ capScope: "device",
23267
+ addonId: null,
23268
+ access: "create"
23269
+ },
22947
23270
  "integrations.create": {
22948
23271
  capName: "integrations",
22949
23272
  capScope: "system",
@@ -24126,6 +24449,18 @@ Object.freeze({
24126
24449
  addonId: null,
24127
24450
  access: "create"
24128
24451
  },
24452
+ "pipelineOrchestrator.setAgentCapabilities": {
24453
+ capName: "pipeline-orchestrator",
24454
+ capScope: "system",
24455
+ addonId: null,
24456
+ access: "create"
24457
+ },
24458
+ "pipelineOrchestrator.setAgentDetectWeight": {
24459
+ capName: "pipeline-orchestrator",
24460
+ capScope: "system",
24461
+ addonId: null,
24462
+ access: "create"
24463
+ },
24129
24464
  "pipelineOrchestrator.setAgentMaxCameras": {
24130
24465
  capName: "pipeline-orchestrator",
24131
24466
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -4638,7 +4638,7 @@ function _instanceof(cls, params = {}) {
4638
4638
  return inst;
4639
4639
  }
4640
4640
  //#endregion
4641
- //#region ../types/dist/sleep-BiDFW0E7.mjs
4641
+ //#region ../types/dist/sleep-CZDdRBua.mjs
4642
4642
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4643
4643
  EventCategory["SystemBoot"] = "system.boot";
4644
4644
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -7249,7 +7249,16 @@ var DecoderStatsSchema = object({
7249
7249
  inputFps: number(),
7250
7250
  outputFps: number(),
7251
7251
  avgDecodeTimeMs: number(),
7252
- droppedFrames: number()
7252
+ droppedFrames: number(),
7253
+ /**
7254
+ * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
7255
+ * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
7256
+ * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
7257
+ * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
7258
+ */
7259
+ lagMs: number().optional(),
7260
+ effectiveFps: number().optional(),
7261
+ adaptiveFps: number().optional()
7253
7262
  });
7254
7263
  var DecoderSessionConfigSchema = object({
7255
7264
  codec: string(),
@@ -7290,7 +7299,15 @@ var DecoderSessionConfigSchema = object({
7290
7299
  * other — `pullFrames` returns nothing for an `'shm'` session and
7291
7300
  * `pullHandles` returns nothing for a `'callback'` session.
7292
7301
  */
7293
- frameSink: _enum(["callback", "shm"]).default("callback")
7302
+ frameSink: _enum(["callback", "shm"]).default("callback"),
7303
+ /**
7304
+ * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
7305
+ * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
7306
+ * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
7307
+ * stream-broker's `streamingDebug` gate — off by default so production logs
7308
+ * stay quiet and the emit path pays zero per-frame cost when disabled.
7309
+ */
7310
+ debug: boolean().optional()
7294
7311
  });
7295
7312
  var EncodeProfileSchema = object({
7296
7313
  video: object({
@@ -10315,6 +10332,100 @@ var coverCapability = {
10315
10332
  runtimeState: CoverStatusSchema
10316
10333
  };
10317
10334
  /**
10335
+ * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
10336
+ * shared by reolink / hikvision / amcrest. Models the common firmware
10337
+ * surface: the IR-cut switching MODE plus the two knobs that gate it
10338
+ * (photocell `sensitivity` + `switchDelaySec`). Each vendor maps these
10339
+ * onto its own ISAPI / Baichuan / Dahua-CGI fields; the cap standardises
10340
+ * the shape so ONE derived-form renders every camera.
10341
+ *
10342
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
10343
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
10344
+ * injected from `status`) reports the live values, and a single
10345
+ * `setSettings` mutation applies a partial change. No hand-written
10346
+ * settings-contribution methods — the framework derives the UI + save
10347
+ * routing from this surface.
10348
+ */
10349
+ /** IR-cut switching mode. `schedule` = time-of-day table configured on the camera. */
10350
+ var DayNightModeSchema = _enum([
10351
+ "auto",
10352
+ "day",
10353
+ "night",
10354
+ "schedule"
10355
+ ]);
10356
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
10357
+ * getOptions availability convention. Normalized values are 0–100. */
10358
+ var NormalizedRangeSchema$1 = object({
10359
+ min: number(),
10360
+ max: number(),
10361
+ step: number()
10362
+ });
10363
+ /**
10364
+ * Current day/night state. Optional fields are absent when the camera
10365
+ * does not expose that knob (a photocell-less model reports no
10366
+ * `sensitivity`). `lastFetchedAt` feeds the runtime-state bridge.
10367
+ */
10368
+ var DayNightStatusSchema = object({
10369
+ mode: DayNightModeSchema,
10370
+ /** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
10371
+ sensitivity: number().optional(),
10372
+ /** Delay before the IR-cut filter flips, in seconds. */
10373
+ switchDelaySec: number().optional(),
10374
+ lastFetchedAt: number()
10375
+ });
10376
+ /**
10377
+ * Per-camera availability descriptor — drives which controls the admin UI
10378
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
10379
+ * (normalized 0–100); the mode choice-set as an array. A provider returns
10380
+ * honest, camera-probed values — never hardcoded.
10381
+ */
10382
+ var DayNightOptionsSchema = object({
10383
+ /** Modes this camera accepts. Empty → the camera has no configurable day/night mode. */
10384
+ modes: array(DayNightModeSchema),
10385
+ supportsSensitivity: boolean(),
10386
+ /** Present when `supportsSensitivity` — the normalized 0–100 range. */
10387
+ sensitivity: NormalizedRangeSchema$1.optional(),
10388
+ supportsSwitchDelay: boolean(),
10389
+ /** Present when `supportsSwitchDelay` — the allowed delay range in seconds. */
10390
+ switchDelaySec: NormalizedRangeSchema$1.optional()
10391
+ });
10392
+ /**
10393
+ * Partial change to the day/night config — every field optional. A
10394
+ * provider ignores fields it does not support.
10395
+ */
10396
+ var DayNightSettingsPatchSchema = object({
10397
+ mode: DayNightModeSchema.optional(),
10398
+ sensitivity: number().optional(),
10399
+ switchDelaySec: number().optional()
10400
+ });
10401
+ var dayNightCapability = {
10402
+ name: "day-night",
10403
+ scope: "device",
10404
+ deviceNative: true,
10405
+ mode: "singleton",
10406
+ deviceTypes: [DeviceType.Camera],
10407
+ deviceConfig: { ui: {
10408
+ kind: "derived-form",
10409
+ builderId: "day-night",
10410
+ tab: "image"
10411
+ } },
10412
+ methods: {
10413
+ getOptions: method(object({ deviceId: number() }), DayNightOptionsSchema),
10414
+ setSettings: method(object({
10415
+ deviceId: number(),
10416
+ settings: DayNightSettingsPatchSchema
10417
+ }), _void(), {
10418
+ kind: "mutation",
10419
+ auth: "admin"
10420
+ })
10421
+ },
10422
+ status: {
10423
+ schema: DayNightStatusSchema,
10424
+ kind: "poll"
10425
+ },
10426
+ runtimeState: DayNightStatusSchema
10427
+ };
10428
+ /**
10318
10429
  * Identity envelope for a device's upstream-system metadata.
10319
10430
  *
10320
10431
  * Two jobs:
@@ -10973,6 +11084,155 @@ var imageCapability = {
10973
11084
  runtimeState: ImageStatusSchema
10974
11085
  };
10975
11086
  /**
11087
+ * Vendor-neutral image / picture-adjustment cap — the per-camera config
11088
+ * cap shared by reolink / hikvision / amcrest. Models the common ISP
11089
+ * surface: the four picture sliders (brightness / contrast / saturation /
11090
+ * sharpness), orientation (mirror / flip / rotate), white-balance,
11091
+ * exposure and backlight-compensation modes.
11092
+ *
11093
+ * NORMALIZATION: every slider is a normalized int 0–100. Vendors expose
11094
+ * these natively as 0–100 or 0–255 (or other ranges); each provider maps
11095
+ * its native range to/from this normalized 0–100 space so the cap surface
11096
+ * (and the derived form) is identical across cameras. `warmth` (manual
11097
+ * white-balance) is likewise normalized 0–100.
11098
+ *
11099
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
11100
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
11101
+ * injected from `status`) reports the live values, and a single
11102
+ * `setSettings` mutation applies a partial change. No hand-written
11103
+ * settings-contribution methods — the framework derives the UI + save
11104
+ * routing from this surface.
11105
+ */
11106
+ /** Sensor/image rotation, degrees clockwise. */
11107
+ var ImageRotateSchema = _enum([
11108
+ "0",
11109
+ "90",
11110
+ "180",
11111
+ "270"
11112
+ ]);
11113
+ /** White-balance mode. `manual` unlocks the normalized `warmth` knob. */
11114
+ var WhiteBalanceModeSchema = _enum(["auto", "manual"]);
11115
+ /** Exposure mode. */
11116
+ var ExposureModeSchema = _enum(["auto", "manual"]);
11117
+ /**
11118
+ * Backlight-compensation mode:
11119
+ * - `off` — disabled
11120
+ * - `blc` — backlight compensation
11121
+ * - `wdr` — wide dynamic range
11122
+ * - `hlc` — highlight compensation
11123
+ */
11124
+ var BacklightModeSchema = _enum([
11125
+ "off",
11126
+ "blc",
11127
+ "wdr",
11128
+ "hlc"
11129
+ ]);
11130
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
11131
+ * getOptions availability convention. Slider values are normalized 0–100. */
11132
+ var NormalizedRangeSchema = object({
11133
+ min: number(),
11134
+ max: number(),
11135
+ step: number()
11136
+ });
11137
+ /**
11138
+ * Current image-adjustment state. Every field optional — absent when the
11139
+ * camera does not expose that control. Slider values are NORMALIZED 0–100.
11140
+ * `lastFetchedAt` feeds the runtime-state bridge.
11141
+ */
11142
+ var ImageSettingsStatusSchema = object({
11143
+ /** Normalized 0–100. */
11144
+ brightness: number().optional(),
11145
+ /** Normalized 0–100. */
11146
+ contrast: number().optional(),
11147
+ /** Normalized 0–100. */
11148
+ saturation: number().optional(),
11149
+ /** Normalized 0–100. */
11150
+ sharpness: number().optional(),
11151
+ mirror: boolean().optional(),
11152
+ flip: boolean().optional(),
11153
+ rotate: ImageRotateSchema.optional(),
11154
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11155
+ /** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
11156
+ warmth: number().optional(),
11157
+ exposureMode: ExposureModeSchema.optional(),
11158
+ backlightMode: BacklightModeSchema.optional(),
11159
+ lastFetchedAt: number()
11160
+ });
11161
+ /**
11162
+ * Per-camera availability descriptor — drives which controls the admin UI
11163
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
11164
+ * (the normalized 0–100 range); enums as arrays of supported values (empty
11165
+ * array → control hidden). A provider returns honest, camera-probed values
11166
+ * — never hardcoded.
11167
+ */
11168
+ var ImageSettingsOptionsSchema = object({
11169
+ supportsBrightness: boolean(),
11170
+ brightness: NormalizedRangeSchema.optional(),
11171
+ supportsContrast: boolean(),
11172
+ contrast: NormalizedRangeSchema.optional(),
11173
+ supportsSaturation: boolean(),
11174
+ saturation: NormalizedRangeSchema.optional(),
11175
+ supportsSharpness: boolean(),
11176
+ sharpness: NormalizedRangeSchema.optional(),
11177
+ supportsMirror: boolean(),
11178
+ supportsFlip: boolean(),
11179
+ /** Supported rotation values. Empty → rotation not configurable. */
11180
+ rotateOptions: array(ImageRotateSchema),
11181
+ /** Supported white-balance modes. Empty → white-balance not configurable. */
11182
+ whiteBalanceModes: array(WhiteBalanceModeSchema),
11183
+ supportsWarmth: boolean(),
11184
+ /** Present when `supportsWarmth` — the normalized 0–100 range. */
11185
+ warmth: NormalizedRangeSchema.optional(),
11186
+ /** Supported exposure modes. Empty → exposure not configurable. */
11187
+ exposureModes: array(ExposureModeSchema),
11188
+ /** Supported backlight modes. Empty → backlight-compensation not configurable. */
11189
+ backlightModes: array(BacklightModeSchema)
11190
+ });
11191
+ /**
11192
+ * Partial change to the image config — every field optional. Slider values
11193
+ * are normalized 0–100. A provider ignores fields it does not support.
11194
+ */
11195
+ var ImageSettingsPatchSchema = object({
11196
+ brightness: number().optional(),
11197
+ contrast: number().optional(),
11198
+ saturation: number().optional(),
11199
+ sharpness: number().optional(),
11200
+ mirror: boolean().optional(),
11201
+ flip: boolean().optional(),
11202
+ rotate: ImageRotateSchema.optional(),
11203
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11204
+ warmth: number().optional(),
11205
+ exposureMode: ExposureModeSchema.optional(),
11206
+ backlightMode: BacklightModeSchema.optional()
11207
+ });
11208
+ var imageSettingsCapability = {
11209
+ name: "image-settings",
11210
+ scope: "device",
11211
+ deviceNative: true,
11212
+ mode: "singleton",
11213
+ deviceTypes: [DeviceType.Camera],
11214
+ deviceConfig: { ui: {
11215
+ kind: "derived-form",
11216
+ builderId: "image-settings",
11217
+ tab: "image"
11218
+ } },
11219
+ methods: {
11220
+ getOptions: method(object({ deviceId: number() }), ImageSettingsOptionsSchema),
11221
+ setSettings: method(object({
11222
+ deviceId: number(),
11223
+ settings: ImageSettingsPatchSchema
11224
+ }), _void(), {
11225
+ kind: "mutation",
11226
+ auth: "admin"
11227
+ })
11228
+ },
11229
+ status: {
11230
+ schema: ImageSettingsStatusSchema,
11231
+ kind: "poll"
11232
+ },
11233
+ runtimeState: ImageSettingsStatusSchema
11234
+ };
11235
+ /**
10976
11236
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10977
11237
  * with a mowing lifecycle plus a dock action.
10978
11238
  *
@@ -11971,6 +12231,16 @@ var RunnerCameraConfigSchema = object({
11971
12231
  * this gate is bypassed.
11972
12232
  */
11973
12233
  onboardMotionDrivesAnalyzer: boolean().default(true),
12234
+ /**
12235
+ * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
12236
+ * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
12237
+ * this is off by default because the recheck re-subscribes a detection session
12238
+ * every N seconds while `watching`, a major source of pull-decoder re-dial
12239
+ * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
12240
+ * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
12241
+ * (and only render) when this is enabled.
12242
+ */
12243
+ occupancyRecheckEnabled: boolean().default(false),
11974
12244
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
11975
12245
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
11976
12246
  /**
@@ -13976,6 +14246,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
13976
14246
  contact: contactCapability,
13977
14247
  control: controlCapability,
13978
14248
  cover: coverCapability,
14249
+ dayNight: dayNightCapability,
13979
14250
  deviceDiscovery: deviceDiscoveryCapability,
13980
14251
  deviceStatus: deviceStatusCapability,
13981
14252
  doorbell: doorbellCapability,
@@ -13988,6 +14259,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
13988
14259
  humidifier: humidifierCapability,
13989
14260
  humiditySensor: humiditySensorCapability,
13990
14261
  image: imageCapability,
14262
+ imageSettings: imageSettingsCapability,
13991
14263
  lawnMowerControl: lawnMowerControlCapability,
13992
14264
  lockControl: lockControlCapability,
13993
14265
  mediaPlayer: mediaPlayerCapability,
@@ -15902,7 +16174,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
15902
16174
  id: string(),
15903
16175
  name: string(),
15904
16176
  isPullMode: boolean().optional(),
15905
- priority: number().optional()
16177
+ priority: number().optional(),
16178
+ hwaccel: string().optional(),
16179
+ probedBestHwaccel: string().optional()
15906
16180
  })), method(DecoderSessionConfigSchema, object({
15907
16181
  sessionId: string(),
15908
16182
  nodeId: string()
@@ -17833,7 +18107,17 @@ var AgentAddonConfigSchema = object({
17833
18107
  });
17834
18108
  var AgentPipelineSettingsSchema = object({
17835
18109
  addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
17836
- maxCameras: number().int().nonnegative().nullable().default(null)
18110
+ maxCameras: number().int().nonnegative().nullable().default(null),
18111
+ /** Per-node detection weight (relative share for the quota balancer). */
18112
+ detectWeight: number().positive().optional(),
18113
+ /** Node is eligible to run the detection pipeline (decode + inference). */
18114
+ detect: boolean().optional(),
18115
+ /** Node is eligible to host decoder sessions. */
18116
+ decode: boolean().optional(),
18117
+ /** Node is eligible to run audio-analyzer sessions. */
18118
+ audio: boolean().optional(),
18119
+ /** Node is eligible to be the ingest / source-owner (serve the restream). */
18120
+ ingest: boolean().optional()
17837
18121
  });
17838
18122
  var CameraPipelineForAgentSchema = object({
17839
18123
  steps: array(PipelineStepInputSchema).readonly(),
@@ -18139,6 +18423,21 @@ method(object({
18139
18423
  }), object({ success: literal(true) }), {
18140
18424
  kind: "mutation",
18141
18425
  auth: "admin"
18426
+ }), method(object({
18427
+ agentNodeId: string(),
18428
+ detectWeight: number().positive().nullable()
18429
+ }), object({ success: literal(true) }), {
18430
+ kind: "mutation",
18431
+ auth: "admin"
18432
+ }), method(object({
18433
+ agentNodeId: string(),
18434
+ detect: boolean().nullable().optional(),
18435
+ decode: boolean().nullable().optional(),
18436
+ audio: boolean().nullable().optional(),
18437
+ ingest: boolean().nullable().optional()
18438
+ }), object({ success: literal(true) }), {
18439
+ kind: "mutation",
18440
+ auth: "admin"
18142
18441
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
18143
18442
  deviceId: number(),
18144
18443
  addonId: string(),
@@ -21993,6 +22292,18 @@ Object.freeze({
21993
22292
  addonId: null,
21994
22293
  access: "view"
21995
22294
  },
22295
+ "dayNight.getOptions": {
22296
+ capName: "day-night",
22297
+ capScope: "device",
22298
+ addonId: null,
22299
+ access: "view"
22300
+ },
22301
+ "dayNight.setSettings": {
22302
+ capName: "day-night",
22303
+ capScope: "device",
22304
+ addonId: null,
22305
+ access: "create"
22306
+ },
21996
22307
  "decoder.createSession": {
21997
22308
  capName: "decoder",
21998
22309
  capScope: "system",
@@ -22923,6 +23234,18 @@ Object.freeze({
22923
23234
  addonId: null,
22924
23235
  access: "create"
22925
23236
  },
23237
+ "imageSettings.getOptions": {
23238
+ capName: "image-settings",
23239
+ capScope: "device",
23240
+ addonId: null,
23241
+ access: "view"
23242
+ },
23243
+ "imageSettings.setSettings": {
23244
+ capName: "image-settings",
23245
+ capScope: "device",
23246
+ addonId: null,
23247
+ access: "create"
23248
+ },
22926
23249
  "integrations.create": {
22927
23250
  capName: "integrations",
22928
23251
  capScope: "system",
@@ -24105,6 +24428,18 @@ Object.freeze({
24105
24428
  addonId: null,
24106
24429
  access: "create"
24107
24430
  },
24431
+ "pipelineOrchestrator.setAgentCapabilities": {
24432
+ capName: "pipeline-orchestrator",
24433
+ capScope: "system",
24434
+ addonId: null,
24435
+ access: "create"
24436
+ },
24437
+ "pipelineOrchestrator.setAgentDetectWeight": {
24438
+ capName: "pipeline-orchestrator",
24439
+ capScope: "system",
24440
+ addonId: null,
24441
+ access: "create"
24442
+ },
24108
24443
  "pipelineOrchestrator.setAgentMaxCameras": {
24109
24444
  capName: "pipeline-orchestrator",
24110
24445
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-wyze",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Wyze camera device-provider addon for CamStack — wraps the @apocaliss92/wyze-bridge-js P2P/DTLS client, feeding the stream-broker via the pull-rfc4571 lazy-publish path (a structural twin of addon-provider-reolink)",
5
5
  "keywords": [
6
6
  "camstack",