@camstack/addon-matter-broker 0.1.14 → 0.1.16

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
@@ -4656,7 +4656,7 @@ function preprocess(fn, schema) {
4656
4656
  });
4657
4657
  }
4658
4658
  //#endregion
4659
- //#region ../types/dist/sleep-BiDFW0E7.mjs
4659
+ //#region ../types/dist/sleep-CZDdRBua.mjs
4660
4660
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4661
4661
  EventCategory["SystemBoot"] = "system.boot";
4662
4662
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -7267,7 +7267,16 @@ var DecoderStatsSchema = object({
7267
7267
  inputFps: number(),
7268
7268
  outputFps: number(),
7269
7269
  avgDecodeTimeMs: number(),
7270
- droppedFrames: number()
7270
+ droppedFrames: number(),
7271
+ /**
7272
+ * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
7273
+ * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
7274
+ * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
7275
+ * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
7276
+ */
7277
+ lagMs: number().optional(),
7278
+ effectiveFps: number().optional(),
7279
+ adaptiveFps: number().optional()
7271
7280
  });
7272
7281
  var DecoderSessionConfigSchema = object({
7273
7282
  codec: string$2(),
@@ -7308,7 +7317,15 @@ var DecoderSessionConfigSchema = object({
7308
7317
  * other — `pullFrames` returns nothing for an `'shm'` session and
7309
7318
  * `pullHandles` returns nothing for a `'callback'` session.
7310
7319
  */
7311
- frameSink: _enum(["callback", "shm"]).default("callback")
7320
+ frameSink: _enum(["callback", "shm"]).default("callback"),
7321
+ /**
7322
+ * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
7323
+ * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
7324
+ * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
7325
+ * stream-broker's `streamingDebug` gate — off by default so production logs
7326
+ * stay quiet and the emit path pays zero per-frame cost when disabled.
7327
+ */
7328
+ debug: boolean().optional()
7312
7329
  });
7313
7330
  var EncodeProfileSchema = object({
7314
7331
  video: object({
@@ -10333,6 +10350,100 @@ var coverCapability = {
10333
10350
  runtimeState: CoverStatusSchema
10334
10351
  };
10335
10352
  /**
10353
+ * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
10354
+ * shared by reolink / hikvision / amcrest. Models the common firmware
10355
+ * surface: the IR-cut switching MODE plus the two knobs that gate it
10356
+ * (photocell `sensitivity` + `switchDelaySec`). Each vendor maps these
10357
+ * onto its own ISAPI / Baichuan / Dahua-CGI fields; the cap standardises
10358
+ * the shape so ONE derived-form renders every camera.
10359
+ *
10360
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
10361
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
10362
+ * injected from `status`) reports the live values, and a single
10363
+ * `setSettings` mutation applies a partial change. No hand-written
10364
+ * settings-contribution methods — the framework derives the UI + save
10365
+ * routing from this surface.
10366
+ */
10367
+ /** IR-cut switching mode. `schedule` = time-of-day table configured on the camera. */
10368
+ var DayNightModeSchema = _enum([
10369
+ "auto",
10370
+ "day",
10371
+ "night",
10372
+ "schedule"
10373
+ ]);
10374
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
10375
+ * getOptions availability convention. Normalized values are 0–100. */
10376
+ var NormalizedRangeSchema$1 = object({
10377
+ min: number(),
10378
+ max: number(),
10379
+ step: number()
10380
+ });
10381
+ /**
10382
+ * Current day/night state. Optional fields are absent when the camera
10383
+ * does not expose that knob (a photocell-less model reports no
10384
+ * `sensitivity`). `lastFetchedAt` feeds the runtime-state bridge.
10385
+ */
10386
+ var DayNightStatusSchema = object({
10387
+ mode: DayNightModeSchema,
10388
+ /** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
10389
+ sensitivity: number().optional(),
10390
+ /** Delay before the IR-cut filter flips, in seconds. */
10391
+ switchDelaySec: number().optional(),
10392
+ lastFetchedAt: number()
10393
+ });
10394
+ /**
10395
+ * Per-camera availability descriptor — drives which controls the admin UI
10396
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
10397
+ * (normalized 0–100); the mode choice-set as an array. A provider returns
10398
+ * honest, camera-probed values — never hardcoded.
10399
+ */
10400
+ var DayNightOptionsSchema = object({
10401
+ /** Modes this camera accepts. Empty → the camera has no configurable day/night mode. */
10402
+ modes: array(DayNightModeSchema),
10403
+ supportsSensitivity: boolean(),
10404
+ /** Present when `supportsSensitivity` — the normalized 0–100 range. */
10405
+ sensitivity: NormalizedRangeSchema$1.optional(),
10406
+ supportsSwitchDelay: boolean(),
10407
+ /** Present when `supportsSwitchDelay` — the allowed delay range in seconds. */
10408
+ switchDelaySec: NormalizedRangeSchema$1.optional()
10409
+ });
10410
+ /**
10411
+ * Partial change to the day/night config — every field optional. A
10412
+ * provider ignores fields it does not support.
10413
+ */
10414
+ var DayNightSettingsPatchSchema = object({
10415
+ mode: DayNightModeSchema.optional(),
10416
+ sensitivity: number().optional(),
10417
+ switchDelaySec: number().optional()
10418
+ });
10419
+ var dayNightCapability = {
10420
+ name: "day-night",
10421
+ scope: "device",
10422
+ deviceNative: true,
10423
+ mode: "singleton",
10424
+ deviceTypes: [DeviceType.Camera],
10425
+ deviceConfig: { ui: {
10426
+ kind: "derived-form",
10427
+ builderId: "day-night",
10428
+ tab: "image"
10429
+ } },
10430
+ methods: {
10431
+ getOptions: method(object({ deviceId: number() }), DayNightOptionsSchema),
10432
+ setSettings: method(object({
10433
+ deviceId: number(),
10434
+ settings: DayNightSettingsPatchSchema
10435
+ }), _void(), {
10436
+ kind: "mutation",
10437
+ auth: "admin"
10438
+ })
10439
+ },
10440
+ status: {
10441
+ schema: DayNightStatusSchema,
10442
+ kind: "poll"
10443
+ },
10444
+ runtimeState: DayNightStatusSchema
10445
+ };
10446
+ /**
10336
10447
  * Identity envelope for a device's upstream-system metadata.
10337
10448
  *
10338
10449
  * Two jobs:
@@ -10991,6 +11102,155 @@ var imageCapability = {
10991
11102
  runtimeState: ImageStatusSchema
10992
11103
  };
10993
11104
  /**
11105
+ * Vendor-neutral image / picture-adjustment cap — the per-camera config
11106
+ * cap shared by reolink / hikvision / amcrest. Models the common ISP
11107
+ * surface: the four picture sliders (brightness / contrast / saturation /
11108
+ * sharpness), orientation (mirror / flip / rotate), white-balance,
11109
+ * exposure and backlight-compensation modes.
11110
+ *
11111
+ * NORMALIZATION: every slider is a normalized int 0–100. Vendors expose
11112
+ * these natively as 0–100 or 0–255 (or other ranges); each provider maps
11113
+ * its native range to/from this normalized 0–100 space so the cap surface
11114
+ * (and the derived form) is identical across cameras. `warmth` (manual
11115
+ * white-balance) is likewise normalized 0–100.
11116
+ *
11117
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
11118
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
11119
+ * injected from `status`) reports the live values, and a single
11120
+ * `setSettings` mutation applies a partial change. No hand-written
11121
+ * settings-contribution methods — the framework derives the UI + save
11122
+ * routing from this surface.
11123
+ */
11124
+ /** Sensor/image rotation, degrees clockwise. */
11125
+ var ImageRotateSchema = _enum([
11126
+ "0",
11127
+ "90",
11128
+ "180",
11129
+ "270"
11130
+ ]);
11131
+ /** White-balance mode. `manual` unlocks the normalized `warmth` knob. */
11132
+ var WhiteBalanceModeSchema = _enum(["auto", "manual"]);
11133
+ /** Exposure mode. */
11134
+ var ExposureModeSchema = _enum(["auto", "manual"]);
11135
+ /**
11136
+ * Backlight-compensation mode:
11137
+ * - `off` — disabled
11138
+ * - `blc` — backlight compensation
11139
+ * - `wdr` — wide dynamic range
11140
+ * - `hlc` — highlight compensation
11141
+ */
11142
+ var BacklightModeSchema = _enum([
11143
+ "off",
11144
+ "blc",
11145
+ "wdr",
11146
+ "hlc"
11147
+ ]);
11148
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
11149
+ * getOptions availability convention. Slider values are normalized 0–100. */
11150
+ var NormalizedRangeSchema = object({
11151
+ min: number(),
11152
+ max: number(),
11153
+ step: number()
11154
+ });
11155
+ /**
11156
+ * Current image-adjustment state. Every field optional — absent when the
11157
+ * camera does not expose that control. Slider values are NORMALIZED 0–100.
11158
+ * `lastFetchedAt` feeds the runtime-state bridge.
11159
+ */
11160
+ var ImageSettingsStatusSchema = object({
11161
+ /** Normalized 0–100. */
11162
+ brightness: number().optional(),
11163
+ /** Normalized 0–100. */
11164
+ contrast: number().optional(),
11165
+ /** Normalized 0–100. */
11166
+ saturation: number().optional(),
11167
+ /** Normalized 0–100. */
11168
+ sharpness: number().optional(),
11169
+ mirror: boolean().optional(),
11170
+ flip: boolean().optional(),
11171
+ rotate: ImageRotateSchema.optional(),
11172
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11173
+ /** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
11174
+ warmth: number().optional(),
11175
+ exposureMode: ExposureModeSchema.optional(),
11176
+ backlightMode: BacklightModeSchema.optional(),
11177
+ lastFetchedAt: number()
11178
+ });
11179
+ /**
11180
+ * Per-camera availability descriptor — drives which controls the admin UI
11181
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
11182
+ * (the normalized 0–100 range); enums as arrays of supported values (empty
11183
+ * array → control hidden). A provider returns honest, camera-probed values
11184
+ * — never hardcoded.
11185
+ */
11186
+ var ImageSettingsOptionsSchema = object({
11187
+ supportsBrightness: boolean(),
11188
+ brightness: NormalizedRangeSchema.optional(),
11189
+ supportsContrast: boolean(),
11190
+ contrast: NormalizedRangeSchema.optional(),
11191
+ supportsSaturation: boolean(),
11192
+ saturation: NormalizedRangeSchema.optional(),
11193
+ supportsSharpness: boolean(),
11194
+ sharpness: NormalizedRangeSchema.optional(),
11195
+ supportsMirror: boolean(),
11196
+ supportsFlip: boolean(),
11197
+ /** Supported rotation values. Empty → rotation not configurable. */
11198
+ rotateOptions: array(ImageRotateSchema),
11199
+ /** Supported white-balance modes. Empty → white-balance not configurable. */
11200
+ whiteBalanceModes: array(WhiteBalanceModeSchema),
11201
+ supportsWarmth: boolean(),
11202
+ /** Present when `supportsWarmth` — the normalized 0–100 range. */
11203
+ warmth: NormalizedRangeSchema.optional(),
11204
+ /** Supported exposure modes. Empty → exposure not configurable. */
11205
+ exposureModes: array(ExposureModeSchema),
11206
+ /** Supported backlight modes. Empty → backlight-compensation not configurable. */
11207
+ backlightModes: array(BacklightModeSchema)
11208
+ });
11209
+ /**
11210
+ * Partial change to the image config — every field optional. Slider values
11211
+ * are normalized 0–100. A provider ignores fields it does not support.
11212
+ */
11213
+ var ImageSettingsPatchSchema = object({
11214
+ brightness: number().optional(),
11215
+ contrast: number().optional(),
11216
+ saturation: number().optional(),
11217
+ sharpness: number().optional(),
11218
+ mirror: boolean().optional(),
11219
+ flip: boolean().optional(),
11220
+ rotate: ImageRotateSchema.optional(),
11221
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11222
+ warmth: number().optional(),
11223
+ exposureMode: ExposureModeSchema.optional(),
11224
+ backlightMode: BacklightModeSchema.optional()
11225
+ });
11226
+ var imageSettingsCapability = {
11227
+ name: "image-settings",
11228
+ scope: "device",
11229
+ deviceNative: true,
11230
+ mode: "singleton",
11231
+ deviceTypes: [DeviceType.Camera],
11232
+ deviceConfig: { ui: {
11233
+ kind: "derived-form",
11234
+ builderId: "image-settings",
11235
+ tab: "image"
11236
+ } },
11237
+ methods: {
11238
+ getOptions: method(object({ deviceId: number() }), ImageSettingsOptionsSchema),
11239
+ setSettings: method(object({
11240
+ deviceId: number(),
11241
+ settings: ImageSettingsPatchSchema
11242
+ }), _void(), {
11243
+ kind: "mutation",
11244
+ auth: "admin"
11245
+ })
11246
+ },
11247
+ status: {
11248
+ schema: ImageSettingsStatusSchema,
11249
+ kind: "poll"
11250
+ },
11251
+ runtimeState: ImageSettingsStatusSchema
11252
+ };
11253
+ /**
10994
11254
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10995
11255
  * with a mowing lifecycle plus a dock action.
10996
11256
  *
@@ -11989,6 +12249,16 @@ var RunnerCameraConfigSchema = object({
11989
12249
  * this gate is bypassed.
11990
12250
  */
11991
12251
  onboardMotionDrivesAnalyzer: boolean().default(true),
12252
+ /**
12253
+ * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
12254
+ * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
12255
+ * this is off by default because the recheck re-subscribes a detection session
12256
+ * every N seconds while `watching`, a major source of pull-decoder re-dial
12257
+ * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
12258
+ * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
12259
+ * (and only render) when this is enabled.
12260
+ */
12261
+ occupancyRecheckEnabled: boolean().default(false),
11992
12262
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
11993
12263
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
11994
12264
  /**
@@ -13994,6 +14264,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
13994
14264
  contact: contactCapability,
13995
14265
  control: controlCapability,
13996
14266
  cover: coverCapability,
14267
+ dayNight: dayNightCapability,
13997
14268
  deviceDiscovery: deviceDiscoveryCapability,
13998
14269
  deviceStatus: deviceStatusCapability,
13999
14270
  doorbell: doorbellCapability,
@@ -14006,6 +14277,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14006
14277
  humidifier: humidifierCapability,
14007
14278
  humiditySensor: humiditySensorCapability,
14008
14279
  image: imageCapability,
14280
+ imageSettings: imageSettingsCapability,
14009
14281
  lawnMowerControl: lawnMowerControlCapability,
14010
14282
  lockControl: lockControlCapability,
14011
14283
  mediaPlayer: mediaPlayerCapability,
@@ -15969,7 +16241,9 @@ method(object({ codec: string$2() }), boolean()), method(_void(), object({
15969
16241
  id: string$2(),
15970
16242
  name: string$2(),
15971
16243
  isPullMode: boolean().optional(),
15972
- priority: number().optional()
16244
+ priority: number().optional(),
16245
+ hwaccel: string$2().optional(),
16246
+ probedBestHwaccel: string$2().optional()
15973
16247
  })), method(DecoderSessionConfigSchema, object({
15974
16248
  sessionId: string$2(),
15975
16249
  nodeId: string$2()
@@ -21995,6 +22269,18 @@ Object.freeze({
21995
22269
  addonId: null,
21996
22270
  access: "view"
21997
22271
  },
22272
+ "dayNight.getOptions": {
22273
+ capName: "day-night",
22274
+ capScope: "device",
22275
+ addonId: null,
22276
+ access: "view"
22277
+ },
22278
+ "dayNight.setSettings": {
22279
+ capName: "day-night",
22280
+ capScope: "device",
22281
+ addonId: null,
22282
+ access: "create"
22283
+ },
21998
22284
  "decoder.createSession": {
21999
22285
  capName: "decoder",
22000
22286
  capScope: "system",
@@ -22925,6 +23211,18 @@ Object.freeze({
22925
23211
  addonId: null,
22926
23212
  access: "create"
22927
23213
  },
23214
+ "imageSettings.getOptions": {
23215
+ capName: "image-settings",
23216
+ capScope: "device",
23217
+ addonId: null,
23218
+ access: "view"
23219
+ },
23220
+ "imageSettings.setSettings": {
23221
+ capName: "image-settings",
23222
+ capScope: "device",
23223
+ addonId: null,
23224
+ access: "create"
23225
+ },
22928
23226
  "integrations.create": {
22929
23227
  capName: "integrations",
22930
23228
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -4654,7 +4654,7 @@ function preprocess(fn, schema) {
4654
4654
  });
4655
4655
  }
4656
4656
  //#endregion
4657
- //#region ../types/dist/sleep-BiDFW0E7.mjs
4657
+ //#region ../types/dist/sleep-CZDdRBua.mjs
4658
4658
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4659
4659
  EventCategory["SystemBoot"] = "system.boot";
4660
4660
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -7265,7 +7265,16 @@ var DecoderStatsSchema = object({
7265
7265
  inputFps: number(),
7266
7266
  outputFps: number(),
7267
7267
  avgDecodeTimeMs: number(),
7268
- droppedFrames: number()
7268
+ droppedFrames: number(),
7269
+ /**
7270
+ * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
7271
+ * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
7272
+ * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
7273
+ * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
7274
+ */
7275
+ lagMs: number().optional(),
7276
+ effectiveFps: number().optional(),
7277
+ adaptiveFps: number().optional()
7269
7278
  });
7270
7279
  var DecoderSessionConfigSchema = object({
7271
7280
  codec: string$2(),
@@ -7306,7 +7315,15 @@ var DecoderSessionConfigSchema = object({
7306
7315
  * other — `pullFrames` returns nothing for an `'shm'` session and
7307
7316
  * `pullHandles` returns nothing for a `'callback'` session.
7308
7317
  */
7309
- frameSink: _enum(["callback", "shm"]).default("callback")
7318
+ frameSink: _enum(["callback", "shm"]).default("callback"),
7319
+ /**
7320
+ * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
7321
+ * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
7322
+ * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
7323
+ * stream-broker's `streamingDebug` gate — off by default so production logs
7324
+ * stay quiet and the emit path pays zero per-frame cost when disabled.
7325
+ */
7326
+ debug: boolean().optional()
7310
7327
  });
7311
7328
  var EncodeProfileSchema = object({
7312
7329
  video: object({
@@ -10331,6 +10348,100 @@ var coverCapability = {
10331
10348
  runtimeState: CoverStatusSchema
10332
10349
  };
10333
10350
  /**
10351
+ * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
10352
+ * shared by reolink / hikvision / amcrest. Models the common firmware
10353
+ * surface: the IR-cut switching MODE plus the two knobs that gate it
10354
+ * (photocell `sensitivity` + `switchDelaySec`). Each vendor maps these
10355
+ * onto its own ISAPI / Baichuan / Dahua-CGI fields; the cap standardises
10356
+ * the shape so ONE derived-form renders every camera.
10357
+ *
10358
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
10359
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
10360
+ * injected from `status`) reports the live values, and a single
10361
+ * `setSettings` mutation applies a partial change. No hand-written
10362
+ * settings-contribution methods — the framework derives the UI + save
10363
+ * routing from this surface.
10364
+ */
10365
+ /** IR-cut switching mode. `schedule` = time-of-day table configured on the camera. */
10366
+ var DayNightModeSchema = _enum([
10367
+ "auto",
10368
+ "day",
10369
+ "night",
10370
+ "schedule"
10371
+ ]);
10372
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
10373
+ * getOptions availability convention. Normalized values are 0–100. */
10374
+ var NormalizedRangeSchema$1 = object({
10375
+ min: number(),
10376
+ max: number(),
10377
+ step: number()
10378
+ });
10379
+ /**
10380
+ * Current day/night state. Optional fields are absent when the camera
10381
+ * does not expose that knob (a photocell-less model reports no
10382
+ * `sensitivity`). `lastFetchedAt` feeds the runtime-state bridge.
10383
+ */
10384
+ var DayNightStatusSchema = object({
10385
+ mode: DayNightModeSchema,
10386
+ /** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
10387
+ sensitivity: number().optional(),
10388
+ /** Delay before the IR-cut filter flips, in seconds. */
10389
+ switchDelaySec: number().optional(),
10390
+ lastFetchedAt: number()
10391
+ });
10392
+ /**
10393
+ * Per-camera availability descriptor — drives which controls the admin UI
10394
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
10395
+ * (normalized 0–100); the mode choice-set as an array. A provider returns
10396
+ * honest, camera-probed values — never hardcoded.
10397
+ */
10398
+ var DayNightOptionsSchema = object({
10399
+ /** Modes this camera accepts. Empty → the camera has no configurable day/night mode. */
10400
+ modes: array(DayNightModeSchema),
10401
+ supportsSensitivity: boolean(),
10402
+ /** Present when `supportsSensitivity` — the normalized 0–100 range. */
10403
+ sensitivity: NormalizedRangeSchema$1.optional(),
10404
+ supportsSwitchDelay: boolean(),
10405
+ /** Present when `supportsSwitchDelay` — the allowed delay range in seconds. */
10406
+ switchDelaySec: NormalizedRangeSchema$1.optional()
10407
+ });
10408
+ /**
10409
+ * Partial change to the day/night config — every field optional. A
10410
+ * provider ignores fields it does not support.
10411
+ */
10412
+ var DayNightSettingsPatchSchema = object({
10413
+ mode: DayNightModeSchema.optional(),
10414
+ sensitivity: number().optional(),
10415
+ switchDelaySec: number().optional()
10416
+ });
10417
+ var dayNightCapability = {
10418
+ name: "day-night",
10419
+ scope: "device",
10420
+ deviceNative: true,
10421
+ mode: "singleton",
10422
+ deviceTypes: [DeviceType.Camera],
10423
+ deviceConfig: { ui: {
10424
+ kind: "derived-form",
10425
+ builderId: "day-night",
10426
+ tab: "image"
10427
+ } },
10428
+ methods: {
10429
+ getOptions: method(object({ deviceId: number() }), DayNightOptionsSchema),
10430
+ setSettings: method(object({
10431
+ deviceId: number(),
10432
+ settings: DayNightSettingsPatchSchema
10433
+ }), _void(), {
10434
+ kind: "mutation",
10435
+ auth: "admin"
10436
+ })
10437
+ },
10438
+ status: {
10439
+ schema: DayNightStatusSchema,
10440
+ kind: "poll"
10441
+ },
10442
+ runtimeState: DayNightStatusSchema
10443
+ };
10444
+ /**
10334
10445
  * Identity envelope for a device's upstream-system metadata.
10335
10446
  *
10336
10447
  * Two jobs:
@@ -10989,6 +11100,155 @@ var imageCapability = {
10989
11100
  runtimeState: ImageStatusSchema
10990
11101
  };
10991
11102
  /**
11103
+ * Vendor-neutral image / picture-adjustment cap — the per-camera config
11104
+ * cap shared by reolink / hikvision / amcrest. Models the common ISP
11105
+ * surface: the four picture sliders (brightness / contrast / saturation /
11106
+ * sharpness), orientation (mirror / flip / rotate), white-balance,
11107
+ * exposure and backlight-compensation modes.
11108
+ *
11109
+ * NORMALIZATION: every slider is a normalized int 0–100. Vendors expose
11110
+ * these natively as 0–100 or 0–255 (or other ranges); each provider maps
11111
+ * its native range to/from this normalized 0–100 space so the cap surface
11112
+ * (and the derived form) is identical across cameras. `warmth` (manual
11113
+ * white-balance) is likewise normalized 0–100.
11114
+ *
11115
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
11116
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
11117
+ * injected from `status`) reports the live values, and a single
11118
+ * `setSettings` mutation applies a partial change. No hand-written
11119
+ * settings-contribution methods — the framework derives the UI + save
11120
+ * routing from this surface.
11121
+ */
11122
+ /** Sensor/image rotation, degrees clockwise. */
11123
+ var ImageRotateSchema = _enum([
11124
+ "0",
11125
+ "90",
11126
+ "180",
11127
+ "270"
11128
+ ]);
11129
+ /** White-balance mode. `manual` unlocks the normalized `warmth` knob. */
11130
+ var WhiteBalanceModeSchema = _enum(["auto", "manual"]);
11131
+ /** Exposure mode. */
11132
+ var ExposureModeSchema = _enum(["auto", "manual"]);
11133
+ /**
11134
+ * Backlight-compensation mode:
11135
+ * - `off` — disabled
11136
+ * - `blc` — backlight compensation
11137
+ * - `wdr` — wide dynamic range
11138
+ * - `hlc` — highlight compensation
11139
+ */
11140
+ var BacklightModeSchema = _enum([
11141
+ "off",
11142
+ "blc",
11143
+ "wdr",
11144
+ "hlc"
11145
+ ]);
11146
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
11147
+ * getOptions availability convention. Slider values are normalized 0–100. */
11148
+ var NormalizedRangeSchema = object({
11149
+ min: number(),
11150
+ max: number(),
11151
+ step: number()
11152
+ });
11153
+ /**
11154
+ * Current image-adjustment state. Every field optional — absent when the
11155
+ * camera does not expose that control. Slider values are NORMALIZED 0–100.
11156
+ * `lastFetchedAt` feeds the runtime-state bridge.
11157
+ */
11158
+ var ImageSettingsStatusSchema = object({
11159
+ /** Normalized 0–100. */
11160
+ brightness: number().optional(),
11161
+ /** Normalized 0–100. */
11162
+ contrast: number().optional(),
11163
+ /** Normalized 0–100. */
11164
+ saturation: number().optional(),
11165
+ /** Normalized 0–100. */
11166
+ sharpness: number().optional(),
11167
+ mirror: boolean().optional(),
11168
+ flip: boolean().optional(),
11169
+ rotate: ImageRotateSchema.optional(),
11170
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11171
+ /** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
11172
+ warmth: number().optional(),
11173
+ exposureMode: ExposureModeSchema.optional(),
11174
+ backlightMode: BacklightModeSchema.optional(),
11175
+ lastFetchedAt: number()
11176
+ });
11177
+ /**
11178
+ * Per-camera availability descriptor — drives which controls the admin UI
11179
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
11180
+ * (the normalized 0–100 range); enums as arrays of supported values (empty
11181
+ * array → control hidden). A provider returns honest, camera-probed values
11182
+ * — never hardcoded.
11183
+ */
11184
+ var ImageSettingsOptionsSchema = object({
11185
+ supportsBrightness: boolean(),
11186
+ brightness: NormalizedRangeSchema.optional(),
11187
+ supportsContrast: boolean(),
11188
+ contrast: NormalizedRangeSchema.optional(),
11189
+ supportsSaturation: boolean(),
11190
+ saturation: NormalizedRangeSchema.optional(),
11191
+ supportsSharpness: boolean(),
11192
+ sharpness: NormalizedRangeSchema.optional(),
11193
+ supportsMirror: boolean(),
11194
+ supportsFlip: boolean(),
11195
+ /** Supported rotation values. Empty → rotation not configurable. */
11196
+ rotateOptions: array(ImageRotateSchema),
11197
+ /** Supported white-balance modes. Empty → white-balance not configurable. */
11198
+ whiteBalanceModes: array(WhiteBalanceModeSchema),
11199
+ supportsWarmth: boolean(),
11200
+ /** Present when `supportsWarmth` — the normalized 0–100 range. */
11201
+ warmth: NormalizedRangeSchema.optional(),
11202
+ /** Supported exposure modes. Empty → exposure not configurable. */
11203
+ exposureModes: array(ExposureModeSchema),
11204
+ /** Supported backlight modes. Empty → backlight-compensation not configurable. */
11205
+ backlightModes: array(BacklightModeSchema)
11206
+ });
11207
+ /**
11208
+ * Partial change to the image config — every field optional. Slider values
11209
+ * are normalized 0–100. A provider ignores fields it does not support.
11210
+ */
11211
+ var ImageSettingsPatchSchema = object({
11212
+ brightness: number().optional(),
11213
+ contrast: number().optional(),
11214
+ saturation: number().optional(),
11215
+ sharpness: number().optional(),
11216
+ mirror: boolean().optional(),
11217
+ flip: boolean().optional(),
11218
+ rotate: ImageRotateSchema.optional(),
11219
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11220
+ warmth: number().optional(),
11221
+ exposureMode: ExposureModeSchema.optional(),
11222
+ backlightMode: BacklightModeSchema.optional()
11223
+ });
11224
+ var imageSettingsCapability = {
11225
+ name: "image-settings",
11226
+ scope: "device",
11227
+ deviceNative: true,
11228
+ mode: "singleton",
11229
+ deviceTypes: [DeviceType.Camera],
11230
+ deviceConfig: { ui: {
11231
+ kind: "derived-form",
11232
+ builderId: "image-settings",
11233
+ tab: "image"
11234
+ } },
11235
+ methods: {
11236
+ getOptions: method(object({ deviceId: number() }), ImageSettingsOptionsSchema),
11237
+ setSettings: method(object({
11238
+ deviceId: number(),
11239
+ settings: ImageSettingsPatchSchema
11240
+ }), _void(), {
11241
+ kind: "mutation",
11242
+ auth: "admin"
11243
+ })
11244
+ },
11245
+ status: {
11246
+ schema: ImageSettingsStatusSchema,
11247
+ kind: "poll"
11248
+ },
11249
+ runtimeState: ImageSettingsStatusSchema
11250
+ };
11251
+ /**
10992
11252
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10993
11253
  * with a mowing lifecycle plus a dock action.
10994
11254
  *
@@ -11987,6 +12247,16 @@ var RunnerCameraConfigSchema = object({
11987
12247
  * this gate is bypassed.
11988
12248
  */
11989
12249
  onboardMotionDrivesAnalyzer: boolean().default(true),
12250
+ /**
12251
+ * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
12252
+ * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
12253
+ * this is off by default because the recheck re-subscribes a detection session
12254
+ * every N seconds while `watching`, a major source of pull-decoder re-dial
12255
+ * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
12256
+ * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
12257
+ * (and only render) when this is enabled.
12258
+ */
12259
+ occupancyRecheckEnabled: boolean().default(false),
11990
12260
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
11991
12261
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
11992
12262
  /**
@@ -13992,6 +14262,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
13992
14262
  contact: contactCapability,
13993
14263
  control: controlCapability,
13994
14264
  cover: coverCapability,
14265
+ dayNight: dayNightCapability,
13995
14266
  deviceDiscovery: deviceDiscoveryCapability,
13996
14267
  deviceStatus: deviceStatusCapability,
13997
14268
  doorbell: doorbellCapability,
@@ -14004,6 +14275,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14004
14275
  humidifier: humidifierCapability,
14005
14276
  humiditySensor: humiditySensorCapability,
14006
14277
  image: imageCapability,
14278
+ imageSettings: imageSettingsCapability,
14007
14279
  lawnMowerControl: lawnMowerControlCapability,
14008
14280
  lockControl: lockControlCapability,
14009
14281
  mediaPlayer: mediaPlayerCapability,
@@ -15967,7 +16239,9 @@ method(object({ codec: string$2() }), boolean()), method(_void(), object({
15967
16239
  id: string$2(),
15968
16240
  name: string$2(),
15969
16241
  isPullMode: boolean().optional(),
15970
- priority: number().optional()
16242
+ priority: number().optional(),
16243
+ hwaccel: string$2().optional(),
16244
+ probedBestHwaccel: string$2().optional()
15971
16245
  })), method(DecoderSessionConfigSchema, object({
15972
16246
  sessionId: string$2(),
15973
16247
  nodeId: string$2()
@@ -21993,6 +22267,18 @@ Object.freeze({
21993
22267
  addonId: null,
21994
22268
  access: "view"
21995
22269
  },
22270
+ "dayNight.getOptions": {
22271
+ capName: "day-night",
22272
+ capScope: "device",
22273
+ addonId: null,
22274
+ access: "view"
22275
+ },
22276
+ "dayNight.setSettings": {
22277
+ capName: "day-night",
22278
+ capScope: "device",
22279
+ addonId: null,
22280
+ access: "create"
22281
+ },
21996
22282
  "decoder.createSession": {
21997
22283
  capName: "decoder",
21998
22284
  capScope: "system",
@@ -22923,6 +23209,18 @@ Object.freeze({
22923
23209
  addonId: null,
22924
23210
  access: "create"
22925
23211
  },
23212
+ "imageSettings.getOptions": {
23213
+ capName: "image-settings",
23214
+ capScope: "device",
23215
+ addonId: null,
23216
+ access: "view"
23217
+ },
23218
+ "imageSettings.setSettings": {
23219
+ capName: "image-settings",
23220
+ capScope: "device",
23221
+ addonId: null,
23222
+ access: "create"
23223
+ },
22926
23224
  "integrations.create": {
22927
23225
  capName: "integrations",
22928
23226
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-matter-broker",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "Matter broker addon for CamStack — owns a Matter fabric (commissioning + the long-lived controller) via the matter.js controller and brokers commissioned Matter nodes into CamStack",
5
5
  "keywords": [
6
6
  "camstack",