@camstack/addon-provider-homematic 1.2.158 → 1.2.159
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 +19 -0
- package/dist/addon.js +602 -16
- package/dist/addon.mjs +602 -16
- package/package.json +4 -2
package/dist/addon.js
CHANGED
|
@@ -8,7 +8,7 @@ let http = require("http");
|
|
|
8
8
|
let crypto$1 = require("crypto");
|
|
9
9
|
let fs_promises = require("fs/promises");
|
|
10
10
|
let path = require("path");
|
|
11
|
-
//#region ../types/dist/event-category-
|
|
11
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
12
12
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
13
13
|
EventCategory["SystemBoot"] = "system.boot";
|
|
14
14
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -334,6 +334,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
334
334
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
335
335
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
336
336
|
/**
|
|
337
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
338
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
339
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
340
|
+
*/
|
|
341
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
342
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
343
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
344
|
+
/**
|
|
337
345
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
338
346
|
* (a settings change via `setAgentInferenceDevices` /
|
|
339
347
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5576,7 +5584,7 @@ var ZodIssueCode = {
|
|
|
5576
5584
|
var ZodFirstPartyTypeKind;
|
|
5577
5585
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5578
5586
|
//#endregion
|
|
5579
|
-
//#region ../types/dist/sleep-
|
|
5587
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5580
5588
|
/**
|
|
5581
5589
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5582
5590
|
* window to float samples (D455).
|
|
@@ -8957,6 +8965,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8957
8965
|
"filesystem-browse",
|
|
8958
8966
|
"flood",
|
|
8959
8967
|
"gas",
|
|
8968
|
+
"group-commands",
|
|
8969
|
+
"group-status",
|
|
8960
8970
|
"heating-valve",
|
|
8961
8971
|
"humidifier",
|
|
8962
8972
|
"humidity-sensor",
|
|
@@ -9775,6 +9785,20 @@ Object.freeze({
|
|
|
9775
9785
|
"path": "detected",
|
|
9776
9786
|
"valueType": "boolean"
|
|
9777
9787
|
}],
|
|
9788
|
+
"group-status": [
|
|
9789
|
+
{
|
|
9790
|
+
"path": "included",
|
|
9791
|
+
"valueType": "number"
|
|
9792
|
+
},
|
|
9793
|
+
{
|
|
9794
|
+
"path": "excluded",
|
|
9795
|
+
"valueType": "number"
|
|
9796
|
+
},
|
|
9797
|
+
{
|
|
9798
|
+
"path": "total",
|
|
9799
|
+
"valueType": "number"
|
|
9800
|
+
}
|
|
9801
|
+
],
|
|
9778
9802
|
"heating-valve": [{
|
|
9779
9803
|
"path": "position",
|
|
9780
9804
|
"valueType": "number"
|
|
@@ -11116,7 +11140,7 @@ function errMsg(err) {
|
|
|
11116
11140
|
return String(err);
|
|
11117
11141
|
}
|
|
11118
11142
|
//#endregion
|
|
11119
|
-
//#region ../types/dist/composition-
|
|
11143
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
11120
11144
|
/**
|
|
11121
11145
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11122
11146
|
*
|
|
@@ -11871,15 +11895,74 @@ function validateExpressionSource(src) {
|
|
|
11871
11895
|
}
|
|
11872
11896
|
return null;
|
|
11873
11897
|
}
|
|
11874
|
-
/**
|
|
11875
|
-
|
|
11876
|
-
|
|
11877
|
-
|
|
11898
|
+
/**
|
|
11899
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11900
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11901
|
+
* `composition.ts` (D659).
|
|
11902
|
+
*/
|
|
11878
11903
|
var CompositionSourceRefSchema = object({
|
|
11879
11904
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11880
11905
|
addonId: string().min(1),
|
|
11881
11906
|
stableId: string().min(1)
|
|
11882
11907
|
});
|
|
11908
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11909
|
+
"temperature",
|
|
11910
|
+
"humidity",
|
|
11911
|
+
"pressure",
|
|
11912
|
+
"illuminance",
|
|
11913
|
+
"power",
|
|
11914
|
+
"energy",
|
|
11915
|
+
"battery",
|
|
11916
|
+
"numeric",
|
|
11917
|
+
"motion",
|
|
11918
|
+
"contact",
|
|
11919
|
+
"leak",
|
|
11920
|
+
"smoke",
|
|
11921
|
+
"occupancy",
|
|
11922
|
+
"binary",
|
|
11923
|
+
"switch",
|
|
11924
|
+
"light"
|
|
11925
|
+
];
|
|
11926
|
+
var NUMERIC_AGGREGATES = [
|
|
11927
|
+
"mean",
|
|
11928
|
+
"median",
|
|
11929
|
+
"min",
|
|
11930
|
+
"max",
|
|
11931
|
+
"sum"
|
|
11932
|
+
];
|
|
11933
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11934
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11935
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11936
|
+
var AGGREGATE_REDUCERS = [
|
|
11937
|
+
"mean",
|
|
11938
|
+
"median",
|
|
11939
|
+
"min",
|
|
11940
|
+
"max",
|
|
11941
|
+
"sum",
|
|
11942
|
+
"any",
|
|
11943
|
+
"all"
|
|
11944
|
+
];
|
|
11945
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11946
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11947
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11948
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11949
|
+
var HelperMemberSchema = object({
|
|
11950
|
+
source: CompositionSourceRefSchema,
|
|
11951
|
+
cap: string().min(1),
|
|
11952
|
+
fieldPath: string().min(1)
|
|
11953
|
+
});
|
|
11954
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11955
|
+
kind: literal("group"),
|
|
11956
|
+
templateId: GroupTemplateIdSchema,
|
|
11957
|
+
aggregate: AggregateReducerSchema,
|
|
11958
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11959
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11960
|
+
active: ActiveCriterionSchema.optional()
|
|
11961
|
+
})]);
|
|
11962
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11963
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11964
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11965
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11883
11966
|
/** One field of one capability of one source device. */
|
|
11884
11967
|
var CompositionFieldReadSchema = object({
|
|
11885
11968
|
source: CompositionSourceRefSchema,
|
|
@@ -11923,7 +12006,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11923
12006
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11924
12007
|
CompositionFromSourceSchema,
|
|
11925
12008
|
CompositionExpressionSourceSchema,
|
|
11926
|
-
CompositionCodeSourceSchema
|
|
12009
|
+
CompositionCodeSourceSchema,
|
|
12010
|
+
object({
|
|
12011
|
+
kind: literal("aggregate"),
|
|
12012
|
+
reducer: _enum([
|
|
12013
|
+
"mean",
|
|
12014
|
+
"median",
|
|
12015
|
+
"min",
|
|
12016
|
+
"max",
|
|
12017
|
+
"sum",
|
|
12018
|
+
"any",
|
|
12019
|
+
"all"
|
|
12020
|
+
]),
|
|
12021
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
12022
|
+
/** `value` is the reading; the others are the member counts. */
|
|
12023
|
+
publish: _enum([
|
|
12024
|
+
"value",
|
|
12025
|
+
"included",
|
|
12026
|
+
"excluded",
|
|
12027
|
+
"total"
|
|
12028
|
+
]),
|
|
12029
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
12030
|
+
empty: _enum([
|
|
12031
|
+
"null",
|
|
12032
|
+
"omit",
|
|
12033
|
+
"offline"
|
|
12034
|
+
])
|
|
12035
|
+
})
|
|
11927
12036
|
]);
|
|
11928
12037
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11929
12038
|
kind: literal("forward"),
|
|
@@ -11969,7 +12078,13 @@ var CompositionSchema = object({
|
|
|
11969
12078
|
kind: literal("existing"),
|
|
11970
12079
|
device: CompositionSourceRefSchema
|
|
11971
12080
|
})]),
|
|
11972
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
12081
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
12082
|
+
/**
|
|
12083
|
+
* Present when the block is a helper template. Absent on a free
|
|
12084
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
12085
|
+
* never the compiled features.
|
|
12086
|
+
*/
|
|
12087
|
+
helper: HelperSpecSchema.optional()
|
|
11973
12088
|
}).superRefine((composition, ctx) => {
|
|
11974
12089
|
const seen = /* @__PURE__ */ new Set();
|
|
11975
12090
|
composition.features.forEach((feature, index) => {
|
|
@@ -18227,7 +18342,10 @@ var CompositionProblemSchema = object({
|
|
|
18227
18342
|
"target-missing",
|
|
18228
18343
|
"target-unreadable",
|
|
18229
18344
|
"not-replaceable",
|
|
18230
|
-
"native-capability-replace"
|
|
18345
|
+
"native-capability-replace",
|
|
18346
|
+
"mixed-quantity",
|
|
18347
|
+
"helper-mismatch",
|
|
18348
|
+
"member-constraint"
|
|
18231
18349
|
]),
|
|
18232
18350
|
path: string(),
|
|
18233
18351
|
message: string()
|
|
@@ -18248,7 +18366,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
18248
18366
|
"null",
|
|
18249
18367
|
"offline",
|
|
18250
18368
|
"unknown",
|
|
18251
|
-
"release"
|
|
18369
|
+
"release",
|
|
18370
|
+
"omit"
|
|
18252
18371
|
]);
|
|
18253
18372
|
/**
|
|
18254
18373
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18462,6 +18581,275 @@ Object.freeze({
|
|
|
18462
18581
|
result: ["number", "null"]
|
|
18463
18582
|
}
|
|
18464
18583
|
});
|
|
18584
|
+
/**
|
|
18585
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18586
|
+
* Data, not a form default written into the block.
|
|
18587
|
+
*/
|
|
18588
|
+
var NOW = {
|
|
18589
|
+
fieldPath: "lastFetchedAt",
|
|
18590
|
+
expr: "now"
|
|
18591
|
+
};
|
|
18592
|
+
var CHANGED = {
|
|
18593
|
+
fieldPath: "lastChangedAt",
|
|
18594
|
+
expr: "now"
|
|
18595
|
+
};
|
|
18596
|
+
function numeric(input) {
|
|
18597
|
+
return {
|
|
18598
|
+
...input,
|
|
18599
|
+
family: "numeric",
|
|
18600
|
+
deviceType: DeviceType.Sensor,
|
|
18601
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18602
|
+
commandCaps: [],
|
|
18603
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18604
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18605
|
+
accept: [{
|
|
18606
|
+
cap: input.outputCap,
|
|
18607
|
+
fieldPath: input.outputField
|
|
18608
|
+
}]
|
|
18609
|
+
};
|
|
18610
|
+
}
|
|
18611
|
+
function binary(input) {
|
|
18612
|
+
return {
|
|
18613
|
+
...input,
|
|
18614
|
+
family: "binary",
|
|
18615
|
+
deviceType: DeviceType.Sensor,
|
|
18616
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18617
|
+
commandCaps: [],
|
|
18618
|
+
quantity: "none",
|
|
18619
|
+
baseUnit: void 0,
|
|
18620
|
+
aggregates: BINARY_AGGREGATES,
|
|
18621
|
+
empty: "offline"
|
|
18622
|
+
};
|
|
18623
|
+
}
|
|
18624
|
+
var GROUP_TEMPLATES = [
|
|
18625
|
+
numeric({
|
|
18626
|
+
id: "temperature",
|
|
18627
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18628
|
+
role: DeviceRole.TemperatureSensor,
|
|
18629
|
+
outputCap: "temperature-sensor",
|
|
18630
|
+
outputField: "celsius",
|
|
18631
|
+
quantity: "temperature",
|
|
18632
|
+
defaultAggregate: "mean",
|
|
18633
|
+
empty: "null",
|
|
18634
|
+
companions: [NOW]
|
|
18635
|
+
}),
|
|
18636
|
+
numeric({
|
|
18637
|
+
id: "humidity",
|
|
18638
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18639
|
+
role: DeviceRole.HumiditySensor,
|
|
18640
|
+
outputCap: "humidity-sensor",
|
|
18641
|
+
outputField: "percent",
|
|
18642
|
+
quantity: "humidity",
|
|
18643
|
+
defaultAggregate: "mean",
|
|
18644
|
+
empty: "null",
|
|
18645
|
+
companions: [NOW]
|
|
18646
|
+
}),
|
|
18647
|
+
numeric({
|
|
18648
|
+
id: "pressure",
|
|
18649
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18650
|
+
role: DeviceRole.PressureSensor,
|
|
18651
|
+
outputCap: "pressure-sensor",
|
|
18652
|
+
outputField: "hpa",
|
|
18653
|
+
quantity: "pressure",
|
|
18654
|
+
defaultAggregate: "mean",
|
|
18655
|
+
empty: "null",
|
|
18656
|
+
companions: [NOW]
|
|
18657
|
+
}),
|
|
18658
|
+
numeric({
|
|
18659
|
+
id: "illuminance",
|
|
18660
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18661
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18662
|
+
outputCap: "ambient-light-sensor",
|
|
18663
|
+
outputField: "lux",
|
|
18664
|
+
quantity: "illuminance",
|
|
18665
|
+
defaultAggregate: "mean",
|
|
18666
|
+
empty: "null",
|
|
18667
|
+
companions: [NOW]
|
|
18668
|
+
}),
|
|
18669
|
+
numeric({
|
|
18670
|
+
id: "power",
|
|
18671
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18672
|
+
role: DeviceRole.PowerSensor,
|
|
18673
|
+
outputCap: "power-meter",
|
|
18674
|
+
outputField: "watts",
|
|
18675
|
+
quantity: "power",
|
|
18676
|
+
defaultAggregate: "sum",
|
|
18677
|
+
empty: "omit",
|
|
18678
|
+
companions: [NOW]
|
|
18679
|
+
}),
|
|
18680
|
+
numeric({
|
|
18681
|
+
id: "energy",
|
|
18682
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18683
|
+
role: DeviceRole.EnergySensor,
|
|
18684
|
+
outputCap: "power-meter",
|
|
18685
|
+
outputField: "kwhTotal",
|
|
18686
|
+
quantity: "energy",
|
|
18687
|
+
defaultAggregate: "sum",
|
|
18688
|
+
empty: "omit",
|
|
18689
|
+
companions: [NOW]
|
|
18690
|
+
}),
|
|
18691
|
+
numeric({
|
|
18692
|
+
id: "battery",
|
|
18693
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18694
|
+
role: DeviceRole.BatterySensor,
|
|
18695
|
+
outputCap: "battery",
|
|
18696
|
+
outputField: "percentage",
|
|
18697
|
+
quantity: "percentage",
|
|
18698
|
+
defaultAggregate: "mean",
|
|
18699
|
+
empty: "null",
|
|
18700
|
+
companions: [
|
|
18701
|
+
{
|
|
18702
|
+
fieldPath: "charging",
|
|
18703
|
+
expr: "\"unknown\""
|
|
18704
|
+
},
|
|
18705
|
+
{
|
|
18706
|
+
fieldPath: "sleeping",
|
|
18707
|
+
expr: "false"
|
|
18708
|
+
},
|
|
18709
|
+
{
|
|
18710
|
+
fieldPath: "lastUpdated",
|
|
18711
|
+
expr: "now"
|
|
18712
|
+
}
|
|
18713
|
+
]
|
|
18714
|
+
}),
|
|
18715
|
+
numeric({
|
|
18716
|
+
id: "numeric",
|
|
18717
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18718
|
+
role: DeviceRole.NumericSensor,
|
|
18719
|
+
outputCap: "numeric-sensor",
|
|
18720
|
+
outputField: "value",
|
|
18721
|
+
quantity: "device",
|
|
18722
|
+
defaultAggregate: "mean",
|
|
18723
|
+
empty: "null",
|
|
18724
|
+
companions: [NOW]
|
|
18725
|
+
}),
|
|
18726
|
+
binary({
|
|
18727
|
+
id: "motion",
|
|
18728
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18729
|
+
role: DeviceRole.MotionSensor,
|
|
18730
|
+
outputCap: "motion",
|
|
18731
|
+
outputField: "detected",
|
|
18732
|
+
defaultAggregate: "any",
|
|
18733
|
+
accept: [{
|
|
18734
|
+
cap: "motion",
|
|
18735
|
+
fieldPath: "detected"
|
|
18736
|
+
}],
|
|
18737
|
+
companions: [{
|
|
18738
|
+
fieldPath: "lastDetectedAt",
|
|
18739
|
+
expr: "null"
|
|
18740
|
+
}, {
|
|
18741
|
+
fieldPath: "autoClearAfterMs",
|
|
18742
|
+
expr: "null"
|
|
18743
|
+
}]
|
|
18744
|
+
}),
|
|
18745
|
+
binary({
|
|
18746
|
+
id: "contact",
|
|
18747
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18748
|
+
role: DeviceRole.ContactSensor,
|
|
18749
|
+
outputCap: "contact",
|
|
18750
|
+
outputField: "entryOpen",
|
|
18751
|
+
defaultAggregate: "any",
|
|
18752
|
+
accept: [{
|
|
18753
|
+
cap: "contact",
|
|
18754
|
+
fieldPath: "entryOpen"
|
|
18755
|
+
}],
|
|
18756
|
+
companions: [CHANGED]
|
|
18757
|
+
}),
|
|
18758
|
+
binary({
|
|
18759
|
+
id: "leak",
|
|
18760
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18761
|
+
role: DeviceRole.LeakSensor,
|
|
18762
|
+
outputCap: "flood",
|
|
18763
|
+
outputField: "flooded",
|
|
18764
|
+
defaultAggregate: "any",
|
|
18765
|
+
accept: [{
|
|
18766
|
+
cap: "flood",
|
|
18767
|
+
fieldPath: "flooded"
|
|
18768
|
+
}],
|
|
18769
|
+
companions: [CHANGED]
|
|
18770
|
+
}),
|
|
18771
|
+
binary({
|
|
18772
|
+
id: "smoke",
|
|
18773
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18774
|
+
role: DeviceRole.SmokeSensor,
|
|
18775
|
+
outputCap: "smoke",
|
|
18776
|
+
outputField: "detected",
|
|
18777
|
+
defaultAggregate: "any",
|
|
18778
|
+
accept: [{
|
|
18779
|
+
cap: "smoke",
|
|
18780
|
+
fieldPath: "detected"
|
|
18781
|
+
}],
|
|
18782
|
+
companions: [CHANGED]
|
|
18783
|
+
}),
|
|
18784
|
+
binary({
|
|
18785
|
+
id: "occupancy",
|
|
18786
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18787
|
+
role: DeviceRole.BinarySensor,
|
|
18788
|
+
outputCap: "binary",
|
|
18789
|
+
outputField: "on",
|
|
18790
|
+
defaultAggregate: "any",
|
|
18791
|
+
accept: [{
|
|
18792
|
+
cap: "motion",
|
|
18793
|
+
fieldPath: "detected"
|
|
18794
|
+
}, {
|
|
18795
|
+
cap: "binary",
|
|
18796
|
+
fieldPath: "on"
|
|
18797
|
+
}],
|
|
18798
|
+
companions: [CHANGED]
|
|
18799
|
+
}),
|
|
18800
|
+
binary({
|
|
18801
|
+
id: "binary",
|
|
18802
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18803
|
+
role: DeviceRole.BinarySensor,
|
|
18804
|
+
outputCap: "binary",
|
|
18805
|
+
outputField: "on",
|
|
18806
|
+
defaultAggregate: "any",
|
|
18807
|
+
accept: [{
|
|
18808
|
+
cap: "binary",
|
|
18809
|
+
fieldPath: "on"
|
|
18810
|
+
}],
|
|
18811
|
+
companions: [CHANGED]
|
|
18812
|
+
}),
|
|
18813
|
+
actuator({
|
|
18814
|
+
id: "switch",
|
|
18815
|
+
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.",
|
|
18816
|
+
deviceType: DeviceType.Switch,
|
|
18817
|
+
outputCap: "switch",
|
|
18818
|
+
commandCaps: ["switch"]
|
|
18819
|
+
}),
|
|
18820
|
+
actuator({
|
|
18821
|
+
id: "light",
|
|
18822
|
+
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.",
|
|
18823
|
+
deviceType: DeviceType.Light,
|
|
18824
|
+
outputCap: "switch",
|
|
18825
|
+
commandCaps: [
|
|
18826
|
+
"switch",
|
|
18827
|
+
"brightness",
|
|
18828
|
+
"color"
|
|
18829
|
+
]
|
|
18830
|
+
})
|
|
18831
|
+
];
|
|
18832
|
+
function actuator(input) {
|
|
18833
|
+
return {
|
|
18834
|
+
...input,
|
|
18835
|
+
family: "actuator",
|
|
18836
|
+
role: void 0,
|
|
18837
|
+
memberDeviceType: input.deviceType,
|
|
18838
|
+
outputField: "on",
|
|
18839
|
+
quantity: "none",
|
|
18840
|
+
baseUnit: void 0,
|
|
18841
|
+
aggregates: BINARY_AGGREGATES,
|
|
18842
|
+
defaultAggregate: "any",
|
|
18843
|
+
empty: "offline",
|
|
18844
|
+
accept: [{
|
|
18845
|
+
cap: "switch",
|
|
18846
|
+
fieldPath: "on"
|
|
18847
|
+
}],
|
|
18848
|
+
companions: [CHANGED]
|
|
18849
|
+
};
|
|
18850
|
+
}
|
|
18851
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18852
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18465
18853
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18466
18854
|
/**
|
|
18467
18855
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -45468,6 +45856,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45468
45856
|
"detection-blind",
|
|
45469
45857
|
"motion-noisy",
|
|
45470
45858
|
"motion-calm",
|
|
45859
|
+
"package-llm-silent",
|
|
45860
|
+
"package-llm-answered",
|
|
45471
45861
|
"recording-stalled",
|
|
45472
45862
|
"recording-healthy",
|
|
45473
45863
|
"recording-degraded",
|
|
@@ -56559,6 +56949,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56559
56949
|
deprecated: string().optional(),
|
|
56560
56950
|
distTags: array(string()).readonly()
|
|
56561
56951
|
});
|
|
56952
|
+
/**
|
|
56953
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56954
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56955
|
+
* tarball failure — never an empty string standing in for either.
|
|
56956
|
+
*/
|
|
56957
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56958
|
+
object({
|
|
56959
|
+
status: literal("ok"),
|
|
56960
|
+
markdown: string()
|
|
56961
|
+
}),
|
|
56962
|
+
object({ status: literal("missing") }),
|
|
56963
|
+
object({
|
|
56964
|
+
status: literal("error"),
|
|
56965
|
+
message: string()
|
|
56966
|
+
})
|
|
56967
|
+
]);
|
|
56968
|
+
var PackageDocsSchema = object({
|
|
56969
|
+
name: string(),
|
|
56970
|
+
version: string(),
|
|
56971
|
+
readme: PackageDocBodySchema,
|
|
56972
|
+
changelog: PackageDocBodySchema
|
|
56973
|
+
});
|
|
56562
56974
|
var SearchResultSchema = object({
|
|
56563
56975
|
name: string(),
|
|
56564
56976
|
version: string(),
|
|
@@ -56777,7 +57189,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56777
57189
|
}), object({ success: literal(true) }), {
|
|
56778
57190
|
kind: "mutation",
|
|
56779
57191
|
auth: "admin"
|
|
56780
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57192
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
57193
|
+
name: string().min(1),
|
|
57194
|
+
version: string().min(1).optional()
|
|
57195
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56781
57196
|
kind: "mutation",
|
|
56782
57197
|
auth: "admin"
|
|
56783
57198
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -60096,6 +60511,88 @@ var gasCapability = {
|
|
|
60096
60511
|
* whether persisting is worth a SQLite commit. */
|
|
60097
60512
|
volatileStateFields: ["lastChangedAt"]
|
|
60098
60513
|
};
|
|
60514
|
+
var GroupCommandsSchema = object({
|
|
60515
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60516
|
+
results: array(object({
|
|
60517
|
+
deviceId: number().int().nonnegative(),
|
|
60518
|
+
cap: string().min(1),
|
|
60519
|
+
method: string().min(1),
|
|
60520
|
+
ok: boolean(),
|
|
60521
|
+
error: string().optional(),
|
|
60522
|
+
/** Ms epoch of the attempt. */
|
|
60523
|
+
at: number()
|
|
60524
|
+
})) });
|
|
60525
|
+
var groupCommandsCapability = {
|
|
60526
|
+
name: "group-commands",
|
|
60527
|
+
scope: "device",
|
|
60528
|
+
deviceNative: true,
|
|
60529
|
+
mode: "singleton",
|
|
60530
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60531
|
+
methods: {},
|
|
60532
|
+
status: {
|
|
60533
|
+
schema: GroupCommandsSchema,
|
|
60534
|
+
kind: "push"
|
|
60535
|
+
},
|
|
60536
|
+
runtimeState: GroupCommandsSchema,
|
|
60537
|
+
/**
|
|
60538
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60539
|
+
* failure would outlive the command that caused it.
|
|
60540
|
+
*
|
|
60541
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60542
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60543
|
+
*/
|
|
60544
|
+
durability: "session",
|
|
60545
|
+
history: "none"
|
|
60546
|
+
};
|
|
60547
|
+
/**
|
|
60548
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60549
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60550
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60551
|
+
* series that later statistics read is the output cap's own history block.
|
|
60552
|
+
*/
|
|
60553
|
+
var GroupStatusSchema = object({
|
|
60554
|
+
/** Members whose current value entered the aggregate. */
|
|
60555
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60556
|
+
precision: 0,
|
|
60557
|
+
label: "Reporting"
|
|
60558
|
+
})),
|
|
60559
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60560
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60561
|
+
precision: 0,
|
|
60562
|
+
label: "Excluded"
|
|
60563
|
+
})),
|
|
60564
|
+
/** `included` + `excluded`. */
|
|
60565
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60566
|
+
precision: 0,
|
|
60567
|
+
label: "Members"
|
|
60568
|
+
}))
|
|
60569
|
+
});
|
|
60570
|
+
var groupStatusCapability = {
|
|
60571
|
+
name: "group-status",
|
|
60572
|
+
scope: "device",
|
|
60573
|
+
deviceNative: true,
|
|
60574
|
+
mode: "singleton",
|
|
60575
|
+
deviceTypes: [
|
|
60576
|
+
DeviceType.Sensor,
|
|
60577
|
+
DeviceType.Switch,
|
|
60578
|
+
DeviceType.Light
|
|
60579
|
+
],
|
|
60580
|
+
methods: {},
|
|
60581
|
+
status: {
|
|
60582
|
+
schema: GroupStatusSchema,
|
|
60583
|
+
kind: "push"
|
|
60584
|
+
},
|
|
60585
|
+
runtimeState: GroupStatusSchema,
|
|
60586
|
+
/**
|
|
60587
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60588
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60589
|
+
*
|
|
60590
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60591
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60592
|
+
*/
|
|
60593
|
+
durability: "session",
|
|
60594
|
+
history: "none"
|
|
60595
|
+
};
|
|
60099
60596
|
var HeatingValveStatusSchema = object({
|
|
60100
60597
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
60101
60598
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -61865,12 +62362,18 @@ var motionCapability = {
|
|
|
61865
62362
|
methods: {
|
|
61866
62363
|
/**
|
|
61867
62364
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
61868
|
-
* for consumers that don't need the full status object
|
|
61869
|
-
*
|
|
61870
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
61871
|
-
* consumer.
|
|
62365
|
+
* for consumers that don't need the full status object. A composed
|
|
62366
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
61872
62367
|
*/
|
|
61873
62368
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
62369
|
+
/**
|
|
62370
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
62371
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
62372
|
+
*/
|
|
62373
|
+
composedMethods: { isDetected: {
|
|
62374
|
+
kind: "slice",
|
|
62375
|
+
field: "detected"
|
|
62376
|
+
} },
|
|
61874
62377
|
events: {
|
|
61875
62378
|
/**
|
|
61876
62379
|
* Fires every time the runner transitions a camera between
|
|
@@ -70061,6 +70564,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
70061
70564
|
featureProbe: featureProbeCapability,
|
|
70062
70565
|
flood: floodCapability,
|
|
70063
70566
|
gas: gasCapability,
|
|
70567
|
+
groupCommands: groupCommandsCapability,
|
|
70568
|
+
groupStatus: groupStatusCapability,
|
|
70064
70569
|
heatingValve: heatingValveCapability,
|
|
70065
70570
|
humidifier: humidifierCapability,
|
|
70066
70571
|
humiditySensor: humiditySensorCapability,
|
|
@@ -71437,6 +71942,13 @@ Object.freeze({
|
|
|
71437
71942
|
access: "view",
|
|
71438
71943
|
role: "admin"
|
|
71439
71944
|
},
|
|
71945
|
+
"addons.getPackageDocs": {
|
|
71946
|
+
capName: "addons",
|
|
71947
|
+
capScope: "system",
|
|
71948
|
+
addonId: null,
|
|
71949
|
+
access: "view",
|
|
71950
|
+
role: "admin"
|
|
71951
|
+
},
|
|
71440
71952
|
"addons.getVersions": {
|
|
71441
71953
|
capName: "addons",
|
|
71442
71954
|
capScope: "system",
|
|
@@ -74545,6 +75057,20 @@ Object.freeze({
|
|
|
74545
75057
|
access: "view",
|
|
74546
75058
|
role: "viewer"
|
|
74547
75059
|
},
|
|
75060
|
+
"groupCommands.getStatus": {
|
|
75061
|
+
capName: "group-commands",
|
|
75062
|
+
capScope: "device",
|
|
75063
|
+
addonId: null,
|
|
75064
|
+
access: "view",
|
|
75065
|
+
role: "viewer"
|
|
75066
|
+
},
|
|
75067
|
+
"groupStatus.getStatus": {
|
|
75068
|
+
capName: "group-status",
|
|
75069
|
+
capScope: "device",
|
|
75070
|
+
addonId: null,
|
|
75071
|
+
access: "view",
|
|
75072
|
+
role: "viewer"
|
|
75073
|
+
},
|
|
74548
75074
|
"heatingValve.getStatus": {
|
|
74549
75075
|
capName: "heating-valve",
|
|
74550
75076
|
capScope: "device",
|
|
@@ -84367,6 +84893,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
84367
84893
|
icon: "flame"
|
|
84368
84894
|
}]
|
|
84369
84895
|
},
|
|
84896
|
+
"group-commands": {
|
|
84897
|
+
scope: "device",
|
|
84898
|
+
noun: t("Group command", "Comando di gruppo")
|
|
84899
|
+
},
|
|
84900
|
+
"group-status": {
|
|
84901
|
+
scope: "device",
|
|
84902
|
+
noun: t("Group", "Gruppo"),
|
|
84903
|
+
state: [
|
|
84904
|
+
{
|
|
84905
|
+
kind: "numeric",
|
|
84906
|
+
field: "included",
|
|
84907
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
84908
|
+
label: t("Reporting", "Rispondono"),
|
|
84909
|
+
icon: "users"
|
|
84910
|
+
},
|
|
84911
|
+
{
|
|
84912
|
+
kind: "numeric",
|
|
84913
|
+
field: "excluded",
|
|
84914
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
84915
|
+
label: t("Excluded", "Esclusi"),
|
|
84916
|
+
icon: "users"
|
|
84917
|
+
},
|
|
84918
|
+
{
|
|
84919
|
+
kind: "numeric",
|
|
84920
|
+
field: "total",
|
|
84921
|
+
quantity: t("the member count", "il numero di membri"),
|
|
84922
|
+
label: t("Members", "Membri"),
|
|
84923
|
+
icon: "sigma"
|
|
84924
|
+
}
|
|
84925
|
+
]
|
|
84926
|
+
},
|
|
84370
84927
|
"humidity-sensor": {
|
|
84371
84928
|
scope: "device",
|
|
84372
84929
|
noun: t("Humidity", "Umidità"),
|
|
@@ -85832,6 +86389,16 @@ Object.freeze({
|
|
|
85832
86389
|
form: "single",
|
|
85833
86390
|
optional: false
|
|
85834
86391
|
}],
|
|
86392
|
+
"groupCommands.getStatus": [{
|
|
86393
|
+
name: "deviceId",
|
|
86394
|
+
form: "single",
|
|
86395
|
+
optional: false
|
|
86396
|
+
}],
|
|
86397
|
+
"groupStatus.getStatus": [{
|
|
86398
|
+
name: "deviceId",
|
|
86399
|
+
form: "single",
|
|
86400
|
+
optional: false
|
|
86401
|
+
}],
|
|
85835
86402
|
"heatingValve.getStatus": [{
|
|
85836
86403
|
name: "deviceId",
|
|
85837
86404
|
form: "single",
|
|
@@ -87816,6 +88383,8 @@ new Map(Object.entries({
|
|
|
87816
88383
|
"detection-blind": "device-events",
|
|
87817
88384
|
"motion-noisy": "device-events",
|
|
87818
88385
|
"motion-calm": "device-events",
|
|
88386
|
+
"package-llm-silent": "device-events",
|
|
88387
|
+
"package-llm-answered": "device-events",
|
|
87819
88388
|
"recording-stalled": "device-events",
|
|
87820
88389
|
"recording-healthy": "device-events",
|
|
87821
88390
|
"recording-degraded": "device-events",
|
|
@@ -87899,6 +88468,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
87899
88468
|
label: "Motion without a subject",
|
|
87900
88469
|
kinds: ["motion-noisy", "motion-calm"]
|
|
87901
88470
|
},
|
|
88471
|
+
{
|
|
88472
|
+
id: "package-llm",
|
|
88473
|
+
family: "device-events",
|
|
88474
|
+
label: "Package confirm",
|
|
88475
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
88476
|
+
},
|
|
87902
88477
|
{
|
|
87903
88478
|
id: "recording",
|
|
87904
88479
|
family: "device-events",
|
|
@@ -88080,6 +88655,8 @@ var DEVICE_EVENTS = [
|
|
|
88080
88655
|
"detection-blind",
|
|
88081
88656
|
"motion-noisy",
|
|
88082
88657
|
"motion-calm",
|
|
88658
|
+
"package-llm-silent",
|
|
88659
|
+
"package-llm-answered",
|
|
88083
88660
|
"recording-stalled",
|
|
88084
88661
|
"recording-healthy",
|
|
88085
88662
|
"recording-degraded",
|
|
@@ -88348,6 +88925,15 @@ new Map([
|
|
|
88348
88925
|
snapshotLabel: "Cameras with constant motion now",
|
|
88349
88926
|
snapshotSection: null
|
|
88350
88927
|
},
|
|
88928
|
+
{
|
|
88929
|
+
id: "package-llm-confirm",
|
|
88930
|
+
family: "device-events",
|
|
88931
|
+
label: "Package confirm (not answering / answering again)",
|
|
88932
|
+
bad: ["package-llm-silent"],
|
|
88933
|
+
recovery: ["package-llm-answered"],
|
|
88934
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
88935
|
+
snapshotSection: null
|
|
88936
|
+
},
|
|
88351
88937
|
{
|
|
88352
88938
|
id: "recording-health",
|
|
88353
88939
|
family: "device-events",
|