@camstack/addon-export-alexa 1.2.123 → 1.2.124
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/export-alexa.addon.js +153 -89
- package/dist/export-alexa.addon.mjs +153 -89
- package/package.json +1 -1
|
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
//#endregion
|
|
27
27
|
let node_crypto = require("node:crypto");
|
|
28
28
|
node_crypto = __toESM(node_crypto, 1);
|
|
29
|
-
//#region ../types/dist/event-category-
|
|
29
|
+
//#region ../types/dist/event-category-BGmz_oxW.mjs
|
|
30
30
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
31
31
|
EventCategory["SystemBoot"] = "system.boot";
|
|
32
32
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -559,6 +559,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
559
559
|
*/
|
|
560
560
|
EventCategory["PipelineAudioInferenceResult"] = "pipeline.audio-inference-result";
|
|
561
561
|
EventCategory["DetectionPhaseTransition"] = "detection.phase-transition";
|
|
562
|
+
/**
|
|
563
|
+
* A camera provider's RAW onboard motion push (D673): the `MotionOnMotionChanged`
|
|
564
|
+
* data shape without `triggeredBy`, built by `providerMotionEvent`. Its one
|
|
565
|
+
* consumer is the orchestrator's camera-sensors bridge, which re-emits the
|
|
566
|
+
* camera's EFFECTIVE onboard motion as `MotionOnMotionChanged` (a pass-through
|
|
567
|
+
* for a camera with no attached sensor). Providers must not emit
|
|
568
|
+
* `MotionOnMotionChanged` themselves; `scripts/check-onboard-motion-emitters.ts`
|
|
569
|
+
* keeps it so (camera-grid is a named, deferred exception).
|
|
570
|
+
*/
|
|
562
571
|
EventCategory["ProviderMotion"] = "provider.motion";
|
|
563
572
|
EventCategory["ProviderDetection"] = "provider.detection";
|
|
564
573
|
EventCategory["EnrichmentEmbeddingStored"] = "enrichment.embedding.stored";
|
|
@@ -5397,7 +5406,7 @@ var ZodIssueCode = {
|
|
|
5397
5406
|
var ZodFirstPartyTypeKind;
|
|
5398
5407
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5399
5408
|
//#endregion
|
|
5400
|
-
//#region ../types/dist/sleep-
|
|
5409
|
+
//#region ../types/dist/sleep-CDCONfkt.mjs
|
|
5401
5410
|
/**
|
|
5402
5411
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5403
5412
|
* window to float samples (D455).
|
|
@@ -7458,7 +7467,7 @@ function errMsg(err) {
|
|
|
7458
7467
|
return String(err);
|
|
7459
7468
|
}
|
|
7460
7469
|
//#endregion
|
|
7461
|
-
//#region ../types/dist/composition-
|
|
7470
|
+
//#region ../types/dist/composition-43aqsZQj.mjs
|
|
7462
7471
|
/**
|
|
7463
7472
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
7464
7473
|
*
|
|
@@ -7515,13 +7524,12 @@ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac
|
|
|
7515
7524
|
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
7516
7525
|
* valutatore puro del suo FRONTE.
|
|
7517
7526
|
*
|
|
7518
|
-
*
|
|
7519
|
-
*
|
|
7520
|
-
*
|
|
7521
|
-
*
|
|
7522
|
-
*
|
|
7523
|
-
* fa suonare il campanello ma non registra" — è esattamente D62.
|
|
7524
|
-
* SPOSTA qui e il doorbell la ri-esporta.
|
|
7527
|
+
* UNA tabella per tutti quelli che chiedono "questo device è ALTO?": il
|
|
7528
|
+
* trigger `RecordingTriggers.sensorDeviceIds` del recorder, i marker dei
|
|
7529
|
+
* sensori della post-analysis, il bridge camera-sensors dell'orchestratore e
|
|
7530
|
+
* le sorgenti di un campanello composto (`doorbellFeatureSources`, D671).
|
|
7531
|
+
* Una seconda copia divergerebbe alla prima cap aggiunta, e il sintomo — "il
|
|
7532
|
+
* sensore fa suonare il campanello ma non registra" — è esattamente D62.
|
|
7525
7533
|
*
|
|
7526
7534
|
* ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
|
|
7527
7535
|
* due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
|
|
@@ -9425,7 +9433,7 @@ var RecordingTriggersSchema = object({
|
|
|
9425
9433
|
*
|
|
9426
9434
|
* Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
|
|
9427
9435
|
* `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
|
|
9428
|
-
* la stessa
|
|
9436
|
+
* la stessa del campanello composto (D671). Ed è il FRONTE, non
|
|
9429
9437
|
* il livello: un contatto trovato già aperto al riavvio del runner non fa
|
|
9430
9438
|
* registrare.
|
|
9431
9439
|
*/
|
|
@@ -15650,28 +15658,10 @@ method(object({
|
|
|
15650
15658
|
deviceIds: array(number()).readonly(),
|
|
15651
15659
|
caps: array(string()).readonly().optional()
|
|
15652
15660
|
}), record(string(), record(string(), unknown().nullable())));
|
|
15653
|
-
|
|
15654
|
-
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
15655
|
-
lastPressedAt: number().nullable(),
|
|
15656
|
-
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
15657
|
-
pressCountSinceStart: number()
|
|
15658
|
-
});
|
|
15659
|
-
object({
|
|
15660
|
-
deviceId: number(),
|
|
15661
|
-
timestamp: number()
|
|
15662
|
-
});
|
|
15663
|
-
/**
|
|
15664
|
-
* The `doorbell-source` extension slot's editable value (D648): the camera's
|
|
15665
|
-
* virtual-doorbell trigger devices, exactly what the wrapper's
|
|
15666
|
-
* `doorbellSources` persists (as `{ deviceId }` records).
|
|
15667
|
-
*/
|
|
15668
|
-
var DoorbellSourceSlotValueSchema = object({ deviceIds: array(number().int().positive()) });
|
|
15661
|
+
var ExtensionSlotIdSchema = _enum(["linked-devices"]);
|
|
15669
15662
|
DeviceType.Camera;
|
|
15670
|
-
DeviceType.Button, DeviceType.Camera;
|
|
15671
|
-
var ExtensionSlotIdSchema = _enum(["doorbell-source", "linked-devices"]);
|
|
15672
|
-
DeviceType.Camera, DeviceType.Camera;
|
|
15673
15663
|
/** A slot's editable value, discriminated on `slot`. */
|
|
15674
|
-
var ExtensionSlotValueSchema = discriminatedUnion("slot", [
|
|
15664
|
+
var ExtensionSlotValueSchema = discriminatedUnion("slot", [LinkedDevicesSlotValueSchema.extend({ slot: literal("linked-devices") })]);
|
|
15675
15665
|
DeviceType.Camera;
|
|
15676
15666
|
var ExtensionSourceAvailabilitySchema = discriminatedUnion("state", [object({ state: literal("ok") }), object({
|
|
15677
15667
|
state: literal("unreachable"),
|
|
@@ -15708,10 +15698,11 @@ var ExtensionSlotSourceSchema = object({
|
|
|
15708
15698
|
});
|
|
15709
15699
|
/**
|
|
15710
15700
|
* A DIFFERENT authority that gates whether the slot's sources do anything —
|
|
15711
|
-
* reported read-only, named, never written through this contract (D62).
|
|
15712
|
-
*
|
|
15713
|
-
*
|
|
15714
|
-
* `unknown` means the gate could
|
|
15701
|
+
* reported read-only, named, never written through this contract (D62) — e.g.
|
|
15702
|
+
* a slot whose sources act only while a wrapper is bound to the host, a
|
|
15703
|
+
* binding that belongs to `deviceManager.setWrapperActive`. No slot reports
|
|
15704
|
+
* one today (`linked-devices` answers `null`). `unknown` means the gate could
|
|
15705
|
+
* not be read; it is not "inactive" (D315).
|
|
15715
15706
|
*/
|
|
15716
15707
|
var ExtensionSlotActivationSchema = object({
|
|
15717
15708
|
state: _enum([
|
|
@@ -15727,7 +15718,7 @@ var ExtensionSlotRowSchema = discriminatedUnion("state", [object({
|
|
|
15727
15718
|
/** `<source>:<slotId>` — the routing key for `listCandidates` / `setSlot`. */
|
|
15728
15719
|
slotRef: string(),
|
|
15729
15720
|
slot: ExtensionSlotIdSchema,
|
|
15730
|
-
/** Names the store written (D62), e.g. `
|
|
15721
|
+
/** Names the store written (D62), e.g. `device-manager:_linkedDeviceIds`. */
|
|
15731
15722
|
authority: string(),
|
|
15732
15723
|
activation: ExtensionSlotActivationSchema.nullable(),
|
|
15733
15724
|
value: ExtensionSlotValueSchema,
|
|
@@ -20827,12 +20818,26 @@ var CameraSensorRefSchema = object({
|
|
|
20827
20818
|
function cameraSensorRefKey(ref) {
|
|
20828
20819
|
return `${ref.addonId}/${ref.stableId}`;
|
|
20829
20820
|
}
|
|
20830
|
-
/**
|
|
20831
|
-
|
|
20832
|
-
|
|
20833
|
-
|
|
20834
|
-
|
|
20835
|
-
|
|
20821
|
+
/**
|
|
20822
|
+
* A sensor's mode (D673). `in-addition`: its motion is the camera's motion too.
|
|
20823
|
+
* `replace`: its motion is the camera's, and while one is READY the camera's
|
|
20824
|
+
* own motion no longer counts on its own. `confirm`: while one is READY the
|
|
20825
|
+
* camera's own motion counts only while a confirm sensor is active — with or
|
|
20826
|
+
* without a replace sensor (spec C2, the controller's ruling on Q1).
|
|
20827
|
+
*/
|
|
20828
|
+
var CameraSensorModeSchema = _enum([
|
|
20829
|
+
"in-addition",
|
|
20830
|
+
"confirm",
|
|
20831
|
+
"replace"
|
|
20832
|
+
]);
|
|
20833
|
+
/** A stored sensor with no mode — every CS-1 row — is in addition. */
|
|
20834
|
+
var DEFAULT_CAMERA_SENSOR_MODE = "in-addition";
|
|
20835
|
+
/**
|
|
20836
|
+
* A camera's attached sensors. A CS-1 row carried an envelope
|
|
20837
|
+
* `mode: 'in-addition'`: `z.object` drops it on parse, and the PARSED value is
|
|
20838
|
+
* what the write stores (D672 rule 3), so it is never written again.
|
|
20839
|
+
*/
|
|
20840
|
+
var CameraSensorsConfigSchema = object({ sensors: array(CameraSensorRefSchema.extend({ mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE) })).min(1).max(8) }).superRefine((value, ctx) => {
|
|
20836
20841
|
const seen = /* @__PURE__ */ new Set();
|
|
20837
20842
|
value.sensors.forEach((ref, index) => {
|
|
20838
20843
|
const key = cameraSensorRefKey(ref);
|
|
@@ -20844,39 +20849,41 @@ var CameraSensorsConfigSchema = object({
|
|
|
20844
20849
|
seen.add(key);
|
|
20845
20850
|
});
|
|
20846
20851
|
});
|
|
20847
|
-
|
|
20852
|
+
/** Every attachment names its mode; an older orchestrator that does not is in addition. */
|
|
20853
|
+
var AttachmentFields = {
|
|
20848
20854
|
addonId: string(),
|
|
20849
|
-
stableId: string()
|
|
20855
|
+
stableId: string(),
|
|
20856
|
+
mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE)
|
|
20850
20857
|
};
|
|
20851
20858
|
var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
20852
20859
|
object({
|
|
20853
|
-
...
|
|
20860
|
+
...AttachmentFields,
|
|
20854
20861
|
state: literal("ready"),
|
|
20855
20862
|
deviceId: number(),
|
|
20856
20863
|
name: string(),
|
|
20857
20864
|
caps: array(string()).readonly()
|
|
20858
20865
|
}),
|
|
20859
20866
|
object({
|
|
20860
|
-
...
|
|
20867
|
+
...AttachmentFields,
|
|
20861
20868
|
state: literal("offline"),
|
|
20862
20869
|
deviceId: number(),
|
|
20863
20870
|
name: string(),
|
|
20864
20871
|
reason: _enum(["offline", "disabled"])
|
|
20865
20872
|
}),
|
|
20866
20873
|
object({
|
|
20867
|
-
...
|
|
20874
|
+
...AttachmentFields,
|
|
20868
20875
|
state: literal("missing"),
|
|
20869
20876
|
reason: string()
|
|
20870
20877
|
}),
|
|
20871
20878
|
object({
|
|
20872
|
-
...
|
|
20879
|
+
...AttachmentFields,
|
|
20873
20880
|
state: literal("unsupported"),
|
|
20874
20881
|
deviceId: number(),
|
|
20875
20882
|
name: string(),
|
|
20876
20883
|
reason: string()
|
|
20877
20884
|
}),
|
|
20878
20885
|
object({
|
|
20879
|
-
...
|
|
20886
|
+
...AttachmentFields,
|
|
20880
20887
|
state: literal("unreadable"),
|
|
20881
20888
|
reason: string()
|
|
20882
20889
|
})
|
|
@@ -20889,17 +20896,49 @@ var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
|
20889
20896
|
* say.
|
|
20890
20897
|
*/
|
|
20891
20898
|
var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
|
|
20899
|
+
/** Whether the camera's OWN motion counts on its own (D673 C2), from its READY sensors (C3). */
|
|
20900
|
+
var CameraOwnMotionSchema = _enum([
|
|
20901
|
+
"always",
|
|
20902
|
+
"when-confirmed",
|
|
20903
|
+
"never"
|
|
20904
|
+
]);
|
|
20905
|
+
/** Confirm / Replace cannot suppress this camera's motion: its provider still emits it directly (D673 C13). */
|
|
20906
|
+
var CameraSensorsNotEnforcedSchema = _enum(["provider-not-split"]);
|
|
20907
|
+
/**
|
|
20908
|
+
* The camera's OWN onboard motion (D696): the raw input the bridge combines,
|
|
20909
|
+
* never the effective value. The camera's `motion` slice is the effective one,
|
|
20910
|
+
* so a view of the camera's own row reads this.
|
|
20911
|
+
* - `atMs`: when the bridge received the camera's last own edge.
|
|
20912
|
+
* - `detected`: evaluated WHEN THE STATUS IS ASKED — the last edge said `true`
|
|
20913
|
+
* AND it is younger than the window the bridge counts the camera's own motion
|
|
20914
|
+
* for (`motionCooldownMs`, floored at two sustain ticks). A camera that never
|
|
20915
|
+
* sends a clear (heartbeats only) therefore reads `false` once no push came
|
|
20916
|
+
* within the window; a status read is a snapshot, so a live view re-asks.
|
|
20917
|
+
* Absent = this orchestrator has not received the camera's own motion since it
|
|
20918
|
+
* started (unknown, never "quiet"), or an orchestrator older than D696.
|
|
20919
|
+
*/
|
|
20920
|
+
var CameraRawLevelSchema = object({
|
|
20921
|
+
detected: boolean(),
|
|
20922
|
+
atMs: number()
|
|
20923
|
+
});
|
|
20892
20924
|
var CameraSensorsStatusSchema = discriminatedUnion("state", [
|
|
20893
|
-
object({
|
|
20925
|
+
object({
|
|
20926
|
+
state: literal("not-configured"),
|
|
20927
|
+
cameraLevel: CameraRawLevelSchema.optional()
|
|
20928
|
+
}),
|
|
20894
20929
|
object({
|
|
20895
20930
|
state: literal("unreadable"),
|
|
20896
|
-
reason: string()
|
|
20931
|
+
reason: string(),
|
|
20932
|
+
cameraLevel: CameraRawLevelSchema.optional()
|
|
20897
20933
|
}),
|
|
20898
20934
|
object({
|
|
20899
20935
|
state: literal("configured"),
|
|
20900
|
-
|
|
20936
|
+
cameraLevel: CameraRawLevelSchema.optional(),
|
|
20901
20937
|
sensors: array(CameraSensorAttachmentSchema).readonly(),
|
|
20902
|
-
|
|
20938
|
+
/** Absent = an orchestrator older than CS-2: it does not say (D315). */
|
|
20939
|
+
cameraMotion: CameraOwnMotionSchema.optional(),
|
|
20940
|
+
notForwarded: CameraSensorsNotForwardedSchema.optional(),
|
|
20941
|
+
notEnforced: CameraSensorsNotEnforcedSchema.optional()
|
|
20903
20942
|
})
|
|
20904
20943
|
]);
|
|
20905
20944
|
Object.freeze({
|
|
@@ -24090,8 +24129,10 @@ var RunnerCameraConfigSchema = object({
|
|
|
24090
24129
|
* - `analyzer`: ML/frame-diff motion detection (motion-wasm or other
|
|
24091
24130
|
* analyzer providers) running on decoded frames in this runner.
|
|
24092
24131
|
* - `onboard`: camera-native motion pushes (Reolink Baichuan, ONVIF
|
|
24093
|
-
* analytics). The provider emits ProviderMotion
|
|
24094
|
-
*
|
|
24132
|
+
* analytics). The provider emits its raw push as `ProviderMotion`
|
|
24133
|
+
* (D673); the orchestrator's camera-sensors bridge re-emits the camera's
|
|
24134
|
+
* effective motion as `MotionOnMotionChanged`, which is what reaches
|
|
24135
|
+
* `reportMotion`.
|
|
24095
24136
|
*/
|
|
24096
24137
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
24097
24138
|
/**
|
|
@@ -24268,7 +24309,15 @@ var RunnerLocalLoadSchema = object({
|
|
|
24268
24309
|
hasGpu: boolean(),
|
|
24269
24310
|
inferenceBackend: string().optional(),
|
|
24270
24311
|
cpuCores: number().optional()
|
|
24271
|
-
})
|
|
24312
|
+
}),
|
|
24313
|
+
/**
|
|
24314
|
+
* Who writes a camera's `motion` runtime slice (D696). `'orchestrator'`: this
|
|
24315
|
+
* runner never writes it. ABSENT = a runner older than D696, which still
|
|
24316
|
+
* writes the slice from its phase machine; the orchestrator does not write
|
|
24317
|
+
* while any runner node is absent-or-unanswered, so one slice never has two
|
|
24318
|
+
* writers.
|
|
24319
|
+
*/
|
|
24320
|
+
motionSliceWriter: literal("orchestrator").optional()
|
|
24272
24321
|
});
|
|
24273
24322
|
/**
|
|
24274
24323
|
* Aggregate runtime metrics for the runner's whole local pool. Mirrors the
|
|
@@ -29109,6 +29158,17 @@ object({
|
|
|
29109
29158
|
deviceId: number(),
|
|
29110
29159
|
status: DeviceStatusSchema
|
|
29111
29160
|
});
|
|
29161
|
+
object({
|
|
29162
|
+
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
29163
|
+
lastPressedAt: number().nullable(),
|
|
29164
|
+
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
29165
|
+
pressCountSinceStart: number()
|
|
29166
|
+
});
|
|
29167
|
+
object({
|
|
29168
|
+
deviceId: number(),
|
|
29169
|
+
timestamp: number()
|
|
29170
|
+
});
|
|
29171
|
+
DeviceType.Button, DeviceType.Camera;
|
|
29112
29172
|
/**
|
|
29113
29173
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
29114
29174
|
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
@@ -30753,9 +30813,9 @@ object({
|
|
|
30753
30813
|
/** Ms epoch of the last detected-true observation. Null if never detected. */
|
|
30754
30814
|
lastDetectedAt: number().nullable(),
|
|
30755
30815
|
/**
|
|
30756
|
-
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device
|
|
30757
|
-
* `null` while false and on every `Sensor`
|
|
30758
|
-
* constant's doc for the one-authority rule.
|
|
30816
|
+
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device (the
|
|
30817
|
+
* orchestrator writes it, D696), `null` while false and on every `Sensor`
|
|
30818
|
+
* device (D475) — see that constant's doc for the one-authority rule.
|
|
30759
30819
|
*
|
|
30760
30820
|
* ## Reading this field still arms nothing
|
|
30761
30821
|
*
|
|
@@ -30773,38 +30833,41 @@ object({
|
|
|
30773
30833
|
* `addon-export-alexa/src/motion-clear-hold.ts` and
|
|
30774
30834
|
* `addon-export-hap`'s `RESET_DEBOUNCE_MS` both do.
|
|
30775
30835
|
*
|
|
30776
|
-
* ## Who writes it
|
|
30777
|
-
*
|
|
30778
|
-
* - **Cameras** — the
|
|
30779
|
-
*
|
|
30780
|
-
* `
|
|
30781
|
-
* `
|
|
30782
|
-
*
|
|
30783
|
-
*
|
|
30784
|
-
* a
|
|
30785
|
-
*
|
|
30786
|
-
*
|
|
30787
|
-
*
|
|
30788
|
-
*
|
|
30789
|
-
*
|
|
30790
|
-
*
|
|
30791
|
-
*
|
|
30792
|
-
*
|
|
30793
|
-
*
|
|
30794
|
-
* `
|
|
30795
|
-
*
|
|
30796
|
-
*
|
|
30797
|
-
*
|
|
30798
|
-
*
|
|
30799
|
-
*
|
|
30800
|
-
*
|
|
30801
|
-
* This predates D475 and is not fixed there: the fix touches every
|
|
30802
|
-
* camera provider. Recorded in D475's Consequences. Do not restore the
|
|
30803
|
-
* "sole writer" wording without also removing the other writers.
|
|
30836
|
+
* ## Who writes it (D696)
|
|
30837
|
+
*
|
|
30838
|
+
* - **Cameras** — the orchestrator, and nothing else. It writes the camera's
|
|
30839
|
+
* EFFECTIVE motion (`addon-pipeline-orchestrator`
|
|
30840
|
+
* `camera-sensors/motion-slice.ts`), alongside the effective
|
|
30841
|
+
* `MotionOnMotionChanged` it emits or receives: the camera-sensors bridge
|
|
30842
|
+
* for a split camera, an unsplit emitter's direct event, the analyzer and
|
|
30843
|
+
* device activity, as the camera's `motionSources` counts them. A source
|
|
30844
|
+
* that never sends a clear falls one window after its last `true`.
|
|
30845
|
+
* `lastDetectedAt` moves only on an effective rise. No camera provider
|
|
30846
|
+
* writes this slice (not even a boot seed), and neither does the runner's
|
|
30847
|
+
* phase machine: its phase is "a session is attached" for every on-motion
|
|
30848
|
+
* session, not motion, and it now has its own `DetectionPhaseTransition`.
|
|
30849
|
+
* A provider's `isDetected` answers from the hub's slice.
|
|
30850
|
+
* - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
|
|
30851
|
+
* imports) — the provider pushes both edges itself, from the upstream
|
|
30852
|
+
* system's own state change. That is the sensor's own fact.
|
|
30853
|
+
*
|
|
30854
|
+
* `scripts/check-onboard-motion-emitters.ts` refuses any other writer of a
|
|
30855
|
+
* `motion` slice; each sensor writer is a named exemption.
|
|
30856
|
+
*
|
|
30857
|
+
* This replaces the D475 §4 rule ("the phase machine is the sole writer").
|
|
30858
|
+
* That rule was never true: Hikvision and Amcrest wrote the slice raw beside
|
|
30859
|
+
* it, every provider seeded it at boot, and every session left it
|
|
30860
|
+
* `detected: true` after its detach.
|
|
30804
30861
|
*/
|
|
30805
30862
|
autoClearAfterMs: number().nullable()
|
|
30806
30863
|
});
|
|
30807
|
-
|
|
30864
|
+
/**
|
|
30865
|
+
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
30866
|
+
* event `EventCategory.MotionOnMotionChanged`. Single source of truth
|
|
30867
|
+
* — both the cap event surface and the bus payload type alias to this
|
|
30868
|
+
* schema.
|
|
30869
|
+
*/
|
|
30870
|
+
var MotionOnMotionChangedDataSchema = object({
|
|
30808
30871
|
deviceId: number(),
|
|
30809
30872
|
detected: boolean(),
|
|
30810
30873
|
timestamp: number(),
|
|
@@ -47281,6 +47344,7 @@ TimelapseRuleInputSchema.extend({
|
|
|
47281
47344
|
createdAt: number(),
|
|
47282
47345
|
updatedAt: number()
|
|
47283
47346
|
});
|
|
47347
|
+
MotionOnMotionChangedDataSchema.omit({ triggeredBy: true });
|
|
47284
47348
|
object({
|
|
47285
47349
|
/**
|
|
47286
47350
|
* Fraction of the box's own size added on EACH side before cutting.
|
|
@@ -51497,7 +51561,7 @@ var ExportAlexaAddon = class extends BaseAddon {
|
|
|
51497
51561
|
* One reconcile pass over every exposed device shortly after boot. This is
|
|
51498
51562
|
* what heals a shape that drifted while the addon was DOWN (or under an
|
|
51499
51563
|
* older build that had no signature at all) with no operator click — the
|
|
51500
|
-
* doorbell
|
|
51564
|
+
* doorbell bound on 615 after it was exposed is exactly that case. Deliberately late
|
|
51501
51565
|
* enough that device providers have registered their caps: a device whose
|
|
51502
51566
|
* bindings have not landed yet builds a shape we must not push.
|
|
51503
51567
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as crypto$1 from "node:crypto";
|
|
2
|
-
//#region ../types/dist/event-category-
|
|
2
|
+
//#region ../types/dist/event-category-BGmz_oxW.mjs
|
|
3
3
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4
4
|
EventCategory["SystemBoot"] = "system.boot";
|
|
5
5
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -532,6 +532,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
532
532
|
*/
|
|
533
533
|
EventCategory["PipelineAudioInferenceResult"] = "pipeline.audio-inference-result";
|
|
534
534
|
EventCategory["DetectionPhaseTransition"] = "detection.phase-transition";
|
|
535
|
+
/**
|
|
536
|
+
* A camera provider's RAW onboard motion push (D673): the `MotionOnMotionChanged`
|
|
537
|
+
* data shape without `triggeredBy`, built by `providerMotionEvent`. Its one
|
|
538
|
+
* consumer is the orchestrator's camera-sensors bridge, which re-emits the
|
|
539
|
+
* camera's EFFECTIVE onboard motion as `MotionOnMotionChanged` (a pass-through
|
|
540
|
+
* for a camera with no attached sensor). Providers must not emit
|
|
541
|
+
* `MotionOnMotionChanged` themselves; `scripts/check-onboard-motion-emitters.ts`
|
|
542
|
+
* keeps it so (camera-grid is a named, deferred exception).
|
|
543
|
+
*/
|
|
535
544
|
EventCategory["ProviderMotion"] = "provider.motion";
|
|
536
545
|
EventCategory["ProviderDetection"] = "provider.detection";
|
|
537
546
|
EventCategory["EnrichmentEmbeddingStored"] = "enrichment.embedding.stored";
|
|
@@ -5370,7 +5379,7 @@ var ZodIssueCode = {
|
|
|
5370
5379
|
var ZodFirstPartyTypeKind;
|
|
5371
5380
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5372
5381
|
//#endregion
|
|
5373
|
-
//#region ../types/dist/sleep-
|
|
5382
|
+
//#region ../types/dist/sleep-CDCONfkt.mjs
|
|
5374
5383
|
/**
|
|
5375
5384
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5376
5385
|
* window to float samples (D455).
|
|
@@ -7431,7 +7440,7 @@ function errMsg(err) {
|
|
|
7431
7440
|
return String(err);
|
|
7432
7441
|
}
|
|
7433
7442
|
//#endregion
|
|
7434
|
-
//#region ../types/dist/composition-
|
|
7443
|
+
//#region ../types/dist/composition-43aqsZQj.mjs
|
|
7435
7444
|
/**
|
|
7436
7445
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
7437
7446
|
*
|
|
@@ -7488,13 +7497,12 @@ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac
|
|
|
7488
7497
|
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
7489
7498
|
* valutatore puro del suo FRONTE.
|
|
7490
7499
|
*
|
|
7491
|
-
*
|
|
7492
|
-
*
|
|
7493
|
-
*
|
|
7494
|
-
*
|
|
7495
|
-
*
|
|
7496
|
-
* fa suonare il campanello ma non registra" — è esattamente D62.
|
|
7497
|
-
* SPOSTA qui e il doorbell la ri-esporta.
|
|
7500
|
+
* UNA tabella per tutti quelli che chiedono "questo device è ALTO?": il
|
|
7501
|
+
* trigger `RecordingTriggers.sensorDeviceIds` del recorder, i marker dei
|
|
7502
|
+
* sensori della post-analysis, il bridge camera-sensors dell'orchestratore e
|
|
7503
|
+
* le sorgenti di un campanello composto (`doorbellFeatureSources`, D671).
|
|
7504
|
+
* Una seconda copia divergerebbe alla prima cap aggiunta, e il sintomo — "il
|
|
7505
|
+
* sensore fa suonare il campanello ma non registra" — è esattamente D62.
|
|
7498
7506
|
*
|
|
7499
7507
|
* ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
|
|
7500
7508
|
* due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
|
|
@@ -9398,7 +9406,7 @@ var RecordingTriggersSchema = object({
|
|
|
9398
9406
|
*
|
|
9399
9407
|
* Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
|
|
9400
9408
|
* `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
|
|
9401
|
-
* la stessa
|
|
9409
|
+
* la stessa del campanello composto (D671). Ed è il FRONTE, non
|
|
9402
9410
|
* il livello: un contatto trovato già aperto al riavvio del runner non fa
|
|
9403
9411
|
* registrare.
|
|
9404
9412
|
*/
|
|
@@ -15623,28 +15631,10 @@ method(object({
|
|
|
15623
15631
|
deviceIds: array(number()).readonly(),
|
|
15624
15632
|
caps: array(string()).readonly().optional()
|
|
15625
15633
|
}), record(string(), record(string(), unknown().nullable())));
|
|
15626
|
-
|
|
15627
|
-
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
15628
|
-
lastPressedAt: number().nullable(),
|
|
15629
|
-
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
15630
|
-
pressCountSinceStart: number()
|
|
15631
|
-
});
|
|
15632
|
-
object({
|
|
15633
|
-
deviceId: number(),
|
|
15634
|
-
timestamp: number()
|
|
15635
|
-
});
|
|
15636
|
-
/**
|
|
15637
|
-
* The `doorbell-source` extension slot's editable value (D648): the camera's
|
|
15638
|
-
* virtual-doorbell trigger devices, exactly what the wrapper's
|
|
15639
|
-
* `doorbellSources` persists (as `{ deviceId }` records).
|
|
15640
|
-
*/
|
|
15641
|
-
var DoorbellSourceSlotValueSchema = object({ deviceIds: array(number().int().positive()) });
|
|
15634
|
+
var ExtensionSlotIdSchema = _enum(["linked-devices"]);
|
|
15642
15635
|
DeviceType.Camera;
|
|
15643
|
-
DeviceType.Button, DeviceType.Camera;
|
|
15644
|
-
var ExtensionSlotIdSchema = _enum(["doorbell-source", "linked-devices"]);
|
|
15645
|
-
DeviceType.Camera, DeviceType.Camera;
|
|
15646
15636
|
/** A slot's editable value, discriminated on `slot`. */
|
|
15647
|
-
var ExtensionSlotValueSchema = discriminatedUnion("slot", [
|
|
15637
|
+
var ExtensionSlotValueSchema = discriminatedUnion("slot", [LinkedDevicesSlotValueSchema.extend({ slot: literal("linked-devices") })]);
|
|
15648
15638
|
DeviceType.Camera;
|
|
15649
15639
|
var ExtensionSourceAvailabilitySchema = discriminatedUnion("state", [object({ state: literal("ok") }), object({
|
|
15650
15640
|
state: literal("unreachable"),
|
|
@@ -15681,10 +15671,11 @@ var ExtensionSlotSourceSchema = object({
|
|
|
15681
15671
|
});
|
|
15682
15672
|
/**
|
|
15683
15673
|
* A DIFFERENT authority that gates whether the slot's sources do anything —
|
|
15684
|
-
* reported read-only, named, never written through this contract (D62).
|
|
15685
|
-
*
|
|
15686
|
-
*
|
|
15687
|
-
* `unknown` means the gate could
|
|
15674
|
+
* reported read-only, named, never written through this contract (D62) — e.g.
|
|
15675
|
+
* a slot whose sources act only while a wrapper is bound to the host, a
|
|
15676
|
+
* binding that belongs to `deviceManager.setWrapperActive`. No slot reports
|
|
15677
|
+
* one today (`linked-devices` answers `null`). `unknown` means the gate could
|
|
15678
|
+
* not be read; it is not "inactive" (D315).
|
|
15688
15679
|
*/
|
|
15689
15680
|
var ExtensionSlotActivationSchema = object({
|
|
15690
15681
|
state: _enum([
|
|
@@ -15700,7 +15691,7 @@ var ExtensionSlotRowSchema = discriminatedUnion("state", [object({
|
|
|
15700
15691
|
/** `<source>:<slotId>` — the routing key for `listCandidates` / `setSlot`. */
|
|
15701
15692
|
slotRef: string(),
|
|
15702
15693
|
slot: ExtensionSlotIdSchema,
|
|
15703
|
-
/** Names the store written (D62), e.g. `
|
|
15694
|
+
/** Names the store written (D62), e.g. `device-manager:_linkedDeviceIds`. */
|
|
15704
15695
|
authority: string(),
|
|
15705
15696
|
activation: ExtensionSlotActivationSchema.nullable(),
|
|
15706
15697
|
value: ExtensionSlotValueSchema,
|
|
@@ -20800,12 +20791,26 @@ var CameraSensorRefSchema = object({
|
|
|
20800
20791
|
function cameraSensorRefKey(ref) {
|
|
20801
20792
|
return `${ref.addonId}/${ref.stableId}`;
|
|
20802
20793
|
}
|
|
20803
|
-
/**
|
|
20804
|
-
|
|
20805
|
-
|
|
20806
|
-
|
|
20807
|
-
|
|
20808
|
-
|
|
20794
|
+
/**
|
|
20795
|
+
* A sensor's mode (D673). `in-addition`: its motion is the camera's motion too.
|
|
20796
|
+
* `replace`: its motion is the camera's, and while one is READY the camera's
|
|
20797
|
+
* own motion no longer counts on its own. `confirm`: while one is READY the
|
|
20798
|
+
* camera's own motion counts only while a confirm sensor is active — with or
|
|
20799
|
+
* without a replace sensor (spec C2, the controller's ruling on Q1).
|
|
20800
|
+
*/
|
|
20801
|
+
var CameraSensorModeSchema = _enum([
|
|
20802
|
+
"in-addition",
|
|
20803
|
+
"confirm",
|
|
20804
|
+
"replace"
|
|
20805
|
+
]);
|
|
20806
|
+
/** A stored sensor with no mode — every CS-1 row — is in addition. */
|
|
20807
|
+
var DEFAULT_CAMERA_SENSOR_MODE = "in-addition";
|
|
20808
|
+
/**
|
|
20809
|
+
* A camera's attached sensors. A CS-1 row carried an envelope
|
|
20810
|
+
* `mode: 'in-addition'`: `z.object` drops it on parse, and the PARSED value is
|
|
20811
|
+
* what the write stores (D672 rule 3), so it is never written again.
|
|
20812
|
+
*/
|
|
20813
|
+
var CameraSensorsConfigSchema = object({ sensors: array(CameraSensorRefSchema.extend({ mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE) })).min(1).max(8) }).superRefine((value, ctx) => {
|
|
20809
20814
|
const seen = /* @__PURE__ */ new Set();
|
|
20810
20815
|
value.sensors.forEach((ref, index) => {
|
|
20811
20816
|
const key = cameraSensorRefKey(ref);
|
|
@@ -20817,39 +20822,41 @@ var CameraSensorsConfigSchema = object({
|
|
|
20817
20822
|
seen.add(key);
|
|
20818
20823
|
});
|
|
20819
20824
|
});
|
|
20820
|
-
|
|
20825
|
+
/** Every attachment names its mode; an older orchestrator that does not is in addition. */
|
|
20826
|
+
var AttachmentFields = {
|
|
20821
20827
|
addonId: string(),
|
|
20822
|
-
stableId: string()
|
|
20828
|
+
stableId: string(),
|
|
20829
|
+
mode: CameraSensorModeSchema.default(DEFAULT_CAMERA_SENSOR_MODE)
|
|
20823
20830
|
};
|
|
20824
20831
|
var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
20825
20832
|
object({
|
|
20826
|
-
...
|
|
20833
|
+
...AttachmentFields,
|
|
20827
20834
|
state: literal("ready"),
|
|
20828
20835
|
deviceId: number(),
|
|
20829
20836
|
name: string(),
|
|
20830
20837
|
caps: array(string()).readonly()
|
|
20831
20838
|
}),
|
|
20832
20839
|
object({
|
|
20833
|
-
...
|
|
20840
|
+
...AttachmentFields,
|
|
20834
20841
|
state: literal("offline"),
|
|
20835
20842
|
deviceId: number(),
|
|
20836
20843
|
name: string(),
|
|
20837
20844
|
reason: _enum(["offline", "disabled"])
|
|
20838
20845
|
}),
|
|
20839
20846
|
object({
|
|
20840
|
-
...
|
|
20847
|
+
...AttachmentFields,
|
|
20841
20848
|
state: literal("missing"),
|
|
20842
20849
|
reason: string()
|
|
20843
20850
|
}),
|
|
20844
20851
|
object({
|
|
20845
|
-
...
|
|
20852
|
+
...AttachmentFields,
|
|
20846
20853
|
state: literal("unsupported"),
|
|
20847
20854
|
deviceId: number(),
|
|
20848
20855
|
name: string(),
|
|
20849
20856
|
reason: string()
|
|
20850
20857
|
}),
|
|
20851
20858
|
object({
|
|
20852
|
-
...
|
|
20859
|
+
...AttachmentFields,
|
|
20853
20860
|
state: literal("unreadable"),
|
|
20854
20861
|
reason: string()
|
|
20855
20862
|
})
|
|
@@ -20862,17 +20869,49 @@ var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
|
20862
20869
|
* say.
|
|
20863
20870
|
*/
|
|
20864
20871
|
var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
|
|
20872
|
+
/** Whether the camera's OWN motion counts on its own (D673 C2), from its READY sensors (C3). */
|
|
20873
|
+
var CameraOwnMotionSchema = _enum([
|
|
20874
|
+
"always",
|
|
20875
|
+
"when-confirmed",
|
|
20876
|
+
"never"
|
|
20877
|
+
]);
|
|
20878
|
+
/** Confirm / Replace cannot suppress this camera's motion: its provider still emits it directly (D673 C13). */
|
|
20879
|
+
var CameraSensorsNotEnforcedSchema = _enum(["provider-not-split"]);
|
|
20880
|
+
/**
|
|
20881
|
+
* The camera's OWN onboard motion (D696): the raw input the bridge combines,
|
|
20882
|
+
* never the effective value. The camera's `motion` slice is the effective one,
|
|
20883
|
+
* so a view of the camera's own row reads this.
|
|
20884
|
+
* - `atMs`: when the bridge received the camera's last own edge.
|
|
20885
|
+
* - `detected`: evaluated WHEN THE STATUS IS ASKED — the last edge said `true`
|
|
20886
|
+
* AND it is younger than the window the bridge counts the camera's own motion
|
|
20887
|
+
* for (`motionCooldownMs`, floored at two sustain ticks). A camera that never
|
|
20888
|
+
* sends a clear (heartbeats only) therefore reads `false` once no push came
|
|
20889
|
+
* within the window; a status read is a snapshot, so a live view re-asks.
|
|
20890
|
+
* Absent = this orchestrator has not received the camera's own motion since it
|
|
20891
|
+
* started (unknown, never "quiet"), or an orchestrator older than D696.
|
|
20892
|
+
*/
|
|
20893
|
+
var CameraRawLevelSchema = object({
|
|
20894
|
+
detected: boolean(),
|
|
20895
|
+
atMs: number()
|
|
20896
|
+
});
|
|
20865
20897
|
var CameraSensorsStatusSchema = discriminatedUnion("state", [
|
|
20866
|
-
object({
|
|
20898
|
+
object({
|
|
20899
|
+
state: literal("not-configured"),
|
|
20900
|
+
cameraLevel: CameraRawLevelSchema.optional()
|
|
20901
|
+
}),
|
|
20867
20902
|
object({
|
|
20868
20903
|
state: literal("unreadable"),
|
|
20869
|
-
reason: string()
|
|
20904
|
+
reason: string(),
|
|
20905
|
+
cameraLevel: CameraRawLevelSchema.optional()
|
|
20870
20906
|
}),
|
|
20871
20907
|
object({
|
|
20872
20908
|
state: literal("configured"),
|
|
20873
|
-
|
|
20909
|
+
cameraLevel: CameraRawLevelSchema.optional(),
|
|
20874
20910
|
sensors: array(CameraSensorAttachmentSchema).readonly(),
|
|
20875
|
-
|
|
20911
|
+
/** Absent = an orchestrator older than CS-2: it does not say (D315). */
|
|
20912
|
+
cameraMotion: CameraOwnMotionSchema.optional(),
|
|
20913
|
+
notForwarded: CameraSensorsNotForwardedSchema.optional(),
|
|
20914
|
+
notEnforced: CameraSensorsNotEnforcedSchema.optional()
|
|
20876
20915
|
})
|
|
20877
20916
|
]);
|
|
20878
20917
|
Object.freeze({
|
|
@@ -24063,8 +24102,10 @@ var RunnerCameraConfigSchema = object({
|
|
|
24063
24102
|
* - `analyzer`: ML/frame-diff motion detection (motion-wasm or other
|
|
24064
24103
|
* analyzer providers) running on decoded frames in this runner.
|
|
24065
24104
|
* - `onboard`: camera-native motion pushes (Reolink Baichuan, ONVIF
|
|
24066
|
-
* analytics). The provider emits ProviderMotion
|
|
24067
|
-
*
|
|
24105
|
+
* analytics). The provider emits its raw push as `ProviderMotion`
|
|
24106
|
+
* (D673); the orchestrator's camera-sensors bridge re-emits the camera's
|
|
24107
|
+
* effective motion as `MotionOnMotionChanged`, which is what reaches
|
|
24108
|
+
* `reportMotion`.
|
|
24068
24109
|
*/
|
|
24069
24110
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
24070
24111
|
/**
|
|
@@ -24241,7 +24282,15 @@ var RunnerLocalLoadSchema = object({
|
|
|
24241
24282
|
hasGpu: boolean(),
|
|
24242
24283
|
inferenceBackend: string().optional(),
|
|
24243
24284
|
cpuCores: number().optional()
|
|
24244
|
-
})
|
|
24285
|
+
}),
|
|
24286
|
+
/**
|
|
24287
|
+
* Who writes a camera's `motion` runtime slice (D696). `'orchestrator'`: this
|
|
24288
|
+
* runner never writes it. ABSENT = a runner older than D696, which still
|
|
24289
|
+
* writes the slice from its phase machine; the orchestrator does not write
|
|
24290
|
+
* while any runner node is absent-or-unanswered, so one slice never has two
|
|
24291
|
+
* writers.
|
|
24292
|
+
*/
|
|
24293
|
+
motionSliceWriter: literal("orchestrator").optional()
|
|
24245
24294
|
});
|
|
24246
24295
|
/**
|
|
24247
24296
|
* Aggregate runtime metrics for the runner's whole local pool. Mirrors the
|
|
@@ -29082,6 +29131,17 @@ object({
|
|
|
29082
29131
|
deviceId: number(),
|
|
29083
29132
|
status: DeviceStatusSchema
|
|
29084
29133
|
});
|
|
29134
|
+
object({
|
|
29135
|
+
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
29136
|
+
lastPressedAt: number().nullable(),
|
|
29137
|
+
/** Counter since provider start. Resets on reboot. Useful for metrics/debug. */
|
|
29138
|
+
pressCountSinceStart: number()
|
|
29139
|
+
});
|
|
29140
|
+
object({
|
|
29141
|
+
deviceId: number(),
|
|
29142
|
+
timestamp: number()
|
|
29143
|
+
});
|
|
29144
|
+
DeviceType.Button, DeviceType.Camera;
|
|
29085
29145
|
/**
|
|
29086
29146
|
* Enum-state sensor — a string value picked from a finite option set.
|
|
29087
29147
|
* Drives HA `sensor` entries with `state_class: enum` (HVAC action
|
|
@@ -30726,9 +30786,9 @@ object({
|
|
|
30726
30786
|
/** Ms epoch of the last detected-true observation. Null if never detected. */
|
|
30727
30787
|
lastDetectedAt: number().nullable(),
|
|
30728
30788
|
/**
|
|
30729
|
-
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device
|
|
30730
|
-
* `null` while false and on every `Sensor`
|
|
30731
|
-
* constant's doc for the one-authority rule.
|
|
30789
|
+
* `MOTION_CLOSE_AFTER_MS` while `detected: true` on a `Camera` device (the
|
|
30790
|
+
* orchestrator writes it, D696), `null` while false and on every `Sensor`
|
|
30791
|
+
* device (D475) — see that constant's doc for the one-authority rule.
|
|
30732
30792
|
*
|
|
30733
30793
|
* ## Reading this field still arms nothing
|
|
30734
30794
|
*
|
|
@@ -30746,38 +30806,41 @@ object({
|
|
|
30746
30806
|
* `addon-export-alexa/src/motion-clear-hold.ts` and
|
|
30747
30807
|
* `addon-export-hap`'s `RESET_DEBOUNCE_MS` both do.
|
|
30748
30808
|
*
|
|
30749
|
-
* ## Who writes it
|
|
30750
|
-
*
|
|
30751
|
-
* - **Cameras** — the
|
|
30752
|
-
*
|
|
30753
|
-
* `
|
|
30754
|
-
* `
|
|
30755
|
-
*
|
|
30756
|
-
*
|
|
30757
|
-
* a
|
|
30758
|
-
*
|
|
30759
|
-
*
|
|
30760
|
-
*
|
|
30761
|
-
*
|
|
30762
|
-
*
|
|
30763
|
-
*
|
|
30764
|
-
*
|
|
30765
|
-
*
|
|
30766
|
-
*
|
|
30767
|
-
* `
|
|
30768
|
-
*
|
|
30769
|
-
*
|
|
30770
|
-
*
|
|
30771
|
-
*
|
|
30772
|
-
*
|
|
30773
|
-
*
|
|
30774
|
-
* This predates D475 and is not fixed there: the fix touches every
|
|
30775
|
-
* camera provider. Recorded in D475's Consequences. Do not restore the
|
|
30776
|
-
* "sole writer" wording without also removing the other writers.
|
|
30809
|
+
* ## Who writes it (D696)
|
|
30810
|
+
*
|
|
30811
|
+
* - **Cameras** — the orchestrator, and nothing else. It writes the camera's
|
|
30812
|
+
* EFFECTIVE motion (`addon-pipeline-orchestrator`
|
|
30813
|
+
* `camera-sensors/motion-slice.ts`), alongside the effective
|
|
30814
|
+
* `MotionOnMotionChanged` it emits or receives: the camera-sensors bridge
|
|
30815
|
+
* for a split camera, an unsplit emitter's direct event, the analyzer and
|
|
30816
|
+
* device activity, as the camera's `motionSources` counts them. A source
|
|
30817
|
+
* that never sends a clear falls one window after its last `true`.
|
|
30818
|
+
* `lastDetectedAt` moves only on an effective rise. No camera provider
|
|
30819
|
+
* writes this slice (not even a boot seed), and neither does the runner's
|
|
30820
|
+
* phase machine: its phase is "a session is attached" for every on-motion
|
|
30821
|
+
* session, not motion, and it now has its own `DetectionPhaseTransition`.
|
|
30822
|
+
* A provider's `isDetected` answers from the hub's slice.
|
|
30823
|
+
* - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
|
|
30824
|
+
* imports) — the provider pushes both edges itself, from the upstream
|
|
30825
|
+
* system's own state change. That is the sensor's own fact.
|
|
30826
|
+
*
|
|
30827
|
+
* `scripts/check-onboard-motion-emitters.ts` refuses any other writer of a
|
|
30828
|
+
* `motion` slice; each sensor writer is a named exemption.
|
|
30829
|
+
*
|
|
30830
|
+
* This replaces the D475 §4 rule ("the phase machine is the sole writer").
|
|
30831
|
+
* That rule was never true: Hikvision and Amcrest wrote the slice raw beside
|
|
30832
|
+
* it, every provider seeded it at boot, and every session left it
|
|
30833
|
+
* `detected: true` after its detach.
|
|
30777
30834
|
*/
|
|
30778
30835
|
autoClearAfterMs: number().nullable()
|
|
30779
30836
|
});
|
|
30780
|
-
|
|
30837
|
+
/**
|
|
30838
|
+
* Payload of `motion.onMotionChanged` event + the corresponding bus
|
|
30839
|
+
* event `EventCategory.MotionOnMotionChanged`. Single source of truth
|
|
30840
|
+
* — both the cap event surface and the bus payload type alias to this
|
|
30841
|
+
* schema.
|
|
30842
|
+
*/
|
|
30843
|
+
var MotionOnMotionChangedDataSchema = object({
|
|
30781
30844
|
deviceId: number(),
|
|
30782
30845
|
detected: boolean(),
|
|
30783
30846
|
timestamp: number(),
|
|
@@ -47254,6 +47317,7 @@ TimelapseRuleInputSchema.extend({
|
|
|
47254
47317
|
createdAt: number(),
|
|
47255
47318
|
updatedAt: number()
|
|
47256
47319
|
});
|
|
47320
|
+
MotionOnMotionChangedDataSchema.omit({ triggeredBy: true });
|
|
47257
47321
|
object({
|
|
47258
47322
|
/**
|
|
47259
47323
|
* Fraction of the box's own size added on EACH side before cutting.
|
|
@@ -51470,7 +51534,7 @@ var ExportAlexaAddon = class extends BaseAddon {
|
|
|
51470
51534
|
* One reconcile pass over every exposed device shortly after boot. This is
|
|
51471
51535
|
* what heals a shape that drifted while the addon was DOWN (or under an
|
|
51472
51536
|
* older build that had no signature at all) with no operator click — the
|
|
51473
|
-
* doorbell
|
|
51537
|
+
* doorbell bound on 615 after it was exposed is exactly that case. Deliberately late
|
|
51474
51538
|
* enough that device providers have registered their caps: a device whose
|
|
51475
51539
|
* bindings have not landed yet builds a shape we must not push.
|
|
51476
51540
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-export-alexa",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.124",
|
|
4
4
|
"description": "Alexa Smart Home Skill export — hub-side OAuth provider + directive handler. The companion AWS Lambda forwards Alexa directives to this addon's /addon/export-alexa/directive endpoint.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|