@camstack/addon-provider-homematic 1.2.120 → 1.2.121
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 +168 -159
- package/dist/addon.mjs +168 -160
- package/dist/index.js +1 -1
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -5379,7 +5379,7 @@ var ZodIssueCode = {
|
|
|
5379
5379
|
var ZodFirstPartyTypeKind;
|
|
5380
5380
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5381
5381
|
//#endregion
|
|
5382
|
-
//#region ../types/dist/sleep-
|
|
5382
|
+
//#region ../types/dist/sleep-C-v96WpE.mjs
|
|
5383
5383
|
/**
|
|
5384
5384
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5385
5385
|
* window to float samples (D455).
|
|
@@ -8228,7 +8228,6 @@ var CompositionSchema = object({
|
|
|
8228
8228
|
});
|
|
8229
8229
|
new Set([
|
|
8230
8230
|
"track",
|
|
8231
|
-
"summary",
|
|
8232
8231
|
"face",
|
|
8233
8232
|
"identity",
|
|
8234
8233
|
"plate",
|
|
@@ -20537,6 +20536,102 @@ var OauthIntegrationDescriptorSchema = object({
|
|
|
20537
20536
|
});
|
|
20538
20537
|
method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
|
|
20539
20538
|
/**
|
|
20539
|
+
* What started a camera's onboard motion (D672). `camera` is the camera's own
|
|
20540
|
+
* firmware; `sensor` is a device the operator ATTACHED to it. Absent on the
|
|
20541
|
+
* wire means the camera: only the camera-sensors bridge ever says `sensor`.
|
|
20542
|
+
*/
|
|
20543
|
+
var MotionTriggeredBySchema = discriminatedUnion("kind", [object({ kind: literal("camera") }), object({
|
|
20544
|
+
kind: literal("sensor"),
|
|
20545
|
+
deviceId: number().int().positive()
|
|
20546
|
+
})]);
|
|
20547
|
+
Object.freeze({ kind: "camera" });
|
|
20548
|
+
var CameraSensorRefSchema = object({
|
|
20549
|
+
addonId: string().min(1),
|
|
20550
|
+
stableId: string().min(1)
|
|
20551
|
+
});
|
|
20552
|
+
function cameraSensorRefKey(ref) {
|
|
20553
|
+
return `${ref.addonId}/${ref.stableId}`;
|
|
20554
|
+
}
|
|
20555
|
+
/** CS-1 accepts exactly one mode; CS-2 (D673) widens it to confirm / replace. */
|
|
20556
|
+
var CameraSensorsModeSchema = _enum(["in-addition"]);
|
|
20557
|
+
object({
|
|
20558
|
+
mode: CameraSensorsModeSchema,
|
|
20559
|
+
sensors: array(CameraSensorRefSchema).min(1).max(8)
|
|
20560
|
+
}).superRefine((value, ctx) => {
|
|
20561
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20562
|
+
value.sensors.forEach((ref, index) => {
|
|
20563
|
+
const key = cameraSensorRefKey(ref);
|
|
20564
|
+
if (seen.has(key)) ctx.addIssue({
|
|
20565
|
+
code: "custom",
|
|
20566
|
+
path: ["sensors", index],
|
|
20567
|
+
message: `duplicate camera sensor ${key}`
|
|
20568
|
+
});
|
|
20569
|
+
seen.add(key);
|
|
20570
|
+
});
|
|
20571
|
+
});
|
|
20572
|
+
var RefFields = {
|
|
20573
|
+
addonId: string(),
|
|
20574
|
+
stableId: string()
|
|
20575
|
+
};
|
|
20576
|
+
var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
20577
|
+
object({
|
|
20578
|
+
...RefFields,
|
|
20579
|
+
state: literal("ready"),
|
|
20580
|
+
deviceId: number(),
|
|
20581
|
+
name: string(),
|
|
20582
|
+
caps: array(string()).readonly()
|
|
20583
|
+
}),
|
|
20584
|
+
object({
|
|
20585
|
+
...RefFields,
|
|
20586
|
+
state: literal("offline"),
|
|
20587
|
+
deviceId: number(),
|
|
20588
|
+
name: string(),
|
|
20589
|
+
reason: _enum(["offline", "disabled"])
|
|
20590
|
+
}),
|
|
20591
|
+
object({
|
|
20592
|
+
...RefFields,
|
|
20593
|
+
state: literal("missing"),
|
|
20594
|
+
reason: string()
|
|
20595
|
+
}),
|
|
20596
|
+
object({
|
|
20597
|
+
...RefFields,
|
|
20598
|
+
state: literal("unsupported"),
|
|
20599
|
+
deviceId: number(),
|
|
20600
|
+
name: string(),
|
|
20601
|
+
reason: string()
|
|
20602
|
+
}),
|
|
20603
|
+
object({
|
|
20604
|
+
...RefFields,
|
|
20605
|
+
state: literal("unreadable"),
|
|
20606
|
+
reason: string()
|
|
20607
|
+
})
|
|
20608
|
+
]);
|
|
20609
|
+
/**
|
|
20610
|
+
* Why a configured camera forwards NOTHING from its sensors, however ready they
|
|
20611
|
+
* are (D672): it does not list `onboard` in `motionSources` (attaching a sensor
|
|
20612
|
+
* does not add it), or it has no active detection config at all (the bridge
|
|
20613
|
+
* reads the active config). Absent = forwarded, or an older node that does not
|
|
20614
|
+
* say.
|
|
20615
|
+
*/
|
|
20616
|
+
var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
|
|
20617
|
+
var CameraSensorsStatusSchema = discriminatedUnion("state", [
|
|
20618
|
+
object({ state: literal("not-configured") }),
|
|
20619
|
+
object({
|
|
20620
|
+
state: literal("unreadable"),
|
|
20621
|
+
reason: string()
|
|
20622
|
+
}),
|
|
20623
|
+
object({
|
|
20624
|
+
state: literal("configured"),
|
|
20625
|
+
mode: CameraSensorsModeSchema,
|
|
20626
|
+
sensors: array(CameraSensorAttachmentSchema).readonly(),
|
|
20627
|
+
notForwarded: CameraSensorsNotForwardedSchema.optional()
|
|
20628
|
+
})
|
|
20629
|
+
]);
|
|
20630
|
+
Object.freeze({
|
|
20631
|
+
state: "unreadable",
|
|
20632
|
+
reason: "camera sensor mappings not loaded"
|
|
20633
|
+
});
|
|
20634
|
+
/**
|
|
20540
20635
|
* A model choice has a SCOPE, and a scope change has a workflow.
|
|
20541
20636
|
*
|
|
20542
20637
|
* ## The two scopes
|
|
@@ -21285,6 +21380,12 @@ var MotionEventSchema = object({
|
|
|
21285
21380
|
/** Populated by B5 (recording playback URL for this event). */
|
|
21286
21381
|
mediaUrl: string().optional(),
|
|
21287
21382
|
/**
|
|
21383
|
+
* The FIRST trigger of an `onboard` episode, written once at open (D672).
|
|
21384
|
+
* Absent = not recorded (a row written before D672, or an analyzer /
|
|
21385
|
+
* device-activity episode) — never read as "the camera" (D393).
|
|
21386
|
+
*/
|
|
21387
|
+
triggeredBy: MotionTriggeredBySchema.optional(),
|
|
21388
|
+
/**
|
|
21288
21389
|
* One row per motion EPISODE, not one per push (D475). `null` while the
|
|
21289
21390
|
* episode is still open — a further rising edge extends it in place rather
|
|
21290
21391
|
* than inserting a new row. Set once, at close, to `lastOnAt - startedAt`
|
|
@@ -21443,6 +21544,21 @@ var ObjectEventSchema = object({
|
|
|
21443
21544
|
keyFrameMediaId: number().int().optional(),
|
|
21444
21545
|
/** Populated by B5 (recording playback URL for this event). */
|
|
21445
21546
|
mediaUrl: string().optional(),
|
|
21547
|
+
/**
|
|
21548
|
+
* When the change this row records HAPPENED, epoch ms, when that is earlier
|
|
21549
|
+
* than {@link timestamp} and the producer could date it (D684).
|
|
21550
|
+
*
|
|
21551
|
+
* Set on a package PICK-UP row only: its `timestamp` is when the departure
|
|
21552
|
+
* was CONCLUDED — five minutes of unseen observed time after the parcel went
|
|
21553
|
+
* — and a notification's footage has to be cut around the pick-up, not the
|
|
21554
|
+
* empty doormat after it (D682). Stored so every path that rebuilds a
|
|
21555
|
+
* notification subject from the row (the boot reconcile, a dry-run) anchors
|
|
21556
|
+
* on the same instant the live hook did.
|
|
21557
|
+
*
|
|
21558
|
+
* `timestamp` keeps its meaning. Absent on every other row and on every
|
|
21559
|
+
* pick-up written before D684 — UNKNOWN, never 0 and never `timestamp`.
|
|
21560
|
+
*/
|
|
21561
|
+
observedAt: number().optional(),
|
|
21446
21562
|
/** The parent track's key-event importance [0,1], propagated to every object
|
|
21447
21563
|
* event of the track (so an event row can be sorted by importance without a
|
|
21448
21564
|
* track join). Absent on legacy rows / before the track was scored. */
|
|
@@ -21778,131 +21894,6 @@ var RecentTracksQueryInput = object({
|
|
|
21778
21894
|
/** See {@link ExcludeSourcesDoc}. */
|
|
21779
21895
|
excludeSources: array(TrackSourceSchema).optional()
|
|
21780
21896
|
});
|
|
21781
|
-
/**
|
|
21782
|
-
* A Summary (D359): the per-camera session envelope that references tracks.
|
|
21783
|
-
* `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
|
|
21784
|
-
* 'summary'`, served by the event-media plane at `/m/<id>`), null until the
|
|
21785
|
-
* first frame with a member visible has been materialised (D482 — it was the
|
|
21786
|
-
* row's composite key, which embedded the owner and could name another table's
|
|
21787
|
-
* row once event ids became per-table rowids).
|
|
21788
|
-
*/
|
|
21789
|
-
var SummarySchema = object({
|
|
21790
|
-
id: string(),
|
|
21791
|
-
deviceId: number(),
|
|
21792
|
-
openedAt: number(),
|
|
21793
|
-
lastActiveAt: number(),
|
|
21794
|
-
sealedAt: number().nullable(),
|
|
21795
|
-
memberCount: number().int().nonnegative(),
|
|
21796
|
-
groupShotMediaId: number().int().nullable()
|
|
21797
|
-
});
|
|
21798
|
-
var SummariesQueryInput = object({
|
|
21799
|
-
deviceIds: array(number()).min(1),
|
|
21800
|
-
since: number().optional(),
|
|
21801
|
-
until: number().optional(),
|
|
21802
|
-
limit: number().int().min(1).max(200).default(50),
|
|
21803
|
-
/** The same member-wise filter {@link listRecentSummaries} takes — one
|
|
21804
|
-
* meaning of "dog" on every summary surface. */
|
|
21805
|
-
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21806
|
-
});
|
|
21807
|
-
var SummaryDetailSchema = object({
|
|
21808
|
-
summary: SummarySchema,
|
|
21809
|
-
/** Members in absorption order, oldest join first. */
|
|
21810
|
-
members: array(object({
|
|
21811
|
-
trackId: string(),
|
|
21812
|
-
/**
|
|
21813
|
-
* The track's class at the time it JOINED, or `null` when it was unresolved
|
|
21814
|
-
* and the track no longer exists to fill it.
|
|
21815
|
-
*
|
|
21816
|
-
* The join, not the latest opinion: class voting can re-decide a track's
|
|
21817
|
-
* class afterwards, and a group's composition is the history of who came
|
|
21818
|
-
* together. A consumer counts these to badge a thumbnail — "two people and a
|
|
21819
|
-
* dog" — rather than being handed a second, denormalised tally that would
|
|
21820
|
-
* drift from the members it claims to describe.
|
|
21821
|
-
*/
|
|
21822
|
-
className: string().nullable(),
|
|
21823
|
-
/** `primary` is the one member that carries the group's identity. */
|
|
21824
|
-
role: _enum([
|
|
21825
|
-
"primary",
|
|
21826
|
-
"sibling",
|
|
21827
|
-
"child"
|
|
21828
|
-
]).nullable(),
|
|
21829
|
-
joinedAt: number(),
|
|
21830
|
-
/** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
|
|
21831
|
-
* at read time. Absent when nothing resolved, never an empty string. */
|
|
21832
|
-
label: string().optional(),
|
|
21833
|
-
/** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
|
|
21834
|
-
* recognised nobody, and absent for a member whose track has been pruned —
|
|
21835
|
-
* a thumbnail that names the wrong person is worse than one naming nobody. */
|
|
21836
|
-
subLabel: string().optional()
|
|
21837
|
-
})).readonly()
|
|
21838
|
-
});
|
|
21839
|
-
/**
|
|
21840
|
-
* What a LIST of groups carries: the envelope plus what it is MADE OF.
|
|
21841
|
-
*
|
|
21842
|
-
* Coarse on purpose — the operator's rule is "only the rough data on the list,
|
|
21843
|
-
* we extend when we notice we need more". Enough to draw the card ("two people
|
|
21844
|
-
* and a dog") and no more. The MEMBERS, their names and the per-member links
|
|
21845
|
-
* are on {@link getSummary}: shipping every member of every group so a client
|
|
21846
|
-
* can count them turns a page of two hundred groups into a thousand records to
|
|
21847
|
-
* draw two hundred badges.
|
|
21848
|
-
*/
|
|
21849
|
-
var SummaryListItemSchema = object({
|
|
21850
|
-
summary: SummarySchema,
|
|
21851
|
-
/** Class counts, most numerous first; `className: null` is a member whose
|
|
21852
|
-
* class never resolved, counted so the counts add up to `memberCount`. */
|
|
21853
|
-
classes: array(object({
|
|
21854
|
-
className: string().nullable(),
|
|
21855
|
-
count: number().int().positive()
|
|
21856
|
-
})).readonly()
|
|
21857
|
-
});
|
|
21858
|
-
var SummariesPageSchema = object({ summaries: array(SummaryListItemSchema).readonly() });
|
|
21859
|
-
/**
|
|
21860
|
-
* The paged feed, deliberately the SAME shape as {@link RecentTracksQueryInput}.
|
|
21861
|
-
*
|
|
21862
|
-
* The reel on the cameras page and the Events gallery both ride a cursor, so a
|
|
21863
|
-
* summaries feed that could only answer "the last N for these cameras"
|
|
21864
|
-
* (`listSummaries`) would make groups available in the timeline and nowhere
|
|
21865
|
-
* else. Two feeds with different ordering contracts would be two ideas of what
|
|
21866
|
-
* "newest" means, on one screen.
|
|
21867
|
-
*/
|
|
21868
|
-
var RecentSummariesQueryInput = object({
|
|
21869
|
-
/** Devices to merge. An empty array yields an empty page. */
|
|
21870
|
-
deviceIds: array(number()),
|
|
21871
|
-
/** Window lower bound on `lastActiveAt` (inclusive). */
|
|
21872
|
-
since: number().optional(),
|
|
21873
|
-
/** Window upper bound on `lastActiveAt` (inclusive). */
|
|
21874
|
-
until: number().optional(),
|
|
21875
|
-
limit: number().int().min(1).max(500).default(100),
|
|
21876
|
-
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
21877
|
-
cursor: string().optional(),
|
|
21878
|
-
/**
|
|
21879
|
-
* Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
|
|
21880
|
-
* deliberately the same name: the events filter tree emits one list of ticked
|
|
21881
|
-
* taxonomy nodes, and a summaries feed that called it something else would
|
|
21882
|
-
* make the operator's one filter component produce two shapes.
|
|
21883
|
-
*
|
|
21884
|
-
* A question about the MEMBERS: a group matches when ANY of them does. "Show
|
|
21885
|
-
* me the arrivals with a dog" has to return the group of four people who had
|
|
21886
|
-
* one with them; a filter on the group's own fields could only ever answer
|
|
21887
|
-
* about its primary.
|
|
21888
|
-
*
|
|
21889
|
-
* Matched against all THREE tiers of a member — the class (`animal`), the
|
|
21890
|
-
* sub-class (`dog`) and the instance (a name, a plate) — because which tier a
|
|
21891
|
-
* ticked node lives on is the taxonomy's business, not the caller's. `dog` is
|
|
21892
|
-
* an event kind in the tree and a tier-1 label on an `animal` track; a filter
|
|
21893
|
-
* that read only the class would answer "animal" and never "dog".
|
|
21894
|
-
*
|
|
21895
|
-
* ABSENT or EMPTY means no filter — absent is not a selection of none.
|
|
21896
|
-
*/
|
|
21897
|
-
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21898
|
-
});
|
|
21899
|
-
var RecentSummariesPageSchema = object({
|
|
21900
|
-
/** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
|
|
21901
|
-
* {@link listSummaries} — one list shape, so a card renders the same
|
|
21902
|
-
* whichever feed drew it. */
|
|
21903
|
-
summaries: array(SummaryListItemSchema).readonly(),
|
|
21904
|
-
nextCursor: string().nullable()
|
|
21905
|
-
});
|
|
21906
21897
|
var RecentTracksPageSchema = object({
|
|
21907
21898
|
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
21908
21899
|
tracks: array(TrackSchema).readonly(),
|
|
@@ -22414,7 +22405,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
22414
22405
|
classes: array(string()).optional(),
|
|
22415
22406
|
/** See {@link ExcludeSourcesDoc}. */
|
|
22416
22407
|
excludeSources: array(TrackSourceSchema).optional()
|
|
22417
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(
|
|
22408
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
22418
22409
|
kind: "mutation",
|
|
22419
22410
|
auth: "admin"
|
|
22420
22411
|
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
|
|
@@ -23634,6 +23625,23 @@ var MotionSourceEnum = _enum([
|
|
|
23634
23625
|
*/
|
|
23635
23626
|
var MotionSourcesSchema = array(MotionSourceEnum);
|
|
23636
23627
|
/**
|
|
23628
|
+
* The operator-facing name of each MOTION source (D672: `onboard` = the
|
|
23629
|
+
* camera's sensors — its own motion plus any sensor attached to it). The wire
|
|
23630
|
+
* value stays `onboard`; only the label changed. `detectionSources: 'onboard'`
|
|
23631
|
+
* ("Camera onboard AI") and the notification source filter keep their labels.
|
|
23632
|
+
*/
|
|
23633
|
+
var MOTION_SOURCE_LABELS = {
|
|
23634
|
+
analyzer: "Frame-diff Analyzer (motion addon)",
|
|
23635
|
+
onboard: "Camera sensors",
|
|
23636
|
+
"device-activity": "Device activity (the device says it is working)"
|
|
23637
|
+
};
|
|
23638
|
+
/** The order the motion-source picker offers them in (not the enum's order). */
|
|
23639
|
+
var MOTION_SOURCE_PICKER_ORDER = [
|
|
23640
|
+
"analyzer",
|
|
23641
|
+
"onboard",
|
|
23642
|
+
"device-activity"
|
|
23643
|
+
];
|
|
23644
|
+
/**
|
|
23637
23645
|
* Which root detector a camera runs — EXACTLY ONE.
|
|
23638
23646
|
*
|
|
23639
23647
|
* Deliberately the SAME vocabulary post-analysis already tags every detection
|
|
@@ -23980,7 +23988,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
23980
23988
|
*/
|
|
23981
23989
|
inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
|
|
23982
23990
|
});
|
|
23983
|
-
|
|
23991
|
+
MOTION_SOURCE_PICKER_ORDER.map((value) => value === "onboard" ? {
|
|
23992
|
+
value,
|
|
23993
|
+
label: MOTION_SOURCE_LABELS[value],
|
|
23994
|
+
description: "The camera's own motion, plus any sensor attached to it"
|
|
23995
|
+
} : {
|
|
23996
|
+
value,
|
|
23997
|
+
label: MOTION_SOURCE_LABELS[value]
|
|
23998
|
+
}), motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, maxSessionHoldMsField.min, maxSessionHoldMsField.max, maxSessionHoldMsField.step, maxSessionHoldMsField.default, audioMotionWindowMsField.min, audioMotionWindowMsField.max, audioMotionWindowMsField.step, audioMotionWindowMsField.default, preRollInferenceFramesField.min, preRollInferenceFramesField.max, preRollInferenceFramesField.step, preRollInferenceFramesField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
|
|
23984
23999
|
/**
|
|
23985
24000
|
* Runtime load summary returned by `getLocalLoad`. Used by the orchestrator's
|
|
23986
24001
|
* load-balancing levels (L2 capacity-based, L3 hardware-aware) to decide
|
|
@@ -24554,6 +24569,11 @@ var CameraStatusSchema = object({
|
|
|
24554
24569
|
*/
|
|
24555
24570
|
switchedOff: array(CameraSwitchIdSchema).readonly(),
|
|
24556
24571
|
/**
|
|
24572
|
+
* The camera's attached sensors (D672). Optional only for a status composed
|
|
24573
|
+
* by an orchestrator older than D672; this orchestrator always sets it.
|
|
24574
|
+
*/
|
|
24575
|
+
cameraSensors: CameraSensorsStatusSchema.optional(),
|
|
24576
|
+
/**
|
|
24557
24577
|
* Stages of the bounded fan-out that were CUT SHORT — a timeout or a
|
|
24558
24578
|
* rejection — and whose block is therefore `null` because we could not
|
|
24559
24579
|
* READ it, not because there is nothing there.
|
|
@@ -31892,7 +31912,9 @@ var MotionOnMotionChangedDataSchema = object({
|
|
|
31892
31912
|
detected: boolean(),
|
|
31893
31913
|
timestamp: number(),
|
|
31894
31914
|
source: MotionSourceEnum,
|
|
31895
|
-
regions: array(MotionRegionSchema).readonly().optional()
|
|
31915
|
+
regions: array(MotionRegionSchema).readonly().optional(),
|
|
31916
|
+
/** Who started it (D672). Absent = the camera itself. Only `onboard` carries `sensor`. */
|
|
31917
|
+
triggeredBy: MotionTriggeredBySchema.optional()
|
|
31896
31918
|
});
|
|
31897
31919
|
var motionCapability = {
|
|
31898
31920
|
name: "motion",
|
|
@@ -45338,12 +45360,6 @@ Object.freeze({
|
|
|
45338
45360
|
addonId: null,
|
|
45339
45361
|
access: "view"
|
|
45340
45362
|
},
|
|
45341
|
-
"pipelineAnalytics.getSummary": {
|
|
45342
|
-
capName: "pipeline-analytics",
|
|
45343
|
-
capScope: "device",
|
|
45344
|
-
addonId: null,
|
|
45345
|
-
access: "view"
|
|
45346
|
-
},
|
|
45347
45363
|
"pipelineAnalytics.getTrack": {
|
|
45348
45364
|
capName: "pipeline-analytics",
|
|
45349
45365
|
capScope: "device",
|
|
@@ -45404,12 +45420,6 @@ Object.freeze({
|
|
|
45404
45420
|
addonId: null,
|
|
45405
45421
|
access: "view"
|
|
45406
45422
|
},
|
|
45407
|
-
"pipelineAnalytics.listRecentSummaries": {
|
|
45408
|
-
capName: "pipeline-analytics",
|
|
45409
|
-
capScope: "device",
|
|
45410
|
-
addonId: null,
|
|
45411
|
-
access: "view"
|
|
45412
|
-
},
|
|
45413
45423
|
"pipelineAnalytics.listRecentTracks": {
|
|
45414
45424
|
capName: "pipeline-analytics",
|
|
45415
45425
|
capScope: "device",
|
|
@@ -45440,12 +45450,6 @@ Object.freeze({
|
|
|
45440
45450
|
addonId: null,
|
|
45441
45451
|
access: "view"
|
|
45442
45452
|
},
|
|
45443
|
-
"pipelineAnalytics.listSummaries": {
|
|
45444
|
-
capName: "pipeline-analytics",
|
|
45445
|
-
capScope: "device",
|
|
45446
|
-
addonId: null,
|
|
45447
|
-
access: "view"
|
|
45448
|
-
},
|
|
45449
45453
|
"pipelineAnalytics.listTrackMedia": {
|
|
45450
45454
|
capName: "pipeline-analytics",
|
|
45451
45455
|
capScope: "device",
|
|
@@ -49615,11 +49619,6 @@ Object.freeze({
|
|
|
49615
49619
|
form: "single",
|
|
49616
49620
|
optional: true
|
|
49617
49621
|
}],
|
|
49618
|
-
"pipelineAnalytics.listRecentSummaries": [{
|
|
49619
|
-
name: "deviceIds",
|
|
49620
|
-
form: "array",
|
|
49621
|
-
optional: false
|
|
49622
|
-
}],
|
|
49623
49622
|
"pipelineAnalytics.listRecentTracks": [{
|
|
49624
49623
|
name: "deviceIds",
|
|
49625
49624
|
form: "array",
|
|
@@ -49630,11 +49629,6 @@ Object.freeze({
|
|
|
49630
49629
|
form: "array",
|
|
49631
49630
|
optional: true
|
|
49632
49631
|
}],
|
|
49633
|
-
"pipelineAnalytics.listSummaries": [{
|
|
49634
|
-
name: "deviceIds",
|
|
49635
|
-
form: "array",
|
|
49636
|
-
optional: false
|
|
49637
|
-
}],
|
|
49638
49632
|
"pipelineAnalytics.listTrackMedia": [{
|
|
49639
49633
|
name: "deviceId",
|
|
49640
49634
|
form: "single",
|
|
@@ -75142,6 +75136,20 @@ var COLD_MOTION = {
|
|
|
75142
75136
|
lastDetectedAt: null,
|
|
75143
75137
|
autoClearAfterMs: null
|
|
75144
75138
|
};
|
|
75139
|
+
/**
|
|
75140
|
+
* The motion seed a constructor writes OVER the slice hydrated from the
|
|
75141
|
+
* persisted runtime state. The level is a placeholder (`false`) until the
|
|
75142
|
+
* CCU says otherwise, but a stored rise is a fact: `lastDetectedAt: null`
|
|
75143
|
+
* means "never detected" (`motion.cap.ts`), and a restart must not turn
|
|
75144
|
+
* "fired an hour ago" into that.
|
|
75145
|
+
*/
|
|
75146
|
+
function coldMotionKeepingRise(stored) {
|
|
75147
|
+
const rise = stored?.lastDetectedAt;
|
|
75148
|
+
return {
|
|
75149
|
+
...COLD_MOTION,
|
|
75150
|
+
lastDetectedAt: typeof rise === "number" && Number.isFinite(rise) && rise > 0 ? rise : null
|
|
75151
|
+
};
|
|
75152
|
+
}
|
|
75145
75153
|
var COLD_CLIMATE = {
|
|
75146
75154
|
mode: "auto",
|
|
75147
75155
|
availableModes: [...[
|
|
@@ -76691,7 +76699,7 @@ var HmSensorDevice = class extends HmChildDevice {
|
|
|
76691
76699
|
getStatus: async () => this.runtimeState.getCapState("motion") ?? COLD_MOTION,
|
|
76692
76700
|
isDetected: async () => (this.runtimeState.getCapState("motion") ?? COLD_MOTION).detected
|
|
76693
76701
|
});
|
|
76694
|
-
this.runtimeState.setCapState("motion",
|
|
76702
|
+
this.runtimeState.setCapState("motion", coldMotionKeepingRise(this.runtimeState.getCapState("motion")));
|
|
76695
76703
|
}
|
|
76696
76704
|
handleValueChanged(event, origin) {
|
|
76697
76705
|
const now = event.ts || Date.now();
|
|
@@ -77735,6 +77743,7 @@ exports.HomematicProviderAddon = HomematicProviderAddon;
|
|
|
77735
77743
|
exports.buildConnectionFormSchema = buildConnectionFormSchema;
|
|
77736
77744
|
exports.buildDeviceAdminUrl = buildDeviceAdminUrl;
|
|
77737
77745
|
exports.climateControlCapability = climateControlCapability;
|
|
77746
|
+
exports.coldMotionKeepingRise = coldMotionKeepingRise;
|
|
77738
77747
|
exports.coverCapability = coverCapability;
|
|
77739
77748
|
exports.createEvent = createEvent;
|
|
77740
77749
|
exports.decodeClimate = decodeClimate;
|
package/dist/addon.mjs
CHANGED
|
@@ -5380,7 +5380,7 @@ var ZodIssueCode = {
|
|
|
5380
5380
|
var ZodFirstPartyTypeKind;
|
|
5381
5381
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5382
5382
|
//#endregion
|
|
5383
|
-
//#region ../types/dist/sleep-
|
|
5383
|
+
//#region ../types/dist/sleep-C-v96WpE.mjs
|
|
5384
5384
|
/**
|
|
5385
5385
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5386
5386
|
* window to float samples (D455).
|
|
@@ -8229,7 +8229,6 @@ var CompositionSchema = object({
|
|
|
8229
8229
|
});
|
|
8230
8230
|
new Set([
|
|
8231
8231
|
"track",
|
|
8232
|
-
"summary",
|
|
8233
8232
|
"face",
|
|
8234
8233
|
"identity",
|
|
8235
8234
|
"plate",
|
|
@@ -20538,6 +20537,102 @@ var OauthIntegrationDescriptorSchema = object({
|
|
|
20538
20537
|
});
|
|
20539
20538
|
method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
|
|
20540
20539
|
/**
|
|
20540
|
+
* What started a camera's onboard motion (D672). `camera` is the camera's own
|
|
20541
|
+
* firmware; `sensor` is a device the operator ATTACHED to it. Absent on the
|
|
20542
|
+
* wire means the camera: only the camera-sensors bridge ever says `sensor`.
|
|
20543
|
+
*/
|
|
20544
|
+
var MotionTriggeredBySchema = discriminatedUnion("kind", [object({ kind: literal("camera") }), object({
|
|
20545
|
+
kind: literal("sensor"),
|
|
20546
|
+
deviceId: number().int().positive()
|
|
20547
|
+
})]);
|
|
20548
|
+
Object.freeze({ kind: "camera" });
|
|
20549
|
+
var CameraSensorRefSchema = object({
|
|
20550
|
+
addonId: string().min(1),
|
|
20551
|
+
stableId: string().min(1)
|
|
20552
|
+
});
|
|
20553
|
+
function cameraSensorRefKey(ref) {
|
|
20554
|
+
return `${ref.addonId}/${ref.stableId}`;
|
|
20555
|
+
}
|
|
20556
|
+
/** CS-1 accepts exactly one mode; CS-2 (D673) widens it to confirm / replace. */
|
|
20557
|
+
var CameraSensorsModeSchema = _enum(["in-addition"]);
|
|
20558
|
+
object({
|
|
20559
|
+
mode: CameraSensorsModeSchema,
|
|
20560
|
+
sensors: array(CameraSensorRefSchema).min(1).max(8)
|
|
20561
|
+
}).superRefine((value, ctx) => {
|
|
20562
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20563
|
+
value.sensors.forEach((ref, index) => {
|
|
20564
|
+
const key = cameraSensorRefKey(ref);
|
|
20565
|
+
if (seen.has(key)) ctx.addIssue({
|
|
20566
|
+
code: "custom",
|
|
20567
|
+
path: ["sensors", index],
|
|
20568
|
+
message: `duplicate camera sensor ${key}`
|
|
20569
|
+
});
|
|
20570
|
+
seen.add(key);
|
|
20571
|
+
});
|
|
20572
|
+
});
|
|
20573
|
+
var RefFields = {
|
|
20574
|
+
addonId: string(),
|
|
20575
|
+
stableId: string()
|
|
20576
|
+
};
|
|
20577
|
+
var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
20578
|
+
object({
|
|
20579
|
+
...RefFields,
|
|
20580
|
+
state: literal("ready"),
|
|
20581
|
+
deviceId: number(),
|
|
20582
|
+
name: string(),
|
|
20583
|
+
caps: array(string()).readonly()
|
|
20584
|
+
}),
|
|
20585
|
+
object({
|
|
20586
|
+
...RefFields,
|
|
20587
|
+
state: literal("offline"),
|
|
20588
|
+
deviceId: number(),
|
|
20589
|
+
name: string(),
|
|
20590
|
+
reason: _enum(["offline", "disabled"])
|
|
20591
|
+
}),
|
|
20592
|
+
object({
|
|
20593
|
+
...RefFields,
|
|
20594
|
+
state: literal("missing"),
|
|
20595
|
+
reason: string()
|
|
20596
|
+
}),
|
|
20597
|
+
object({
|
|
20598
|
+
...RefFields,
|
|
20599
|
+
state: literal("unsupported"),
|
|
20600
|
+
deviceId: number(),
|
|
20601
|
+
name: string(),
|
|
20602
|
+
reason: string()
|
|
20603
|
+
}),
|
|
20604
|
+
object({
|
|
20605
|
+
...RefFields,
|
|
20606
|
+
state: literal("unreadable"),
|
|
20607
|
+
reason: string()
|
|
20608
|
+
})
|
|
20609
|
+
]);
|
|
20610
|
+
/**
|
|
20611
|
+
* Why a configured camera forwards NOTHING from its sensors, however ready they
|
|
20612
|
+
* are (D672): it does not list `onboard` in `motionSources` (attaching a sensor
|
|
20613
|
+
* does not add it), or it has no active detection config at all (the bridge
|
|
20614
|
+
* reads the active config). Absent = forwarded, or an older node that does not
|
|
20615
|
+
* say.
|
|
20616
|
+
*/
|
|
20617
|
+
var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
|
|
20618
|
+
var CameraSensorsStatusSchema = discriminatedUnion("state", [
|
|
20619
|
+
object({ state: literal("not-configured") }),
|
|
20620
|
+
object({
|
|
20621
|
+
state: literal("unreadable"),
|
|
20622
|
+
reason: string()
|
|
20623
|
+
}),
|
|
20624
|
+
object({
|
|
20625
|
+
state: literal("configured"),
|
|
20626
|
+
mode: CameraSensorsModeSchema,
|
|
20627
|
+
sensors: array(CameraSensorAttachmentSchema).readonly(),
|
|
20628
|
+
notForwarded: CameraSensorsNotForwardedSchema.optional()
|
|
20629
|
+
})
|
|
20630
|
+
]);
|
|
20631
|
+
Object.freeze({
|
|
20632
|
+
state: "unreadable",
|
|
20633
|
+
reason: "camera sensor mappings not loaded"
|
|
20634
|
+
});
|
|
20635
|
+
/**
|
|
20541
20636
|
* A model choice has a SCOPE, and a scope change has a workflow.
|
|
20542
20637
|
*
|
|
20543
20638
|
* ## The two scopes
|
|
@@ -21286,6 +21381,12 @@ var MotionEventSchema = object({
|
|
|
21286
21381
|
/** Populated by B5 (recording playback URL for this event). */
|
|
21287
21382
|
mediaUrl: string().optional(),
|
|
21288
21383
|
/**
|
|
21384
|
+
* The FIRST trigger of an `onboard` episode, written once at open (D672).
|
|
21385
|
+
* Absent = not recorded (a row written before D672, or an analyzer /
|
|
21386
|
+
* device-activity episode) — never read as "the camera" (D393).
|
|
21387
|
+
*/
|
|
21388
|
+
triggeredBy: MotionTriggeredBySchema.optional(),
|
|
21389
|
+
/**
|
|
21289
21390
|
* One row per motion EPISODE, not one per push (D475). `null` while the
|
|
21290
21391
|
* episode is still open — a further rising edge extends it in place rather
|
|
21291
21392
|
* than inserting a new row. Set once, at close, to `lastOnAt - startedAt`
|
|
@@ -21444,6 +21545,21 @@ var ObjectEventSchema = object({
|
|
|
21444
21545
|
keyFrameMediaId: number().int().optional(),
|
|
21445
21546
|
/** Populated by B5 (recording playback URL for this event). */
|
|
21446
21547
|
mediaUrl: string().optional(),
|
|
21548
|
+
/**
|
|
21549
|
+
* When the change this row records HAPPENED, epoch ms, when that is earlier
|
|
21550
|
+
* than {@link timestamp} and the producer could date it (D684).
|
|
21551
|
+
*
|
|
21552
|
+
* Set on a package PICK-UP row only: its `timestamp` is when the departure
|
|
21553
|
+
* was CONCLUDED — five minutes of unseen observed time after the parcel went
|
|
21554
|
+
* — and a notification's footage has to be cut around the pick-up, not the
|
|
21555
|
+
* empty doormat after it (D682). Stored so every path that rebuilds a
|
|
21556
|
+
* notification subject from the row (the boot reconcile, a dry-run) anchors
|
|
21557
|
+
* on the same instant the live hook did.
|
|
21558
|
+
*
|
|
21559
|
+
* `timestamp` keeps its meaning. Absent on every other row and on every
|
|
21560
|
+
* pick-up written before D684 — UNKNOWN, never 0 and never `timestamp`.
|
|
21561
|
+
*/
|
|
21562
|
+
observedAt: number().optional(),
|
|
21447
21563
|
/** The parent track's key-event importance [0,1], propagated to every object
|
|
21448
21564
|
* event of the track (so an event row can be sorted by importance without a
|
|
21449
21565
|
* track join). Absent on legacy rows / before the track was scored. */
|
|
@@ -21779,131 +21895,6 @@ var RecentTracksQueryInput = object({
|
|
|
21779
21895
|
/** See {@link ExcludeSourcesDoc}. */
|
|
21780
21896
|
excludeSources: array(TrackSourceSchema).optional()
|
|
21781
21897
|
});
|
|
21782
|
-
/**
|
|
21783
|
-
* A Summary (D359): the per-camera session envelope that references tracks.
|
|
21784
|
-
* `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
|
|
21785
|
-
* 'summary'`, served by the event-media plane at `/m/<id>`), null until the
|
|
21786
|
-
* first frame with a member visible has been materialised (D482 — it was the
|
|
21787
|
-
* row's composite key, which embedded the owner and could name another table's
|
|
21788
|
-
* row once event ids became per-table rowids).
|
|
21789
|
-
*/
|
|
21790
|
-
var SummarySchema = object({
|
|
21791
|
-
id: string(),
|
|
21792
|
-
deviceId: number(),
|
|
21793
|
-
openedAt: number(),
|
|
21794
|
-
lastActiveAt: number(),
|
|
21795
|
-
sealedAt: number().nullable(),
|
|
21796
|
-
memberCount: number().int().nonnegative(),
|
|
21797
|
-
groupShotMediaId: number().int().nullable()
|
|
21798
|
-
});
|
|
21799
|
-
var SummariesQueryInput = object({
|
|
21800
|
-
deviceIds: array(number()).min(1),
|
|
21801
|
-
since: number().optional(),
|
|
21802
|
-
until: number().optional(),
|
|
21803
|
-
limit: number().int().min(1).max(200).default(50),
|
|
21804
|
-
/** The same member-wise filter {@link listRecentSummaries} takes — one
|
|
21805
|
-
* meaning of "dog" on every summary surface. */
|
|
21806
|
-
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21807
|
-
});
|
|
21808
|
-
var SummaryDetailSchema = object({
|
|
21809
|
-
summary: SummarySchema,
|
|
21810
|
-
/** Members in absorption order, oldest join first. */
|
|
21811
|
-
members: array(object({
|
|
21812
|
-
trackId: string(),
|
|
21813
|
-
/**
|
|
21814
|
-
* The track's class at the time it JOINED, or `null` when it was unresolved
|
|
21815
|
-
* and the track no longer exists to fill it.
|
|
21816
|
-
*
|
|
21817
|
-
* The join, not the latest opinion: class voting can re-decide a track's
|
|
21818
|
-
* class afterwards, and a group's composition is the history of who came
|
|
21819
|
-
* together. A consumer counts these to badge a thumbnail — "two people and a
|
|
21820
|
-
* dog" — rather than being handed a second, denormalised tally that would
|
|
21821
|
-
* drift from the members it claims to describe.
|
|
21822
|
-
*/
|
|
21823
|
-
className: string().nullable(),
|
|
21824
|
-
/** `primary` is the one member that carries the group's identity. */
|
|
21825
|
-
role: _enum([
|
|
21826
|
-
"primary",
|
|
21827
|
-
"sibling",
|
|
21828
|
-
"child"
|
|
21829
|
-
]).nullable(),
|
|
21830
|
-
joinedAt: number(),
|
|
21831
|
-
/** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
|
|
21832
|
-
* at read time. Absent when nothing resolved, never an empty string. */
|
|
21833
|
-
label: string().optional(),
|
|
21834
|
-
/** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
|
|
21835
|
-
* recognised nobody, and absent for a member whose track has been pruned —
|
|
21836
|
-
* a thumbnail that names the wrong person is worse than one naming nobody. */
|
|
21837
|
-
subLabel: string().optional()
|
|
21838
|
-
})).readonly()
|
|
21839
|
-
});
|
|
21840
|
-
/**
|
|
21841
|
-
* What a LIST of groups carries: the envelope plus what it is MADE OF.
|
|
21842
|
-
*
|
|
21843
|
-
* Coarse on purpose — the operator's rule is "only the rough data on the list,
|
|
21844
|
-
* we extend when we notice we need more". Enough to draw the card ("two people
|
|
21845
|
-
* and a dog") and no more. The MEMBERS, their names and the per-member links
|
|
21846
|
-
* are on {@link getSummary}: shipping every member of every group so a client
|
|
21847
|
-
* can count them turns a page of two hundred groups into a thousand records to
|
|
21848
|
-
* draw two hundred badges.
|
|
21849
|
-
*/
|
|
21850
|
-
var SummaryListItemSchema = object({
|
|
21851
|
-
summary: SummarySchema,
|
|
21852
|
-
/** Class counts, most numerous first; `className: null` is a member whose
|
|
21853
|
-
* class never resolved, counted so the counts add up to `memberCount`. */
|
|
21854
|
-
classes: array(object({
|
|
21855
|
-
className: string().nullable(),
|
|
21856
|
-
count: number().int().positive()
|
|
21857
|
-
})).readonly()
|
|
21858
|
-
});
|
|
21859
|
-
var SummariesPageSchema = object({ summaries: array(SummaryListItemSchema).readonly() });
|
|
21860
|
-
/**
|
|
21861
|
-
* The paged feed, deliberately the SAME shape as {@link RecentTracksQueryInput}.
|
|
21862
|
-
*
|
|
21863
|
-
* The reel on the cameras page and the Events gallery both ride a cursor, so a
|
|
21864
|
-
* summaries feed that could only answer "the last N for these cameras"
|
|
21865
|
-
* (`listSummaries`) would make groups available in the timeline and nowhere
|
|
21866
|
-
* else. Two feeds with different ordering contracts would be two ideas of what
|
|
21867
|
-
* "newest" means, on one screen.
|
|
21868
|
-
*/
|
|
21869
|
-
var RecentSummariesQueryInput = object({
|
|
21870
|
-
/** Devices to merge. An empty array yields an empty page. */
|
|
21871
|
-
deviceIds: array(number()),
|
|
21872
|
-
/** Window lower bound on `lastActiveAt` (inclusive). */
|
|
21873
|
-
since: number().optional(),
|
|
21874
|
-
/** Window upper bound on `lastActiveAt` (inclusive). */
|
|
21875
|
-
until: number().optional(),
|
|
21876
|
-
limit: number().int().min(1).max(500).default(100),
|
|
21877
|
-
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
21878
|
-
cursor: string().optional(),
|
|
21879
|
-
/**
|
|
21880
|
-
* Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
|
|
21881
|
-
* deliberately the same name: the events filter tree emits one list of ticked
|
|
21882
|
-
* taxonomy nodes, and a summaries feed that called it something else would
|
|
21883
|
-
* make the operator's one filter component produce two shapes.
|
|
21884
|
-
*
|
|
21885
|
-
* A question about the MEMBERS: a group matches when ANY of them does. "Show
|
|
21886
|
-
* me the arrivals with a dog" has to return the group of four people who had
|
|
21887
|
-
* one with them; a filter on the group's own fields could only ever answer
|
|
21888
|
-
* about its primary.
|
|
21889
|
-
*
|
|
21890
|
-
* Matched against all THREE tiers of a member — the class (`animal`), the
|
|
21891
|
-
* sub-class (`dog`) and the instance (a name, a plate) — because which tier a
|
|
21892
|
-
* ticked node lives on is the taxonomy's business, not the caller's. `dog` is
|
|
21893
|
-
* an event kind in the tree and a tier-1 label on an `animal` track; a filter
|
|
21894
|
-
* that read only the class would answer "animal" and never "dog".
|
|
21895
|
-
*
|
|
21896
|
-
* ABSENT or EMPTY means no filter — absent is not a selection of none.
|
|
21897
|
-
*/
|
|
21898
|
-
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21899
|
-
});
|
|
21900
|
-
var RecentSummariesPageSchema = object({
|
|
21901
|
-
/** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
|
|
21902
|
-
* {@link listSummaries} — one list shape, so a card renders the same
|
|
21903
|
-
* whichever feed drew it. */
|
|
21904
|
-
summaries: array(SummaryListItemSchema).readonly(),
|
|
21905
|
-
nextCursor: string().nullable()
|
|
21906
|
-
});
|
|
21907
21898
|
var RecentTracksPageSchema = object({
|
|
21908
21899
|
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
21909
21900
|
tracks: array(TrackSchema).readonly(),
|
|
@@ -22415,7 +22406,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
22415
22406
|
classes: array(string()).optional(),
|
|
22416
22407
|
/** See {@link ExcludeSourcesDoc}. */
|
|
22417
22408
|
excludeSources: array(TrackSourceSchema).optional()
|
|
22418
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(
|
|
22409
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
22419
22410
|
kind: "mutation",
|
|
22420
22411
|
auth: "admin"
|
|
22421
22412
|
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
|
|
@@ -23635,6 +23626,23 @@ var MotionSourceEnum = _enum([
|
|
|
23635
23626
|
*/
|
|
23636
23627
|
var MotionSourcesSchema = array(MotionSourceEnum);
|
|
23637
23628
|
/**
|
|
23629
|
+
* The operator-facing name of each MOTION source (D672: `onboard` = the
|
|
23630
|
+
* camera's sensors — its own motion plus any sensor attached to it). The wire
|
|
23631
|
+
* value stays `onboard`; only the label changed. `detectionSources: 'onboard'`
|
|
23632
|
+
* ("Camera onboard AI") and the notification source filter keep their labels.
|
|
23633
|
+
*/
|
|
23634
|
+
var MOTION_SOURCE_LABELS = {
|
|
23635
|
+
analyzer: "Frame-diff Analyzer (motion addon)",
|
|
23636
|
+
onboard: "Camera sensors",
|
|
23637
|
+
"device-activity": "Device activity (the device says it is working)"
|
|
23638
|
+
};
|
|
23639
|
+
/** The order the motion-source picker offers them in (not the enum's order). */
|
|
23640
|
+
var MOTION_SOURCE_PICKER_ORDER = [
|
|
23641
|
+
"analyzer",
|
|
23642
|
+
"onboard",
|
|
23643
|
+
"device-activity"
|
|
23644
|
+
];
|
|
23645
|
+
/**
|
|
23638
23646
|
* Which root detector a camera runs — EXACTLY ONE.
|
|
23639
23647
|
*
|
|
23640
23648
|
* Deliberately the SAME vocabulary post-analysis already tags every detection
|
|
@@ -23981,7 +23989,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
23981
23989
|
*/
|
|
23982
23990
|
inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
|
|
23983
23991
|
});
|
|
23984
|
-
|
|
23992
|
+
MOTION_SOURCE_PICKER_ORDER.map((value) => value === "onboard" ? {
|
|
23993
|
+
value,
|
|
23994
|
+
label: MOTION_SOURCE_LABELS[value],
|
|
23995
|
+
description: "The camera's own motion, plus any sensor attached to it"
|
|
23996
|
+
} : {
|
|
23997
|
+
value,
|
|
23998
|
+
label: MOTION_SOURCE_LABELS[value]
|
|
23999
|
+
}), motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, maxSessionHoldMsField.min, maxSessionHoldMsField.max, maxSessionHoldMsField.step, maxSessionHoldMsField.default, audioMotionWindowMsField.min, audioMotionWindowMsField.max, audioMotionWindowMsField.step, audioMotionWindowMsField.default, preRollInferenceFramesField.min, preRollInferenceFramesField.max, preRollInferenceFramesField.step, preRollInferenceFramesField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
|
|
23985
24000
|
/**
|
|
23986
24001
|
* Runtime load summary returned by `getLocalLoad`. Used by the orchestrator's
|
|
23987
24002
|
* load-balancing levels (L2 capacity-based, L3 hardware-aware) to decide
|
|
@@ -24555,6 +24570,11 @@ var CameraStatusSchema = object({
|
|
|
24555
24570
|
*/
|
|
24556
24571
|
switchedOff: array(CameraSwitchIdSchema).readonly(),
|
|
24557
24572
|
/**
|
|
24573
|
+
* The camera's attached sensors (D672). Optional only for a status composed
|
|
24574
|
+
* by an orchestrator older than D672; this orchestrator always sets it.
|
|
24575
|
+
*/
|
|
24576
|
+
cameraSensors: CameraSensorsStatusSchema.optional(),
|
|
24577
|
+
/**
|
|
24558
24578
|
* Stages of the bounded fan-out that were CUT SHORT — a timeout or a
|
|
24559
24579
|
* rejection — and whose block is therefore `null` because we could not
|
|
24560
24580
|
* READ it, not because there is nothing there.
|
|
@@ -31893,7 +31913,9 @@ var MotionOnMotionChangedDataSchema = object({
|
|
|
31893
31913
|
detected: boolean(),
|
|
31894
31914
|
timestamp: number(),
|
|
31895
31915
|
source: MotionSourceEnum,
|
|
31896
|
-
regions: array(MotionRegionSchema).readonly().optional()
|
|
31916
|
+
regions: array(MotionRegionSchema).readonly().optional(),
|
|
31917
|
+
/** Who started it (D672). Absent = the camera itself. Only `onboard` carries `sensor`. */
|
|
31918
|
+
triggeredBy: MotionTriggeredBySchema.optional()
|
|
31897
31919
|
});
|
|
31898
31920
|
var motionCapability = {
|
|
31899
31921
|
name: "motion",
|
|
@@ -45339,12 +45361,6 @@ Object.freeze({
|
|
|
45339
45361
|
addonId: null,
|
|
45340
45362
|
access: "view"
|
|
45341
45363
|
},
|
|
45342
|
-
"pipelineAnalytics.getSummary": {
|
|
45343
|
-
capName: "pipeline-analytics",
|
|
45344
|
-
capScope: "device",
|
|
45345
|
-
addonId: null,
|
|
45346
|
-
access: "view"
|
|
45347
|
-
},
|
|
45348
45364
|
"pipelineAnalytics.getTrack": {
|
|
45349
45365
|
capName: "pipeline-analytics",
|
|
45350
45366
|
capScope: "device",
|
|
@@ -45405,12 +45421,6 @@ Object.freeze({
|
|
|
45405
45421
|
addonId: null,
|
|
45406
45422
|
access: "view"
|
|
45407
45423
|
},
|
|
45408
|
-
"pipelineAnalytics.listRecentSummaries": {
|
|
45409
|
-
capName: "pipeline-analytics",
|
|
45410
|
-
capScope: "device",
|
|
45411
|
-
addonId: null,
|
|
45412
|
-
access: "view"
|
|
45413
|
-
},
|
|
45414
45424
|
"pipelineAnalytics.listRecentTracks": {
|
|
45415
45425
|
capName: "pipeline-analytics",
|
|
45416
45426
|
capScope: "device",
|
|
@@ -45441,12 +45451,6 @@ Object.freeze({
|
|
|
45441
45451
|
addonId: null,
|
|
45442
45452
|
access: "view"
|
|
45443
45453
|
},
|
|
45444
|
-
"pipelineAnalytics.listSummaries": {
|
|
45445
|
-
capName: "pipeline-analytics",
|
|
45446
|
-
capScope: "device",
|
|
45447
|
-
addonId: null,
|
|
45448
|
-
access: "view"
|
|
45449
|
-
},
|
|
45450
45454
|
"pipelineAnalytics.listTrackMedia": {
|
|
45451
45455
|
capName: "pipeline-analytics",
|
|
45452
45456
|
capScope: "device",
|
|
@@ -49616,11 +49620,6 @@ Object.freeze({
|
|
|
49616
49620
|
form: "single",
|
|
49617
49621
|
optional: true
|
|
49618
49622
|
}],
|
|
49619
|
-
"pipelineAnalytics.listRecentSummaries": [{
|
|
49620
|
-
name: "deviceIds",
|
|
49621
|
-
form: "array",
|
|
49622
|
-
optional: false
|
|
49623
|
-
}],
|
|
49624
49623
|
"pipelineAnalytics.listRecentTracks": [{
|
|
49625
49624
|
name: "deviceIds",
|
|
49626
49625
|
form: "array",
|
|
@@ -49631,11 +49630,6 @@ Object.freeze({
|
|
|
49631
49630
|
form: "array",
|
|
49632
49631
|
optional: true
|
|
49633
49632
|
}],
|
|
49634
|
-
"pipelineAnalytics.listSummaries": [{
|
|
49635
|
-
name: "deviceIds",
|
|
49636
|
-
form: "array",
|
|
49637
|
-
optional: false
|
|
49638
|
-
}],
|
|
49639
49633
|
"pipelineAnalytics.listTrackMedia": [{
|
|
49640
49634
|
name: "deviceId",
|
|
49641
49635
|
form: "single",
|
|
@@ -75143,6 +75137,20 @@ var COLD_MOTION = {
|
|
|
75143
75137
|
lastDetectedAt: null,
|
|
75144
75138
|
autoClearAfterMs: null
|
|
75145
75139
|
};
|
|
75140
|
+
/**
|
|
75141
|
+
* The motion seed a constructor writes OVER the slice hydrated from the
|
|
75142
|
+
* persisted runtime state. The level is a placeholder (`false`) until the
|
|
75143
|
+
* CCU says otherwise, but a stored rise is a fact: `lastDetectedAt: null`
|
|
75144
|
+
* means "never detected" (`motion.cap.ts`), and a restart must not turn
|
|
75145
|
+
* "fired an hour ago" into that.
|
|
75146
|
+
*/
|
|
75147
|
+
function coldMotionKeepingRise(stored) {
|
|
75148
|
+
const rise = stored?.lastDetectedAt;
|
|
75149
|
+
return {
|
|
75150
|
+
...COLD_MOTION,
|
|
75151
|
+
lastDetectedAt: typeof rise === "number" && Number.isFinite(rise) && rise > 0 ? rise : null
|
|
75152
|
+
};
|
|
75153
|
+
}
|
|
75146
75154
|
var COLD_CLIMATE = {
|
|
75147
75155
|
mode: "auto",
|
|
75148
75156
|
availableModes: [...[
|
|
@@ -76692,7 +76700,7 @@ var HmSensorDevice = class extends HmChildDevice {
|
|
|
76692
76700
|
getStatus: async () => this.runtimeState.getCapState("motion") ?? COLD_MOTION,
|
|
76693
76701
|
isDetected: async () => (this.runtimeState.getCapState("motion") ?? COLD_MOTION).detected
|
|
76694
76702
|
});
|
|
76695
|
-
this.runtimeState.setCapState("motion",
|
|
76703
|
+
this.runtimeState.setCapState("motion", coldMotionKeepingRise(this.runtimeState.getCapState("motion")));
|
|
76696
76704
|
}
|
|
76697
76705
|
handleValueChanged(event, origin) {
|
|
76698
76706
|
const now = event.ts || Date.now();
|
|
@@ -77729,4 +77737,4 @@ var HomematicProviderAddon = class extends BaseDeviceProvider {
|
|
|
77729
77737
|
}
|
|
77730
77738
|
};
|
|
77731
77739
|
//#endregion
|
|
77732
|
-
export {
|
|
77740
|
+
export { object as A, deviceAdminLinkCapability as C, switchCapability as D, motionCapability as E, HomematicProviderAddon, EventCategory as M, DeviceType as O, coverCapability as S, lockControlCapability as T, homematicConfigSchema as _, decodeClimate as a, buildDeviceAdminUrl as b, toHmClimateMode as c, inferHmDeviceType as d, mapHmChannel as f, homematicAddonConfigSchema as g, buildConnectionFormSchema as h, registerTemperatureCap as i, string as j, createEvent as k, deriveHmEntitySpecs as l, homematicFacades as m, registerHumidityCap as n, decodeCover as o, mapHmDeviceChannels as p, registerPowerMeterCap as r, decodeLock as s, registerAmbientLightCap as t, coldMotionKeepingRise as u, toHomematicOptions as v, eventEmitterCapability as w, climateControlCapability as x, BaseDevice as y };
|
package/dist/index.js
CHANGED
|
@@ -395,7 +395,7 @@ var HomematicDevice = class extends require_addon.BaseDevice {
|
|
|
395
395
|
getStatus: async () => this.runtimeState.getCapState("motion") ?? COLD_MOTION,
|
|
396
396
|
isDetected: async () => (this.runtimeState.getCapState("motion") ?? COLD_MOTION).detected
|
|
397
397
|
});
|
|
398
|
-
this.runtimeState.setCapState("motion",
|
|
398
|
+
this.runtimeState.setCapState("motion", require_addon.coldMotionKeepingRise(this.runtimeState.getCapState("motion")));
|
|
399
399
|
}
|
|
400
400
|
registerEventEmitterCap(keyChannels) {
|
|
401
401
|
this.eventTypes = keyEventVocabulary(keyChannels);
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as object, C as deviceAdminLinkCapability, D as switchCapability, E as motionCapability, HomematicProviderAddon, M as EventCategory, O as DeviceType, S as coverCapability, T as lockControlCapability, _ as homematicConfigSchema, a as decodeClimate, b as buildDeviceAdminUrl, c as toHmClimateMode, d as inferHmDeviceType, f as mapHmChannel, g as homematicAddonConfigSchema, h as buildConnectionFormSchema, i as registerTemperatureCap, j as string, k as createEvent, l as deriveHmEntitySpecs, m as homematicFacades, n as registerHumidityCap, o as decodeCover, p as mapHmDeviceChannels, r as registerPowerMeterCap, s as decodeLock, t as registerAmbientLightCap, u as coldMotionKeepingRise, v as toHomematicOptions, w as eventEmitterCapability, x as climateControlCapability, y as BaseDevice } from "./addon.mjs";
|
|
2
2
|
//#region src/homematic-device.ts
|
|
3
3
|
/**
|
|
4
4
|
* Persisted config every Homematic-backed device carries. `address` is
|
|
@@ -394,7 +394,7 @@ var HomematicDevice = class extends BaseDevice {
|
|
|
394
394
|
getStatus: async () => this.runtimeState.getCapState("motion") ?? COLD_MOTION,
|
|
395
395
|
isDetected: async () => (this.runtimeState.getCapState("motion") ?? COLD_MOTION).detected
|
|
396
396
|
});
|
|
397
|
-
this.runtimeState.setCapState("motion",
|
|
397
|
+
this.runtimeState.setCapState("motion", coldMotionKeepingRise(this.runtimeState.getCapState("motion")));
|
|
398
398
|
}
|
|
399
399
|
registerEventEmitterCap(keyChannels) {
|
|
400
400
|
this.eventTypes = keyEventVocabulary(keyChannels);
|
package/package.json
CHANGED