@camstack/addon-provider-homeassistant 1.2.7 → 1.2.9
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 +117 -3
- package/dist/addon.mjs +117 -3
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
let node_crypto = require("node:crypto");
|
|
3
3
|
let node_zlib = require("node:zlib");
|
|
4
|
-
//#region ../types/dist/event-category-
|
|
4
|
+
//#region ../types/dist/event-category-Bz24uP1U.mjs
|
|
5
5
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
6
6
|
EventCategory["SystemBoot"] = "system.boot";
|
|
7
7
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -272,6 +272,19 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
272
272
|
*/
|
|
273
273
|
EventCategory["DeviceStateChanged"] = "device.state-changed";
|
|
274
274
|
/**
|
|
275
|
+
* Frame occupancy for a camera CHANGED — a tracked object was gained or
|
|
276
|
+
* lost. Carries `{ deviceId, totalObjects, byClass, zones }`.
|
|
277
|
+
*
|
|
278
|
+
* Emitted only on a change, so a steady scene is silent. It exists so a
|
|
279
|
+
* client can stop polling `zoneAnalytics.getCurrentSnapshot`: that was the
|
|
280
|
+
* one live badge with no push signal at all, and it cost a request every
|
|
281
|
+
* four seconds per visible camera.
|
|
282
|
+
*
|
|
283
|
+
* Like every event it is telemetry and may be dropped ([D8]) — a consumer
|
|
284
|
+
* keeps a slow reconcile rather than trusting it alone.
|
|
285
|
+
*/
|
|
286
|
+
EventCategory["ZoneAnalyticsOccupancyChanged"] = "zone-analytics.occupancy-changed";
|
|
287
|
+
/**
|
|
275
288
|
* Cap event fired by every device that registers the `battery`
|
|
276
289
|
* capability. Mirrors the cap definition's `onStatusChanged`. Carries
|
|
277
290
|
* `{ deviceId, status: BatteryStatus }`. Subscribers (alert center,
|
|
@@ -9637,6 +9650,29 @@ var NcOccupancyConditionSchema = object({
|
|
|
9637
9650
|
count: number().int().min(0).default(1),
|
|
9638
9651
|
sustainSeconds: number().int().min(0).max(3600).default(15)
|
|
9639
9652
|
});
|
|
9653
|
+
/**
|
|
9654
|
+
* Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
|
|
9655
|
+
*
|
|
9656
|
+
* The values are not symmetric, and deliberately so — the absent value has to
|
|
9657
|
+
* mean exactly what every rule authored before this condition existed already
|
|
9658
|
+
* does:
|
|
9659
|
+
* - `enter` — entries and every NON-crossing record (movement state,
|
|
9660
|
+
* package, sensor). Exits are rejected. **This is the absent behaviour**:
|
|
9661
|
+
* an operator who never asked for exits must not start receiving them.
|
|
9662
|
+
* - `exit` — ONLY an exit crossing. A record that is not a crossing at all
|
|
9663
|
+
* fails closed, because "the car left the drive" is a question about a
|
|
9664
|
+
* boundary, not about a detection.
|
|
9665
|
+
* - `any` — no direction filter; entries, exits and non-crossings alike.
|
|
9666
|
+
*
|
|
9667
|
+
* A rule asking for a direction should normally also scope `zones`, which the
|
|
9668
|
+
* engine evaluates against the crossed zone as well as the current membership
|
|
9669
|
+
* (an exit's membership no longer contains the zone it just left).
|
|
9670
|
+
*/
|
|
9671
|
+
var NcCrossingSchema = _enum([
|
|
9672
|
+
"enter",
|
|
9673
|
+
"exit",
|
|
9674
|
+
"any"
|
|
9675
|
+
]);
|
|
9640
9676
|
/** Admin-zone membership condition (zone IDs as stamped by the ZoneEngine). */
|
|
9641
9677
|
var NcZoneConditionSchema = object({
|
|
9642
9678
|
ids: array(string().min(1)).min(1),
|
|
@@ -9661,6 +9697,13 @@ var NcConditionsSchema = object({
|
|
|
9661
9697
|
/** Veto zones — any hit fails the rule. */
|
|
9662
9698
|
zonesExclude: array(string().min(1)).optional(),
|
|
9663
9699
|
/**
|
|
9700
|
+
* Zone-crossing direction. IMMEDIATE only — a crossing is a per-event fact
|
|
9701
|
+
* and a closed track carries none, so a `track-end` rule asking for one
|
|
9702
|
+
* fails closed (use `zones`, which tests `zonesVisited`). ABSENT = `enter`,
|
|
9703
|
+
* which is exactly today's behaviour. See {@link NcCrossingSchema}.
|
|
9704
|
+
*/
|
|
9705
|
+
crossing: NcCrossingSchema.optional(),
|
|
9706
|
+
/**
|
|
9664
9707
|
* Exact (case-insensitive) match on the record's collapsed `label`
|
|
9665
9708
|
* (identity name / plate text / subclass).
|
|
9666
9709
|
*/
|
|
@@ -9849,11 +9892,31 @@ var NcMediaPolicySchema = object({
|
|
|
9849
9892
|
*/
|
|
9850
9893
|
profile: CamProfileSchema.optional()
|
|
9851
9894
|
});
|
|
9895
|
+
/**
|
|
9896
|
+
* Cooldown GRANULARITY over the subject's class — how much a fired
|
|
9897
|
+
* notification suppresses.
|
|
9898
|
+
* - `shared` (default, and the absent value) — one window for the whole
|
|
9899
|
+
* rule/scope: a cat silences the next dog for `cooldownSec`.
|
|
9900
|
+
* - `per-class` — an independent window per detected class, so cat→dog fires
|
|
9901
|
+
* at once and cat→cat still waits.
|
|
9902
|
+
*
|
|
9903
|
+
* AUDIO subjects are ALWAYS per-class regardless of this setting: a scream
|
|
9904
|
+
* must not be swallowed by a bark's window (the precedent this generalizes —
|
|
9905
|
+
* see `cooldownKey` in the rule engine).
|
|
9906
|
+
*/
|
|
9907
|
+
var NcThrottleGranularitySchema = _enum(["shared", "per-class"]);
|
|
9852
9908
|
/** Throttle — cooldown survives restarts (rebuilt from the outbox on boot). */
|
|
9853
9909
|
var NcThrottleSchema = object({
|
|
9854
9910
|
cooldownSec: number().int().min(0).max(86400).default(60),
|
|
9855
9911
|
/** `rule` = one shared cooldown; `rule-device` = per-camera cooldown. */
|
|
9856
|
-
scope: _enum(["rule", "rule-device"]).default("rule-device")
|
|
9912
|
+
scope: _enum(["rule", "rule-device"]).default("rule-device"),
|
|
9913
|
+
/**
|
|
9914
|
+
* Class granularity of the cooldown key. Optional rather than defaulted:
|
|
9915
|
+
* a Zod default does NOT run on the addon→addon cap path, so a persisted
|
|
9916
|
+
* rule authored before this field simply carries none — and the engine
|
|
9917
|
+
* reads absent as `shared`, the pre-existing behaviour.
|
|
9918
|
+
*/
|
|
9919
|
+
granularity: NcThrottleGranularitySchema.optional()
|
|
9857
9920
|
});
|
|
9858
9921
|
/** Client-supplied rule fields (server stamps id/createdBy/createdAt/updatedAt). */
|
|
9859
9922
|
var NcRuleInputSchema = object({
|
|
@@ -9961,6 +10024,7 @@ var NcConditionDescriptorSchema = object({
|
|
|
9961
10024
|
"schedule",
|
|
9962
10025
|
"plateMatcher",
|
|
9963
10026
|
"packagePhase",
|
|
10027
|
+
"crossingSelect",
|
|
9964
10028
|
"polygonDraw",
|
|
9965
10029
|
"occupancy"
|
|
9966
10030
|
]),
|
|
@@ -14296,6 +14360,18 @@ var motionCapability = {
|
|
|
14296
14360
|
name: "motion",
|
|
14297
14361
|
scope: "device",
|
|
14298
14362
|
mode: "singleton",
|
|
14363
|
+
/**
|
|
14364
|
+
* Providers register per-device natives via `ctx.registerNativeCap`
|
|
14365
|
+
* (Hikvision/Reolink/Amcrest/Wyze/HA/Homematic/Alexa/Matter) — there is
|
|
14366
|
+
* NO system singleton provider. Without this flag `resolveCapMount`
|
|
14367
|
+
* derived `{ kind: 'singleton' }`, so `motion.getStatus`/`isDetected`
|
|
14368
|
+
* resolved via `registry.getSingleton('motion')` (always null) and every
|
|
14369
|
+
* call 412'd "provider not available" while bindings listed a live
|
|
14370
|
+
* `motion` native (2026-08-02). The flag routes the router through
|
|
14371
|
+
* `requireDeviceScoped` → `getProviderForDevice`, like `motion-trigger`,
|
|
14372
|
+
* `snapshot` and every other per-device native cap.
|
|
14373
|
+
*/
|
|
14374
|
+
deviceNative: true,
|
|
14299
14375
|
deviceTypes: [DeviceType.Camera, DeviceType.Sensor],
|
|
14300
14376
|
methods: {
|
|
14301
14377
|
/**
|
|
@@ -19313,7 +19389,10 @@ method(object({
|
|
|
19313
19389
|
}), method(object({
|
|
19314
19390
|
deviceId: number(),
|
|
19315
19391
|
caps: array(string()).readonly().optional()
|
|
19316
|
-
}), record(string(), unknown().nullable()))
|
|
19392
|
+
}), record(string(), unknown().nullable())), method(object({
|
|
19393
|
+
deviceIds: array(number()).readonly(),
|
|
19394
|
+
caps: array(string()).readonly().optional()
|
|
19395
|
+
}), record(string(), record(string(), unknown().nullable())));
|
|
19317
19396
|
method(object({ deviceId: number() }), record(string(), record(string(), unknown()))), method(object({
|
|
19318
19397
|
deviceId: number(),
|
|
19319
19398
|
capName: string()
|
|
@@ -20735,6 +20814,29 @@ var MotionEventSchema = object({
|
|
|
20735
20814
|
* Absent on legacy rows ⇒ treat as `pipeline`.
|
|
20736
20815
|
*/
|
|
20737
20816
|
var DetectionSourceSchema = _enum(["pipeline", "onboard"]);
|
|
20817
|
+
/**
|
|
20818
|
+
* The confirmed zone crossing that produced an object event. Present ONLY on
|
|
20819
|
+
* an event emitted BY a crossing (`zone.enter` / `zone.exit`); a movement-state
|
|
20820
|
+
* event (`object.entering` / `leaving` / `stationary` / `loitering`) and an
|
|
20821
|
+
* appearance event carry none, so a rule asking for a direction fails closed
|
|
20822
|
+
* on them.
|
|
20823
|
+
*
|
|
20824
|
+
* Exactly ONE crossing per event: the emitter turns each confirmed crossing
|
|
20825
|
+
* into its own event, so a frame in which a track enters A while leaving B
|
|
20826
|
+
* produces two events with two directions — never one ambiguous row.
|
|
20827
|
+
*
|
|
20828
|
+
* `zoneId` is load-bearing for an EXIT: the event's `zones` list is the
|
|
20829
|
+
* membership the box has NOW, and by definition it no longer contains the zone
|
|
20830
|
+
* that was just left. Without the id here, a zone-scoped rule could never match
|
|
20831
|
+
* the exit it asked for.
|
|
20832
|
+
*/
|
|
20833
|
+
var ZoneCrossingSchema = object({
|
|
20834
|
+
direction: _enum(["enter", "exit"]),
|
|
20835
|
+
/** Admin zone id crossed. */
|
|
20836
|
+
zoneId: string(),
|
|
20837
|
+
/** Zone display name at crossing time (falls back to the id). */
|
|
20838
|
+
zoneName: string().optional()
|
|
20839
|
+
});
|
|
20738
20840
|
var ObjectEventSchema = object({
|
|
20739
20841
|
...BaseEventFields,
|
|
20740
20842
|
kind: literal("object"),
|
|
@@ -20761,6 +20863,12 @@ var ObjectEventSchema = object({
|
|
|
20761
20863
|
zones: array(string()).readonly().optional(),
|
|
20762
20864
|
/** Omitted in slim projection. */
|
|
20763
20865
|
state: TrackStateSchema.optional(),
|
|
20866
|
+
/**
|
|
20867
|
+
* The zone crossing this event IS, when it is one. Absent on every other
|
|
20868
|
+
* event kind (movement state, appearance, package) — see
|
|
20869
|
+
* {@link ZoneCrossingSchema}. Omitted in slim projection.
|
|
20870
|
+
*/
|
|
20871
|
+
zoneCrossing: ZoneCrossingSchema.optional(),
|
|
20764
20872
|
/** Detection-frame dimensions in pixels — let consumers normalize the
|
|
20765
20873
|
* pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
|
|
20766
20874
|
frameWidth: number().optional(),
|
|
@@ -26174,6 +26282,12 @@ Object.freeze({
|
|
|
26174
26282
|
addonId: null,
|
|
26175
26283
|
access: "view"
|
|
26176
26284
|
},
|
|
26285
|
+
"deviceManager.getDeviceStatusAggregateBatch": {
|
|
26286
|
+
capName: "device-manager",
|
|
26287
|
+
capScope: "system",
|
|
26288
|
+
addonId: null,
|
|
26289
|
+
access: "view"
|
|
26290
|
+
},
|
|
26177
26291
|
"deviceManager.getLinkedDevices": {
|
|
26178
26292
|
capName: "device-manager",
|
|
26179
26293
|
capScope: "system",
|
package/dist/addon.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
|
|
3
|
-
//#region ../types/dist/event-category-
|
|
3
|
+
//#region ../types/dist/event-category-Bz24uP1U.mjs
|
|
4
4
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
5
5
|
EventCategory["SystemBoot"] = "system.boot";
|
|
6
6
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -271,6 +271,19 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
271
271
|
*/
|
|
272
272
|
EventCategory["DeviceStateChanged"] = "device.state-changed";
|
|
273
273
|
/**
|
|
274
|
+
* Frame occupancy for a camera CHANGED — a tracked object was gained or
|
|
275
|
+
* lost. Carries `{ deviceId, totalObjects, byClass, zones }`.
|
|
276
|
+
*
|
|
277
|
+
* Emitted only on a change, so a steady scene is silent. It exists so a
|
|
278
|
+
* client can stop polling `zoneAnalytics.getCurrentSnapshot`: that was the
|
|
279
|
+
* one live badge with no push signal at all, and it cost a request every
|
|
280
|
+
* four seconds per visible camera.
|
|
281
|
+
*
|
|
282
|
+
* Like every event it is telemetry and may be dropped ([D8]) — a consumer
|
|
283
|
+
* keeps a slow reconcile rather than trusting it alone.
|
|
284
|
+
*/
|
|
285
|
+
EventCategory["ZoneAnalyticsOccupancyChanged"] = "zone-analytics.occupancy-changed";
|
|
286
|
+
/**
|
|
274
287
|
* Cap event fired by every device that registers the `battery`
|
|
275
288
|
* capability. Mirrors the cap definition's `onStatusChanged`. Carries
|
|
276
289
|
* `{ deviceId, status: BatteryStatus }`. Subscribers (alert center,
|
|
@@ -9636,6 +9649,29 @@ var NcOccupancyConditionSchema = object({
|
|
|
9636
9649
|
count: number().int().min(0).default(1),
|
|
9637
9650
|
sustainSeconds: number().int().min(0).max(3600).default(15)
|
|
9638
9651
|
});
|
|
9652
|
+
/**
|
|
9653
|
+
* Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
|
|
9654
|
+
*
|
|
9655
|
+
* The values are not symmetric, and deliberately so — the absent value has to
|
|
9656
|
+
* mean exactly what every rule authored before this condition existed already
|
|
9657
|
+
* does:
|
|
9658
|
+
* - `enter` — entries and every NON-crossing record (movement state,
|
|
9659
|
+
* package, sensor). Exits are rejected. **This is the absent behaviour**:
|
|
9660
|
+
* an operator who never asked for exits must not start receiving them.
|
|
9661
|
+
* - `exit` — ONLY an exit crossing. A record that is not a crossing at all
|
|
9662
|
+
* fails closed, because "the car left the drive" is a question about a
|
|
9663
|
+
* boundary, not about a detection.
|
|
9664
|
+
* - `any` — no direction filter; entries, exits and non-crossings alike.
|
|
9665
|
+
*
|
|
9666
|
+
* A rule asking for a direction should normally also scope `zones`, which the
|
|
9667
|
+
* engine evaluates against the crossed zone as well as the current membership
|
|
9668
|
+
* (an exit's membership no longer contains the zone it just left).
|
|
9669
|
+
*/
|
|
9670
|
+
var NcCrossingSchema = _enum([
|
|
9671
|
+
"enter",
|
|
9672
|
+
"exit",
|
|
9673
|
+
"any"
|
|
9674
|
+
]);
|
|
9639
9675
|
/** Admin-zone membership condition (zone IDs as stamped by the ZoneEngine). */
|
|
9640
9676
|
var NcZoneConditionSchema = object({
|
|
9641
9677
|
ids: array(string().min(1)).min(1),
|
|
@@ -9660,6 +9696,13 @@ var NcConditionsSchema = object({
|
|
|
9660
9696
|
/** Veto zones — any hit fails the rule. */
|
|
9661
9697
|
zonesExclude: array(string().min(1)).optional(),
|
|
9662
9698
|
/**
|
|
9699
|
+
* Zone-crossing direction. IMMEDIATE only — a crossing is a per-event fact
|
|
9700
|
+
* and a closed track carries none, so a `track-end` rule asking for one
|
|
9701
|
+
* fails closed (use `zones`, which tests `zonesVisited`). ABSENT = `enter`,
|
|
9702
|
+
* which is exactly today's behaviour. See {@link NcCrossingSchema}.
|
|
9703
|
+
*/
|
|
9704
|
+
crossing: NcCrossingSchema.optional(),
|
|
9705
|
+
/**
|
|
9663
9706
|
* Exact (case-insensitive) match on the record's collapsed `label`
|
|
9664
9707
|
* (identity name / plate text / subclass).
|
|
9665
9708
|
*/
|
|
@@ -9848,11 +9891,31 @@ var NcMediaPolicySchema = object({
|
|
|
9848
9891
|
*/
|
|
9849
9892
|
profile: CamProfileSchema.optional()
|
|
9850
9893
|
});
|
|
9894
|
+
/**
|
|
9895
|
+
* Cooldown GRANULARITY over the subject's class — how much a fired
|
|
9896
|
+
* notification suppresses.
|
|
9897
|
+
* - `shared` (default, and the absent value) — one window for the whole
|
|
9898
|
+
* rule/scope: a cat silences the next dog for `cooldownSec`.
|
|
9899
|
+
* - `per-class` — an independent window per detected class, so cat→dog fires
|
|
9900
|
+
* at once and cat→cat still waits.
|
|
9901
|
+
*
|
|
9902
|
+
* AUDIO subjects are ALWAYS per-class regardless of this setting: a scream
|
|
9903
|
+
* must not be swallowed by a bark's window (the precedent this generalizes —
|
|
9904
|
+
* see `cooldownKey` in the rule engine).
|
|
9905
|
+
*/
|
|
9906
|
+
var NcThrottleGranularitySchema = _enum(["shared", "per-class"]);
|
|
9851
9907
|
/** Throttle — cooldown survives restarts (rebuilt from the outbox on boot). */
|
|
9852
9908
|
var NcThrottleSchema = object({
|
|
9853
9909
|
cooldownSec: number().int().min(0).max(86400).default(60),
|
|
9854
9910
|
/** `rule` = one shared cooldown; `rule-device` = per-camera cooldown. */
|
|
9855
|
-
scope: _enum(["rule", "rule-device"]).default("rule-device")
|
|
9911
|
+
scope: _enum(["rule", "rule-device"]).default("rule-device"),
|
|
9912
|
+
/**
|
|
9913
|
+
* Class granularity of the cooldown key. Optional rather than defaulted:
|
|
9914
|
+
* a Zod default does NOT run on the addon→addon cap path, so a persisted
|
|
9915
|
+
* rule authored before this field simply carries none — and the engine
|
|
9916
|
+
* reads absent as `shared`, the pre-existing behaviour.
|
|
9917
|
+
*/
|
|
9918
|
+
granularity: NcThrottleGranularitySchema.optional()
|
|
9856
9919
|
});
|
|
9857
9920
|
/** Client-supplied rule fields (server stamps id/createdBy/createdAt/updatedAt). */
|
|
9858
9921
|
var NcRuleInputSchema = object({
|
|
@@ -9960,6 +10023,7 @@ var NcConditionDescriptorSchema = object({
|
|
|
9960
10023
|
"schedule",
|
|
9961
10024
|
"plateMatcher",
|
|
9962
10025
|
"packagePhase",
|
|
10026
|
+
"crossingSelect",
|
|
9963
10027
|
"polygonDraw",
|
|
9964
10028
|
"occupancy"
|
|
9965
10029
|
]),
|
|
@@ -14295,6 +14359,18 @@ var motionCapability = {
|
|
|
14295
14359
|
name: "motion",
|
|
14296
14360
|
scope: "device",
|
|
14297
14361
|
mode: "singleton",
|
|
14362
|
+
/**
|
|
14363
|
+
* Providers register per-device natives via `ctx.registerNativeCap`
|
|
14364
|
+
* (Hikvision/Reolink/Amcrest/Wyze/HA/Homematic/Alexa/Matter) — there is
|
|
14365
|
+
* NO system singleton provider. Without this flag `resolveCapMount`
|
|
14366
|
+
* derived `{ kind: 'singleton' }`, so `motion.getStatus`/`isDetected`
|
|
14367
|
+
* resolved via `registry.getSingleton('motion')` (always null) and every
|
|
14368
|
+
* call 412'd "provider not available" while bindings listed a live
|
|
14369
|
+
* `motion` native (2026-08-02). The flag routes the router through
|
|
14370
|
+
* `requireDeviceScoped` → `getProviderForDevice`, like `motion-trigger`,
|
|
14371
|
+
* `snapshot` and every other per-device native cap.
|
|
14372
|
+
*/
|
|
14373
|
+
deviceNative: true,
|
|
14298
14374
|
deviceTypes: [DeviceType.Camera, DeviceType.Sensor],
|
|
14299
14375
|
methods: {
|
|
14300
14376
|
/**
|
|
@@ -19312,7 +19388,10 @@ method(object({
|
|
|
19312
19388
|
}), method(object({
|
|
19313
19389
|
deviceId: number(),
|
|
19314
19390
|
caps: array(string()).readonly().optional()
|
|
19315
|
-
}), record(string(), unknown().nullable()))
|
|
19391
|
+
}), record(string(), unknown().nullable())), method(object({
|
|
19392
|
+
deviceIds: array(number()).readonly(),
|
|
19393
|
+
caps: array(string()).readonly().optional()
|
|
19394
|
+
}), record(string(), record(string(), unknown().nullable())));
|
|
19316
19395
|
method(object({ deviceId: number() }), record(string(), record(string(), unknown()))), method(object({
|
|
19317
19396
|
deviceId: number(),
|
|
19318
19397
|
capName: string()
|
|
@@ -20734,6 +20813,29 @@ var MotionEventSchema = object({
|
|
|
20734
20813
|
* Absent on legacy rows ⇒ treat as `pipeline`.
|
|
20735
20814
|
*/
|
|
20736
20815
|
var DetectionSourceSchema = _enum(["pipeline", "onboard"]);
|
|
20816
|
+
/**
|
|
20817
|
+
* The confirmed zone crossing that produced an object event. Present ONLY on
|
|
20818
|
+
* an event emitted BY a crossing (`zone.enter` / `zone.exit`); a movement-state
|
|
20819
|
+
* event (`object.entering` / `leaving` / `stationary` / `loitering`) and an
|
|
20820
|
+
* appearance event carry none, so a rule asking for a direction fails closed
|
|
20821
|
+
* on them.
|
|
20822
|
+
*
|
|
20823
|
+
* Exactly ONE crossing per event: the emitter turns each confirmed crossing
|
|
20824
|
+
* into its own event, so a frame in which a track enters A while leaving B
|
|
20825
|
+
* produces two events with two directions — never one ambiguous row.
|
|
20826
|
+
*
|
|
20827
|
+
* `zoneId` is load-bearing for an EXIT: the event's `zones` list is the
|
|
20828
|
+
* membership the box has NOW, and by definition it no longer contains the zone
|
|
20829
|
+
* that was just left. Without the id here, a zone-scoped rule could never match
|
|
20830
|
+
* the exit it asked for.
|
|
20831
|
+
*/
|
|
20832
|
+
var ZoneCrossingSchema = object({
|
|
20833
|
+
direction: _enum(["enter", "exit"]),
|
|
20834
|
+
/** Admin zone id crossed. */
|
|
20835
|
+
zoneId: string(),
|
|
20836
|
+
/** Zone display name at crossing time (falls back to the id). */
|
|
20837
|
+
zoneName: string().optional()
|
|
20838
|
+
});
|
|
20737
20839
|
var ObjectEventSchema = object({
|
|
20738
20840
|
...BaseEventFields,
|
|
20739
20841
|
kind: literal("object"),
|
|
@@ -20760,6 +20862,12 @@ var ObjectEventSchema = object({
|
|
|
20760
20862
|
zones: array(string()).readonly().optional(),
|
|
20761
20863
|
/** Omitted in slim projection. */
|
|
20762
20864
|
state: TrackStateSchema.optional(),
|
|
20865
|
+
/**
|
|
20866
|
+
* The zone crossing this event IS, when it is one. Absent on every other
|
|
20867
|
+
* event kind (movement state, appearance, package) — see
|
|
20868
|
+
* {@link ZoneCrossingSchema}. Omitted in slim projection.
|
|
20869
|
+
*/
|
|
20870
|
+
zoneCrossing: ZoneCrossingSchema.optional(),
|
|
20763
20871
|
/** Detection-frame dimensions in pixels — let consumers normalize the
|
|
20764
20872
|
* pixel-space `bbox` onto a displayed image. Omitted in slim projection. */
|
|
20765
20873
|
frameWidth: number().optional(),
|
|
@@ -26173,6 +26281,12 @@ Object.freeze({
|
|
|
26173
26281
|
addonId: null,
|
|
26174
26282
|
access: "view"
|
|
26175
26283
|
},
|
|
26284
|
+
"deviceManager.getDeviceStatusAggregateBatch": {
|
|
26285
|
+
capName: "device-manager",
|
|
26286
|
+
capScope: "system",
|
|
26287
|
+
addonId: null,
|
|
26288
|
+
access: "view"
|
|
26289
|
+
},
|
|
26176
26290
|
"deviceManager.getLinkedDevices": {
|
|
26177
26291
|
capName: "device-manager",
|
|
26178
26292
|
capScope: "system",
|