@camstack/addon-provider-unifi 0.2.109 → 0.2.111

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
@@ -5360,7 +5360,7 @@ var ZodIssueCode = {
5360
5360
  var ZodFirstPartyTypeKind;
5361
5361
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5362
5362
  //#endregion
5363
- //#region ../types/dist/sleep-BDR76Ykr.mjs
5363
+ //#region ../types/dist/sleep-B1y0Fo1U.mjs
5364
5364
  /**
5365
5365
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5366
5366
  * window to float samples (D455).
@@ -30886,14 +30886,81 @@ var privacyMaskCapability = {
30886
30886
  * whether persisting is worth a SQLite commit. */
30887
30887
  volatileStateFields: ["lastFetchedAt"]
30888
30888
  };
30889
+ /**
30890
+ * What a preset id DOES on this camera.
30891
+ *
30892
+ * On several PTZ firmwares the preset namespace is shared: low ids are stored
30893
+ * positions, a reserved band triggers camera FUNCTIONS. The dispensa camera
30894
+ * (Hikvision) returns its own reserved band in the preset list, named by the
30895
+ * firmware:
30896
+ *
30897
+ * 34 Back to origin · 39 Day mode · 40 Night mode · 46 Day/Night Auto Mode
30898
+ * 92 Set manual limits · 93 Save manual limits · 94 Remote reboot
30899
+ * 95 Call OSD menu
30900
+ *
30901
+ * We used to hand all of these to the UI as ordinary presets. Saving over one
30902
+ * is what produced `PUT /ISAPI/PTZCtrl/channels/1/presets/34 -> HTTP 500`: the
30903
+ * camera refusing to let "Back to origin" be overwritten, surfaced to the
30904
+ * operator as a transport failure.
30905
+ *
30906
+ * A function preset stays fully usable as a DESTINATION -- `goToPreset('34')`
30907
+ * is the single most useful thing that camera can do. Only `savePreset` and
30908
+ * `deletePreset` are gated.
30909
+ */
30910
+ var PtzPresetFunctionSchema = _enum([
30911
+ "home",
30912
+ "day-mode",
30913
+ "night-mode",
30914
+ "day-night-auto",
30915
+ "set-limits",
30916
+ "save-limits",
30917
+ "reboot",
30918
+ "osd-menu"
30919
+ ]);
30889
30920
  var PtzPresetSchema = object({
30890
30921
  id: string(),
30891
- name: string()
30922
+ name: string(),
30923
+ /**
30924
+ * The firmware function this id performs, when the provider KNOWS the id is
30925
+ * reserved. `null` = an ordinary stored position, OR a reserved id this
30926
+ * provider does not recognise -- the two are told apart by `writable`.
30927
+ */
30928
+ fn: PtzPresetFunctionSchema.nullable(),
30929
+ /**
30930
+ * Whether `savePreset` / `deletePreset` may target this id. A provider sets
30931
+ * it false only for a band it KNOWS is reserved; where the firmware is not
30932
+ * documented it stays true and a refusal comes from the camera, named.
30933
+ */
30934
+ writable: boolean()
30892
30935
  });
30936
+ /**
30937
+ * Where the head is pointing -- per axis, and `null` when the driver cannot
30938
+ * read it.
30939
+ *
30940
+ * It used to be three REQUIRED numbers, which left a provider that cannot read
30941
+ * position no way to say so. All four said `0`:
30942
+ *
30943
+ * reolink `return { pan: 0, tilt: 0, zoom: 0 }` "until a position-query
30944
+ * path lands upstream"
30945
+ * hikvision stub, "firmware-dependent and frequently absent"
30946
+ * amcrest stub, "no generic absolute-position read for this model family"
30947
+ * onvif throws
30948
+ *
30949
+ * So every consumer asking where a camera points was told "perfectly centred"
30950
+ * by four cameras that had never looked. That is D393 -- a measurement that
30951
+ * FAILED is `null`, never `0`, and the type says so all the way to the
30952
+ * decision -- the same shape as the unreadable `statfs` folded into "0 bytes of
30953
+ * headroom", which evacuated a healthy disk.
30954
+ *
30955
+ * D393 also says to check for a narrower structural TWIN of the result type.
30956
+ * There is one: `PtzStatusSchema` extends this, so the lie had already
30957
+ * propagated into `getStatus`, which is the surface `getPosition`'s own comment
30958
+ * tells callers to migrate to.
30959
+ */
30893
30960
  var PtzPositionSchema = object({
30894
- pan: number(),
30895
- tilt: number(),
30896
- zoom: number()
30961
+ pan: number().nullable(),
30962
+ tilt: number().nullable(),
30963
+ zoom: number().nullable()
30897
30964
  });
30898
30965
  var PtzMoveCommandSchema = object({
30899
30966
  pan: number().optional(),
@@ -30912,7 +30979,72 @@ var PtzOptionsSchema = object({
30912
30979
  maxPresets: number().optional(),
30913
30980
  /** Whether the camera exposes a controllable autofocus toggle
30914
30981
  * (boolean `hasX` per the getOptions availability convention). */
30915
- hasAutofocus: boolean()
30982
+ hasAutofocus: boolean(),
30983
+ /**
30984
+ * How many distinct speeds this camera's NATIVE scale offers.
30985
+ *
30986
+ * The cap's `speed` is normalized 0..1 and each provider maps it down --
30987
+ * Baichuan 1..63, Dahua 1..8, ISAPI's percentage -100..100. The normalized
30988
+ * value hides how coarse that really is: asking an amcrest for `0.37` is
30989
+ * meaningless, because it has eight steps and three of them round to the
30990
+ * same one. A loop that tunes its own gain has to know the granularity of
30991
+ * the knob it is turning.
30992
+ *
30993
+ * `null` = the driver does not know, or the scale is continuous (ONVIF takes
30994
+ * a float). Never a made-up number.
30995
+ */
30996
+ speedSteps: number().int().positive().nullable(),
30997
+ /**
30998
+ * How long ONE `move` pulse runs on this driver, ms.
30999
+ *
31000
+ * `move` is a self-terminating burst everywhere, but every provider hardcoded
31001
+ * its own duration in private -- 200 reolink, 350 amcrest, 500 hikvision,
31002
+ * 1000 onvif -- so no caller could read it. It is the DENOMINATOR of "how far
31003
+ * did the head travel per pulse": without it a measured displacement has no
31004
+ * gain to be divided into.
31005
+ *
31006
+ * `null` = the driver cannot say.
31007
+ */
31008
+ moveImpulseMs: number().int().positive().nullable()
31009
+ });
31010
+ /**
31011
+ * Which preset `goHome` goes to, and WHO decided.
31012
+ *
31013
+ * `goHome` used to be three vendor "conventions" written in three comments --
31014
+ * Reolink preset 0, Hikvision preset '1', Dahua preset 1 -- and on this fleet
31015
+ * not one of the three cameras honours its own:
31016
+ *
31017
+ * 592 Videocamera camera Daniel (reolink) preset 0 holds "stanza"
31018
+ * 1438 Videocamera dispensa (hikvision) preset 1 holds "Credenza"
31019
+ * 3836 Videocamera studio (amcrest) preset 1 holds "Preset1"
31020
+ *
31021
+ * So `goHome` meant "go wherever the operator happened to save in slot 0 or 1",
31022
+ * and two of the three swallowed the failure in a bare `catch`. For autotrack
31023
+ * this is the HOTTEST path -- it runs every time a subject is released -- so it
31024
+ * needs an answer that is true per camera and audible when it is missing.
31025
+ *
31026
+ * `source` is what makes it honest:
31027
+ * - `operator` -- picked in the UI, stored by the provider.
31028
+ * - `firmware` -- the camera itself named a preset `fn: 'home'` (Hikvision's
31029
+ * "Back to origin"), adopted as the default with nothing to configure.
31030
+ * - `native` -- the driver homes WITHOUT a preset at all. ONVIF does:
31031
+ * `goHome` is `ptzAbsoluteMove({x:0, y:0, zoom:0})`. `presetId` is null and
31032
+ * that is not a failure -- there is nothing to pick, and the UI must offer
31033
+ * no picker.
31034
+ * - `none` -- nothing is configured and the camera names nothing.
31035
+ * `goHome` REFUSES rather than moving the head somewhere arbitrary.
31036
+ *
31037
+ * `source === 'none'` is the refusal condition, NOT `presetId === null`: the
31038
+ * native case has no preset and homes perfectly well.
31039
+ */
31040
+ var PtzHomePresetSchema = object({
31041
+ presetId: string().nullable(),
31042
+ source: _enum([
31043
+ "operator",
31044
+ "firmware",
31045
+ "native",
31046
+ "none"
31047
+ ])
30916
31048
  });
30917
31049
  DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(PtzMoveCommandSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(PtzPresetSchema)), method(object({
30918
31050
  deviceId: number(),
@@ -30930,7 +31062,13 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
30930
31062
  }), _void(), {
30931
31063
  kind: "mutation",
30932
31064
  auth: "admin"
30933
- }), method(object({ deviceId: number() }), PtzOptionsSchema), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), PtzPositionSchema), method(object({
31065
+ }), method(object({ deviceId: number() }), PtzOptionsSchema), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), PtzHomePresetSchema), method(object({
31066
+ deviceId: number(),
31067
+ presetId: string().nullable()
31068
+ }), _void(), {
31069
+ kind: "mutation",
31070
+ auth: "admin"
31071
+ }), method(object({ deviceId: number() }), PtzPositionSchema), method(object({
30934
31072
  deviceId: number(),
30935
31073
  enabled: boolean()
30936
31074
  }), _void(), { kind: "mutation" });
@@ -40184,6 +40322,12 @@ Object.freeze({
40184
40322
  addonId: null,
40185
40323
  access: "delete"
40186
40324
  },
40325
+ "ptz.getHomePreset": {
40326
+ capName: "ptz",
40327
+ capScope: "device",
40328
+ addonId: null,
40329
+ access: "view"
40330
+ },
40187
40331
  "ptz.getOptions": {
40188
40332
  capName: "ptz",
40189
40333
  capScope: "device",
@@ -40232,6 +40376,12 @@ Object.freeze({
40232
40376
  addonId: null,
40233
40377
  access: "create"
40234
40378
  },
40379
+ "ptz.setHomePreset": {
40380
+ capName: "ptz",
40381
+ capScope: "device",
40382
+ addonId: null,
40383
+ access: "create"
40384
+ },
40235
40385
  "ptz.stop": {
40236
40386
  capName: "ptz",
40237
40387
  capScope: "device",
@@ -43405,6 +43555,11 @@ Object.freeze({
43405
43555
  form: "single",
43406
43556
  optional: false
43407
43557
  }],
43558
+ "ptz.getHomePreset": [{
43559
+ name: "deviceId",
43560
+ form: "single",
43561
+ optional: false
43562
+ }],
43408
43563
  "ptz.getOptions": [{
43409
43564
  name: "deviceId",
43410
43565
  form: "single",
@@ -43445,6 +43600,11 @@ Object.freeze({
43445
43600
  form: "single",
43446
43601
  optional: false
43447
43602
  }],
43603
+ "ptz.setHomePreset": [{
43604
+ name: "deviceId",
43605
+ form: "single",
43606
+ optional: false
43607
+ }],
43448
43608
  "ptz.stop": [{
43449
43609
  name: "deviceId",
43450
43610
  form: "single",
package/dist/addon.mjs CHANGED
@@ -5359,7 +5359,7 @@ var ZodIssueCode = {
5359
5359
  var ZodFirstPartyTypeKind;
5360
5360
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5361
5361
  //#endregion
5362
- //#region ../types/dist/sleep-BDR76Ykr.mjs
5362
+ //#region ../types/dist/sleep-B1y0Fo1U.mjs
5363
5363
  /**
5364
5364
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5365
5365
  * window to float samples (D455).
@@ -30885,14 +30885,81 @@ var privacyMaskCapability = {
30885
30885
  * whether persisting is worth a SQLite commit. */
30886
30886
  volatileStateFields: ["lastFetchedAt"]
30887
30887
  };
30888
+ /**
30889
+ * What a preset id DOES on this camera.
30890
+ *
30891
+ * On several PTZ firmwares the preset namespace is shared: low ids are stored
30892
+ * positions, a reserved band triggers camera FUNCTIONS. The dispensa camera
30893
+ * (Hikvision) returns its own reserved band in the preset list, named by the
30894
+ * firmware:
30895
+ *
30896
+ * 34 Back to origin · 39 Day mode · 40 Night mode · 46 Day/Night Auto Mode
30897
+ * 92 Set manual limits · 93 Save manual limits · 94 Remote reboot
30898
+ * 95 Call OSD menu
30899
+ *
30900
+ * We used to hand all of these to the UI as ordinary presets. Saving over one
30901
+ * is what produced `PUT /ISAPI/PTZCtrl/channels/1/presets/34 -> HTTP 500`: the
30902
+ * camera refusing to let "Back to origin" be overwritten, surfaced to the
30903
+ * operator as a transport failure.
30904
+ *
30905
+ * A function preset stays fully usable as a DESTINATION -- `goToPreset('34')`
30906
+ * is the single most useful thing that camera can do. Only `savePreset` and
30907
+ * `deletePreset` are gated.
30908
+ */
30909
+ var PtzPresetFunctionSchema = _enum([
30910
+ "home",
30911
+ "day-mode",
30912
+ "night-mode",
30913
+ "day-night-auto",
30914
+ "set-limits",
30915
+ "save-limits",
30916
+ "reboot",
30917
+ "osd-menu"
30918
+ ]);
30888
30919
  var PtzPresetSchema = object({
30889
30920
  id: string(),
30890
- name: string()
30921
+ name: string(),
30922
+ /**
30923
+ * The firmware function this id performs, when the provider KNOWS the id is
30924
+ * reserved. `null` = an ordinary stored position, OR a reserved id this
30925
+ * provider does not recognise -- the two are told apart by `writable`.
30926
+ */
30927
+ fn: PtzPresetFunctionSchema.nullable(),
30928
+ /**
30929
+ * Whether `savePreset` / `deletePreset` may target this id. A provider sets
30930
+ * it false only for a band it KNOWS is reserved; where the firmware is not
30931
+ * documented it stays true and a refusal comes from the camera, named.
30932
+ */
30933
+ writable: boolean()
30891
30934
  });
30935
+ /**
30936
+ * Where the head is pointing -- per axis, and `null` when the driver cannot
30937
+ * read it.
30938
+ *
30939
+ * It used to be three REQUIRED numbers, which left a provider that cannot read
30940
+ * position no way to say so. All four said `0`:
30941
+ *
30942
+ * reolink `return { pan: 0, tilt: 0, zoom: 0 }` "until a position-query
30943
+ * path lands upstream"
30944
+ * hikvision stub, "firmware-dependent and frequently absent"
30945
+ * amcrest stub, "no generic absolute-position read for this model family"
30946
+ * onvif throws
30947
+ *
30948
+ * So every consumer asking where a camera points was told "perfectly centred"
30949
+ * by four cameras that had never looked. That is D393 -- a measurement that
30950
+ * FAILED is `null`, never `0`, and the type says so all the way to the
30951
+ * decision -- the same shape as the unreadable `statfs` folded into "0 bytes of
30952
+ * headroom", which evacuated a healthy disk.
30953
+ *
30954
+ * D393 also says to check for a narrower structural TWIN of the result type.
30955
+ * There is one: `PtzStatusSchema` extends this, so the lie had already
30956
+ * propagated into `getStatus`, which is the surface `getPosition`'s own comment
30957
+ * tells callers to migrate to.
30958
+ */
30892
30959
  var PtzPositionSchema = object({
30893
- pan: number(),
30894
- tilt: number(),
30895
- zoom: number()
30960
+ pan: number().nullable(),
30961
+ tilt: number().nullable(),
30962
+ zoom: number().nullable()
30896
30963
  });
30897
30964
  var PtzMoveCommandSchema = object({
30898
30965
  pan: number().optional(),
@@ -30911,7 +30978,72 @@ var PtzOptionsSchema = object({
30911
30978
  maxPresets: number().optional(),
30912
30979
  /** Whether the camera exposes a controllable autofocus toggle
30913
30980
  * (boolean `hasX` per the getOptions availability convention). */
30914
- hasAutofocus: boolean()
30981
+ hasAutofocus: boolean(),
30982
+ /**
30983
+ * How many distinct speeds this camera's NATIVE scale offers.
30984
+ *
30985
+ * The cap's `speed` is normalized 0..1 and each provider maps it down --
30986
+ * Baichuan 1..63, Dahua 1..8, ISAPI's percentage -100..100. The normalized
30987
+ * value hides how coarse that really is: asking an amcrest for `0.37` is
30988
+ * meaningless, because it has eight steps and three of them round to the
30989
+ * same one. A loop that tunes its own gain has to know the granularity of
30990
+ * the knob it is turning.
30991
+ *
30992
+ * `null` = the driver does not know, or the scale is continuous (ONVIF takes
30993
+ * a float). Never a made-up number.
30994
+ */
30995
+ speedSteps: number().int().positive().nullable(),
30996
+ /**
30997
+ * How long ONE `move` pulse runs on this driver, ms.
30998
+ *
30999
+ * `move` is a self-terminating burst everywhere, but every provider hardcoded
31000
+ * its own duration in private -- 200 reolink, 350 amcrest, 500 hikvision,
31001
+ * 1000 onvif -- so no caller could read it. It is the DENOMINATOR of "how far
31002
+ * did the head travel per pulse": without it a measured displacement has no
31003
+ * gain to be divided into.
31004
+ *
31005
+ * `null` = the driver cannot say.
31006
+ */
31007
+ moveImpulseMs: number().int().positive().nullable()
31008
+ });
31009
+ /**
31010
+ * Which preset `goHome` goes to, and WHO decided.
31011
+ *
31012
+ * `goHome` used to be three vendor "conventions" written in three comments --
31013
+ * Reolink preset 0, Hikvision preset '1', Dahua preset 1 -- and on this fleet
31014
+ * not one of the three cameras honours its own:
31015
+ *
31016
+ * 592 Videocamera camera Daniel (reolink) preset 0 holds "stanza"
31017
+ * 1438 Videocamera dispensa (hikvision) preset 1 holds "Credenza"
31018
+ * 3836 Videocamera studio (amcrest) preset 1 holds "Preset1"
31019
+ *
31020
+ * So `goHome` meant "go wherever the operator happened to save in slot 0 or 1",
31021
+ * and two of the three swallowed the failure in a bare `catch`. For autotrack
31022
+ * this is the HOTTEST path -- it runs every time a subject is released -- so it
31023
+ * needs an answer that is true per camera and audible when it is missing.
31024
+ *
31025
+ * `source` is what makes it honest:
31026
+ * - `operator` -- picked in the UI, stored by the provider.
31027
+ * - `firmware` -- the camera itself named a preset `fn: 'home'` (Hikvision's
31028
+ * "Back to origin"), adopted as the default with nothing to configure.
31029
+ * - `native` -- the driver homes WITHOUT a preset at all. ONVIF does:
31030
+ * `goHome` is `ptzAbsoluteMove({x:0, y:0, zoom:0})`. `presetId` is null and
31031
+ * that is not a failure -- there is nothing to pick, and the UI must offer
31032
+ * no picker.
31033
+ * - `none` -- nothing is configured and the camera names nothing.
31034
+ * `goHome` REFUSES rather than moving the head somewhere arbitrary.
31035
+ *
31036
+ * `source === 'none'` is the refusal condition, NOT `presetId === null`: the
31037
+ * native case has no preset and homes perfectly well.
31038
+ */
31039
+ var PtzHomePresetSchema = object({
31040
+ presetId: string().nullable(),
31041
+ source: _enum([
31042
+ "operator",
31043
+ "firmware",
31044
+ "native",
31045
+ "none"
31046
+ ])
30915
31047
  });
30916
31048
  DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(PtzMoveCommandSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(PtzPresetSchema)), method(object({
30917
31049
  deviceId: number(),
@@ -30929,7 +31061,13 @@ DeviceType.Camera, method(PtzMoveCommandSchema.extend({ deviceId: number() }), _
30929
31061
  }), _void(), {
30930
31062
  kind: "mutation",
30931
31063
  auth: "admin"
30932
- }), method(object({ deviceId: number() }), PtzOptionsSchema), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), PtzPositionSchema), method(object({
31064
+ }), method(object({ deviceId: number() }), PtzOptionsSchema), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), PtzHomePresetSchema), method(object({
31065
+ deviceId: number(),
31066
+ presetId: string().nullable()
31067
+ }), _void(), {
31068
+ kind: "mutation",
31069
+ auth: "admin"
31070
+ }), method(object({ deviceId: number() }), PtzPositionSchema), method(object({
30933
31071
  deviceId: number(),
30934
31072
  enabled: boolean()
30935
31073
  }), _void(), { kind: "mutation" });
@@ -40183,6 +40321,12 @@ Object.freeze({
40183
40321
  addonId: null,
40184
40322
  access: "delete"
40185
40323
  },
40324
+ "ptz.getHomePreset": {
40325
+ capName: "ptz",
40326
+ capScope: "device",
40327
+ addonId: null,
40328
+ access: "view"
40329
+ },
40186
40330
  "ptz.getOptions": {
40187
40331
  capName: "ptz",
40188
40332
  capScope: "device",
@@ -40231,6 +40375,12 @@ Object.freeze({
40231
40375
  addonId: null,
40232
40376
  access: "create"
40233
40377
  },
40378
+ "ptz.setHomePreset": {
40379
+ capName: "ptz",
40380
+ capScope: "device",
40381
+ addonId: null,
40382
+ access: "create"
40383
+ },
40234
40384
  "ptz.stop": {
40235
40385
  capName: "ptz",
40236
40386
  capScope: "device",
@@ -43404,6 +43554,11 @@ Object.freeze({
43404
43554
  form: "single",
43405
43555
  optional: false
43406
43556
  }],
43557
+ "ptz.getHomePreset": [{
43558
+ name: "deviceId",
43559
+ form: "single",
43560
+ optional: false
43561
+ }],
43407
43562
  "ptz.getOptions": [{
43408
43563
  name: "deviceId",
43409
43564
  form: "single",
@@ -43444,6 +43599,11 @@ Object.freeze({
43444
43599
  form: "single",
43445
43600
  optional: false
43446
43601
  }],
43602
+ "ptz.setHomePreset": [{
43603
+ name: "deviceId",
43604
+ form: "single",
43605
+ optional: false
43606
+ }],
43447
43607
  "ptz.stop": [{
43448
43608
  name: "deviceId",
43449
43609
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-unifi",
3
- "version": "0.2.109",
3
+ "version": "0.2.111",
4
4
  "description": "UniFi Network controller device-provider addon for CamStack — local-controller infra switches/APs (as containers) + network-client presence. NO cameras/Protect.",
5
5
  "keywords": [
6
6
  "camstack",