@camstack/addon-provider-petkit 0.1.3 → 0.1.5

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
@@ -4644,7 +4644,7 @@ function preprocess(fn, schema) {
4644
4644
  });
4645
4645
  }
4646
4646
  //#endregion
4647
- //#region ../types/dist/sleep-BiDFW0E7.mjs
4647
+ //#region ../types/dist/sleep-CZDdRBua.mjs
4648
4648
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4649
4649
  EventCategory["SystemBoot"] = "system.boot";
4650
4650
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -7255,7 +7255,16 @@ var DecoderStatsSchema = object({
7255
7255
  inputFps: number(),
7256
7256
  outputFps: number(),
7257
7257
  avgDecodeTimeMs: number(),
7258
- droppedFrames: number()
7258
+ droppedFrames: number(),
7259
+ /**
7260
+ * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
7261
+ * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
7262
+ * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
7263
+ * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
7264
+ */
7265
+ lagMs: number().optional(),
7266
+ effectiveFps: number().optional(),
7267
+ adaptiveFps: number().optional()
7259
7268
  });
7260
7269
  var DecoderSessionConfigSchema = object({
7261
7270
  codec: string(),
@@ -7296,7 +7305,15 @@ var DecoderSessionConfigSchema = object({
7296
7305
  * other — `pullFrames` returns nothing for an `'shm'` session and
7297
7306
  * `pullHandles` returns nothing for a `'callback'` session.
7298
7307
  */
7299
- frameSink: _enum(["callback", "shm"]).default("callback")
7308
+ frameSink: _enum(["callback", "shm"]).default("callback"),
7309
+ /**
7310
+ * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
7311
+ * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
7312
+ * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
7313
+ * stream-broker's `streamingDebug` gate — off by default so production logs
7314
+ * stay quiet and the emit path pays zero per-frame cost when disabled.
7315
+ */
7316
+ debug: boolean().optional()
7300
7317
  });
7301
7318
  var EncodeProfileSchema = object({
7302
7319
  video: object({
@@ -10321,6 +10338,100 @@ var coverCapability = {
10321
10338
  runtimeState: CoverStatusSchema
10322
10339
  };
10323
10340
  /**
10341
+ * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
10342
+ * shared by reolink / hikvision / amcrest. Models the common firmware
10343
+ * surface: the IR-cut switching MODE plus the two knobs that gate it
10344
+ * (photocell `sensitivity` + `switchDelaySec`). Each vendor maps these
10345
+ * onto its own ISAPI / Baichuan / Dahua-CGI fields; the cap standardises
10346
+ * the shape so ONE derived-form renders every camera.
10347
+ *
10348
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
10349
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
10350
+ * injected from `status`) reports the live values, and a single
10351
+ * `setSettings` mutation applies a partial change. No hand-written
10352
+ * settings-contribution methods — the framework derives the UI + save
10353
+ * routing from this surface.
10354
+ */
10355
+ /** IR-cut switching mode. `schedule` = time-of-day table configured on the camera. */
10356
+ var DayNightModeSchema = _enum([
10357
+ "auto",
10358
+ "day",
10359
+ "night",
10360
+ "schedule"
10361
+ ]);
10362
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
10363
+ * getOptions availability convention. Normalized values are 0–100. */
10364
+ var NormalizedRangeSchema$1 = object({
10365
+ min: number(),
10366
+ max: number(),
10367
+ step: number()
10368
+ });
10369
+ /**
10370
+ * Current day/night state. Optional fields are absent when the camera
10371
+ * does not expose that knob (a photocell-less model reports no
10372
+ * `sensitivity`). `lastFetchedAt` feeds the runtime-state bridge.
10373
+ */
10374
+ var DayNightStatusSchema = object({
10375
+ mode: DayNightModeSchema,
10376
+ /** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
10377
+ sensitivity: number().optional(),
10378
+ /** Delay before the IR-cut filter flips, in seconds. */
10379
+ switchDelaySec: number().optional(),
10380
+ lastFetchedAt: number()
10381
+ });
10382
+ /**
10383
+ * Per-camera availability descriptor — drives which controls the admin UI
10384
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
10385
+ * (normalized 0–100); the mode choice-set as an array. A provider returns
10386
+ * honest, camera-probed values — never hardcoded.
10387
+ */
10388
+ var DayNightOptionsSchema = object({
10389
+ /** Modes this camera accepts. Empty → the camera has no configurable day/night mode. */
10390
+ modes: array(DayNightModeSchema),
10391
+ supportsSensitivity: boolean(),
10392
+ /** Present when `supportsSensitivity` — the normalized 0–100 range. */
10393
+ sensitivity: NormalizedRangeSchema$1.optional(),
10394
+ supportsSwitchDelay: boolean(),
10395
+ /** Present when `supportsSwitchDelay` — the allowed delay range in seconds. */
10396
+ switchDelaySec: NormalizedRangeSchema$1.optional()
10397
+ });
10398
+ /**
10399
+ * Partial change to the day/night config — every field optional. A
10400
+ * provider ignores fields it does not support.
10401
+ */
10402
+ var DayNightSettingsPatchSchema = object({
10403
+ mode: DayNightModeSchema.optional(),
10404
+ sensitivity: number().optional(),
10405
+ switchDelaySec: number().optional()
10406
+ });
10407
+ var dayNightCapability = {
10408
+ name: "day-night",
10409
+ scope: "device",
10410
+ deviceNative: true,
10411
+ mode: "singleton",
10412
+ deviceTypes: [DeviceType.Camera],
10413
+ deviceConfig: { ui: {
10414
+ kind: "derived-form",
10415
+ builderId: "day-night",
10416
+ tab: "image"
10417
+ } },
10418
+ methods: {
10419
+ getOptions: method(object({ deviceId: number() }), DayNightOptionsSchema),
10420
+ setSettings: method(object({
10421
+ deviceId: number(),
10422
+ settings: DayNightSettingsPatchSchema
10423
+ }), _void(), {
10424
+ kind: "mutation",
10425
+ auth: "admin"
10426
+ })
10427
+ },
10428
+ status: {
10429
+ schema: DayNightStatusSchema,
10430
+ kind: "poll"
10431
+ },
10432
+ runtimeState: DayNightStatusSchema
10433
+ };
10434
+ /**
10324
10435
  * Identity envelope for a device's upstream-system metadata.
10325
10436
  *
10326
10437
  * Two jobs:
@@ -10979,6 +11090,155 @@ var imageCapability = {
10979
11090
  runtimeState: ImageStatusSchema
10980
11091
  };
10981
11092
  /**
11093
+ * Vendor-neutral image / picture-adjustment cap — the per-camera config
11094
+ * cap shared by reolink / hikvision / amcrest. Models the common ISP
11095
+ * surface: the four picture sliders (brightness / contrast / saturation /
11096
+ * sharpness), orientation (mirror / flip / rotate), white-balance,
11097
+ * exposure and backlight-compensation modes.
11098
+ *
11099
+ * NORMALIZATION: every slider is a normalized int 0–100. Vendors expose
11100
+ * these natively as 0–100 or 0–255 (or other ranges); each provider maps
11101
+ * its native range to/from this normalized 0–100 space so the cap surface
11102
+ * (and the derived form) is identical across cameras. `warmth` (manual
11103
+ * white-balance) is likewise normalized 0–100.
11104
+ *
11105
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
11106
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
11107
+ * injected from `status`) reports the live values, and a single
11108
+ * `setSettings` mutation applies a partial change. No hand-written
11109
+ * settings-contribution methods — the framework derives the UI + save
11110
+ * routing from this surface.
11111
+ */
11112
+ /** Sensor/image rotation, degrees clockwise. */
11113
+ var ImageRotateSchema = _enum([
11114
+ "0",
11115
+ "90",
11116
+ "180",
11117
+ "270"
11118
+ ]);
11119
+ /** White-balance mode. `manual` unlocks the normalized `warmth` knob. */
11120
+ var WhiteBalanceModeSchema = _enum(["auto", "manual"]);
11121
+ /** Exposure mode. */
11122
+ var ExposureModeSchema = _enum(["auto", "manual"]);
11123
+ /**
11124
+ * Backlight-compensation mode:
11125
+ * - `off` — disabled
11126
+ * - `blc` — backlight compensation
11127
+ * - `wdr` — wide dynamic range
11128
+ * - `hlc` — highlight compensation
11129
+ */
11130
+ var BacklightModeSchema = _enum([
11131
+ "off",
11132
+ "blc",
11133
+ "wdr",
11134
+ "hlc"
11135
+ ]);
11136
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
11137
+ * getOptions availability convention. Slider values are normalized 0–100. */
11138
+ var NormalizedRangeSchema = object({
11139
+ min: number(),
11140
+ max: number(),
11141
+ step: number()
11142
+ });
11143
+ /**
11144
+ * Current image-adjustment state. Every field optional — absent when the
11145
+ * camera does not expose that control. Slider values are NORMALIZED 0–100.
11146
+ * `lastFetchedAt` feeds the runtime-state bridge.
11147
+ */
11148
+ var ImageSettingsStatusSchema = object({
11149
+ /** Normalized 0–100. */
11150
+ brightness: number().optional(),
11151
+ /** Normalized 0–100. */
11152
+ contrast: number().optional(),
11153
+ /** Normalized 0–100. */
11154
+ saturation: number().optional(),
11155
+ /** Normalized 0–100. */
11156
+ sharpness: number().optional(),
11157
+ mirror: boolean().optional(),
11158
+ flip: boolean().optional(),
11159
+ rotate: ImageRotateSchema.optional(),
11160
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11161
+ /** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
11162
+ warmth: number().optional(),
11163
+ exposureMode: ExposureModeSchema.optional(),
11164
+ backlightMode: BacklightModeSchema.optional(),
11165
+ lastFetchedAt: number()
11166
+ });
11167
+ /**
11168
+ * Per-camera availability descriptor — drives which controls the admin UI
11169
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
11170
+ * (the normalized 0–100 range); enums as arrays of supported values (empty
11171
+ * array → control hidden). A provider returns honest, camera-probed values
11172
+ * — never hardcoded.
11173
+ */
11174
+ var ImageSettingsOptionsSchema = object({
11175
+ supportsBrightness: boolean(),
11176
+ brightness: NormalizedRangeSchema.optional(),
11177
+ supportsContrast: boolean(),
11178
+ contrast: NormalizedRangeSchema.optional(),
11179
+ supportsSaturation: boolean(),
11180
+ saturation: NormalizedRangeSchema.optional(),
11181
+ supportsSharpness: boolean(),
11182
+ sharpness: NormalizedRangeSchema.optional(),
11183
+ supportsMirror: boolean(),
11184
+ supportsFlip: boolean(),
11185
+ /** Supported rotation values. Empty → rotation not configurable. */
11186
+ rotateOptions: array(ImageRotateSchema),
11187
+ /** Supported white-balance modes. Empty → white-balance not configurable. */
11188
+ whiteBalanceModes: array(WhiteBalanceModeSchema),
11189
+ supportsWarmth: boolean(),
11190
+ /** Present when `supportsWarmth` — the normalized 0–100 range. */
11191
+ warmth: NormalizedRangeSchema.optional(),
11192
+ /** Supported exposure modes. Empty → exposure not configurable. */
11193
+ exposureModes: array(ExposureModeSchema),
11194
+ /** Supported backlight modes. Empty → backlight-compensation not configurable. */
11195
+ backlightModes: array(BacklightModeSchema)
11196
+ });
11197
+ /**
11198
+ * Partial change to the image config — every field optional. Slider values
11199
+ * are normalized 0–100. A provider ignores fields it does not support.
11200
+ */
11201
+ var ImageSettingsPatchSchema = object({
11202
+ brightness: number().optional(),
11203
+ contrast: number().optional(),
11204
+ saturation: number().optional(),
11205
+ sharpness: number().optional(),
11206
+ mirror: boolean().optional(),
11207
+ flip: boolean().optional(),
11208
+ rotate: ImageRotateSchema.optional(),
11209
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11210
+ warmth: number().optional(),
11211
+ exposureMode: ExposureModeSchema.optional(),
11212
+ backlightMode: BacklightModeSchema.optional()
11213
+ });
11214
+ var imageSettingsCapability = {
11215
+ name: "image-settings",
11216
+ scope: "device",
11217
+ deviceNative: true,
11218
+ mode: "singleton",
11219
+ deviceTypes: [DeviceType.Camera],
11220
+ deviceConfig: { ui: {
11221
+ kind: "derived-form",
11222
+ builderId: "image-settings",
11223
+ tab: "image"
11224
+ } },
11225
+ methods: {
11226
+ getOptions: method(object({ deviceId: number() }), ImageSettingsOptionsSchema),
11227
+ setSettings: method(object({
11228
+ deviceId: number(),
11229
+ settings: ImageSettingsPatchSchema
11230
+ }), _void(), {
11231
+ kind: "mutation",
11232
+ auth: "admin"
11233
+ })
11234
+ },
11235
+ status: {
11236
+ schema: ImageSettingsStatusSchema,
11237
+ kind: "poll"
11238
+ },
11239
+ runtimeState: ImageSettingsStatusSchema
11240
+ };
11241
+ /**
10982
11242
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10983
11243
  * with a mowing lifecycle plus a dock action.
10984
11244
  *
@@ -11977,6 +12237,16 @@ var RunnerCameraConfigSchema = object({
11977
12237
  * this gate is bypassed.
11978
12238
  */
11979
12239
  onboardMotionDrivesAnalyzer: boolean().default(true),
12240
+ /**
12241
+ * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
12242
+ * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
12243
+ * this is off by default because the recheck re-subscribes a detection session
12244
+ * every N seconds while `watching`, a major source of pull-decoder re-dial
12245
+ * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
12246
+ * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
12247
+ * (and only render) when this is enabled.
12248
+ */
12249
+ occupancyRecheckEnabled: boolean().default(false),
11980
12250
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
11981
12251
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
11982
12252
  /**
@@ -13982,6 +14252,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
13982
14252
  contact: contactCapability,
13983
14253
  control: controlCapability,
13984
14254
  cover: coverCapability,
14255
+ dayNight: dayNightCapability,
13985
14256
  deviceDiscovery: deviceDiscoveryCapability,
13986
14257
  deviceStatus: deviceStatusCapability,
13987
14258
  doorbell: doorbellCapability,
@@ -13994,6 +14265,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
13994
14265
  humidifier: humidifierCapability,
13995
14266
  humiditySensor: humiditySensorCapability,
13996
14267
  image: imageCapability,
14268
+ imageSettings: imageSettingsCapability,
13997
14269
  lawnMowerControl: lawnMowerControlCapability,
13998
14270
  lockControl: lockControlCapability,
13999
14271
  mediaPlayer: mediaPlayerCapability,
@@ -15908,7 +16180,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
15908
16180
  id: string(),
15909
16181
  name: string(),
15910
16182
  isPullMode: boolean().optional(),
15911
- priority: number().optional()
16183
+ priority: number().optional(),
16184
+ hwaccel: string().optional(),
16185
+ probedBestHwaccel: string().optional()
15912
16186
  })), method(DecoderSessionConfigSchema, object({
15913
16187
  sessionId: string(),
15914
16188
  nodeId: string()
@@ -21917,6 +22191,18 @@ Object.freeze({
21917
22191
  addonId: null,
21918
22192
  access: "view"
21919
22193
  },
22194
+ "dayNight.getOptions": {
22195
+ capName: "day-night",
22196
+ capScope: "device",
22197
+ addonId: null,
22198
+ access: "view"
22199
+ },
22200
+ "dayNight.setSettings": {
22201
+ capName: "day-night",
22202
+ capScope: "device",
22203
+ addonId: null,
22204
+ access: "create"
22205
+ },
21920
22206
  "decoder.createSession": {
21921
22207
  capName: "decoder",
21922
22208
  capScope: "system",
@@ -22847,6 +23133,18 @@ Object.freeze({
22847
23133
  addonId: null,
22848
23134
  access: "create"
22849
23135
  },
23136
+ "imageSettings.getOptions": {
23137
+ capName: "image-settings",
23138
+ capScope: "device",
23139
+ addonId: null,
23140
+ access: "view"
23141
+ },
23142
+ "imageSettings.setSettings": {
23143
+ capName: "image-settings",
23144
+ capScope: "device",
23145
+ addonId: null,
23146
+ access: "create"
23147
+ },
22850
23148
  "integrations.create": {
22851
23149
  capName: "integrations",
22852
23150
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -4643,7 +4643,7 @@ function preprocess(fn, schema) {
4643
4643
  });
4644
4644
  }
4645
4645
  //#endregion
4646
- //#region ../types/dist/sleep-BiDFW0E7.mjs
4646
+ //#region ../types/dist/sleep-CZDdRBua.mjs
4647
4647
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4648
4648
  EventCategory["SystemBoot"] = "system.boot";
4649
4649
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -7254,7 +7254,16 @@ var DecoderStatsSchema = object({
7254
7254
  inputFps: number(),
7255
7255
  outputFps: number(),
7256
7256
  avgDecodeTimeMs: number(),
7257
- droppedFrames: number()
7257
+ droppedFrames: number(),
7258
+ /**
7259
+ * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
7260
+ * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
7261
+ * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
7262
+ * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
7263
+ */
7264
+ lagMs: number().optional(),
7265
+ effectiveFps: number().optional(),
7266
+ adaptiveFps: number().optional()
7258
7267
  });
7259
7268
  var DecoderSessionConfigSchema = object({
7260
7269
  codec: string(),
@@ -7295,7 +7304,15 @@ var DecoderSessionConfigSchema = object({
7295
7304
  * other — `pullFrames` returns nothing for an `'shm'` session and
7296
7305
  * `pullHandles` returns nothing for a `'callback'` session.
7297
7306
  */
7298
- frameSink: _enum(["callback", "shm"]).default("callback")
7307
+ frameSink: _enum(["callback", "shm"]).default("callback"),
7308
+ /**
7309
+ * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
7310
+ * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
7311
+ * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
7312
+ * stream-broker's `streamingDebug` gate — off by default so production logs
7313
+ * stay quiet and the emit path pays zero per-frame cost when disabled.
7314
+ */
7315
+ debug: boolean().optional()
7299
7316
  });
7300
7317
  var EncodeProfileSchema = object({
7301
7318
  video: object({
@@ -10320,6 +10337,100 @@ var coverCapability = {
10320
10337
  runtimeState: CoverStatusSchema
10321
10338
  };
10322
10339
  /**
10340
+ * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
10341
+ * shared by reolink / hikvision / amcrest. Models the common firmware
10342
+ * surface: the IR-cut switching MODE plus the two knobs that gate it
10343
+ * (photocell `sensitivity` + `switchDelaySec`). Each vendor maps these
10344
+ * onto its own ISAPI / Baichuan / Dahua-CGI fields; the cap standardises
10345
+ * the shape so ONE derived-form renders every camera.
10346
+ *
10347
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
10348
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
10349
+ * injected from `status`) reports the live values, and a single
10350
+ * `setSettings` mutation applies a partial change. No hand-written
10351
+ * settings-contribution methods — the framework derives the UI + save
10352
+ * routing from this surface.
10353
+ */
10354
+ /** IR-cut switching mode. `schedule` = time-of-day table configured on the camera. */
10355
+ var DayNightModeSchema = _enum([
10356
+ "auto",
10357
+ "day",
10358
+ "night",
10359
+ "schedule"
10360
+ ]);
10361
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
10362
+ * getOptions availability convention. Normalized values are 0–100. */
10363
+ var NormalizedRangeSchema$1 = object({
10364
+ min: number(),
10365
+ max: number(),
10366
+ step: number()
10367
+ });
10368
+ /**
10369
+ * Current day/night state. Optional fields are absent when the camera
10370
+ * does not expose that knob (a photocell-less model reports no
10371
+ * `sensitivity`). `lastFetchedAt` feeds the runtime-state bridge.
10372
+ */
10373
+ var DayNightStatusSchema = object({
10374
+ mode: DayNightModeSchema,
10375
+ /** IR-cut trigger sensitivity, NORMALIZED 0–100 (higher = switches to night sooner). */
10376
+ sensitivity: number().optional(),
10377
+ /** Delay before the IR-cut filter flips, in seconds. */
10378
+ switchDelaySec: number().optional(),
10379
+ lastFetchedAt: number()
10380
+ });
10381
+ /**
10382
+ * Per-camera availability descriptor — drives which controls the admin UI
10383
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
10384
+ * (normalized 0–100); the mode choice-set as an array. A provider returns
10385
+ * honest, camera-probed values — never hardcoded.
10386
+ */
10387
+ var DayNightOptionsSchema = object({
10388
+ /** Modes this camera accepts. Empty → the camera has no configurable day/night mode. */
10389
+ modes: array(DayNightModeSchema),
10390
+ supportsSensitivity: boolean(),
10391
+ /** Present when `supportsSensitivity` — the normalized 0–100 range. */
10392
+ sensitivity: NormalizedRangeSchema$1.optional(),
10393
+ supportsSwitchDelay: boolean(),
10394
+ /** Present when `supportsSwitchDelay` — the allowed delay range in seconds. */
10395
+ switchDelaySec: NormalizedRangeSchema$1.optional()
10396
+ });
10397
+ /**
10398
+ * Partial change to the day/night config — every field optional. A
10399
+ * provider ignores fields it does not support.
10400
+ */
10401
+ var DayNightSettingsPatchSchema = object({
10402
+ mode: DayNightModeSchema.optional(),
10403
+ sensitivity: number().optional(),
10404
+ switchDelaySec: number().optional()
10405
+ });
10406
+ var dayNightCapability = {
10407
+ name: "day-night",
10408
+ scope: "device",
10409
+ deviceNative: true,
10410
+ mode: "singleton",
10411
+ deviceTypes: [DeviceType.Camera],
10412
+ deviceConfig: { ui: {
10413
+ kind: "derived-form",
10414
+ builderId: "day-night",
10415
+ tab: "image"
10416
+ } },
10417
+ methods: {
10418
+ getOptions: method(object({ deviceId: number() }), DayNightOptionsSchema),
10419
+ setSettings: method(object({
10420
+ deviceId: number(),
10421
+ settings: DayNightSettingsPatchSchema
10422
+ }), _void(), {
10423
+ kind: "mutation",
10424
+ auth: "admin"
10425
+ })
10426
+ },
10427
+ status: {
10428
+ schema: DayNightStatusSchema,
10429
+ kind: "poll"
10430
+ },
10431
+ runtimeState: DayNightStatusSchema
10432
+ };
10433
+ /**
10323
10434
  * Identity envelope for a device's upstream-system metadata.
10324
10435
  *
10325
10436
  * Two jobs:
@@ -10978,6 +11089,155 @@ var imageCapability = {
10978
11089
  runtimeState: ImageStatusSchema
10979
11090
  };
10980
11091
  /**
11092
+ * Vendor-neutral image / picture-adjustment cap — the per-camera config
11093
+ * cap shared by reolink / hikvision / amcrest. Models the common ISP
11094
+ * surface: the four picture sliders (brightness / contrast / saturation /
11095
+ * sharpness), orientation (mirror / flip / rotate), white-balance,
11096
+ * exposure and backlight-compensation modes.
11097
+ *
11098
+ * NORMALIZATION: every slider is a normalized int 0–100. Vendors expose
11099
+ * these natively as 0–100 or 0–255 (or other ranges); each provider maps
11100
+ * its native range to/from this normalized 0–100 space so the cap surface
11101
+ * (and the derived form) is identical across cameras. `warmth` (manual
11102
+ * white-balance) is likewise normalized 0–100.
11103
+ *
11104
+ * Follows the D14 `deviceConfig` archetype (see `stream-params.cap.ts`):
11105
+ * `getOptions` advertises per-camera availability, `getStatus` (auto-
11106
+ * injected from `status`) reports the live values, and a single
11107
+ * `setSettings` mutation applies a partial change. No hand-written
11108
+ * settings-contribution methods — the framework derives the UI + save
11109
+ * routing from this surface.
11110
+ */
11111
+ /** Sensor/image rotation, degrees clockwise. */
11112
+ var ImageRotateSchema = _enum([
11113
+ "0",
11114
+ "90",
11115
+ "180",
11116
+ "270"
11117
+ ]);
11118
+ /** White-balance mode. `manual` unlocks the normalized `warmth` knob. */
11119
+ var WhiteBalanceModeSchema = _enum(["auto", "manual"]);
11120
+ /** Exposure mode. */
11121
+ var ExposureModeSchema = _enum(["auto", "manual"]);
11122
+ /**
11123
+ * Backlight-compensation mode:
11124
+ * - `off` — disabled
11125
+ * - `blc` — backlight compensation
11126
+ * - `wdr` — wide dynamic range
11127
+ * - `hlc` — highlight compensation
11128
+ */
11129
+ var BacklightModeSchema = _enum([
11130
+ "off",
11131
+ "blc",
11132
+ "wdr",
11133
+ "hlc"
11134
+ ]);
11135
+ /** Normalized numeric range descriptor — `{ min, max, step }` per the
11136
+ * getOptions availability convention. Slider values are normalized 0–100. */
11137
+ var NormalizedRangeSchema = object({
11138
+ min: number(),
11139
+ max: number(),
11140
+ step: number()
11141
+ });
11142
+ /**
11143
+ * Current image-adjustment state. Every field optional — absent when the
11144
+ * camera does not expose that control. Slider values are NORMALIZED 0–100.
11145
+ * `lastFetchedAt` feeds the runtime-state bridge.
11146
+ */
11147
+ var ImageSettingsStatusSchema = object({
11148
+ /** Normalized 0–100. */
11149
+ brightness: number().optional(),
11150
+ /** Normalized 0–100. */
11151
+ contrast: number().optional(),
11152
+ /** Normalized 0–100. */
11153
+ saturation: number().optional(),
11154
+ /** Normalized 0–100. */
11155
+ sharpness: number().optional(),
11156
+ mirror: boolean().optional(),
11157
+ flip: boolean().optional(),
11158
+ rotate: ImageRotateSchema.optional(),
11159
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11160
+ /** Manual white-balance warmth, NORMALIZED 0–100. Meaningful only when `whiteBalance === 'manual'`. */
11161
+ warmth: number().optional(),
11162
+ exposureMode: ExposureModeSchema.optional(),
11163
+ backlightMode: BacklightModeSchema.optional(),
11164
+ lastFetchedAt: number()
11165
+ });
11166
+ /**
11167
+ * Per-camera availability descriptor — drives which controls the admin UI
11168
+ * renders. Booleans as `supportsX`; numeric ranges as `{ min, max, step }`
11169
+ * (the normalized 0–100 range); enums as arrays of supported values (empty
11170
+ * array → control hidden). A provider returns honest, camera-probed values
11171
+ * — never hardcoded.
11172
+ */
11173
+ var ImageSettingsOptionsSchema = object({
11174
+ supportsBrightness: boolean(),
11175
+ brightness: NormalizedRangeSchema.optional(),
11176
+ supportsContrast: boolean(),
11177
+ contrast: NormalizedRangeSchema.optional(),
11178
+ supportsSaturation: boolean(),
11179
+ saturation: NormalizedRangeSchema.optional(),
11180
+ supportsSharpness: boolean(),
11181
+ sharpness: NormalizedRangeSchema.optional(),
11182
+ supportsMirror: boolean(),
11183
+ supportsFlip: boolean(),
11184
+ /** Supported rotation values. Empty → rotation not configurable. */
11185
+ rotateOptions: array(ImageRotateSchema),
11186
+ /** Supported white-balance modes. Empty → white-balance not configurable. */
11187
+ whiteBalanceModes: array(WhiteBalanceModeSchema),
11188
+ supportsWarmth: boolean(),
11189
+ /** Present when `supportsWarmth` — the normalized 0–100 range. */
11190
+ warmth: NormalizedRangeSchema.optional(),
11191
+ /** Supported exposure modes. Empty → exposure not configurable. */
11192
+ exposureModes: array(ExposureModeSchema),
11193
+ /** Supported backlight modes. Empty → backlight-compensation not configurable. */
11194
+ backlightModes: array(BacklightModeSchema)
11195
+ });
11196
+ /**
11197
+ * Partial change to the image config — every field optional. Slider values
11198
+ * are normalized 0–100. A provider ignores fields it does not support.
11199
+ */
11200
+ var ImageSettingsPatchSchema = object({
11201
+ brightness: number().optional(),
11202
+ contrast: number().optional(),
11203
+ saturation: number().optional(),
11204
+ sharpness: number().optional(),
11205
+ mirror: boolean().optional(),
11206
+ flip: boolean().optional(),
11207
+ rotate: ImageRotateSchema.optional(),
11208
+ whiteBalance: WhiteBalanceModeSchema.optional(),
11209
+ warmth: number().optional(),
11210
+ exposureMode: ExposureModeSchema.optional(),
11211
+ backlightMode: BacklightModeSchema.optional()
11212
+ });
11213
+ var imageSettingsCapability = {
11214
+ name: "image-settings",
11215
+ scope: "device",
11216
+ deviceNative: true,
11217
+ mode: "singleton",
11218
+ deviceTypes: [DeviceType.Camera],
11219
+ deviceConfig: { ui: {
11220
+ kind: "derived-form",
11221
+ builderId: "image-settings",
11222
+ tab: "image"
11223
+ } },
11224
+ methods: {
11225
+ getOptions: method(object({ deviceId: number() }), ImageSettingsOptionsSchema),
11226
+ setSettings: method(object({
11227
+ deviceId: number(),
11228
+ settings: ImageSettingsPatchSchema
11229
+ }), _void(), {
11230
+ kind: "mutation",
11231
+ auth: "admin"
11232
+ })
11233
+ },
11234
+ status: {
11235
+ schema: ImageSettingsStatusSchema,
11236
+ kind: "poll"
11237
+ },
11238
+ runtimeState: ImageSettingsStatusSchema
11239
+ };
11240
+ /**
10981
11241
  * Robotic lawn-mower cap. Models HA `lawn_mower.*` entities — anything
10982
11242
  * with a mowing lifecycle plus a dock action.
10983
11243
  *
@@ -11976,6 +12236,16 @@ var RunnerCameraConfigSchema = object({
11976
12236
  * this gate is bypassed.
11977
12237
  */
11978
12238
  onboardMotionDrivesAnalyzer: boolean().default(true),
12239
+ /**
12240
+ * Master toggle for the occupancy re-check. When `false` (DEFAULT) the runner
12241
+ * never arms the periodic recheck timer, regardless of `occupancyRecheckSec` —
12242
+ * this is off by default because the recheck re-subscribes a detection session
12243
+ * every N seconds while `watching`, a major source of pull-decoder re-dial
12244
+ * churn (each cycle creates+tears a session → RTSP re-dial → latency). The
12245
+ * `occupancyRecheckSec` / `occupancyRecheckFrames` sliders only take effect
12246
+ * (and only render) when this is enabled.
12247
+ */
12248
+ occupancyRecheckEnabled: boolean().default(false),
11979
12249
  occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
11980
12250
  occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
11981
12251
  /**
@@ -13981,6 +14251,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
13981
14251
  contact: contactCapability,
13982
14252
  control: controlCapability,
13983
14253
  cover: coverCapability,
14254
+ dayNight: dayNightCapability,
13984
14255
  deviceDiscovery: deviceDiscoveryCapability,
13985
14256
  deviceStatus: deviceStatusCapability,
13986
14257
  doorbell: doorbellCapability,
@@ -13993,6 +14264,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
13993
14264
  humidifier: humidifierCapability,
13994
14265
  humiditySensor: humiditySensorCapability,
13995
14266
  image: imageCapability,
14267
+ imageSettings: imageSettingsCapability,
13996
14268
  lawnMowerControl: lawnMowerControlCapability,
13997
14269
  lockControl: lockControlCapability,
13998
14270
  mediaPlayer: mediaPlayerCapability,
@@ -15907,7 +16179,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
15907
16179
  id: string(),
15908
16180
  name: string(),
15909
16181
  isPullMode: boolean().optional(),
15910
- priority: number().optional()
16182
+ priority: number().optional(),
16183
+ hwaccel: string().optional(),
16184
+ probedBestHwaccel: string().optional()
15911
16185
  })), method(DecoderSessionConfigSchema, object({
15912
16186
  sessionId: string(),
15913
16187
  nodeId: string()
@@ -21916,6 +22190,18 @@ Object.freeze({
21916
22190
  addonId: null,
21917
22191
  access: "view"
21918
22192
  },
22193
+ "dayNight.getOptions": {
22194
+ capName: "day-night",
22195
+ capScope: "device",
22196
+ addonId: null,
22197
+ access: "view"
22198
+ },
22199
+ "dayNight.setSettings": {
22200
+ capName: "day-night",
22201
+ capScope: "device",
22202
+ addonId: null,
22203
+ access: "create"
22204
+ },
21919
22205
  "decoder.createSession": {
21920
22206
  capName: "decoder",
21921
22207
  capScope: "system",
@@ -22846,6 +23132,18 @@ Object.freeze({
22846
23132
  addonId: null,
22847
23133
  access: "create"
22848
23134
  },
23135
+ "imageSettings.getOptions": {
23136
+ capName: "image-settings",
23137
+ capScope: "device",
23138
+ addonId: null,
23139
+ access: "view"
23140
+ },
23141
+ "imageSettings.setSettings": {
23142
+ capName: "image-settings",
23143
+ capScope: "device",
23144
+ addonId: null,
23145
+ access: "create"
23146
+ },
22849
23147
  "integrations.create": {
22850
23148
  capName: "integrations",
22851
23149
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-petkit",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "PetKit smart-feeder device-provider addon for CamStack — wraps the @apocaliss92/nodepetkit PetKit cloud client",
5
5
  "keywords": [
6
6
  "camstack",