@camstack/addon-provider-homematic 1.2.160 → 1.2.161
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 +6 -0
- package/dist/addon.js +853 -249
- package/dist/addon.mjs +853 -249
- package/dist/index.js +7 -7
- package/dist/index.mjs +7 -7
- package/package.json +1 -1
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-DmZDPDf_.mjs
|
|
12
12
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
13
13
|
EventCategory["SystemBoot"] = "system.boot";
|
|
14
14
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -635,7 +635,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
635
635
|
* (a track was promoted to a stationary-registry entry) or departs (the
|
|
636
636
|
* object moved / was removed). Telemetry (D8): lossy, drives a UI refresh of
|
|
637
637
|
* the dedicated "Stationary" section — never the live event feed. Payload:
|
|
638
|
-
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp }`.
|
|
638
|
+
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp, observedAt, zones }`.
|
|
639
639
|
*/
|
|
640
640
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
641
641
|
/**
|
|
@@ -773,6 +773,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
773
773
|
*/
|
|
774
774
|
EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
|
|
775
775
|
/**
|
|
776
|
+
* An action run started or ended. Emitted by the `actions` surface.
|
|
777
|
+
* Payload: `ActionRunChanged` (`{ actionId, runId, isRunning, outcome?, lastRunAt, lastError }`).
|
|
778
|
+
*/
|
|
779
|
+
EventCategory["ActionsRunChanged"] = "actions.onRunChanged";
|
|
780
|
+
/**
|
|
776
781
|
* Progress update from a running model conversion job.
|
|
777
782
|
* Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
|
|
778
783
|
* Emitted by `addon-model-studio` on the converting node.
|
|
@@ -5584,7 +5589,7 @@ var ZodIssueCode = {
|
|
|
5584
5589
|
var ZodFirstPartyTypeKind;
|
|
5585
5590
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5586
5591
|
//#endregion
|
|
5587
|
-
//#region ../types/dist/sleep
|
|
5592
|
+
//#region ../types/dist/sleep-Crlmu_tO.mjs
|
|
5588
5593
|
/**
|
|
5589
5594
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5590
5595
|
* window to float samples (D455).
|
|
@@ -8892,6 +8897,8 @@ Object.freeze({ "doorbell": "lastPressedAt" });
|
|
|
8892
8897
|
/** Every capability name, so addon code can check a name without the schema graph. */
|
|
8893
8898
|
var CAP_NAMES = Object.freeze([
|
|
8894
8899
|
"accessories",
|
|
8900
|
+
"action-source",
|
|
8901
|
+
"actions",
|
|
8895
8902
|
"addon-pages",
|
|
8896
8903
|
"addon-pages-source",
|
|
8897
8904
|
"addon-routes",
|
|
@@ -9080,11 +9087,11 @@ var CAP_NAMES = Object.freeze([
|
|
|
9080
9087
|
Object.freeze({
|
|
9081
9088
|
"air-quality-sensor": [
|
|
9082
9089
|
{
|
|
9083
|
-
"path": "
|
|
9090
|
+
"path": "co2",
|
|
9084
9091
|
"valueType": "number"
|
|
9085
9092
|
},
|
|
9086
9093
|
{
|
|
9087
|
-
"path": "
|
|
9094
|
+
"path": "voc",
|
|
9088
9095
|
"valueType": "number"
|
|
9089
9096
|
},
|
|
9090
9097
|
{
|
|
@@ -9134,7 +9141,7 @@ Object.freeze({
|
|
|
9134
9141
|
}
|
|
9135
9142
|
],
|
|
9136
9143
|
"ambient-light-sensor": [{
|
|
9137
|
-
"path": "
|
|
9144
|
+
"path": "illuminance",
|
|
9138
9145
|
"valueType": "number"
|
|
9139
9146
|
}],
|
|
9140
9147
|
"audio-metrics": [
|
|
@@ -9195,7 +9202,7 @@ Object.freeze({
|
|
|
9195
9202
|
],
|
|
9196
9203
|
"battery": [
|
|
9197
9204
|
{
|
|
9198
|
-
"path": "
|
|
9205
|
+
"path": "level",
|
|
9199
9206
|
"valueType": "number"
|
|
9200
9207
|
},
|
|
9201
9208
|
{
|
|
@@ -9217,7 +9224,7 @@ Object.freeze({
|
|
|
9217
9224
|
"valueType": "number"
|
|
9218
9225
|
},
|
|
9219
9226
|
{
|
|
9220
|
-
"path": "
|
|
9227
|
+
"path": "voltage",
|
|
9221
9228
|
"valueType": "number"
|
|
9222
9229
|
},
|
|
9223
9230
|
{
|
|
@@ -9238,7 +9245,7 @@ Object.freeze({
|
|
|
9238
9245
|
"valueType": "boolean"
|
|
9239
9246
|
}],
|
|
9240
9247
|
"brightness": [{
|
|
9241
|
-
"path": "
|
|
9248
|
+
"path": "level",
|
|
9242
9249
|
"valueType": "number"
|
|
9243
9250
|
}],
|
|
9244
9251
|
"broker": [{
|
|
@@ -9439,7 +9446,7 @@ Object.freeze({
|
|
|
9439
9446
|
"valueType": "number"
|
|
9440
9447
|
},
|
|
9441
9448
|
{
|
|
9442
|
-
"path": "
|
|
9449
|
+
"path": "colorTemperature",
|
|
9443
9450
|
"valueType": "number"
|
|
9444
9451
|
}
|
|
9445
9452
|
],
|
|
@@ -9618,15 +9625,15 @@ Object.freeze({
|
|
|
9618
9625
|
"valueType": "string"
|
|
9619
9626
|
},
|
|
9620
9627
|
{
|
|
9621
|
-
"path": "
|
|
9628
|
+
"path": "remaining",
|
|
9622
9629
|
"valueType": "number"
|
|
9623
9630
|
},
|
|
9624
9631
|
{
|
|
9625
|
-
"path": "
|
|
9632
|
+
"path": "delayedStart",
|
|
9626
9633
|
"valueType": "number"
|
|
9627
9634
|
},
|
|
9628
9635
|
{
|
|
9629
|
-
"path": "
|
|
9636
|
+
"path": "progress",
|
|
9630
9637
|
"valueType": "number"
|
|
9631
9638
|
},
|
|
9632
9639
|
{
|
|
@@ -9740,7 +9747,7 @@ Object.freeze({
|
|
|
9740
9747
|
],
|
|
9741
9748
|
"fan-control": [
|
|
9742
9749
|
{
|
|
9743
|
-
"path": "
|
|
9750
|
+
"path": "speed",
|
|
9744
9751
|
"valueType": "number"
|
|
9745
9752
|
},
|
|
9746
9753
|
{
|
|
@@ -9840,7 +9847,7 @@ Object.freeze({
|
|
|
9840
9847
|
}
|
|
9841
9848
|
],
|
|
9842
9849
|
"humidity-sensor": [{
|
|
9843
|
-
"path": "
|
|
9850
|
+
"path": "humidity",
|
|
9844
9851
|
"valueType": "number"
|
|
9845
9852
|
}],
|
|
9846
9853
|
"image": [{
|
|
@@ -9950,7 +9957,7 @@ Object.freeze({
|
|
|
9950
9957
|
"valueType": "number"
|
|
9951
9958
|
},
|
|
9952
9959
|
{
|
|
9953
|
-
"path": "
|
|
9960
|
+
"path": "progress",
|
|
9954
9961
|
"valueType": "number"
|
|
9955
9962
|
},
|
|
9956
9963
|
{
|
|
@@ -10029,11 +10036,11 @@ Object.freeze({
|
|
|
10029
10036
|
"valueType": "string"
|
|
10030
10037
|
},
|
|
10031
10038
|
{
|
|
10032
|
-
"path": "
|
|
10039
|
+
"path": "position",
|
|
10033
10040
|
"valueType": "number"
|
|
10034
10041
|
},
|
|
10035
10042
|
{
|
|
10036
|
-
"path": "
|
|
10043
|
+
"path": "duration",
|
|
10037
10044
|
"valueType": "number"
|
|
10038
10045
|
},
|
|
10039
10046
|
{
|
|
@@ -10135,11 +10142,11 @@ Object.freeze({
|
|
|
10135
10142
|
]
|
|
10136
10143
|
},
|
|
10137
10144
|
{
|
|
10138
|
-
"path": "
|
|
10145
|
+
"path": "signal",
|
|
10139
10146
|
"valueType": "number"
|
|
10140
10147
|
},
|
|
10141
10148
|
{
|
|
10142
|
-
"path": "
|
|
10149
|
+
"path": "rssi",
|
|
10143
10150
|
"valueType": "number"
|
|
10144
10151
|
},
|
|
10145
10152
|
{
|
|
@@ -10194,6 +10201,18 @@ Object.freeze({
|
|
|
10194
10201
|
"path": "foodLevel",
|
|
10195
10202
|
"valueType": "number"
|
|
10196
10203
|
},
|
|
10204
|
+
{
|
|
10205
|
+
"path": "bowlFood",
|
|
10206
|
+
"valueType": "number"
|
|
10207
|
+
},
|
|
10208
|
+
{
|
|
10209
|
+
"path": "eating",
|
|
10210
|
+
"valueType": "boolean"
|
|
10211
|
+
},
|
|
10212
|
+
{
|
|
10213
|
+
"path": "supportsMarkRefilled",
|
|
10214
|
+
"valueType": "boolean"
|
|
10215
|
+
},
|
|
10197
10216
|
{
|
|
10198
10217
|
"path": "food1",
|
|
10199
10218
|
"valueType": "number"
|
|
@@ -10258,23 +10277,23 @@ Object.freeze({
|
|
|
10258
10277
|
],
|
|
10259
10278
|
"power-meter": [
|
|
10260
10279
|
{
|
|
10261
|
-
"path": "
|
|
10280
|
+
"path": "power",
|
|
10262
10281
|
"valueType": "number"
|
|
10263
10282
|
},
|
|
10264
10283
|
{
|
|
10265
|
-
"path": "
|
|
10284
|
+
"path": "energy",
|
|
10266
10285
|
"valueType": "number"
|
|
10267
10286
|
},
|
|
10268
10287
|
{
|
|
10269
|
-
"path": "
|
|
10288
|
+
"path": "voltage",
|
|
10270
10289
|
"valueType": "number"
|
|
10271
10290
|
},
|
|
10272
10291
|
{
|
|
10273
|
-
"path": "
|
|
10292
|
+
"path": "current",
|
|
10274
10293
|
"valueType": "number"
|
|
10275
10294
|
},
|
|
10276
10295
|
{
|
|
10277
|
-
"path": "
|
|
10296
|
+
"path": "apparentPower",
|
|
10278
10297
|
"valueType": "number"
|
|
10279
10298
|
},
|
|
10280
10299
|
{
|
|
@@ -10302,14 +10321,10 @@ Object.freeze({
|
|
|
10302
10321
|
{
|
|
10303
10322
|
"path": "gps.accuracyMeters",
|
|
10304
10323
|
"valueType": "number"
|
|
10305
|
-
},
|
|
10306
|
-
{
|
|
10307
|
-
"path": "batteryPercent",
|
|
10308
|
-
"valueType": "number"
|
|
10309
10324
|
}
|
|
10310
10325
|
],
|
|
10311
10326
|
"pressure-sensor": [{
|
|
10312
|
-
"path": "
|
|
10327
|
+
"path": "pressure",
|
|
10313
10328
|
"valueType": "number"
|
|
10314
10329
|
}],
|
|
10315
10330
|
"privacy-mask": [{
|
|
@@ -10623,7 +10638,7 @@ Object.freeze({
|
|
|
10623
10638
|
"valueType": "boolean"
|
|
10624
10639
|
}],
|
|
10625
10640
|
"temperature-sensor": [{
|
|
10626
|
-
"path": "
|
|
10641
|
+
"path": "temperature",
|
|
10627
10642
|
"valueType": "number"
|
|
10628
10643
|
}],
|
|
10629
10644
|
"update": [
|
|
@@ -10671,7 +10686,7 @@ Object.freeze({
|
|
|
10671
10686
|
"valueType": "string"
|
|
10672
10687
|
},
|
|
10673
10688
|
{
|
|
10674
|
-
"path": "
|
|
10689
|
+
"path": "progress",
|
|
10675
10690
|
"valueType": "number"
|
|
10676
10691
|
},
|
|
10677
10692
|
{
|
|
@@ -11156,7 +11171,7 @@ function errMsg(err) {
|
|
|
11156
11171
|
return String(err);
|
|
11157
11172
|
}
|
|
11158
11173
|
//#endregion
|
|
11159
|
-
//#region ../types/dist/composition-
|
|
11174
|
+
//#region ../types/dist/composition-CZImLpOI.mjs
|
|
11160
11175
|
/**
|
|
11161
11176
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11162
11177
|
*
|
|
@@ -15676,6 +15691,14 @@ var AutomationConditionLeafSchema = object({
|
|
|
15676
15691
|
array(union([string(), number()]))
|
|
15677
15692
|
])
|
|
15678
15693
|
});
|
|
15694
|
+
var AutomationConditionStationaryPresentSchema = object({
|
|
15695
|
+
kind: literal("stationary-present"),
|
|
15696
|
+
deviceId: number().int().nonnegative(),
|
|
15697
|
+
/** Class names; a macro class matches every raw class that maps to it. */
|
|
15698
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
15699
|
+
/** The parked object must be in at least one of these zones. */
|
|
15700
|
+
zones: array(string().min(1)).min(1).optional()
|
|
15701
|
+
});
|
|
15679
15702
|
/**
|
|
15680
15703
|
* The expression leaf, declared as a plain object rather than an intersection
|
|
15681
15704
|
* with {@link ExpressionSourceSchema}: a discriminated union has to be able to
|
|
@@ -15709,7 +15732,8 @@ var AutomationConditionSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
15709
15732
|
child: AutomationConditionSchema
|
|
15710
15733
|
}),
|
|
15711
15734
|
AutomationConditionLeafSchema,
|
|
15712
|
-
AutomationConditionExpressionSchema
|
|
15735
|
+
AutomationConditionExpressionSchema,
|
|
15736
|
+
AutomationConditionStationaryPresentSchema
|
|
15713
15737
|
]));
|
|
15714
15738
|
/**
|
|
15715
15739
|
* What starts a run.
|
|
@@ -15750,7 +15774,34 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
15750
15774
|
kind: literal("schedule"),
|
|
15751
15775
|
cron: string().min(1).max(120)
|
|
15752
15776
|
}),
|
|
15753
|
-
object({ kind: literal("manual") })
|
|
15777
|
+
object({ kind: literal("manual") }),
|
|
15778
|
+
object({
|
|
15779
|
+
kind: literal("detection"),
|
|
15780
|
+
/** Class names. A macro class (`animal`, `vehicle`, `person`, `package`)
|
|
15781
|
+
* matches every raw class that maps to it; any other name matches
|
|
15782
|
+
* exactly. */
|
|
15783
|
+
classes: array(string().min(1)).min(1),
|
|
15784
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
15785
|
+
/** The track must have visited at least one of these zones. */
|
|
15786
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
15787
|
+
/** Best-so-far confidence the track must reach. */
|
|
15788
|
+
minScore: number().min(0).max(1).optional()
|
|
15789
|
+
}),
|
|
15790
|
+
object({
|
|
15791
|
+
kind: literal("stationary"),
|
|
15792
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
15793
|
+
/** Class names; a macro class matches like the detection trigger. */
|
|
15794
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
15795
|
+
/** The parked object must be in at least one of these zones. */
|
|
15796
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
15797
|
+
/** `appeared`: it became parked. `departed`: the registry retired it.
|
|
15798
|
+
* The vocabulary of `PipelineAnalyticsStationaryChanged`. */
|
|
15799
|
+
phase: _enum(["appeared", "departed"])
|
|
15800
|
+
}),
|
|
15801
|
+
object({
|
|
15802
|
+
kind: literal("interval"),
|
|
15803
|
+
minutes: number().int().min(1).max(1440)
|
|
15804
|
+
})
|
|
15754
15805
|
]);
|
|
15755
15806
|
/**
|
|
15756
15807
|
* One action step.
|
|
@@ -15770,28 +15821,47 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
15770
15821
|
* is called. The runner still receives a number and is untouched; the
|
|
15771
15822
|
* resolution is the recipe's job, not the runner's.
|
|
15772
15823
|
*/
|
|
15824
|
+
var AutomationWaitStepSchema = object({
|
|
15825
|
+
kind: literal("wait"),
|
|
15826
|
+
seconds: number().min(0).max(300)
|
|
15827
|
+
});
|
|
15828
|
+
var AutomationCapStepSchema = object({
|
|
15829
|
+
kind: literal("cap"),
|
|
15830
|
+
/**
|
|
15831
|
+
* One device, several same-family devices (locks / climate family / …),
|
|
15832
|
+
* or `{ $var }` for the device that triggered the run. An array is
|
|
15833
|
+
* fan-out at codegen — each id gets the same cap.method call.
|
|
15834
|
+
*/
|
|
15835
|
+
deviceId: union([
|
|
15836
|
+
number().int(),
|
|
15837
|
+
array(number().int()).min(1),
|
|
15838
|
+
object({ $var: string().min(1) })
|
|
15839
|
+
]),
|
|
15840
|
+
cap: string().min(1),
|
|
15841
|
+
method: string().min(1),
|
|
15842
|
+
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
15843
|
+
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
15844
|
+
* the expression leaf. */
|
|
15845
|
+
args: record(string(), unknown()).optional()
|
|
15846
|
+
});
|
|
15847
|
+
/**
|
|
15848
|
+
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
15849
|
+
* call back into an Action — so an Action can never reach itself (no cycles).
|
|
15850
|
+
*/
|
|
15851
|
+
var ActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepSchema]);
|
|
15773
15852
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
15853
|
+
AutomationWaitStepSchema,
|
|
15854
|
+
AutomationCapStepSchema,
|
|
15774
15855
|
object({
|
|
15775
|
-
kind: literal("
|
|
15776
|
-
|
|
15777
|
-
|
|
15778
|
-
|
|
15779
|
-
|
|
15780
|
-
|
|
15781
|
-
|
|
15782
|
-
|
|
15783
|
-
|
|
15784
|
-
*/
|
|
15785
|
-
deviceId: union([
|
|
15786
|
-
number().int(),
|
|
15787
|
-
array(number().int()).min(1),
|
|
15788
|
-
object({ $var: string().min(1) })
|
|
15789
|
-
]),
|
|
15790
|
-
cap: string().min(1),
|
|
15791
|
-
method: string().min(1),
|
|
15792
|
-
/** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
|
|
15793
|
-
* evaluate (§3.2.3). Anything beyond substitution is the expression leaf. */
|
|
15794
|
-
args: record(string(), unknown()).optional()
|
|
15856
|
+
kind: literal("action"),
|
|
15857
|
+
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
15858
|
+
actionId: string().min(1),
|
|
15859
|
+
/** Values for the action's declared variables; the others take their default. */
|
|
15860
|
+
variables: record(string(), union([
|
|
15861
|
+
string(),
|
|
15862
|
+
number(),
|
|
15863
|
+
boolean()
|
|
15864
|
+
])).optional()
|
|
15795
15865
|
}),
|
|
15796
15866
|
object({
|
|
15797
15867
|
kind: literal("code"),
|
|
@@ -15800,10 +15870,357 @@ var AutomationActionSchema = discriminatedUnion("kind", [
|
|
|
15800
15870
|
code: string().min(1).max(2e4)
|
|
15801
15871
|
})
|
|
15802
15872
|
]);
|
|
15873
|
+
/**
|
|
15874
|
+
* How a trigger that arrives while the automation is busy (or cooling down) is
|
|
15875
|
+
* handled. One of the automation's execution modes, never a property of its
|
|
15876
|
+
* actions. Absent means `single`.
|
|
15877
|
+
*
|
|
15878
|
+
* - `single` — drop the trigger while a run is in progress (traced + logged).
|
|
15879
|
+
* - `restart` — abort the run in progress (at its next step boundary), start fresh.
|
|
15880
|
+
* - `queued` — queue up to `max` triggers, drop the rest (traced).
|
|
15881
|
+
* - `parallel` — up to `max` runs at once, drop the rest (traced).
|
|
15882
|
+
* - `cooldown` — `single`, and no new run until `minutes` after the last run
|
|
15883
|
+
* STARTED; persisted across a restart. A manual trigger bypasses only this
|
|
15884
|
+
* wait, never the single/queued limits.
|
|
15885
|
+
*/
|
|
15886
|
+
var AutomationRunModeSchema = discriminatedUnion("mode", [
|
|
15887
|
+
object({ mode: literal("single") }),
|
|
15888
|
+
object({ mode: literal("restart") }),
|
|
15889
|
+
object({
|
|
15890
|
+
mode: literal("queued"),
|
|
15891
|
+
max: number().int().min(1).max(10)
|
|
15892
|
+
}),
|
|
15893
|
+
object({
|
|
15894
|
+
mode: literal("parallel"),
|
|
15895
|
+
max: number().int().min(1).max(10)
|
|
15896
|
+
}),
|
|
15897
|
+
object({
|
|
15898
|
+
mode: literal("cooldown"),
|
|
15899
|
+
minutes: number().int().min(1).max(1440)
|
|
15900
|
+
})
|
|
15901
|
+
]);
|
|
15803
15902
|
var AutomationRecipeSchema = object({
|
|
15804
15903
|
triggers: array(AutomationTriggerSchema),
|
|
15805
15904
|
conditions: AutomationConditionSchema.optional(),
|
|
15806
|
-
actions: array(AutomationActionSchema)
|
|
15905
|
+
actions: array(AutomationActionSchema),
|
|
15906
|
+
runMode: AutomationRunModeSchema.optional(),
|
|
15907
|
+
/** How many run traces the automation keeps (default {@link DEFAULT_TRACE_KEEP}). */
|
|
15908
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
15909
|
+
});
|
|
15910
|
+
new Set([
|
|
15911
|
+
{
|
|
15912
|
+
id: "person",
|
|
15913
|
+
name: "Person"
|
|
15914
|
+
},
|
|
15915
|
+
{
|
|
15916
|
+
id: "vehicle",
|
|
15917
|
+
name: "Vehicle"
|
|
15918
|
+
},
|
|
15919
|
+
{
|
|
15920
|
+
id: "animal",
|
|
15921
|
+
name: "Animal"
|
|
15922
|
+
},
|
|
15923
|
+
{
|
|
15924
|
+
id: "package",
|
|
15925
|
+
name: "Package"
|
|
15926
|
+
}
|
|
15927
|
+
].map((l) => l.id));
|
|
15928
|
+
var COCO_TO_MACRO = {
|
|
15929
|
+
mapping: {
|
|
15930
|
+
person: "person",
|
|
15931
|
+
bicycle: "vehicle",
|
|
15932
|
+
car: "vehicle",
|
|
15933
|
+
motorcycle: "vehicle",
|
|
15934
|
+
airplane: "vehicle",
|
|
15935
|
+
bus: "vehicle",
|
|
15936
|
+
train: "vehicle",
|
|
15937
|
+
truck: "vehicle",
|
|
15938
|
+
boat: "vehicle",
|
|
15939
|
+
bird: "animal",
|
|
15940
|
+
cat: "animal",
|
|
15941
|
+
dog: "animal",
|
|
15942
|
+
horse: "animal",
|
|
15943
|
+
sheep: "animal",
|
|
15944
|
+
cow: "animal",
|
|
15945
|
+
elephant: "animal",
|
|
15946
|
+
bear: "animal",
|
|
15947
|
+
zebra: "animal",
|
|
15948
|
+
giraffe: "animal",
|
|
15949
|
+
suitcase: "package",
|
|
15950
|
+
backpack: "package",
|
|
15951
|
+
handbag: "package"
|
|
15952
|
+
},
|
|
15953
|
+
preserveOriginal: false
|
|
15954
|
+
};
|
|
15955
|
+
new Set(Object.values(COCO_TO_MACRO.mapping));
|
|
15956
|
+
/**
|
|
15957
|
+
* Run traces — what an automation (or, later, an Action run) DID, node by node,
|
|
15958
|
+
* so the editor can paint every block green or red with its reason.
|
|
15959
|
+
*
|
|
15960
|
+
* A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
|
|
15961
|
+
* every condition node (containers and leaves, including the ones a
|
|
15962
|
+
* short-circuit never reached), the run-mode verdict and every action step —
|
|
15963
|
+
* each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
|
|
15964
|
+
* for an Action run). Skipped
|
|
15965
|
+
* evaluations are traced too, and identical consecutive skips collapse into a
|
|
15966
|
+
* repeat count so a trigger that fails every 5 minutes cannot flush real runs.
|
|
15967
|
+
*
|
|
15968
|
+
* {@link AutomationStepTraceSchema} is deliberately free of automation
|
|
15969
|
+
* vocabulary so an Action run records the same step shape.
|
|
15970
|
+
*/
|
|
15971
|
+
/** A value a trace may show: JSON primitives and short lists, nothing deeper. */
|
|
15972
|
+
var TraceValueSchema = union([
|
|
15973
|
+
string(),
|
|
15974
|
+
number(),
|
|
15975
|
+
boolean(),
|
|
15976
|
+
_null(),
|
|
15977
|
+
array(union([string(), number()]))
|
|
15978
|
+
]);
|
|
15979
|
+
var AutomationRunOutcomeSchema = _enum([
|
|
15980
|
+
"ran",
|
|
15981
|
+
"skipped-trigger",
|
|
15982
|
+
"skipped-conditions",
|
|
15983
|
+
"skipped-cooldown",
|
|
15984
|
+
"skipped-overlap",
|
|
15985
|
+
"failed",
|
|
15986
|
+
"aborted"
|
|
15987
|
+
]);
|
|
15988
|
+
/** `not-evaluated` = a short-circuit never reached the node. */
|
|
15989
|
+
var TraceNodeOutcomeSchema = _enum([
|
|
15990
|
+
"pass",
|
|
15991
|
+
"fail",
|
|
15992
|
+
"not-evaluated"
|
|
15993
|
+
]);
|
|
15994
|
+
var AutomationTriggerTraceSchema = object({
|
|
15995
|
+
kind: string().min(1),
|
|
15996
|
+
outcome: _enum(["pass", "fail"]),
|
|
15997
|
+
/** Why an event was rejected ("class person not in [dog]") or what fired. */
|
|
15998
|
+
reason: string(),
|
|
15999
|
+
/** deviceId, className, trackId, score … — only what the trigger exposes. */
|
|
16000
|
+
vars: record(string(), TraceValueSchema)
|
|
16001
|
+
});
|
|
16002
|
+
var AutomationConditionTraceNodeSchema = object({
|
|
16003
|
+
/** `conditions` for the root, `conditions.<i>` for its i-th child, … */
|
|
16004
|
+
path: string().min(1),
|
|
16005
|
+
kind: _enum([
|
|
16006
|
+
"all",
|
|
16007
|
+
"any",
|
|
16008
|
+
"not",
|
|
16009
|
+
"condition",
|
|
16010
|
+
"expression",
|
|
16011
|
+
"stationary-present"
|
|
16012
|
+
]),
|
|
16013
|
+
outcome: TraceNodeOutcomeSchema,
|
|
16014
|
+
reason: string(),
|
|
16015
|
+
deviceId: number().int().optional(),
|
|
16016
|
+
cap: string().optional(),
|
|
16017
|
+
fieldPath: string().optional(),
|
|
16018
|
+
operator: string().optional(),
|
|
16019
|
+
expected: TraceValueSchema.optional(),
|
|
16020
|
+
/** What the mirror held; `null` when it held nothing (unknown). */
|
|
16021
|
+
observed: TraceValueSchema.optional()
|
|
16022
|
+
});
|
|
16023
|
+
var AutomationRunVerdictSchema = object({
|
|
16024
|
+
mode: AutomationRunModeSchema,
|
|
16025
|
+
decision: _enum([
|
|
16026
|
+
"run",
|
|
16027
|
+
"queued",
|
|
16028
|
+
"restart",
|
|
16029
|
+
"drop",
|
|
16030
|
+
"cooldown",
|
|
16031
|
+
"bypass"
|
|
16032
|
+
]),
|
|
16033
|
+
reason: string()
|
|
16034
|
+
});
|
|
16035
|
+
/** One executed (or not-run) step — shared by automations and Action runs. */
|
|
16036
|
+
var AutomationStepTraceSchema = object({
|
|
16037
|
+
/** `actions.<i>` */
|
|
16038
|
+
path: string().min(1),
|
|
16039
|
+
kind: string().min(1),
|
|
16040
|
+
cap: string().optional(),
|
|
16041
|
+
method: string().optional(),
|
|
16042
|
+
deviceId: number().int().optional(),
|
|
16043
|
+
startedAt: number().optional(),
|
|
16044
|
+
endedAt: number().optional(),
|
|
16045
|
+
outcome: _enum([
|
|
16046
|
+
"ok",
|
|
16047
|
+
"error",
|
|
16048
|
+
"not-run"
|
|
16049
|
+
]),
|
|
16050
|
+
message: string().optional()
|
|
16051
|
+
});
|
|
16052
|
+
var AutomationRunTraceSchema = object({
|
|
16053
|
+
runId: string().min(1),
|
|
16054
|
+
startedAt: number(),
|
|
16055
|
+
endedAt: number(),
|
|
16056
|
+
trigger: AutomationTriggerTraceSchema,
|
|
16057
|
+
conditions: array(AutomationConditionTraceNodeSchema),
|
|
16058
|
+
verdict: AutomationRunVerdictSchema.optional(),
|
|
16059
|
+
steps: array(AutomationStepTraceSchema),
|
|
16060
|
+
outcome: AutomationRunOutcomeSchema,
|
|
16061
|
+
/** How many identical consecutive skips this trace stands for (>= 1). */
|
|
16062
|
+
repeat: number().int().min(1),
|
|
16063
|
+
/** When the latest of those repeats happened. */
|
|
16064
|
+
lastAt: number()
|
|
16065
|
+
});
|
|
16066
|
+
/**
|
|
16067
|
+
* What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
|
|
16068
|
+
* `action:<actionId>`): the cooldown stamp and the trace ring.
|
|
16069
|
+
*/
|
|
16070
|
+
var AutomationStateDocSchema = object({
|
|
16071
|
+
version: literal(1),
|
|
16072
|
+
lastRunStartedAt: number().nullable(),
|
|
16073
|
+
traces: array(AutomationRunTraceSchema)
|
|
16074
|
+
});
|
|
16075
|
+
/**
|
|
16076
|
+
* Actions — named, runnable things an operator (or an automation) can start,
|
|
16077
|
+
* declared as LIST ENTRIES, never as devices.
|
|
16078
|
+
*
|
|
16079
|
+
* An entry is either **internal** (a short list of cap/wait steps kept in the
|
|
16080
|
+
* hub's `actions` record kind) or declared by an addon through the
|
|
16081
|
+
* `action-source` collection (a Home Assistant script, a scene …). The one
|
|
16082
|
+
* surface the UI and automations talk to is the `actions` cap; it keeps no
|
|
16083
|
+
* catalog of its own (D3) — every `list` asks the providers live.
|
|
16084
|
+
*
|
|
16085
|
+
* This file is the data half: the entry schema, the variables an entry may
|
|
16086
|
+
* declare, and the pure resolution of the values a run was given. It holds no
|
|
16087
|
+
* runtime.
|
|
16088
|
+
*/
|
|
16089
|
+
/** What a variable's value is. `select` takes one of `options`. */
|
|
16090
|
+
var ActionVariableTypeSchema = _enum([
|
|
16091
|
+
"string",
|
|
16092
|
+
"number",
|
|
16093
|
+
"boolean",
|
|
16094
|
+
"select"
|
|
16095
|
+
]);
|
|
16096
|
+
var ACTION_VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
16097
|
+
var ActionVariableValueSchema = union([
|
|
16098
|
+
string(),
|
|
16099
|
+
number(),
|
|
16100
|
+
boolean()
|
|
16101
|
+
]);
|
|
16102
|
+
/**
|
|
16103
|
+
* One declared variable. Steps reference it as `{ $var: 'name' }` (the whole
|
|
16104
|
+
* value) or `{{vars.name}}` (inside a string) in their args.
|
|
16105
|
+
*/
|
|
16106
|
+
var ActionVariableSchema = object({
|
|
16107
|
+
name: string().regex(ACTION_VARIABLE_NAME_RE),
|
|
16108
|
+
label: string().min(1).max(120).optional(),
|
|
16109
|
+
type: ActionVariableTypeSchema,
|
|
16110
|
+
required: boolean().optional(),
|
|
16111
|
+
default: ActionVariableValueSchema.optional(),
|
|
16112
|
+
/** The allowed values of a `select`. */
|
|
16113
|
+
options: array(string().min(1)).min(1).optional()
|
|
16114
|
+
}).superRefine((v, ctx) => {
|
|
16115
|
+
if (v.type === "select" && v.options === void 0) ctx.addIssue({
|
|
16116
|
+
code: "custom",
|
|
16117
|
+
message: "a select variable needs options",
|
|
16118
|
+
path: ["options"]
|
|
16119
|
+
});
|
|
16120
|
+
if (v.default !== void 0 && variableValueError(v, v.default) !== null) ctx.addIssue({
|
|
16121
|
+
code: "custom",
|
|
16122
|
+
message: variableValueError(v, v.default) ?? "invalid default",
|
|
16123
|
+
path: ["default"]
|
|
16124
|
+
});
|
|
16125
|
+
});
|
|
16126
|
+
/** Why `value` is not a legal value for the variable, or null when it is. */
|
|
16127
|
+
function variableValueError(variable, value) {
|
|
16128
|
+
switch (variable.type) {
|
|
16129
|
+
case "string": return typeof value === "string" ? null : `variable "${variable.name}" must be a string`;
|
|
16130
|
+
case "number": return typeof value === "number" && Number.isFinite(value) ? null : `variable "${variable.name}" must be a number`;
|
|
16131
|
+
case "boolean": return typeof value === "boolean" ? null : `variable "${variable.name}" must be true or false`;
|
|
16132
|
+
case "select": return typeof value === "string" && (variable.options ?? []).includes(value) ? null : `variable "${variable.name}" must be one of ${(variable.options ?? []).join(", ")}`;
|
|
16133
|
+
}
|
|
16134
|
+
}
|
|
16135
|
+
var ActionSourceKindSchema = _enum(["internal", "addon"]);
|
|
16136
|
+
function isInternalActionId(actionId) {
|
|
16137
|
+
return actionId.startsWith("internal:") && actionId.length > 9;
|
|
16138
|
+
}
|
|
16139
|
+
/** The addon behind a `<addonId>:<localId>` id, or null for anything else (internal included). */
|
|
16140
|
+
function addonIdOfActionId(actionId) {
|
|
16141
|
+
if (isInternalActionId(actionId)) return null;
|
|
16142
|
+
const at = actionId.indexOf(":");
|
|
16143
|
+
return at > 0 && at < actionId.length - 1 ? actionId.slice(0, at) : null;
|
|
16144
|
+
}
|
|
16145
|
+
var ActionStatusSchema = object({
|
|
16146
|
+
isRunning: boolean(),
|
|
16147
|
+
/** Ms epoch the latest run STARTED; null when it never ran. */
|
|
16148
|
+
lastRunAt: number().nullable(),
|
|
16149
|
+
/** The latest run's failure; null on success or when it never ran. */
|
|
16150
|
+
lastError: string().nullable()
|
|
16151
|
+
});
|
|
16152
|
+
var ActionEntrySchema = object({
|
|
16153
|
+
/** `internal:<uuid>` or `<addonId>:<localId>`. */
|
|
16154
|
+
id: string().min(3),
|
|
16155
|
+
name: string().min(1).max(120),
|
|
16156
|
+
/** The addon that declared it; `core-blocks` for an internal one. */
|
|
16157
|
+
addonId: string().min(1),
|
|
16158
|
+
source: ActionSourceKindSchema,
|
|
16159
|
+
/** An addon-declared entry is edited where it was declared. */
|
|
16160
|
+
readOnly: boolean(),
|
|
16161
|
+
/** Internal only: cap and wait steps. No action-in-action, so no cycles. */
|
|
16162
|
+
steps: array(ActionStepSchema).min(1).max(50).optional(),
|
|
16163
|
+
variables: array(ActionVariableSchema).max(20).optional(),
|
|
16164
|
+
status: ActionStatusSchema
|
|
16165
|
+
}).superRefine((entry, ctx) => {
|
|
16166
|
+
if (entry.source === "internal") {
|
|
16167
|
+
if (!isInternalActionId(entry.id)) ctx.addIssue({
|
|
16168
|
+
code: "custom",
|
|
16169
|
+
message: "an internal action id is internal:<uuid>",
|
|
16170
|
+
path: ["id"]
|
|
16171
|
+
});
|
|
16172
|
+
return;
|
|
16173
|
+
}
|
|
16174
|
+
if (entry.steps !== void 0) ctx.addIssue({
|
|
16175
|
+
code: "custom",
|
|
16176
|
+
message: "only an internal action carries steps",
|
|
16177
|
+
path: ["steps"]
|
|
16178
|
+
});
|
|
16179
|
+
if (!entry.readOnly) ctx.addIssue({
|
|
16180
|
+
code: "custom",
|
|
16181
|
+
message: "an addon action is read-only here",
|
|
16182
|
+
path: ["readOnly"]
|
|
16183
|
+
});
|
|
16184
|
+
if (addonIdOfActionId(entry.id) === null) ctx.addIssue({
|
|
16185
|
+
code: "custom",
|
|
16186
|
+
message: "an addon action id is <addonId>:<localId>",
|
|
16187
|
+
path: ["id"]
|
|
16188
|
+
});
|
|
16189
|
+
});
|
|
16190
|
+
/** What an operator writes for an internal action. */
|
|
16191
|
+
var ActionInputSchema = object({
|
|
16192
|
+
name: string().min(1).max(120),
|
|
16193
|
+
steps: array(ActionStepSchema).min(1).max(50),
|
|
16194
|
+
variables: array(ActionVariableSchema).max(20).optional()
|
|
16195
|
+
});
|
|
16196
|
+
/** Who started a run. Absent = the operator pressed it. */
|
|
16197
|
+
var ActionRunOriginSchema = object({
|
|
16198
|
+
/** The automation block whose step started it. */
|
|
16199
|
+
blockId: string().min(1).optional() });
|
|
16200
|
+
/** `started` = the caller did not ask to wait. */
|
|
16201
|
+
var ActionRunOutcomeSchema = union([AutomationRunOutcomeSchema, literal("started")]);
|
|
16202
|
+
var ActionRunResultSchema = object({
|
|
16203
|
+
runId: string().min(1),
|
|
16204
|
+
outcome: ActionRunOutcomeSchema,
|
|
16205
|
+
/** Why it did not run, or what failed. */
|
|
16206
|
+
message: string().optional()
|
|
16207
|
+
});
|
|
16208
|
+
_enum([
|
|
16209
|
+
"not-found",
|
|
16210
|
+
"read-only",
|
|
16211
|
+
"invalid-variables",
|
|
16212
|
+
"invalid-steps",
|
|
16213
|
+
"not-linked",
|
|
16214
|
+
"busy"
|
|
16215
|
+
]);
|
|
16216
|
+
object({
|
|
16217
|
+
actionId: string(),
|
|
16218
|
+
runId: string(),
|
|
16219
|
+
isRunning: boolean(),
|
|
16220
|
+
/** Set when the run ended. */
|
|
16221
|
+
outcome: AutomationRunOutcomeSchema.optional(),
|
|
16222
|
+
lastRunAt: number().nullable(),
|
|
16223
|
+
lastError: string().nullable()
|
|
15807
16224
|
});
|
|
15808
16225
|
/**
|
|
15809
16226
|
* `addon-pages` — system-scoped singleton aggregator cap. Public-facing
|
|
@@ -18539,7 +18956,7 @@ var CompositionEventPlanSchema = object({
|
|
|
18539
18956
|
stateField: string(),
|
|
18540
18957
|
fieldKey: string()
|
|
18541
18958
|
});
|
|
18542
|
-
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.
|
|
18959
|
+
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.temperature`. */
|
|
18543
18960
|
var CompositionProblemSchema = object({
|
|
18544
18961
|
code: _enum([
|
|
18545
18962
|
"reserved-variant",
|
|
@@ -18858,7 +19275,7 @@ var GROUP_TEMPLATES = [
|
|
|
18858
19275
|
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
18859
19276
|
role: DeviceRole.TemperatureSensor,
|
|
18860
19277
|
outputCap: "temperature-sensor",
|
|
18861
|
-
outputField: "
|
|
19278
|
+
outputField: "temperature",
|
|
18862
19279
|
quantity: "temperature",
|
|
18863
19280
|
defaultAggregate: "mean",
|
|
18864
19281
|
empty: "null",
|
|
@@ -18869,7 +19286,7 @@ var GROUP_TEMPLATES = [
|
|
|
18869
19286
|
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18870
19287
|
role: DeviceRole.HumiditySensor,
|
|
18871
19288
|
outputCap: "humidity-sensor",
|
|
18872
|
-
outputField: "
|
|
19289
|
+
outputField: "humidity",
|
|
18873
19290
|
quantity: "humidity",
|
|
18874
19291
|
defaultAggregate: "mean",
|
|
18875
19292
|
empty: "null",
|
|
@@ -18880,7 +19297,7 @@ var GROUP_TEMPLATES = [
|
|
|
18880
19297
|
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
18881
19298
|
role: DeviceRole.PressureSensor,
|
|
18882
19299
|
outputCap: "pressure-sensor",
|
|
18883
|
-
outputField: "
|
|
19300
|
+
outputField: "pressure",
|
|
18884
19301
|
quantity: "pressure",
|
|
18885
19302
|
defaultAggregate: "mean",
|
|
18886
19303
|
empty: "null",
|
|
@@ -18891,7 +19308,7 @@ var GROUP_TEMPLATES = [
|
|
|
18891
19308
|
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
18892
19309
|
role: DeviceRole.AmbientLightSensor,
|
|
18893
19310
|
outputCap: "ambient-light-sensor",
|
|
18894
|
-
outputField: "
|
|
19311
|
+
outputField: "illuminance",
|
|
18895
19312
|
quantity: "illuminance",
|
|
18896
19313
|
defaultAggregate: "mean",
|
|
18897
19314
|
empty: "null",
|
|
@@ -18902,7 +19319,7 @@ var GROUP_TEMPLATES = [
|
|
|
18902
19319
|
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
18903
19320
|
role: DeviceRole.PowerSensor,
|
|
18904
19321
|
outputCap: "power-meter",
|
|
18905
|
-
outputField: "
|
|
19322
|
+
outputField: "power",
|
|
18906
19323
|
quantity: "power",
|
|
18907
19324
|
defaultAggregate: "sum",
|
|
18908
19325
|
empty: "omit",
|
|
@@ -18913,7 +19330,7 @@ var GROUP_TEMPLATES = [
|
|
|
18913
19330
|
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
18914
19331
|
role: DeviceRole.EnergySensor,
|
|
18915
19332
|
outputCap: "power-meter",
|
|
18916
|
-
outputField: "
|
|
19333
|
+
outputField: "energy",
|
|
18917
19334
|
quantity: "energy",
|
|
18918
19335
|
defaultAggregate: "sum",
|
|
18919
19336
|
empty: "omit",
|
|
@@ -18924,7 +19341,7 @@ var GROUP_TEMPLATES = [
|
|
|
18924
19341
|
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
18925
19342
|
role: DeviceRole.BatterySensor,
|
|
18926
19343
|
outputCap: "battery",
|
|
18927
|
-
outputField: "
|
|
19344
|
+
outputField: "level",
|
|
18928
19345
|
quantity: "percentage",
|
|
18929
19346
|
defaultAggregate: "mean",
|
|
18930
19347
|
empty: "null",
|
|
@@ -19502,7 +19919,18 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
|
|
|
19502
19919
|
kind: "mutation",
|
|
19503
19920
|
auth: "admin",
|
|
19504
19921
|
access: "view"
|
|
19505
|
-
})
|
|
19922
|
+
}), method(object({
|
|
19923
|
+
blockId: string().min(1),
|
|
19924
|
+
trace: AutomationRunTraceSchema.optional(),
|
|
19925
|
+
runStartedAt: number().optional(),
|
|
19926
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
19927
|
+
}), _void(), {
|
|
19928
|
+
kind: "mutation",
|
|
19929
|
+
auth: "admin"
|
|
19930
|
+
}), method(object({ blockId: string().min(1) }), AutomationStateDocSchema, { auth: "admin" }), method(object({ blockId: string().min(1) }), object({
|
|
19931
|
+
traces: array(AutomationRunTraceSchema),
|
|
19932
|
+
lastError: string().nullable()
|
|
19933
|
+
}), { auth: "admin" });
|
|
19506
19934
|
/**
|
|
19507
19935
|
* `custom-model-registry` — collection cap exposing operator-registered
|
|
19508
19936
|
* custom detection models. Each provider (today: `addon-model-studio`)
|
|
@@ -44991,51 +45419,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
|
|
|
44991
45419
|
kind: "mutation",
|
|
44992
45420
|
auth: "admin"
|
|
44993
45421
|
});
|
|
44994
|
-
new Set([
|
|
44995
|
-
{
|
|
44996
|
-
id: "person",
|
|
44997
|
-
name: "Person"
|
|
44998
|
-
},
|
|
44999
|
-
{
|
|
45000
|
-
id: "vehicle",
|
|
45001
|
-
name: "Vehicle"
|
|
45002
|
-
},
|
|
45003
|
-
{
|
|
45004
|
-
id: "animal",
|
|
45005
|
-
name: "Animal"
|
|
45006
|
-
},
|
|
45007
|
-
{
|
|
45008
|
-
id: "package",
|
|
45009
|
-
name: "Package"
|
|
45010
|
-
}
|
|
45011
|
-
].map((l) => l.id));
|
|
45012
|
-
var COCO_TO_MACRO = {
|
|
45013
|
-
mapping: {
|
|
45014
|
-
person: "person",
|
|
45015
|
-
bicycle: "vehicle",
|
|
45016
|
-
car: "vehicle",
|
|
45017
|
-
motorcycle: "vehicle",
|
|
45018
|
-
airplane: "vehicle",
|
|
45019
|
-
bus: "vehicle",
|
|
45020
|
-
train: "vehicle",
|
|
45021
|
-
truck: "vehicle",
|
|
45022
|
-
boat: "vehicle",
|
|
45023
|
-
bird: "animal",
|
|
45024
|
-
cat: "animal",
|
|
45025
|
-
dog: "animal",
|
|
45026
|
-
horse: "animal",
|
|
45027
|
-
sheep: "animal",
|
|
45028
|
-
cow: "animal",
|
|
45029
|
-
elephant: "animal",
|
|
45030
|
-
bear: "animal",
|
|
45031
|
-
zebra: "animal",
|
|
45032
|
-
giraffe: "animal",
|
|
45033
|
-
suitcase: "package",
|
|
45034
|
-
backpack: "package",
|
|
45035
|
-
handbag: "package"
|
|
45036
|
-
},
|
|
45037
|
-
preserveOriginal: false
|
|
45038
|
-
};
|
|
45039
45422
|
var AUDIO_MACRO_LABELS = [
|
|
45040
45423
|
{
|
|
45041
45424
|
id: "speech",
|
|
@@ -57602,9 +57985,9 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
57602
57985
|
*/
|
|
57603
57986
|
var AirQualitySensorStatusSchema = object({
|
|
57604
57987
|
/** Carbon dioxide concentration in ppm. */
|
|
57605
|
-
|
|
57988
|
+
co2: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
57606
57989
|
/** Total volatile organic compounds in ppb. */
|
|
57607
|
-
|
|
57990
|
+
voc: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
57608
57991
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
57609
57992
|
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
57610
57993
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
@@ -57637,12 +58020,12 @@ var airQualitySensorCapability = {
|
|
|
57637
58020
|
* History (D850): recorded series.
|
|
57638
58021
|
*/
|
|
57639
58022
|
history: { fields: {
|
|
57640
|
-
|
|
58023
|
+
co2: {
|
|
57641
58024
|
kind: "gauge",
|
|
57642
58025
|
unit: "ppm",
|
|
57643
58026
|
deadband: 5
|
|
57644
58027
|
},
|
|
57645
|
-
|
|
58028
|
+
voc: {
|
|
57646
58029
|
kind: "gauge",
|
|
57647
58030
|
unit: "ppb",
|
|
57648
58031
|
deadband: 5
|
|
@@ -57673,7 +58056,7 @@ var airQualitySensorCapability = {
|
|
|
57673
58056
|
*/
|
|
57674
58057
|
var AmbientLightSensorStatusSchema = object({
|
|
57675
58058
|
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
57676
|
-
|
|
58059
|
+
illuminance: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
57677
58060
|
precision: 0,
|
|
57678
58061
|
label: "Illuminance"
|
|
57679
58062
|
})),
|
|
@@ -57702,7 +58085,7 @@ var ambientLightSensorCapability = {
|
|
|
57702
58085
|
/**
|
|
57703
58086
|
* History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
|
|
57704
58087
|
*/
|
|
57705
|
-
history: { fields: {
|
|
58088
|
+
history: { fields: { illuminance: {
|
|
57706
58089
|
kind: "gauge",
|
|
57707
58090
|
unit: "lx",
|
|
57708
58091
|
deadbandPct: 10,
|
|
@@ -57841,6 +58224,84 @@ var audioMetricsCapability = {
|
|
|
57841
58224
|
*/
|
|
57842
58225
|
history: "none"
|
|
57843
58226
|
};
|
|
58227
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
58228
|
+
actionId: string().min(1),
|
|
58229
|
+
variables: record(string(), ActionVariableValueSchema).optional()
|
|
58230
|
+
}), _void(), {
|
|
58231
|
+
kind: "mutation",
|
|
58232
|
+
auth: "admin"
|
|
58233
|
+
}), method(object({ actionId: string().min(1) }), _void(), {
|
|
58234
|
+
kind: "mutation",
|
|
58235
|
+
auth: "admin"
|
|
58236
|
+
});
|
|
58237
|
+
/**
|
|
58238
|
+
* actions — the ONE surface for runnable actions, for the UI and for
|
|
58239
|
+
* automations. Provided by the core-blocks builtin on the hub.
|
|
58240
|
+
*
|
|
58241
|
+
* An action is a LIST ENTRY, not a device (D883): either internal (cap and wait
|
|
58242
|
+
* steps, kept in the hub's `actions` record kind) or declared by an addon over
|
|
58243
|
+
* `action-source`. `list` asks every `action-source` provider LIVE and overlays
|
|
58244
|
+
* the run status from the hub's `runs` ledger; there is no catalog here to
|
|
58245
|
+
* drift (D3).
|
|
58246
|
+
*
|
|
58247
|
+
* **Permissions follow the camera, as linked devices do.** An action is linked
|
|
58248
|
+
* to cameras by the operator (`setLinks`, D356: nothing links itself). A
|
|
58249
|
+
* non-admin may `get` / `run` an action only through a camera they may see that
|
|
58250
|
+
* links it: they name the camera (`deviceId`, a top-level field so the scope
|
|
58251
|
+
* gate sees it) and the provider refuses an action that camera does not link.
|
|
58252
|
+
* An admin, and an in-process caller (an automation block), may run any action.
|
|
58253
|
+
* Every refusal is typed (`[not-linked] …`) and logged.
|
|
58254
|
+
*
|
|
58255
|
+
* A second `run` of an action that is already running is REFUSED — traced and
|
|
58256
|
+
* logged — never queued.
|
|
58257
|
+
*/
|
|
58258
|
+
var ActionIdInput = object({ actionId: string().min(1) });
|
|
58259
|
+
var ActionLinksSchema = object({
|
|
58260
|
+
deviceId: number().int().nonnegative(),
|
|
58261
|
+
actionIds: array(string().min(1)).max(100)
|
|
58262
|
+
});
|
|
58263
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
58264
|
+
actionId: string().min(1),
|
|
58265
|
+
deviceId: number().int().nonnegative().optional()
|
|
58266
|
+
}), object({ action: ActionEntrySchema.nullable() }), {
|
|
58267
|
+
role: "viewer",
|
|
58268
|
+
auth: "protected",
|
|
58269
|
+
kind: "query",
|
|
58270
|
+
caller: "required"
|
|
58271
|
+
}), method(object({
|
|
58272
|
+
actionId: string().min(1),
|
|
58273
|
+
variables: record(string(), ActionVariableValueSchema).optional(),
|
|
58274
|
+
wait: boolean().optional(),
|
|
58275
|
+
origin: ActionRunOriginSchema.optional(),
|
|
58276
|
+
deviceId: number().int().nonnegative().optional()
|
|
58277
|
+
}), ActionRunResultSchema, {
|
|
58278
|
+
role: "viewer",
|
|
58279
|
+
auth: "protected",
|
|
58280
|
+
kind: "mutation",
|
|
58281
|
+
caller: "required"
|
|
58282
|
+
}), method(ActionIdInput, _void(), {
|
|
58283
|
+
kind: "mutation",
|
|
58284
|
+
auth: "admin"
|
|
58285
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
|
|
58286
|
+
kind: "mutation",
|
|
58287
|
+
auth: "admin"
|
|
58288
|
+
}), method(object({
|
|
58289
|
+
actionId: string().min(1),
|
|
58290
|
+
action: ActionInputSchema.partial()
|
|
58291
|
+
}), object({ action: ActionEntrySchema }), {
|
|
58292
|
+
kind: "mutation",
|
|
58293
|
+
auth: "admin"
|
|
58294
|
+
}), method(ActionIdInput, _void(), {
|
|
58295
|
+
kind: "mutation",
|
|
58296
|
+
auth: "admin"
|
|
58297
|
+
}), method(object({ deviceId: number().int().nonnegative() }), array(ActionEntrySchema), {
|
|
58298
|
+
role: "viewer",
|
|
58299
|
+
auth: "protected",
|
|
58300
|
+
kind: "query"
|
|
58301
|
+
}), method(object({ deviceId: number().int().nonnegative() }), ActionLinksSchema, { auth: "admin" }), method(ActionLinksSchema, ActionLinksSchema, {
|
|
58302
|
+
kind: "mutation",
|
|
58303
|
+
auth: "admin"
|
|
58304
|
+
});
|
|
57844
58305
|
/**
|
|
57845
58306
|
* Automation-control cap. Models HA `automation.*` entities on
|
|
57846
58307
|
* `DeviceType.Automation`. An automation is a trigger+condition+
|
|
@@ -57937,7 +58398,7 @@ var BatteryStatusSchema = object({
|
|
|
57937
58398
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
57938
58399
|
* declines to band a non-finite reading, which is the correct shape.
|
|
57939
58400
|
*/
|
|
57940
|
-
|
|
58401
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
57941
58402
|
/**
|
|
57942
58403
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
57943
58404
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -57947,7 +58408,7 @@ var BatteryStatusSchema = object({
|
|
|
57947
58408
|
* `'unknown'` is the absence of an answer: the provider has not read the
|
|
57948
58409
|
* power fields yet, or the firmware reported neither. Before it existed,
|
|
57949
58410
|
* two unreadable fields produced `'none'`, and a camera nobody had reached
|
|
57950
|
-
* was drawn "on battery alone" — the same D315 defect `
|
|
58411
|
+
* was drawn "on battery alone" — the same D315 defect `level` closed
|
|
57951
58412
|
* by going nullable. Consumers SKIP it (no charger state published, no
|
|
57952
58413
|
* glyph, no HomeKit ChargingState) rather than coerce it either way.
|
|
57953
58414
|
*/
|
|
@@ -57971,7 +58432,7 @@ var BatteryStatusSchema = object({
|
|
|
57971
58432
|
* that only report charge. A second reading on this cap, not a second
|
|
57972
58433
|
* `numeric-sensor` on the same device.
|
|
57973
58434
|
*/
|
|
57974
|
-
|
|
58435
|
+
voltage: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
57975
58436
|
/**
|
|
57976
58437
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
57977
58438
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -58005,7 +58466,7 @@ var BatteryStatusSchema = object({
|
|
|
58005
58466
|
/**
|
|
58006
58467
|
* True when the source is a BINARY low-battery indicator (HA
|
|
58007
58468
|
* `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
|
|
58008
|
-
* charge level — `
|
|
58469
|
+
* charge level — `level` is then a coarse stand-in (100 = normal,
|
|
58009
58470
|
* sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
|
|
58010
58471
|
* misleading exact percentage. Absent/false → genuine 0–100 % reading.
|
|
58011
58472
|
*/
|
|
@@ -58025,15 +58486,15 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
58025
58486
|
var batteryCustomize = {
|
|
58026
58487
|
version: 1,
|
|
58027
58488
|
targets: [{
|
|
58028
|
-
id: "
|
|
58489
|
+
id: "level",
|
|
58029
58490
|
cardinality: "scalar",
|
|
58030
58491
|
vocabulary: {
|
|
58031
58492
|
cap: "battery",
|
|
58032
|
-
stateField: "
|
|
58493
|
+
stateField: "level"
|
|
58033
58494
|
},
|
|
58034
58495
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
58035
58496
|
apply: "add",
|
|
58036
|
-
path: "
|
|
58497
|
+
path: "level",
|
|
58037
58498
|
sources: [{
|
|
58038
58499
|
kind: "field",
|
|
58039
58500
|
valueKinds: ["number", "string"],
|
|
@@ -58127,7 +58588,7 @@ onStatusChanged: { data: object({
|
|
|
58127
58588
|
schema: BatteryStatusSchema,
|
|
58128
58589
|
kind: "push",
|
|
58129
58590
|
empty: {
|
|
58130
|
-
|
|
58591
|
+
level: null,
|
|
58131
58592
|
charging: "unknown",
|
|
58132
58593
|
sleeping: false,
|
|
58133
58594
|
lastUpdated: 0
|
|
@@ -58154,11 +58615,11 @@ onStatusChanged: { data: object({
|
|
|
58154
58615
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
58155
58616
|
*/
|
|
58156
58617
|
history: { fields: {
|
|
58157
|
-
|
|
58618
|
+
level: {
|
|
58158
58619
|
kind: "gauge",
|
|
58159
58620
|
unit: "%"
|
|
58160
58621
|
},
|
|
58161
|
-
|
|
58622
|
+
voltage: {
|
|
58162
58623
|
kind: "gauge",
|
|
58163
58624
|
unit: "V"
|
|
58164
58625
|
}
|
|
@@ -58218,14 +58679,14 @@ var binaryCapability = {
|
|
|
58218
58679
|
* controls to this single-method surface.
|
|
58219
58680
|
*
|
|
58220
58681
|
* The cap is intentionally minimal: a single `setBrightness({deviceId,
|
|
58221
|
-
*
|
|
58682
|
+
* level})` mutation plus the auto-injected `getStatus`. Drivers
|
|
58222
58683
|
* that expose richer controls (color temperature, scenes, schedules)
|
|
58223
58684
|
* should surface those via the device's `getSettingsUISchema()`
|
|
58224
58685
|
* instead of bloating this cap.
|
|
58225
58686
|
*/
|
|
58226
58687
|
var BrightnessStatusSchema = object({
|
|
58227
58688
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
58228
|
-
|
|
58689
|
+
level: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
58229
58690
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
58230
58691
|
lastChangedAt: number()
|
|
58231
58692
|
});
|
|
@@ -58237,7 +58698,7 @@ var brightnessCapability = {
|
|
|
58237
58698
|
deviceTypes: [DeviceType.Light],
|
|
58238
58699
|
methods: { setBrightness: method(object({
|
|
58239
58700
|
deviceId: number().int().nonnegative(),
|
|
58240
|
-
|
|
58701
|
+
level: number().min(0).max(100)
|
|
58241
58702
|
}), _void(), {
|
|
58242
58703
|
kind: "mutation",
|
|
58243
58704
|
auth: "protected"
|
|
@@ -58250,7 +58711,7 @@ var brightnessCapability = {
|
|
|
58250
58711
|
*/
|
|
58251
58712
|
onBrightnessChanged: { data: object({
|
|
58252
58713
|
deviceId: number(),
|
|
58253
|
-
|
|
58714
|
+
level: number().min(0).max(100),
|
|
58254
58715
|
lastChangedAt: number()
|
|
58255
58716
|
}) } },
|
|
58256
58717
|
status: {
|
|
@@ -58273,7 +58734,7 @@ onBrightnessChanged: { data: object({
|
|
|
58273
58734
|
/**
|
|
58274
58735
|
* History (D850): recorded series. Actuator tier: level keeps every change.
|
|
58275
58736
|
*/
|
|
58276
|
-
history: { fields: {
|
|
58737
|
+
history: { fields: { level: {
|
|
58277
58738
|
kind: "gauge",
|
|
58278
58739
|
unit: "%",
|
|
58279
58740
|
minIntervalMs: 0
|
|
@@ -58870,11 +59331,11 @@ var ColorInputSchema = discriminatedUnion("mode", [
|
|
|
58870
59331
|
}),
|
|
58871
59332
|
object({
|
|
58872
59333
|
mode: literal("mired"),
|
|
58873
|
-
|
|
59334
|
+
colorTemperature: number().int().min(50).max(1e3)
|
|
58874
59335
|
})
|
|
58875
59336
|
]);
|
|
58876
59337
|
var ColorStatusSchema = object({
|
|
58877
|
-
/** Active color mode — which of `rgb` / `hsv` / `
|
|
59338
|
+
/** Active color mode — which of `rgb` / `hsv` / `colorTemperature` reflects
|
|
58878
59339
|
* the bulb's current state. */
|
|
58879
59340
|
mode: _enum([
|
|
58880
59341
|
"rgb",
|
|
@@ -58886,7 +59347,7 @@ var ColorStatusSchema = object({
|
|
|
58886
59347
|
/** Populated when `mode === 'hsv'`. */
|
|
58887
59348
|
hsv: HsvTripletSchema.optional(),
|
|
58888
59349
|
/** Populated when `mode === 'mired'`. */
|
|
58889
|
-
|
|
59350
|
+
colorTemperature: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
58890
59351
|
/** Ms epoch of the last operator-driven change. */
|
|
58891
59352
|
lastChangedAt: number()
|
|
58892
59353
|
});
|
|
@@ -58918,7 +59379,7 @@ onColorChanged: { data: object({
|
|
|
58918
59379
|
]),
|
|
58919
59380
|
rgb: RgbTripletSchema.optional(),
|
|
58920
59381
|
hsv: HsvTripletSchema.optional(),
|
|
58921
|
-
|
|
59382
|
+
colorTemperature: number().int().optional(),
|
|
58922
59383
|
lastChangedAt: number()
|
|
58923
59384
|
}) } },
|
|
58924
59385
|
status: {
|
|
@@ -59795,11 +60256,11 @@ var DishwasherStatusSchema = object({
|
|
|
59795
60256
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
59796
60257
|
availablePrograms: array(string()),
|
|
59797
60258
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
59798
|
-
|
|
60259
|
+
remaining: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59799
60260
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
59800
|
-
|
|
60261
|
+
delayedStart: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
59801
60262
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
59802
|
-
|
|
60263
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
59803
60264
|
/** True when the door is reported open; null when the door state is not known. */
|
|
59804
60265
|
doorOpen: boolean().nullable(),
|
|
59805
60266
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -60018,14 +60479,14 @@ var dishwasherCapability = {
|
|
|
60018
60479
|
runtimeState: DishwasherStatusSchema,
|
|
60019
60480
|
durability: "session",
|
|
60020
60481
|
history: { fields: {
|
|
60021
|
-
|
|
60482
|
+
progress: {
|
|
60022
60483
|
kind: "gauge",
|
|
60023
60484
|
unit: "%",
|
|
60024
60485
|
deadband: 2
|
|
60025
60486
|
},
|
|
60026
60487
|
state: { kind: "enum" },
|
|
60027
60488
|
operationState: { kind: "enum" },
|
|
60028
|
-
|
|
60489
|
+
remaining: {
|
|
60029
60490
|
kind: "gauge",
|
|
60030
60491
|
unit: "s",
|
|
60031
60492
|
minIntervalMs: 6e4
|
|
@@ -60616,7 +61077,7 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
60616
61077
|
var FanControlStatusSchema = object({
|
|
60617
61078
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
60618
61079
|
* speed surface (single-speed fan). */
|
|
60619
|
-
|
|
61080
|
+
speed: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60620
61081
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
60621
61082
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
60622
61083
|
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
@@ -60643,7 +61104,7 @@ var fanControlCapability = {
|
|
|
60643
61104
|
methods: {
|
|
60644
61105
|
setPercentage: method(object({
|
|
60645
61106
|
deviceId: number().int().nonnegative(),
|
|
60646
|
-
|
|
61107
|
+
speed: number().min(0).max(100)
|
|
60647
61108
|
}), _void(), {
|
|
60648
61109
|
kind: "mutation",
|
|
60649
61110
|
auth: "protected"
|
|
@@ -60676,7 +61137,7 @@ var fanControlCapability = {
|
|
|
60676
61137
|
},
|
|
60677
61138
|
/**
|
|
60678
61139
|
* Runtime-state slice — mirrored by the kernel. UI fan speed
|
|
60679
|
-
* sliders read `
|
|
61140
|
+
* sliders read `speed` for live updates.
|
|
60680
61141
|
*/
|
|
60681
61142
|
runtimeState: FanControlStatusSchema,
|
|
60682
61143
|
/**
|
|
@@ -60690,7 +61151,7 @@ var fanControlCapability = {
|
|
|
60690
61151
|
* History (D850): recorded series. Actuator tier: speed keeps every change.
|
|
60691
61152
|
*/
|
|
60692
61153
|
history: { fields: {
|
|
60693
|
-
|
|
61154
|
+
speed: {
|
|
60694
61155
|
kind: "gauge",
|
|
60695
61156
|
unit: "%",
|
|
60696
61157
|
minIntervalMs: 0
|
|
@@ -61135,7 +61596,7 @@ var humidifierCapability = {
|
|
|
61135
61596
|
*/
|
|
61136
61597
|
var HumiditySensorStatusSchema = object({
|
|
61137
61598
|
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
61138
|
-
|
|
61599
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
61139
61600
|
precision: 0,
|
|
61140
61601
|
label: "Humidity"
|
|
61141
61602
|
})),
|
|
@@ -61164,7 +61625,7 @@ var humiditySensorCapability = {
|
|
|
61164
61625
|
/**
|
|
61165
61626
|
* History (D850): recorded series.
|
|
61166
61627
|
*/
|
|
61167
|
-
history: { fields: {
|
|
61628
|
+
history: { fields: { humidity: {
|
|
61168
61629
|
kind: "gauge",
|
|
61169
61630
|
unit: "%",
|
|
61170
61631
|
deadband: .5
|
|
@@ -61804,7 +62265,7 @@ var LawnMowerControlStatusSchema = object({
|
|
|
61804
62265
|
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61805
62266
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
61806
62267
|
* task is active / progress is unavailable. */
|
|
61807
|
-
|
|
62268
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61808
62269
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
61809
62270
|
* or null when unknown. */
|
|
61810
62271
|
currentCode: number().nullable().meta(readingMeta("none")),
|
|
@@ -62304,7 +62765,7 @@ var lockControlCapability = {
|
|
|
62304
62765
|
volatileStateFields: ["lastChangedAt"]
|
|
62305
62766
|
};
|
|
62306
62767
|
/**
|
|
62307
|
-
* A monotonic total between resets (D944). Energy uses `power-meter.
|
|
62768
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.energy`
|
|
62308
62769
|
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
62309
62770
|
* `value` is the time integral in the source quantity's accumulated base
|
|
62310
62771
|
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
@@ -62398,10 +62859,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
62398
62859
|
currentMedia: MediaInfoSchema.nullable(),
|
|
62399
62860
|
/** Current playback position in ms. Null when not seekable or
|
|
62400
62861
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
62401
|
-
|
|
62862
|
+
position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62402
62863
|
/** Total duration of the current media in ms. Null when unknown
|
|
62403
62864
|
* (live stream) or nothing is playing. */
|
|
62404
|
-
|
|
62865
|
+
duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
62405
62866
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
62406
62867
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
62407
62868
|
shuffle: boolean().nullable(),
|
|
@@ -62440,7 +62901,7 @@ var mediaPlayerCapability = {
|
|
|
62440
62901
|
}),
|
|
62441
62902
|
seek: method(object({
|
|
62442
62903
|
deviceId: number().int().nonnegative(),
|
|
62443
|
-
|
|
62904
|
+
position: number().int().nonnegative()
|
|
62444
62905
|
}), _void(), {
|
|
62445
62906
|
kind: "mutation",
|
|
62446
62907
|
auth: "protected"
|
|
@@ -62512,7 +62973,7 @@ var mediaPlayerCapability = {
|
|
|
62512
62973
|
/**
|
|
62513
62974
|
* History (D850): volume (a level an operator or an automation sets; the
|
|
62514
62975
|
* default 10 s floor folds a slider drag into its end value) and mute.
|
|
62515
|
-
* `
|
|
62976
|
+
* `position` is not recorded: it moves continuously while playing.
|
|
62516
62977
|
*/
|
|
62517
62978
|
history: { fields: {
|
|
62518
62979
|
volumeLevel: {
|
|
@@ -63474,9 +63935,9 @@ var NetworkLinkStatusSchema = object({
|
|
|
63474
63935
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
63475
63936
|
* SKIP a null rather than coerce it.
|
|
63476
63937
|
*/
|
|
63477
|
-
|
|
63938
|
+
signal: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
63478
63939
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
63479
|
-
|
|
63940
|
+
rssi: number().optional().meta(readingMeta("signal-level")),
|
|
63480
63941
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
63481
63942
|
ssid: string().optional(),
|
|
63482
63943
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
@@ -63512,7 +63973,7 @@ onStatusChanged: { data: object({
|
|
|
63512
63973
|
kind: "push",
|
|
63513
63974
|
empty: {
|
|
63514
63975
|
type: "unknown",
|
|
63515
|
-
|
|
63976
|
+
signal: null,
|
|
63516
63977
|
lastUpdated: 0
|
|
63517
63978
|
}
|
|
63518
63979
|
},
|
|
@@ -63535,13 +63996,13 @@ onStatusChanged: { data: object({
|
|
|
63535
63996
|
* History (D850): recorded series.
|
|
63536
63997
|
*/
|
|
63537
63998
|
history: { fields: {
|
|
63538
|
-
|
|
63999
|
+
signal: {
|
|
63539
64000
|
kind: "gauge",
|
|
63540
64001
|
unit: "%",
|
|
63541
64002
|
deadband: 3,
|
|
63542
64003
|
minIntervalMs: 6e4
|
|
63543
64004
|
},
|
|
63544
|
-
|
|
64005
|
+
rssi: {
|
|
63545
64006
|
kind: "gauge",
|
|
63546
64007
|
unit: "dBm",
|
|
63547
64008
|
deadband: 2,
|
|
@@ -64286,10 +64747,20 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
64286
64747
|
]);
|
|
64287
64748
|
var gramsPortion = number().int().min(4).max(200);
|
|
64288
64749
|
var PetFeederStatusSchema = object({
|
|
64289
|
-
/** Food
|
|
64290
|
-
*
|
|
64291
|
-
* bowl
|
|
64750
|
+
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
64751
|
+
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
64752
|
+
* amount in the bowl is `bowlFood`. On dual-hopper models this is the
|
|
64753
|
+
* combined reading; per-hopper levels live in `food1`/`food2`. Null when
|
|
64754
|
+
* the device has not reported yet. */
|
|
64292
64755
|
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
64756
|
+
/** Food in the BOWL as the feeder reports it (`state.bowl`), in the
|
|
64757
|
+
* feeder's own units. Null when the model reports none. */
|
|
64758
|
+
bowlFood: number().nullable().meta(readingMeta("none")),
|
|
64759
|
+
/** True while the pet is eating (`state.eating`). */
|
|
64760
|
+
eating: boolean(),
|
|
64761
|
+
/** Whether `markFoodReplenished` does anything on this model. When false
|
|
64762
|
+
* the client must not offer it. */
|
|
64763
|
+
supportsMarkRefilled: boolean(),
|
|
64293
64764
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
64294
64765
|
* single-hopper models. */
|
|
64295
64766
|
food1: number().nullable().meta(readingMeta("none")),
|
|
@@ -64297,8 +64768,8 @@ var PetFeederStatusSchema = object({
|
|
|
64297
64768
|
* single-hopper models. */
|
|
64298
64769
|
food2: number().nullable().meta(readingMeta("none")),
|
|
64299
64770
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
64300
|
-
* (`device_class: problem`, on = low). True when the
|
|
64301
|
-
*
|
|
64771
|
+
* (`device_class: problem`, on = low). True when the tank reports empty,
|
|
64772
|
+
* or, on a dual-hopper model, when EITHER hopper is empty. */
|
|
64302
64773
|
lowFood: boolean(),
|
|
64303
64774
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
64304
64775
|
* device has no battery reading. */
|
|
@@ -64366,7 +64837,9 @@ var petFeederCapability = {
|
|
|
64366
64837
|
kind: "mutation",
|
|
64367
64838
|
auth: "protected"
|
|
64368
64839
|
}),
|
|
64369
|
-
/**
|
|
64840
|
+
/** Tell the PetKit cloud a hopper was refilled so it stops its low-food
|
|
64841
|
+
* reminders (D4H/D4S/D4SH only — see `supportsMarkRefilled`). It does not
|
|
64842
|
+
* change any sensor reading. */
|
|
64370
64843
|
markFoodReplenished: method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
64371
64844
|
kind: "mutation",
|
|
64372
64845
|
auth: "protected"
|
|
@@ -64439,6 +64912,7 @@ var petFeederCapability = {
|
|
|
64439
64912
|
*/
|
|
64440
64913
|
history: { fields: {
|
|
64441
64914
|
foodLevel: { kind: "gauge" },
|
|
64915
|
+
bowlFood: { kind: "gauge" },
|
|
64442
64916
|
food1: { kind: "gauge" },
|
|
64443
64917
|
food2: { kind: "gauge" },
|
|
64444
64918
|
batteryPower: {
|
|
@@ -64848,16 +65322,16 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
64848
65322
|
* in real-world devices.
|
|
64849
65323
|
*/
|
|
64850
65324
|
var PowerMeterStatusSchema = object({
|
|
64851
|
-
/** Instantaneous power draw
|
|
64852
|
-
|
|
65325
|
+
/** Instantaneous power draw (watts). */
|
|
65326
|
+
power: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
64853
65327
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
64854
|
-
|
|
64855
|
-
/** Voltage
|
|
64856
|
-
|
|
65328
|
+
energy: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
65329
|
+
/** Voltage (volts). */
|
|
65330
|
+
voltage: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
64857
65331
|
/** Current in amperes. */
|
|
64858
|
-
|
|
65332
|
+
current: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
64859
65333
|
/** Apparent power in volt-amperes. */
|
|
64860
|
-
|
|
65334
|
+
apparentPower: number().optional().meta(readingMeta("apparent-power")),
|
|
64861
65335
|
/** Power factor (0..1) if reported. */
|
|
64862
65336
|
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
64863
65337
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -64915,14 +65389,14 @@ function powerTarget(id, unit) {
|
|
|
64915
65389
|
advancedExpression: true
|
|
64916
65390
|
};
|
|
64917
65391
|
}
|
|
64918
|
-
/** "Power and energy" extension:
|
|
65392
|
+
/** "Power and energy" extension: power, energy, voltage and current from other devices (D951). */
|
|
64919
65393
|
var powerMeterCustomize = {
|
|
64920
65394
|
version: 1,
|
|
64921
65395
|
targets: [
|
|
64922
|
-
powerTarget("
|
|
64923
|
-
powerTarget("
|
|
64924
|
-
powerTarget("
|
|
64925
|
-
powerTarget("
|
|
65396
|
+
powerTarget("power", "W"),
|
|
65397
|
+
powerTarget("energy", "kWh"),
|
|
65398
|
+
powerTarget("voltage", "V"),
|
|
65399
|
+
powerTarget("current", "A")
|
|
64926
65400
|
]
|
|
64927
65401
|
};
|
|
64928
65402
|
var powerMeterCapability = {
|
|
@@ -64938,41 +65412,41 @@ var powerMeterCapability = {
|
|
|
64938
65412
|
},
|
|
64939
65413
|
runtimeState: PowerMeterStatusSchema,
|
|
64940
65414
|
/**
|
|
64941
|
-
* Runtime-state durability: **restored** — as `numeric-sensor`; `
|
|
65415
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`; `energy` is an accumulator whose restored value is the baseline.
|
|
64942
65416
|
*
|
|
64943
65417
|
* See `RuntimeStateDurability`. Enforced by
|
|
64944
65418
|
* `scripts/check-runtime-state-durability.ts`.
|
|
64945
65419
|
*/
|
|
64946
65420
|
durability: "restored",
|
|
64947
65421
|
/**
|
|
64948
|
-
* History (D850): recorded series. Gauges are floored at 30 s; `
|
|
65422
|
+
* History (D850): recorded series. Gauges are floored at 30 s; `energy` is the one monotonic meter (counter).
|
|
64949
65423
|
*/
|
|
64950
65424
|
history: { fields: {
|
|
64951
|
-
|
|
65425
|
+
power: {
|
|
64952
65426
|
kind: "gauge",
|
|
64953
65427
|
unit: "W",
|
|
64954
65428
|
deadband: 1,
|
|
64955
65429
|
minIntervalMs: 3e4
|
|
64956
65430
|
},
|
|
64957
|
-
|
|
65431
|
+
energy: {
|
|
64958
65432
|
kind: "counter",
|
|
64959
65433
|
unit: "kWh",
|
|
64960
65434
|
deadband: .01,
|
|
64961
65435
|
minIntervalMs: 6e4
|
|
64962
65436
|
},
|
|
64963
|
-
|
|
65437
|
+
voltage: {
|
|
64964
65438
|
kind: "gauge",
|
|
64965
65439
|
unit: "V",
|
|
64966
65440
|
deadband: 1,
|
|
64967
65441
|
minIntervalMs: 3e4
|
|
64968
65442
|
},
|
|
64969
|
-
|
|
65443
|
+
current: {
|
|
64970
65444
|
kind: "gauge",
|
|
64971
65445
|
unit: "A",
|
|
64972
65446
|
deadband: .05,
|
|
64973
65447
|
minIntervalMs: 3e4
|
|
64974
65448
|
},
|
|
64975
|
-
|
|
65449
|
+
apparentPower: {
|
|
64976
65450
|
kind: "gauge",
|
|
64977
65451
|
unit: "VA",
|
|
64978
65452
|
deadband: 1,
|
|
@@ -65022,9 +65496,6 @@ var PresenceStatusSchema = object({
|
|
|
65022
65496
|
location: string().nullable(),
|
|
65023
65497
|
/** GPS coordinates when available. Null otherwise. */
|
|
65024
65498
|
gps: GpsLocationSchema.nullable(),
|
|
65025
|
-
/** Optional battery level of the tracking device (0..100). Null
|
|
65026
|
-
* when not reported. */
|
|
65027
|
-
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65028
65499
|
/** Ms epoch when the slice was last updated. */
|
|
65029
65500
|
lastChangedAt: number()
|
|
65030
65501
|
});
|
|
@@ -65053,14 +65524,7 @@ var presenceCapability = {
|
|
|
65053
65524
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65054
65525
|
*/
|
|
65055
65526
|
durability: "restored",
|
|
65056
|
-
|
|
65057
|
-
* History (D850): recorded series.
|
|
65058
|
-
*/
|
|
65059
|
-
history: { fields: { batteryPercent: {
|
|
65060
|
-
kind: "gauge",
|
|
65061
|
-
unit: "%",
|
|
65062
|
-
deadband: 1
|
|
65063
|
-
} } },
|
|
65527
|
+
history: "none",
|
|
65064
65528
|
/** Clock fields: written, but excluded from the compare that decides
|
|
65065
65529
|
* whether persisting is worth a SQLite commit. */
|
|
65066
65530
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -65075,7 +65539,7 @@ var presenceCapability = {
|
|
|
65075
65539
|
*/
|
|
65076
65540
|
var PressureSensorStatusSchema = object({
|
|
65077
65541
|
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
65078
|
-
|
|
65542
|
+
pressure: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
65079
65543
|
/** Ms epoch when the slice was last updated. */
|
|
65080
65544
|
lastFetchedAt: number()
|
|
65081
65545
|
});
|
|
@@ -65101,7 +65565,7 @@ var pressureSensorCapability = {
|
|
|
65101
65565
|
/**
|
|
65102
65566
|
* History (D850): recorded series.
|
|
65103
65567
|
*/
|
|
65104
|
-
history: { fields: {
|
|
65568
|
+
history: { fields: { pressure: {
|
|
65105
65569
|
kind: "gauge",
|
|
65106
65570
|
unit: "hPa",
|
|
65107
65571
|
deadband: .1
|
|
@@ -68800,7 +69264,7 @@ var tamperCapability = {
|
|
|
68800
69264
|
*/
|
|
68801
69265
|
var TemperatureSensorStatusSchema = object({
|
|
68802
69266
|
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
68803
|
-
|
|
69267
|
+
temperature: number().nullable().meta(readingMeta("temperature", {
|
|
68804
69268
|
precision: 1,
|
|
68805
69269
|
label: "Temperature"
|
|
68806
69270
|
})),
|
|
@@ -68829,7 +69293,7 @@ var temperatureSensorCapability = {
|
|
|
68829
69293
|
/**
|
|
68830
69294
|
* History (D850): recorded series.
|
|
68831
69295
|
*/
|
|
68832
|
-
history: { fields: {
|
|
69296
|
+
history: { fields: { temperature: {
|
|
68833
69297
|
kind: "gauge",
|
|
68834
69298
|
unit: "°C",
|
|
68835
69299
|
deadband: .1
|
|
@@ -69126,7 +69590,7 @@ var VacuumControlStatusSchema = object({
|
|
|
69126
69590
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
69127
69591
|
availableFanSpeeds: array(string()),
|
|
69128
69592
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
69129
|
-
|
|
69593
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
69130
69594
|
/** Current error code (0 / null = no error). */
|
|
69131
69595
|
errorCode: number().nullable().meta(readingMeta("none")),
|
|
69132
69596
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
@@ -71163,7 +71627,7 @@ var BaseDevice = class {
|
|
|
71163
71627
|
* `device-local-state.ts`. Drivers access via:
|
|
71164
71628
|
*
|
|
71165
71629
|
* `this.state.battery.sleeping = true` // patches the battery slice
|
|
71166
|
-
* `const pct = this.state.battery.
|
|
71630
|
+
* `const pct = this.state.battery.level` // reads the battery slice
|
|
71167
71631
|
* `this.state.deviceStatus.online = true` // mirrors `markOnline(true)`
|
|
71168
71632
|
*
|
|
71169
71633
|
* Adding a new cap with `runtimeState:` automatically extends this
|
|
@@ -71203,7 +71667,7 @@ var BaseDevice = class {
|
|
|
71203
71667
|
* shape; drivers don't redeclare it, they just write through.
|
|
71204
71668
|
*
|
|
71205
71669
|
* Read: `this.runtimeState.getCapState('battery')` →
|
|
71206
|
-
* `{
|
|
71670
|
+
* `{level, charging, sleeping, lastUpdated}` for any
|
|
71207
71671
|
* provider that registers `batteryCapability`.
|
|
71208
71672
|
* Write: `this.runtimeState.setCapState('battery', { … })`.
|
|
71209
71673
|
*
|
|
@@ -72377,6 +72841,104 @@ Object.freeze({
|
|
|
72377
72841
|
access: "create",
|
|
72378
72842
|
role: "admin"
|
|
72379
72843
|
},
|
|
72844
|
+
"actions.create": {
|
|
72845
|
+
capName: "actions",
|
|
72846
|
+
capScope: "system",
|
|
72847
|
+
addonId: null,
|
|
72848
|
+
access: "create",
|
|
72849
|
+
role: "admin"
|
|
72850
|
+
},
|
|
72851
|
+
"actions.delete": {
|
|
72852
|
+
capName: "actions",
|
|
72853
|
+
capScope: "system",
|
|
72854
|
+
addonId: null,
|
|
72855
|
+
access: "delete",
|
|
72856
|
+
role: "admin"
|
|
72857
|
+
},
|
|
72858
|
+
"actions.get": {
|
|
72859
|
+
capName: "actions",
|
|
72860
|
+
capScope: "system",
|
|
72861
|
+
addonId: null,
|
|
72862
|
+
access: "view",
|
|
72863
|
+
role: "viewer"
|
|
72864
|
+
},
|
|
72865
|
+
"actions.getLinks": {
|
|
72866
|
+
capName: "actions",
|
|
72867
|
+
capScope: "system",
|
|
72868
|
+
addonId: null,
|
|
72869
|
+
access: "view",
|
|
72870
|
+
role: "admin"
|
|
72871
|
+
},
|
|
72872
|
+
"actions.getTraces": {
|
|
72873
|
+
capName: "actions",
|
|
72874
|
+
capScope: "system",
|
|
72875
|
+
addonId: null,
|
|
72876
|
+
access: "view",
|
|
72877
|
+
role: "admin"
|
|
72878
|
+
},
|
|
72879
|
+
"actions.list": {
|
|
72880
|
+
capName: "actions",
|
|
72881
|
+
capScope: "system",
|
|
72882
|
+
addonId: null,
|
|
72883
|
+
access: "view",
|
|
72884
|
+
role: "admin"
|
|
72885
|
+
},
|
|
72886
|
+
"actions.listForCamera": {
|
|
72887
|
+
capName: "actions",
|
|
72888
|
+
capScope: "system",
|
|
72889
|
+
addonId: null,
|
|
72890
|
+
access: "view",
|
|
72891
|
+
role: "viewer"
|
|
72892
|
+
},
|
|
72893
|
+
"actions.run": {
|
|
72894
|
+
capName: "actions",
|
|
72895
|
+
capScope: "system",
|
|
72896
|
+
addonId: null,
|
|
72897
|
+
access: "create",
|
|
72898
|
+
role: "viewer"
|
|
72899
|
+
},
|
|
72900
|
+
"actions.setLinks": {
|
|
72901
|
+
capName: "actions",
|
|
72902
|
+
capScope: "system",
|
|
72903
|
+
addonId: null,
|
|
72904
|
+
access: "create",
|
|
72905
|
+
role: "admin"
|
|
72906
|
+
},
|
|
72907
|
+
"actions.stop": {
|
|
72908
|
+
capName: "actions",
|
|
72909
|
+
capScope: "system",
|
|
72910
|
+
addonId: null,
|
|
72911
|
+
access: "create",
|
|
72912
|
+
role: "admin"
|
|
72913
|
+
},
|
|
72914
|
+
"actions.update": {
|
|
72915
|
+
capName: "actions",
|
|
72916
|
+
capScope: "system",
|
|
72917
|
+
addonId: null,
|
|
72918
|
+
access: "create",
|
|
72919
|
+
role: "admin"
|
|
72920
|
+
},
|
|
72921
|
+
"actionSource.listActions": {
|
|
72922
|
+
capName: "action-source",
|
|
72923
|
+
capScope: "system",
|
|
72924
|
+
addonId: null,
|
|
72925
|
+
access: "view",
|
|
72926
|
+
role: "admin"
|
|
72927
|
+
},
|
|
72928
|
+
"actionSource.runAction": {
|
|
72929
|
+
capName: "action-source",
|
|
72930
|
+
capScope: "system",
|
|
72931
|
+
addonId: null,
|
|
72932
|
+
access: "create",
|
|
72933
|
+
role: "admin"
|
|
72934
|
+
},
|
|
72935
|
+
"actionSource.stopAction": {
|
|
72936
|
+
capName: "action-source",
|
|
72937
|
+
capScope: "system",
|
|
72938
|
+
addonId: null,
|
|
72939
|
+
access: "create",
|
|
72940
|
+
role: "admin"
|
|
72941
|
+
},
|
|
72380
72942
|
"addonPages.listPages": {
|
|
72381
72943
|
capName: "addon-pages",
|
|
72382
72944
|
capScope: "system",
|
|
@@ -73658,6 +74220,13 @@ Object.freeze({
|
|
|
73658
74220
|
access: "view",
|
|
73659
74221
|
role: "admin"
|
|
73660
74222
|
},
|
|
74223
|
+
"coreBlocks.getAutomationRunState": {
|
|
74224
|
+
capName: "core-blocks",
|
|
74225
|
+
capScope: "system",
|
|
74226
|
+
addonId: null,
|
|
74227
|
+
access: "view",
|
|
74228
|
+
role: "admin"
|
|
74229
|
+
},
|
|
73661
74230
|
"coreBlocks.getBlockSettings": {
|
|
73662
74231
|
capName: "core-blocks",
|
|
73663
74232
|
capScope: "system",
|
|
@@ -73679,6 +74248,13 @@ Object.freeze({
|
|
|
73679
74248
|
access: "view",
|
|
73680
74249
|
role: "admin"
|
|
73681
74250
|
},
|
|
74251
|
+
"coreBlocks.getTraces": {
|
|
74252
|
+
capName: "core-blocks",
|
|
74253
|
+
capScope: "system",
|
|
74254
|
+
addonId: null,
|
|
74255
|
+
access: "view",
|
|
74256
|
+
role: "admin"
|
|
74257
|
+
},
|
|
73682
74258
|
"coreBlocks.getTypeDefs": {
|
|
73683
74259
|
capName: "core-blocks",
|
|
73684
74260
|
capScope: "system",
|
|
@@ -73714,6 +74290,13 @@ Object.freeze({
|
|
|
73714
74290
|
access: "create",
|
|
73715
74291
|
role: "admin"
|
|
73716
74292
|
},
|
|
74293
|
+
"coreBlocks.reportAutomationRun": {
|
|
74294
|
+
capName: "core-blocks",
|
|
74295
|
+
capScope: "system",
|
|
74296
|
+
addonId: null,
|
|
74297
|
+
access: "create",
|
|
74298
|
+
role: "admin"
|
|
74299
|
+
},
|
|
73717
74300
|
"coreBlocks.restart": {
|
|
73718
74301
|
capName: "core-blocks",
|
|
73719
74302
|
capScope: "system",
|
|
@@ -82287,7 +82870,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82287
82870
|
label: t("Full brightness", "Luminosità massima"),
|
|
82288
82871
|
phrase: t("Set {device} to full brightness", "Porta {device} alla massima luminosità"),
|
|
82289
82872
|
icon: "sun",
|
|
82290
|
-
args: {
|
|
82873
|
+
args: { level: 100 }
|
|
82291
82874
|
},
|
|
82292
82875
|
{
|
|
82293
82876
|
id: "brightness.half",
|
|
@@ -82295,7 +82878,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82295
82878
|
label: t("Half brightness", "Luminosità a metà"),
|
|
82296
82879
|
phrase: t("Dim {device} to half", "Abbassa {device} a metà luminosità"),
|
|
82297
82880
|
icon: "sun-dim",
|
|
82298
|
-
args: {
|
|
82881
|
+
args: { level: 50 }
|
|
82299
82882
|
},
|
|
82300
82883
|
{
|
|
82301
82884
|
id: "brightness.off",
|
|
@@ -82303,16 +82886,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82303
82886
|
label: t("Brightness off", "Luminosità a zero"),
|
|
82304
82887
|
phrase: t("Dim {device} to zero", "Abbassa {device} a zero"),
|
|
82305
82888
|
icon: "lightbulb-off",
|
|
82306
|
-
args: {
|
|
82889
|
+
args: { level: 0 }
|
|
82307
82890
|
},
|
|
82308
82891
|
{
|
|
82309
82892
|
id: "brightness.set",
|
|
82310
82893
|
method: "setBrightness",
|
|
82311
82894
|
label: t("Set brightness", "Imposta la luminosità"),
|
|
82312
|
-
phrase: t("Set the brightness of {device} to {
|
|
82895
|
+
phrase: t("Set the brightness of {device} to {level}", "Imposta la luminosità di {device} a {level}"),
|
|
82313
82896
|
icon: "sun-medium",
|
|
82314
82897
|
openArgs: [{
|
|
82315
|
-
key: "
|
|
82898
|
+
key: "level",
|
|
82316
82899
|
label: PERCENT,
|
|
82317
82900
|
offer: {
|
|
82318
82901
|
kind: "number",
|
|
@@ -82326,13 +82909,13 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82326
82909
|
],
|
|
82327
82910
|
state: [{
|
|
82328
82911
|
kind: "numeric",
|
|
82329
|
-
field: "
|
|
82912
|
+
field: "level",
|
|
82330
82913
|
quantity: t("the brightness", "la luminosità"),
|
|
82331
82914
|
label: t("Brightness", "Luminosità"),
|
|
82332
82915
|
unit: "%",
|
|
82333
82916
|
icon: "sun"
|
|
82334
82917
|
}],
|
|
82335
|
-
events: { onBrightnessChanged: { notOperatorFacing: "the `
|
|
82918
|
+
events: { onBrightnessChanged: { notOperatorFacing: "the `level` state trigger reads the same change" } }
|
|
82336
82919
|
},
|
|
82337
82920
|
color: {
|
|
82338
82921
|
scope: "device",
|
|
@@ -82346,7 +82929,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82346
82929
|
icon: "sun",
|
|
82347
82930
|
args: { color: {
|
|
82348
82931
|
mode: "mired",
|
|
82349
|
-
|
|
82932
|
+
colorTemperature: 370
|
|
82350
82933
|
} }
|
|
82351
82934
|
},
|
|
82352
82935
|
{
|
|
@@ -82357,7 +82940,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82357
82940
|
icon: "snowflake",
|
|
82358
82941
|
args: { color: {
|
|
82359
82942
|
mode: "mired",
|
|
82360
|
-
|
|
82943
|
+
colorTemperature: 200
|
|
82361
82944
|
} }
|
|
82362
82945
|
},
|
|
82363
82946
|
{
|
|
@@ -82971,7 +83554,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82971
83554
|
label: t("Fan off", "Ventilatore spento"),
|
|
82972
83555
|
phrase: t("Stop {device}", "Ferma {device}"),
|
|
82973
83556
|
icon: "power-off",
|
|
82974
|
-
args: {
|
|
83557
|
+
args: { speed: 0 }
|
|
82975
83558
|
},
|
|
82976
83559
|
{
|
|
82977
83560
|
id: "fan.full",
|
|
@@ -82979,16 +83562,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
82979
83562
|
label: t("Fan full", "Ventilatore al massimo"),
|
|
82980
83563
|
phrase: t("Run {device} at full speed", "Porta {device} alla massima velocità"),
|
|
82981
83564
|
icon: "fan",
|
|
82982
|
-
args: {
|
|
83565
|
+
args: { speed: 100 }
|
|
82983
83566
|
},
|
|
82984
83567
|
{
|
|
82985
83568
|
id: "fan.speed",
|
|
82986
83569
|
method: "setPercentage",
|
|
82987
83570
|
label: t("Set speed", "Imposta la velocità"),
|
|
82988
|
-
phrase: t("Set the speed of {device} to {
|
|
83571
|
+
phrase: t("Set the speed of {device} to {speed}", "Imposta la velocità di {device} al {speed}"),
|
|
82989
83572
|
icon: "fan",
|
|
82990
83573
|
openArgs: [{
|
|
82991
|
-
key: "
|
|
83574
|
+
key: "speed",
|
|
82992
83575
|
label: t("Speed", "Velocità"),
|
|
82993
83576
|
offer: {
|
|
82994
83577
|
kind: "number",
|
|
@@ -83050,7 +83633,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83050
83633
|
],
|
|
83051
83634
|
state: [{
|
|
83052
83635
|
kind: "numeric",
|
|
83053
|
-
field: "
|
|
83636
|
+
field: "speed",
|
|
83054
83637
|
quantity: t("the speed", "la velocità"),
|
|
83055
83638
|
label: t("Speed", "Velocità"),
|
|
83056
83639
|
unit: "%",
|
|
@@ -83848,7 +84431,7 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
83848
84431
|
},
|
|
83849
84432
|
{
|
|
83850
84433
|
kind: "numeric",
|
|
83851
|
-
field: "
|
|
84434
|
+
field: "progress",
|
|
83852
84435
|
quantity: t("the cycle progress", "l’avanzamento del lavaggio"),
|
|
83853
84436
|
label: t("Progress", "Avanzamento"),
|
|
83854
84437
|
unit: "%",
|
|
@@ -84206,10 +84789,10 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
84206
84789
|
id: "media.seek",
|
|
84207
84790
|
method: "seek",
|
|
84208
84791
|
label: t("Seek", "Vai al punto"),
|
|
84209
|
-
phrase: t("Move {device} to {
|
|
84792
|
+
phrase: t("Move {device} to {position}", "Porta {device} al punto {position}"),
|
|
84210
84793
|
icon: "fast-forward",
|
|
84211
84794
|
openArgs: [{
|
|
84212
|
-
key: "
|
|
84795
|
+
key: "position",
|
|
84213
84796
|
label: t("Position", "Posizione"),
|
|
84214
84797
|
offer: {
|
|
84215
84798
|
kind: "number",
|
|
@@ -85258,7 +85841,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85258
85841
|
state: [
|
|
85259
85842
|
{
|
|
85260
85843
|
kind: "numeric",
|
|
85261
|
-
field: "
|
|
85844
|
+
field: "co2",
|
|
85262
85845
|
quantity: t("the CO₂", "la CO₂"),
|
|
85263
85846
|
label: t("CO₂", "CO₂"),
|
|
85264
85847
|
unit: "ppm",
|
|
@@ -85266,7 +85849,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85266
85849
|
},
|
|
85267
85850
|
{
|
|
85268
85851
|
kind: "numeric",
|
|
85269
|
-
field: "
|
|
85852
|
+
field: "voc",
|
|
85270
85853
|
quantity: t("the VOC level", "il livello di COV"),
|
|
85271
85854
|
label: t("VOC", "COV"),
|
|
85272
85855
|
unit: "ppb",
|
|
@@ -85302,7 +85885,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85302
85885
|
noun: t("Light level", "Luminosità ambiente"),
|
|
85303
85886
|
state: [{
|
|
85304
85887
|
kind: "numeric",
|
|
85305
|
-
field: "
|
|
85888
|
+
field: "illuminance",
|
|
85306
85889
|
quantity: t("the light level", "la luminosità"),
|
|
85307
85890
|
label: t("Illuminance", "Illuminamento"),
|
|
85308
85891
|
unit: "lx",
|
|
@@ -85505,7 +86088,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85505
86088
|
noun: t("Humidity", "Umidità"),
|
|
85506
86089
|
state: [{
|
|
85507
86090
|
kind: "numeric",
|
|
85508
|
-
field: "
|
|
86091
|
+
field: "humidity",
|
|
85509
86092
|
quantity: t("the humidity", "l’umidità"),
|
|
85510
86093
|
label: t("Humidity", "Umidità"),
|
|
85511
86094
|
unit: "%",
|
|
@@ -85553,7 +86136,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85553
86136
|
state: [
|
|
85554
86137
|
{
|
|
85555
86138
|
kind: "numeric",
|
|
85556
|
-
field: "
|
|
86139
|
+
field: "power",
|
|
85557
86140
|
quantity: t("the power draw", "il consumo"),
|
|
85558
86141
|
label: t("Power", "Potenza"),
|
|
85559
86142
|
unit: "W",
|
|
@@ -85561,7 +86144,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85561
86144
|
},
|
|
85562
86145
|
{
|
|
85563
86146
|
kind: "numeric",
|
|
85564
|
-
field: "
|
|
86147
|
+
field: "energy",
|
|
85565
86148
|
quantity: t("the energy used", "l’energia consumata"),
|
|
85566
86149
|
label: t("Energy", "Energia"),
|
|
85567
86150
|
unit: "kWh",
|
|
@@ -85569,7 +86152,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85569
86152
|
},
|
|
85570
86153
|
{
|
|
85571
86154
|
kind: "numeric",
|
|
85572
|
-
field: "
|
|
86155
|
+
field: "voltage",
|
|
85573
86156
|
quantity: t("the voltage", "la tensione"),
|
|
85574
86157
|
label: t("Voltage", "Tensione"),
|
|
85575
86158
|
unit: "V",
|
|
@@ -85577,7 +86160,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85577
86160
|
},
|
|
85578
86161
|
{
|
|
85579
86162
|
kind: "numeric",
|
|
85580
|
-
field: "
|
|
86163
|
+
field: "current",
|
|
85581
86164
|
quantity: t("the current", "la corrente"),
|
|
85582
86165
|
label: t("Current", "Corrente"),
|
|
85583
86166
|
unit: "A",
|
|
@@ -85594,13 +86177,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85594
86177
|
label: t("Where", "Posizione"),
|
|
85595
86178
|
phrase: t("When {device} is at {value}", "Quando {device} è in {value}"),
|
|
85596
86179
|
icon: "map-pin"
|
|
85597
|
-
}, {
|
|
85598
|
-
kind: "numeric",
|
|
85599
|
-
field: "batteryPercent",
|
|
85600
|
-
quantity: t("the phone battery", "la batteria del telefono"),
|
|
85601
|
-
label: t("Battery", "Batteria"),
|
|
85602
|
-
unit: "%",
|
|
85603
|
-
icon: "battery"
|
|
85604
86180
|
}]
|
|
85605
86181
|
},
|
|
85606
86182
|
"pressure-sensor": {
|
|
@@ -85608,7 +86184,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85608
86184
|
noun: t("Pressure", "Pressione"),
|
|
85609
86185
|
state: [{
|
|
85610
86186
|
kind: "numeric",
|
|
85611
|
-
field: "
|
|
86187
|
+
field: "pressure",
|
|
85612
86188
|
quantity: t("the pressure", "la pressione"),
|
|
85613
86189
|
label: t("Pressure", "Pressione"),
|
|
85614
86190
|
unit: "hPa",
|
|
@@ -85644,7 +86220,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85644
86220
|
noun: t("Temperature", "Temperatura"),
|
|
85645
86221
|
state: [{
|
|
85646
86222
|
kind: "numeric",
|
|
85647
|
-
field: "
|
|
86223
|
+
field: "temperature",
|
|
85648
86224
|
quantity: t("the temperature", "la temperatura"),
|
|
85649
86225
|
label: t("Temperature", "Temperatura"),
|
|
85650
86226
|
unit: "°C",
|
|
@@ -85715,7 +86291,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85715
86291
|
state: [
|
|
85716
86292
|
{
|
|
85717
86293
|
kind: "numeric",
|
|
85718
|
-
field: "
|
|
86294
|
+
field: "level",
|
|
85719
86295
|
quantity: t("the battery level", "il livello della batteria"),
|
|
85720
86296
|
label: t("Battery", "Batteria"),
|
|
85721
86297
|
unit: "%",
|
|
@@ -85757,7 +86333,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85757
86333
|
icon: "battery-charging"
|
|
85758
86334
|
}
|
|
85759
86335
|
],
|
|
85760
|
-
events: { onStatusChanged: { notOperatorFacing: "the
|
|
86336
|
+
events: { onStatusChanged: { notOperatorFacing: "the level / sleeping / charging state triggers each read one field of this change" } },
|
|
85761
86337
|
extraEvents: [{
|
|
85762
86338
|
category: EventCategory.DeviceAwake,
|
|
85763
86339
|
label: t("Woke up", "Risvegliato"),
|
|
@@ -85775,7 +86351,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
85775
86351
|
noun: t("Network link", "Collegamento di rete"),
|
|
85776
86352
|
state: [{
|
|
85777
86353
|
kind: "numeric",
|
|
85778
|
-
field: "
|
|
86354
|
+
field: "signal",
|
|
85779
86355
|
quantity: t("the signal strength", "l’intensità del segnale"),
|
|
85780
86356
|
label: t("Signal", "Segnale"),
|
|
85781
86357
|
unit: "%",
|
|
@@ -85868,6 +86444,8 @@ var ML = "model and training machinery — no device action";
|
|
|
85868
86444
|
var INTERNAL = "internal plumbing between addons — never operator-facing";
|
|
85869
86445
|
/** Every system-scoped cap, with why it is not a device's vocabulary. */
|
|
85870
86446
|
var SYSTEM_CAP_VOCABULARY = {
|
|
86447
|
+
"action-source": system(INTERNAL),
|
|
86448
|
+
actions: system("declared actions — run from the Actions page and from the cameras that link them"),
|
|
85871
86449
|
"addon-pages": system(UI_PLUMBING),
|
|
85872
86450
|
"addon-pages-source": system(UI_PLUMBING),
|
|
85873
86451
|
"addon-routes": system(UI_PLUMBING),
|
|
@@ -86064,6 +86642,31 @@ Object.freeze({
|
|
|
86064
86642
|
form: "single",
|
|
86065
86643
|
optional: false
|
|
86066
86644
|
}],
|
|
86645
|
+
"actions.get": [{
|
|
86646
|
+
name: "deviceId",
|
|
86647
|
+
form: "single",
|
|
86648
|
+
optional: true
|
|
86649
|
+
}],
|
|
86650
|
+
"actions.getLinks": [{
|
|
86651
|
+
name: "deviceId",
|
|
86652
|
+
form: "single",
|
|
86653
|
+
optional: false
|
|
86654
|
+
}],
|
|
86655
|
+
"actions.listForCamera": [{
|
|
86656
|
+
name: "deviceId",
|
|
86657
|
+
form: "single",
|
|
86658
|
+
optional: false
|
|
86659
|
+
}],
|
|
86660
|
+
"actions.run": [{
|
|
86661
|
+
name: "deviceId",
|
|
86662
|
+
form: "single",
|
|
86663
|
+
optional: true
|
|
86664
|
+
}],
|
|
86665
|
+
"actions.setLinks": [{
|
|
86666
|
+
name: "deviceId",
|
|
86667
|
+
form: "single",
|
|
86668
|
+
optional: false
|
|
86669
|
+
}],
|
|
86067
86670
|
"addonSettings.getDeviceSettings": [{
|
|
86068
86671
|
name: "deviceId",
|
|
86069
86672
|
form: "single",
|
|
@@ -90287,6 +90890,7 @@ function bestLocationMatch(externalName, existing, threshold = .8) {
|
|
|
90287
90890
|
}
|
|
90288
90891
|
return best;
|
|
90289
90892
|
}
|
|
90893
|
+
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
90290
90894
|
var MB = 1024 * 1024;
|
|
90291
90895
|
1024 * MB, 3072 * MB;
|
|
90292
90896
|
//#endregion
|
|
@@ -115639,15 +116243,15 @@ var HmActuatorDevice = class extends HmChildDevice {
|
|
|
115639
116243
|
* keep that class a thin actuator-wiring layer.
|
|
115640
116244
|
*/
|
|
115641
116245
|
var COLD_TEMPERATURE = {
|
|
115642
|
-
|
|
116246
|
+
temperature: 0,
|
|
115643
116247
|
lastFetchedAt: 0
|
|
115644
116248
|
};
|
|
115645
116249
|
var COLD_HUMIDITY = {
|
|
115646
|
-
|
|
116250
|
+
humidity: 0,
|
|
115647
116251
|
lastFetchedAt: 0
|
|
115648
116252
|
};
|
|
115649
116253
|
var COLD_AMBIENT_LIGHT = {
|
|
115650
|
-
|
|
116254
|
+
illuminance: 0,
|
|
115651
116255
|
lastFetchedAt: 0
|
|
115652
116256
|
};
|
|
115653
116257
|
var COLD_POWER = { lastFetchedAt: 0 };
|
|
@@ -115739,15 +116343,15 @@ var HmSensorDevice = class extends HmChildDevice {
|
|
|
115739
116343
|
decodeSensorPush(parameter, value, now) {
|
|
115740
116344
|
if (typeof value !== "number") return;
|
|
115741
116345
|
if (this.caps.has("temperature-sensor") && parameter === "ACTUAL_TEMPERATURE") this.runtimeState.setCapState("temperature-sensor", {
|
|
115742
|
-
|
|
116346
|
+
temperature: value,
|
|
115743
116347
|
lastFetchedAt: now
|
|
115744
116348
|
});
|
|
115745
116349
|
if (this.caps.has("humidity-sensor") && parameter === "HUMIDITY") this.runtimeState.setCapState("humidity-sensor", {
|
|
115746
|
-
|
|
116350
|
+
humidity: value,
|
|
115747
116351
|
lastFetchedAt: now
|
|
115748
116352
|
});
|
|
115749
116353
|
if (this.caps.has("ambient-light-sensor") && parameter === "ILLUMINATION") this.runtimeState.setCapState("ambient-light-sensor", {
|
|
115750
|
-
|
|
116354
|
+
illuminance: Math.max(0, value),
|
|
115751
116355
|
lastFetchedAt: now
|
|
115752
116356
|
});
|
|
115753
116357
|
this.decodePowerPush(parameter, value, now);
|
|
@@ -115760,28 +116364,28 @@ var HmSensorDevice = class extends HmChildDevice {
|
|
|
115760
116364
|
case "POWER":
|
|
115761
116365
|
this.runtimeState.setCapState("power-meter", {
|
|
115762
116366
|
...prev,
|
|
115763
|
-
|
|
116367
|
+
power: value,
|
|
115764
116368
|
lastFetchedAt: now
|
|
115765
116369
|
});
|
|
115766
116370
|
return;
|
|
115767
116371
|
case "ENERGY_COUNTER":
|
|
115768
116372
|
this.runtimeState.setCapState("power-meter", {
|
|
115769
116373
|
...prev,
|
|
115770
|
-
|
|
116374
|
+
energy: value / 1e3,
|
|
115771
116375
|
lastFetchedAt: now
|
|
115772
116376
|
});
|
|
115773
116377
|
return;
|
|
115774
116378
|
case "VOLTAGE":
|
|
115775
116379
|
this.runtimeState.setCapState("power-meter", {
|
|
115776
116380
|
...prev,
|
|
115777
|
-
|
|
116381
|
+
voltage: value,
|
|
115778
116382
|
lastFetchedAt: now
|
|
115779
116383
|
});
|
|
115780
116384
|
return;
|
|
115781
116385
|
case "CURRENT":
|
|
115782
116386
|
this.runtimeState.setCapState("power-meter", {
|
|
115783
116387
|
...prev,
|
|
115784
|
-
|
|
116388
|
+
current: value / 1e3,
|
|
115785
116389
|
lastFetchedAt: now
|
|
115786
116390
|
});
|
|
115787
116391
|
return;
|
|
@@ -115879,7 +116483,7 @@ var COLD_BINARY = {
|
|
|
115879
116483
|
lastChangedAt: 0
|
|
115880
116484
|
};
|
|
115881
116485
|
var COLD_TEMP = {
|
|
115882
|
-
|
|
116486
|
+
temperature: 0,
|
|
115883
116487
|
lastFetchedAt: 0
|
|
115884
116488
|
};
|
|
115885
116489
|
/**
|
|
@@ -115943,7 +116547,7 @@ var HmDiagnosticDevice = class extends HmChildDevice {
|
|
|
115943
116547
|
if (stored === null) return;
|
|
115944
116548
|
if (this.capName === "temperature-sensor") {
|
|
115945
116549
|
this.runtimeState.setCapState("temperature-sensor", {
|
|
115946
|
-
|
|
116550
|
+
temperature: stored,
|
|
115947
116551
|
lastFetchedAt: now
|
|
115948
116552
|
});
|
|
115949
116553
|
return;
|