@camstack/addon-provider-homeassistant 1.1.19 → 1.1.21

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
@@ -4629,7 +4629,7 @@ function _instanceof(cls, params = {}) {
4629
4629
  return inst;
4630
4630
  }
4631
4631
  //#endregion
4632
- //#region ../types/dist/sleep-BiDFW0E7.mjs
4632
+ //#region ../types/dist/sleep-CZDdRBua.mjs
4633
4633
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4634
4634
  EventCategory["SystemBoot"] = "system.boot";
4635
4635
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -7240,7 +7240,16 @@ var DecoderStatsSchema = object({
7240
7240
  inputFps: number(),
7241
7241
  outputFps: number(),
7242
7242
  avgDecodeTimeMs: number(),
7243
- droppedFrames: number()
7243
+ droppedFrames: number(),
7244
+ /**
7245
+ * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
7246
+ * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
7247
+ * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
7248
+ * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
7249
+ */
7250
+ lagMs: number().optional(),
7251
+ effectiveFps: number().optional(),
7252
+ adaptiveFps: number().optional()
7244
7253
  });
7245
7254
  var DecoderSessionConfigSchema = object({
7246
7255
  codec: string(),
@@ -7281,7 +7290,15 @@ var DecoderSessionConfigSchema = object({
7281
7290
  * other — `pullFrames` returns nothing for an `'shm'` session and
7282
7291
  * `pullHandles` returns nothing for a `'callback'` session.
7283
7292
  */
7284
- frameSink: _enum(["callback", "shm"]).default("callback")
7293
+ frameSink: _enum(["callback", "shm"]).default("callback"),
7294
+ /**
7295
+ * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
7296
+ * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
7297
+ * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
7298
+ * stream-broker's `streamingDebug` gate — off by default so production logs
7299
+ * stay quiet and the emit path pays zero per-frame cost when disabled.
7300
+ */
7301
+ debug: boolean().optional()
7285
7302
  });
7286
7303
  var EncodeProfileSchema = object({
7287
7304
  video: object({
@@ -10499,6 +10516,100 @@ var coverCapability = {
10499
10516
  runtimeState: CoverStatusSchema
10500
10517
  };
10501
10518
  /**
10519
+ * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
10520
+ * shared by reolink / hikvision / amcrest. Models the common firmware
10521
+ * surface: the IR-cut switching MODE plus the two knobs that gate it
10522
+ * (photocell `sensitivity` + `switchDelaySec`). Each vendor maps these
10523
+ * onto its own ISAPI / Baichuan / Dahua-CGI fields; the cap standardises
10524
+ * the shape so ONE derived-form renders every camera.
10525
+ *
10526
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
10527
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
10528
+ * injected from `status`) reports the live values, and a single
10529
+ * `setSettings` mutation applies a partial change. No hand-written
10530
+ * settings-contribution methods — the framework derives the UI + save
10531
+ * routing from this surface.
10532
+ */
10533
+ /** IR-cut switching mode. `schedule` = time-of-day table configured on the camera. */
10534
+ var DayNightModeSchema = _enum([
10535
+ "auto",
10536
+ "day",
10537
+ "night",
10538
+ "schedule"
10539
+ ]);
10540
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
10541
+ * getOptions availability convention. Normalized values are 0–100. */
10542
+ var NormalizedRangeSchema$1 = object({
10543
+ min: number(),
10544
+ max: number(),
10545
+ step: number()
10546
+ });
10547
+ /**
10548
+ * Current day/night state. Optional fields are absent when the camera
10549
+ * does not expose that knob (a photocell-less model reports no
10550
+ * `sensitivity`). `lastFetchedAt` feeds the runtime-state bridge.
10551
+ */
10552
+ var DayNightStatusSchema = object({
10553
+ mode: DayNightModeSchema,
10554
+ /** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
10555
+ sensitivity: number().optional(),
10556
+ /** Delay before the IR-cut filter flips, in seconds. */
10557
+ switchDelaySec: number().optional(),
10558
+ lastFetchedAt: number()
10559
+ });
10560
+ /**
10561
+ * Per-camera availability descriptor — drives which controls the admin UI
10562
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
10563
+ * (normalized 0–100); the mode choice-set as an array. A provider returns
10564
+ * honest, camera-probed values — never hardcoded.
10565
+ */
10566
+ var DayNightOptionsSchema = object({
10567
+ /** Modes this camera accepts. Empty → the camera has no configurable day/night mode. */
10568
+ modes: array(DayNightModeSchema),
10569
+ supportsSensitivity: boolean(),
10570
+ /** Present when `supportsSensitivity` — the normalized 0–100 range. */
10571
+ sensitivity: NormalizedRangeSchema$1.optional(),
10572
+ supportsSwitchDelay: boolean(),
10573
+ /** Present when `supportsSwitchDelay` — the allowed delay range in seconds. */
10574
+ switchDelaySec: NormalizedRangeSchema$1.optional()
10575
+ });
10576
+ /**
10577
+ * Partial change to the day/night config — every field optional. A
10578
+ * provider ignores fields it does not support.
10579
+ */
10580
+ var DayNightSettingsPatchSchema = object({
10581
+ mode: DayNightModeSchema.optional(),
10582
+ sensitivity: number().optional(),
10583
+ switchDelaySec: number().optional()
10584
+ });
10585
+ var dayNightCapability = {
10586
+ name: "day-night",
10587
+ scope: "device",
10588
+ deviceNative: true,
10589
+ mode: "singleton",
10590
+ deviceTypes: [DeviceType.Camera],
10591
+ deviceConfig: { ui: {
10592
+ kind: "derived-form",
10593
+ builderId: "day-night",
10594
+ tab: "image"
10595
+ } },
10596
+ methods: {
10597
+ getOptions: method(object({ deviceId: number() }), DayNightOptionsSchema),
10598
+ setSettings: method(object({
10599
+ deviceId: number(),
10600
+ settings: DayNightSettingsPatchSchema
10601
+ }), _void(), {
10602
+ kind: "mutation",
10603
+ auth: "admin"
10604
+ })
10605
+ },
10606
+ status: {
10607
+ schema: DayNightStatusSchema,
10608
+ kind: "poll"
10609
+ },
10610
+ runtimeState: DayNightStatusSchema
10611
+ };
10612
+ /**
10502
10613
  * Identity envelope for a device's upstream-system metadata.
10503
10614
  *
10504
10615
  * Two jobs:
@@ -11202,6 +11313,155 @@ var imageCapability = {
11202
11313
  runtimeState: ImageStatusSchema
11203
11314
  };
11204
11315
  /**
11316
+ * Vendor-neutral image / picture-adjustment cap — the per-camera config
11317
+ * cap shared by reolink / hikvision / amcrest. Models the common ISP
11318
+ * surface: the four picture sliders (brightness / contrast / saturation /
11319
+ * sharpness), orientation (mirror / flip / rotate), white-balance,
11320
+ * exposure and backlight-compensation modes.
11321
+ *
11322
+ * NORMALIZATION: every slider is a normalized int 0–100. Vendors expose
11323
+ * these natively as 0–100 or 0–255 (or other ranges); each provider maps
11324
+ * its native range to/from this normalized 0–100 space so the cap surface
11325
+ * (and the derived form) is identical across cameras. `warmth` (manual
11326
+ * white-balance) is likewise normalized 0–100.
11327
+ *
11328
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
11329
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
11330
+ * injected from `status`) reports the live values, and a single
11331
+ * `setSettings` mutation applies a partial change. No hand-written
11332
+ * settings-contribution methods — the framework derives the UI + save
11333
+ * routing from this surface.
11334
+ */
11335
+ /** Sensor/image rotation, degrees clockwise. */
11336
+ var ImageRotateSchema = _enum([
11337
+ "0",
11338
+ "90",
11339
+ "180",
11340
+ "270"
11341
+ ]);
11342
+ /** White-balance mode. `manual` unlocks the normalized `warmth` knob. */
11343
+ var WhiteBalanceModeSchema = _enum(["auto", "manual"]);
11344
+ /** Exposure mode. */
11345
+ var ExposureModeSchema = _enum(["auto", "manual"]);
11346
+ /**
11347
+ * Backlight-compensation mode:
11348
+ * - `off` — disabled
11349
+ * - `blc` — backlight compensation
11350
+ * - `wdr` — wide dynamic range
11351
+ * - `hlc` — highlight compensation
11352
+ */
11353
+ var BacklightModeSchema = _enum([
11354
+ "off",
11355
+ "blc",
11356
+ "wdr",
11357
+ "hlc"
11358
+ ]);
11359
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
11360
+ * getOptions availability convention. Slider values are normalized 0–100. */
11361
+ var NormalizedRangeSchema = object({
11362
+ min: number(),
11363
+ max: number(),
11364
+ step: number()
11365
+ });
11366
+ /**
11367
+ * Current image-adjustment state. Every field optional — absent when the
11368
+ * camera does not expose that control. Slider values are NORMALIZED 0–100.
11369
+ * `lastFetchedAt` feeds the runtime-state bridge.
11370
+ */
11371
+ var ImageSettingsStatusSchema = object({
11372
+ /** Normalized 0–100. */
11373
+ brightness: number().optional(),
11374
+ /** Normalized 0–100. */
11375
+ contrast: number().optional(),
11376
+ /** Normalized 0–100. */
11377
+ saturation: number().optional(),
11378
+ /** Normalized 0–100. */
11379
+ sharpness: number().optional(),
11380
+ mirror: boolean().optional(),
11381
+ flip: boolean().optional(),
11382
+ rotate: ImageRotateSchema.optional(),
11383
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11384
+ /** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
11385
+ warmth: number().optional(),
11386
+ exposureMode: ExposureModeSchema.optional(),
11387
+ backlightMode: BacklightModeSchema.optional(),
11388
+ lastFetchedAt: number()
11389
+ });
11390
+ /**
11391
+ * Per-camera availability descriptor — drives which controls the admin UI
11392
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
11393
+ * (the normalized 0–100 range); enums as arrays of supported values (empty
11394
+ * array → control hidden). A provider returns honest, camera-probed values
11395
+ * — never hardcoded.
11396
+ */
11397
+ var ImageSettingsOptionsSchema = object({
11398
+ supportsBrightness: boolean(),
11399
+ brightness: NormalizedRangeSchema.optional(),
11400
+ supportsContrast: boolean(),
11401
+ contrast: NormalizedRangeSchema.optional(),
11402
+ supportsSaturation: boolean(),
11403
+ saturation: NormalizedRangeSchema.optional(),
11404
+ supportsSharpness: boolean(),
11405
+ sharpness: NormalizedRangeSchema.optional(),
11406
+ supportsMirror: boolean(),
11407
+ supportsFlip: boolean(),
11408
+ /** Supported rotation values. Empty → rotation not configurable. */
11409
+ rotateOptions: array(ImageRotateSchema),
11410
+ /** Supported white-balance modes. Empty → white-balance not configurable. */
11411
+ whiteBalanceModes: array(WhiteBalanceModeSchema),
11412
+ supportsWarmth: boolean(),
11413
+ /** Present when `supportsWarmth` — the normalized 0–100 range. */
11414
+ warmth: NormalizedRangeSchema.optional(),
11415
+ /** Supported exposure modes. Empty → exposure not configurable. */
11416
+ exposureModes: array(ExposureModeSchema),
11417
+ /** Supported backlight modes. Empty → backlight-compensation not configurable. */
11418
+ backlightModes: array(BacklightModeSchema)
11419
+ });
11420
+ /**
11421
+ * Partial change to the image config — every field optional. Slider values
11422
+ * are normalized 0–100. A provider ignores fields it does not support.
11423
+ */
11424
+ var ImageSettingsPatchSchema = object({
11425
+ brightness: number().optional(),
11426
+ contrast: number().optional(),
11427
+ saturation: number().optional(),
11428
+ sharpness: number().optional(),
11429
+ mirror: boolean().optional(),
11430
+ flip: boolean().optional(),
11431
+ rotate: ImageRotateSchema.optional(),
11432
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11433
+ warmth: number().optional(),
11434
+ exposureMode: ExposureModeSchema.optional(),
11435
+ backlightMode: BacklightModeSchema.optional()
11436
+ });
11437
+ var imageSettingsCapability = {
11438
+ name: "image-settings",
11439
+ scope: "device",
11440
+ deviceNative: true,
11441
+ mode: "singleton",
11442
+ deviceTypes: [DeviceType.Camera],
11443
+ deviceConfig: { ui: {
11444
+ kind: "derived-form",
11445
+ builderId: "image-settings",
11446
+ tab: "image"
11447
+ } },
11448
+ methods: {
11449
+ getOptions: method(object({ deviceId: number() }), ImageSettingsOptionsSchema),
11450
+ setSettings: method(object({
11451
+ deviceId: number(),
11452
+ settings: ImageSettingsPatchSchema
11453
+ }), _void(), {
11454
+ kind: "mutation",
11455
+ auth: "admin"
11456
+ })
11457
+ },
11458
+ status: {
11459
+ schema: ImageSettingsStatusSchema,
11460
+ kind: "poll"
11461
+ },
11462
+ runtimeState: ImageSettingsStatusSchema
11463
+ };
11464
+ /**
11205
11465
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
11206
11466
  * with a mowing lifecycle plus a dock action.
11207
11467
  *
@@ -12200,6 +12460,16 @@ var RunnerCameraConfigSchema = object({
12200
12460
  * this gate is bypassed.
12201
12461
  */
12202
12462
  onboardMotionDrivesAnalyzer: boolean().default(true),
12463
+ /**
12464
+ * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
12465
+ * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
12466
+ * this is off by default because the recheck re-subscribes a detection session
12467
+ * every N seconds while `watching`, a major source of pull-decoder re-dial
12468
+ * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
12469
+ * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
12470
+ * (and only render) when this is enabled.
12471
+ */
12472
+ occupancyRecheckEnabled: boolean().default(false),
12203
12473
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
12204
12474
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
12205
12475
  /**
@@ -14205,6 +14475,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14205
14475
  contact: contactCapability,
14206
14476
  control: controlCapability,
14207
14477
  cover: coverCapability,
14478
+ dayNight: dayNightCapability,
14208
14479
  deviceDiscovery: deviceDiscoveryCapability,
14209
14480
  deviceStatus: deviceStatusCapability,
14210
14481
  doorbell: doorbellCapability,
@@ -14217,6 +14488,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14217
14488
  humidifier: humidifierCapability,
14218
14489
  humiditySensor: humiditySensorCapability,
14219
14490
  image: imageCapability,
14491
+ imageSettings: imageSettingsCapability,
14220
14492
  lawnMowerControl: lawnMowerControlCapability,
14221
14493
  lockControl: lockControlCapability,
14222
14494
  mediaPlayer: mediaPlayerCapability,
@@ -16180,7 +16452,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
16180
16452
  id: string(),
16181
16453
  name: string(),
16182
16454
  isPullMode: boolean().optional(),
16183
- priority: number().optional()
16455
+ priority: number().optional(),
16456
+ hwaccel: string().optional(),
16457
+ probedBestHwaccel: string().optional()
16184
16458
  })), method(DecoderSessionConfigSchema, object({
16185
16459
  sessionId: string(),
16186
16460
  nodeId: string()
@@ -22292,6 +22566,18 @@ Object.freeze({
22292
22566
  addonId: null,
22293
22567
  access: "view"
22294
22568
  },
22569
+ "dayNight.getOptions": {
22570
+ capName: "day-night",
22571
+ capScope: "device",
22572
+ addonId: null,
22573
+ access: "view"
22574
+ },
22575
+ "dayNight.setSettings": {
22576
+ capName: "day-night",
22577
+ capScope: "device",
22578
+ addonId: null,
22579
+ access: "create"
22580
+ },
22295
22581
  "decoder.createSession": {
22296
22582
  capName: "decoder",
22297
22583
  capScope: "system",
@@ -23222,6 +23508,18 @@ Object.freeze({
23222
23508
  addonId: null,
23223
23509
  access: "create"
23224
23510
  },
23511
+ "imageSettings.getOptions": {
23512
+ capName: "image-settings",
23513
+ capScope: "device",
23514
+ addonId: null,
23515
+ access: "view"
23516
+ },
23517
+ "imageSettings.setSettings": {
23518
+ capName: "image-settings",
23519
+ capScope: "device",
23520
+ addonId: null,
23521
+ access: "create"
23522
+ },
23225
23523
  "integrations.create": {
23226
23524
  capName: "integrations",
23227
23525
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -4628,7 +4628,7 @@ function _instanceof(cls, params = {}) {
4628
4628
  return inst;
4629
4629
  }
4630
4630
  //#endregion
4631
- //#region ../types/dist/sleep-BiDFW0E7.mjs
4631
+ //#region ../types/dist/sleep-CZDdRBua.mjs
4632
4632
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4633
4633
  EventCategory["SystemBoot"] = "system.boot";
4634
4634
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -7239,7 +7239,16 @@ var DecoderStatsSchema = object({
7239
7239
  inputFps: number(),
7240
7240
  outputFps: number(),
7241
7241
  avgDecodeTimeMs: number(),
7242
- droppedFrames: number()
7242
+ droppedFrames: number(),
7243
+ /**
7244
+ * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
7245
+ * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
7246
+ * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
7247
+ * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
7248
+ */
7249
+ lagMs: number().optional(),
7250
+ effectiveFps: number().optional(),
7251
+ adaptiveFps: number().optional()
7243
7252
  });
7244
7253
  var DecoderSessionConfigSchema = object({
7245
7254
  codec: string(),
@@ -7280,7 +7289,15 @@ var DecoderSessionConfigSchema = object({
7280
7289
  * other — `pullFrames` returns nothing for an `'shm'` session and
7281
7290
  * `pullHandles` returns nothing for a `'callback'` session.
7282
7291
  */
7283
- frameSink: _enum(["callback", "shm"]).default("callback")
7292
+ frameSink: _enum(["callback", "shm"]).default("callback"),
7293
+ /**
7294
+ * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
7295
+ * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
7296
+ * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
7297
+ * stream-broker's `streamingDebug` gate — off by default so production logs
7298
+ * stay quiet and the emit path pays zero per-frame cost when disabled.
7299
+ */
7300
+ debug: boolean().optional()
7284
7301
  });
7285
7302
  var EncodeProfileSchema = object({
7286
7303
  video: object({
@@ -10498,6 +10515,100 @@ var coverCapability = {
10498
10515
  runtimeState: CoverStatusSchema
10499
10516
  };
10500
10517
  /**
10518
+ * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
10519
+ * shared by reolink / hikvision / amcrest. Models the common firmware
10520
+ * surface: the IR-cut switching MODE plus the two knobs that gate it
10521
+ * (photocell `sensitivity` + `switchDelaySec`). Each vendor maps these
10522
+ * onto its own ISAPI / Baichuan / Dahua-CGI fields; the cap standardises
10523
+ * the shape so ONE derived-form renders every camera.
10524
+ *
10525
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
10526
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
10527
+ * injected from `status`) reports the live values, and a single
10528
+ * `setSettings` mutation applies a partial change. No hand-written
10529
+ * settings-contribution methods — the framework derives the UI + save
10530
+ * routing from this surface.
10531
+ */
10532
+ /** IR-cut switching mode. `schedule` = time-of-day table configured on the camera. */
10533
+ var DayNightModeSchema = _enum([
10534
+ "auto",
10535
+ "day",
10536
+ "night",
10537
+ "schedule"
10538
+ ]);
10539
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
10540
+ * getOptions availability convention. Normalized values are 0–100. */
10541
+ var NormalizedRangeSchema$1 = object({
10542
+ min: number(),
10543
+ max: number(),
10544
+ step: number()
10545
+ });
10546
+ /**
10547
+ * Current day/night state. Optional fields are absent when the camera
10548
+ * does not expose that knob (a photocell-less model reports no
10549
+ * `sensitivity`). `lastFetchedAt` feeds the runtime-state bridge.
10550
+ */
10551
+ var DayNightStatusSchema = object({
10552
+ mode: DayNightModeSchema,
10553
+ /** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
10554
+ sensitivity: number().optional(),
10555
+ /** Delay before the IR-cut filter flips, in seconds. */
10556
+ switchDelaySec: number().optional(),
10557
+ lastFetchedAt: number()
10558
+ });
10559
+ /**
10560
+ * Per-camera availability descriptor — drives which controls the admin UI
10561
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
10562
+ * (normalized 0–100); the mode choice-set as an array. A provider returns
10563
+ * honest, camera-probed values — never hardcoded.
10564
+ */
10565
+ var DayNightOptionsSchema = object({
10566
+ /** Modes this camera accepts. Empty → the camera has no configurable day/night mode. */
10567
+ modes: array(DayNightModeSchema),
10568
+ supportsSensitivity: boolean(),
10569
+ /** Present when `supportsSensitivity` — the normalized 0–100 range. */
10570
+ sensitivity: NormalizedRangeSchema$1.optional(),
10571
+ supportsSwitchDelay: boolean(),
10572
+ /** Present when `supportsSwitchDelay` — the allowed delay range in seconds. */
10573
+ switchDelaySec: NormalizedRangeSchema$1.optional()
10574
+ });
10575
+ /**
10576
+ * Partial change to the day/night config — every field optional. A
10577
+ * provider ignores fields it does not support.
10578
+ */
10579
+ var DayNightSettingsPatchSchema = object({
10580
+ mode: DayNightModeSchema.optional(),
10581
+ sensitivity: number().optional(),
10582
+ switchDelaySec: number().optional()
10583
+ });
10584
+ var dayNightCapability = {
10585
+ name: "day-night",
10586
+ scope: "device",
10587
+ deviceNative: true,
10588
+ mode: "singleton",
10589
+ deviceTypes: [DeviceType.Camera],
10590
+ deviceConfig: { ui: {
10591
+ kind: "derived-form",
10592
+ builderId: "day-night",
10593
+ tab: "image"
10594
+ } },
10595
+ methods: {
10596
+ getOptions: method(object({ deviceId: number() }), DayNightOptionsSchema),
10597
+ setSettings: method(object({
10598
+ deviceId: number(),
10599
+ settings: DayNightSettingsPatchSchema
10600
+ }), _void(), {
10601
+ kind: "mutation",
10602
+ auth: "admin"
10603
+ })
10604
+ },
10605
+ status: {
10606
+ schema: DayNightStatusSchema,
10607
+ kind: "poll"
10608
+ },
10609
+ runtimeState: DayNightStatusSchema
10610
+ };
10611
+ /**
10501
10612
  * Identity envelope for a device's upstream-system metadata.
10502
10613
  *
10503
10614
  * Two jobs:
@@ -11201,6 +11312,155 @@ var imageCapability = {
11201
11312
  runtimeState: ImageStatusSchema
11202
11313
  };
11203
11314
  /**
11315
+ * Vendor-neutral image / picture-adjustment cap — the per-camera config
11316
+ * cap shared by reolink / hikvision / amcrest. Models the common ISP
11317
+ * surface: the four picture sliders (brightness / contrast / saturation /
11318
+ * sharpness), orientation (mirror / flip / rotate), white-balance,
11319
+ * exposure and backlight-compensation modes.
11320
+ *
11321
+ * NORMALIZATION: every slider is a normalized int 0–100. Vendors expose
11322
+ * these natively as 0–100 or 0–255 (or other ranges); each provider maps
11323
+ * its native range to/from this normalized 0–100 space so the cap surface
11324
+ * (and the derived form) is identical across cameras. `warmth` (manual
11325
+ * white-balance) is likewise normalized 0–100.
11326
+ *
11327
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
11328
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
11329
+ * injected from `status`) reports the live values, and a single
11330
+ * `setSettings` mutation applies a partial change. No hand-written
11331
+ * settings-contribution methods — the framework derives the UI + save
11332
+ * routing from this surface.
11333
+ */
11334
+ /** Sensor/image rotation, degrees clockwise. */
11335
+ var ImageRotateSchema = _enum([
11336
+ "0",
11337
+ "90",
11338
+ "180",
11339
+ "270"
11340
+ ]);
11341
+ /** White-balance mode. `manual` unlocks the normalized `warmth` knob. */
11342
+ var WhiteBalanceModeSchema = _enum(["auto", "manual"]);
11343
+ /** Exposure mode. */
11344
+ var ExposureModeSchema = _enum(["auto", "manual"]);
11345
+ /**
11346
+ * Backlight-compensation mode:
11347
+ * - `off` — disabled
11348
+ * - `blc` — backlight compensation
11349
+ * - `wdr` — wide dynamic range
11350
+ * - `hlc` — highlight compensation
11351
+ */
11352
+ var BacklightModeSchema = _enum([
11353
+ "off",
11354
+ "blc",
11355
+ "wdr",
11356
+ "hlc"
11357
+ ]);
11358
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
11359
+ * getOptions availability convention. Slider values are normalized 0–100. */
11360
+ var NormalizedRangeSchema = object({
11361
+ min: number(),
11362
+ max: number(),
11363
+ step: number()
11364
+ });
11365
+ /**
11366
+ * Current image-adjustment state. Every field optional — absent when the
11367
+ * camera does not expose that control. Slider values are NORMALIZED 0–100.
11368
+ * `lastFetchedAt` feeds the runtime-state bridge.
11369
+ */
11370
+ var ImageSettingsStatusSchema = object({
11371
+ /** Normalized 0–100. */
11372
+ brightness: number().optional(),
11373
+ /** Normalized 0–100. */
11374
+ contrast: number().optional(),
11375
+ /** Normalized 0–100. */
11376
+ saturation: number().optional(),
11377
+ /** Normalized 0–100. */
11378
+ sharpness: number().optional(),
11379
+ mirror: boolean().optional(),
11380
+ flip: boolean().optional(),
11381
+ rotate: ImageRotateSchema.optional(),
11382
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11383
+ /** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
11384
+ warmth: number().optional(),
11385
+ exposureMode: ExposureModeSchema.optional(),
11386
+ backlightMode: BacklightModeSchema.optional(),
11387
+ lastFetchedAt: number()
11388
+ });
11389
+ /**
11390
+ * Per-camera availability descriptor — drives which controls the admin UI
11391
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
11392
+ * (the normalized 0–100 range); enums as arrays of supported values (empty
11393
+ * array → control hidden). A provider returns honest, camera-probed values
11394
+ * — never hardcoded.
11395
+ */
11396
+ var ImageSettingsOptionsSchema = object({
11397
+ supportsBrightness: boolean(),
11398
+ brightness: NormalizedRangeSchema.optional(),
11399
+ supportsContrast: boolean(),
11400
+ contrast: NormalizedRangeSchema.optional(),
11401
+ supportsSaturation: boolean(),
11402
+ saturation: NormalizedRangeSchema.optional(),
11403
+ supportsSharpness: boolean(),
11404
+ sharpness: NormalizedRangeSchema.optional(),
11405
+ supportsMirror: boolean(),
11406
+ supportsFlip: boolean(),
11407
+ /** Supported rotation values. Empty → rotation not configurable. */
11408
+ rotateOptions: array(ImageRotateSchema),
11409
+ /** Supported white-balance modes. Empty → white-balance not configurable. */
11410
+ whiteBalanceModes: array(WhiteBalanceModeSchema),
11411
+ supportsWarmth: boolean(),
11412
+ /** Present when `supportsWarmth` — the normalized 0–100 range. */
11413
+ warmth: NormalizedRangeSchema.optional(),
11414
+ /** Supported exposure modes. Empty → exposure not configurable. */
11415
+ exposureModes: array(ExposureModeSchema),
11416
+ /** Supported backlight modes. Empty → backlight-compensation not configurable. */
11417
+ backlightModes: array(BacklightModeSchema)
11418
+ });
11419
+ /**
11420
+ * Partial change to the image config — every field optional. Slider values
11421
+ * are normalized 0–100. A provider ignores fields it does not support.
11422
+ */
11423
+ var ImageSettingsPatchSchema = object({
11424
+ brightness: number().optional(),
11425
+ contrast: number().optional(),
11426
+ saturation: number().optional(),
11427
+ sharpness: number().optional(),
11428
+ mirror: boolean().optional(),
11429
+ flip: boolean().optional(),
11430
+ rotate: ImageRotateSchema.optional(),
11431
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11432
+ warmth: number().optional(),
11433
+ exposureMode: ExposureModeSchema.optional(),
11434
+ backlightMode: BacklightModeSchema.optional()
11435
+ });
11436
+ var imageSettingsCapability = {
11437
+ name: "image-settings",
11438
+ scope: "device",
11439
+ deviceNative: true,
11440
+ mode: "singleton",
11441
+ deviceTypes: [DeviceType.Camera],
11442
+ deviceConfig: { ui: {
11443
+ kind: "derived-form",
11444
+ builderId: "image-settings",
11445
+ tab: "image"
11446
+ } },
11447
+ methods: {
11448
+ getOptions: method(object({ deviceId: number() }), ImageSettingsOptionsSchema),
11449
+ setSettings: method(object({
11450
+ deviceId: number(),
11451
+ settings: ImageSettingsPatchSchema
11452
+ }), _void(), {
11453
+ kind: "mutation",
11454
+ auth: "admin"
11455
+ })
11456
+ },
11457
+ status: {
11458
+ schema: ImageSettingsStatusSchema,
11459
+ kind: "poll"
11460
+ },
11461
+ runtimeState: ImageSettingsStatusSchema
11462
+ };
11463
+ /**
11204
11464
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
11205
11465
  * with a mowing lifecycle plus a dock action.
11206
11466
  *
@@ -12199,6 +12459,16 @@ var RunnerCameraConfigSchema = object({
12199
12459
  * this gate is bypassed.
12200
12460
  */
12201
12461
  onboardMotionDrivesAnalyzer: boolean().default(true),
12462
+ /**
12463
+ * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
12464
+ * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
12465
+ * this is off by default because the recheck re-subscribes a detection session
12466
+ * every N seconds while `watching`, a major source of pull-decoder re-dial
12467
+ * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
12468
+ * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
12469
+ * (and only render) when this is enabled.
12470
+ */
12471
+ occupancyRecheckEnabled: boolean().default(false),
12202
12472
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
12203
12473
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
12204
12474
  /**
@@ -14204,6 +14474,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14204
14474
  contact: contactCapability,
14205
14475
  control: controlCapability,
14206
14476
  cover: coverCapability,
14477
+ dayNight: dayNightCapability,
14207
14478
  deviceDiscovery: deviceDiscoveryCapability,
14208
14479
  deviceStatus: deviceStatusCapability,
14209
14480
  doorbell: doorbellCapability,
@@ -14216,6 +14487,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14216
14487
  humidifier: humidifierCapability,
14217
14488
  humiditySensor: humiditySensorCapability,
14218
14489
  image: imageCapability,
14490
+ imageSettings: imageSettingsCapability,
14219
14491
  lawnMowerControl: lawnMowerControlCapability,
14220
14492
  lockControl: lockControlCapability,
14221
14493
  mediaPlayer: mediaPlayerCapability,
@@ -16179,7 +16451,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
16179
16451
  id: string(),
16180
16452
  name: string(),
16181
16453
  isPullMode: boolean().optional(),
16182
- priority: number().optional()
16454
+ priority: number().optional(),
16455
+ hwaccel: string().optional(),
16456
+ probedBestHwaccel: string().optional()
16183
16457
  })), method(DecoderSessionConfigSchema, object({
16184
16458
  sessionId: string(),
16185
16459
  nodeId: string()
@@ -22291,6 +22565,18 @@ Object.freeze({
22291
22565
  addonId: null,
22292
22566
  access: "view"
22293
22567
  },
22568
+ "dayNight.getOptions": {
22569
+ capName: "day-night",
22570
+ capScope: "device",
22571
+ addonId: null,
22572
+ access: "view"
22573
+ },
22574
+ "dayNight.setSettings": {
22575
+ capName: "day-night",
22576
+ capScope: "device",
22577
+ addonId: null,
22578
+ access: "create"
22579
+ },
22294
22580
  "decoder.createSession": {
22295
22581
  capName: "decoder",
22296
22582
  capScope: "system",
@@ -23221,6 +23507,18 @@ Object.freeze({
23221
23507
  addonId: null,
23222
23508
  access: "create"
23223
23509
  },
23510
+ "imageSettings.getOptions": {
23511
+ capName: "image-settings",
23512
+ capScope: "device",
23513
+ addonId: null,
23514
+ access: "view"
23515
+ },
23516
+ "imageSettings.setSettings": {
23517
+ capName: "image-settings",
23518
+ capScope: "device",
23519
+ addonId: null,
23520
+ access: "create"
23521
+ },
23224
23522
  "integrations.create": {
23225
23523
  capName: "integrations",
23226
23524
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homeassistant",
3
- "version": "1.1.19",
3
+ "version": "1.1.21",
4
4
  "description": "Home Assistant device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",