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