@camstack/addon-provider-homematic 1.1.16 → 1.1.18

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
@@ -4651,7 +4651,7 @@ function preprocess(fn, schema) {
4651
4651
  });
4652
4652
  }
4653
4653
  //#endregion
4654
- //#region ../types/dist/sleep-BiDFW0E7.mjs
4654
+ //#region ../types/dist/sleep-CZDdRBua.mjs
4655
4655
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4656
4656
  EventCategory["SystemBoot"] = "system.boot";
4657
4657
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -7262,7 +7262,16 @@ var DecoderStatsSchema = object({
7262
7262
  inputFps: number(),
7263
7263
  outputFps: number(),
7264
7264
  avgDecodeTimeMs: number(),
7265
- droppedFrames: number()
7265
+ droppedFrames: number(),
7266
+ /**
7267
+ * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
7268
+ * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
7269
+ * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
7270
+ * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
7271
+ */
7272
+ lagMs: number().optional(),
7273
+ effectiveFps: number().optional(),
7274
+ adaptiveFps: number().optional()
7266
7275
  });
7267
7276
  var DecoderSessionConfigSchema = object({
7268
7277
  codec: string(),
@@ -7303,7 +7312,15 @@ var DecoderSessionConfigSchema = object({
7303
7312
  * other — `pullFrames` returns nothing for an `'shm'` session and
7304
7313
  * `pullHandles` returns nothing for a `'callback'` session.
7305
7314
  */
7306
- frameSink: _enum(["callback", "shm"]).default("callback")
7315
+ frameSink: _enum(["callback", "shm"]).default("callback"),
7316
+ /**
7317
+ * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
7318
+ * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
7319
+ * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
7320
+ * stream-broker's `streamingDebug` gate — off by default so production logs
7321
+ * stay quiet and the emit path pays zero per-frame cost when disabled.
7322
+ */
7323
+ debug: boolean().optional()
7307
7324
  });
7308
7325
  var EncodeProfileSchema = object({
7309
7326
  video: object({
@@ -10328,6 +10345,100 @@ var coverCapability = {
10328
10345
  runtimeState: CoverStatusSchema
10329
10346
  };
10330
10347
  /**
10348
+ * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
10349
+ * shared by reolink / hikvision / amcrest. Models the common firmware
10350
+ * surface: the IR-cut switching MODE plus the two knobs that gate it
10351
+ * (photocell `sensitivity` + `switchDelaySec`). Each vendor maps these
10352
+ * onto its own ISAPI / Baichuan / Dahua-CGI fields; the cap standardises
10353
+ * the shape so ONE derived-form renders every camera.
10354
+ *
10355
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
10356
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
10357
+ * injected from `status`) reports the live values, and a single
10358
+ * `setSettings` mutation applies a partial change. No hand-written
10359
+ * settings-contribution methods — the framework derives the UI + save
10360
+ * routing from this surface.
10361
+ */
10362
+ /** IR-cut switching mode. `schedule` = time-of-day table configured on the camera. */
10363
+ var DayNightModeSchema = _enum([
10364
+ "auto",
10365
+ "day",
10366
+ "night",
10367
+ "schedule"
10368
+ ]);
10369
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
10370
+ * getOptions availability convention. Normalized values are 0–100. */
10371
+ var NormalizedRangeSchema$1 = object({
10372
+ min: number(),
10373
+ max: number(),
10374
+ step: number()
10375
+ });
10376
+ /**
10377
+ * Current day/night state. Optional fields are absent when the camera
10378
+ * does not expose that knob (a photocell-less model reports no
10379
+ * `sensitivity`). `lastFetchedAt` feeds the runtime-state bridge.
10380
+ */
10381
+ var DayNightStatusSchema = object({
10382
+ mode: DayNightModeSchema,
10383
+ /** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
10384
+ sensitivity: number().optional(),
10385
+ /** Delay before the IR-cut filter flips, in seconds. */
10386
+ switchDelaySec: number().optional(),
10387
+ lastFetchedAt: number()
10388
+ });
10389
+ /**
10390
+ * Per-camera availability descriptor — drives which controls the admin UI
10391
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
10392
+ * (normalized 0–100); the mode choice-set as an array. A provider returns
10393
+ * honest, camera-probed values — never hardcoded.
10394
+ */
10395
+ var DayNightOptionsSchema = object({
10396
+ /** Modes this camera accepts. Empty → the camera has no configurable day/night mode. */
10397
+ modes: array(DayNightModeSchema),
10398
+ supportsSensitivity: boolean(),
10399
+ /** Present when `supportsSensitivity` — the normalized 0–100 range. */
10400
+ sensitivity: NormalizedRangeSchema$1.optional(),
10401
+ supportsSwitchDelay: boolean(),
10402
+ /** Present when `supportsSwitchDelay` — the allowed delay range in seconds. */
10403
+ switchDelaySec: NormalizedRangeSchema$1.optional()
10404
+ });
10405
+ /**
10406
+ * Partial change to the day/night config — every field optional. A
10407
+ * provider ignores fields it does not support.
10408
+ */
10409
+ var DayNightSettingsPatchSchema = object({
10410
+ mode: DayNightModeSchema.optional(),
10411
+ sensitivity: number().optional(),
10412
+ switchDelaySec: number().optional()
10413
+ });
10414
+ var dayNightCapability = {
10415
+ name: "day-night",
10416
+ scope: "device",
10417
+ deviceNative: true,
10418
+ mode: "singleton",
10419
+ deviceTypes: [DeviceType.Camera],
10420
+ deviceConfig: { ui: {
10421
+ kind: "derived-form",
10422
+ builderId: "day-night",
10423
+ tab: "image"
10424
+ } },
10425
+ methods: {
10426
+ getOptions: method(object({ deviceId: number() }), DayNightOptionsSchema),
10427
+ setSettings: method(object({
10428
+ deviceId: number(),
10429
+ settings: DayNightSettingsPatchSchema
10430
+ }), _void(), {
10431
+ kind: "mutation",
10432
+ auth: "admin"
10433
+ })
10434
+ },
10435
+ status: {
10436
+ schema: DayNightStatusSchema,
10437
+ kind: "poll"
10438
+ },
10439
+ runtimeState: DayNightStatusSchema
10440
+ };
10441
+ /**
10331
10442
  * Identity envelope for a device's upstream-system metadata.
10332
10443
  *
10333
10444
  * Two jobs:
@@ -10986,6 +11097,155 @@ var imageCapability = {
10986
11097
  runtimeState: ImageStatusSchema
10987
11098
  };
10988
11099
  /**
11100
+ * Vendor-neutral image / picture-adjustment cap — the per-camera config
11101
+ * cap shared by reolink / hikvision / amcrest. Models the common ISP
11102
+ * surface: the four picture sliders (brightness / contrast / saturation /
11103
+ * sharpness), orientation (mirror / flip / rotate), white-balance,
11104
+ * exposure and backlight-compensation modes.
11105
+ *
11106
+ * NORMALIZATION: every slider is a normalized int 0–100. Vendors expose
11107
+ * these natively as 0–100 or 0–255 (or other ranges); each provider maps
11108
+ * its native range to/from this normalized 0–100 space so the cap surface
11109
+ * (and the derived form) is identical across cameras. `warmth` (manual
11110
+ * white-balance) is likewise normalized 0–100.
11111
+ *
11112
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
11113
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
11114
+ * injected from `status`) reports the live values, and a single
11115
+ * `setSettings` mutation applies a partial change. No hand-written
11116
+ * settings-contribution methods — the framework derives the UI + save
11117
+ * routing from this surface.
11118
+ */
11119
+ /** Sensor/image rotation, degrees clockwise. */
11120
+ var ImageRotateSchema = _enum([
11121
+ "0",
11122
+ "90",
11123
+ "180",
11124
+ "270"
11125
+ ]);
11126
+ /** White-balance mode. `manual` unlocks the normalized `warmth` knob. */
11127
+ var WhiteBalanceModeSchema = _enum(["auto", "manual"]);
11128
+ /** Exposure mode. */
11129
+ var ExposureModeSchema = _enum(["auto", "manual"]);
11130
+ /**
11131
+ * Backlight-compensation mode:
11132
+ * - `off` — disabled
11133
+ * - `blc` — backlight compensation
11134
+ * - `wdr` — wide dynamic range
11135
+ * - `hlc` — highlight compensation
11136
+ */
11137
+ var BacklightModeSchema = _enum([
11138
+ "off",
11139
+ "blc",
11140
+ "wdr",
11141
+ "hlc"
11142
+ ]);
11143
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
11144
+ * getOptions availability convention. Slider values are normalized 0–100. */
11145
+ var NormalizedRangeSchema = object({
11146
+ min: number(),
11147
+ max: number(),
11148
+ step: number()
11149
+ });
11150
+ /**
11151
+ * Current image-adjustment state. Every field optional — absent when the
11152
+ * camera does not expose that control. Slider values are NORMALIZED 0–100.
11153
+ * `lastFetchedAt` feeds the runtime-state bridge.
11154
+ */
11155
+ var ImageSettingsStatusSchema = object({
11156
+ /** Normalized 0–100. */
11157
+ brightness: number().optional(),
11158
+ /** Normalized 0–100. */
11159
+ contrast: number().optional(),
11160
+ /** Normalized 0–100. */
11161
+ saturation: number().optional(),
11162
+ /** Normalized 0–100. */
11163
+ sharpness: number().optional(),
11164
+ mirror: boolean().optional(),
11165
+ flip: boolean().optional(),
11166
+ rotate: ImageRotateSchema.optional(),
11167
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11168
+ /** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
11169
+ warmth: number().optional(),
11170
+ exposureMode: ExposureModeSchema.optional(),
11171
+ backlightMode: BacklightModeSchema.optional(),
11172
+ lastFetchedAt: number()
11173
+ });
11174
+ /**
11175
+ * Per-camera availability descriptor — drives which controls the admin UI
11176
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
11177
+ * (the normalized 0–100 range); enums as arrays of supported values (empty
11178
+ * array → control hidden). A provider returns honest, camera-probed values
11179
+ * — never hardcoded.
11180
+ */
11181
+ var ImageSettingsOptionsSchema = object({
11182
+ supportsBrightness: boolean(),
11183
+ brightness: NormalizedRangeSchema.optional(),
11184
+ supportsContrast: boolean(),
11185
+ contrast: NormalizedRangeSchema.optional(),
11186
+ supportsSaturation: boolean(),
11187
+ saturation: NormalizedRangeSchema.optional(),
11188
+ supportsSharpness: boolean(),
11189
+ sharpness: NormalizedRangeSchema.optional(),
11190
+ supportsMirror: boolean(),
11191
+ supportsFlip: boolean(),
11192
+ /** Supported rotation values. Empty → rotation not configurable. */
11193
+ rotateOptions: array(ImageRotateSchema),
11194
+ /** Supported white-balance modes. Empty → white-balance not configurable. */
11195
+ whiteBalanceModes: array(WhiteBalanceModeSchema),
11196
+ supportsWarmth: boolean(),
11197
+ /** Present when `supportsWarmth` — the normalized 0–100 range. */
11198
+ warmth: NormalizedRangeSchema.optional(),
11199
+ /** Supported exposure modes. Empty → exposure not configurable. */
11200
+ exposureModes: array(ExposureModeSchema),
11201
+ /** Supported backlight modes. Empty → backlight-compensation not configurable. */
11202
+ backlightModes: array(BacklightModeSchema)
11203
+ });
11204
+ /**
11205
+ * Partial change to the image config — every field optional. Slider values
11206
+ * are normalized 0–100. A provider ignores fields it does not support.
11207
+ */
11208
+ var ImageSettingsPatchSchema = object({
11209
+ brightness: number().optional(),
11210
+ contrast: number().optional(),
11211
+ saturation: number().optional(),
11212
+ sharpness: number().optional(),
11213
+ mirror: boolean().optional(),
11214
+ flip: boolean().optional(),
11215
+ rotate: ImageRotateSchema.optional(),
11216
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11217
+ warmth: number().optional(),
11218
+ exposureMode: ExposureModeSchema.optional(),
11219
+ backlightMode: BacklightModeSchema.optional()
11220
+ });
11221
+ var imageSettingsCapability = {
11222
+ name: "image-settings",
11223
+ scope: "device",
11224
+ deviceNative: true,
11225
+ mode: "singleton",
11226
+ deviceTypes: [DeviceType.Camera],
11227
+ deviceConfig: { ui: {
11228
+ kind: "derived-form",
11229
+ builderId: "image-settings",
11230
+ tab: "image"
11231
+ } },
11232
+ methods: {
11233
+ getOptions: method(object({ deviceId: number() }), ImageSettingsOptionsSchema),
11234
+ setSettings: method(object({
11235
+ deviceId: number(),
11236
+ settings: ImageSettingsPatchSchema
11237
+ }), _void(), {
11238
+ kind: "mutation",
11239
+ auth: "admin"
11240
+ })
11241
+ },
11242
+ status: {
11243
+ schema: ImageSettingsStatusSchema,
11244
+ kind: "poll"
11245
+ },
11246
+ runtimeState: ImageSettingsStatusSchema
11247
+ };
11248
+ /**
10989
11249
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10990
11250
  * with a mowing lifecycle plus a dock action.
10991
11251
  *
@@ -11984,6 +12244,16 @@ var RunnerCameraConfigSchema = object({
11984
12244
  * this gate is bypassed.
11985
12245
  */
11986
12246
  onboardMotionDrivesAnalyzer: boolean().default(true),
12247
+ /**
12248
+ * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
12249
+ * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
12250
+ * this is off by default because the recheck re-subscribes a detection session
12251
+ * every N seconds while `watching`, a major source of pull-decoder re-dial
12252
+ * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
12253
+ * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
12254
+ * (and only render) when this is enabled.
12255
+ */
12256
+ occupancyRecheckEnabled: boolean().default(false),
11987
12257
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
11988
12258
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
11989
12259
  /**
@@ -13989,6 +14259,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
13989
14259
  contact: contactCapability,
13990
14260
  control: controlCapability,
13991
14261
  cover: coverCapability,
14262
+ dayNight: dayNightCapability,
13992
14263
  deviceDiscovery: deviceDiscoveryCapability,
13993
14264
  deviceStatus: deviceStatusCapability,
13994
14265
  doorbell: doorbellCapability,
@@ -14001,6 +14272,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14001
14272
  humidifier: humidifierCapability,
14002
14273
  humiditySensor: humiditySensorCapability,
14003
14274
  image: imageCapability,
14275
+ imageSettings: imageSettingsCapability,
14004
14276
  lawnMowerControl: lawnMowerControlCapability,
14005
14277
  lockControl: lockControlCapability,
14006
14278
  mediaPlayer: mediaPlayerCapability,
@@ -15964,7 +16236,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
15964
16236
  id: string(),
15965
16237
  name: string(),
15966
16238
  isPullMode: boolean().optional(),
15967
- priority: number().optional()
16239
+ priority: number().optional(),
16240
+ hwaccel: string().optional(),
16241
+ probedBestHwaccel: string().optional()
15968
16242
  })), method(DecoderSessionConfigSchema, object({
15969
16243
  sessionId: string(),
15970
16244
  nodeId: string()
@@ -21973,6 +22247,18 @@ Object.freeze({
21973
22247
  addonId: null,
21974
22248
  access: "view"
21975
22249
  },
22250
+ "dayNight.getOptions": {
22251
+ capName: "day-night",
22252
+ capScope: "device",
22253
+ addonId: null,
22254
+ access: "view"
22255
+ },
22256
+ "dayNight.setSettings": {
22257
+ capName: "day-night",
22258
+ capScope: "device",
22259
+ addonId: null,
22260
+ access: "create"
22261
+ },
21976
22262
  "decoder.createSession": {
21977
22263
  capName: "decoder",
21978
22264
  capScope: "system",
@@ -22903,6 +23189,18 @@ Object.freeze({
22903
23189
  addonId: null,
22904
23190
  access: "create"
22905
23191
  },
23192
+ "imageSettings.getOptions": {
23193
+ capName: "image-settings",
23194
+ capScope: "device",
23195
+ addonId: null,
23196
+ access: "view"
23197
+ },
23198
+ "imageSettings.setSettings": {
23199
+ capName: "image-settings",
23200
+ capScope: "device",
23201
+ addonId: null,
23202
+ access: "create"
23203
+ },
22906
23204
  "integrations.create": {
22907
23205
  capName: "integrations",
22908
23206
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -4652,7 +4652,7 @@ function preprocess(fn, schema) {
4652
4652
  });
4653
4653
  }
4654
4654
  //#endregion
4655
- //#region ../types/dist/sleep-BiDFW0E7.mjs
4655
+ //#region ../types/dist/sleep-CZDdRBua.mjs
4656
4656
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4657
4657
  EventCategory["SystemBoot"] = "system.boot";
4658
4658
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -7263,7 +7263,16 @@ var DecoderStatsSchema = object({
7263
7263
  inputFps: number(),
7264
7264
  outputFps: number(),
7265
7265
  avgDecodeTimeMs: number(),
7266
- droppedFrames: number()
7266
+ droppedFrames: number(),
7267
+ /**
7268
+ * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
7269
+ * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
7270
+ * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
7271
+ * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
7272
+ */
7273
+ lagMs: number().optional(),
7274
+ effectiveFps: number().optional(),
7275
+ adaptiveFps: number().optional()
7267
7276
  });
7268
7277
  var DecoderSessionConfigSchema = object({
7269
7278
  codec: string(),
@@ -7304,7 +7313,15 @@ var DecoderSessionConfigSchema = object({
7304
7313
  * other — `pullFrames` returns nothing for an `'shm'` session and
7305
7314
  * `pullHandles` returns nothing for a `'callback'` session.
7306
7315
  */
7307
- frameSink: _enum(["callback", "shm"]).default("callback")
7316
+ frameSink: _enum(["callback", "shm"]).default("callback"),
7317
+ /**
7318
+ * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
7319
+ * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
7320
+ * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
7321
+ * stream-broker's `streamingDebug` gate — off by default so production logs
7322
+ * stay quiet and the emit path pays zero per-frame cost when disabled.
7323
+ */
7324
+ debug: boolean().optional()
7308
7325
  });
7309
7326
  var EncodeProfileSchema = object({
7310
7327
  video: object({
@@ -10329,6 +10346,100 @@ var coverCapability = {
10329
10346
  runtimeState: CoverStatusSchema
10330
10347
  };
10331
10348
  /**
10349
+ * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
10350
+ * shared by reolink / hikvision / amcrest. Models the common firmware
10351
+ * surface: the IR-cut switching MODE plus the two knobs that gate it
10352
+ * (photocell `sensitivity` + `switchDelaySec`). Each vendor maps these
10353
+ * onto its own ISAPI / Baichuan / Dahua-CGI fields; the cap standardises
10354
+ * the shape so ONE derived-form renders every camera.
10355
+ *
10356
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
10357
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
10358
+ * injected from `status`) reports the live values, and a single
10359
+ * `setSettings` mutation applies a partial change. No hand-written
10360
+ * settings-contribution methods — the framework derives the UI + save
10361
+ * routing from this surface.
10362
+ */
10363
+ /** IR-cut switching mode. `schedule` = time-of-day table configured on the camera. */
10364
+ var DayNightModeSchema = _enum([
10365
+ "auto",
10366
+ "day",
10367
+ "night",
10368
+ "schedule"
10369
+ ]);
10370
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
10371
+ * getOptions availability convention. Normalized values are 0–100. */
10372
+ var NormalizedRangeSchema$1 = object({
10373
+ min: number(),
10374
+ max: number(),
10375
+ step: number()
10376
+ });
10377
+ /**
10378
+ * Current day/night state. Optional fields are absent when the camera
10379
+ * does not expose that knob (a photocell-less model reports no
10380
+ * `sensitivity`). `lastFetchedAt` feeds the runtime-state bridge.
10381
+ */
10382
+ var DayNightStatusSchema = object({
10383
+ mode: DayNightModeSchema,
10384
+ /** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
10385
+ sensitivity: number().optional(),
10386
+ /** Delay before the IR-cut filter flips, in seconds. */
10387
+ switchDelaySec: number().optional(),
10388
+ lastFetchedAt: number()
10389
+ });
10390
+ /**
10391
+ * Per-camera availability descriptor — drives which controls the admin UI
10392
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
10393
+ * (normalized 0–100); the mode choice-set as an array. A provider returns
10394
+ * honest, camera-probed values — never hardcoded.
10395
+ */
10396
+ var DayNightOptionsSchema = object({
10397
+ /** Modes this camera accepts. Empty → the camera has no configurable day/night mode. */
10398
+ modes: array(DayNightModeSchema),
10399
+ supportsSensitivity: boolean(),
10400
+ /** Present when `supportsSensitivity` — the normalized 0–100 range. */
10401
+ sensitivity: NormalizedRangeSchema$1.optional(),
10402
+ supportsSwitchDelay: boolean(),
10403
+ /** Present when `supportsSwitchDelay` — the allowed delay range in seconds. */
10404
+ switchDelaySec: NormalizedRangeSchema$1.optional()
10405
+ });
10406
+ /**
10407
+ * Partial change to the day/night config — every field optional. A
10408
+ * provider ignores fields it does not support.
10409
+ */
10410
+ var DayNightSettingsPatchSchema = object({
10411
+ mode: DayNightModeSchema.optional(),
10412
+ sensitivity: number().optional(),
10413
+ switchDelaySec: number().optional()
10414
+ });
10415
+ var dayNightCapability = {
10416
+ name: "day-night",
10417
+ scope: "device",
10418
+ deviceNative: true,
10419
+ mode: "singleton",
10420
+ deviceTypes: [DeviceType.Camera],
10421
+ deviceConfig: { ui: {
10422
+ kind: "derived-form",
10423
+ builderId: "day-night",
10424
+ tab: "image"
10425
+ } },
10426
+ methods: {
10427
+ getOptions: method(object({ deviceId: number() }), DayNightOptionsSchema),
10428
+ setSettings: method(object({
10429
+ deviceId: number(),
10430
+ settings: DayNightSettingsPatchSchema
10431
+ }), _void(), {
10432
+ kind: "mutation",
10433
+ auth: "admin"
10434
+ })
10435
+ },
10436
+ status: {
10437
+ schema: DayNightStatusSchema,
10438
+ kind: "poll"
10439
+ },
10440
+ runtimeState: DayNightStatusSchema
10441
+ };
10442
+ /**
10332
10443
  * Identity envelope for a device's upstream-system metadata.
10333
10444
  *
10334
10445
  * Two jobs:
@@ -10987,6 +11098,155 @@ var imageCapability = {
10987
11098
  runtimeState: ImageStatusSchema
10988
11099
  };
10989
11100
  /**
11101
+ * Vendor-neutral image / picture-adjustment cap — the per-camera config
11102
+ * cap shared by reolink / hikvision / amcrest. Models the common ISP
11103
+ * surface: the four picture sliders (brightness / contrast / saturation /
11104
+ * sharpness), orientation (mirror / flip / rotate), white-balance,
11105
+ * exposure and backlight-compensation modes.
11106
+ *
11107
+ * NORMALIZATION: every slider is a normalized int 0–100. Vendors expose
11108
+ * these natively as 0–100 or 0–255 (or other ranges); each provider maps
11109
+ * its native range to/from this normalized 0–100 space so the cap surface
11110
+ * (and the derived form) is identical across cameras. `warmth` (manual
11111
+ * white-balance) is likewise normalized 0–100.
11112
+ *
11113
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
11114
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
11115
+ * injected from `status`) reports the live values, and a single
11116
+ * `setSettings` mutation applies a partial change. No hand-written
11117
+ * settings-contribution methods — the framework derives the UI + save
11118
+ * routing from this surface.
11119
+ */
11120
+ /** Sensor/image rotation, degrees clockwise. */
11121
+ var ImageRotateSchema = _enum([
11122
+ "0",
11123
+ "90",
11124
+ "180",
11125
+ "270"
11126
+ ]);
11127
+ /** White-balance mode. `manual` unlocks the normalized `warmth` knob. */
11128
+ var WhiteBalanceModeSchema = _enum(["auto", "manual"]);
11129
+ /** Exposure mode. */
11130
+ var ExposureModeSchema = _enum(["auto", "manual"]);
11131
+ /**
11132
+ * Backlight-compensation mode:
11133
+ * - `off` — disabled
11134
+ * - `blc` — backlight compensation
11135
+ * - `wdr` — wide dynamic range
11136
+ * - `hlc` — highlight compensation
11137
+ */
11138
+ var BacklightModeSchema = _enum([
11139
+ "off",
11140
+ "blc",
11141
+ "wdr",
11142
+ "hlc"
11143
+ ]);
11144
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
11145
+ * getOptions availability convention. Slider values are normalized 0–100. */
11146
+ var NormalizedRangeSchema = object({
11147
+ min: number(),
11148
+ max: number(),
11149
+ step: number()
11150
+ });
11151
+ /**
11152
+ * Current image-adjustment state. Every field optional — absent when the
11153
+ * camera does not expose that control. Slider values are NORMALIZED 0–100.
11154
+ * `lastFetchedAt` feeds the runtime-state bridge.
11155
+ */
11156
+ var ImageSettingsStatusSchema = object({
11157
+ /** Normalized 0–100. */
11158
+ brightness: number().optional(),
11159
+ /** Normalized 0–100. */
11160
+ contrast: number().optional(),
11161
+ /** Normalized 0–100. */
11162
+ saturation: number().optional(),
11163
+ /** Normalized 0–100. */
11164
+ sharpness: number().optional(),
11165
+ mirror: boolean().optional(),
11166
+ flip: boolean().optional(),
11167
+ rotate: ImageRotateSchema.optional(),
11168
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11169
+ /** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
11170
+ warmth: number().optional(),
11171
+ exposureMode: ExposureModeSchema.optional(),
11172
+ backlightMode: BacklightModeSchema.optional(),
11173
+ lastFetchedAt: number()
11174
+ });
11175
+ /**
11176
+ * Per-camera availability descriptor — drives which controls the admin UI
11177
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
11178
+ * (the normalized 0–100 range); enums as arrays of supported values (empty
11179
+ * array → control hidden). A provider returns honest, camera-probed values
11180
+ * — never hardcoded.
11181
+ */
11182
+ var ImageSettingsOptionsSchema = object({
11183
+ supportsBrightness: boolean(),
11184
+ brightness: NormalizedRangeSchema.optional(),
11185
+ supportsContrast: boolean(),
11186
+ contrast: NormalizedRangeSchema.optional(),
11187
+ supportsSaturation: boolean(),
11188
+ saturation: NormalizedRangeSchema.optional(),
11189
+ supportsSharpness: boolean(),
11190
+ sharpness: NormalizedRangeSchema.optional(),
11191
+ supportsMirror: boolean(),
11192
+ supportsFlip: boolean(),
11193
+ /** Supported rotation values. Empty → rotation not configurable. */
11194
+ rotateOptions: array(ImageRotateSchema),
11195
+ /** Supported white-balance modes. Empty → white-balance not configurable. */
11196
+ whiteBalanceModes: array(WhiteBalanceModeSchema),
11197
+ supportsWarmth: boolean(),
11198
+ /** Present when `supportsWarmth` — the normalized 0–100 range. */
11199
+ warmth: NormalizedRangeSchema.optional(),
11200
+ /** Supported exposure modes. Empty → exposure not configurable. */
11201
+ exposureModes: array(ExposureModeSchema),
11202
+ /** Supported backlight modes. Empty → backlight-compensation not configurable. */
11203
+ backlightModes: array(BacklightModeSchema)
11204
+ });
11205
+ /**
11206
+ * Partial change to the image config — every field optional. Slider values
11207
+ * are normalized 0–100. A provider ignores fields it does not support.
11208
+ */
11209
+ var ImageSettingsPatchSchema = object({
11210
+ brightness: number().optional(),
11211
+ contrast: number().optional(),
11212
+ saturation: number().optional(),
11213
+ sharpness: number().optional(),
11214
+ mirror: boolean().optional(),
11215
+ flip: boolean().optional(),
11216
+ rotate: ImageRotateSchema.optional(),
11217
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11218
+ warmth: number().optional(),
11219
+ exposureMode: ExposureModeSchema.optional(),
11220
+ backlightMode: BacklightModeSchema.optional()
11221
+ });
11222
+ var imageSettingsCapability = {
11223
+ name: "image-settings",
11224
+ scope: "device",
11225
+ deviceNative: true,
11226
+ mode: "singleton",
11227
+ deviceTypes: [DeviceType.Camera],
11228
+ deviceConfig: { ui: {
11229
+ kind: "derived-form",
11230
+ builderId: "image-settings",
11231
+ tab: "image"
11232
+ } },
11233
+ methods: {
11234
+ getOptions: method(object({ deviceId: number() }), ImageSettingsOptionsSchema),
11235
+ setSettings: method(object({
11236
+ deviceId: number(),
11237
+ settings: ImageSettingsPatchSchema
11238
+ }), _void(), {
11239
+ kind: "mutation",
11240
+ auth: "admin"
11241
+ })
11242
+ },
11243
+ status: {
11244
+ schema: ImageSettingsStatusSchema,
11245
+ kind: "poll"
11246
+ },
11247
+ runtimeState: ImageSettingsStatusSchema
11248
+ };
11249
+ /**
10990
11250
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10991
11251
  * with a mowing lifecycle plus a dock action.
10992
11252
  *
@@ -11985,6 +12245,16 @@ var RunnerCameraConfigSchema = object({
11985
12245
  * this gate is bypassed.
11986
12246
  */
11987
12247
  onboardMotionDrivesAnalyzer: boolean().default(true),
12248
+ /**
12249
+ * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
12250
+ * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
12251
+ * this is off by default because the recheck re-subscribes a detection session
12252
+ * every N seconds while `watching`, a major source of pull-decoder re-dial
12253
+ * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
12254
+ * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
12255
+ * (and only render) when this is enabled.
12256
+ */
12257
+ occupancyRecheckEnabled: boolean().default(false),
11988
12258
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
11989
12259
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
11990
12260
  /**
@@ -13990,6 +14260,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
13990
14260
  contact: contactCapability,
13991
14261
  control: controlCapability,
13992
14262
  cover: coverCapability,
14263
+ dayNight: dayNightCapability,
13993
14264
  deviceDiscovery: deviceDiscoveryCapability,
13994
14265
  deviceStatus: deviceStatusCapability,
13995
14266
  doorbell: doorbellCapability,
@@ -14002,6 +14273,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
14002
14273
  humidifier: humidifierCapability,
14003
14274
  humiditySensor: humiditySensorCapability,
14004
14275
  image: imageCapability,
14276
+ imageSettings: imageSettingsCapability,
14005
14277
  lawnMowerControl: lawnMowerControlCapability,
14006
14278
  lockControl: lockControlCapability,
14007
14279
  mediaPlayer: mediaPlayerCapability,
@@ -15965,7 +16237,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
15965
16237
  id: string(),
15966
16238
  name: string(),
15967
16239
  isPullMode: boolean().optional(),
15968
- priority: number().optional()
16240
+ priority: number().optional(),
16241
+ hwaccel: string().optional(),
16242
+ probedBestHwaccel: string().optional()
15969
16243
  })), method(DecoderSessionConfigSchema, object({
15970
16244
  sessionId: string(),
15971
16245
  nodeId: string()
@@ -21974,6 +22248,18 @@ Object.freeze({
21974
22248
  addonId: null,
21975
22249
  access: "view"
21976
22250
  },
22251
+ "dayNight.getOptions": {
22252
+ capName: "day-night",
22253
+ capScope: "device",
22254
+ addonId: null,
22255
+ access: "view"
22256
+ },
22257
+ "dayNight.setSettings": {
22258
+ capName: "day-night",
22259
+ capScope: "device",
22260
+ addonId: null,
22261
+ access: "create"
22262
+ },
21977
22263
  "decoder.createSession": {
21978
22264
  capName: "decoder",
21979
22265
  capScope: "system",
@@ -22904,6 +23190,18 @@ Object.freeze({
22904
23190
  addonId: null,
22905
23191
  access: "create"
22906
23192
  },
23193
+ "imageSettings.getOptions": {
23194
+ capName: "image-settings",
23195
+ capScope: "device",
23196
+ addonId: null,
23197
+ access: "view"
23198
+ },
23199
+ "imageSettings.setSettings": {
23200
+ capName: "image-settings",
23201
+ capScope: "device",
23202
+ addonId: null,
23203
+ access: "create"
23204
+ },
22907
23205
  "integrations.create": {
22908
23206
  capName: "integrations",
22909
23207
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homematic",
3
- "version": "1.1.16",
3
+ "version": "1.1.18",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",