@camstack/addon-provider-reolink 1.2.212 → 1.2.213
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 +855 -251
- package/dist/addon.mjs +855 -251
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -36,7 +36,7 @@ let node_os = require("node:os");
|
|
|
36
36
|
node_os = require_chunk.__toESM(node_os, 1);
|
|
37
37
|
let node_fs = require("node:fs");
|
|
38
38
|
node_fs = require_chunk.__toESM(node_fs, 1);
|
|
39
|
-
//#region ../types/dist/event-category-
|
|
39
|
+
//#region ../types/dist/event-category-DmZDPDf_.mjs
|
|
40
40
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
41
41
|
EventCategory["SystemBoot"] = "system.boot";
|
|
42
42
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -663,7 +663,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
663
663
|
* (a track was promoted to a stationary-registry entry) or departs (the
|
|
664
664
|
* object moved / was removed). Telemetry (D8): lossy, drives a UI refresh of
|
|
665
665
|
* the dedicated "Stationary" section — never the live event feed. Payload:
|
|
666
|
-
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp }`.
|
|
666
|
+
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp, observedAt, zones }`.
|
|
667
667
|
*/
|
|
668
668
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
669
669
|
/**
|
|
@@ -801,6 +801,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
801
801
|
*/
|
|
802
802
|
EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
|
|
803
803
|
/**
|
|
804
|
+
* An action run started or ended. Emitted by the `actions` surface.
|
|
805
|
+
* Payload: `ActionRunChanged` (`{ actionId, runId, isRunning, outcome?, lastRunAt, lastError }`).
|
|
806
|
+
*/
|
|
807
|
+
EventCategory["ActionsRunChanged"] = "actions.onRunChanged";
|
|
808
|
+
/**
|
|
804
809
|
* Progress update from a running model conversion job.
|
|
805
810
|
* Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
|
|
806
811
|
* Emitted by `addon-model-studio` on the converting node.
|
|
@@ -5479,7 +5484,7 @@ var ZodIssueCode = {
|
|
|
5479
5484
|
var ZodFirstPartyTypeKind;
|
|
5480
5485
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5481
5486
|
//#endregion
|
|
5482
|
-
//#region ../types/dist/sleep
|
|
5487
|
+
//#region ../types/dist/sleep-Crlmu_tO.mjs
|
|
5483
5488
|
/**
|
|
5484
5489
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5485
5490
|
* window to float samples (D455).
|
|
@@ -8637,6 +8642,8 @@ Object.freeze({ "doorbell": "lastPressedAt" });
|
|
|
8637
8642
|
/** Every capability name, so addon code can check a name without the schema graph. */
|
|
8638
8643
|
var CAP_NAMES = Object.freeze([
|
|
8639
8644
|
"accessories",
|
|
8645
|
+
"action-source",
|
|
8646
|
+
"actions",
|
|
8640
8647
|
"addon-pages",
|
|
8641
8648
|
"addon-pages-source",
|
|
8642
8649
|
"addon-routes",
|
|
@@ -8825,11 +8832,11 @@ var CAP_NAMES = Object.freeze([
|
|
|
8825
8832
|
Object.freeze({
|
|
8826
8833
|
"air-quality-sensor": [
|
|
8827
8834
|
{
|
|
8828
|
-
"path": "
|
|
8835
|
+
"path": "co2",
|
|
8829
8836
|
"valueType": "number"
|
|
8830
8837
|
},
|
|
8831
8838
|
{
|
|
8832
|
-
"path": "
|
|
8839
|
+
"path": "voc",
|
|
8833
8840
|
"valueType": "number"
|
|
8834
8841
|
},
|
|
8835
8842
|
{
|
|
@@ -8879,7 +8886,7 @@ Object.freeze({
|
|
|
8879
8886
|
}
|
|
8880
8887
|
],
|
|
8881
8888
|
"ambient-light-sensor": [{
|
|
8882
|
-
"path": "
|
|
8889
|
+
"path": "illuminance",
|
|
8883
8890
|
"valueType": "number"
|
|
8884
8891
|
}],
|
|
8885
8892
|
"audio-metrics": [
|
|
@@ -8940,7 +8947,7 @@ Object.freeze({
|
|
|
8940
8947
|
],
|
|
8941
8948
|
"battery": [
|
|
8942
8949
|
{
|
|
8943
|
-
"path": "
|
|
8950
|
+
"path": "level",
|
|
8944
8951
|
"valueType": "number"
|
|
8945
8952
|
},
|
|
8946
8953
|
{
|
|
@@ -8962,7 +8969,7 @@ Object.freeze({
|
|
|
8962
8969
|
"valueType": "number"
|
|
8963
8970
|
},
|
|
8964
8971
|
{
|
|
8965
|
-
"path": "
|
|
8972
|
+
"path": "voltage",
|
|
8966
8973
|
"valueType": "number"
|
|
8967
8974
|
},
|
|
8968
8975
|
{
|
|
@@ -8983,7 +8990,7 @@ Object.freeze({
|
|
|
8983
8990
|
"valueType": "boolean"
|
|
8984
8991
|
}],
|
|
8985
8992
|
"brightness": [{
|
|
8986
|
-
"path": "
|
|
8993
|
+
"path": "level",
|
|
8987
8994
|
"valueType": "number"
|
|
8988
8995
|
}],
|
|
8989
8996
|
"broker": [{
|
|
@@ -9184,7 +9191,7 @@ Object.freeze({
|
|
|
9184
9191
|
"valueType": "number"
|
|
9185
9192
|
},
|
|
9186
9193
|
{
|
|
9187
|
-
"path": "
|
|
9194
|
+
"path": "colorTemperature",
|
|
9188
9195
|
"valueType": "number"
|
|
9189
9196
|
}
|
|
9190
9197
|
],
|
|
@@ -9363,15 +9370,15 @@ Object.freeze({
|
|
|
9363
9370
|
"valueType": "string"
|
|
9364
9371
|
},
|
|
9365
9372
|
{
|
|
9366
|
-
"path": "
|
|
9373
|
+
"path": "remaining",
|
|
9367
9374
|
"valueType": "number"
|
|
9368
9375
|
},
|
|
9369
9376
|
{
|
|
9370
|
-
"path": "
|
|
9377
|
+
"path": "delayedStart",
|
|
9371
9378
|
"valueType": "number"
|
|
9372
9379
|
},
|
|
9373
9380
|
{
|
|
9374
|
-
"path": "
|
|
9381
|
+
"path": "progress",
|
|
9375
9382
|
"valueType": "number"
|
|
9376
9383
|
},
|
|
9377
9384
|
{
|
|
@@ -9485,7 +9492,7 @@ Object.freeze({
|
|
|
9485
9492
|
],
|
|
9486
9493
|
"fan-control": [
|
|
9487
9494
|
{
|
|
9488
|
-
"path": "
|
|
9495
|
+
"path": "speed",
|
|
9489
9496
|
"valueType": "number"
|
|
9490
9497
|
},
|
|
9491
9498
|
{
|
|
@@ -9585,7 +9592,7 @@ Object.freeze({
|
|
|
9585
9592
|
}
|
|
9586
9593
|
],
|
|
9587
9594
|
"humidity-sensor": [{
|
|
9588
|
-
"path": "
|
|
9595
|
+
"path": "humidity",
|
|
9589
9596
|
"valueType": "number"
|
|
9590
9597
|
}],
|
|
9591
9598
|
"image": [{
|
|
@@ -9695,7 +9702,7 @@ Object.freeze({
|
|
|
9695
9702
|
"valueType": "number"
|
|
9696
9703
|
},
|
|
9697
9704
|
{
|
|
9698
|
-
"path": "
|
|
9705
|
+
"path": "progress",
|
|
9699
9706
|
"valueType": "number"
|
|
9700
9707
|
},
|
|
9701
9708
|
{
|
|
@@ -9774,11 +9781,11 @@ Object.freeze({
|
|
|
9774
9781
|
"valueType": "string"
|
|
9775
9782
|
},
|
|
9776
9783
|
{
|
|
9777
|
-
"path": "
|
|
9784
|
+
"path": "position",
|
|
9778
9785
|
"valueType": "number"
|
|
9779
9786
|
},
|
|
9780
9787
|
{
|
|
9781
|
-
"path": "
|
|
9788
|
+
"path": "duration",
|
|
9782
9789
|
"valueType": "number"
|
|
9783
9790
|
},
|
|
9784
9791
|
{
|
|
@@ -9880,11 +9887,11 @@ Object.freeze({
|
|
|
9880
9887
|
]
|
|
9881
9888
|
},
|
|
9882
9889
|
{
|
|
9883
|
-
"path": "
|
|
9890
|
+
"path": "signal",
|
|
9884
9891
|
"valueType": "number"
|
|
9885
9892
|
},
|
|
9886
9893
|
{
|
|
9887
|
-
"path": "
|
|
9894
|
+
"path": "rssi",
|
|
9888
9895
|
"valueType": "number"
|
|
9889
9896
|
},
|
|
9890
9897
|
{
|
|
@@ -9939,6 +9946,18 @@ Object.freeze({
|
|
|
9939
9946
|
"path": "foodLevel",
|
|
9940
9947
|
"valueType": "number"
|
|
9941
9948
|
},
|
|
9949
|
+
{
|
|
9950
|
+
"path": "bowlFood",
|
|
9951
|
+
"valueType": "number"
|
|
9952
|
+
},
|
|
9953
|
+
{
|
|
9954
|
+
"path": "eating",
|
|
9955
|
+
"valueType": "boolean"
|
|
9956
|
+
},
|
|
9957
|
+
{
|
|
9958
|
+
"path": "supportsMarkRefilled",
|
|
9959
|
+
"valueType": "boolean"
|
|
9960
|
+
},
|
|
9942
9961
|
{
|
|
9943
9962
|
"path": "food1",
|
|
9944
9963
|
"valueType": "number"
|
|
@@ -10003,23 +10022,23 @@ Object.freeze({
|
|
|
10003
10022
|
],
|
|
10004
10023
|
"power-meter": [
|
|
10005
10024
|
{
|
|
10006
|
-
"path": "
|
|
10025
|
+
"path": "power",
|
|
10007
10026
|
"valueType": "number"
|
|
10008
10027
|
},
|
|
10009
10028
|
{
|
|
10010
|
-
"path": "
|
|
10029
|
+
"path": "energy",
|
|
10011
10030
|
"valueType": "number"
|
|
10012
10031
|
},
|
|
10013
10032
|
{
|
|
10014
|
-
"path": "
|
|
10033
|
+
"path": "voltage",
|
|
10015
10034
|
"valueType": "number"
|
|
10016
10035
|
},
|
|
10017
10036
|
{
|
|
10018
|
-
"path": "
|
|
10037
|
+
"path": "current",
|
|
10019
10038
|
"valueType": "number"
|
|
10020
10039
|
},
|
|
10021
10040
|
{
|
|
10022
|
-
"path": "
|
|
10041
|
+
"path": "apparentPower",
|
|
10023
10042
|
"valueType": "number"
|
|
10024
10043
|
},
|
|
10025
10044
|
{
|
|
@@ -10047,14 +10066,10 @@ Object.freeze({
|
|
|
10047
10066
|
{
|
|
10048
10067
|
"path": "gps.accuracyMeters",
|
|
10049
10068
|
"valueType": "number"
|
|
10050
|
-
},
|
|
10051
|
-
{
|
|
10052
|
-
"path": "batteryPercent",
|
|
10053
|
-
"valueType": "number"
|
|
10054
10069
|
}
|
|
10055
10070
|
],
|
|
10056
10071
|
"pressure-sensor": [{
|
|
10057
|
-
"path": "
|
|
10072
|
+
"path": "pressure",
|
|
10058
10073
|
"valueType": "number"
|
|
10059
10074
|
}],
|
|
10060
10075
|
"privacy-mask": [{
|
|
@@ -10368,7 +10383,7 @@ Object.freeze({
|
|
|
10368
10383
|
"valueType": "boolean"
|
|
10369
10384
|
}],
|
|
10370
10385
|
"temperature-sensor": [{
|
|
10371
|
-
"path": "
|
|
10386
|
+
"path": "temperature",
|
|
10372
10387
|
"valueType": "number"
|
|
10373
10388
|
}],
|
|
10374
10389
|
"update": [
|
|
@@ -10416,7 +10431,7 @@ Object.freeze({
|
|
|
10416
10431
|
"valueType": "string"
|
|
10417
10432
|
},
|
|
10418
10433
|
{
|
|
10419
|
-
"path": "
|
|
10434
|
+
"path": "progress",
|
|
10420
10435
|
"valueType": "number"
|
|
10421
10436
|
},
|
|
10422
10437
|
{
|
|
@@ -10929,7 +10944,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10929
10944
|
return DeviceRole;
|
|
10930
10945
|
}({});
|
|
10931
10946
|
//#endregion
|
|
10932
|
-
//#region ../types/dist/composition-
|
|
10947
|
+
//#region ../types/dist/composition-CZImLpOI.mjs
|
|
10933
10948
|
/**
|
|
10934
10949
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10935
10950
|
*
|
|
@@ -16019,6 +16034,14 @@ var AutomationConditionLeafSchema = object({
|
|
|
16019
16034
|
array(union([string(), number()]))
|
|
16020
16035
|
])
|
|
16021
16036
|
});
|
|
16037
|
+
var AutomationConditionStationaryPresentSchema = object({
|
|
16038
|
+
kind: literal("stationary-present"),
|
|
16039
|
+
deviceId: number().int().nonnegative(),
|
|
16040
|
+
/** Class names; a macro class matches every raw class that maps to it. */
|
|
16041
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
16042
|
+
/** The parked object must be in at least one of these zones. */
|
|
16043
|
+
zones: array(string().min(1)).min(1).optional()
|
|
16044
|
+
});
|
|
16022
16045
|
/**
|
|
16023
16046
|
* The expression leaf, declared as a plain object rather than an intersection
|
|
16024
16047
|
* with {@link ExpressionSourceSchema}: a discriminated union has to be able to
|
|
@@ -16052,7 +16075,8 @@ var AutomationConditionSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
16052
16075
|
child: AutomationConditionSchema
|
|
16053
16076
|
}),
|
|
16054
16077
|
AutomationConditionLeafSchema,
|
|
16055
|
-
AutomationConditionExpressionSchema
|
|
16078
|
+
AutomationConditionExpressionSchema,
|
|
16079
|
+
AutomationConditionStationaryPresentSchema
|
|
16056
16080
|
]));
|
|
16057
16081
|
/**
|
|
16058
16082
|
* What starts a run.
|
|
@@ -16093,7 +16117,34 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
16093
16117
|
kind: literal("schedule"),
|
|
16094
16118
|
cron: string().min(1).max(120)
|
|
16095
16119
|
}),
|
|
16096
|
-
object({ kind: literal("manual") })
|
|
16120
|
+
object({ kind: literal("manual") }),
|
|
16121
|
+
object({
|
|
16122
|
+
kind: literal("detection"),
|
|
16123
|
+
/** Class names. A macro class (`animal`, `vehicle`, `person`, `package`)
|
|
16124
|
+
* matches every raw class that maps to it; any other name matches
|
|
16125
|
+
* exactly. */
|
|
16126
|
+
classes: array(string().min(1)).min(1),
|
|
16127
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
16128
|
+
/** The track must have visited at least one of these zones. */
|
|
16129
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
16130
|
+
/** Best-so-far confidence the track must reach. */
|
|
16131
|
+
minScore: number().min(0).max(1).optional()
|
|
16132
|
+
}),
|
|
16133
|
+
object({
|
|
16134
|
+
kind: literal("stationary"),
|
|
16135
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
16136
|
+
/** Class names; a macro class matches like the detection trigger. */
|
|
16137
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
16138
|
+
/** The parked object must be in at least one of these zones. */
|
|
16139
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
16140
|
+
/** `appeared`: it became parked. `departed`: the registry retired it.
|
|
16141
|
+
* The vocabulary of `PipelineAnalyticsStationaryChanged`. */
|
|
16142
|
+
phase: _enum(["appeared", "departed"])
|
|
16143
|
+
}),
|
|
16144
|
+
object({
|
|
16145
|
+
kind: literal("interval"),
|
|
16146
|
+
minutes: number().int().min(1).max(1440)
|
|
16147
|
+
})
|
|
16097
16148
|
]);
|
|
16098
16149
|
/**
|
|
16099
16150
|
* One action step.
|
|
@@ -16113,28 +16164,47 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
16113
16164
|
* is called. The runner still receives a number and is untouched; the
|
|
16114
16165
|
* resolution is the recipe's job, not the runner's.
|
|
16115
16166
|
*/
|
|
16167
|
+
var AutomationWaitStepSchema = object({
|
|
16168
|
+
kind: literal("wait"),
|
|
16169
|
+
seconds: number().min(0).max(300)
|
|
16170
|
+
});
|
|
16171
|
+
var AutomationCapStepSchema = object({
|
|
16172
|
+
kind: literal("cap"),
|
|
16173
|
+
/**
|
|
16174
|
+
* One device, several same-family devices (locks / climate family / …),
|
|
16175
|
+
* or `{ $var }` for the device that triggered the run. An array is
|
|
16176
|
+
* fan-out at codegen — each id gets the same cap.method call.
|
|
16177
|
+
*/
|
|
16178
|
+
deviceId: union([
|
|
16179
|
+
number().int(),
|
|
16180
|
+
array(number().int()).min(1),
|
|
16181
|
+
object({ $var: string().min(1) })
|
|
16182
|
+
]),
|
|
16183
|
+
cap: string().min(1),
|
|
16184
|
+
method: string().min(1),
|
|
16185
|
+
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
16186
|
+
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
16187
|
+
* the expression leaf. */
|
|
16188
|
+
args: record(string(), unknown()).optional()
|
|
16189
|
+
});
|
|
16190
|
+
/**
|
|
16191
|
+
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
16192
|
+
* call back into an Action — so an Action can never reach itself (no cycles).
|
|
16193
|
+
*/
|
|
16194
|
+
var ActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepSchema]);
|
|
16116
16195
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
16196
|
+
AutomationWaitStepSchema,
|
|
16197
|
+
AutomationCapStepSchema,
|
|
16117
16198
|
object({
|
|
16118
|
-
kind: literal("
|
|
16119
|
-
|
|
16120
|
-
|
|
16121
|
-
|
|
16122
|
-
|
|
16123
|
-
|
|
16124
|
-
|
|
16125
|
-
|
|
16126
|
-
|
|
16127
|
-
*/
|
|
16128
|
-
deviceId: union([
|
|
16129
|
-
number().int(),
|
|
16130
|
-
array(number().int()).min(1),
|
|
16131
|
-
object({ $var: string().min(1) })
|
|
16132
|
-
]),
|
|
16133
|
-
cap: string().min(1),
|
|
16134
|
-
method: string().min(1),
|
|
16135
|
-
/** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
|
|
16136
|
-
* evaluate (§3.2.3). Anything beyond substitution is the expression leaf. */
|
|
16137
|
-
args: record(string(), unknown()).optional()
|
|
16199
|
+
kind: literal("action"),
|
|
16200
|
+
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
16201
|
+
actionId: string().min(1),
|
|
16202
|
+
/** Values for the action's declared variables; the others take their default. */
|
|
16203
|
+
variables: record(string(), union([
|
|
16204
|
+
string(),
|
|
16205
|
+
number(),
|
|
16206
|
+
boolean()
|
|
16207
|
+
])).optional()
|
|
16138
16208
|
}),
|
|
16139
16209
|
object({
|
|
16140
16210
|
kind: literal("code"),
|
|
@@ -16143,10 +16213,357 @@ var AutomationActionSchema = discriminatedUnion("kind", [
|
|
|
16143
16213
|
code: string().min(1).max(2e4)
|
|
16144
16214
|
})
|
|
16145
16215
|
]);
|
|
16216
|
+
/**
|
|
16217
|
+
* How a trigger that arrives while the automation is busy (or cooling down) is
|
|
16218
|
+
* handled. One of the automation's execution modes, never a property of its
|
|
16219
|
+
* actions. Absent means `single`.
|
|
16220
|
+
*
|
|
16221
|
+
* - `single` — drop the trigger while a run is in progress (traced + logged).
|
|
16222
|
+
* - `restart` — abort the run in progress (at its next step boundary), start fresh.
|
|
16223
|
+
* - `queued` — queue up to `max` triggers, drop the rest (traced).
|
|
16224
|
+
* - `parallel` — up to `max` runs at once, drop the rest (traced).
|
|
16225
|
+
* - `cooldown` — `single`, and no new run until `minutes` after the last run
|
|
16226
|
+
* STARTED; persisted across a restart. A manual trigger bypasses only this
|
|
16227
|
+
* wait, never the single/queued limits.
|
|
16228
|
+
*/
|
|
16229
|
+
var AutomationRunModeSchema = discriminatedUnion("mode", [
|
|
16230
|
+
object({ mode: literal("single") }),
|
|
16231
|
+
object({ mode: literal("restart") }),
|
|
16232
|
+
object({
|
|
16233
|
+
mode: literal("queued"),
|
|
16234
|
+
max: number().int().min(1).max(10)
|
|
16235
|
+
}),
|
|
16236
|
+
object({
|
|
16237
|
+
mode: literal("parallel"),
|
|
16238
|
+
max: number().int().min(1).max(10)
|
|
16239
|
+
}),
|
|
16240
|
+
object({
|
|
16241
|
+
mode: literal("cooldown"),
|
|
16242
|
+
minutes: number().int().min(1).max(1440)
|
|
16243
|
+
})
|
|
16244
|
+
]);
|
|
16146
16245
|
var AutomationRecipeSchema = object({
|
|
16147
16246
|
triggers: array(AutomationTriggerSchema),
|
|
16148
16247
|
conditions: AutomationConditionSchema.optional(),
|
|
16149
|
-
actions: array(AutomationActionSchema)
|
|
16248
|
+
actions: array(AutomationActionSchema),
|
|
16249
|
+
runMode: AutomationRunModeSchema.optional(),
|
|
16250
|
+
/** How many run traces the automation keeps (default {@link DEFAULT_TRACE_KEEP}). */
|
|
16251
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
16252
|
+
});
|
|
16253
|
+
new Set([
|
|
16254
|
+
{
|
|
16255
|
+
id: "person",
|
|
16256
|
+
name: "Person"
|
|
16257
|
+
},
|
|
16258
|
+
{
|
|
16259
|
+
id: "vehicle",
|
|
16260
|
+
name: "Vehicle"
|
|
16261
|
+
},
|
|
16262
|
+
{
|
|
16263
|
+
id: "animal",
|
|
16264
|
+
name: "Animal"
|
|
16265
|
+
},
|
|
16266
|
+
{
|
|
16267
|
+
id: "package",
|
|
16268
|
+
name: "Package"
|
|
16269
|
+
}
|
|
16270
|
+
].map((l) => l.id));
|
|
16271
|
+
var COCO_TO_MACRO = {
|
|
16272
|
+
mapping: {
|
|
16273
|
+
person: "person",
|
|
16274
|
+
bicycle: "vehicle",
|
|
16275
|
+
car: "vehicle",
|
|
16276
|
+
motorcycle: "vehicle",
|
|
16277
|
+
airplane: "vehicle",
|
|
16278
|
+
bus: "vehicle",
|
|
16279
|
+
train: "vehicle",
|
|
16280
|
+
truck: "vehicle",
|
|
16281
|
+
boat: "vehicle",
|
|
16282
|
+
bird: "animal",
|
|
16283
|
+
cat: "animal",
|
|
16284
|
+
dog: "animal",
|
|
16285
|
+
horse: "animal",
|
|
16286
|
+
sheep: "animal",
|
|
16287
|
+
cow: "animal",
|
|
16288
|
+
elephant: "animal",
|
|
16289
|
+
bear: "animal",
|
|
16290
|
+
zebra: "animal",
|
|
16291
|
+
giraffe: "animal",
|
|
16292
|
+
suitcase: "package",
|
|
16293
|
+
backpack: "package",
|
|
16294
|
+
handbag: "package"
|
|
16295
|
+
},
|
|
16296
|
+
preserveOriginal: false
|
|
16297
|
+
};
|
|
16298
|
+
new Set(Object.values(COCO_TO_MACRO.mapping));
|
|
16299
|
+
/**
|
|
16300
|
+
* Run traces — what an automation (or, later, an Action run) DID, node by node,
|
|
16301
|
+
* so the editor can paint every block green or red with its reason.
|
|
16302
|
+
*
|
|
16303
|
+
* A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
|
|
16304
|
+
* every condition node (containers and leaves, including the ones a
|
|
16305
|
+
* short-circuit never reached), the run-mode verdict and every action step —
|
|
16306
|
+
* each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
|
|
16307
|
+
* for an Action run). Skipped
|
|
16308
|
+
* evaluations are traced too, and identical consecutive skips collapse into a
|
|
16309
|
+
* repeat count so a trigger that fails every 5 minutes cannot flush real runs.
|
|
16310
|
+
*
|
|
16311
|
+
* {@link AutomationStepTraceSchema} is deliberately free of automation
|
|
16312
|
+
* vocabulary so an Action run records the same step shape.
|
|
16313
|
+
*/
|
|
16314
|
+
/** A value a trace may show: JSON primitives and short lists, nothing deeper. */
|
|
16315
|
+
var TraceValueSchema = union([
|
|
16316
|
+
string(),
|
|
16317
|
+
number(),
|
|
16318
|
+
boolean(),
|
|
16319
|
+
_null(),
|
|
16320
|
+
array(union([string(), number()]))
|
|
16321
|
+
]);
|
|
16322
|
+
var AutomationRunOutcomeSchema = _enum([
|
|
16323
|
+
"ran",
|
|
16324
|
+
"skipped-trigger",
|
|
16325
|
+
"skipped-conditions",
|
|
16326
|
+
"skipped-cooldown",
|
|
16327
|
+
"skipped-overlap",
|
|
16328
|
+
"failed",
|
|
16329
|
+
"aborted"
|
|
16330
|
+
]);
|
|
16331
|
+
/** `not-evaluated` = a short-circuit never reached the node. */
|
|
16332
|
+
var TraceNodeOutcomeSchema = _enum([
|
|
16333
|
+
"pass",
|
|
16334
|
+
"fail",
|
|
16335
|
+
"not-evaluated"
|
|
16336
|
+
]);
|
|
16337
|
+
var AutomationTriggerTraceSchema = object({
|
|
16338
|
+
kind: string().min(1),
|
|
16339
|
+
outcome: _enum(["pass", "fail"]),
|
|
16340
|
+
/** Why an event was rejected ("class person not in [dog]") or what fired. */
|
|
16341
|
+
reason: string(),
|
|
16342
|
+
/** deviceId, className, trackId, score … — only what the trigger exposes. */
|
|
16343
|
+
vars: record(string(), TraceValueSchema)
|
|
16344
|
+
});
|
|
16345
|
+
var AutomationConditionTraceNodeSchema = object({
|
|
16346
|
+
/** `conditions` for the root, `conditions.<i>` for its i-th child, … */
|
|
16347
|
+
path: string().min(1),
|
|
16348
|
+
kind: _enum([
|
|
16349
|
+
"all",
|
|
16350
|
+
"any",
|
|
16351
|
+
"not",
|
|
16352
|
+
"condition",
|
|
16353
|
+
"expression",
|
|
16354
|
+
"stationary-present"
|
|
16355
|
+
]),
|
|
16356
|
+
outcome: TraceNodeOutcomeSchema,
|
|
16357
|
+
reason: string(),
|
|
16358
|
+
deviceId: number().int().optional(),
|
|
16359
|
+
cap: string().optional(),
|
|
16360
|
+
fieldPath: string().optional(),
|
|
16361
|
+
operator: string().optional(),
|
|
16362
|
+
expected: TraceValueSchema.optional(),
|
|
16363
|
+
/** What the mirror held; `null` when it held nothing (unknown). */
|
|
16364
|
+
observed: TraceValueSchema.optional()
|
|
16365
|
+
});
|
|
16366
|
+
var AutomationRunVerdictSchema = object({
|
|
16367
|
+
mode: AutomationRunModeSchema,
|
|
16368
|
+
decision: _enum([
|
|
16369
|
+
"run",
|
|
16370
|
+
"queued",
|
|
16371
|
+
"restart",
|
|
16372
|
+
"drop",
|
|
16373
|
+
"cooldown",
|
|
16374
|
+
"bypass"
|
|
16375
|
+
]),
|
|
16376
|
+
reason: string()
|
|
16377
|
+
});
|
|
16378
|
+
/** One executed (or not-run) step — shared by automations and Action runs. */
|
|
16379
|
+
var AutomationStepTraceSchema = object({
|
|
16380
|
+
/** `actions.<i>` */
|
|
16381
|
+
path: string().min(1),
|
|
16382
|
+
kind: string().min(1),
|
|
16383
|
+
cap: string().optional(),
|
|
16384
|
+
method: string().optional(),
|
|
16385
|
+
deviceId: number().int().optional(),
|
|
16386
|
+
startedAt: number().optional(),
|
|
16387
|
+
endedAt: number().optional(),
|
|
16388
|
+
outcome: _enum([
|
|
16389
|
+
"ok",
|
|
16390
|
+
"error",
|
|
16391
|
+
"not-run"
|
|
16392
|
+
]),
|
|
16393
|
+
message: string().optional()
|
|
16394
|
+
});
|
|
16395
|
+
var AutomationRunTraceSchema = object({
|
|
16396
|
+
runId: string().min(1),
|
|
16397
|
+
startedAt: number(),
|
|
16398
|
+
endedAt: number(),
|
|
16399
|
+
trigger: AutomationTriggerTraceSchema,
|
|
16400
|
+
conditions: array(AutomationConditionTraceNodeSchema),
|
|
16401
|
+
verdict: AutomationRunVerdictSchema.optional(),
|
|
16402
|
+
steps: array(AutomationStepTraceSchema),
|
|
16403
|
+
outcome: AutomationRunOutcomeSchema,
|
|
16404
|
+
/** How many identical consecutive skips this trace stands for (>= 1). */
|
|
16405
|
+
repeat: number().int().min(1),
|
|
16406
|
+
/** When the latest of those repeats happened. */
|
|
16407
|
+
lastAt: number()
|
|
16408
|
+
});
|
|
16409
|
+
/**
|
|
16410
|
+
* What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
|
|
16411
|
+
* `action:<actionId>`): the cooldown stamp and the trace ring.
|
|
16412
|
+
*/
|
|
16413
|
+
var AutomationStateDocSchema = object({
|
|
16414
|
+
version: literal(1),
|
|
16415
|
+
lastRunStartedAt: number().nullable(),
|
|
16416
|
+
traces: array(AutomationRunTraceSchema)
|
|
16417
|
+
});
|
|
16418
|
+
/**
|
|
16419
|
+
* Actions — named, runnable things an operator (or an automation) can start,
|
|
16420
|
+
* declared as LIST ENTRIES, never as devices.
|
|
16421
|
+
*
|
|
16422
|
+
* An entry is either **internal** (a short list of cap/wait steps kept in the
|
|
16423
|
+
* hub's `actions` record kind) or declared by an addon through the
|
|
16424
|
+
* `action-source` collection (a Home Assistant script, a scene …). The one
|
|
16425
|
+
* surface the UI and automations talk to is the `actions` cap; it keeps no
|
|
16426
|
+
* catalog of its own (D3) — every `list` asks the providers live.
|
|
16427
|
+
*
|
|
16428
|
+
* This file is the data half: the entry schema, the variables an entry may
|
|
16429
|
+
* declare, and the pure resolution of the values a run was given. It holds no
|
|
16430
|
+
* runtime.
|
|
16431
|
+
*/
|
|
16432
|
+
/** What a variable's value is. `select` takes one of `options`. */
|
|
16433
|
+
var ActionVariableTypeSchema = _enum([
|
|
16434
|
+
"string",
|
|
16435
|
+
"number",
|
|
16436
|
+
"boolean",
|
|
16437
|
+
"select"
|
|
16438
|
+
]);
|
|
16439
|
+
var ACTION_VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
16440
|
+
var ActionVariableValueSchema = union([
|
|
16441
|
+
string(),
|
|
16442
|
+
number(),
|
|
16443
|
+
boolean()
|
|
16444
|
+
]);
|
|
16445
|
+
/**
|
|
16446
|
+
* One declared variable. Steps reference it as `{ $var: 'name' }` (the whole
|
|
16447
|
+
* value) or `{{vars.name}}` (inside a string) in their args.
|
|
16448
|
+
*/
|
|
16449
|
+
var ActionVariableSchema = object({
|
|
16450
|
+
name: string().regex(ACTION_VARIABLE_NAME_RE),
|
|
16451
|
+
label: string().min(1).max(120).optional(),
|
|
16452
|
+
type: ActionVariableTypeSchema,
|
|
16453
|
+
required: boolean().optional(),
|
|
16454
|
+
default: ActionVariableValueSchema.optional(),
|
|
16455
|
+
/** The allowed values of a `select`. */
|
|
16456
|
+
options: array(string().min(1)).min(1).optional()
|
|
16457
|
+
}).superRefine((v, ctx) => {
|
|
16458
|
+
if (v.type === "select" && v.options === void 0) ctx.addIssue({
|
|
16459
|
+
code: "custom",
|
|
16460
|
+
message: "a select variable needs options",
|
|
16461
|
+
path: ["options"]
|
|
16462
|
+
});
|
|
16463
|
+
if (v.default !== void 0 && variableValueError(v, v.default) !== null) ctx.addIssue({
|
|
16464
|
+
code: "custom",
|
|
16465
|
+
message: variableValueError(v, v.default) ?? "invalid default",
|
|
16466
|
+
path: ["default"]
|
|
16467
|
+
});
|
|
16468
|
+
});
|
|
16469
|
+
/** Why `value` is not a legal value for the variable, or null when it is. */
|
|
16470
|
+
function variableValueError(variable, value) {
|
|
16471
|
+
switch (variable.type) {
|
|
16472
|
+
case "string": return typeof value === "string" ? null : `variable "${variable.name}" must be a string`;
|
|
16473
|
+
case "number": return typeof value === "number" && Number.isFinite(value) ? null : `variable "${variable.name}" must be a number`;
|
|
16474
|
+
case "boolean": return typeof value === "boolean" ? null : `variable "${variable.name}" must be true or false`;
|
|
16475
|
+
case "select": return typeof value === "string" && (variable.options ?? []).includes(value) ? null : `variable "${variable.name}" must be one of ${(variable.options ?? []).join(", ")}`;
|
|
16476
|
+
}
|
|
16477
|
+
}
|
|
16478
|
+
var ActionSourceKindSchema = _enum(["internal", "addon"]);
|
|
16479
|
+
function isInternalActionId(actionId) {
|
|
16480
|
+
return actionId.startsWith("internal:") && actionId.length > 9;
|
|
16481
|
+
}
|
|
16482
|
+
/** The addon behind a `<addonId>:<localId>` id, or null for anything else (internal included). */
|
|
16483
|
+
function addonIdOfActionId(actionId) {
|
|
16484
|
+
if (isInternalActionId(actionId)) return null;
|
|
16485
|
+
const at = actionId.indexOf(":");
|
|
16486
|
+
return at > 0 && at < actionId.length - 1 ? actionId.slice(0, at) : null;
|
|
16487
|
+
}
|
|
16488
|
+
var ActionStatusSchema = object({
|
|
16489
|
+
isRunning: boolean(),
|
|
16490
|
+
/** Ms epoch the latest run STARTED; null when it never ran. */
|
|
16491
|
+
lastRunAt: number().nullable(),
|
|
16492
|
+
/** The latest run's failure; null on success or when it never ran. */
|
|
16493
|
+
lastError: string().nullable()
|
|
16494
|
+
});
|
|
16495
|
+
var ActionEntrySchema = object({
|
|
16496
|
+
/** `internal:<uuid>` or `<addonId>:<localId>`. */
|
|
16497
|
+
id: string().min(3),
|
|
16498
|
+
name: string().min(1).max(120),
|
|
16499
|
+
/** The addon that declared it; `core-blocks` for an internal one. */
|
|
16500
|
+
addonId: string().min(1),
|
|
16501
|
+
source: ActionSourceKindSchema,
|
|
16502
|
+
/** An addon-declared entry is edited where it was declared. */
|
|
16503
|
+
readOnly: boolean(),
|
|
16504
|
+
/** Internal only: cap and wait steps. No action-in-action, so no cycles. */
|
|
16505
|
+
steps: array(ActionStepSchema).min(1).max(50).optional(),
|
|
16506
|
+
variables: array(ActionVariableSchema).max(20).optional(),
|
|
16507
|
+
status: ActionStatusSchema
|
|
16508
|
+
}).superRefine((entry, ctx) => {
|
|
16509
|
+
if (entry.source === "internal") {
|
|
16510
|
+
if (!isInternalActionId(entry.id)) ctx.addIssue({
|
|
16511
|
+
code: "custom",
|
|
16512
|
+
message: "an internal action id is internal:<uuid>",
|
|
16513
|
+
path: ["id"]
|
|
16514
|
+
});
|
|
16515
|
+
return;
|
|
16516
|
+
}
|
|
16517
|
+
if (entry.steps !== void 0) ctx.addIssue({
|
|
16518
|
+
code: "custom",
|
|
16519
|
+
message: "only an internal action carries steps",
|
|
16520
|
+
path: ["steps"]
|
|
16521
|
+
});
|
|
16522
|
+
if (!entry.readOnly) ctx.addIssue({
|
|
16523
|
+
code: "custom",
|
|
16524
|
+
message: "an addon action is read-only here",
|
|
16525
|
+
path: ["readOnly"]
|
|
16526
|
+
});
|
|
16527
|
+
if (addonIdOfActionId(entry.id) === null) ctx.addIssue({
|
|
16528
|
+
code: "custom",
|
|
16529
|
+
message: "an addon action id is <addonId>:<localId>",
|
|
16530
|
+
path: ["id"]
|
|
16531
|
+
});
|
|
16532
|
+
});
|
|
16533
|
+
/** What an operator writes for an internal action. */
|
|
16534
|
+
var ActionInputSchema = object({
|
|
16535
|
+
name: string().min(1).max(120),
|
|
16536
|
+
steps: array(ActionStepSchema).min(1).max(50),
|
|
16537
|
+
variables: array(ActionVariableSchema).max(20).optional()
|
|
16538
|
+
});
|
|
16539
|
+
/** Who started a run. Absent = the operator pressed it. */
|
|
16540
|
+
var ActionRunOriginSchema = object({
|
|
16541
|
+
/** The automation block whose step started it. */
|
|
16542
|
+
blockId: string().min(1).optional() });
|
|
16543
|
+
/** `started` = the caller did not ask to wait. */
|
|
16544
|
+
var ActionRunOutcomeSchema = union([AutomationRunOutcomeSchema, literal("started")]);
|
|
16545
|
+
var ActionRunResultSchema = object({
|
|
16546
|
+
runId: string().min(1),
|
|
16547
|
+
outcome: ActionRunOutcomeSchema,
|
|
16548
|
+
/** Why it did not run, or what failed. */
|
|
16549
|
+
message: string().optional()
|
|
16550
|
+
});
|
|
16551
|
+
_enum([
|
|
16552
|
+
"not-found",
|
|
16553
|
+
"read-only",
|
|
16554
|
+
"invalid-variables",
|
|
16555
|
+
"invalid-steps",
|
|
16556
|
+
"not-linked",
|
|
16557
|
+
"busy"
|
|
16558
|
+
]);
|
|
16559
|
+
object({
|
|
16560
|
+
actionId: string(),
|
|
16561
|
+
runId: string(),
|
|
16562
|
+
isRunning: boolean(),
|
|
16563
|
+
/** Set when the run ended. */
|
|
16564
|
+
outcome: AutomationRunOutcomeSchema.optional(),
|
|
16565
|
+
lastRunAt: number().nullable(),
|
|
16566
|
+
lastError: string().nullable()
|
|
16150
16567
|
});
|
|
16151
16568
|
/**
|
|
16152
16569
|
* `addon-pages` — system-scoped singleton aggregator cap. Public-facing
|
|
@@ -18833,7 +19250,7 @@ var CompositionEventPlanSchema = object({
|
|
|
18833
19250
|
stateField: string(),
|
|
18834
19251
|
fieldKey: string()
|
|
18835
19252
|
});
|
|
18836
|
-
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.
|
|
19253
|
+
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.temperature`. */
|
|
18837
19254
|
var CompositionProblemSchema = object({
|
|
18838
19255
|
code: _enum([
|
|
18839
19256
|
"reserved-variant",
|
|
@@ -19152,7 +19569,7 @@ var GROUP_TEMPLATES = [
|
|
|
19152
19569
|
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
19153
19570
|
role: DeviceRole.TemperatureSensor,
|
|
19154
19571
|
outputCap: "temperature-sensor",
|
|
19155
|
-
outputField: "
|
|
19572
|
+
outputField: "temperature",
|
|
19156
19573
|
quantity: "temperature",
|
|
19157
19574
|
defaultAggregate: "mean",
|
|
19158
19575
|
empty: "null",
|
|
@@ -19163,7 +19580,7 @@ var GROUP_TEMPLATES = [
|
|
|
19163
19580
|
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
19164
19581
|
role: DeviceRole.HumiditySensor,
|
|
19165
19582
|
outputCap: "humidity-sensor",
|
|
19166
|
-
outputField: "
|
|
19583
|
+
outputField: "humidity",
|
|
19167
19584
|
quantity: "humidity",
|
|
19168
19585
|
defaultAggregate: "mean",
|
|
19169
19586
|
empty: "null",
|
|
@@ -19174,7 +19591,7 @@ var GROUP_TEMPLATES = [
|
|
|
19174
19591
|
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
19175
19592
|
role: DeviceRole.PressureSensor,
|
|
19176
19593
|
outputCap: "pressure-sensor",
|
|
19177
|
-
outputField: "
|
|
19594
|
+
outputField: "pressure",
|
|
19178
19595
|
quantity: "pressure",
|
|
19179
19596
|
defaultAggregate: "mean",
|
|
19180
19597
|
empty: "null",
|
|
@@ -19185,7 +19602,7 @@ var GROUP_TEMPLATES = [
|
|
|
19185
19602
|
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
19186
19603
|
role: DeviceRole.AmbientLightSensor,
|
|
19187
19604
|
outputCap: "ambient-light-sensor",
|
|
19188
|
-
outputField: "
|
|
19605
|
+
outputField: "illuminance",
|
|
19189
19606
|
quantity: "illuminance",
|
|
19190
19607
|
defaultAggregate: "mean",
|
|
19191
19608
|
empty: "null",
|
|
@@ -19196,7 +19613,7 @@ var GROUP_TEMPLATES = [
|
|
|
19196
19613
|
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
19197
19614
|
role: DeviceRole.PowerSensor,
|
|
19198
19615
|
outputCap: "power-meter",
|
|
19199
|
-
outputField: "
|
|
19616
|
+
outputField: "power",
|
|
19200
19617
|
quantity: "power",
|
|
19201
19618
|
defaultAggregate: "sum",
|
|
19202
19619
|
empty: "omit",
|
|
@@ -19207,7 +19624,7 @@ var GROUP_TEMPLATES = [
|
|
|
19207
19624
|
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
19208
19625
|
role: DeviceRole.EnergySensor,
|
|
19209
19626
|
outputCap: "power-meter",
|
|
19210
|
-
outputField: "
|
|
19627
|
+
outputField: "energy",
|
|
19211
19628
|
quantity: "energy",
|
|
19212
19629
|
defaultAggregate: "sum",
|
|
19213
19630
|
empty: "omit",
|
|
@@ -19218,7 +19635,7 @@ var GROUP_TEMPLATES = [
|
|
|
19218
19635
|
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
19219
19636
|
role: DeviceRole.BatterySensor,
|
|
19220
19637
|
outputCap: "battery",
|
|
19221
|
-
outputField: "
|
|
19638
|
+
outputField: "level",
|
|
19222
19639
|
quantity: "percentage",
|
|
19223
19640
|
defaultAggregate: "mean",
|
|
19224
19641
|
empty: "null",
|
|
@@ -19796,7 +20213,18 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
|
|
|
19796
20213
|
kind: "mutation",
|
|
19797
20214
|
auth: "admin",
|
|
19798
20215
|
access: "view"
|
|
19799
|
-
})
|
|
20216
|
+
}), method(object({
|
|
20217
|
+
blockId: string().min(1),
|
|
20218
|
+
trace: AutomationRunTraceSchema.optional(),
|
|
20219
|
+
runStartedAt: number().optional(),
|
|
20220
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
20221
|
+
}), _void(), {
|
|
20222
|
+
kind: "mutation",
|
|
20223
|
+
auth: "admin"
|
|
20224
|
+
}), method(object({ blockId: string().min(1) }), AutomationStateDocSchema, { auth: "admin" }), method(object({ blockId: string().min(1) }), object({
|
|
20225
|
+
traces: array(AutomationRunTraceSchema),
|
|
20226
|
+
lastError: string().nullable()
|
|
20227
|
+
}), { auth: "admin" });
|
|
19800
20228
|
/**
|
|
19801
20229
|
* `custom-model-registry` — collection cap exposing operator-registered
|
|
19802
20230
|
* custom detection models. Each provider (today: `addon-model-studio`)
|
|
@@ -45234,51 +45662,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
|
|
|
45234
45662
|
kind: "mutation",
|
|
45235
45663
|
auth: "admin"
|
|
45236
45664
|
});
|
|
45237
|
-
new Set([
|
|
45238
|
-
{
|
|
45239
|
-
id: "person",
|
|
45240
|
-
name: "Person"
|
|
45241
|
-
},
|
|
45242
|
-
{
|
|
45243
|
-
id: "vehicle",
|
|
45244
|
-
name: "Vehicle"
|
|
45245
|
-
},
|
|
45246
|
-
{
|
|
45247
|
-
id: "animal",
|
|
45248
|
-
name: "Animal"
|
|
45249
|
-
},
|
|
45250
|
-
{
|
|
45251
|
-
id: "package",
|
|
45252
|
-
name: "Package"
|
|
45253
|
-
}
|
|
45254
|
-
].map((l) => l.id));
|
|
45255
|
-
var COCO_TO_MACRO = {
|
|
45256
|
-
mapping: {
|
|
45257
|
-
person: "person",
|
|
45258
|
-
bicycle: "vehicle",
|
|
45259
|
-
car: "vehicle",
|
|
45260
|
-
motorcycle: "vehicle",
|
|
45261
|
-
airplane: "vehicle",
|
|
45262
|
-
bus: "vehicle",
|
|
45263
|
-
train: "vehicle",
|
|
45264
|
-
truck: "vehicle",
|
|
45265
|
-
boat: "vehicle",
|
|
45266
|
-
bird: "animal",
|
|
45267
|
-
cat: "animal",
|
|
45268
|
-
dog: "animal",
|
|
45269
|
-
horse: "animal",
|
|
45270
|
-
sheep: "animal",
|
|
45271
|
-
cow: "animal",
|
|
45272
|
-
elephant: "animal",
|
|
45273
|
-
bear: "animal",
|
|
45274
|
-
zebra: "animal",
|
|
45275
|
-
giraffe: "animal",
|
|
45276
|
-
suitcase: "package",
|
|
45277
|
-
backpack: "package",
|
|
45278
|
-
handbag: "package"
|
|
45279
|
-
},
|
|
45280
|
-
preserveOriginal: false
|
|
45281
|
-
};
|
|
45282
45665
|
var AUDIO_MACRO_LABELS = [
|
|
45283
45666
|
{
|
|
45284
45667
|
id: "speech",
|
|
@@ -58367,9 +58750,9 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
58367
58750
|
*/
|
|
58368
58751
|
var AirQualitySensorStatusSchema = object({
|
|
58369
58752
|
/** Carbon dioxide concentration in ppm. */
|
|
58370
|
-
|
|
58753
|
+
co2: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
58371
58754
|
/** Total volatile organic compounds in ppb. */
|
|
58372
|
-
|
|
58755
|
+
voc: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
58373
58756
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
58374
58757
|
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
58375
58758
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
@@ -58402,12 +58785,12 @@ var airQualitySensorCapability = {
|
|
|
58402
58785
|
* History (D850): recorded series.
|
|
58403
58786
|
*/
|
|
58404
58787
|
history: { fields: {
|
|
58405
|
-
|
|
58788
|
+
co2: {
|
|
58406
58789
|
kind: "gauge",
|
|
58407
58790
|
unit: "ppm",
|
|
58408
58791
|
deadband: 5
|
|
58409
58792
|
},
|
|
58410
|
-
|
|
58793
|
+
voc: {
|
|
58411
58794
|
kind: "gauge",
|
|
58412
58795
|
unit: "ppb",
|
|
58413
58796
|
deadband: 5
|
|
@@ -58438,7 +58821,7 @@ var airQualitySensorCapability = {
|
|
|
58438
58821
|
*/
|
|
58439
58822
|
var AmbientLightSensorStatusSchema = object({
|
|
58440
58823
|
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
58441
|
-
|
|
58824
|
+
illuminance: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
58442
58825
|
precision: 0,
|
|
58443
58826
|
label: "Illuminance"
|
|
58444
58827
|
})),
|
|
@@ -58467,7 +58850,7 @@ var ambientLightSensorCapability = {
|
|
|
58467
58850
|
/**
|
|
58468
58851
|
* History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
|
|
58469
58852
|
*/
|
|
58470
|
-
history: { fields: {
|
|
58853
|
+
history: { fields: { illuminance: {
|
|
58471
58854
|
kind: "gauge",
|
|
58472
58855
|
unit: "lx",
|
|
58473
58856
|
deadbandPct: 10,
|
|
@@ -58606,6 +58989,84 @@ var audioMetricsCapability = {
|
|
|
58606
58989
|
*/
|
|
58607
58990
|
history: "none"
|
|
58608
58991
|
};
|
|
58992
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
58993
|
+
actionId: string().min(1),
|
|
58994
|
+
variables: record(string(), ActionVariableValueSchema).optional()
|
|
58995
|
+
}), _void(), {
|
|
58996
|
+
kind: "mutation",
|
|
58997
|
+
auth: "admin"
|
|
58998
|
+
}), method(object({ actionId: string().min(1) }), _void(), {
|
|
58999
|
+
kind: "mutation",
|
|
59000
|
+
auth: "admin"
|
|
59001
|
+
});
|
|
59002
|
+
/**
|
|
59003
|
+
* actions — the ONE surface for runnable actions, for the UI and for
|
|
59004
|
+
* automations. Provided by the core-blocks builtin on the hub.
|
|
59005
|
+
*
|
|
59006
|
+
* An action is a LIST ENTRY, not a device (D883): either internal (cap and wait
|
|
59007
|
+
* steps, kept in the hub's `actions` record kind) or declared by an addon over
|
|
59008
|
+
* `action-source`. `list` asks every `action-source` provider LIVE and overlays
|
|
59009
|
+
* the run status from the hub's `runs` ledger; there is no catalog here to
|
|
59010
|
+
* drift (D3).
|
|
59011
|
+
*
|
|
59012
|
+
* **Permissions follow the camera, as linked devices do.** An action is linked
|
|
59013
|
+
* to cameras by the operator (`setLinks`, D356: nothing links itself). A
|
|
59014
|
+
* non-admin may `get` / `run` an action only through a camera they may see that
|
|
59015
|
+
* links it: they name the camera (`deviceId`, a top-level field so the scope
|
|
59016
|
+
* gate sees it) and the provider refuses an action that camera does not link.
|
|
59017
|
+
* An admin, and an in-process caller (an automation block), may run any action.
|
|
59018
|
+
* Every refusal is typed (`[not-linked] …`) and logged.
|
|
59019
|
+
*
|
|
59020
|
+
* A second `run` of an action that is already running is REFUSED — traced and
|
|
59021
|
+
* logged — never queued.
|
|
59022
|
+
*/
|
|
59023
|
+
var ActionIdInput = object({ actionId: string().min(1) });
|
|
59024
|
+
var ActionLinksSchema = object({
|
|
59025
|
+
deviceId: number().int().nonnegative(),
|
|
59026
|
+
actionIds: array(string().min(1)).max(100)
|
|
59027
|
+
});
|
|
59028
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
59029
|
+
actionId: string().min(1),
|
|
59030
|
+
deviceId: number().int().nonnegative().optional()
|
|
59031
|
+
}), object({ action: ActionEntrySchema.nullable() }), {
|
|
59032
|
+
role: "viewer",
|
|
59033
|
+
auth: "protected",
|
|
59034
|
+
kind: "query",
|
|
59035
|
+
caller: "required"
|
|
59036
|
+
}), method(object({
|
|
59037
|
+
actionId: string().min(1),
|
|
59038
|
+
variables: record(string(), ActionVariableValueSchema).optional(),
|
|
59039
|
+
wait: boolean().optional(),
|
|
59040
|
+
origin: ActionRunOriginSchema.optional(),
|
|
59041
|
+
deviceId: number().int().nonnegative().optional()
|
|
59042
|
+
}), ActionRunResultSchema, {
|
|
59043
|
+
role: "viewer",
|
|
59044
|
+
auth: "protected",
|
|
59045
|
+
kind: "mutation",
|
|
59046
|
+
caller: "required"
|
|
59047
|
+
}), method(ActionIdInput, _void(), {
|
|
59048
|
+
kind: "mutation",
|
|
59049
|
+
auth: "admin"
|
|
59050
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
|
|
59051
|
+
kind: "mutation",
|
|
59052
|
+
auth: "admin"
|
|
59053
|
+
}), method(object({
|
|
59054
|
+
actionId: string().min(1),
|
|
59055
|
+
action: ActionInputSchema.partial()
|
|
59056
|
+
}), object({ action: ActionEntrySchema }), {
|
|
59057
|
+
kind: "mutation",
|
|
59058
|
+
auth: "admin"
|
|
59059
|
+
}), method(ActionIdInput, _void(), {
|
|
59060
|
+
kind: "mutation",
|
|
59061
|
+
auth: "admin"
|
|
59062
|
+
}), method(object({ deviceId: number().int().nonnegative() }), array(ActionEntrySchema), {
|
|
59063
|
+
role: "viewer",
|
|
59064
|
+
auth: "protected",
|
|
59065
|
+
kind: "query"
|
|
59066
|
+
}), method(object({ deviceId: number().int().nonnegative() }), ActionLinksSchema, { auth: "admin" }), method(ActionLinksSchema, ActionLinksSchema, {
|
|
59067
|
+
kind: "mutation",
|
|
59068
|
+
auth: "admin"
|
|
59069
|
+
});
|
|
58609
59070
|
/**
|
|
58610
59071
|
* Automation-control cap. Models HA `automation.*` entities on
|
|
58611
59072
|
* `DeviceType.Automation`. An automation is a trigger+condition+
|
|
@@ -58702,7 +59163,7 @@ var BatteryStatusSchema = object({
|
|
|
58702
59163
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
58703
59164
|
* declines to band a non-finite reading, which is the correct shape.
|
|
58704
59165
|
*/
|
|
58705
|
-
|
|
59166
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
58706
59167
|
/**
|
|
58707
59168
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
58708
59169
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -58712,7 +59173,7 @@ var BatteryStatusSchema = object({
|
|
|
58712
59173
|
* `'unknown'` is the absence of an answer: the provider has not read the
|
|
58713
59174
|
* power fields yet, or the firmware reported neither. Before it existed,
|
|
58714
59175
|
* two unreadable fields produced `'none'`, and a camera nobody had reached
|
|
58715
|
-
* was drawn "on battery alone" — the same D315 defect `
|
|
59176
|
+
* was drawn "on battery alone" — the same D315 defect `level` closed
|
|
58716
59177
|
* by going nullable. Consumers SKIP it (no charger state published, no
|
|
58717
59178
|
* glyph, no HomeKit ChargingState) rather than coerce it either way.
|
|
58718
59179
|
*/
|
|
@@ -58736,7 +59197,7 @@ var BatteryStatusSchema = object({
|
|
|
58736
59197
|
* that only report charge. A second reading on this cap, not a second
|
|
58737
59198
|
* `numeric-sensor` on the same device.
|
|
58738
59199
|
*/
|
|
58739
|
-
|
|
59200
|
+
voltage: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
58740
59201
|
/**
|
|
58741
59202
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
58742
59203
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -58770,7 +59231,7 @@ var BatteryStatusSchema = object({
|
|
|
58770
59231
|
/**
|
|
58771
59232
|
* True when the source is a BINARY low-battery indicator (HA
|
|
58772
59233
|
* `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
|
|
58773
|
-
* charge level — `
|
|
59234
|
+
* charge level — `level` is then a coarse stand-in (100 = normal,
|
|
58774
59235
|
* sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
|
|
58775
59236
|
* misleading exact percentage. Absent/false → genuine 0–100 % reading.
|
|
58776
59237
|
*/
|
|
@@ -58790,15 +59251,15 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
58790
59251
|
var batteryCustomize = {
|
|
58791
59252
|
version: 1,
|
|
58792
59253
|
targets: [{
|
|
58793
|
-
id: "
|
|
59254
|
+
id: "level",
|
|
58794
59255
|
cardinality: "scalar",
|
|
58795
59256
|
vocabulary: {
|
|
58796
59257
|
cap: "battery",
|
|
58797
|
-
stateField: "
|
|
59258
|
+
stateField: "level"
|
|
58798
59259
|
},
|
|
58799
59260
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
58800
59261
|
apply: "add",
|
|
58801
|
-
path: "
|
|
59262
|
+
path: "level",
|
|
58802
59263
|
sources: [{
|
|
58803
59264
|
kind: "field",
|
|
58804
59265
|
valueKinds: ["number", "string"],
|
|
@@ -58892,7 +59353,7 @@ onStatusChanged: { data: object({
|
|
|
58892
59353
|
schema: BatteryStatusSchema,
|
|
58893
59354
|
kind: "push",
|
|
58894
59355
|
empty: {
|
|
58895
|
-
|
|
59356
|
+
level: null,
|
|
58896
59357
|
charging: "unknown",
|
|
58897
59358
|
sleeping: false,
|
|
58898
59359
|
lastUpdated: 0
|
|
@@ -58919,11 +59380,11 @@ onStatusChanged: { data: object({
|
|
|
58919
59380
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
58920
59381
|
*/
|
|
58921
59382
|
history: { fields: {
|
|
58922
|
-
|
|
59383
|
+
level: {
|
|
58923
59384
|
kind: "gauge",
|
|
58924
59385
|
unit: "%"
|
|
58925
59386
|
},
|
|
58926
|
-
|
|
59387
|
+
voltage: {
|
|
58927
59388
|
kind: "gauge",
|
|
58928
59389
|
unit: "V"
|
|
58929
59390
|
}
|
|
@@ -58983,14 +59444,14 @@ var binaryCapability = {
|
|
|
58983
59444
|
* controls to this single-method surface.
|
|
58984
59445
|
*
|
|
58985
59446
|
* The cap is intentionally minimal: a single `setBrightness({deviceId,
|
|
58986
|
-
*
|
|
59447
|
+
* level})` mutation plus the auto-injected `getStatus`. Drivers
|
|
58987
59448
|
* that expose richer controls (color temperature, scenes, schedules)
|
|
58988
59449
|
* should surface those via the device's `getSettingsUISchema()`
|
|
58989
59450
|
* instead of bloating this cap.
|
|
58990
59451
|
*/
|
|
58991
59452
|
var BrightnessStatusSchema = object({
|
|
58992
59453
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
58993
|
-
|
|
59454
|
+
level: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
58994
59455
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
58995
59456
|
lastChangedAt: number()
|
|
58996
59457
|
});
|
|
@@ -59002,7 +59463,7 @@ var brightnessCapability = {
|
|
|
59002
59463
|
deviceTypes: [DeviceType.Light],
|
|
59003
59464
|
methods: { setBrightness: method(object({
|
|
59004
59465
|
deviceId: number().int().nonnegative(),
|
|
59005
|
-
|
|
59466
|
+
level: number().min(0).max(100)
|
|
59006
59467
|
}), _void(), {
|
|
59007
59468
|
kind: "mutation",
|
|
59008
59469
|
auth: "protected"
|
|
@@ -59015,7 +59476,7 @@ var brightnessCapability = {
|
|
|
59015
59476
|
*/
|
|
59016
59477
|
onBrightnessChanged: { data: object({
|
|
59017
59478
|
deviceId: number(),
|
|
59018
|
-
|
|
59479
|
+
level: number().min(0).max(100),
|
|
59019
59480
|
lastChangedAt: number()
|
|
59020
59481
|
}) } },
|
|
59021
59482
|
status: {
|
|
@@ -59038,7 +59499,7 @@ onBrightnessChanged: { data: object({
|
|
|
59038
59499
|
/**
|
|
59039
59500
|
* History (D850): recorded series. Actuator tier: level keeps every change.
|
|
59040
59501
|
*/
|
|
59041
|
-
history: { fields: {
|
|
59502
|
+
history: { fields: { level: {
|
|
59042
59503
|
kind: "gauge",
|
|
59043
59504
|
unit: "%",
|
|
59044
59505
|
minIntervalMs: 0
|
|
@@ -59635,11 +60096,11 @@ var ColorInputSchema = discriminatedUnion("mode", [
|
|
|
59635
60096
|
}),
|
|
59636
60097
|
object({
|
|
59637
60098
|
mode: literal("mired"),
|
|
59638
|
-
|
|
60099
|
+
colorTemperature: number().int().min(50).max(1e3)
|
|
59639
60100
|
})
|
|
59640
60101
|
]);
|
|
59641
60102
|
var ColorStatusSchema = object({
|
|
59642
|
-
/** Active color mode — which of `rgb` / `hsv` / `
|
|
60103
|
+
/** Active color mode — which of `rgb` / `hsv` / `colorTemperature` reflects
|
|
59643
60104
|
* the bulb's current state. */
|
|
59644
60105
|
mode: _enum([
|
|
59645
60106
|
"rgb",
|
|
@@ -59651,7 +60112,7 @@ var ColorStatusSchema = object({
|
|
|
59651
60112
|
/** Populated when `mode === 'hsv'`. */
|
|
59652
60113
|
hsv: HsvTripletSchema.optional(),
|
|
59653
60114
|
/** Populated when `mode === 'mired'`. */
|
|
59654
|
-
|
|
60115
|
+
colorTemperature: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
59655
60116
|
/** Ms epoch of the last operator-driven change. */
|
|
59656
60117
|
lastChangedAt: number()
|
|
59657
60118
|
});
|
|
@@ -59683,7 +60144,7 @@ onColorChanged: { data: object({
|
|
|
59683
60144
|
]),
|
|
59684
60145
|
rgb: RgbTripletSchema.optional(),
|
|
59685
60146
|
hsv: HsvTripletSchema.optional(),
|
|
59686
|
-
|
|
60147
|
+
colorTemperature: number().int().optional(),
|
|
59687
60148
|
lastChangedAt: number()
|
|
59688
60149
|
}) } },
|
|
59689
60150
|
status: {
|
|
@@ -60560,11 +61021,11 @@ var DishwasherStatusSchema = object({
|
|
|
60560
61021
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
60561
61022
|
availablePrograms: array(string()),
|
|
60562
61023
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
60563
|
-
|
|
61024
|
+
remaining: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
60564
61025
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
60565
|
-
|
|
61026
|
+
delayedStart: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
60566
61027
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
60567
|
-
|
|
61028
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60568
61029
|
/** True when the door is reported open; null when the door state is not known. */
|
|
60569
61030
|
doorOpen: boolean().nullable(),
|
|
60570
61031
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -60783,14 +61244,14 @@ var dishwasherCapability = {
|
|
|
60783
61244
|
runtimeState: DishwasherStatusSchema,
|
|
60784
61245
|
durability: "session",
|
|
60785
61246
|
history: { fields: {
|
|
60786
|
-
|
|
61247
|
+
progress: {
|
|
60787
61248
|
kind: "gauge",
|
|
60788
61249
|
unit: "%",
|
|
60789
61250
|
deadband: 2
|
|
60790
61251
|
},
|
|
60791
61252
|
state: { kind: "enum" },
|
|
60792
61253
|
operationState: { kind: "enum" },
|
|
60793
|
-
|
|
61254
|
+
remaining: {
|
|
60794
61255
|
kind: "gauge",
|
|
60795
61256
|
unit: "s",
|
|
60796
61257
|
minIntervalMs: 6e4
|
|
@@ -61381,7 +61842,7 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
61381
61842
|
var FanControlStatusSchema = object({
|
|
61382
61843
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
61383
61844
|
* speed surface (single-speed fan). */
|
|
61384
|
-
|
|
61845
|
+
speed: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61385
61846
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
61386
61847
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
61387
61848
|
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
@@ -61408,7 +61869,7 @@ var fanControlCapability = {
|
|
|
61408
61869
|
methods: {
|
|
61409
61870
|
setPercentage: method(object({
|
|
61410
61871
|
deviceId: number().int().nonnegative(),
|
|
61411
|
-
|
|
61872
|
+
speed: number().min(0).max(100)
|
|
61412
61873
|
}), _void(), {
|
|
61413
61874
|
kind: "mutation",
|
|
61414
61875
|
auth: "protected"
|
|
@@ -61441,7 +61902,7 @@ var fanControlCapability = {
|
|
|
61441
61902
|
},
|
|
61442
61903
|
/**
|
|
61443
61904
|
* Runtime-state slice — mirrored by the kernel. UI fan speed
|
|
61444
|
-
* sliders read `
|
|
61905
|
+
* sliders read `speed` for live updates.
|
|
61445
61906
|
*/
|
|
61446
61907
|
runtimeState: FanControlStatusSchema,
|
|
61447
61908
|
/**
|
|
@@ -61455,7 +61916,7 @@ var fanControlCapability = {
|
|
|
61455
61916
|
* History (D850): recorded series. Actuator tier: speed keeps every change.
|
|
61456
61917
|
*/
|
|
61457
61918
|
history: { fields: {
|
|
61458
|
-
|
|
61919
|
+
speed: {
|
|
61459
61920
|
kind: "gauge",
|
|
61460
61921
|
unit: "%",
|
|
61461
61922
|
minIntervalMs: 0
|
|
@@ -61900,7 +62361,7 @@ var humidifierCapability = {
|
|
|
61900
62361
|
*/
|
|
61901
62362
|
var HumiditySensorStatusSchema = object({
|
|
61902
62363
|
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
61903
|
-
|
|
62364
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
61904
62365
|
precision: 0,
|
|
61905
62366
|
label: "Humidity"
|
|
61906
62367
|
})),
|
|
@@ -61929,7 +62390,7 @@ var humiditySensorCapability = {
|
|
|
61929
62390
|
/**
|
|
61930
62391
|
* History (D850): recorded series.
|
|
61931
62392
|
*/
|
|
61932
|
-
history: { fields: {
|
|
62393
|
+
history: { fields: { humidity: {
|
|
61933
62394
|
kind: "gauge",
|
|
61934
62395
|
unit: "%",
|
|
61935
62396
|
deadband: .5
|
|
@@ -62569,7 +63030,7 @@ var LawnMowerControlStatusSchema = object({
|
|
|
62569
63030
|
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62570
63031
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
62571
63032
|
* task is active / progress is unavailable. */
|
|
62572
|
-
|
|
63033
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62573
63034
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
62574
63035
|
* or null when unknown. */
|
|
62575
63036
|
currentCode: number().nullable().meta(readingMeta("none")),
|
|
@@ -63069,7 +63530,7 @@ var lockControlCapability = {
|
|
|
63069
63530
|
volatileStateFields: ["lastChangedAt"]
|
|
63070
63531
|
};
|
|
63071
63532
|
/**
|
|
63072
|
-
* A monotonic total between resets (D944). Energy uses `power-meter.
|
|
63533
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.energy`
|
|
63073
63534
|
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
63074
63535
|
* `value` is the time integral in the source quantity's accumulated base
|
|
63075
63536
|
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
@@ -63163,10 +63624,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
63163
63624
|
currentMedia: MediaInfoSchema.nullable(),
|
|
63164
63625
|
/** Current playback position in ms. Null when not seekable or
|
|
63165
63626
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
63166
|
-
|
|
63627
|
+
position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
63167
63628
|
/** Total duration of the current media in ms. Null when unknown
|
|
63168
63629
|
* (live stream) or nothing is playing. */
|
|
63169
|
-
|
|
63630
|
+
duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
63170
63631
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
63171
63632
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
63172
63633
|
shuffle: boolean().nullable(),
|
|
@@ -63205,7 +63666,7 @@ var mediaPlayerCapability = {
|
|
|
63205
63666
|
}),
|
|
63206
63667
|
seek: method(object({
|
|
63207
63668
|
deviceId: number().int().nonnegative(),
|
|
63208
|
-
|
|
63669
|
+
position: number().int().nonnegative()
|
|
63209
63670
|
}), _void(), {
|
|
63210
63671
|
kind: "mutation",
|
|
63211
63672
|
auth: "protected"
|
|
@@ -63277,7 +63738,7 @@ var mediaPlayerCapability = {
|
|
|
63277
63738
|
/**
|
|
63278
63739
|
* History (D850): volume (a level an operator or an automation sets; the
|
|
63279
63740
|
* default 10 s floor folds a slider drag into its end value) and mute.
|
|
63280
|
-
* `
|
|
63741
|
+
* `position` is not recorded: it moves continuously while playing.
|
|
63281
63742
|
*/
|
|
63282
63743
|
history: { fields: {
|
|
63283
63744
|
volumeLevel: {
|
|
@@ -64239,9 +64700,9 @@ var NetworkLinkStatusSchema = object({
|
|
|
64239
64700
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
64240
64701
|
* SKIP a null rather than coerce it.
|
|
64241
64702
|
*/
|
|
64242
|
-
|
|
64703
|
+
signal: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64243
64704
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
64244
|
-
|
|
64705
|
+
rssi: number().optional().meta(readingMeta("signal-level")),
|
|
64245
64706
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
64246
64707
|
ssid: string().optional(),
|
|
64247
64708
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
@@ -64250,7 +64711,7 @@ var NetworkLinkStatusSchema = object({
|
|
|
64250
64711
|
/** The slice a provider seeds before its first read: nothing is known yet. */
|
|
64251
64712
|
var NETWORK_LINK_UNKNOWN = {
|
|
64252
64713
|
type: "unknown",
|
|
64253
|
-
|
|
64714
|
+
signal: null,
|
|
64254
64715
|
lastUpdated: 0
|
|
64255
64716
|
};
|
|
64256
64717
|
/**
|
|
@@ -64267,9 +64728,9 @@ function signalPercentFromBars(bars, maxBars) {
|
|
|
64267
64728
|
* below is 0 %, -50 dBm and above is 100 %, linear between. Non-finite or
|
|
64268
64729
|
* positive input is not an RSSI: `null`.
|
|
64269
64730
|
*/
|
|
64270
|
-
function signalPercentFromRssi(
|
|
64271
|
-
if (
|
|
64272
|
-
return Math.round((Math.min(-50, Math.max(-100,
|
|
64731
|
+
function signalPercentFromRssi(rssi) {
|
|
64732
|
+
if (rssi === void 0 || !Number.isFinite(rssi) || rssi > 0) return null;
|
|
64733
|
+
return Math.round((Math.min(-50, Math.max(-100, rssi)) + 100) * 2);
|
|
64273
64734
|
}
|
|
64274
64735
|
var networkLinkCapability = {
|
|
64275
64736
|
name: "network-link",
|
|
@@ -64320,13 +64781,13 @@ onStatusChanged: { data: object({
|
|
|
64320
64781
|
* History (D850): recorded series.
|
|
64321
64782
|
*/
|
|
64322
64783
|
history: { fields: {
|
|
64323
|
-
|
|
64784
|
+
signal: {
|
|
64324
64785
|
kind: "gauge",
|
|
64325
64786
|
unit: "%",
|
|
64326
64787
|
deadband: 3,
|
|
64327
64788
|
minIntervalMs: 6e4
|
|
64328
64789
|
},
|
|
64329
|
-
|
|
64790
|
+
rssi: {
|
|
64330
64791
|
kind: "gauge",
|
|
64331
64792
|
unit: "dBm",
|
|
64332
64793
|
deadband: 2,
|
|
@@ -65117,10 +65578,20 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
65117
65578
|
]);
|
|
65118
65579
|
var gramsPortion = number().int().min(4).max(200);
|
|
65119
65580
|
var PetFeederStatusSchema = object({
|
|
65120
|
-
/** Food
|
|
65121
|
-
*
|
|
65122
|
-
* bowl
|
|
65581
|
+
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
65582
|
+
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
65583
|
+
* amount in the bowl is `bowlFood`. On dual-hopper models this is the
|
|
65584
|
+
* combined reading; per-hopper levels live in `food1`/`food2`. Null when
|
|
65585
|
+
* the device has not reported yet. */
|
|
65123
65586
|
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
65587
|
+
/** Food in the BOWL as the feeder reports it (`state.bowl`), in the
|
|
65588
|
+
* feeder's own units. Null when the model reports none. */
|
|
65589
|
+
bowlFood: number().nullable().meta(readingMeta("none")),
|
|
65590
|
+
/** True while the pet is eating (`state.eating`). */
|
|
65591
|
+
eating: boolean(),
|
|
65592
|
+
/** Whether `markFoodReplenished` does anything on this model. When false
|
|
65593
|
+
* the client must not offer it. */
|
|
65594
|
+
supportsMarkRefilled: boolean(),
|
|
65124
65595
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
65125
65596
|
* single-hopper models. */
|
|
65126
65597
|
food1: number().nullable().meta(readingMeta("none")),
|
|
@@ -65128,8 +65599,8 @@ var PetFeederStatusSchema = object({
|
|
|
65128
65599
|
* single-hopper models. */
|
|
65129
65600
|
food2: number().nullable().meta(readingMeta("none")),
|
|
65130
65601
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
65131
|
-
* (`device_class: problem`, on = low). True when the
|
|
65132
|
-
*
|
|
65602
|
+
* (`device_class: problem`, on = low). True when the tank reports empty,
|
|
65603
|
+
* or, on a dual-hopper model, when EITHER hopper is empty. */
|
|
65133
65604
|
lowFood: boolean(),
|
|
65134
65605
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
65135
65606
|
* device has no battery reading. */
|
|
@@ -65197,7 +65668,9 @@ var petFeederCapability = {
|
|
|
65197
65668
|
kind: "mutation",
|
|
65198
65669
|
auth: "protected"
|
|
65199
65670
|
}),
|
|
65200
|
-
/**
|
|
65671
|
+
/** Tell the PetKit cloud a hopper was refilled so it stops its low-food
|
|
65672
|
+
* reminders (D4H/D4S/D4SH only — see `supportsMarkRefilled`). It does not
|
|
65673
|
+
* change any sensor reading. */
|
|
65201
65674
|
markFoodReplenished: method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
65202
65675
|
kind: "mutation",
|
|
65203
65676
|
auth: "protected"
|
|
@@ -65270,6 +65743,7 @@ var petFeederCapability = {
|
|
|
65270
65743
|
*/
|
|
65271
65744
|
history: { fields: {
|
|
65272
65745
|
foodLevel: { kind: "gauge" },
|
|
65746
|
+
bowlFood: { kind: "gauge" },
|
|
65273
65747
|
food1: { kind: "gauge" },
|
|
65274
65748
|
food2: { kind: "gauge" },
|
|
65275
65749
|
batteryPower: {
|
|
@@ -65679,16 +66153,16 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
65679
66153
|
* in real-world devices.
|
|
65680
66154
|
*/
|
|
65681
66155
|
var PowerMeterStatusSchema = object({
|
|
65682
|
-
/** Instantaneous power draw
|
|
65683
|
-
|
|
66156
|
+
/** Instantaneous power draw (watts). */
|
|
66157
|
+
power: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
65684
66158
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
65685
|
-
|
|
65686
|
-
/** Voltage
|
|
65687
|
-
|
|
66159
|
+
energy: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
66160
|
+
/** Voltage (volts). */
|
|
66161
|
+
voltage: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
65688
66162
|
/** Current in amperes. */
|
|
65689
|
-
|
|
66163
|
+
current: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
65690
66164
|
/** Apparent power in volt-amperes. */
|
|
65691
|
-
|
|
66165
|
+
apparentPower: number().optional().meta(readingMeta("apparent-power")),
|
|
65692
66166
|
/** Power factor (0..1) if reported. */
|
|
65693
66167
|
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
65694
66168
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -65746,14 +66220,14 @@ function powerTarget(id, unit) {
|
|
|
65746
66220
|
advancedExpression: true
|
|
65747
66221
|
};
|
|
65748
66222
|
}
|
|
65749
|
-
/** "Power and energy" extension:
|
|
66223
|
+
/** "Power and energy" extension: power, energy, voltage and current from other devices (D951). */
|
|
65750
66224
|
var powerMeterCustomize = {
|
|
65751
66225
|
version: 1,
|
|
65752
66226
|
targets: [
|
|
65753
|
-
powerTarget("
|
|
65754
|
-
powerTarget("
|
|
65755
|
-
powerTarget("
|
|
65756
|
-
powerTarget("
|
|
66227
|
+
powerTarget("power", "W"),
|
|
66228
|
+
powerTarget("energy", "kWh"),
|
|
66229
|
+
powerTarget("voltage", "V"),
|
|
66230
|
+
powerTarget("current", "A")
|
|
65757
66231
|
]
|
|
65758
66232
|
};
|
|
65759
66233
|
var powerMeterCapability = {
|
|
@@ -65769,41 +66243,41 @@ var powerMeterCapability = {
|
|
|
65769
66243
|
},
|
|
65770
66244
|
runtimeState: PowerMeterStatusSchema,
|
|
65771
66245
|
/**
|
|
65772
|
-
* Runtime-state durability: **restored** — as `numeric-sensor`; `
|
|
66246
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`; `energy` is an accumulator whose restored value is the baseline.
|
|
65773
66247
|
*
|
|
65774
66248
|
* See `RuntimeStateDurability`. Enforced by
|
|
65775
66249
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65776
66250
|
*/
|
|
65777
66251
|
durability: "restored",
|
|
65778
66252
|
/**
|
|
65779
|
-
* History (D850): recorded series. Gauges are floored at 30 s; `
|
|
66253
|
+
* History (D850): recorded series. Gauges are floored at 30 s; `energy` is the one monotonic meter (counter).
|
|
65780
66254
|
*/
|
|
65781
66255
|
history: { fields: {
|
|
65782
|
-
|
|
66256
|
+
power: {
|
|
65783
66257
|
kind: "gauge",
|
|
65784
66258
|
unit: "W",
|
|
65785
66259
|
deadband: 1,
|
|
65786
66260
|
minIntervalMs: 3e4
|
|
65787
66261
|
},
|
|
65788
|
-
|
|
66262
|
+
energy: {
|
|
65789
66263
|
kind: "counter",
|
|
65790
66264
|
unit: "kWh",
|
|
65791
66265
|
deadband: .01,
|
|
65792
66266
|
minIntervalMs: 6e4
|
|
65793
66267
|
},
|
|
65794
|
-
|
|
66268
|
+
voltage: {
|
|
65795
66269
|
kind: "gauge",
|
|
65796
66270
|
unit: "V",
|
|
65797
66271
|
deadband: 1,
|
|
65798
66272
|
minIntervalMs: 3e4
|
|
65799
66273
|
},
|
|
65800
|
-
|
|
66274
|
+
current: {
|
|
65801
66275
|
kind: "gauge",
|
|
65802
66276
|
unit: "A",
|
|
65803
66277
|
deadband: .05,
|
|
65804
66278
|
minIntervalMs: 3e4
|
|
65805
66279
|
},
|
|
65806
|
-
|
|
66280
|
+
apparentPower: {
|
|
65807
66281
|
kind: "gauge",
|
|
65808
66282
|
unit: "VA",
|
|
65809
66283
|
deadband: 1,
|
|
@@ -65853,9 +66327,6 @@ var PresenceStatusSchema = object({
|
|
|
65853
66327
|
location: string().nullable(),
|
|
65854
66328
|
/** GPS coordinates when available. Null otherwise. */
|
|
65855
66329
|
gps: GpsLocationSchema.nullable(),
|
|
65856
|
-
/** Optional battery level of the tracking device (0..100). Null
|
|
65857
|
-
* when not reported. */
|
|
65858
|
-
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65859
66330
|
/** Ms epoch when the slice was last updated. */
|
|
65860
66331
|
lastChangedAt: number()
|
|
65861
66332
|
});
|
|
@@ -65884,14 +66355,7 @@ var presenceCapability = {
|
|
|
65884
66355
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65885
66356
|
*/
|
|
65886
66357
|
durability: "restored",
|
|
65887
|
-
|
|
65888
|
-
* History (D850): recorded series.
|
|
65889
|
-
*/
|
|
65890
|
-
history: { fields: { batteryPercent: {
|
|
65891
|
-
kind: "gauge",
|
|
65892
|
-
unit: "%",
|
|
65893
|
-
deadband: 1
|
|
65894
|
-
} } },
|
|
66358
|
+
history: "none",
|
|
65895
66359
|
/** Clock fields: written, but excluded from the compare that decides
|
|
65896
66360
|
* whether persisting is worth a SQLite commit. */
|
|
65897
66361
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -65906,7 +66370,7 @@ var presenceCapability = {
|
|
|
65906
66370
|
*/
|
|
65907
66371
|
var PressureSensorStatusSchema = object({
|
|
65908
66372
|
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
65909
|
-
|
|
66373
|
+
pressure: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
65910
66374
|
/** Ms epoch when the slice was last updated. */
|
|
65911
66375
|
lastFetchedAt: number()
|
|
65912
66376
|
});
|
|
@@ -65932,7 +66396,7 @@ var pressureSensorCapability = {
|
|
|
65932
66396
|
/**
|
|
65933
66397
|
* History (D850): recorded series.
|
|
65934
66398
|
*/
|
|
65935
|
-
history: { fields: {
|
|
66399
|
+
history: { fields: { pressure: {
|
|
65936
66400
|
kind: "gauge",
|
|
65937
66401
|
unit: "hPa",
|
|
65938
66402
|
deadband: .1
|
|
@@ -70135,7 +70599,7 @@ var tamperCapability = {
|
|
|
70135
70599
|
*/
|
|
70136
70600
|
var TemperatureSensorStatusSchema = object({
|
|
70137
70601
|
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
70138
|
-
|
|
70602
|
+
temperature: number().nullable().meta(readingMeta("temperature", {
|
|
70139
70603
|
precision: 1,
|
|
70140
70604
|
label: "Temperature"
|
|
70141
70605
|
})),
|
|
@@ -70164,7 +70628,7 @@ var temperatureSensorCapability = {
|
|
|
70164
70628
|
/**
|
|
70165
70629
|
* History (D850): recorded series.
|
|
70166
70630
|
*/
|
|
70167
|
-
history: { fields: {
|
|
70631
|
+
history: { fields: { temperature: {
|
|
70168
70632
|
kind: "gauge",
|
|
70169
70633
|
unit: "°C",
|
|
70170
70634
|
deadband: .1
|
|
@@ -70461,7 +70925,7 @@ var VacuumControlStatusSchema = object({
|
|
|
70461
70925
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
70462
70926
|
availableFanSpeeds: array(string()),
|
|
70463
70927
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
70464
|
-
|
|
70928
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
70465
70929
|
/** Current error code (0 / null = no error). */
|
|
70466
70930
|
errorCode: number().nullable().meta(readingMeta("none")),
|
|
70467
70931
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
@@ -72263,7 +72727,7 @@ var BaseDevice = class {
|
|
|
72263
72727
|
* `device-local-state.ts`. Drivers access via:
|
|
72264
72728
|
*
|
|
72265
72729
|
* `this.state.battery.sleeping = true` // patches the battery slice
|
|
72266
|
-
* `const pct = this.state.battery.
|
|
72730
|
+
* `const pct = this.state.battery.level` // reads the battery slice
|
|
72267
72731
|
* `this.state.deviceStatus.online = true` // mirrors `markOnline(true)`
|
|
72268
72732
|
*
|
|
72269
72733
|
* Adding a new cap with `runtimeState:` automatically extends this
|
|
@@ -72303,7 +72767,7 @@ var BaseDevice = class {
|
|
|
72303
72767
|
* shape; drivers don't redeclare it, they just write through.
|
|
72304
72768
|
*
|
|
72305
72769
|
* Read: `this.runtimeState.getCapState('battery')` →
|
|
72306
|
-
* `{
|
|
72770
|
+
* `{level, charging, sleeping, lastUpdated}` for any
|
|
72307
72771
|
* provider that registers `batteryCapability`.
|
|
72308
72772
|
* Write: `this.runtimeState.setCapState('battery', { … })`.
|
|
72309
72773
|
*
|
|
@@ -73477,6 +73941,104 @@ Object.freeze({
|
|
|
73477
73941
|
access: "create",
|
|
73478
73942
|
role: "admin"
|
|
73479
73943
|
},
|
|
73944
|
+
"actions.create": {
|
|
73945
|
+
capName: "actions",
|
|
73946
|
+
capScope: "system",
|
|
73947
|
+
addonId: null,
|
|
73948
|
+
access: "create",
|
|
73949
|
+
role: "admin"
|
|
73950
|
+
},
|
|
73951
|
+
"actions.delete": {
|
|
73952
|
+
capName: "actions",
|
|
73953
|
+
capScope: "system",
|
|
73954
|
+
addonId: null,
|
|
73955
|
+
access: "delete",
|
|
73956
|
+
role: "admin"
|
|
73957
|
+
},
|
|
73958
|
+
"actions.get": {
|
|
73959
|
+
capName: "actions",
|
|
73960
|
+
capScope: "system",
|
|
73961
|
+
addonId: null,
|
|
73962
|
+
access: "view",
|
|
73963
|
+
role: "viewer"
|
|
73964
|
+
},
|
|
73965
|
+
"actions.getLinks": {
|
|
73966
|
+
capName: "actions",
|
|
73967
|
+
capScope: "system",
|
|
73968
|
+
addonId: null,
|
|
73969
|
+
access: "view",
|
|
73970
|
+
role: "admin"
|
|
73971
|
+
},
|
|
73972
|
+
"actions.getTraces": {
|
|
73973
|
+
capName: "actions",
|
|
73974
|
+
capScope: "system",
|
|
73975
|
+
addonId: null,
|
|
73976
|
+
access: "view",
|
|
73977
|
+
role: "admin"
|
|
73978
|
+
},
|
|
73979
|
+
"actions.list": {
|
|
73980
|
+
capName: "actions",
|
|
73981
|
+
capScope: "system",
|
|
73982
|
+
addonId: null,
|
|
73983
|
+
access: "view",
|
|
73984
|
+
role: "admin"
|
|
73985
|
+
},
|
|
73986
|
+
"actions.listForCamera": {
|
|
73987
|
+
capName: "actions",
|
|
73988
|
+
capScope: "system",
|
|
73989
|
+
addonId: null,
|
|
73990
|
+
access: "view",
|
|
73991
|
+
role: "viewer"
|
|
73992
|
+
},
|
|
73993
|
+
"actions.run": {
|
|
73994
|
+
capName: "actions",
|
|
73995
|
+
capScope: "system",
|
|
73996
|
+
addonId: null,
|
|
73997
|
+
access: "create",
|
|
73998
|
+
role: "viewer"
|
|
73999
|
+
},
|
|
74000
|
+
"actions.setLinks": {
|
|
74001
|
+
capName: "actions",
|
|
74002
|
+
capScope: "system",
|
|
74003
|
+
addonId: null,
|
|
74004
|
+
access: "create",
|
|
74005
|
+
role: "admin"
|
|
74006
|
+
},
|
|
74007
|
+
"actions.stop": {
|
|
74008
|
+
capName: "actions",
|
|
74009
|
+
capScope: "system",
|
|
74010
|
+
addonId: null,
|
|
74011
|
+
access: "create",
|
|
74012
|
+
role: "admin"
|
|
74013
|
+
},
|
|
74014
|
+
"actions.update": {
|
|
74015
|
+
capName: "actions",
|
|
74016
|
+
capScope: "system",
|
|
74017
|
+
addonId: null,
|
|
74018
|
+
access: "create",
|
|
74019
|
+
role: "admin"
|
|
74020
|
+
},
|
|
74021
|
+
"actionSource.listActions": {
|
|
74022
|
+
capName: "action-source",
|
|
74023
|
+
capScope: "system",
|
|
74024
|
+
addonId: null,
|
|
74025
|
+
access: "view",
|
|
74026
|
+
role: "admin"
|
|
74027
|
+
},
|
|
74028
|
+
"actionSource.runAction": {
|
|
74029
|
+
capName: "action-source",
|
|
74030
|
+
capScope: "system",
|
|
74031
|
+
addonId: null,
|
|
74032
|
+
access: "create",
|
|
74033
|
+
role: "admin"
|
|
74034
|
+
},
|
|
74035
|
+
"actionSource.stopAction": {
|
|
74036
|
+
capName: "action-source",
|
|
74037
|
+
capScope: "system",
|
|
74038
|
+
addonId: null,
|
|
74039
|
+
access: "create",
|
|
74040
|
+
role: "admin"
|
|
74041
|
+
},
|
|
73480
74042
|
"addonPages.listPages": {
|
|
73481
74043
|
capName: "addon-pages",
|
|
73482
74044
|
capScope: "system",
|
|
@@ -74758,6 +75320,13 @@ Object.freeze({
|
|
|
74758
75320
|
access: "view",
|
|
74759
75321
|
role: "admin"
|
|
74760
75322
|
},
|
|
75323
|
+
"coreBlocks.getAutomationRunState": {
|
|
75324
|
+
capName: "core-blocks",
|
|
75325
|
+
capScope: "system",
|
|
75326
|
+
addonId: null,
|
|
75327
|
+
access: "view",
|
|
75328
|
+
role: "admin"
|
|
75329
|
+
},
|
|
74761
75330
|
"coreBlocks.getBlockSettings": {
|
|
74762
75331
|
capName: "core-blocks",
|
|
74763
75332
|
capScope: "system",
|
|
@@ -74779,6 +75348,13 @@ Object.freeze({
|
|
|
74779
75348
|
access: "view",
|
|
74780
75349
|
role: "admin"
|
|
74781
75350
|
},
|
|
75351
|
+
"coreBlocks.getTraces": {
|
|
75352
|
+
capName: "core-blocks",
|
|
75353
|
+
capScope: "system",
|
|
75354
|
+
addonId: null,
|
|
75355
|
+
access: "view",
|
|
75356
|
+
role: "admin"
|
|
75357
|
+
},
|
|
74782
75358
|
"coreBlocks.getTypeDefs": {
|
|
74783
75359
|
capName: "core-blocks",
|
|
74784
75360
|
capScope: "system",
|
|
@@ -74814,6 +75390,13 @@ Object.freeze({
|
|
|
74814
75390
|
access: "create",
|
|
74815
75391
|
role: "admin"
|
|
74816
75392
|
},
|
|
75393
|
+
"coreBlocks.reportAutomationRun": {
|
|
75394
|
+
capName: "core-blocks",
|
|
75395
|
+
capScope: "system",
|
|
75396
|
+
addonId: null,
|
|
75397
|
+
access: "create",
|
|
75398
|
+
role: "admin"
|
|
75399
|
+
},
|
|
74817
75400
|
"coreBlocks.restart": {
|
|
74818
75401
|
capName: "core-blocks",
|
|
74819
75402
|
capScope: "system",
|
|
@@ -83387,7 +83970,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83387
83970
|
label: t("Full brightness", "Luminosità massima"),
|
|
83388
83971
|
phrase: t("Set {device} to full brightness", "Porta {device} alla massima luminosità"),
|
|
83389
83972
|
icon: "sun",
|
|
83390
|
-
args: {
|
|
83973
|
+
args: { level: 100 }
|
|
83391
83974
|
},
|
|
83392
83975
|
{
|
|
83393
83976
|
id: "brightness.half",
|
|
@@ -83395,7 +83978,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83395
83978
|
label: t("Half brightness", "Luminosità a metà"),
|
|
83396
83979
|
phrase: t("Dim {device} to half", "Abbassa {device} a metà luminosità"),
|
|
83397
83980
|
icon: "sun-dim",
|
|
83398
|
-
args: {
|
|
83981
|
+
args: { level: 50 }
|
|
83399
83982
|
},
|
|
83400
83983
|
{
|
|
83401
83984
|
id: "brightness.off",
|
|
@@ -83403,16 +83986,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83403
83986
|
label: t("Brightness off", "Luminosità a zero"),
|
|
83404
83987
|
phrase: t("Dim {device} to zero", "Abbassa {device} a zero"),
|
|
83405
83988
|
icon: "lightbulb-off",
|
|
83406
|
-
args: {
|
|
83989
|
+
args: { level: 0 }
|
|
83407
83990
|
},
|
|
83408
83991
|
{
|
|
83409
83992
|
id: "brightness.set",
|
|
83410
83993
|
method: "setBrightness",
|
|
83411
83994
|
label: t("Set brightness", "Imposta la luminosità"),
|
|
83412
|
-
phrase: t("Set the brightness of {device} to {
|
|
83995
|
+
phrase: t("Set the brightness of {device} to {level}", "Imposta la luminosità di {device} a {level}"),
|
|
83413
83996
|
icon: "sun-medium",
|
|
83414
83997
|
openArgs: [{
|
|
83415
|
-
key: "
|
|
83998
|
+
key: "level",
|
|
83416
83999
|
label: PERCENT,
|
|
83417
84000
|
offer: {
|
|
83418
84001
|
kind: "number",
|
|
@@ -83426,13 +84009,13 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83426
84009
|
],
|
|
83427
84010
|
state: [{
|
|
83428
84011
|
kind: "numeric",
|
|
83429
|
-
field: "
|
|
84012
|
+
field: "level",
|
|
83430
84013
|
quantity: t("the brightness", "la luminosità"),
|
|
83431
84014
|
label: t("Brightness", "Luminosità"),
|
|
83432
84015
|
unit: "%",
|
|
83433
84016
|
icon: "sun"
|
|
83434
84017
|
}],
|
|
83435
|
-
events: { onBrightnessChanged: { notOperatorFacing: "the `
|
|
84018
|
+
events: { onBrightnessChanged: { notOperatorFacing: "the `level` state trigger reads the same change" } }
|
|
83436
84019
|
},
|
|
83437
84020
|
color: {
|
|
83438
84021
|
scope: "device",
|
|
@@ -83446,7 +84029,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83446
84029
|
icon: "sun",
|
|
83447
84030
|
args: { color: {
|
|
83448
84031
|
mode: "mired",
|
|
83449
|
-
|
|
84032
|
+
colorTemperature: 370
|
|
83450
84033
|
} }
|
|
83451
84034
|
},
|
|
83452
84035
|
{
|
|
@@ -83457,7 +84040,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83457
84040
|
icon: "snowflake",
|
|
83458
84041
|
args: { color: {
|
|
83459
84042
|
mode: "mired",
|
|
83460
|
-
|
|
84043
|
+
colorTemperature: 200
|
|
83461
84044
|
} }
|
|
83462
84045
|
},
|
|
83463
84046
|
{
|
|
@@ -84071,7 +84654,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
84071
84654
|
label: t("Fan off", "Ventilatore spento"),
|
|
84072
84655
|
phrase: t("Stop {device}", "Ferma {device}"),
|
|
84073
84656
|
icon: "power-off",
|
|
84074
|
-
args: {
|
|
84657
|
+
args: { speed: 0 }
|
|
84075
84658
|
},
|
|
84076
84659
|
{
|
|
84077
84660
|
id: "fan.full",
|
|
@@ -84079,16 +84662,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
84079
84662
|
label: t("Fan full", "Ventilatore al massimo"),
|
|
84080
84663
|
phrase: t("Run {device} at full speed", "Porta {device} alla massima velocità"),
|
|
84081
84664
|
icon: "fan",
|
|
84082
|
-
args: {
|
|
84665
|
+
args: { speed: 100 }
|
|
84083
84666
|
},
|
|
84084
84667
|
{
|
|
84085
84668
|
id: "fan.speed",
|
|
84086
84669
|
method: "setPercentage",
|
|
84087
84670
|
label: t("Set speed", "Imposta la velocità"),
|
|
84088
|
-
phrase: t("Set the speed of {device} to {
|
|
84671
|
+
phrase: t("Set the speed of {device} to {speed}", "Imposta la velocità di {device} al {speed}"),
|
|
84089
84672
|
icon: "fan",
|
|
84090
84673
|
openArgs: [{
|
|
84091
|
-
key: "
|
|
84674
|
+
key: "speed",
|
|
84092
84675
|
label: t("Speed", "Velocità"),
|
|
84093
84676
|
offer: {
|
|
84094
84677
|
kind: "number",
|
|
@@ -84150,7 +84733,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
84150
84733
|
],
|
|
84151
84734
|
state: [{
|
|
84152
84735
|
kind: "numeric",
|
|
84153
|
-
field: "
|
|
84736
|
+
field: "speed",
|
|
84154
84737
|
quantity: t("the speed", "la velocità"),
|
|
84155
84738
|
label: t("Speed", "Velocità"),
|
|
84156
84739
|
unit: "%",
|
|
@@ -84948,7 +85531,7 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
84948
85531
|
},
|
|
84949
85532
|
{
|
|
84950
85533
|
kind: "numeric",
|
|
84951
|
-
field: "
|
|
85534
|
+
field: "progress",
|
|
84952
85535
|
quantity: t("the cycle progress", "l’avanzamento del lavaggio"),
|
|
84953
85536
|
label: t("Progress", "Avanzamento"),
|
|
84954
85537
|
unit: "%",
|
|
@@ -85306,10 +85889,10 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
85306
85889
|
id: "media.seek",
|
|
85307
85890
|
method: "seek",
|
|
85308
85891
|
label: t("Seek", "Vai al punto"),
|
|
85309
|
-
phrase: t("Move {device} to {
|
|
85892
|
+
phrase: t("Move {device} to {position}", "Porta {device} al punto {position}"),
|
|
85310
85893
|
icon: "fast-forward",
|
|
85311
85894
|
openArgs: [{
|
|
85312
|
-
key: "
|
|
85895
|
+
key: "position",
|
|
85313
85896
|
label: t("Position", "Posizione"),
|
|
85314
85897
|
offer: {
|
|
85315
85898
|
kind: "number",
|
|
@@ -86358,7 +86941,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86358
86941
|
state: [
|
|
86359
86942
|
{
|
|
86360
86943
|
kind: "numeric",
|
|
86361
|
-
field: "
|
|
86944
|
+
field: "co2",
|
|
86362
86945
|
quantity: t("the CO₂", "la CO₂"),
|
|
86363
86946
|
label: t("CO₂", "CO₂"),
|
|
86364
86947
|
unit: "ppm",
|
|
@@ -86366,7 +86949,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86366
86949
|
},
|
|
86367
86950
|
{
|
|
86368
86951
|
kind: "numeric",
|
|
86369
|
-
field: "
|
|
86952
|
+
field: "voc",
|
|
86370
86953
|
quantity: t("the VOC level", "il livello di COV"),
|
|
86371
86954
|
label: t("VOC", "COV"),
|
|
86372
86955
|
unit: "ppb",
|
|
@@ -86402,7 +86985,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86402
86985
|
noun: t("Light level", "Luminosità ambiente"),
|
|
86403
86986
|
state: [{
|
|
86404
86987
|
kind: "numeric",
|
|
86405
|
-
field: "
|
|
86988
|
+
field: "illuminance",
|
|
86406
86989
|
quantity: t("the light level", "la luminosità"),
|
|
86407
86990
|
label: t("Illuminance", "Illuminamento"),
|
|
86408
86991
|
unit: "lx",
|
|
@@ -86605,7 +87188,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86605
87188
|
noun: t("Humidity", "Umidità"),
|
|
86606
87189
|
state: [{
|
|
86607
87190
|
kind: "numeric",
|
|
86608
|
-
field: "
|
|
87191
|
+
field: "humidity",
|
|
86609
87192
|
quantity: t("the humidity", "l’umidità"),
|
|
86610
87193
|
label: t("Humidity", "Umidità"),
|
|
86611
87194
|
unit: "%",
|
|
@@ -86653,7 +87236,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86653
87236
|
state: [
|
|
86654
87237
|
{
|
|
86655
87238
|
kind: "numeric",
|
|
86656
|
-
field: "
|
|
87239
|
+
field: "power",
|
|
86657
87240
|
quantity: t("the power draw", "il consumo"),
|
|
86658
87241
|
label: t("Power", "Potenza"),
|
|
86659
87242
|
unit: "W",
|
|
@@ -86661,7 +87244,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86661
87244
|
},
|
|
86662
87245
|
{
|
|
86663
87246
|
kind: "numeric",
|
|
86664
|
-
field: "
|
|
87247
|
+
field: "energy",
|
|
86665
87248
|
quantity: t("the energy used", "l’energia consumata"),
|
|
86666
87249
|
label: t("Energy", "Energia"),
|
|
86667
87250
|
unit: "kWh",
|
|
@@ -86669,7 +87252,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86669
87252
|
},
|
|
86670
87253
|
{
|
|
86671
87254
|
kind: "numeric",
|
|
86672
|
-
field: "
|
|
87255
|
+
field: "voltage",
|
|
86673
87256
|
quantity: t("the voltage", "la tensione"),
|
|
86674
87257
|
label: t("Voltage", "Tensione"),
|
|
86675
87258
|
unit: "V",
|
|
@@ -86677,7 +87260,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86677
87260
|
},
|
|
86678
87261
|
{
|
|
86679
87262
|
kind: "numeric",
|
|
86680
|
-
field: "
|
|
87263
|
+
field: "current",
|
|
86681
87264
|
quantity: t("the current", "la corrente"),
|
|
86682
87265
|
label: t("Current", "Corrente"),
|
|
86683
87266
|
unit: "A",
|
|
@@ -86694,13 +87277,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86694
87277
|
label: t("Where", "Posizione"),
|
|
86695
87278
|
phrase: t("When {device} is at {value}", "Quando {device} è in {value}"),
|
|
86696
87279
|
icon: "map-pin"
|
|
86697
|
-
}, {
|
|
86698
|
-
kind: "numeric",
|
|
86699
|
-
field: "batteryPercent",
|
|
86700
|
-
quantity: t("the phone battery", "la batteria del telefono"),
|
|
86701
|
-
label: t("Battery", "Batteria"),
|
|
86702
|
-
unit: "%",
|
|
86703
|
-
icon: "battery"
|
|
86704
87280
|
}]
|
|
86705
87281
|
},
|
|
86706
87282
|
"pressure-sensor": {
|
|
@@ -86708,7 +87284,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86708
87284
|
noun: t("Pressure", "Pressione"),
|
|
86709
87285
|
state: [{
|
|
86710
87286
|
kind: "numeric",
|
|
86711
|
-
field: "
|
|
87287
|
+
field: "pressure",
|
|
86712
87288
|
quantity: t("the pressure", "la pressione"),
|
|
86713
87289
|
label: t("Pressure", "Pressione"),
|
|
86714
87290
|
unit: "hPa",
|
|
@@ -86744,7 +87320,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86744
87320
|
noun: t("Temperature", "Temperatura"),
|
|
86745
87321
|
state: [{
|
|
86746
87322
|
kind: "numeric",
|
|
86747
|
-
field: "
|
|
87323
|
+
field: "temperature",
|
|
86748
87324
|
quantity: t("the temperature", "la temperatura"),
|
|
86749
87325
|
label: t("Temperature", "Temperatura"),
|
|
86750
87326
|
unit: "°C",
|
|
@@ -86815,7 +87391,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86815
87391
|
state: [
|
|
86816
87392
|
{
|
|
86817
87393
|
kind: "numeric",
|
|
86818
|
-
field: "
|
|
87394
|
+
field: "level",
|
|
86819
87395
|
quantity: t("the battery level", "il livello della batteria"),
|
|
86820
87396
|
label: t("Battery", "Batteria"),
|
|
86821
87397
|
unit: "%",
|
|
@@ -86857,7 +87433,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86857
87433
|
icon: "battery-charging"
|
|
86858
87434
|
}
|
|
86859
87435
|
],
|
|
86860
|
-
events: { onStatusChanged: { notOperatorFacing: "the
|
|
87436
|
+
events: { onStatusChanged: { notOperatorFacing: "the level / sleeping / charging state triggers each read one field of this change" } },
|
|
86861
87437
|
extraEvents: [{
|
|
86862
87438
|
category: EventCategory.DeviceAwake,
|
|
86863
87439
|
label: t("Woke up", "Risvegliato"),
|
|
@@ -86875,7 +87451,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86875
87451
|
noun: t("Network link", "Collegamento di rete"),
|
|
86876
87452
|
state: [{
|
|
86877
87453
|
kind: "numeric",
|
|
86878
|
-
field: "
|
|
87454
|
+
field: "signal",
|
|
86879
87455
|
quantity: t("the signal strength", "l’intensità del segnale"),
|
|
86880
87456
|
label: t("Signal", "Segnale"),
|
|
86881
87457
|
unit: "%",
|
|
@@ -86968,6 +87544,8 @@ var ML = "model and training machinery — no device action";
|
|
|
86968
87544
|
var INTERNAL = "internal plumbing between addons — never operator-facing";
|
|
86969
87545
|
/** Every system-scoped cap, with why it is not a device's vocabulary. */
|
|
86970
87546
|
var SYSTEM_CAP_VOCABULARY = {
|
|
87547
|
+
"action-source": system(INTERNAL),
|
|
87548
|
+
actions: system("declared actions — run from the Actions page and from the cameras that link them"),
|
|
86971
87549
|
"addon-pages": system(UI_PLUMBING),
|
|
86972
87550
|
"addon-pages-source": system(UI_PLUMBING),
|
|
86973
87551
|
"addon-routes": system(UI_PLUMBING),
|
|
@@ -87316,6 +87894,31 @@ Object.freeze({
|
|
|
87316
87894
|
form: "single",
|
|
87317
87895
|
optional: false
|
|
87318
87896
|
}],
|
|
87897
|
+
"actions.get": [{
|
|
87898
|
+
name: "deviceId",
|
|
87899
|
+
form: "single",
|
|
87900
|
+
optional: true
|
|
87901
|
+
}],
|
|
87902
|
+
"actions.getLinks": [{
|
|
87903
|
+
name: "deviceId",
|
|
87904
|
+
form: "single",
|
|
87905
|
+
optional: false
|
|
87906
|
+
}],
|
|
87907
|
+
"actions.listForCamera": [{
|
|
87908
|
+
name: "deviceId",
|
|
87909
|
+
form: "single",
|
|
87910
|
+
optional: false
|
|
87911
|
+
}],
|
|
87912
|
+
"actions.run": [{
|
|
87913
|
+
name: "deviceId",
|
|
87914
|
+
form: "single",
|
|
87915
|
+
optional: true
|
|
87916
|
+
}],
|
|
87917
|
+
"actions.setLinks": [{
|
|
87918
|
+
name: "deviceId",
|
|
87919
|
+
form: "single",
|
|
87920
|
+
optional: false
|
|
87921
|
+
}],
|
|
87319
87922
|
"addonSettings.getDeviceSettings": [{
|
|
87320
87923
|
name: "deviceId",
|
|
87321
87924
|
form: "single",
|
|
@@ -91448,6 +92051,7 @@ DEFAULT_NATIVE_LEASE_SETTINGS.activityMs;
|
|
|
91448
92051
|
DEFAULT_NATIVE_LEASE_SETTINGS.tileBudgetMb;
|
|
91449
92052
|
DEFAULT_NATIVE_LEASE_SETTINGS.sceneBudgetMb;
|
|
91450
92053
|
DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
92054
|
+
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
91451
92055
|
var MB = 1024 * 1024;
|
|
91452
92056
|
1024 * MB, 3072 * MB;
|
|
91453
92057
|
//#endregion
|
|
@@ -200817,7 +201421,7 @@ var FloodlightAccessory = class extends BaseDevice {
|
|
|
200817
201421
|
lastChangedAt: ts
|
|
200818
201422
|
});
|
|
200819
201423
|
if (brightness !== void 0) this.setCapSlice(brightnessCapability, {
|
|
200820
|
-
|
|
201424
|
+
level: brightness,
|
|
200821
201425
|
lastChangedAt: ts
|
|
200822
201426
|
});
|
|
200823
201427
|
this.hasFetchedFromFirmware = true;
|
|
@@ -200936,7 +201540,7 @@ var FloodlightAccessory = class extends BaseDevice {
|
|
|
200936
201540
|
}
|
|
200937
201541
|
brightnessView() {
|
|
200938
201542
|
return this.getCapSlice(brightnessCapability) ?? {
|
|
200939
|
-
|
|
201543
|
+
level: 100,
|
|
200940
201544
|
lastChangedAt: 0
|
|
200941
201545
|
};
|
|
200942
201546
|
}
|
|
@@ -200961,19 +201565,19 @@ var FloodlightAccessory = class extends BaseDevice {
|
|
|
200961
201565
|
registerBrightnessCap() {
|
|
200962
201566
|
this.ctx.registerNativeCap(brightnessCapability, {
|
|
200963
201567
|
getStatus: async () => this.brightnessView(),
|
|
200964
|
-
setBrightness: async ({ deviceId, percentage }) => {
|
|
201568
|
+
setBrightness: async ({ deviceId, level: percentage }) => {
|
|
200965
201569
|
if (deviceId !== this.id) return;
|
|
200966
201570
|
const value = Math.max(0, Math.min(100, percentage));
|
|
200967
201571
|
if (this.switchView().on) await (await this.api).setWhiteLedState(this.channel, void 0, value);
|
|
200968
201572
|
this.setCapSlice(brightnessCapability, {
|
|
200969
|
-
|
|
201573
|
+
level: value,
|
|
200970
201574
|
lastChangedAt: Date.now()
|
|
200971
201575
|
});
|
|
200972
201576
|
this.lastSetAtMs = Date.now();
|
|
200973
201577
|
}
|
|
200974
201578
|
});
|
|
200975
201579
|
this.setCapSlice(brightnessCapability, {
|
|
200976
|
-
|
|
201580
|
+
level: 100,
|
|
200977
201581
|
lastChangedAt: 0
|
|
200978
201582
|
});
|
|
200979
201583
|
}
|
|
@@ -201649,13 +202253,13 @@ function mapNetworkReadout(readout, now) {
|
|
|
201649
202253
|
const type = linkTypeOf(readout);
|
|
201650
202254
|
const raw = readout.wifiSignal;
|
|
201651
202255
|
const wireless = type === "wifi" || type === "cellular";
|
|
201652
|
-
const
|
|
202256
|
+
const signal = wireless ? signalPercentOf(raw) : null;
|
|
201653
202257
|
const rssiDbm = wireless && raw !== void 0 && Number.isFinite(raw) && raw < 0 ? raw : void 0;
|
|
201654
202258
|
const ssid = wireless && readout.ssid !== void 0 && readout.ssid !== "" ? readout.ssid : void 0;
|
|
201655
202259
|
return {
|
|
201656
202260
|
type,
|
|
201657
|
-
|
|
201658
|
-
...rssiDbm !== void 0 ? { rssiDbm } : {},
|
|
202261
|
+
signal,
|
|
202262
|
+
...rssiDbm !== void 0 ? { rssi: rssiDbm } : {},
|
|
201659
202263
|
...ssid !== void 0 ? { ssid } : {},
|
|
201660
202264
|
lastUpdated: now
|
|
201661
202265
|
};
|
|
@@ -204898,7 +205502,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
204898
205502
|
*/
|
|
204899
205503
|
mapBatteryInfo(info) {
|
|
204900
205504
|
return {
|
|
204901
|
-
|
|
205505
|
+
level: typeof info.batteryPercent === "number" ? Math.max(0, Math.min(100, Math.round(info.batteryPercent))) : this.state.battery.level ?? null,
|
|
204902
205506
|
charging: reportsPowerSource(info) ? deriveChargingSource(info.adapterStatus, info.chargeStatus) : this.state.battery.charging ?? "unknown",
|
|
204903
205507
|
sleeping: info.sleeping === true || this.sleeping,
|
|
204904
205508
|
lastUpdated: Date.now()
|
|
@@ -205034,7 +205638,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
205034
205638
|
}
|
|
205035
205639
|
});
|
|
205036
205640
|
if (this.getCapSlice(batteryCapability) === null) this.setCapSlice(batteryCapability, {
|
|
205037
|
-
|
|
205641
|
+
level: null,
|
|
205038
205642
|
charging: "none",
|
|
205039
205643
|
sleeping: false,
|
|
205040
205644
|
lastUpdated: Date.now()
|
|
@@ -205262,7 +205866,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
205262
205866
|
});
|
|
205263
205867
|
this.setCapSlice(batteryCapability, {
|
|
205264
205868
|
...this.state.battery,
|
|
205265
|
-
|
|
205869
|
+
level: mapped.level,
|
|
205266
205870
|
charging: mapped.charging,
|
|
205267
205871
|
lastUpdated: Date.now()
|
|
205268
205872
|
});
|