@camstack/addon-provider-ecowitt 0.2.147 → 0.2.148
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 +602 -16
- package/dist/addon.mjs +602 -16
- package/package.json +4 -2
package/dist/addon.js
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
let http = require("http");
|
|
3
3
|
let events = require("events");
|
|
4
4
|
let dgram = require("dgram");
|
|
5
|
-
//#region ../types/dist/event-category-
|
|
5
|
+
//#region ../types/dist/event-category-CT-hz5Rb.mjs
|
|
6
6
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
7
7
|
EventCategory["SystemBoot"] = "system.boot";
|
|
8
8
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -328,6 +328,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
328
328
|
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
329
329
|
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
330
330
|
/**
|
|
331
|
+
* A camera's package LLM confirm has failed closed three times in a row
|
|
332
|
+
* (D931, 2026-10-26). One edge per camera until
|
|
333
|
+
* {@link PipelinePackageLlmAnswered}.
|
|
334
|
+
*/
|
|
335
|
+
EventCategory["PipelinePackageLlmSilent"] = "pipeline.package-llm-silent";
|
|
336
|
+
/** The recovery edge of {@link PipelinePackageLlmSilent}: a confirm returned yes or no. */
|
|
337
|
+
EventCategory["PipelinePackageLlmAnswered"] = "pipeline.package-llm-answered";
|
|
338
|
+
/**
|
|
331
339
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
332
340
|
* (a settings change via `setAgentInferenceDevices` /
|
|
333
341
|
* `setCameraStepToggle` / `setCameraStepSettings`). Orchestrator
|
|
@@ -5437,7 +5445,7 @@ var ZodIssueCode$1 = {
|
|
|
5437
5445
|
var ZodFirstPartyTypeKind$1;
|
|
5438
5446
|
ZodFirstPartyTypeKind$1 || (ZodFirstPartyTypeKind$1 = {});
|
|
5439
5447
|
//#endregion
|
|
5440
|
-
//#region ../types/dist/sleep-
|
|
5448
|
+
//#region ../types/dist/sleep-bykKrTgu.mjs
|
|
5441
5449
|
/**
|
|
5442
5450
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5443
5451
|
* window to float samples (D455).
|
|
@@ -8630,6 +8638,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
8630
8638
|
"filesystem-browse",
|
|
8631
8639
|
"flood",
|
|
8632
8640
|
"gas",
|
|
8641
|
+
"group-commands",
|
|
8642
|
+
"group-status",
|
|
8633
8643
|
"heating-valve",
|
|
8634
8644
|
"humidifier",
|
|
8635
8645
|
"humidity-sensor",
|
|
@@ -9448,6 +9458,20 @@ Object.freeze({
|
|
|
9448
9458
|
"path": "detected",
|
|
9449
9459
|
"valueType": "boolean"
|
|
9450
9460
|
}],
|
|
9461
|
+
"group-status": [
|
|
9462
|
+
{
|
|
9463
|
+
"path": "included",
|
|
9464
|
+
"valueType": "number"
|
|
9465
|
+
},
|
|
9466
|
+
{
|
|
9467
|
+
"path": "excluded",
|
|
9468
|
+
"valueType": "number"
|
|
9469
|
+
},
|
|
9470
|
+
{
|
|
9471
|
+
"path": "total",
|
|
9472
|
+
"valueType": "number"
|
|
9473
|
+
}
|
|
9474
|
+
],
|
|
9451
9475
|
"heating-valve": [{
|
|
9452
9476
|
"path": "position",
|
|
9453
9477
|
"valueType": "number"
|
|
@@ -10803,7 +10827,7 @@ function errMsg(err) {
|
|
|
10803
10827
|
return String(err);
|
|
10804
10828
|
}
|
|
10805
10829
|
//#endregion
|
|
10806
|
-
//#region ../types/dist/composition-
|
|
10830
|
+
//#region ../types/dist/composition-OhpuespA.mjs
|
|
10807
10831
|
/**
|
|
10808
10832
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10809
10833
|
*
|
|
@@ -11558,15 +11582,74 @@ function validateExpressionSource(src) {
|
|
|
11558
11582
|
}
|
|
11559
11583
|
return null;
|
|
11560
11584
|
}
|
|
11561
|
-
/**
|
|
11562
|
-
|
|
11563
|
-
|
|
11564
|
-
|
|
11585
|
+
/**
|
|
11586
|
+
* A composition source identity: `(addonId, stableId)`, never a numeric device
|
|
11587
|
+
* id. Split out so helper schemas can name it without a cycle through
|
|
11588
|
+
* `composition.ts` (D659).
|
|
11589
|
+
*/
|
|
11565
11590
|
var CompositionSourceRefSchema = object({
|
|
11566
11591
|
/** The owning addon; `stableId` is unique only within it. */
|
|
11567
11592
|
addonId: string().min(1),
|
|
11568
11593
|
stableId: string().min(1)
|
|
11569
11594
|
});
|
|
11595
|
+
var GROUP_TEMPLATE_IDS = [
|
|
11596
|
+
"temperature",
|
|
11597
|
+
"humidity",
|
|
11598
|
+
"pressure",
|
|
11599
|
+
"illuminance",
|
|
11600
|
+
"power",
|
|
11601
|
+
"energy",
|
|
11602
|
+
"battery",
|
|
11603
|
+
"numeric",
|
|
11604
|
+
"motion",
|
|
11605
|
+
"contact",
|
|
11606
|
+
"leak",
|
|
11607
|
+
"smoke",
|
|
11608
|
+
"occupancy",
|
|
11609
|
+
"binary",
|
|
11610
|
+
"switch",
|
|
11611
|
+
"light"
|
|
11612
|
+
];
|
|
11613
|
+
var NUMERIC_AGGREGATES = [
|
|
11614
|
+
"mean",
|
|
11615
|
+
"median",
|
|
11616
|
+
"min",
|
|
11617
|
+
"max",
|
|
11618
|
+
"sum"
|
|
11619
|
+
];
|
|
11620
|
+
var BINARY_AGGREGATES = ["any", "all"];
|
|
11621
|
+
/** How an actuator group decides it is on. Unknown members never count as off. */
|
|
11622
|
+
var ACTIVE_CRITERIA = ["at-least-one", "all"];
|
|
11623
|
+
var AGGREGATE_REDUCERS = [
|
|
11624
|
+
"mean",
|
|
11625
|
+
"median",
|
|
11626
|
+
"min",
|
|
11627
|
+
"max",
|
|
11628
|
+
"sum",
|
|
11629
|
+
"any",
|
|
11630
|
+
"all"
|
|
11631
|
+
];
|
|
11632
|
+
var GroupTemplateIdSchema = _enum(GROUP_TEMPLATE_IDS);
|
|
11633
|
+
var AggregateReducerSchema = _enum(AGGREGATE_REDUCERS);
|
|
11634
|
+
var ActiveCriterionSchema = _enum(ACTIVE_CRITERIA);
|
|
11635
|
+
/** One member. The field is stored so occupancy can name motion or binary. */
|
|
11636
|
+
var HelperMemberSchema = object({
|
|
11637
|
+
source: CompositionSourceRefSchema,
|
|
11638
|
+
cap: string().min(1),
|
|
11639
|
+
fieldPath: string().min(1)
|
|
11640
|
+
});
|
|
11641
|
+
var HelperSpecSchema = discriminatedUnion("kind", [object({
|
|
11642
|
+
kind: literal("group"),
|
|
11643
|
+
templateId: GroupTemplateIdSchema,
|
|
11644
|
+
aggregate: AggregateReducerSchema,
|
|
11645
|
+
members: array(HelperMemberSchema).min(1).max(64),
|
|
11646
|
+
/** Actuator groups only. Readings leave this unset. */
|
|
11647
|
+
active: ActiveCriterionSchema.optional()
|
|
11648
|
+
})]);
|
|
11649
|
+
/** A composed device's stableId is this prefix plus the block id. */
|
|
11650
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
11651
|
+
/** Longest snippet a `code` source may carry (slice 4). */
|
|
11652
|
+
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
11570
11653
|
/** One field of one capability of one source device. */
|
|
11571
11654
|
var CompositionFieldReadSchema = object({
|
|
11572
11655
|
source: CompositionSourceRefSchema,
|
|
@@ -11610,7 +11693,33 @@ var CompositionCodeSourceSchema = object({
|
|
|
11610
11693
|
var CompositionFieldSourceSchema = discriminatedUnion("kind", [
|
|
11611
11694
|
CompositionFromSourceSchema,
|
|
11612
11695
|
CompositionExpressionSourceSchema,
|
|
11613
|
-
CompositionCodeSourceSchema
|
|
11696
|
+
CompositionCodeSourceSchema,
|
|
11697
|
+
object({
|
|
11698
|
+
kind: literal("aggregate"),
|
|
11699
|
+
reducer: _enum([
|
|
11700
|
+
"mean",
|
|
11701
|
+
"median",
|
|
11702
|
+
"min",
|
|
11703
|
+
"max",
|
|
11704
|
+
"sum",
|
|
11705
|
+
"any",
|
|
11706
|
+
"all"
|
|
11707
|
+
]),
|
|
11708
|
+
reads: array(CompositionFieldReadSchema).min(1).max(64),
|
|
11709
|
+
/** `value` is the reading; the others are the member counts. */
|
|
11710
|
+
publish: _enum([
|
|
11711
|
+
"value",
|
|
11712
|
+
"included",
|
|
11713
|
+
"excluded",
|
|
11714
|
+
"total"
|
|
11715
|
+
]),
|
|
11716
|
+
/** What a `value` publish does when nobody is included. Counts ignore this. */
|
|
11717
|
+
empty: _enum([
|
|
11718
|
+
"null",
|
|
11719
|
+
"omit",
|
|
11720
|
+
"offline"
|
|
11721
|
+
])
|
|
11722
|
+
})
|
|
11614
11723
|
]);
|
|
11615
11724
|
var CompositionCommandTargetSchema = discriminatedUnion("kind", [object({
|
|
11616
11725
|
kind: literal("forward"),
|
|
@@ -11656,7 +11765,13 @@ var CompositionSchema = object({
|
|
|
11656
11765
|
kind: literal("existing"),
|
|
11657
11766
|
device: CompositionSourceRefSchema
|
|
11658
11767
|
})]),
|
|
11659
|
-
features: array(CompositionFeatureSchema).min(1).max(16)
|
|
11768
|
+
features: array(CompositionFeatureSchema).min(1).max(16),
|
|
11769
|
+
/**
|
|
11770
|
+
* Present when the block is a helper template. Absent on a free
|
|
11771
|
+
* composition (the room example, device 4603). The editor reads this,
|
|
11772
|
+
* never the compiled features.
|
|
11773
|
+
*/
|
|
11774
|
+
helper: HelperSpecSchema.optional()
|
|
11660
11775
|
}).superRefine((composition, ctx) => {
|
|
11661
11776
|
const seen = /* @__PURE__ */ new Set();
|
|
11662
11777
|
composition.features.forEach((feature, index) => {
|
|
@@ -17865,7 +17980,10 @@ var CompositionProblemSchema = object({
|
|
|
17865
17980
|
"target-missing",
|
|
17866
17981
|
"target-unreadable",
|
|
17867
17982
|
"not-replaceable",
|
|
17868
|
-
"native-capability-replace"
|
|
17983
|
+
"native-capability-replace",
|
|
17984
|
+
"mixed-quantity",
|
|
17985
|
+
"helper-mismatch",
|
|
17986
|
+
"member-constraint"
|
|
17869
17987
|
]),
|
|
17870
17988
|
path: string(),
|
|
17871
17989
|
message: string()
|
|
@@ -17886,7 +18004,8 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
17886
18004
|
"null",
|
|
17887
18005
|
"offline",
|
|
17888
18006
|
"unknown",
|
|
17889
|
-
"release"
|
|
18007
|
+
"release",
|
|
18008
|
+
"omit"
|
|
17890
18009
|
]);
|
|
17891
18010
|
/**
|
|
17892
18011
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
@@ -18100,6 +18219,275 @@ Object.freeze({
|
|
|
18100
18219
|
result: ["number", "null"]
|
|
18101
18220
|
}
|
|
18102
18221
|
});
|
|
18222
|
+
/**
|
|
18223
|
+
* One catalog row per base reading a group helper can build (D944 §3).
|
|
18224
|
+
* Data, not a form default written into the block.
|
|
18225
|
+
*/
|
|
18226
|
+
var NOW = {
|
|
18227
|
+
fieldPath: "lastFetchedAt",
|
|
18228
|
+
expr: "now"
|
|
18229
|
+
};
|
|
18230
|
+
var CHANGED = {
|
|
18231
|
+
fieldPath: "lastChangedAt",
|
|
18232
|
+
expr: "now"
|
|
18233
|
+
};
|
|
18234
|
+
function numeric(input) {
|
|
18235
|
+
return {
|
|
18236
|
+
...input,
|
|
18237
|
+
family: "numeric",
|
|
18238
|
+
deviceType: DeviceType.Sensor,
|
|
18239
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18240
|
+
commandCaps: [],
|
|
18241
|
+
baseUnit: baseUnitOf(input.quantity),
|
|
18242
|
+
aggregates: NUMERIC_AGGREGATES,
|
|
18243
|
+
accept: [{
|
|
18244
|
+
cap: input.outputCap,
|
|
18245
|
+
fieldPath: input.outputField
|
|
18246
|
+
}]
|
|
18247
|
+
};
|
|
18248
|
+
}
|
|
18249
|
+
function binary(input) {
|
|
18250
|
+
return {
|
|
18251
|
+
...input,
|
|
18252
|
+
family: "binary",
|
|
18253
|
+
deviceType: DeviceType.Sensor,
|
|
18254
|
+
memberDeviceType: DeviceType.Sensor,
|
|
18255
|
+
commandCaps: [],
|
|
18256
|
+
quantity: "none",
|
|
18257
|
+
baseUnit: void 0,
|
|
18258
|
+
aggregates: BINARY_AGGREGATES,
|
|
18259
|
+
empty: "offline"
|
|
18260
|
+
};
|
|
18261
|
+
}
|
|
18262
|
+
var GROUP_TEMPLATES = [
|
|
18263
|
+
numeric({
|
|
18264
|
+
id: "temperature",
|
|
18265
|
+
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18266
|
+
role: DeviceRole.TemperatureSensor,
|
|
18267
|
+
outputCap: "temperature-sensor",
|
|
18268
|
+
outputField: "celsius",
|
|
18269
|
+
quantity: "temperature",
|
|
18270
|
+
defaultAggregate: "mean",
|
|
18271
|
+
empty: "null",
|
|
18272
|
+
companions: [NOW]
|
|
18273
|
+
}),
|
|
18274
|
+
numeric({
|
|
18275
|
+
id: "humidity",
|
|
18276
|
+
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18277
|
+
role: DeviceRole.HumiditySensor,
|
|
18278
|
+
outputCap: "humidity-sensor",
|
|
18279
|
+
outputField: "percent",
|
|
18280
|
+
quantity: "humidity",
|
|
18281
|
+
defaultAggregate: "mean",
|
|
18282
|
+
empty: "null",
|
|
18283
|
+
companions: [NOW]
|
|
18284
|
+
}),
|
|
18285
|
+
numeric({
|
|
18286
|
+
id: "pressure",
|
|
18287
|
+
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18288
|
+
role: DeviceRole.PressureSensor,
|
|
18289
|
+
outputCap: "pressure-sensor",
|
|
18290
|
+
outputField: "hpa",
|
|
18291
|
+
quantity: "pressure",
|
|
18292
|
+
defaultAggregate: "mean",
|
|
18293
|
+
empty: "null",
|
|
18294
|
+
companions: [NOW]
|
|
18295
|
+
}),
|
|
18296
|
+
numeric({
|
|
18297
|
+
id: "illuminance",
|
|
18298
|
+
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18299
|
+
role: DeviceRole.AmbientLightSensor,
|
|
18300
|
+
outputCap: "ambient-light-sensor",
|
|
18301
|
+
outputField: "lux",
|
|
18302
|
+
quantity: "illuminance",
|
|
18303
|
+
defaultAggregate: "mean",
|
|
18304
|
+
empty: "null",
|
|
18305
|
+
companions: [NOW]
|
|
18306
|
+
}),
|
|
18307
|
+
numeric({
|
|
18308
|
+
id: "power",
|
|
18309
|
+
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18310
|
+
role: DeviceRole.PowerSensor,
|
|
18311
|
+
outputCap: "power-meter",
|
|
18312
|
+
outputField: "watts",
|
|
18313
|
+
quantity: "power",
|
|
18314
|
+
defaultAggregate: "sum",
|
|
18315
|
+
empty: "omit",
|
|
18316
|
+
companions: [NOW]
|
|
18317
|
+
}),
|
|
18318
|
+
numeric({
|
|
18319
|
+
id: "energy",
|
|
18320
|
+
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18321
|
+
role: DeviceRole.EnergySensor,
|
|
18322
|
+
outputCap: "power-meter",
|
|
18323
|
+
outputField: "kwhTotal",
|
|
18324
|
+
quantity: "energy",
|
|
18325
|
+
defaultAggregate: "sum",
|
|
18326
|
+
empty: "omit",
|
|
18327
|
+
companions: [NOW]
|
|
18328
|
+
}),
|
|
18329
|
+
numeric({
|
|
18330
|
+
id: "battery",
|
|
18331
|
+
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18332
|
+
role: DeviceRole.BatterySensor,
|
|
18333
|
+
outputCap: "battery",
|
|
18334
|
+
outputField: "percentage",
|
|
18335
|
+
quantity: "percentage",
|
|
18336
|
+
defaultAggregate: "mean",
|
|
18337
|
+
empty: "null",
|
|
18338
|
+
companions: [
|
|
18339
|
+
{
|
|
18340
|
+
fieldPath: "charging",
|
|
18341
|
+
expr: "\"unknown\""
|
|
18342
|
+
},
|
|
18343
|
+
{
|
|
18344
|
+
fieldPath: "sleeping",
|
|
18345
|
+
expr: "false"
|
|
18346
|
+
},
|
|
18347
|
+
{
|
|
18348
|
+
fieldPath: "lastUpdated",
|
|
18349
|
+
expr: "now"
|
|
18350
|
+
}
|
|
18351
|
+
]
|
|
18352
|
+
}),
|
|
18353
|
+
numeric({
|
|
18354
|
+
id: "numeric",
|
|
18355
|
+
summary: "A numeric reading in the members’ shared quantity. Mixed quantities are refused. Nobody reporting publishes null, not 0.",
|
|
18356
|
+
role: DeviceRole.NumericSensor,
|
|
18357
|
+
outputCap: "numeric-sensor",
|
|
18358
|
+
outputField: "value",
|
|
18359
|
+
quantity: "device",
|
|
18360
|
+
defaultAggregate: "mean",
|
|
18361
|
+
empty: "null",
|
|
18362
|
+
companions: [NOW]
|
|
18363
|
+
}),
|
|
18364
|
+
binary({
|
|
18365
|
+
id: "motion",
|
|
18366
|
+
summary: "Any or all motion. Offline and unknown members are left out, never read as off. Nobody reporting takes the device offline.",
|
|
18367
|
+
role: DeviceRole.MotionSensor,
|
|
18368
|
+
outputCap: "motion",
|
|
18369
|
+
outputField: "detected",
|
|
18370
|
+
defaultAggregate: "any",
|
|
18371
|
+
accept: [{
|
|
18372
|
+
cap: "motion",
|
|
18373
|
+
fieldPath: "detected"
|
|
18374
|
+
}],
|
|
18375
|
+
companions: [{
|
|
18376
|
+
fieldPath: "lastDetectedAt",
|
|
18377
|
+
expr: "null"
|
|
18378
|
+
}, {
|
|
18379
|
+
fieldPath: "autoClearAfterMs",
|
|
18380
|
+
expr: "null"
|
|
18381
|
+
}]
|
|
18382
|
+
}),
|
|
18383
|
+
binary({
|
|
18384
|
+
id: "contact",
|
|
18385
|
+
summary: "Any or all open contacts. Offline and unknown members are left out, never read as closed.",
|
|
18386
|
+
role: DeviceRole.ContactSensor,
|
|
18387
|
+
outputCap: "contact",
|
|
18388
|
+
outputField: "entryOpen",
|
|
18389
|
+
defaultAggregate: "any",
|
|
18390
|
+
accept: [{
|
|
18391
|
+
cap: "contact",
|
|
18392
|
+
fieldPath: "entryOpen"
|
|
18393
|
+
}],
|
|
18394
|
+
companions: [CHANGED]
|
|
18395
|
+
}),
|
|
18396
|
+
binary({
|
|
18397
|
+
id: "leak",
|
|
18398
|
+
summary: "Any or all leak detections. Offline and unknown members are left out, never read as dry.",
|
|
18399
|
+
role: DeviceRole.LeakSensor,
|
|
18400
|
+
outputCap: "flood",
|
|
18401
|
+
outputField: "flooded",
|
|
18402
|
+
defaultAggregate: "any",
|
|
18403
|
+
accept: [{
|
|
18404
|
+
cap: "flood",
|
|
18405
|
+
fieldPath: "flooded"
|
|
18406
|
+
}],
|
|
18407
|
+
companions: [CHANGED]
|
|
18408
|
+
}),
|
|
18409
|
+
binary({
|
|
18410
|
+
id: "smoke",
|
|
18411
|
+
summary: "Any or all smoke detections. Offline and unknown members are left out, never read as clear.",
|
|
18412
|
+
role: DeviceRole.SmokeSensor,
|
|
18413
|
+
outputCap: "smoke",
|
|
18414
|
+
outputField: "detected",
|
|
18415
|
+
defaultAggregate: "any",
|
|
18416
|
+
accept: [{
|
|
18417
|
+
cap: "smoke",
|
|
18418
|
+
fieldPath: "detected"
|
|
18419
|
+
}],
|
|
18420
|
+
companions: [CHANGED]
|
|
18421
|
+
}),
|
|
18422
|
+
binary({
|
|
18423
|
+
id: "occupancy",
|
|
18424
|
+
summary: "Any or all of motion or binary sensors, published as a binary. Presence zones are not aggregated. Nobody reporting is offline, not off.",
|
|
18425
|
+
role: DeviceRole.BinarySensor,
|
|
18426
|
+
outputCap: "binary",
|
|
18427
|
+
outputField: "on",
|
|
18428
|
+
defaultAggregate: "any",
|
|
18429
|
+
accept: [{
|
|
18430
|
+
cap: "motion",
|
|
18431
|
+
fieldPath: "detected"
|
|
18432
|
+
}, {
|
|
18433
|
+
cap: "binary",
|
|
18434
|
+
fieldPath: "on"
|
|
18435
|
+
}],
|
|
18436
|
+
companions: [CHANGED]
|
|
18437
|
+
}),
|
|
18438
|
+
binary({
|
|
18439
|
+
id: "binary",
|
|
18440
|
+
summary: "Any or all generic binary sensors. Offline and unknown members are left out, never read as off.",
|
|
18441
|
+
role: DeviceRole.BinarySensor,
|
|
18442
|
+
outputCap: "binary",
|
|
18443
|
+
outputField: "on",
|
|
18444
|
+
defaultAggregate: "any",
|
|
18445
|
+
accept: [{
|
|
18446
|
+
cap: "binary",
|
|
18447
|
+
fieldPath: "on"
|
|
18448
|
+
}],
|
|
18449
|
+
companions: [CHANGED]
|
|
18450
|
+
}),
|
|
18451
|
+
actuator({
|
|
18452
|
+
id: "switch",
|
|
18453
|
+
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.",
|
|
18454
|
+
deviceType: DeviceType.Switch,
|
|
18455
|
+
outputCap: "switch",
|
|
18456
|
+
commandCaps: ["switch"]
|
|
18457
|
+
}),
|
|
18458
|
+
actuator({
|
|
18459
|
+
id: "light",
|
|
18460
|
+
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.",
|
|
18461
|
+
deviceType: DeviceType.Light,
|
|
18462
|
+
outputCap: "switch",
|
|
18463
|
+
commandCaps: [
|
|
18464
|
+
"switch",
|
|
18465
|
+
"brightness",
|
|
18466
|
+
"color"
|
|
18467
|
+
]
|
|
18468
|
+
})
|
|
18469
|
+
];
|
|
18470
|
+
function actuator(input) {
|
|
18471
|
+
return {
|
|
18472
|
+
...input,
|
|
18473
|
+
family: "actuator",
|
|
18474
|
+
role: void 0,
|
|
18475
|
+
memberDeviceType: input.deviceType,
|
|
18476
|
+
outputField: "on",
|
|
18477
|
+
quantity: "none",
|
|
18478
|
+
baseUnit: void 0,
|
|
18479
|
+
aggregates: BINARY_AGGREGATES,
|
|
18480
|
+
defaultAggregate: "any",
|
|
18481
|
+
empty: "offline",
|
|
18482
|
+
accept: [{
|
|
18483
|
+
cap: "switch",
|
|
18484
|
+
fieldPath: "on"
|
|
18485
|
+
}],
|
|
18486
|
+
companions: [CHANGED]
|
|
18487
|
+
};
|
|
18488
|
+
}
|
|
18489
|
+
new Map(GROUP_TEMPLATES.map((template) => [template.id, template]));
|
|
18490
|
+
DeviceFeature.LightColorRgb, DeviceFeature.LightColorHsv, DeviceFeature.LightColorMired;
|
|
18103
18491
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
18104
18492
|
/**
|
|
18105
18493
|
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
@@ -45089,6 +45477,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
45089
45477
|
"detection-blind",
|
|
45090
45478
|
"motion-noisy",
|
|
45091
45479
|
"motion-calm",
|
|
45480
|
+
"package-llm-silent",
|
|
45481
|
+
"package-llm-answered",
|
|
45092
45482
|
"recording-stalled",
|
|
45093
45483
|
"recording-healthy",
|
|
45094
45484
|
"recording-degraded",
|
|
@@ -56180,6 +56570,28 @@ var PackageVersionInfoSchema = object({
|
|
|
56180
56570
|
deprecated: string().optional(),
|
|
56181
56571
|
distTags: array(string()).readonly()
|
|
56182
56572
|
});
|
|
56573
|
+
/**
|
|
56574
|
+
* One published document. `ok` is markdown from the registry. `missing` means
|
|
56575
|
+
* the registry answered and the file was not there. `error` is a registry or
|
|
56576
|
+
* tarball failure — never an empty string standing in for either.
|
|
56577
|
+
*/
|
|
56578
|
+
var PackageDocBodySchema = discriminatedUnion("status", [
|
|
56579
|
+
object({
|
|
56580
|
+
status: literal("ok"),
|
|
56581
|
+
markdown: string()
|
|
56582
|
+
}),
|
|
56583
|
+
object({ status: literal("missing") }),
|
|
56584
|
+
object({
|
|
56585
|
+
status: literal("error"),
|
|
56586
|
+
message: string()
|
|
56587
|
+
})
|
|
56588
|
+
]);
|
|
56589
|
+
var PackageDocsSchema = object({
|
|
56590
|
+
name: string(),
|
|
56591
|
+
version: string(),
|
|
56592
|
+
readme: PackageDocBodySchema,
|
|
56593
|
+
changelog: PackageDocBodySchema
|
|
56594
|
+
});
|
|
56183
56595
|
var SearchResultSchema = object({
|
|
56184
56596
|
name: string(),
|
|
56185
56597
|
version: string(),
|
|
@@ -56398,7 +56810,10 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
56398
56810
|
}), object({ success: literal(true) }), {
|
|
56399
56811
|
kind: "mutation",
|
|
56400
56812
|
auth: "admin"
|
|
56401
|
-
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56813
|
+
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({
|
|
56814
|
+
name: string().min(1),
|
|
56815
|
+
version: string().min(1).optional()
|
|
56816
|
+
}), PackageDocsSchema, { auth: "admin" }), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
56402
56817
|
kind: "mutation",
|
|
56403
56818
|
auth: "admin"
|
|
56404
56819
|
}), method(object({ packageName: string() }), object({ success: literal(true) }), {
|
|
@@ -59717,6 +60132,88 @@ var gasCapability = {
|
|
|
59717
60132
|
* whether persisting is worth a SQLite commit. */
|
|
59718
60133
|
volatileStateFields: ["lastChangedAt"]
|
|
59719
60134
|
};
|
|
60135
|
+
var GroupCommandsSchema = object({
|
|
60136
|
+
/** One row per member that has been commanded. A later command replaces that member's row. */
|
|
60137
|
+
results: array(object({
|
|
60138
|
+
deviceId: number().int().nonnegative(),
|
|
60139
|
+
cap: string().min(1),
|
|
60140
|
+
method: string().min(1),
|
|
60141
|
+
ok: boolean(),
|
|
60142
|
+
error: string().optional(),
|
|
60143
|
+
/** Ms epoch of the attempt. */
|
|
60144
|
+
at: number()
|
|
60145
|
+
})) });
|
|
60146
|
+
var groupCommandsCapability = {
|
|
60147
|
+
name: "group-commands",
|
|
60148
|
+
scope: "device",
|
|
60149
|
+
deviceNative: true,
|
|
60150
|
+
mode: "singleton",
|
|
60151
|
+
deviceTypes: [DeviceType.Switch, DeviceType.Light],
|
|
60152
|
+
methods: {},
|
|
60153
|
+
status: {
|
|
60154
|
+
schema: GroupCommandsSchema,
|
|
60155
|
+
kind: "push"
|
|
60156
|
+
},
|
|
60157
|
+
runtimeState: GroupCommandsSchema,
|
|
60158
|
+
/**
|
|
60159
|
+
* Runtime-state durability: **session** — the last attempt. A restored
|
|
60160
|
+
* failure would outlive the command that caused it.
|
|
60161
|
+
*
|
|
60162
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60163
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60164
|
+
*/
|
|
60165
|
+
durability: "session",
|
|
60166
|
+
history: "none"
|
|
60167
|
+
};
|
|
60168
|
+
/**
|
|
60169
|
+
* How many members of a helper group answered (D944). Counts are integers,
|
|
60170
|
+
* not measurements: zero included is a real count, never a stand-in reading.
|
|
60171
|
+
* The reading itself stays on the output capability. History is none — the
|
|
60172
|
+
* series that later statistics read is the output cap's own history block.
|
|
60173
|
+
*/
|
|
60174
|
+
var GroupStatusSchema = object({
|
|
60175
|
+
/** Members whose current value entered the aggregate. */
|
|
60176
|
+
included: number().int().nonnegative().meta(readingMeta("count", {
|
|
60177
|
+
precision: 0,
|
|
60178
|
+
label: "Reporting"
|
|
60179
|
+
})),
|
|
60180
|
+
/** Members left out: offline, unknown, or not a finite reading (D393). */
|
|
60181
|
+
excluded: number().int().nonnegative().meta(readingMeta("count", {
|
|
60182
|
+
precision: 0,
|
|
60183
|
+
label: "Excluded"
|
|
60184
|
+
})),
|
|
60185
|
+
/** `included` + `excluded`. */
|
|
60186
|
+
total: number().int().nonnegative().meta(readingMeta("count", {
|
|
60187
|
+
precision: 0,
|
|
60188
|
+
label: "Members"
|
|
60189
|
+
}))
|
|
60190
|
+
});
|
|
60191
|
+
var groupStatusCapability = {
|
|
60192
|
+
name: "group-status",
|
|
60193
|
+
scope: "device",
|
|
60194
|
+
deviceNative: true,
|
|
60195
|
+
mode: "singleton",
|
|
60196
|
+
deviceTypes: [
|
|
60197
|
+
DeviceType.Sensor,
|
|
60198
|
+
DeviceType.Switch,
|
|
60199
|
+
DeviceType.Light
|
|
60200
|
+
],
|
|
60201
|
+
methods: {},
|
|
60202
|
+
status: {
|
|
60203
|
+
schema: GroupStatusSchema,
|
|
60204
|
+
kind: "push"
|
|
60205
|
+
},
|
|
60206
|
+
runtimeState: GroupStatusSchema,
|
|
60207
|
+
/**
|
|
60208
|
+
* Runtime-state durability: **session** — recomputed from members on the
|
|
60209
|
+
* next source event; a restored count would outlive the readings it named.
|
|
60210
|
+
*
|
|
60211
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
60212
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
60213
|
+
*/
|
|
60214
|
+
durability: "session",
|
|
60215
|
+
history: "none"
|
|
60216
|
+
};
|
|
59720
60217
|
var HeatingValveStatusSchema = object({
|
|
59721
60218
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
59722
60219
|
position: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -61486,12 +61983,18 @@ var motionCapability = {
|
|
|
61486
61983
|
methods: {
|
|
61487
61984
|
/**
|
|
61488
61985
|
* Pull the current motion state synchronously. Convenience shortcut
|
|
61489
|
-
* for consumers that don't need the full status object
|
|
61490
|
-
*
|
|
61491
|
-
* `getStatus` once the auto-injected status surface lands in every
|
|
61492
|
-
* consumer.
|
|
61986
|
+
* for consumers that don't need the full status object. A composed
|
|
61987
|
+
* group answers from its slice (D944): unknown throws, it is not off.
|
|
61493
61988
|
*/
|
|
61494
61989
|
isDetected: method(object({ deviceId: number() }), boolean()) },
|
|
61990
|
+
/**
|
|
61991
|
+
* A composed motion group serves `isDetected` from `detected` (D944).
|
|
61992
|
+
* Without this the cap stays uncomposable (`has-commands`).
|
|
61993
|
+
*/
|
|
61994
|
+
composedMethods: { isDetected: {
|
|
61995
|
+
kind: "slice",
|
|
61996
|
+
field: "detected"
|
|
61997
|
+
} },
|
|
61495
61998
|
events: {
|
|
61496
61999
|
/**
|
|
61497
62000
|
* Fires every time the runner transitions a camera between
|
|
@@ -69682,6 +70185,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
69682
70185
|
featureProbe: featureProbeCapability,
|
|
69683
70186
|
flood: floodCapability,
|
|
69684
70187
|
gas: gasCapability,
|
|
70188
|
+
groupCommands: groupCommandsCapability,
|
|
70189
|
+
groupStatus: groupStatusCapability,
|
|
69685
70190
|
heatingValve: heatingValveCapability,
|
|
69686
70191
|
humidifier: humidifierCapability,
|
|
69687
70192
|
humiditySensor: humiditySensorCapability,
|
|
@@ -71058,6 +71563,13 @@ Object.freeze({
|
|
|
71058
71563
|
access: "view",
|
|
71059
71564
|
role: "admin"
|
|
71060
71565
|
},
|
|
71566
|
+
"addons.getPackageDocs": {
|
|
71567
|
+
capName: "addons",
|
|
71568
|
+
capScope: "system",
|
|
71569
|
+
addonId: null,
|
|
71570
|
+
access: "view",
|
|
71571
|
+
role: "admin"
|
|
71572
|
+
},
|
|
71061
71573
|
"addons.getVersions": {
|
|
71062
71574
|
capName: "addons",
|
|
71063
71575
|
capScope: "system",
|
|
@@ -74166,6 +74678,20 @@ Object.freeze({
|
|
|
74166
74678
|
access: "view",
|
|
74167
74679
|
role: "viewer"
|
|
74168
74680
|
},
|
|
74681
|
+
"groupCommands.getStatus": {
|
|
74682
|
+
capName: "group-commands",
|
|
74683
|
+
capScope: "device",
|
|
74684
|
+
addonId: null,
|
|
74685
|
+
access: "view",
|
|
74686
|
+
role: "viewer"
|
|
74687
|
+
},
|
|
74688
|
+
"groupStatus.getStatus": {
|
|
74689
|
+
capName: "group-status",
|
|
74690
|
+
capScope: "device",
|
|
74691
|
+
addonId: null,
|
|
74692
|
+
access: "view",
|
|
74693
|
+
role: "viewer"
|
|
74694
|
+
},
|
|
74169
74695
|
"heatingValve.getStatus": {
|
|
74170
74696
|
capName: "heating-valve",
|
|
74171
74697
|
capScope: "device",
|
|
@@ -83988,6 +84514,37 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
83988
84514
|
icon: "flame"
|
|
83989
84515
|
}]
|
|
83990
84516
|
},
|
|
84517
|
+
"group-commands": {
|
|
84518
|
+
scope: "device",
|
|
84519
|
+
noun: t("Group command", "Comando di gruppo")
|
|
84520
|
+
},
|
|
84521
|
+
"group-status": {
|
|
84522
|
+
scope: "device",
|
|
84523
|
+
noun: t("Group", "Gruppo"),
|
|
84524
|
+
state: [
|
|
84525
|
+
{
|
|
84526
|
+
kind: "numeric",
|
|
84527
|
+
field: "included",
|
|
84528
|
+
quantity: t("the members reporting", "i membri che rispondono"),
|
|
84529
|
+
label: t("Reporting", "Rispondono"),
|
|
84530
|
+
icon: "users"
|
|
84531
|
+
},
|
|
84532
|
+
{
|
|
84533
|
+
kind: "numeric",
|
|
84534
|
+
field: "excluded",
|
|
84535
|
+
quantity: t("the members left out", "i membri esclusi"),
|
|
84536
|
+
label: t("Excluded", "Esclusi"),
|
|
84537
|
+
icon: "users"
|
|
84538
|
+
},
|
|
84539
|
+
{
|
|
84540
|
+
kind: "numeric",
|
|
84541
|
+
field: "total",
|
|
84542
|
+
quantity: t("the member count", "il numero di membri"),
|
|
84543
|
+
label: t("Members", "Membri"),
|
|
84544
|
+
icon: "sigma"
|
|
84545
|
+
}
|
|
84546
|
+
]
|
|
84547
|
+
},
|
|
83991
84548
|
"humidity-sensor": {
|
|
83992
84549
|
scope: "device",
|
|
83993
84550
|
noun: t("Humidity", "Umidità"),
|
|
@@ -85453,6 +86010,16 @@ Object.freeze({
|
|
|
85453
86010
|
form: "single",
|
|
85454
86011
|
optional: false
|
|
85455
86012
|
}],
|
|
86013
|
+
"groupCommands.getStatus": [{
|
|
86014
|
+
name: "deviceId",
|
|
86015
|
+
form: "single",
|
|
86016
|
+
optional: false
|
|
86017
|
+
}],
|
|
86018
|
+
"groupStatus.getStatus": [{
|
|
86019
|
+
name: "deviceId",
|
|
86020
|
+
form: "single",
|
|
86021
|
+
optional: false
|
|
86022
|
+
}],
|
|
85456
86023
|
"heatingValve.getStatus": [{
|
|
85457
86024
|
name: "deviceId",
|
|
85458
86025
|
form: "single",
|
|
@@ -87437,6 +88004,8 @@ new Map(Object.entries({
|
|
|
87437
88004
|
"detection-blind": "device-events",
|
|
87438
88005
|
"motion-noisy": "device-events",
|
|
87439
88006
|
"motion-calm": "device-events",
|
|
88007
|
+
"package-llm-silent": "device-events",
|
|
88008
|
+
"package-llm-answered": "device-events",
|
|
87440
88009
|
"recording-stalled": "device-events",
|
|
87441
88010
|
"recording-healthy": "device-events",
|
|
87442
88011
|
"recording-degraded": "device-events",
|
|
@@ -87520,6 +88089,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
87520
88089
|
label: "Motion without a subject",
|
|
87521
88090
|
kinds: ["motion-noisy", "motion-calm"]
|
|
87522
88091
|
},
|
|
88092
|
+
{
|
|
88093
|
+
id: "package-llm",
|
|
88094
|
+
family: "device-events",
|
|
88095
|
+
label: "Package confirm",
|
|
88096
|
+
kinds: ["package-llm-silent", "package-llm-answered"]
|
|
88097
|
+
},
|
|
87523
88098
|
{
|
|
87524
88099
|
id: "recording",
|
|
87525
88100
|
family: "device-events",
|
|
@@ -87701,6 +88276,8 @@ var DEVICE_EVENTS = [
|
|
|
87701
88276
|
"detection-blind",
|
|
87702
88277
|
"motion-noisy",
|
|
87703
88278
|
"motion-calm",
|
|
88279
|
+
"package-llm-silent",
|
|
88280
|
+
"package-llm-answered",
|
|
87704
88281
|
"recording-stalled",
|
|
87705
88282
|
"recording-healthy",
|
|
87706
88283
|
"recording-degraded",
|
|
@@ -87969,6 +88546,15 @@ new Map([
|
|
|
87969
88546
|
snapshotLabel: "Cameras with constant motion now",
|
|
87970
88547
|
snapshotSection: null
|
|
87971
88548
|
},
|
|
88549
|
+
{
|
|
88550
|
+
id: "package-llm-confirm",
|
|
88551
|
+
family: "device-events",
|
|
88552
|
+
label: "Package confirm (not answering / answering again)",
|
|
88553
|
+
bad: ["package-llm-silent"],
|
|
88554
|
+
recovery: ["package-llm-answered"],
|
|
88555
|
+
snapshotLabel: "Cameras whose package confirm is not answering",
|
|
88556
|
+
snapshotSection: null
|
|
88557
|
+
},
|
|
87972
88558
|
{
|
|
87973
88559
|
id: "recording-health",
|
|
87974
88560
|
family: "device-events",
|