@camstack/addon-matter-broker 0.2.148 → 0.2.149
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/CHANGELOG.md +12 -0
- package/README.md +18 -0
- package/dist/addon.js +649 -16
- package/dist/addon.mjs +649 -16
- package/package.json +4 -2
package/dist/addon.js
CHANGED
|
@@ -13,7 +13,7 @@ let node_stream_promises = require("node:stream/promises");
|
|
|
13
13
|
let node_net = require("node:net");
|
|
14
14
|
let node_dgram = require("node:dgram");
|
|
15
15
|
node_dgram = require_esm.__toESM(node_dgram, 1);
|
|
16
|
-
//#region ../types/dist/event-category-
|
|
16
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
17
17
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
18
18
|
EventCategory["SystemBoot"] = "system.boot";
|
|
19
19
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -339,6 +339,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
339
339
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
340
340
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
341
341
|
/**
|
|
342
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
343
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
344
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
345
|
+
*/
|
|
346
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
347
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
348
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
349
|
+
/**
|
|
342
350
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
343
351
|
* (a settings change via `setAgentInferenceDevices` /
|
|
344
352
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5581,7 +5589,7 @@ var ZodIssueCode = {
|
|
|
5581
5589
|
var ZodFirstPartyTypeKind;
|
|
5582
5590
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5583
5591
|
//#endregion
|
|
5584
|
-
//#region ../types/dist/sleep-
|
|
5592
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5585
5593
|
/**
|
|
5586
5594
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5587
5595
|
* window to float samples (D455).
|
|
@@ -8362,6 +8370,53 @@ var READING_QUANTITIES = [
|
|
|
8362
8370
|
];
|
|
8363
8371
|
var ReadingQuantitySchema = _enum(READING_QUANTITIES);
|
|
8364
8372
|
new Set(READING_QUANTITIES);
|
|
8373
|
+
/**
|
|
8374
|
+
* Stored unit symbol for a quantity. `none` means the number is dimensionless
|
|
8375
|
+
* (or an index / ratio / count). `device` means the cap has no single unit.
|
|
8376
|
+
*/
|
|
8377
|
+
var QUANTITY_BASE = {
|
|
8378
|
+
temperature: "°C",
|
|
8379
|
+
pressure: "hPa",
|
|
8380
|
+
speed: "m/s",
|
|
8381
|
+
precipitation: "mm",
|
|
8382
|
+
"precipitation-rate": "mm/h",
|
|
8383
|
+
length: "m",
|
|
8384
|
+
area: "m²",
|
|
8385
|
+
illuminance: "lx",
|
|
8386
|
+
irradiance: "W/m²",
|
|
8387
|
+
power: "W",
|
|
8388
|
+
energy: "kWh",
|
|
8389
|
+
voltage: "V",
|
|
8390
|
+
current: "A",
|
|
8391
|
+
"apparent-power": "VA",
|
|
8392
|
+
humidity: "%",
|
|
8393
|
+
percentage: "%",
|
|
8394
|
+
"concentration-volume": "ppm",
|
|
8395
|
+
"concentration-mass": "µg/m³",
|
|
8396
|
+
"concentration-ppb": "ppb",
|
|
8397
|
+
volume: "L",
|
|
8398
|
+
duration: "s",
|
|
8399
|
+
"duration-ms": "ms",
|
|
8400
|
+
information: "B",
|
|
8401
|
+
"sound-level": "dBFS",
|
|
8402
|
+
"signal-level": "dBm",
|
|
8403
|
+
"colour-temperature": "mired",
|
|
8404
|
+
angle: "°",
|
|
8405
|
+
bitrate: "kbps",
|
|
8406
|
+
rate: "fps",
|
|
8407
|
+
mass: "kg",
|
|
8408
|
+
index: "none",
|
|
8409
|
+
ratio: "none",
|
|
8410
|
+
count: "none",
|
|
8411
|
+
none: "none",
|
|
8412
|
+
device: "device"
|
|
8413
|
+
};
|
|
8414
|
+
/** The stored unit, or `undefined` when the quantity has no unit symbol. */
|
|
8415
|
+
function baseUnitOf(quantity) {
|
|
8416
|
+
const symbol = QUANTITY_BASE[quantity];
|
|
8417
|
+
if (symbol === "none" || symbol === "device") return void 0;
|
|
8418
|
+
return symbol;
|
|
8419
|
+
}
|
|
8365
8420
|
function readingMeta(quantity, extras) {
|
|
8366
8421
|
return {
|
|
8367
8422
|
quantity,
|
|
@@ -8915,6 +8970,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8915
8970
|
"filesystem-browse",
|
|
8916
8971
|
"flood",
|
|
8917
8972
|
"gas",
|
|
8973
|
+
"group-commands",
|
|
8974
|
+
"group-status",
|
|
8918
8975
|
"heating-valve",
|
|
8919
8976
|
"humidifier",
|
|
8920
8977
|
"humidity-sensor",
|
|
@@ -9733,6 +9790,20 @@ Object.freeze({
|
|
|
9733
9790
|
"path": "detected",
|
|
9734
9791
|
"valueType": "boolean"
|
|
9735
9792
|
}],
|
|
9793
|
+
"group-status": [
|
|
9794
|
+
{
|
|
9795
|
+
"path": "included",
|
|
9796
|
+
"valueType": "number"
|
|
9797
|
+
},
|
|
9798
|
+
{
|
|
9799
|
+
"path": "excluded",
|
|
9800
|
+
"valueType": "number"
|
|
9801
|
+
},
|
|
9802
|
+
{
|
|
9803
|
+
"path": "total",
|
|
9804
|
+
"valueType": "number"
|
|
9805
|
+
}
|
|
9806
|
+
],
|
|
9736
9807
|
"heating-valve": [{
|
|
9737
9808
|
"path": "position",
|
|
9738
9809
|
"valueType": "number"
|
|
@@ -11074,7 +11145,7 @@ function errMsg(err) {
|
|
|
11074
11145
|
return String(err);
|
|
11075
11146
|
}
|
|
11076
11147
|
//#endregion
|
|
11077
|
-
//#region ../types/dist/composition-
|
|
11148
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
11078
11149
|
/**
|
|
11079
11150
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11080
11151
|
*
|
|
@@ -11829,15 +11900,74 @@ function validateExpressionSource(src) {
|
|
|
11829
11900
|
}
|
|
11830
11901
|
return null;
|
|
11831
11902
|
}
|
|
11832
|
-
/**
|
|
11833
|
-
|
|
11834
|
-
|
|
11835
|
-
|
|
11903
|
+
/**
|
|
11904
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11905
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11906
|
+
* `composition.ts` (D659).
|
|
11907
|
+
*/
|
|
11836
11908
|
var CompositionSourceRefSchema = object({
|
|
11837
11909
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11838
11910
|
addonId: string$2().min(1),
|
|
11839
11911
|
stableId: string$2().min(1)
|
|
11840
11912
|
});
|
|
11913
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11914
|
+
"temperature",
|
|
11915
|
+
"humidity",
|
|
11916
|
+
"pressure",
|
|
11917
|
+
"illuminance",
|
|
11918
|
+
"power",
|
|
11919
|
+
"energy",
|
|
11920
|
+
"battery",
|
|
11921
|
+
"numeric",
|
|
11922
|
+
"motion",
|
|
11923
|
+
"contact",
|
|
11924
|
+
"leak",
|
|
11925
|
+
"smoke",
|
|
11926
|
+
"occupancy",
|
|
11927
|
+
"binary",
|
|
11928
|
+
"switch",
|
|
11929
|
+
"light"
|
|
11930
|
+
];
|
|
11931
|
+
var NUMERIC_AGGREGATES = [
|
|
11932
|
+
"mean",
|
|
11933
|
+
"median",
|
|
11934
|
+
"min",
|
|
11935
|
+
"max",
|
|
11936
|
+
"sum"
|
|
11937
|
+
];
|
|
11938
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11939
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11940
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11941
|
+
var AGGREGATE_REDUCERS = [
|
|
11942
|
+
"mean",
|
|
11943
|
+
"median",
|
|
11944
|
+
"min",
|
|
11945
|
+
"max",
|
|
11946
|
+
"sum",
|
|
11947
|
+
"any",
|
|
11948
|
+
"all"
|
|
11949
|
+
];
|
|
11950
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11951
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11952
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11953
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11954
|
+
var HelperMemberSchema = object({
|
|
11955
|
+
source: CompositionSourceRefSchema,
|
|
11956
|
+
cap: string$2().min(1),
|
|
11957
|
+
fieldPath: string$2().min(1)
|
|
11958
|
+
});
|
|
11959
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11960
|
+
kind: literal("group"),
|
|
11961
|
+
templateId: GroupTemplateIdSchema,
|
|
11962
|
+
aggregate: AggregateReducerSchema,
|
|
11963
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11964
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11965
|
+
active: ActiveCriterionSchema.optional()
|
|
11966
|
+
})]);
|
|
11967
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11968
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11969
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11970
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11841
11971
|
/** One field of one capability of one source device. */
|
|
11842
11972
|
var CompositionFieldReadSchema = object({
|
|
11843
11973
|
source: CompositionSourceRefSchema,
|
|
@@ -11881,7 +12011,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11881
12011
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11882
12012
|
CompositionFromSourceSchema,
|
|
11883
12013
|
CompositionExpressionSourceSchema,
|
|
11884
|
-
CompositionCodeSourceSchema
|
|
12014
|
+
CompositionCodeSourceSchema,
|
|
12015
|
+
object({
|
|
12016
|
+
kind: literal("aggregate"),
|
|
12017
|
+
reducer: _enum([
|
|
12018
|
+
"mean",
|
|
12019
|
+
"median",
|
|
12020
|
+
"min",
|
|
12021
|
+
"max",
|
|
12022
|
+
"sum",
|
|
12023
|
+
"any",
|
|
12024
|
+
"all"
|
|
12025
|
+
]),
|
|
12026
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12027
|
+
/** `value` is the reading; the others are the member counts. */
|
|
12028
|
+
publish: _enum([
|
|
12029
|
+
"value",
|
|
12030
|
+
"included",
|
|
12031
|
+
"excluded",
|
|
12032
|
+
"total"
|
|
12033
|
+
]),
|
|
12034
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
12035
|
+
empty: _enum([
|
|
12036
|
+
"null",
|
|
12037
|
+
"omit",
|
|
12038
|
+
"offline"
|
|
12039
|
+
])
|
|
12040
|
+
})
|
|
11885
12041
|
]);
|
|
11886
12042
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11887
12043
|
kind: literal("forward"),
|
|
@@ -11927,7 +12083,13 @@ var CompositionSchema = object({
|
|
|
11927
12083
|
kind: literal("existing"),
|
|
11928
12084
|
device: CompositionSourceRefSchema
|
|
11929
12085
|
})]),
|
|
11930
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
12086
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
12087
|
+
/**
|
|
12088
|
+
* Present when the block is a helper template. Absent on a free
|
|
12089
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
12090
|
+
* never the compiled features.
|
|
12091
|
+
*/
|
|
12092
|
+
helper: HelperSpecSchema.optional()
|
|
11931
12093
|
}).superRefine((composition, ctx) => {
|
|
11932
12094
|
const seen = /* @__PURE__ */ new Set();
|
|
11933
12095
|
composition.features.forEach((feature, index) => {
|
|
@@ -18185,7 +18347,10 @@ var CompositionProblemSchema = object({
|
|
|
18185
18347
|
"target-missing",
|
|
18186
18348
|
"target-unreadable",
|
|
18187
18349
|
"not-replaceable",
|
|
18188
|
-
"native-capability-replace"
|
|
18350
|
+
"native-capability-replace",
|
|
18351
|
+
"mixed-quantity",
|
|
18352
|
+
"helper-mismatch",
|
|
18353
|
+
"member-constraint"
|
|
18189
18354
|
]),
|
|
18190
18355
|
path: string$2(),
|
|
18191
18356
|
message: string$2()
|
|
@@ -18206,7 +18371,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18206
18371
|
"null",
|
|
18207
18372
|
"offline",
|
|
18208
18373
|
"unknown",
|
|
18209
|
-
"release"
|
|
18374
|
+
"release",
|
|
18375
|
+
"omit"
|
|
18210
18376
|
]);
|
|
18211
18377
|
/**
|
|
18212
18378
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18420,6 +18586,275 @@ Object.freeze({
|
|
|
18420
18586
|
result: ["number", "null"]
|
|
18421
18587
|
}
|
|
18422
18588
|
});
|
|
18589
|
+
/**
|
|
18590
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18591
|
+
* Data, not a form default written into the block.
|
|
18592
|
+
*/
|
|
18593
|
+
var NOW = {
|
|
18594
|
+
fieldPath: "lastFetchedAt",
|
|
18595
|
+
expr: "now"
|
|
18596
|
+
};
|
|
18597
|
+
var CHANGED = {
|
|
18598
|
+
fieldPath: "lastChangedAt",
|
|
18599
|
+
expr: "now"
|
|
18600
|
+
};
|
|
18601
|
+
function numeric(input) {
|
|
18602
|
+
return {
|
|
18603
|
+
...input,
|
|
18604
|
+
family: "numeric",
|
|
18605
|
+
deviceType: DeviceType.Sensor,
|
|
18606
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18607
|
+
commandCaps: [],
|
|
18608
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18609
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18610
|
+
accept: [{
|
|
18611
|
+
cap: input.outputCap,
|
|
18612
|
+
fieldPath: input.outputField
|
|
18613
|
+
}]
|
|
18614
|
+
};
|
|
18615
|
+
}
|
|
18616
|
+
function binary(input) {
|
|
18617
|
+
return {
|
|
18618
|
+
...input,
|
|
18619
|
+
family: "binary",
|
|
18620
|
+
deviceType: DeviceType.Sensor,
|
|
18621
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18622
|
+
commandCaps: [],
|
|
18623
|
+
quantity: "none",
|
|
18624
|
+
baseUnit: void 0,
|
|
18625
|
+
aggregates: BINARY_AGGREGATES,
|
|
18626
|
+
empty: "offline"
|
|
18627
|
+
};
|
|
18628
|
+
}
|
|
18629
|
+
var GROUP_TEMPLATES = [
|
|
18630
|
+
numeric({
|
|
18631
|
+
id: "temperature",
|
|
18632
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18633
|
+
role: DeviceRole.TemperatureSensor,
|
|
18634
|
+
outputCap: "temperature-sensor",
|
|
18635
|
+
outputField: "celsius",
|
|
18636
|
+
quantity: "temperature",
|
|
18637
|
+
defaultAggregate: "mean",
|
|
18638
|
+
empty: "null",
|
|
18639
|
+
companions: [NOW]
|
|
18640
|
+
}),
|
|
18641
|
+
numeric({
|
|
18642
|
+
id: "humidity",
|
|
18643
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18644
|
+
role: DeviceRole.HumiditySensor,
|
|
18645
|
+
outputCap: "humidity-sensor",
|
|
18646
|
+
outputField: "percent",
|
|
18647
|
+
quantity: "humidity",
|
|
18648
|
+
defaultAggregate: "mean",
|
|
18649
|
+
empty: "null",
|
|
18650
|
+
companions: [NOW]
|
|
18651
|
+
}),
|
|
18652
|
+
numeric({
|
|
18653
|
+
id: "pressure",
|
|
18654
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18655
|
+
role: DeviceRole.PressureSensor,
|
|
18656
|
+
outputCap: "pressure-sensor",
|
|
18657
|
+
outputField: "hpa",
|
|
18658
|
+
quantity: "pressure",
|
|
18659
|
+
defaultAggregate: "mean",
|
|
18660
|
+
empty: "null",
|
|
18661
|
+
companions: [NOW]
|
|
18662
|
+
}),
|
|
18663
|
+
numeric({
|
|
18664
|
+
id: "illuminance",
|
|
18665
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18666
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18667
|
+
outputCap: "ambient-light-sensor",
|
|
18668
|
+
outputField: "lux",
|
|
18669
|
+
quantity: "illuminance",
|
|
18670
|
+
defaultAggregate: "mean",
|
|
18671
|
+
empty: "null",
|
|
18672
|
+
companions: [NOW]
|
|
18673
|
+
}),
|
|
18674
|
+
numeric({
|
|
18675
|
+
id: "power",
|
|
18676
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18677
|
+
role: DeviceRole.PowerSensor,
|
|
18678
|
+
outputCap: "power-meter",
|
|
18679
|
+
outputField: "watts",
|
|
18680
|
+
quantity: "power",
|
|
18681
|
+
defaultAggregate: "sum",
|
|
18682
|
+
empty: "omit",
|
|
18683
|
+
companions: [NOW]
|
|
18684
|
+
}),
|
|
18685
|
+
numeric({
|
|
18686
|
+
id: "energy",
|
|
18687
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18688
|
+
role: DeviceRole.EnergySensor,
|
|
18689
|
+
outputCap: "power-meter",
|
|
18690
|
+
outputField: "kwhTotal",
|
|
18691
|
+
quantity: "energy",
|
|
18692
|
+
defaultAggregate: "sum",
|
|
18693
|
+
empty: "omit",
|
|
18694
|
+
companions: [NOW]
|
|
18695
|
+
}),
|
|
18696
|
+
numeric({
|
|
18697
|
+
id: "battery",
|
|
18698
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18699
|
+
role: DeviceRole.BatterySensor,
|
|
18700
|
+
outputCap: "battery",
|
|
18701
|
+
outputField: "percentage",
|
|
18702
|
+
quantity: "percentage",
|
|
18703
|
+
defaultAggregate: "mean",
|
|
18704
|
+
empty: "null",
|
|
18705
|
+
companions: [
|
|
18706
|
+
{
|
|
18707
|
+
fieldPath: "charging",
|
|
18708
|
+
expr: "\"unknown\""
|
|
18709
|
+
},
|
|
18710
|
+
{
|
|
18711
|
+
fieldPath: "sleeping",
|
|
18712
|
+
expr: "false"
|
|
18713
|
+
},
|
|
18714
|
+
{
|
|
18715
|
+
fieldPath: "lastUpdated",
|
|
18716
|
+
expr: "now"
|
|
18717
|
+
}
|
|
18718
|
+
]
|
|
18719
|
+
}),
|
|
18720
|
+
numeric({
|
|
18721
|
+
id: "numeric",
|
|
18722
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18723
|
+
role: DeviceRole.NumericSensor,
|
|
18724
|
+
outputCap: "numeric-sensor",
|
|
18725
|
+
outputField: "value",
|
|
18726
|
+
quantity: "device",
|
|
18727
|
+
defaultAggregate: "mean",
|
|
18728
|
+
empty: "null",
|
|
18729
|
+
companions: [NOW]
|
|
18730
|
+
}),
|
|
18731
|
+
binary({
|
|
18732
|
+
id: "motion",
|
|
18733
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18734
|
+
role: DeviceRole.MotionSensor,
|
|
18735
|
+
outputCap: "motion",
|
|
18736
|
+
outputField: "detected",
|
|
18737
|
+
defaultAggregate: "any",
|
|
18738
|
+
accept: [{
|
|
18739
|
+
cap: "motion",
|
|
18740
|
+
fieldPath: "detected"
|
|
18741
|
+
}],
|
|
18742
|
+
companions: [{
|
|
18743
|
+
fieldPath: "lastDetectedAt",
|
|
18744
|
+
expr: "null"
|
|
18745
|
+
}, {
|
|
18746
|
+
fieldPath: "autoClearAfterMs",
|
|
18747
|
+
expr: "null"
|
|
18748
|
+
}]
|
|
18749
|
+
}),
|
|
18750
|
+
binary({
|
|
18751
|
+
id: "contact",
|
|
18752
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18753
|
+
role: DeviceRole.ContactSensor,
|
|
18754
|
+
outputCap: "contact",
|
|
18755
|
+
outputField: "entryOpen",
|
|
18756
|
+
defaultAggregate: "any",
|
|
18757
|
+
accept: [{
|
|
18758
|
+
cap: "contact",
|
|
18759
|
+
fieldPath: "entryOpen"
|
|
18760
|
+
}],
|
|
18761
|
+
companions: [CHANGED]
|
|
18762
|
+
}),
|
|
18763
|
+
binary({
|
|
18764
|
+
id: "leak",
|
|
18765
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18766
|
+
role: DeviceRole.LeakSensor,
|
|
18767
|
+
outputCap: "flood",
|
|
18768
|
+
outputField: "flooded",
|
|
18769
|
+
defaultAggregate: "any",
|
|
18770
|
+
accept: [{
|
|
18771
|
+
cap: "flood",
|
|
18772
|
+
fieldPath: "flooded"
|
|
18773
|
+
}],
|
|
18774
|
+
companions: [CHANGED]
|
|
18775
|
+
}),
|
|
18776
|
+
binary({
|
|
18777
|
+
id: "smoke",
|
|
18778
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18779
|
+
role: DeviceRole.SmokeSensor,
|
|
18780
|
+
outputCap: "smoke",
|
|
18781
|
+
outputField: "detected",
|
|
18782
|
+
defaultAggregate: "any",
|
|
18783
|
+
accept: [{
|
|
18784
|
+
cap: "smoke",
|
|
18785
|
+
fieldPath: "detected"
|
|
18786
|
+
}],
|
|
18787
|
+
companions: [CHANGED]
|
|
18788
|
+
}),
|
|
18789
|
+
binary({
|
|
18790
|
+
id: "occupancy",
|
|
18791
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18792
|
+
role: DeviceRole.BinarySensor,
|
|
18793
|
+
outputCap: "binary",
|
|
18794
|
+
outputField: "on",
|
|
18795
|
+
defaultAggregate: "any",
|
|
18796
|
+
accept: [{
|
|
18797
|
+
cap: "motion",
|
|
18798
|
+
fieldPath: "detected"
|
|
18799
|
+
}, {
|
|
18800
|
+
cap: "binary",
|
|
18801
|
+
fieldPath: "on"
|
|
18802
|
+
}],
|
|
18803
|
+
companions: [CHANGED]
|
|
18804
|
+
}),
|
|
18805
|
+
binary({
|
|
18806
|
+
id: "binary",
|
|
18807
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18808
|
+
role: DeviceRole.BinarySensor,
|
|
18809
|
+
outputCap: "binary",
|
|
18810
|
+
outputField: "on",
|
|
18811
|
+
defaultAggregate: "any",
|
|
18812
|
+
accept: [{
|
|
18813
|
+
cap: "binary",
|
|
18814
|
+
fieldPath: "on"
|
|
18815
|
+
}],
|
|
18816
|
+
companions: [CHANGED]
|
|
18817
|
+
}),
|
|
18818
|
+
actuator({
|
|
18819
|
+
id: "switch",
|
|
18820
|
+
summary: "On when at least one switch is on, or when all of them are. Offline and unknown members are left out of that decision, never read as off, and still receive the command.",
|
|
18821
|
+
deviceType: DeviceType.Switch,
|
|
18822
|
+
outputCap: "switch",
|
|
18823
|
+
commandCaps: ["switch"]
|
|
18824
|
+
}),
|
|
18825
|
+
actuator({
|
|
18826
|
+
id: "light",
|
|
18827
|
+
summary: "On when at least one light is on, or when all of them are. Brightness and colour are offered only when every member has them. A command is not sent to a member that lacks it.",
|
|
18828
|
+
deviceType: DeviceType.Light,
|
|
18829
|
+
outputCap: "switch",
|
|
18830
|
+
commandCaps: [
|
|
18831
|
+
"switch",
|
|
18832
|
+
"brightness",
|
|
18833
|
+
"color"
|
|
18834
|
+
]
|
|
18835
|
+
})
|
|
18836
|
+
];
|
|
18837
|
+
function actuator(input) {
|
|
18838
|
+
return {
|
|
18839
|
+
...input,
|
|
18840
|
+
family: "actuator",
|
|
18841
|
+
role: void 0,
|
|
18842
|
+
memberDeviceType: input.deviceType,
|
|
18843
|
+
outputField: "on",
|
|
18844
|
+
quantity: "none",
|
|
18845
|
+
baseUnit: void 0,
|
|
18846
|
+
aggregates: BINARY_AGGREGATES,
|
|
18847
|
+
defaultAggregate: "any",
|
|
18848
|
+
empty: "offline",
|
|
18849
|
+
accept: [{
|
|
18850
|
+
cap: "switch",
|
|
18851
|
+
fieldPath: "on"
|
|
18852
|
+
}],
|
|
18853
|
+
companions: [CHANGED]
|
|
18854
|
+
};
|
|
18855
|
+
}
|
|
18856
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18857
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18423
18858
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18424
18859
|
/**
|
|
18425
18860
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -45239,6 +45674,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45239
45674
|
"detection-blind",
|
|
45240
45675
|
"motion-noisy",
|
|
45241
45676
|
"motion-calm",
|
|
45677
|
+
"package-llm-silent",
|
|
45678
|
+
"package-llm-answered",
|
|
45242
45679
|
"recording-stalled",
|
|
45243
45680
|
"recording-healthy",
|
|
45244
45681
|
"recording-degraded",
|
|
@@ -56330,6 +56767,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56330
56767
|
deprecated: string$2().optional(),
|
|
56331
56768
|
distTags: array(string$2()).readonly()
|
|
56332
56769
|
});
|
|
56770
|
+
/**
|
|
56771
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56772
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56773
|
+
* tarball failure — never an empty string standing in for either.
|
|
56774
|
+
*/
|
|
56775
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56776
|
+
object({
|
|
56777
|
+
status: literal("ok"),
|
|
56778
|
+
markdown: string$2()
|
|
56779
|
+
}),
|
|
56780
|
+
object({ status: literal("missing") }),
|
|
56781
|
+
object({
|
|
56782
|
+
status: literal("error"),
|
|
56783
|
+
message: string$2()
|
|
56784
|
+
})
|
|
56785
|
+
]);
|
|
56786
|
+
var PackageDocsSchema = object({
|
|
56787
|
+
name: string$2(),
|
|
56788
|
+
version: string$2(),
|
|
56789
|
+
readme: PackageDocBodySchema,
|
|
56790
|
+
changelog: PackageDocBodySchema
|
|
56791
|
+
});
|
|
56333
56792
|
var SearchResultSchema = object({
|
|
56334
56793
|
name: string$2(),
|
|
56335
56794
|
version: string$2(),
|
|
@@ -56548,7 +57007,10 @@ method(object({ nodeId: string$2().optional() }).optional(), array(AddonListItem
|
|
|
56548
57007
|
}), object({ success: literal(true) }), {
|
|
56549
57008
|
kind: "mutation",
|
|
56550
57009
|
auth: "admin"
|
|
56551
|
-
}), method(object({ name: string$2() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57010
|
+
}), method(object({ name: string$2() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57011
|
+
name: string$2().min(1),
|
|
57012
|
+
version: string$2().min(1).optional()
|
|
57013
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string$2() }), RestartAddonResultSchema, {
|
|
56552
57014
|
kind: "mutation",
|
|
56553
57015
|
auth: "admin"
|
|
56554
57016
|
}), method(object({ packageName: string$2() }), object({ success: literal(true) }), {
|
|
@@ -59884,6 +60346,88 @@ var gasCapability = {
|
|
|
59884
60346
|
* whether persisting is worth a SQLite commit. */
|
|
59885
60347
|
volatileStateFields: ["lastChangedAt"]
|
|
59886
60348
|
};
|
|
60349
|
+
var GroupCommandsSchema = object({
|
|
60350
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60351
|
+
results: array(object({
|
|
60352
|
+
deviceId: number().int().nonnegative(),
|
|
60353
|
+
cap: string$2().min(1),
|
|
60354
|
+
method: string$2().min(1),
|
|
60355
|
+
ok: boolean(),
|
|
60356
|
+
error: string$2().optional(),
|
|
60357
|
+
/** Ms epoch of the attempt. */
|
|
60358
|
+
at: number()
|
|
60359
|
+
})) });
|
|
60360
|
+
var groupCommandsCapability = {
|
|
60361
|
+
name: "group-commands",
|
|
60362
|
+
scope: "device",
|
|
60363
|
+
deviceNative: true,
|
|
60364
|
+
mode: "singleton",
|
|
60365
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60366
|
+
methods: {},
|
|
60367
|
+
status: {
|
|
60368
|
+
schema: GroupCommandsSchema,
|
|
60369
|
+
kind: "push"
|
|
60370
|
+
},
|
|
60371
|
+
runtimeState: GroupCommandsSchema,
|
|
60372
|
+
/**
|
|
60373
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60374
|
+
* failure would outlive the command that caused it.
|
|
60375
|
+
*
|
|
60376
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60377
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60378
|
+
*/
|
|
60379
|
+
durability: "session",
|
|
60380
|
+
history: "none"
|
|
60381
|
+
};
|
|
60382
|
+
/**
|
|
60383
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60384
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60385
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60386
|
+
* series that later statistics read is the output cap's own history block.
|
|
60387
|
+
*/
|
|
60388
|
+
var GroupStatusSchema = object({
|
|
60389
|
+
/** Members whose current value entered the aggregate. */
|
|
60390
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60391
|
+
precision: 0,
|
|
60392
|
+
label: "Reporting"
|
|
60393
|
+
})),
|
|
60394
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60395
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60396
|
+
precision: 0,
|
|
60397
|
+
label: "Excluded"
|
|
60398
|
+
})),
|
|
60399
|
+
/** `included` + `excluded`. */
|
|
60400
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60401
|
+
precision: 0,
|
|
60402
|
+
label: "Members"
|
|
60403
|
+
}))
|
|
60404
|
+
});
|
|
60405
|
+
var groupStatusCapability = {
|
|
60406
|
+
name: "group-status",
|
|
60407
|
+
scope: "device",
|
|
60408
|
+
deviceNative: true,
|
|
60409
|
+
mode: "singleton",
|
|
60410
|
+
deviceTypes: [
|
|
60411
|
+
DeviceType.Sensor,
|
|
60412
|
+
DeviceType.Switch,
|
|
60413
|
+
DeviceType.Light
|
|
60414
|
+
],
|
|
60415
|
+
methods: {},
|
|
60416
|
+
status: {
|
|
60417
|
+
schema: GroupStatusSchema,
|
|
60418
|
+
kind: "push"
|
|
60419
|
+
},
|
|
60420
|
+
runtimeState: GroupStatusSchema,
|
|
60421
|
+
/**
|
|
60422
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60423
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60424
|
+
*
|
|
60425
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60426
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60427
|
+
*/
|
|
60428
|
+
durability: "session",
|
|
60429
|
+
history: "none"
|
|
60430
|
+
};
|
|
59887
60431
|
var HeatingValveStatusSchema = object({
|
|
59888
60432
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
59889
60433
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -61653,12 +62197,18 @@ var motionCapability = {
|
|
|
61653
62197
|
methods: {
|
|
61654
62198
|
/**
|
|
61655
62199
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
61656
|
-
* for consumers that don't need the full status object
|
|
61657
|
-
*
|
|
61658
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
61659
|
-
* consumer.
|
|
62200
|
+
* for consumers that don't need the full status object. A composed
|
|
62201
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
61660
62202
|
*/
|
|
61661
62203
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
62204
|
+
/**
|
|
62205
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
62206
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
62207
|
+
*/
|
|
62208
|
+
composedMethods: { isDetected: {
|
|
62209
|
+
kind: "slice",
|
|
62210
|
+
field: "detected"
|
|
62211
|
+
} },
|
|
61662
62212
|
events: {
|
|
61663
62213
|
/**
|
|
61664
62214
|
* Fires every time the runner transitions a camera between
|
|
@@ -69466,6 +70016,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
69466
70016
|
featureProbe: featureProbeCapability,
|
|
69467
70017
|
flood: floodCapability,
|
|
69468
70018
|
gas: gasCapability,
|
|
70019
|
+
groupCommands: groupCommandsCapability,
|
|
70020
|
+
groupStatus: groupStatusCapability,
|
|
69469
70021
|
heatingValve: heatingValveCapability,
|
|
69470
70022
|
humidifier: humidifierCapability,
|
|
69471
70023
|
humiditySensor: humiditySensorCapability,
|
|
@@ -70842,6 +71394,13 @@ Object.freeze({
|
|
|
70842
71394
|
access: "view",
|
|
70843
71395
|
role: "admin"
|
|
70844
71396
|
},
|
|
71397
|
+
"addons.getPackageDocs": {
|
|
71398
|
+
capName: "addons",
|
|
71399
|
+
capScope: "system",
|
|
71400
|
+
addonId: null,
|
|
71401
|
+
access: "view",
|
|
71402
|
+
role: "admin"
|
|
71403
|
+
},
|
|
70845
71404
|
"addons.getVersions": {
|
|
70846
71405
|
capName: "addons",
|
|
70847
71406
|
capScope: "system",
|
|
@@ -73950,6 +74509,20 @@ Object.freeze({
|
|
|
73950
74509
|
access: "view",
|
|
73951
74510
|
role: "viewer"
|
|
73952
74511
|
},
|
|
74512
|
+
"groupCommands.getStatus": {
|
|
74513
|
+
capName: "group-commands",
|
|
74514
|
+
capScope: "device",
|
|
74515
|
+
addonId: null,
|
|
74516
|
+
access: "view",
|
|
74517
|
+
role: "viewer"
|
|
74518
|
+
},
|
|
74519
|
+
"groupStatus.getStatus": {
|
|
74520
|
+
capName: "group-status",
|
|
74521
|
+
capScope: "device",
|
|
74522
|
+
addonId: null,
|
|
74523
|
+
access: "view",
|
|
74524
|
+
role: "viewer"
|
|
74525
|
+
},
|
|
73953
74526
|
"heatingValve.getStatus": {
|
|
73954
74527
|
capName: "heating-valve",
|
|
73955
74528
|
capScope: "device",
|
|
@@ -83772,6 +84345,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83772
84345
|
icon: "flame"
|
|
83773
84346
|
}]
|
|
83774
84347
|
},
|
|
84348
|
+
"group-commands": {
|
|
84349
|
+
scope: "device",
|
|
84350
|
+
noun: t("Group command", "Comando di gruppo")
|
|
84351
|
+
},
|
|
84352
|
+
"group-status": {
|
|
84353
|
+
scope: "device",
|
|
84354
|
+
noun: t("Group", "Gruppo"),
|
|
84355
|
+
state: [
|
|
84356
|
+
{
|
|
84357
|
+
kind: "numeric",
|
|
84358
|
+
field: "included",
|
|
84359
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
84360
|
+
label: t("Reporting", "Rispondono"),
|
|
84361
|
+
icon: "users"
|
|
84362
|
+
},
|
|
84363
|
+
{
|
|
84364
|
+
kind: "numeric",
|
|
84365
|
+
field: "excluded",
|
|
84366
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
84367
|
+
label: t("Excluded", "Esclusi"),
|
|
84368
|
+
icon: "users"
|
|
84369
|
+
},
|
|
84370
|
+
{
|
|
84371
|
+
kind: "numeric",
|
|
84372
|
+
field: "total",
|
|
84373
|
+
quantity: t("the member count", "il numero di membri"),
|
|
84374
|
+
label: t("Members", "Membri"),
|
|
84375
|
+
icon: "sigma"
|
|
84376
|
+
}
|
|
84377
|
+
]
|
|
84378
|
+
},
|
|
83775
84379
|
"humidity-sensor": {
|
|
83776
84380
|
scope: "device",
|
|
83777
84381
|
noun: t("Humidity", "Umidità"),
|
|
@@ -85237,6 +85841,16 @@ Object.freeze({
|
|
|
85237
85841
|
form: "single",
|
|
85238
85842
|
optional: false
|
|
85239
85843
|
}],
|
|
85844
|
+
"groupCommands.getStatus": [{
|
|
85845
|
+
name: "deviceId",
|
|
85846
|
+
form: "single",
|
|
85847
|
+
optional: false
|
|
85848
|
+
}],
|
|
85849
|
+
"groupStatus.getStatus": [{
|
|
85850
|
+
name: "deviceId",
|
|
85851
|
+
form: "single",
|
|
85852
|
+
optional: false
|
|
85853
|
+
}],
|
|
85240
85854
|
"heatingValve.getStatus": [{
|
|
85241
85855
|
name: "deviceId",
|
|
85242
85856
|
form: "single",
|
|
@@ -87221,6 +87835,8 @@ new Map(Object.entries({
|
|
|
87221
87835
|
"detection-blind": "device-events",
|
|
87222
87836
|
"motion-noisy": "device-events",
|
|
87223
87837
|
"motion-calm": "device-events",
|
|
87838
|
+
"package-llm-silent": "device-events",
|
|
87839
|
+
"package-llm-answered": "device-events",
|
|
87224
87840
|
"recording-stalled": "device-events",
|
|
87225
87841
|
"recording-healthy": "device-events",
|
|
87226
87842
|
"recording-degraded": "device-events",
|
|
@@ -87304,6 +87920,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
87304
87920
|
label: "Motion without a subject",
|
|
87305
87921
|
kinds: ["motion-noisy", "motion-calm"]
|
|
87306
87922
|
},
|
|
87923
|
+
{
|
|
87924
|
+
id: "package-llm",
|
|
87925
|
+
family: "device-events",
|
|
87926
|
+
label: "Package confirm",
|
|
87927
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
87928
|
+
},
|
|
87307
87929
|
{
|
|
87308
87930
|
id: "recording",
|
|
87309
87931
|
family: "device-events",
|
|
@@ -87485,6 +88107,8 @@ var DEVICE_EVENTS = [
|
|
|
87485
88107
|
"detection-blind",
|
|
87486
88108
|
"motion-noisy",
|
|
87487
88109
|
"motion-calm",
|
|
88110
|
+
"package-llm-silent",
|
|
88111
|
+
"package-llm-answered",
|
|
87488
88112
|
"recording-stalled",
|
|
87489
88113
|
"recording-healthy",
|
|
87490
88114
|
"recording-degraded",
|
|
@@ -87753,6 +88377,15 @@ new Map([
|
|
|
87753
88377
|
snapshotLabel: "Cameras with constant motion now",
|
|
87754
88378
|
snapshotSection: null
|
|
87755
88379
|
},
|
|
88380
|
+
{
|
|
88381
|
+
id: "package-llm-confirm",
|
|
88382
|
+
family: "device-events",
|
|
88383
|
+
label: "Package confirm (not answering / answering again)",
|
|
88384
|
+
bad: ["package-llm-silent"],
|
|
88385
|
+
recovery: ["package-llm-answered"],
|
|
88386
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
88387
|
+
snapshotSection: null
|
|
88388
|
+
},
|
|
87756
88389
|
{
|
|
87757
88390
|
id: "recording-health",
|
|
87758
88391
|
family: "device-events",
|