@camstack/addon-export-hap 1.2.82 → 1.2.84

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.
@@ -5491,6 +5491,12 @@ Object.fromEntries([
5491
5491
  icon: "move",
5492
5492
  order: 40
5493
5493
  },
5494
+ {
5495
+ id: "navigation",
5496
+ label: "Navigation",
5497
+ icon: "compass",
5498
+ order: 41
5499
+ },
5494
5500
  {
5495
5501
  id: "consumables",
5496
5502
  label: "Consumables",
@@ -6524,6 +6530,21 @@ var CameraStreamSchema = object({
6524
6530
  */
6525
6531
  autoEligible: boolean().optional(),
6526
6532
  /**
6533
+ * The profile slot the PUBLISHER says this stream is: `low` for a stream
6534
+ * whose only sensible role is the low-bandwidth one, `high` for a main
6535
+ * stream. Consulted by the broker's automatic ranking
6536
+ * (`rankInitialAssignment`) BEFORE the pixel-count heuristic, and only there:
6537
+ * an operator's manual assignment still wins, and an absent hint is the
6538
+ * pixel-ranked default every camera had before this field existed.
6539
+ *
6540
+ * Why it exists: a camera with ONE stream ranked to `mid` — the slot no
6541
+ * storage class is written for on its own (`recordings` is high|mid,
6542
+ * `recordingsLow` is low) and the one profile scrub does not read. The robot
6543
+ * camera's single 720p relay is a `low` in every respect except the slot the
6544
+ * heuristic put it in.
6545
+ */
6546
+ profileHint: CamProfileSchema.optional(),
6547
+ /**
6527
6548
  * Transport-specific opaque metadata. The broker passes it through to
6528
6549
  * the source reader without inspecting it. Currently used by
6529
6550
  * `pull-rfc4571` streams to carry the upstream SDP (so the reader can
@@ -8554,7 +8575,22 @@ var RecordingTriggersSchema = object({
8554
8575
  * il livello: un contatto trovato già aperto al riavvio del runner non fa
8555
8576
  * registrare.
8556
8577
  */
8557
- sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
8578
+ sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional(),
8579
+ /**
8580
+ * La camera registra per tutta la durata del SEGNALE che lei stessa
8581
+ * pubblica — la cap `recording-signal` (`active: true` mentre il device è in
8582
+ * funzione: un robot che pulisce). È un LIVELLO, non un fronte: la finestra
8583
+ * resta aperta finché il segnale è alto e si chiude `postBufferSec` dopo la
8584
+ * caduta, così una pulizia di quaranta minuti è UNA clip.
8585
+ *
8586
+ * Non nomina un device: il segnale è della camera stessa, tenuto fresco dal
8587
+ * suo provider (D224); il recorder lo ascolta su `DeviceStateChanged` e lo
8588
+ * riconcilia leggendo la slice via RPC, con un tetto oltre il quale un
8589
+ * segnale mai abbassato (un evento perso) non può tenere aperta una
8590
+ * registrazione (D11). Vedi `recorder/addon/band-decision.ts`
8591
+ * (`holdTrigger` / `releaseTrigger`).
8592
+ */
8593
+ deviceSignal: boolean().optional()
8558
8594
  });
8559
8595
  /**
8560
8596
  * Mode of a single recording band — the recorder per-band vocabulary.
@@ -12072,6 +12108,8 @@ method(object({
12072
12108
  label: string().optional(),
12073
12109
  deviceFeatures: array(string()).optional(),
12074
12110
  autoEligible: boolean().optional(),
12111
+ /** The slot the publisher says this stream IS — see `CameraStreamSchema.profileHint`. */
12112
+ profileHint: CamProfileSchema.optional(),
12075
12113
  metadata: record(string(), unknown()).optional(),
12076
12114
  /** Required when kind === 'derived' — the source camStreamId the
12077
12115
  * derived broker reads its encoded plane from.
@@ -28510,6 +28548,47 @@ method(object({
28510
28548
  auth: "protected"
28511
28549
  });
28512
28550
  /**
28551
+ * A camera's own "record me NOW" LEVEL — a signal the device raises while
28552
+ * something it knows about is happening (a robot vacuum cleaning, a machine
28553
+ * running, a gate open) and lowers when it stops.
28554
+ *
28555
+ * It is a level, not an edge. The sensor triggers the recorder already listens
28556
+ * to (`SOURCE_CAP_ACTIVE_FIELD`) fire on a rising edge and record for a fixed
28557
+ * post-buffer; a cleaning lasts forty minutes, and forty minutes of "this is
28558
+ * still happening" cannot be expressed as an edge plus a post-buffer without
28559
+ * either re-triggering on a timer (polling — D224 forbids the consumer keeping
28560
+ * the fact fresh) or picking a post-buffer long enough to cover every job,
28561
+ * which records the dock for that long after every short one. So the recorder
28562
+ * reads the LEVEL: it records for as long as `active` is true, plus the band's
28563
+ * own post-buffer once it falls.
28564
+ *
28565
+ * Who owns the fact: the PROVIDER of the device, which already reads the state
28566
+ * the signal is derived from (the vacuum's lifecycle state, for Dreame). It
28567
+ * writes this slice on every change; consumers subscribe to the kernel's
28568
+ * `DeviceStateChanged` for it and read it back through
28569
+ * `deviceState.getCapSlice` to reconcile — never a second copy, never a poll
28570
+ * against the device (D224, D8/D11).
28571
+ *
28572
+ * Deliberately NOT a `binary` sensor on the camera: a binary sensor is exported
28573
+ * to Home Assistant, HomeKit and the sensor picker as a thing an operator can
28574
+ * bind, and "the camera wants to record" is not a room sensor. It is a fact
28575
+ * about the camera, on the camera.
28576
+ */
28577
+ var RecordingSignalStatusSchema = object({
28578
+ /** True while the device asks to be recorded. */
28579
+ active: boolean(),
28580
+ /**
28581
+ * Why, in the provider's own vocabulary (a vacuum's `cleaning` / `docked`,
28582
+ * …). Free text for the log line and the UI badge; the recorder never
28583
+ * branches on it.
28584
+ */
28585
+ reason: string(),
28586
+ /** Ms epoch of the last `active` transition. 0 if never observed. */
28587
+ lastChangedAt: number()
28588
+ });
28589
+ RecordingSignalStatusSchema.extend({ lastFetchedAt: number() });
28590
+ DeviceType.Camera, method(object({ deviceId: number() }), RecordingSignalStatusSchema);
28591
+ /**
28513
28592
  * scene-monitor — device-scoped reference-region state cap. An operator marks
28514
28593
  * a rect ROI on a camera frame and names one or more states; the engine
28515
28594
  * (pipeline-analytics, designated post-processing node) reports which state is
@@ -28891,6 +28970,8 @@ var CamStreamDescriptorSchema = object({
28891
28970
  deviceFeatures: array(string()).optional(),
28892
28971
  /** Eligible for automatic profile assignment. Absent = `true`. */
28893
28972
  autoEligible: boolean().optional(),
28973
+ /** The slot the publisher says this stream IS — see `CameraStreamSchema.profileHint`. */
28974
+ profileHint: CamProfileSchema.optional(),
28894
28975
  /** Transport-specific opaque metadata (e.g. rfc4571 SDP). */
28895
28976
  metadata: record(string(), unknown()).optional()
28896
28977
  });
@@ -34852,6 +34933,12 @@ Object.freeze({
34852
34933
  addonId: null,
34853
34934
  access: "view"
34854
34935
  },
34936
+ "recordingSignal.getStatus": {
34937
+ capName: "recording-signal",
34938
+ capScope: "device",
34939
+ addonId: null,
34940
+ access: "view"
34941
+ },
34855
34942
  "sceneMonitor.captureReference": {
34856
34943
  capName: "scene-monitor",
34857
34944
  capScope: "device",
@@ -37844,6 +37931,11 @@ Object.freeze({
37844
37931
  form: "single",
37845
37932
  optional: true
37846
37933
  }],
37934
+ "recordingSignal.getStatus": [{
37935
+ name: "deviceId",
37936
+ form: "single",
37937
+ optional: false
37938
+ }],
37847
37939
  "sceneMonitor.captureReference": [{
37848
37940
  name: "deviceId",
37849
37941
  form: "single",
@@ -5479,6 +5479,12 @@ Object.fromEntries([
5479
5479
  icon: "move",
5480
5480
  order: 40
5481
5481
  },
5482
+ {
5483
+ id: "navigation",
5484
+ label: "Navigation",
5485
+ icon: "compass",
5486
+ order: 41
5487
+ },
5482
5488
  {
5483
5489
  id: "consumables",
5484
5490
  label: "Consumables",
@@ -6512,6 +6518,21 @@ var CameraStreamSchema = object({
6512
6518
  */
6513
6519
  autoEligible: boolean().optional(),
6514
6520
  /**
6521
+ * The profile slot the PUBLISHER says this stream is: `low` for a stream
6522
+ * whose only sensible role is the low-bandwidth one, `high` for a main
6523
+ * stream. Consulted by the broker's automatic ranking
6524
+ * (`rankInitialAssignment`) BEFORE the pixel-count heuristic, and only there:
6525
+ * an operator's manual assignment still wins, and an absent hint is the
6526
+ * pixel-ranked default every camera had before this field existed.
6527
+ *
6528
+ * Why it exists: a camera with ONE stream ranked to `mid` — the slot no
6529
+ * storage class is written for on its own (`recordings` is high|mid,
6530
+ * `recordingsLow` is low) and the one profile scrub does not read. The robot
6531
+ * camera's single 720p relay is a `low` in every respect except the slot the
6532
+ * heuristic put it in.
6533
+ */
6534
+ profileHint: CamProfileSchema.optional(),
6535
+ /**
6515
6536
  * Transport-specific opaque metadata. The broker passes it through to
6516
6537
  * the source reader without inspecting it. Currently used by
6517
6538
  * `pull-rfc4571` streams to carry the upstream SDP (so the reader can
@@ -8542,7 +8563,22 @@ var RecordingTriggersSchema = object({
8542
8563
  * il livello: un contatto trovato già aperto al riavvio del runner non fa
8543
8564
  * registrare.
8544
8565
  */
8545
- sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
8566
+ sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional(),
8567
+ /**
8568
+ * La camera registra per tutta la durata del SEGNALE che lei stessa
8569
+ * pubblica — la cap `recording-signal` (`active: true` mentre il device è in
8570
+ * funzione: un robot che pulisce). È un LIVELLO, non un fronte: la finestra
8571
+ * resta aperta finché il segnale è alto e si chiude `postBufferSec` dopo la
8572
+ * caduta, così una pulizia di quaranta minuti è UNA clip.
8573
+ *
8574
+ * Non nomina un device: il segnale è della camera stessa, tenuto fresco dal
8575
+ * suo provider (D224); il recorder lo ascolta su `DeviceStateChanged` e lo
8576
+ * riconcilia leggendo la slice via RPC, con un tetto oltre il quale un
8577
+ * segnale mai abbassato (un evento perso) non può tenere aperta una
8578
+ * registrazione (D11). Vedi `recorder/addon/band-decision.ts`
8579
+ * (`holdTrigger` / `releaseTrigger`).
8580
+ */
8581
+ deviceSignal: boolean().optional()
8546
8582
  });
8547
8583
  /**
8548
8584
  * Mode of a single recording band — the recorder per-band vocabulary.
@@ -12060,6 +12096,8 @@ method(object({
12060
12096
  label: string().optional(),
12061
12097
  deviceFeatures: array(string()).optional(),
12062
12098
  autoEligible: boolean().optional(),
12099
+ /** The slot the publisher says this stream IS — see `CameraStreamSchema.profileHint`. */
12100
+ profileHint: CamProfileSchema.optional(),
12063
12101
  metadata: record(string(), unknown()).optional(),
12064
12102
  /** Required when kind === 'derived' — the source camStreamId the
12065
12103
  * derived broker reads its encoded plane from.
@@ -28498,6 +28536,47 @@ method(object({
28498
28536
  auth: "protected"
28499
28537
  });
28500
28538
  /**
28539
+ * A camera's own "record me NOW" LEVEL — a signal the device raises while
28540
+ * something it knows about is happening (a robot vacuum cleaning, a machine
28541
+ * running, a gate open) and lowers when it stops.
28542
+ *
28543
+ * It is a level, not an edge. The sensor triggers the recorder already listens
28544
+ * to (`SOURCE_CAP_ACTIVE_FIELD`) fire on a rising edge and record for a fixed
28545
+ * post-buffer; a cleaning lasts forty minutes, and forty minutes of "this is
28546
+ * still happening" cannot be expressed as an edge plus a post-buffer without
28547
+ * either re-triggering on a timer (polling — D224 forbids the consumer keeping
28548
+ * the fact fresh) or picking a post-buffer long enough to cover every job,
28549
+ * which records the dock for that long after every short one. So the recorder
28550
+ * reads the LEVEL: it records for as long as `active` is true, plus the band's
28551
+ * own post-buffer once it falls.
28552
+ *
28553
+ * Who owns the fact: the PROVIDER of the device, which already reads the state
28554
+ * the signal is derived from (the vacuum's lifecycle state, for Dreame). It
28555
+ * writes this slice on every change; consumers subscribe to the kernel's
28556
+ * `DeviceStateChanged` for it and read it back through
28557
+ * `deviceState.getCapSlice` to reconcile — never a second copy, never a poll
28558
+ * against the device (D224, D8/D11).
28559
+ *
28560
+ * Deliberately NOT a `binary` sensor on the camera: a binary sensor is exported
28561
+ * to Home Assistant, HomeKit and the sensor picker as a thing an operator can
28562
+ * bind, and "the camera wants to record" is not a room sensor. It is a fact
28563
+ * about the camera, on the camera.
28564
+ */
28565
+ var RecordingSignalStatusSchema = object({
28566
+ /** True while the device asks to be recorded. */
28567
+ active: boolean(),
28568
+ /**
28569
+ * Why, in the provider's own vocabulary (a vacuum's `cleaning` / `docked`,
28570
+ * …). Free text for the log line and the UI badge; the recorder never
28571
+ * branches on it.
28572
+ */
28573
+ reason: string(),
28574
+ /** Ms epoch of the last `active` transition. 0 if never observed. */
28575
+ lastChangedAt: number()
28576
+ });
28577
+ RecordingSignalStatusSchema.extend({ lastFetchedAt: number() });
28578
+ DeviceType.Camera, method(object({ deviceId: number() }), RecordingSignalStatusSchema);
28579
+ /**
28501
28580
  * scene-monitor — device-scoped reference-region state cap. An operator marks
28502
28581
  * a rect ROI on a camera frame and names one or more states; the engine
28503
28582
  * (pipeline-analytics, designated post-processing node) reports which state is
@@ -28879,6 +28958,8 @@ var CamStreamDescriptorSchema = object({
28879
28958
  deviceFeatures: array(string()).optional(),
28880
28959
  /** Eligible for automatic profile assignment. Absent = `true`. */
28881
28960
  autoEligible: boolean().optional(),
28961
+ /** The slot the publisher says this stream IS — see `CameraStreamSchema.profileHint`. */
28962
+ profileHint: CamProfileSchema.optional(),
28882
28963
  /** Transport-specific opaque metadata (e.g. rfc4571 SDP). */
28883
28964
  metadata: record(string(), unknown()).optional()
28884
28965
  });
@@ -34840,6 +34921,12 @@ Object.freeze({
34840
34921
  addonId: null,
34841
34922
  access: "view"
34842
34923
  },
34924
+ "recordingSignal.getStatus": {
34925
+ capName: "recording-signal",
34926
+ capScope: "device",
34927
+ addonId: null,
34928
+ access: "view"
34929
+ },
34843
34930
  "sceneMonitor.captureReference": {
34844
34931
  capName: "scene-monitor",
34845
34932
  capScope: "device",
@@ -37832,6 +37919,11 @@ Object.freeze({
37832
37919
  form: "single",
37833
37920
  optional: true
37834
37921
  }],
37922
+ "recordingSignal.getStatus": [{
37923
+ name: "deviceId",
37924
+ form: "single",
37925
+ optional: false
37926
+ }],
37835
37927
  "sceneMonitor.captureReference": [{
37836
37928
  name: "deviceId",
37837
37929
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-export-hap",
3
- "version": "1.2.82",
3
+ "version": "1.2.84",
4
4
  "description": "HomeKit (HAP) exporter for CamStack devices. Publishes each exposed device as its own HomeKit accessory: cameras and doorbells with SRTP streaming, HomeKit Secure Video, motion, two-way audio, PTZ and battery; switches, lights, locks and sensors through a capability→service table.",
5
5
  "keywords": [
6
6
  "camstack",