@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.mjs
CHANGED
|
@@ -28,7 +28,7 @@ import { URL as URL$1 } from "url";
|
|
|
28
28
|
import { spawn as spawn$1 } from "node:child_process";
|
|
29
29
|
import os, { tmpdir } from "node:os";
|
|
30
30
|
import { createReadStream } from "node:fs";
|
|
31
|
-
//#region ../types/dist/event-category-
|
|
31
|
+
//#region ../types/dist/event-category-DmZDPDf_.mjs
|
|
32
32
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
33
33
|
EventCategory["SystemBoot"] = "system.boot";
|
|
34
34
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -655,7 +655,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
655
655
|
* (a track was promoted to a stationary-registry entry) or departs (the
|
|
656
656
|
* object moved / was removed). Telemetry (D8): lossy, drives a UI refresh of
|
|
657
657
|
* the dedicated "Stationary" section — never the live event feed. Payload:
|
|
658
|
-
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp }`.
|
|
658
|
+
* `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp, observedAt, zones }`.
|
|
659
659
|
*/
|
|
660
660
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
661
661
|
/**
|
|
@@ -793,6 +793,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
793
793
|
*/
|
|
794
794
|
EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
|
|
795
795
|
/**
|
|
796
|
+
* An action run started or ended. Emitted by the `actions` surface.
|
|
797
|
+
* Payload: `ActionRunChanged` (`{ actionId, runId, isRunning, outcome?, lastRunAt, lastError }`).
|
|
798
|
+
*/
|
|
799
|
+
EventCategory["ActionsRunChanged"] = "actions.onRunChanged";
|
|
800
|
+
/**
|
|
796
801
|
* Progress update from a running model conversion job.
|
|
797
802
|
* Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
|
|
798
803
|
* Emitted by `addon-model-studio` on the converting node.
|
|
@@ -5471,7 +5476,7 @@ var ZodIssueCode = {
|
|
|
5471
5476
|
var ZodFirstPartyTypeKind;
|
|
5472
5477
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5473
5478
|
//#endregion
|
|
5474
|
-
//#region ../types/dist/sleep
|
|
5479
|
+
//#region ../types/dist/sleep-Crlmu_tO.mjs
|
|
5475
5480
|
/**
|
|
5476
5481
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5477
5482
|
* window to float samples (D455).
|
|
@@ -8629,6 +8634,8 @@ Object.freeze({ "doorbell": "lastPressedAt" });
|
|
|
8629
8634
|
/** Every capability name, so addon code can check a name without the schema graph. */
|
|
8630
8635
|
var CAP_NAMES = Object.freeze([
|
|
8631
8636
|
"accessories",
|
|
8637
|
+
"action-source",
|
|
8638
|
+
"actions",
|
|
8632
8639
|
"addon-pages",
|
|
8633
8640
|
"addon-pages-source",
|
|
8634
8641
|
"addon-routes",
|
|
@@ -8817,11 +8824,11 @@ var CAP_NAMES = Object.freeze([
|
|
|
8817
8824
|
Object.freeze({
|
|
8818
8825
|
"air-quality-sensor": [
|
|
8819
8826
|
{
|
|
8820
|
-
"path": "
|
|
8827
|
+
"path": "co2",
|
|
8821
8828
|
"valueType": "number"
|
|
8822
8829
|
},
|
|
8823
8830
|
{
|
|
8824
|
-
"path": "
|
|
8831
|
+
"path": "voc",
|
|
8825
8832
|
"valueType": "number"
|
|
8826
8833
|
},
|
|
8827
8834
|
{
|
|
@@ -8871,7 +8878,7 @@ Object.freeze({
|
|
|
8871
8878
|
}
|
|
8872
8879
|
],
|
|
8873
8880
|
"ambient-light-sensor": [{
|
|
8874
|
-
"path": "
|
|
8881
|
+
"path": "illuminance",
|
|
8875
8882
|
"valueType": "number"
|
|
8876
8883
|
}],
|
|
8877
8884
|
"audio-metrics": [
|
|
@@ -8932,7 +8939,7 @@ Object.freeze({
|
|
|
8932
8939
|
],
|
|
8933
8940
|
"battery": [
|
|
8934
8941
|
{
|
|
8935
|
-
"path": "
|
|
8942
|
+
"path": "level",
|
|
8936
8943
|
"valueType": "number"
|
|
8937
8944
|
},
|
|
8938
8945
|
{
|
|
@@ -8954,7 +8961,7 @@ Object.freeze({
|
|
|
8954
8961
|
"valueType": "number"
|
|
8955
8962
|
},
|
|
8956
8963
|
{
|
|
8957
|
-
"path": "
|
|
8964
|
+
"path": "voltage",
|
|
8958
8965
|
"valueType": "number"
|
|
8959
8966
|
},
|
|
8960
8967
|
{
|
|
@@ -8975,7 +8982,7 @@ Object.freeze({
|
|
|
8975
8982
|
"valueType": "boolean"
|
|
8976
8983
|
}],
|
|
8977
8984
|
"brightness": [{
|
|
8978
|
-
"path": "
|
|
8985
|
+
"path": "level",
|
|
8979
8986
|
"valueType": "number"
|
|
8980
8987
|
}],
|
|
8981
8988
|
"broker": [{
|
|
@@ -9176,7 +9183,7 @@ Object.freeze({
|
|
|
9176
9183
|
"valueType": "number"
|
|
9177
9184
|
},
|
|
9178
9185
|
{
|
|
9179
|
-
"path": "
|
|
9186
|
+
"path": "colorTemperature",
|
|
9180
9187
|
"valueType": "number"
|
|
9181
9188
|
}
|
|
9182
9189
|
],
|
|
@@ -9355,15 +9362,15 @@ Object.freeze({
|
|
|
9355
9362
|
"valueType": "string"
|
|
9356
9363
|
},
|
|
9357
9364
|
{
|
|
9358
|
-
"path": "
|
|
9365
|
+
"path": "remaining",
|
|
9359
9366
|
"valueType": "number"
|
|
9360
9367
|
},
|
|
9361
9368
|
{
|
|
9362
|
-
"path": "
|
|
9369
|
+
"path": "delayedStart",
|
|
9363
9370
|
"valueType": "number"
|
|
9364
9371
|
},
|
|
9365
9372
|
{
|
|
9366
|
-
"path": "
|
|
9373
|
+
"path": "progress",
|
|
9367
9374
|
"valueType": "number"
|
|
9368
9375
|
},
|
|
9369
9376
|
{
|
|
@@ -9477,7 +9484,7 @@ Object.freeze({
|
|
|
9477
9484
|
],
|
|
9478
9485
|
"fan-control": [
|
|
9479
9486
|
{
|
|
9480
|
-
"path": "
|
|
9487
|
+
"path": "speed",
|
|
9481
9488
|
"valueType": "number"
|
|
9482
9489
|
},
|
|
9483
9490
|
{
|
|
@@ -9577,7 +9584,7 @@ Object.freeze({
|
|
|
9577
9584
|
}
|
|
9578
9585
|
],
|
|
9579
9586
|
"humidity-sensor": [{
|
|
9580
|
-
"path": "
|
|
9587
|
+
"path": "humidity",
|
|
9581
9588
|
"valueType": "number"
|
|
9582
9589
|
}],
|
|
9583
9590
|
"image": [{
|
|
@@ -9687,7 +9694,7 @@ Object.freeze({
|
|
|
9687
9694
|
"valueType": "number"
|
|
9688
9695
|
},
|
|
9689
9696
|
{
|
|
9690
|
-
"path": "
|
|
9697
|
+
"path": "progress",
|
|
9691
9698
|
"valueType": "number"
|
|
9692
9699
|
},
|
|
9693
9700
|
{
|
|
@@ -9766,11 +9773,11 @@ Object.freeze({
|
|
|
9766
9773
|
"valueType": "string"
|
|
9767
9774
|
},
|
|
9768
9775
|
{
|
|
9769
|
-
"path": "
|
|
9776
|
+
"path": "position",
|
|
9770
9777
|
"valueType": "number"
|
|
9771
9778
|
},
|
|
9772
9779
|
{
|
|
9773
|
-
"path": "
|
|
9780
|
+
"path": "duration",
|
|
9774
9781
|
"valueType": "number"
|
|
9775
9782
|
},
|
|
9776
9783
|
{
|
|
@@ -9872,11 +9879,11 @@ Object.freeze({
|
|
|
9872
9879
|
]
|
|
9873
9880
|
},
|
|
9874
9881
|
{
|
|
9875
|
-
"path": "
|
|
9882
|
+
"path": "signal",
|
|
9876
9883
|
"valueType": "number"
|
|
9877
9884
|
},
|
|
9878
9885
|
{
|
|
9879
|
-
"path": "
|
|
9886
|
+
"path": "rssi",
|
|
9880
9887
|
"valueType": "number"
|
|
9881
9888
|
},
|
|
9882
9889
|
{
|
|
@@ -9931,6 +9938,18 @@ Object.freeze({
|
|
|
9931
9938
|
"path": "foodLevel",
|
|
9932
9939
|
"valueType": "number"
|
|
9933
9940
|
},
|
|
9941
|
+
{
|
|
9942
|
+
"path": "bowlFood",
|
|
9943
|
+
"valueType": "number"
|
|
9944
|
+
},
|
|
9945
|
+
{
|
|
9946
|
+
"path": "eating",
|
|
9947
|
+
"valueType": "boolean"
|
|
9948
|
+
},
|
|
9949
|
+
{
|
|
9950
|
+
"path": "supportsMarkRefilled",
|
|
9951
|
+
"valueType": "boolean"
|
|
9952
|
+
},
|
|
9934
9953
|
{
|
|
9935
9954
|
"path": "food1",
|
|
9936
9955
|
"valueType": "number"
|
|
@@ -9995,23 +10014,23 @@ Object.freeze({
|
|
|
9995
10014
|
],
|
|
9996
10015
|
"power-meter": [
|
|
9997
10016
|
{
|
|
9998
|
-
"path": "
|
|
10017
|
+
"path": "power",
|
|
9999
10018
|
"valueType": "number"
|
|
10000
10019
|
},
|
|
10001
10020
|
{
|
|
10002
|
-
"path": "
|
|
10021
|
+
"path": "energy",
|
|
10003
10022
|
"valueType": "number"
|
|
10004
10023
|
},
|
|
10005
10024
|
{
|
|
10006
|
-
"path": "
|
|
10025
|
+
"path": "voltage",
|
|
10007
10026
|
"valueType": "number"
|
|
10008
10027
|
},
|
|
10009
10028
|
{
|
|
10010
|
-
"path": "
|
|
10029
|
+
"path": "current",
|
|
10011
10030
|
"valueType": "number"
|
|
10012
10031
|
},
|
|
10013
10032
|
{
|
|
10014
|
-
"path": "
|
|
10033
|
+
"path": "apparentPower",
|
|
10015
10034
|
"valueType": "number"
|
|
10016
10035
|
},
|
|
10017
10036
|
{
|
|
@@ -10039,14 +10058,10 @@ Object.freeze({
|
|
|
10039
10058
|
{
|
|
10040
10059
|
"path": "gps.accuracyMeters",
|
|
10041
10060
|
"valueType": "number"
|
|
10042
|
-
},
|
|
10043
|
-
{
|
|
10044
|
-
"path": "batteryPercent",
|
|
10045
|
-
"valueType": "number"
|
|
10046
10061
|
}
|
|
10047
10062
|
],
|
|
10048
10063
|
"pressure-sensor": [{
|
|
10049
|
-
"path": "
|
|
10064
|
+
"path": "pressure",
|
|
10050
10065
|
"valueType": "number"
|
|
10051
10066
|
}],
|
|
10052
10067
|
"privacy-mask": [{
|
|
@@ -10360,7 +10375,7 @@ Object.freeze({
|
|
|
10360
10375
|
"valueType": "boolean"
|
|
10361
10376
|
}],
|
|
10362
10377
|
"temperature-sensor": [{
|
|
10363
|
-
"path": "
|
|
10378
|
+
"path": "temperature",
|
|
10364
10379
|
"valueType": "number"
|
|
10365
10380
|
}],
|
|
10366
10381
|
"update": [
|
|
@@ -10408,7 +10423,7 @@ Object.freeze({
|
|
|
10408
10423
|
"valueType": "string"
|
|
10409
10424
|
},
|
|
10410
10425
|
{
|
|
10411
|
-
"path": "
|
|
10426
|
+
"path": "progress",
|
|
10412
10427
|
"valueType": "number"
|
|
10413
10428
|
},
|
|
10414
10429
|
{
|
|
@@ -10921,7 +10936,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
10921
10936
|
return DeviceRole;
|
|
10922
10937
|
}({});
|
|
10923
10938
|
//#endregion
|
|
10924
|
-
//#region ../types/dist/composition-
|
|
10939
|
+
//#region ../types/dist/composition-CZImLpOI.mjs
|
|
10925
10940
|
/**
|
|
10926
10941
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
10927
10942
|
*
|
|
@@ -16011,6 +16026,14 @@ var AutomationConditionLeafSchema = object({
|
|
|
16011
16026
|
array(union([string(), number()]))
|
|
16012
16027
|
])
|
|
16013
16028
|
});
|
|
16029
|
+
var AutomationConditionStationaryPresentSchema = object({
|
|
16030
|
+
kind: literal("stationary-present"),
|
|
16031
|
+
deviceId: number().int().nonnegative(),
|
|
16032
|
+
/** Class names; a macro class matches every raw class that maps to it. */
|
|
16033
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
16034
|
+
/** The parked object must be in at least one of these zones. */
|
|
16035
|
+
zones: array(string().min(1)).min(1).optional()
|
|
16036
|
+
});
|
|
16014
16037
|
/**
|
|
16015
16038
|
* The expression leaf, declared as a plain object rather than an intersection
|
|
16016
16039
|
* with {@link ExpressionSourceSchema}: a discriminated union has to be able to
|
|
@@ -16044,7 +16067,8 @@ var AutomationConditionSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
16044
16067
|
child: AutomationConditionSchema
|
|
16045
16068
|
}),
|
|
16046
16069
|
AutomationConditionLeafSchema,
|
|
16047
|
-
AutomationConditionExpressionSchema
|
|
16070
|
+
AutomationConditionExpressionSchema,
|
|
16071
|
+
AutomationConditionStationaryPresentSchema
|
|
16048
16072
|
]));
|
|
16049
16073
|
/**
|
|
16050
16074
|
* What starts a run.
|
|
@@ -16085,7 +16109,34 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
16085
16109
|
kind: literal("schedule"),
|
|
16086
16110
|
cron: string().min(1).max(120)
|
|
16087
16111
|
}),
|
|
16088
|
-
object({ kind: literal("manual") })
|
|
16112
|
+
object({ kind: literal("manual") }),
|
|
16113
|
+
object({
|
|
16114
|
+
kind: literal("detection"),
|
|
16115
|
+
/** Class names. A macro class (`animal`, `vehicle`, `person`, `package`)
|
|
16116
|
+
* matches every raw class that maps to it; any other name matches
|
|
16117
|
+
* exactly. */
|
|
16118
|
+
classes: array(string().min(1)).min(1),
|
|
16119
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
16120
|
+
/** The track must have visited at least one of these zones. */
|
|
16121
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
16122
|
+
/** Best-so-far confidence the track must reach. */
|
|
16123
|
+
minScore: number().min(0).max(1).optional()
|
|
16124
|
+
}),
|
|
16125
|
+
object({
|
|
16126
|
+
kind: literal("stationary"),
|
|
16127
|
+
deviceIds: array(number().int().nonnegative()).min(1),
|
|
16128
|
+
/** Class names; a macro class matches like the detection trigger. */
|
|
16129
|
+
classes: array(string().min(1)).min(1).optional(),
|
|
16130
|
+
/** The parked object must be in at least one of these zones. */
|
|
16131
|
+
zones: array(string().min(1)).min(1).optional(),
|
|
16132
|
+
/** `appeared`: it became parked. `departed`: the registry retired it.
|
|
16133
|
+
* The vocabulary of `PipelineAnalyticsStationaryChanged`. */
|
|
16134
|
+
phase: _enum(["appeared", "departed"])
|
|
16135
|
+
}),
|
|
16136
|
+
object({
|
|
16137
|
+
kind: literal("interval"),
|
|
16138
|
+
minutes: number().int().min(1).max(1440)
|
|
16139
|
+
})
|
|
16089
16140
|
]);
|
|
16090
16141
|
/**
|
|
16091
16142
|
* One action step.
|
|
@@ -16105,28 +16156,47 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
|
|
|
16105
16156
|
* is called. The runner still receives a number and is untouched; the
|
|
16106
16157
|
* resolution is the recipe's job, not the runner's.
|
|
16107
16158
|
*/
|
|
16159
|
+
var AutomationWaitStepSchema = object({
|
|
16160
|
+
kind: literal("wait"),
|
|
16161
|
+
seconds: number().min(0).max(300)
|
|
16162
|
+
});
|
|
16163
|
+
var AutomationCapStepSchema = object({
|
|
16164
|
+
kind: literal("cap"),
|
|
16165
|
+
/**
|
|
16166
|
+
* One device, several same-family devices (locks / climate family / …),
|
|
16167
|
+
* or `{ $var }` for the device that triggered the run. An array is
|
|
16168
|
+
* fan-out at codegen — each id gets the same cap.method call.
|
|
16169
|
+
*/
|
|
16170
|
+
deviceId: union([
|
|
16171
|
+
number().int(),
|
|
16172
|
+
array(number().int()).min(1),
|
|
16173
|
+
object({ $var: string().min(1) })
|
|
16174
|
+
]),
|
|
16175
|
+
cap: string().min(1),
|
|
16176
|
+
method: string().min(1),
|
|
16177
|
+
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
16178
|
+
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
16179
|
+
* the expression leaf. */
|
|
16180
|
+
args: record(string(), unknown()).optional()
|
|
16181
|
+
});
|
|
16182
|
+
/**
|
|
16183
|
+
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
16184
|
+
* call back into an Action — so an Action can never reach itself (no cycles).
|
|
16185
|
+
*/
|
|
16186
|
+
var ActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepSchema]);
|
|
16108
16187
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
16188
|
+
AutomationWaitStepSchema,
|
|
16189
|
+
AutomationCapStepSchema,
|
|
16109
16190
|
object({
|
|
16110
|
-
kind: literal("
|
|
16111
|
-
|
|
16112
|
-
|
|
16113
|
-
|
|
16114
|
-
|
|
16115
|
-
|
|
16116
|
-
|
|
16117
|
-
|
|
16118
|
-
|
|
16119
|
-
*/
|
|
16120
|
-
deviceId: union([
|
|
16121
|
-
number().int(),
|
|
16122
|
-
array(number().int()).min(1),
|
|
16123
|
-
object({ $var: string().min(1) })
|
|
16124
|
-
]),
|
|
16125
|
-
cap: string().min(1),
|
|
16126
|
-
method: string().min(1),
|
|
16127
|
-
/** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
|
|
16128
|
-
* evaluate (§3.2.3). Anything beyond substitution is the expression leaf. */
|
|
16129
|
-
args: record(string(), unknown()).optional()
|
|
16191
|
+
kind: literal("action"),
|
|
16192
|
+
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
16193
|
+
actionId: string().min(1),
|
|
16194
|
+
/** Values for the action's declared variables; the others take their default. */
|
|
16195
|
+
variables: record(string(), union([
|
|
16196
|
+
string(),
|
|
16197
|
+
number(),
|
|
16198
|
+
boolean()
|
|
16199
|
+
])).optional()
|
|
16130
16200
|
}),
|
|
16131
16201
|
object({
|
|
16132
16202
|
kind: literal("code"),
|
|
@@ -16135,10 +16205,357 @@ var AutomationActionSchema = discriminatedUnion("kind", [
|
|
|
16135
16205
|
code: string().min(1).max(2e4)
|
|
16136
16206
|
})
|
|
16137
16207
|
]);
|
|
16208
|
+
/**
|
|
16209
|
+
* How a trigger that arrives while the automation is busy (or cooling down) is
|
|
16210
|
+
* handled. One of the automation's execution modes, never a property of its
|
|
16211
|
+
* actions. Absent means `single`.
|
|
16212
|
+
*
|
|
16213
|
+
* - `single` — drop the trigger while a run is in progress (traced + logged).
|
|
16214
|
+
* - `restart` — abort the run in progress (at its next step boundary), start fresh.
|
|
16215
|
+
* - `queued` — queue up to `max` triggers, drop the rest (traced).
|
|
16216
|
+
* - `parallel` — up to `max` runs at once, drop the rest (traced).
|
|
16217
|
+
* - `cooldown` — `single`, and no new run until `minutes` after the last run
|
|
16218
|
+
* STARTED; persisted across a restart. A manual trigger bypasses only this
|
|
16219
|
+
* wait, never the single/queued limits.
|
|
16220
|
+
*/
|
|
16221
|
+
var AutomationRunModeSchema = discriminatedUnion("mode", [
|
|
16222
|
+
object({ mode: literal("single") }),
|
|
16223
|
+
object({ mode: literal("restart") }),
|
|
16224
|
+
object({
|
|
16225
|
+
mode: literal("queued"),
|
|
16226
|
+
max: number().int().min(1).max(10)
|
|
16227
|
+
}),
|
|
16228
|
+
object({
|
|
16229
|
+
mode: literal("parallel"),
|
|
16230
|
+
max: number().int().min(1).max(10)
|
|
16231
|
+
}),
|
|
16232
|
+
object({
|
|
16233
|
+
mode: literal("cooldown"),
|
|
16234
|
+
minutes: number().int().min(1).max(1440)
|
|
16235
|
+
})
|
|
16236
|
+
]);
|
|
16138
16237
|
var AutomationRecipeSchema = object({
|
|
16139
16238
|
triggers: array(AutomationTriggerSchema),
|
|
16140
16239
|
conditions: AutomationConditionSchema.optional(),
|
|
16141
|
-
actions: array(AutomationActionSchema)
|
|
16240
|
+
actions: array(AutomationActionSchema),
|
|
16241
|
+
runMode: AutomationRunModeSchema.optional(),
|
|
16242
|
+
/** How many run traces the automation keeps (default {@link DEFAULT_TRACE_KEEP}). */
|
|
16243
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
16244
|
+
});
|
|
16245
|
+
new Set([
|
|
16246
|
+
{
|
|
16247
|
+
id: "person",
|
|
16248
|
+
name: "Person"
|
|
16249
|
+
},
|
|
16250
|
+
{
|
|
16251
|
+
id: "vehicle",
|
|
16252
|
+
name: "Vehicle"
|
|
16253
|
+
},
|
|
16254
|
+
{
|
|
16255
|
+
id: "animal",
|
|
16256
|
+
name: "Animal"
|
|
16257
|
+
},
|
|
16258
|
+
{
|
|
16259
|
+
id: "package",
|
|
16260
|
+
name: "Package"
|
|
16261
|
+
}
|
|
16262
|
+
].map((l) => l.id));
|
|
16263
|
+
var COCO_TO_MACRO = {
|
|
16264
|
+
mapping: {
|
|
16265
|
+
person: "person",
|
|
16266
|
+
bicycle: "vehicle",
|
|
16267
|
+
car: "vehicle",
|
|
16268
|
+
motorcycle: "vehicle",
|
|
16269
|
+
airplane: "vehicle",
|
|
16270
|
+
bus: "vehicle",
|
|
16271
|
+
train: "vehicle",
|
|
16272
|
+
truck: "vehicle",
|
|
16273
|
+
boat: "vehicle",
|
|
16274
|
+
bird: "animal",
|
|
16275
|
+
cat: "animal",
|
|
16276
|
+
dog: "animal",
|
|
16277
|
+
horse: "animal",
|
|
16278
|
+
sheep: "animal",
|
|
16279
|
+
cow: "animal",
|
|
16280
|
+
elephant: "animal",
|
|
16281
|
+
bear: "animal",
|
|
16282
|
+
zebra: "animal",
|
|
16283
|
+
giraffe: "animal",
|
|
16284
|
+
suitcase: "package",
|
|
16285
|
+
backpack: "package",
|
|
16286
|
+
handbag: "package"
|
|
16287
|
+
},
|
|
16288
|
+
preserveOriginal: false
|
|
16289
|
+
};
|
|
16290
|
+
new Set(Object.values(COCO_TO_MACRO.mapping));
|
|
16291
|
+
/**
|
|
16292
|
+
* Run traces — what an automation (or, later, an Action run) DID, node by node,
|
|
16293
|
+
* so the editor can paint every block green or red with its reason.
|
|
16294
|
+
*
|
|
16295
|
+
* A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
|
|
16296
|
+
* every condition node (containers and leaves, including the ones a
|
|
16297
|
+
* short-circuit never reached), the run-mode verdict and every action step —
|
|
16298
|
+
* each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
|
|
16299
|
+
* for an Action run). Skipped
|
|
16300
|
+
* evaluations are traced too, and identical consecutive skips collapse into a
|
|
16301
|
+
* repeat count so a trigger that fails every 5 minutes cannot flush real runs.
|
|
16302
|
+
*
|
|
16303
|
+
* {@link AutomationStepTraceSchema} is deliberately free of automation
|
|
16304
|
+
* vocabulary so an Action run records the same step shape.
|
|
16305
|
+
*/
|
|
16306
|
+
/** A value a trace may show: JSON primitives and short lists, nothing deeper. */
|
|
16307
|
+
var TraceValueSchema = union([
|
|
16308
|
+
string(),
|
|
16309
|
+
number(),
|
|
16310
|
+
boolean(),
|
|
16311
|
+
_null(),
|
|
16312
|
+
array(union([string(), number()]))
|
|
16313
|
+
]);
|
|
16314
|
+
var AutomationRunOutcomeSchema = _enum([
|
|
16315
|
+
"ran",
|
|
16316
|
+
"skipped-trigger",
|
|
16317
|
+
"skipped-conditions",
|
|
16318
|
+
"skipped-cooldown",
|
|
16319
|
+
"skipped-overlap",
|
|
16320
|
+
"failed",
|
|
16321
|
+
"aborted"
|
|
16322
|
+
]);
|
|
16323
|
+
/** `not-evaluated` = a short-circuit never reached the node. */
|
|
16324
|
+
var TraceNodeOutcomeSchema = _enum([
|
|
16325
|
+
"pass",
|
|
16326
|
+
"fail",
|
|
16327
|
+
"not-evaluated"
|
|
16328
|
+
]);
|
|
16329
|
+
var AutomationTriggerTraceSchema = object({
|
|
16330
|
+
kind: string().min(1),
|
|
16331
|
+
outcome: _enum(["pass", "fail"]),
|
|
16332
|
+
/** Why an event was rejected ("class person not in [dog]") or what fired. */
|
|
16333
|
+
reason: string(),
|
|
16334
|
+
/** deviceId, className, trackId, score … — only what the trigger exposes. */
|
|
16335
|
+
vars: record(string(), TraceValueSchema)
|
|
16336
|
+
});
|
|
16337
|
+
var AutomationConditionTraceNodeSchema = object({
|
|
16338
|
+
/** `conditions` for the root, `conditions.<i>` for its i-th child, … */
|
|
16339
|
+
path: string().min(1),
|
|
16340
|
+
kind: _enum([
|
|
16341
|
+
"all",
|
|
16342
|
+
"any",
|
|
16343
|
+
"not",
|
|
16344
|
+
"condition",
|
|
16345
|
+
"expression",
|
|
16346
|
+
"stationary-present"
|
|
16347
|
+
]),
|
|
16348
|
+
outcome: TraceNodeOutcomeSchema,
|
|
16349
|
+
reason: string(),
|
|
16350
|
+
deviceId: number().int().optional(),
|
|
16351
|
+
cap: string().optional(),
|
|
16352
|
+
fieldPath: string().optional(),
|
|
16353
|
+
operator: string().optional(),
|
|
16354
|
+
expected: TraceValueSchema.optional(),
|
|
16355
|
+
/** What the mirror held; `null` when it held nothing (unknown). */
|
|
16356
|
+
observed: TraceValueSchema.optional()
|
|
16357
|
+
});
|
|
16358
|
+
var AutomationRunVerdictSchema = object({
|
|
16359
|
+
mode: AutomationRunModeSchema,
|
|
16360
|
+
decision: _enum([
|
|
16361
|
+
"run",
|
|
16362
|
+
"queued",
|
|
16363
|
+
"restart",
|
|
16364
|
+
"drop",
|
|
16365
|
+
"cooldown",
|
|
16366
|
+
"bypass"
|
|
16367
|
+
]),
|
|
16368
|
+
reason: string()
|
|
16369
|
+
});
|
|
16370
|
+
/** One executed (or not-run) step — shared by automations and Action runs. */
|
|
16371
|
+
var AutomationStepTraceSchema = object({
|
|
16372
|
+
/** `actions.<i>` */
|
|
16373
|
+
path: string().min(1),
|
|
16374
|
+
kind: string().min(1),
|
|
16375
|
+
cap: string().optional(),
|
|
16376
|
+
method: string().optional(),
|
|
16377
|
+
deviceId: number().int().optional(),
|
|
16378
|
+
startedAt: number().optional(),
|
|
16379
|
+
endedAt: number().optional(),
|
|
16380
|
+
outcome: _enum([
|
|
16381
|
+
"ok",
|
|
16382
|
+
"error",
|
|
16383
|
+
"not-run"
|
|
16384
|
+
]),
|
|
16385
|
+
message: string().optional()
|
|
16386
|
+
});
|
|
16387
|
+
var AutomationRunTraceSchema = object({
|
|
16388
|
+
runId: string().min(1),
|
|
16389
|
+
startedAt: number(),
|
|
16390
|
+
endedAt: number(),
|
|
16391
|
+
trigger: AutomationTriggerTraceSchema,
|
|
16392
|
+
conditions: array(AutomationConditionTraceNodeSchema),
|
|
16393
|
+
verdict: AutomationRunVerdictSchema.optional(),
|
|
16394
|
+
steps: array(AutomationStepTraceSchema),
|
|
16395
|
+
outcome: AutomationRunOutcomeSchema,
|
|
16396
|
+
/** How many identical consecutive skips this trace stands for (>= 1). */
|
|
16397
|
+
repeat: number().int().min(1),
|
|
16398
|
+
/** When the latest of those repeats happened. */
|
|
16399
|
+
lastAt: number()
|
|
16400
|
+
});
|
|
16401
|
+
/**
|
|
16402
|
+
* What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
|
|
16403
|
+
* `action:<actionId>`): the cooldown stamp and the trace ring.
|
|
16404
|
+
*/
|
|
16405
|
+
var AutomationStateDocSchema = object({
|
|
16406
|
+
version: literal(1),
|
|
16407
|
+
lastRunStartedAt: number().nullable(),
|
|
16408
|
+
traces: array(AutomationRunTraceSchema)
|
|
16409
|
+
});
|
|
16410
|
+
/**
|
|
16411
|
+
* Actions — named, runnable things an operator (or an automation) can start,
|
|
16412
|
+
* declared as LIST ENTRIES, never as devices.
|
|
16413
|
+
*
|
|
16414
|
+
* An entry is either **internal** (a short list of cap/wait steps kept in the
|
|
16415
|
+
* hub's `actions` record kind) or declared by an addon through the
|
|
16416
|
+
* `action-source` collection (a Home Assistant script, a scene …). The one
|
|
16417
|
+
* surface the UI and automations talk to is the `actions` cap; it keeps no
|
|
16418
|
+
* catalog of its own (D3) — every `list` asks the providers live.
|
|
16419
|
+
*
|
|
16420
|
+
* This file is the data half: the entry schema, the variables an entry may
|
|
16421
|
+
* declare, and the pure resolution of the values a run was given. It holds no
|
|
16422
|
+
* runtime.
|
|
16423
|
+
*/
|
|
16424
|
+
/** What a variable's value is. `select` takes one of `options`. */
|
|
16425
|
+
var ActionVariableTypeSchema = _enum([
|
|
16426
|
+
"string",
|
|
16427
|
+
"number",
|
|
16428
|
+
"boolean",
|
|
16429
|
+
"select"
|
|
16430
|
+
]);
|
|
16431
|
+
var ACTION_VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
16432
|
+
var ActionVariableValueSchema = union([
|
|
16433
|
+
string(),
|
|
16434
|
+
number(),
|
|
16435
|
+
boolean()
|
|
16436
|
+
]);
|
|
16437
|
+
/**
|
|
16438
|
+
* One declared variable. Steps reference it as `{ $var: 'name' }` (the whole
|
|
16439
|
+
* value) or `{{vars.name}}` (inside a string) in their args.
|
|
16440
|
+
*/
|
|
16441
|
+
var ActionVariableSchema = object({
|
|
16442
|
+
name: string().regex(ACTION_VARIABLE_NAME_RE),
|
|
16443
|
+
label: string().min(1).max(120).optional(),
|
|
16444
|
+
type: ActionVariableTypeSchema,
|
|
16445
|
+
required: boolean().optional(),
|
|
16446
|
+
default: ActionVariableValueSchema.optional(),
|
|
16447
|
+
/** The allowed values of a `select`. */
|
|
16448
|
+
options: array(string().min(1)).min(1).optional()
|
|
16449
|
+
}).superRefine((v, ctx) => {
|
|
16450
|
+
if (v.type === "select" && v.options === void 0) ctx.addIssue({
|
|
16451
|
+
code: "custom",
|
|
16452
|
+
message: "a select variable needs options",
|
|
16453
|
+
path: ["options"]
|
|
16454
|
+
});
|
|
16455
|
+
if (v.default !== void 0 && variableValueError(v, v.default) !== null) ctx.addIssue({
|
|
16456
|
+
code: "custom",
|
|
16457
|
+
message: variableValueError(v, v.default) ?? "invalid default",
|
|
16458
|
+
path: ["default"]
|
|
16459
|
+
});
|
|
16460
|
+
});
|
|
16461
|
+
/** Why `value` is not a legal value for the variable, or null when it is. */
|
|
16462
|
+
function variableValueError(variable, value) {
|
|
16463
|
+
switch (variable.type) {
|
|
16464
|
+
case "string": return typeof value === "string" ? null : `variable "${variable.name}" must be a string`;
|
|
16465
|
+
case "number": return typeof value === "number" && Number.isFinite(value) ? null : `variable "${variable.name}" must be a number`;
|
|
16466
|
+
case "boolean": return typeof value === "boolean" ? null : `variable "${variable.name}" must be true or false`;
|
|
16467
|
+
case "select": return typeof value === "string" && (variable.options ?? []).includes(value) ? null : `variable "${variable.name}" must be one of ${(variable.options ?? []).join(", ")}`;
|
|
16468
|
+
}
|
|
16469
|
+
}
|
|
16470
|
+
var ActionSourceKindSchema = _enum(["internal", "addon"]);
|
|
16471
|
+
function isInternalActionId(actionId) {
|
|
16472
|
+
return actionId.startsWith("internal:") && actionId.length > 9;
|
|
16473
|
+
}
|
|
16474
|
+
/** The addon behind a `<addonId>:<localId>` id, or null for anything else (internal included). */
|
|
16475
|
+
function addonIdOfActionId(actionId) {
|
|
16476
|
+
if (isInternalActionId(actionId)) return null;
|
|
16477
|
+
const at = actionId.indexOf(":");
|
|
16478
|
+
return at > 0 && at < actionId.length - 1 ? actionId.slice(0, at) : null;
|
|
16479
|
+
}
|
|
16480
|
+
var ActionStatusSchema = object({
|
|
16481
|
+
isRunning: boolean(),
|
|
16482
|
+
/** Ms epoch the latest run STARTED; null when it never ran. */
|
|
16483
|
+
lastRunAt: number().nullable(),
|
|
16484
|
+
/** The latest run's failure; null on success or when it never ran. */
|
|
16485
|
+
lastError: string().nullable()
|
|
16486
|
+
});
|
|
16487
|
+
var ActionEntrySchema = object({
|
|
16488
|
+
/** `internal:<uuid>` or `<addonId>:<localId>`. */
|
|
16489
|
+
id: string().min(3),
|
|
16490
|
+
name: string().min(1).max(120),
|
|
16491
|
+
/** The addon that declared it; `core-blocks` for an internal one. */
|
|
16492
|
+
addonId: string().min(1),
|
|
16493
|
+
source: ActionSourceKindSchema,
|
|
16494
|
+
/** An addon-declared entry is edited where it was declared. */
|
|
16495
|
+
readOnly: boolean(),
|
|
16496
|
+
/** Internal only: cap and wait steps. No action-in-action, so no cycles. */
|
|
16497
|
+
steps: array(ActionStepSchema).min(1).max(50).optional(),
|
|
16498
|
+
variables: array(ActionVariableSchema).max(20).optional(),
|
|
16499
|
+
status: ActionStatusSchema
|
|
16500
|
+
}).superRefine((entry, ctx) => {
|
|
16501
|
+
if (entry.source === "internal") {
|
|
16502
|
+
if (!isInternalActionId(entry.id)) ctx.addIssue({
|
|
16503
|
+
code: "custom",
|
|
16504
|
+
message: "an internal action id is internal:<uuid>",
|
|
16505
|
+
path: ["id"]
|
|
16506
|
+
});
|
|
16507
|
+
return;
|
|
16508
|
+
}
|
|
16509
|
+
if (entry.steps !== void 0) ctx.addIssue({
|
|
16510
|
+
code: "custom",
|
|
16511
|
+
message: "only an internal action carries steps",
|
|
16512
|
+
path: ["steps"]
|
|
16513
|
+
});
|
|
16514
|
+
if (!entry.readOnly) ctx.addIssue({
|
|
16515
|
+
code: "custom",
|
|
16516
|
+
message: "an addon action is read-only here",
|
|
16517
|
+
path: ["readOnly"]
|
|
16518
|
+
});
|
|
16519
|
+
if (addonIdOfActionId(entry.id) === null) ctx.addIssue({
|
|
16520
|
+
code: "custom",
|
|
16521
|
+
message: "an addon action id is <addonId>:<localId>",
|
|
16522
|
+
path: ["id"]
|
|
16523
|
+
});
|
|
16524
|
+
});
|
|
16525
|
+
/** What an operator writes for an internal action. */
|
|
16526
|
+
var ActionInputSchema = object({
|
|
16527
|
+
name: string().min(1).max(120),
|
|
16528
|
+
steps: array(ActionStepSchema).min(1).max(50),
|
|
16529
|
+
variables: array(ActionVariableSchema).max(20).optional()
|
|
16530
|
+
});
|
|
16531
|
+
/** Who started a run. Absent = the operator pressed it. */
|
|
16532
|
+
var ActionRunOriginSchema = object({
|
|
16533
|
+
/** The automation block whose step started it. */
|
|
16534
|
+
blockId: string().min(1).optional() });
|
|
16535
|
+
/** `started` = the caller did not ask to wait. */
|
|
16536
|
+
var ActionRunOutcomeSchema = union([AutomationRunOutcomeSchema, literal("started")]);
|
|
16537
|
+
var ActionRunResultSchema = object({
|
|
16538
|
+
runId: string().min(1),
|
|
16539
|
+
outcome: ActionRunOutcomeSchema,
|
|
16540
|
+
/** Why it did not run, or what failed. */
|
|
16541
|
+
message: string().optional()
|
|
16542
|
+
});
|
|
16543
|
+
_enum([
|
|
16544
|
+
"not-found",
|
|
16545
|
+
"read-only",
|
|
16546
|
+
"invalid-variables",
|
|
16547
|
+
"invalid-steps",
|
|
16548
|
+
"not-linked",
|
|
16549
|
+
"busy"
|
|
16550
|
+
]);
|
|
16551
|
+
object({
|
|
16552
|
+
actionId: string(),
|
|
16553
|
+
runId: string(),
|
|
16554
|
+
isRunning: boolean(),
|
|
16555
|
+
/** Set when the run ended. */
|
|
16556
|
+
outcome: AutomationRunOutcomeSchema.optional(),
|
|
16557
|
+
lastRunAt: number().nullable(),
|
|
16558
|
+
lastError: string().nullable()
|
|
16142
16559
|
});
|
|
16143
16560
|
/**
|
|
16144
16561
|
* `addon-pages` — system-scoped singleton aggregator cap. Public-facing
|
|
@@ -18825,7 +19242,7 @@ var CompositionEventPlanSchema = object({
|
|
|
18825
19242
|
stateField: string(),
|
|
18826
19243
|
fieldKey: string()
|
|
18827
19244
|
});
|
|
18828
|
-
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.
|
|
19245
|
+
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.temperature`. */
|
|
18829
19246
|
var CompositionProblemSchema = object({
|
|
18830
19247
|
code: _enum([
|
|
18831
19248
|
"reserved-variant",
|
|
@@ -19144,7 +19561,7 @@ var GROUP_TEMPLATES = [
|
|
|
19144
19561
|
summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
|
|
19145
19562
|
role: DeviceRole.TemperatureSensor,
|
|
19146
19563
|
outputCap: "temperature-sensor",
|
|
19147
|
-
outputField: "
|
|
19564
|
+
outputField: "temperature",
|
|
19148
19565
|
quantity: "temperature",
|
|
19149
19566
|
defaultAggregate: "mean",
|
|
19150
19567
|
empty: "null",
|
|
@@ -19155,7 +19572,7 @@ var GROUP_TEMPLATES = [
|
|
|
19155
19572
|
summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
19156
19573
|
role: DeviceRole.HumiditySensor,
|
|
19157
19574
|
outputCap: "humidity-sensor",
|
|
19158
|
-
outputField: "
|
|
19575
|
+
outputField: "humidity",
|
|
19159
19576
|
quantity: "humidity",
|
|
19160
19577
|
defaultAggregate: "mean",
|
|
19161
19578
|
empty: "null",
|
|
@@ -19166,7 +19583,7 @@ var GROUP_TEMPLATES = [
|
|
|
19166
19583
|
summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
|
|
19167
19584
|
role: DeviceRole.PressureSensor,
|
|
19168
19585
|
outputCap: "pressure-sensor",
|
|
19169
|
-
outputField: "
|
|
19586
|
+
outputField: "pressure",
|
|
19170
19587
|
quantity: "pressure",
|
|
19171
19588
|
defaultAggregate: "mean",
|
|
19172
19589
|
empty: "null",
|
|
@@ -19177,7 +19594,7 @@ var GROUP_TEMPLATES = [
|
|
|
19177
19594
|
summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
|
|
19178
19595
|
role: DeviceRole.AmbientLightSensor,
|
|
19179
19596
|
outputCap: "ambient-light-sensor",
|
|
19180
|
-
outputField: "
|
|
19597
|
+
outputField: "illuminance",
|
|
19181
19598
|
quantity: "illuminance",
|
|
19182
19599
|
defaultAggregate: "mean",
|
|
19183
19600
|
empty: "null",
|
|
@@ -19188,7 +19605,7 @@ var GROUP_TEMPLATES = [
|
|
|
19188
19605
|
summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
|
|
19189
19606
|
role: DeviceRole.PowerSensor,
|
|
19190
19607
|
outputCap: "power-meter",
|
|
19191
|
-
outputField: "
|
|
19608
|
+
outputField: "power",
|
|
19192
19609
|
quantity: "power",
|
|
19193
19610
|
defaultAggregate: "sum",
|
|
19194
19611
|
empty: "omit",
|
|
@@ -19199,7 +19616,7 @@ var GROUP_TEMPLATES = [
|
|
|
19199
19616
|
summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
|
|
19200
19617
|
role: DeviceRole.EnergySensor,
|
|
19201
19618
|
outputCap: "power-meter",
|
|
19202
|
-
outputField: "
|
|
19619
|
+
outputField: "energy",
|
|
19203
19620
|
quantity: "energy",
|
|
19204
19621
|
defaultAggregate: "sum",
|
|
19205
19622
|
empty: "omit",
|
|
@@ -19210,7 +19627,7 @@ var GROUP_TEMPLATES = [
|
|
|
19210
19627
|
summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
|
|
19211
19628
|
role: DeviceRole.BatterySensor,
|
|
19212
19629
|
outputCap: "battery",
|
|
19213
|
-
outputField: "
|
|
19630
|
+
outputField: "level",
|
|
19214
19631
|
quantity: "percentage",
|
|
19215
19632
|
defaultAggregate: "mean",
|
|
19216
19633
|
empty: "null",
|
|
@@ -19788,7 +20205,18 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
|
|
|
19788
20205
|
kind: "mutation",
|
|
19789
20206
|
auth: "admin",
|
|
19790
20207
|
access: "view"
|
|
19791
|
-
})
|
|
20208
|
+
}), method(object({
|
|
20209
|
+
blockId: string().min(1),
|
|
20210
|
+
trace: AutomationRunTraceSchema.optional(),
|
|
20211
|
+
runStartedAt: number().optional(),
|
|
20212
|
+
keepTraces: number().int().min(1).max(100).optional()
|
|
20213
|
+
}), _void(), {
|
|
20214
|
+
kind: "mutation",
|
|
20215
|
+
auth: "admin"
|
|
20216
|
+
}), method(object({ blockId: string().min(1) }), AutomationStateDocSchema, { auth: "admin" }), method(object({ blockId: string().min(1) }), object({
|
|
20217
|
+
traces: array(AutomationRunTraceSchema),
|
|
20218
|
+
lastError: string().nullable()
|
|
20219
|
+
}), { auth: "admin" });
|
|
19792
20220
|
/**
|
|
19793
20221
|
* `custom-model-registry` — collection cap exposing operator-registered
|
|
19794
20222
|
* custom detection models. Each provider (today: `addon-model-studio`)
|
|
@@ -45226,51 +45654,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
|
|
|
45226
45654
|
kind: "mutation",
|
|
45227
45655
|
auth: "admin"
|
|
45228
45656
|
});
|
|
45229
|
-
new Set([
|
|
45230
|
-
{
|
|
45231
|
-
id: "person",
|
|
45232
|
-
name: "Person"
|
|
45233
|
-
},
|
|
45234
|
-
{
|
|
45235
|
-
id: "vehicle",
|
|
45236
|
-
name: "Vehicle"
|
|
45237
|
-
},
|
|
45238
|
-
{
|
|
45239
|
-
id: "animal",
|
|
45240
|
-
name: "Animal"
|
|
45241
|
-
},
|
|
45242
|
-
{
|
|
45243
|
-
id: "package",
|
|
45244
|
-
name: "Package"
|
|
45245
|
-
}
|
|
45246
|
-
].map((l) => l.id));
|
|
45247
|
-
var COCO_TO_MACRO = {
|
|
45248
|
-
mapping: {
|
|
45249
|
-
person: "person",
|
|
45250
|
-
bicycle: "vehicle",
|
|
45251
|
-
car: "vehicle",
|
|
45252
|
-
motorcycle: "vehicle",
|
|
45253
|
-
airplane: "vehicle",
|
|
45254
|
-
bus: "vehicle",
|
|
45255
|
-
train: "vehicle",
|
|
45256
|
-
truck: "vehicle",
|
|
45257
|
-
boat: "vehicle",
|
|
45258
|
-
bird: "animal",
|
|
45259
|
-
cat: "animal",
|
|
45260
|
-
dog: "animal",
|
|
45261
|
-
horse: "animal",
|
|
45262
|
-
sheep: "animal",
|
|
45263
|
-
cow: "animal",
|
|
45264
|
-
elephant: "animal",
|
|
45265
|
-
bear: "animal",
|
|
45266
|
-
zebra: "animal",
|
|
45267
|
-
giraffe: "animal",
|
|
45268
|
-
suitcase: "package",
|
|
45269
|
-
backpack: "package",
|
|
45270
|
-
handbag: "package"
|
|
45271
|
-
},
|
|
45272
|
-
preserveOriginal: false
|
|
45273
|
-
};
|
|
45274
45657
|
var AUDIO_MACRO_LABELS = [
|
|
45275
45658
|
{
|
|
45276
45659
|
id: "speech",
|
|
@@ -58359,9 +58742,9 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
|
|
|
58359
58742
|
*/
|
|
58360
58743
|
var AirQualitySensorStatusSchema = object({
|
|
58361
58744
|
/** Carbon dioxide concentration in ppm. */
|
|
58362
|
-
|
|
58745
|
+
co2: number().min(0).optional().meta(readingMeta("concentration-volume")),
|
|
58363
58746
|
/** Total volatile organic compounds in ppb. */
|
|
58364
|
-
|
|
58747
|
+
voc: number().min(0).optional().meta(readingMeta("concentration-ppb")),
|
|
58365
58748
|
/** Particulate matter ≤ 2.5 μm in µg/m³. */
|
|
58366
58749
|
pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
|
|
58367
58750
|
/** Particulate matter ≤ 10 μm in µg/m³. */
|
|
@@ -58394,12 +58777,12 @@ var airQualitySensorCapability = {
|
|
|
58394
58777
|
* History (D850): recorded series.
|
|
58395
58778
|
*/
|
|
58396
58779
|
history: { fields: {
|
|
58397
|
-
|
|
58780
|
+
co2: {
|
|
58398
58781
|
kind: "gauge",
|
|
58399
58782
|
unit: "ppm",
|
|
58400
58783
|
deadband: 5
|
|
58401
58784
|
},
|
|
58402
|
-
|
|
58785
|
+
voc: {
|
|
58403
58786
|
kind: "gauge",
|
|
58404
58787
|
unit: "ppb",
|
|
58405
58788
|
deadband: 5
|
|
@@ -58430,7 +58813,7 @@ var airQualitySensorCapability = {
|
|
|
58430
58813
|
*/
|
|
58431
58814
|
var AmbientLightSensorStatusSchema = object({
|
|
58432
58815
|
/** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
|
|
58433
|
-
|
|
58816
|
+
illuminance: number().min(0).nullable().meta(readingMeta("illuminance", {
|
|
58434
58817
|
precision: 0,
|
|
58435
58818
|
label: "Illuminance"
|
|
58436
58819
|
})),
|
|
@@ -58459,7 +58842,7 @@ var ambientLightSensorCapability = {
|
|
|
58459
58842
|
/**
|
|
58460
58843
|
* History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
|
|
58461
58844
|
*/
|
|
58462
|
-
history: { fields: {
|
|
58845
|
+
history: { fields: { illuminance: {
|
|
58463
58846
|
kind: "gauge",
|
|
58464
58847
|
unit: "lx",
|
|
58465
58848
|
deadbandPct: 10,
|
|
@@ -58598,6 +58981,84 @@ var audioMetricsCapability = {
|
|
|
58598
58981
|
*/
|
|
58599
58982
|
history: "none"
|
|
58600
58983
|
};
|
|
58984
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
58985
|
+
actionId: string().min(1),
|
|
58986
|
+
variables: record(string(), ActionVariableValueSchema).optional()
|
|
58987
|
+
}), _void(), {
|
|
58988
|
+
kind: "mutation",
|
|
58989
|
+
auth: "admin"
|
|
58990
|
+
}), method(object({ actionId: string().min(1) }), _void(), {
|
|
58991
|
+
kind: "mutation",
|
|
58992
|
+
auth: "admin"
|
|
58993
|
+
});
|
|
58994
|
+
/**
|
|
58995
|
+
* actions — the ONE surface for runnable actions, for the UI and for
|
|
58996
|
+
* automations. Provided by the core-blocks builtin on the hub.
|
|
58997
|
+
*
|
|
58998
|
+
* An action is a LIST ENTRY, not a device (D883): either internal (cap and wait
|
|
58999
|
+
* steps, kept in the hub's `actions` record kind) or declared by an addon over
|
|
59000
|
+
* `action-source`. `list` asks every `action-source` provider LIVE and overlays
|
|
59001
|
+
* the run status from the hub's `runs` ledger; there is no catalog here to
|
|
59002
|
+
* drift (D3).
|
|
59003
|
+
*
|
|
59004
|
+
* **Permissions follow the camera, as linked devices do.** An action is linked
|
|
59005
|
+
* to cameras by the operator (`setLinks`, D356: nothing links itself). A
|
|
59006
|
+
* non-admin may `get` / `run` an action only through a camera they may see that
|
|
59007
|
+
* links it: they name the camera (`deviceId`, a top-level field so the scope
|
|
59008
|
+
* gate sees it) and the provider refuses an action that camera does not link.
|
|
59009
|
+
* An admin, and an in-process caller (an automation block), may run any action.
|
|
59010
|
+
* Every refusal is typed (`[not-linked] …`) and logged.
|
|
59011
|
+
*
|
|
59012
|
+
* A second `run` of an action that is already running is REFUSED — traced and
|
|
59013
|
+
* logged — never queued.
|
|
59014
|
+
*/
|
|
59015
|
+
var ActionIdInput = object({ actionId: string().min(1) });
|
|
59016
|
+
var ActionLinksSchema = object({
|
|
59017
|
+
deviceId: number().int().nonnegative(),
|
|
59018
|
+
actionIds: array(string().min(1)).max(100)
|
|
59019
|
+
});
|
|
59020
|
+
method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
59021
|
+
actionId: string().min(1),
|
|
59022
|
+
deviceId: number().int().nonnegative().optional()
|
|
59023
|
+
}), object({ action: ActionEntrySchema.nullable() }), {
|
|
59024
|
+
role: "viewer",
|
|
59025
|
+
auth: "protected",
|
|
59026
|
+
kind: "query",
|
|
59027
|
+
caller: "required"
|
|
59028
|
+
}), method(object({
|
|
59029
|
+
actionId: string().min(1),
|
|
59030
|
+
variables: record(string(), ActionVariableValueSchema).optional(),
|
|
59031
|
+
wait: boolean().optional(),
|
|
59032
|
+
origin: ActionRunOriginSchema.optional(),
|
|
59033
|
+
deviceId: number().int().nonnegative().optional()
|
|
59034
|
+
}), ActionRunResultSchema, {
|
|
59035
|
+
role: "viewer",
|
|
59036
|
+
auth: "protected",
|
|
59037
|
+
kind: "mutation",
|
|
59038
|
+
caller: "required"
|
|
59039
|
+
}), method(ActionIdInput, _void(), {
|
|
59040
|
+
kind: "mutation",
|
|
59041
|
+
auth: "admin"
|
|
59042
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
|
|
59043
|
+
kind: "mutation",
|
|
59044
|
+
auth: "admin"
|
|
59045
|
+
}), method(object({
|
|
59046
|
+
actionId: string().min(1),
|
|
59047
|
+
action: ActionInputSchema.partial()
|
|
59048
|
+
}), object({ action: ActionEntrySchema }), {
|
|
59049
|
+
kind: "mutation",
|
|
59050
|
+
auth: "admin"
|
|
59051
|
+
}), method(ActionIdInput, _void(), {
|
|
59052
|
+
kind: "mutation",
|
|
59053
|
+
auth: "admin"
|
|
59054
|
+
}), method(object({ deviceId: number().int().nonnegative() }), array(ActionEntrySchema), {
|
|
59055
|
+
role: "viewer",
|
|
59056
|
+
auth: "protected",
|
|
59057
|
+
kind: "query"
|
|
59058
|
+
}), method(object({ deviceId: number().int().nonnegative() }), ActionLinksSchema, { auth: "admin" }), method(ActionLinksSchema, ActionLinksSchema, {
|
|
59059
|
+
kind: "mutation",
|
|
59060
|
+
auth: "admin"
|
|
59061
|
+
});
|
|
58601
59062
|
/**
|
|
58602
59063
|
* Automation-control cap. Models HA `automation.*` entities on
|
|
58603
59064
|
* `DeviceType.Automation`. An automation is a trigger+condition+
|
|
@@ -58694,7 +59155,7 @@ var BatteryStatusSchema = object({
|
|
|
58694
59155
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
58695
59156
|
* declines to band a non-finite reading, which is the correct shape.
|
|
58696
59157
|
*/
|
|
58697
|
-
|
|
59158
|
+
level: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
|
|
58698
59159
|
/**
|
|
58699
59160
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
58700
59161
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -58704,7 +59165,7 @@ var BatteryStatusSchema = object({
|
|
|
58704
59165
|
* `'unknown'` is the absence of an answer: the provider has not read the
|
|
58705
59166
|
* power fields yet, or the firmware reported neither. Before it existed,
|
|
58706
59167
|
* two unreadable fields produced `'none'`, and a camera nobody had reached
|
|
58707
|
-
* was drawn "on battery alone" — the same D315 defect `
|
|
59168
|
+
* was drawn "on battery alone" — the same D315 defect `level` closed
|
|
58708
59169
|
* by going nullable. Consumers SKIP it (no charger state published, no
|
|
58709
59170
|
* glyph, no HomeKit ChargingState) rather than coerce it either way.
|
|
58710
59171
|
*/
|
|
@@ -58728,7 +59189,7 @@ var BatteryStatusSchema = object({
|
|
|
58728
59189
|
* that only report charge. A second reading on this cap, not a second
|
|
58729
59190
|
* `numeric-sensor` on the same device.
|
|
58730
59191
|
*/
|
|
58731
|
-
|
|
59192
|
+
voltage: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
58732
59193
|
/**
|
|
58733
59194
|
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
58734
59195
|
* completed firmware round-trip, an observed wake, or an inbound push
|
|
@@ -58762,7 +59223,7 @@ var BatteryStatusSchema = object({
|
|
|
58762
59223
|
/**
|
|
58763
59224
|
* True when the source is a BINARY low-battery indicator (HA
|
|
58764
59225
|
* `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
|
|
58765
|
-
* charge level — `
|
|
59226
|
+
* charge level — `level` is then a coarse stand-in (100 = normal,
|
|
58766
59227
|
* sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
|
|
58767
59228
|
* misleading exact percentage. Absent/false → genuine 0–100 % reading.
|
|
58768
59229
|
*/
|
|
@@ -58782,15 +59243,15 @@ var BATTERY_DEVICE_TYPES = [
|
|
|
58782
59243
|
var batteryCustomize = {
|
|
58783
59244
|
version: 1,
|
|
58784
59245
|
targets: [{
|
|
58785
|
-
id: "
|
|
59246
|
+
id: "level",
|
|
58786
59247
|
cardinality: "scalar",
|
|
58787
59248
|
vocabulary: {
|
|
58788
59249
|
cap: "battery",
|
|
58789
|
-
stateField: "
|
|
59250
|
+
stateField: "level"
|
|
58790
59251
|
},
|
|
58791
59252
|
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
58792
59253
|
apply: "add",
|
|
58793
|
-
path: "
|
|
59254
|
+
path: "level",
|
|
58794
59255
|
sources: [{
|
|
58795
59256
|
kind: "field",
|
|
58796
59257
|
valueKinds: ["number", "string"],
|
|
@@ -58884,7 +59345,7 @@ onStatusChanged: { data: object({
|
|
|
58884
59345
|
schema: BatteryStatusSchema,
|
|
58885
59346
|
kind: "push",
|
|
58886
59347
|
empty: {
|
|
58887
|
-
|
|
59348
|
+
level: null,
|
|
58888
59349
|
charging: "unknown",
|
|
58889
59350
|
sleeping: false,
|
|
58890
59351
|
lastUpdated: 0
|
|
@@ -58911,11 +59372,11 @@ onStatusChanged: { data: object({
|
|
|
58911
59372
|
* History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
|
|
58912
59373
|
*/
|
|
58913
59374
|
history: { fields: {
|
|
58914
|
-
|
|
59375
|
+
level: {
|
|
58915
59376
|
kind: "gauge",
|
|
58916
59377
|
unit: "%"
|
|
58917
59378
|
},
|
|
58918
|
-
|
|
59379
|
+
voltage: {
|
|
58919
59380
|
kind: "gauge",
|
|
58920
59381
|
unit: "V"
|
|
58921
59382
|
}
|
|
@@ -58975,14 +59436,14 @@ var binaryCapability = {
|
|
|
58975
59436
|
* controls to this single-method surface.
|
|
58976
59437
|
*
|
|
58977
59438
|
* The cap is intentionally minimal: a single `setBrightness({deviceId,
|
|
58978
|
-
*
|
|
59439
|
+
* level})` mutation plus the auto-injected `getStatus`. Drivers
|
|
58979
59440
|
* that expose richer controls (color temperature, scenes, schedules)
|
|
58980
59441
|
* should surface those via the device's `getSettingsUISchema()`
|
|
58981
59442
|
* instead of bloating this cap.
|
|
58982
59443
|
*/
|
|
58983
59444
|
var BrightnessStatusSchema = object({
|
|
58984
59445
|
/** Current level as 0..100 inclusive. Firmware-reported. */
|
|
58985
|
-
|
|
59446
|
+
level: number().min(0).max(100).meta(readingMeta("percentage")),
|
|
58986
59447
|
/** Ms epoch of the last operator-driven change. Useful for UI freshness. */
|
|
58987
59448
|
lastChangedAt: number()
|
|
58988
59449
|
});
|
|
@@ -58994,7 +59455,7 @@ var brightnessCapability = {
|
|
|
58994
59455
|
deviceTypes: [DeviceType.Light],
|
|
58995
59456
|
methods: { setBrightness: method(object({
|
|
58996
59457
|
deviceId: number().int().nonnegative(),
|
|
58997
|
-
|
|
59458
|
+
level: number().min(0).max(100)
|
|
58998
59459
|
}), _void(), {
|
|
58999
59460
|
kind: "mutation",
|
|
59000
59461
|
auth: "protected"
|
|
@@ -59007,7 +59468,7 @@ var brightnessCapability = {
|
|
|
59007
59468
|
*/
|
|
59008
59469
|
onBrightnessChanged: { data: object({
|
|
59009
59470
|
deviceId: number(),
|
|
59010
|
-
|
|
59471
|
+
level: number().min(0).max(100),
|
|
59011
59472
|
lastChangedAt: number()
|
|
59012
59473
|
}) } },
|
|
59013
59474
|
status: {
|
|
@@ -59030,7 +59491,7 @@ onBrightnessChanged: { data: object({
|
|
|
59030
59491
|
/**
|
|
59031
59492
|
* History (D850): recorded series. Actuator tier: level keeps every change.
|
|
59032
59493
|
*/
|
|
59033
|
-
history: { fields: {
|
|
59494
|
+
history: { fields: { level: {
|
|
59034
59495
|
kind: "gauge",
|
|
59035
59496
|
unit: "%",
|
|
59036
59497
|
minIntervalMs: 0
|
|
@@ -59627,11 +60088,11 @@ var ColorInputSchema = discriminatedUnion("mode", [
|
|
|
59627
60088
|
}),
|
|
59628
60089
|
object({
|
|
59629
60090
|
mode: literal("mired"),
|
|
59630
|
-
|
|
60091
|
+
colorTemperature: number().int().min(50).max(1e3)
|
|
59631
60092
|
})
|
|
59632
60093
|
]);
|
|
59633
60094
|
var ColorStatusSchema = object({
|
|
59634
|
-
/** Active color mode — which of `rgb` / `hsv` / `
|
|
60095
|
+
/** Active color mode — which of `rgb` / `hsv` / `colorTemperature` reflects
|
|
59635
60096
|
* the bulb's current state. */
|
|
59636
60097
|
mode: _enum([
|
|
59637
60098
|
"rgb",
|
|
@@ -59643,7 +60104,7 @@ var ColorStatusSchema = object({
|
|
|
59643
60104
|
/** Populated when `mode === 'hsv'`. */
|
|
59644
60105
|
hsv: HsvTripletSchema.optional(),
|
|
59645
60106
|
/** Populated when `mode === 'mired'`. */
|
|
59646
|
-
|
|
60107
|
+
colorTemperature: number().int().optional().meta(readingMeta("colour-temperature")),
|
|
59647
60108
|
/** Ms epoch of the last operator-driven change. */
|
|
59648
60109
|
lastChangedAt: number()
|
|
59649
60110
|
});
|
|
@@ -59675,7 +60136,7 @@ onColorChanged: { data: object({
|
|
|
59675
60136
|
]),
|
|
59676
60137
|
rgb: RgbTripletSchema.optional(),
|
|
59677
60138
|
hsv: HsvTripletSchema.optional(),
|
|
59678
|
-
|
|
60139
|
+
colorTemperature: number().int().optional(),
|
|
59679
60140
|
lastChangedAt: number()
|
|
59680
60141
|
}) } },
|
|
59681
60142
|
status: {
|
|
@@ -60552,11 +61013,11 @@ var DishwasherStatusSchema = object({
|
|
|
60552
61013
|
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
60553
61014
|
availablePrograms: array(string()),
|
|
60554
61015
|
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
60555
|
-
|
|
61016
|
+
remaining: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
60556
61017
|
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
60557
|
-
|
|
61018
|
+
delayedStart: number().int().nonnegative().nullable().meta(readingMeta("duration")),
|
|
60558
61019
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
60559
|
-
|
|
61020
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
60560
61021
|
/** True when the door is reported open; null when the door state is not known. */
|
|
60561
61022
|
doorOpen: boolean().nullable(),
|
|
60562
61023
|
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
@@ -60775,14 +61236,14 @@ var dishwasherCapability = {
|
|
|
60775
61236
|
runtimeState: DishwasherStatusSchema,
|
|
60776
61237
|
durability: "session",
|
|
60777
61238
|
history: { fields: {
|
|
60778
|
-
|
|
61239
|
+
progress: {
|
|
60779
61240
|
kind: "gauge",
|
|
60780
61241
|
unit: "%",
|
|
60781
61242
|
deadband: 2
|
|
60782
61243
|
},
|
|
60783
61244
|
state: { kind: "enum" },
|
|
60784
61245
|
operationState: { kind: "enum" },
|
|
60785
|
-
|
|
61246
|
+
remaining: {
|
|
60786
61247
|
kind: "gauge",
|
|
60787
61248
|
unit: "s",
|
|
60788
61249
|
minIntervalMs: 6e4
|
|
@@ -61373,7 +61834,7 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
|
|
|
61373
61834
|
var FanControlStatusSchema = object({
|
|
61374
61835
|
/** Active speed as 0..100 inclusive. Null when the device has no
|
|
61375
61836
|
* speed surface (single-speed fan). */
|
|
61376
|
-
|
|
61837
|
+
speed: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
61377
61838
|
/** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
|
|
61378
61839
|
* a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
|
|
61379
61840
|
percentageStep: number().positive().optional().meta(readingMeta("percentage")),
|
|
@@ -61400,7 +61861,7 @@ var fanControlCapability = {
|
|
|
61400
61861
|
methods: {
|
|
61401
61862
|
setPercentage: method(object({
|
|
61402
61863
|
deviceId: number().int().nonnegative(),
|
|
61403
|
-
|
|
61864
|
+
speed: number().min(0).max(100)
|
|
61404
61865
|
}), _void(), {
|
|
61405
61866
|
kind: "mutation",
|
|
61406
61867
|
auth: "protected"
|
|
@@ -61433,7 +61894,7 @@ var fanControlCapability = {
|
|
|
61433
61894
|
},
|
|
61434
61895
|
/**
|
|
61435
61896
|
* Runtime-state slice — mirrored by the kernel. UI fan speed
|
|
61436
|
-
* sliders read `
|
|
61897
|
+
* sliders read `speed` for live updates.
|
|
61437
61898
|
*/
|
|
61438
61899
|
runtimeState: FanControlStatusSchema,
|
|
61439
61900
|
/**
|
|
@@ -61447,7 +61908,7 @@ var fanControlCapability = {
|
|
|
61447
61908
|
* History (D850): recorded series. Actuator tier: speed keeps every change.
|
|
61448
61909
|
*/
|
|
61449
61910
|
history: { fields: {
|
|
61450
|
-
|
|
61911
|
+
speed: {
|
|
61451
61912
|
kind: "gauge",
|
|
61452
61913
|
unit: "%",
|
|
61453
61914
|
minIntervalMs: 0
|
|
@@ -61892,7 +62353,7 @@ var humidifierCapability = {
|
|
|
61892
62353
|
*/
|
|
61893
62354
|
var HumiditySensorStatusSchema = object({
|
|
61894
62355
|
/** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
|
|
61895
|
-
|
|
62356
|
+
humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
|
|
61896
62357
|
precision: 0,
|
|
61897
62358
|
label: "Humidity"
|
|
61898
62359
|
})),
|
|
@@ -61921,7 +62382,7 @@ var humiditySensorCapability = {
|
|
|
61921
62382
|
/**
|
|
61922
62383
|
* History (D850): recorded series.
|
|
61923
62384
|
*/
|
|
61924
|
-
history: { fields: {
|
|
62385
|
+
history: { fields: { humidity: {
|
|
61925
62386
|
kind: "gauge",
|
|
61926
62387
|
unit: "%",
|
|
61927
62388
|
deadband: .5
|
|
@@ -62561,7 +63022,7 @@ var LawnMowerControlStatusSchema = object({
|
|
|
62561
63022
|
batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62562
63023
|
/** 0..100 mowing-completion percentage of the current task, or null when no
|
|
62563
63024
|
* task is active / progress is unavailable. */
|
|
62564
|
-
|
|
63025
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
62565
63026
|
/** Current device/event code (dynamic — mostly status, sometimes an error),
|
|
62566
63027
|
* or null when unknown. */
|
|
62567
63028
|
currentCode: number().nullable().meta(readingMeta("none")),
|
|
@@ -63061,7 +63522,7 @@ var lockControlCapability = {
|
|
|
63061
63522
|
volatileStateFields: ["lastChangedAt"]
|
|
63062
63523
|
};
|
|
63063
63524
|
/**
|
|
63064
|
-
* A monotonic total between resets (D944). Energy uses `power-meter.
|
|
63525
|
+
* A monotonic total between resets (D944). Energy uses `power-meter.energy`
|
|
63065
63526
|
* so dashboards keep one series; every other instantaneous reading lands here.
|
|
63066
63527
|
* `value` is the time integral in the source quantity's accumulated base
|
|
63067
63528
|
* (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
|
|
@@ -63155,10 +63616,10 @@ var MediaPlayerStatusSchema = object({
|
|
|
63155
63616
|
currentMedia: MediaInfoSchema.nullable(),
|
|
63156
63617
|
/** Current playback position in ms. Null when not seekable or
|
|
63157
63618
|
* nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
|
|
63158
|
-
|
|
63619
|
+
position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
63159
63620
|
/** Total duration of the current media in ms. Null when unknown
|
|
63160
63621
|
* (live stream) or nothing is playing. */
|
|
63161
|
-
|
|
63622
|
+
duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
|
|
63162
63623
|
/** Shuffle toggle. Null when no shuffle surface.
|
|
63163
63624
|
* Pair with `DeviceFeature.MediaPlayerShuffle`. */
|
|
63164
63625
|
shuffle: boolean().nullable(),
|
|
@@ -63197,7 +63658,7 @@ var mediaPlayerCapability = {
|
|
|
63197
63658
|
}),
|
|
63198
63659
|
seek: method(object({
|
|
63199
63660
|
deviceId: number().int().nonnegative(),
|
|
63200
|
-
|
|
63661
|
+
position: number().int().nonnegative()
|
|
63201
63662
|
}), _void(), {
|
|
63202
63663
|
kind: "mutation",
|
|
63203
63664
|
auth: "protected"
|
|
@@ -63269,7 +63730,7 @@ var mediaPlayerCapability = {
|
|
|
63269
63730
|
/**
|
|
63270
63731
|
* History (D850): volume (a level an operator or an automation sets; the
|
|
63271
63732
|
* default 10 s floor folds a slider drag into its end value) and mute.
|
|
63272
|
-
* `
|
|
63733
|
+
* `position` is not recorded: it moves continuously while playing.
|
|
63273
63734
|
*/
|
|
63274
63735
|
history: { fields: {
|
|
63275
63736
|
volumeLevel: {
|
|
@@ -64231,9 +64692,9 @@ var NetworkLinkStatusSchema = object({
|
|
|
64231
64692
|
* one whose reading has not landed must not be drawn at 0 %. Consumers
|
|
64232
64693
|
* SKIP a null rather than coerce it.
|
|
64233
64694
|
*/
|
|
64234
|
-
|
|
64695
|
+
signal: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
64235
64696
|
/** Raw received signal strength in dBm, when the firmware reports one. */
|
|
64236
|
-
|
|
64697
|
+
rssi: number().optional().meta(readingMeta("signal-level")),
|
|
64237
64698
|
/** Network name of a wireless link, when the firmware reports it. */
|
|
64238
64699
|
ssid: string().optional(),
|
|
64239
64700
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
@@ -64242,7 +64703,7 @@ var NetworkLinkStatusSchema = object({
|
|
|
64242
64703
|
/** The slice a provider seeds before its first read: nothing is known yet. */
|
|
64243
64704
|
var NETWORK_LINK_UNKNOWN = {
|
|
64244
64705
|
type: "unknown",
|
|
64245
|
-
|
|
64706
|
+
signal: null,
|
|
64246
64707
|
lastUpdated: 0
|
|
64247
64708
|
};
|
|
64248
64709
|
/**
|
|
@@ -64259,9 +64720,9 @@ function signalPercentFromBars(bars, maxBars) {
|
|
|
64259
64720
|
* below is 0 %, -50 dBm and above is 100 %, linear between. Non-finite or
|
|
64260
64721
|
* positive input is not an RSSI: `null`.
|
|
64261
64722
|
*/
|
|
64262
|
-
function signalPercentFromRssi(
|
|
64263
|
-
if (
|
|
64264
|
-
return Math.round((Math.min(-50, Math.max(-100,
|
|
64723
|
+
function signalPercentFromRssi(rssi) {
|
|
64724
|
+
if (rssi === void 0 || !Number.isFinite(rssi) || rssi > 0) return null;
|
|
64725
|
+
return Math.round((Math.min(-50, Math.max(-100, rssi)) + 100) * 2);
|
|
64265
64726
|
}
|
|
64266
64727
|
var networkLinkCapability = {
|
|
64267
64728
|
name: "network-link",
|
|
@@ -64312,13 +64773,13 @@ onStatusChanged: { data: object({
|
|
|
64312
64773
|
* History (D850): recorded series.
|
|
64313
64774
|
*/
|
|
64314
64775
|
history: { fields: {
|
|
64315
|
-
|
|
64776
|
+
signal: {
|
|
64316
64777
|
kind: "gauge",
|
|
64317
64778
|
unit: "%",
|
|
64318
64779
|
deadband: 3,
|
|
64319
64780
|
minIntervalMs: 6e4
|
|
64320
64781
|
},
|
|
64321
|
-
|
|
64782
|
+
rssi: {
|
|
64322
64783
|
kind: "gauge",
|
|
64323
64784
|
unit: "dBm",
|
|
64324
64785
|
deadband: 2,
|
|
@@ -65109,10 +65570,20 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
65109
65570
|
]);
|
|
65110
65571
|
var gramsPortion = number().int().min(4).max(200);
|
|
65111
65572
|
var PetFeederStatusSchema = object({
|
|
65112
|
-
/** Food
|
|
65113
|
-
*
|
|
65114
|
-
* bowl
|
|
65573
|
+
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
65574
|
+
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
65575
|
+
* amount in the bowl is `bowlFood`. On dual-hopper models this is the
|
|
65576
|
+
* combined reading; per-hopper levels live in `food1`/`food2`. Null when
|
|
65577
|
+
* the device has not reported yet. */
|
|
65115
65578
|
foodLevel: number().nullable().meta(readingMeta("none")),
|
|
65579
|
+
/** Food in the BOWL as the feeder reports it (`state.bowl`), in the
|
|
65580
|
+
* feeder's own units. Null when the model reports none. */
|
|
65581
|
+
bowlFood: number().nullable().meta(readingMeta("none")),
|
|
65582
|
+
/** True while the pet is eating (`state.eating`). */
|
|
65583
|
+
eating: boolean(),
|
|
65584
|
+
/** Whether `markFoodReplenished` does anything on this model. When false
|
|
65585
|
+
* the client must not offer it. */
|
|
65586
|
+
supportsMarkRefilled: boolean(),
|
|
65116
65587
|
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
65117
65588
|
* single-hopper models. */
|
|
65118
65589
|
food1: number().nullable().meta(readingMeta("none")),
|
|
@@ -65120,8 +65591,8 @@ var PetFeederStatusSchema = object({
|
|
|
65120
65591
|
* single-hopper models. */
|
|
65121
65592
|
food2: number().nullable().meta(readingMeta("none")),
|
|
65122
65593
|
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
65123
|
-
* (`device_class: problem`, on = low). True when the
|
|
65124
|
-
*
|
|
65594
|
+
* (`device_class: problem`, on = low). True when the tank reports empty,
|
|
65595
|
+
* or, on a dual-hopper model, when EITHER hopper is empty. */
|
|
65125
65596
|
lowFood: boolean(),
|
|
65126
65597
|
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
65127
65598
|
* device has no battery reading. */
|
|
@@ -65189,7 +65660,9 @@ var petFeederCapability = {
|
|
|
65189
65660
|
kind: "mutation",
|
|
65190
65661
|
auth: "protected"
|
|
65191
65662
|
}),
|
|
65192
|
-
/**
|
|
65663
|
+
/** Tell the PetKit cloud a hopper was refilled so it stops its low-food
|
|
65664
|
+
* reminders (D4H/D4S/D4SH only — see `supportsMarkRefilled`). It does not
|
|
65665
|
+
* change any sensor reading. */
|
|
65193
65666
|
markFoodReplenished: method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
65194
65667
|
kind: "mutation",
|
|
65195
65668
|
auth: "protected"
|
|
@@ -65262,6 +65735,7 @@ var petFeederCapability = {
|
|
|
65262
65735
|
*/
|
|
65263
65736
|
history: { fields: {
|
|
65264
65737
|
foodLevel: { kind: "gauge" },
|
|
65738
|
+
bowlFood: { kind: "gauge" },
|
|
65265
65739
|
food1: { kind: "gauge" },
|
|
65266
65740
|
food2: { kind: "gauge" },
|
|
65267
65741
|
batteryPower: {
|
|
@@ -65671,16 +66145,16 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
65671
66145
|
* in real-world devices.
|
|
65672
66146
|
*/
|
|
65673
66147
|
var PowerMeterStatusSchema = object({
|
|
65674
|
-
/** Instantaneous power draw
|
|
65675
|
-
|
|
66148
|
+
/** Instantaneous power draw (watts). */
|
|
66149
|
+
power: number().optional().meta(readingMeta("power", { label: "Power" })),
|
|
65676
66150
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
65677
|
-
|
|
65678
|
-
/** Voltage
|
|
65679
|
-
|
|
66151
|
+
energy: number().optional().meta(readingMeta("energy", { label: "Energy" })),
|
|
66152
|
+
/** Voltage (volts). */
|
|
66153
|
+
voltage: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
|
|
65680
66154
|
/** Current in amperes. */
|
|
65681
|
-
|
|
66155
|
+
current: number().optional().meta(readingMeta("current", { label: "Current" })),
|
|
65682
66156
|
/** Apparent power in volt-amperes. */
|
|
65683
|
-
|
|
66157
|
+
apparentPower: number().optional().meta(readingMeta("apparent-power")),
|
|
65684
66158
|
/** Power factor (0..1) if reported. */
|
|
65685
66159
|
powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
|
|
65686
66160
|
/** Ms epoch when the slice was last updated. */
|
|
@@ -65738,14 +66212,14 @@ function powerTarget(id, unit) {
|
|
|
65738
66212
|
advancedExpression: true
|
|
65739
66213
|
};
|
|
65740
66214
|
}
|
|
65741
|
-
/** "Power and energy" extension:
|
|
66215
|
+
/** "Power and energy" extension: power, energy, voltage and current from other devices (D951). */
|
|
65742
66216
|
var powerMeterCustomize = {
|
|
65743
66217
|
version: 1,
|
|
65744
66218
|
targets: [
|
|
65745
|
-
powerTarget("
|
|
65746
|
-
powerTarget("
|
|
65747
|
-
powerTarget("
|
|
65748
|
-
powerTarget("
|
|
66219
|
+
powerTarget("power", "W"),
|
|
66220
|
+
powerTarget("energy", "kWh"),
|
|
66221
|
+
powerTarget("voltage", "V"),
|
|
66222
|
+
powerTarget("current", "A")
|
|
65749
66223
|
]
|
|
65750
66224
|
};
|
|
65751
66225
|
var powerMeterCapability = {
|
|
@@ -65761,41 +66235,41 @@ var powerMeterCapability = {
|
|
|
65761
66235
|
},
|
|
65762
66236
|
runtimeState: PowerMeterStatusSchema,
|
|
65763
66237
|
/**
|
|
65764
|
-
* Runtime-state durability: **restored** — as `numeric-sensor`; `
|
|
66238
|
+
* Runtime-state durability: **restored** — as `numeric-sensor`; `energy` is an accumulator whose restored value is the baseline.
|
|
65765
66239
|
*
|
|
65766
66240
|
* See `RuntimeStateDurability`. Enforced by
|
|
65767
66241
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65768
66242
|
*/
|
|
65769
66243
|
durability: "restored",
|
|
65770
66244
|
/**
|
|
65771
|
-
* History (D850): recorded series. Gauges are floored at 30 s; `
|
|
66245
|
+
* History (D850): recorded series. Gauges are floored at 30 s; `energy` is the one monotonic meter (counter).
|
|
65772
66246
|
*/
|
|
65773
66247
|
history: { fields: {
|
|
65774
|
-
|
|
66248
|
+
power: {
|
|
65775
66249
|
kind: "gauge",
|
|
65776
66250
|
unit: "W",
|
|
65777
66251
|
deadband: 1,
|
|
65778
66252
|
minIntervalMs: 3e4
|
|
65779
66253
|
},
|
|
65780
|
-
|
|
66254
|
+
energy: {
|
|
65781
66255
|
kind: "counter",
|
|
65782
66256
|
unit: "kWh",
|
|
65783
66257
|
deadband: .01,
|
|
65784
66258
|
minIntervalMs: 6e4
|
|
65785
66259
|
},
|
|
65786
|
-
|
|
66260
|
+
voltage: {
|
|
65787
66261
|
kind: "gauge",
|
|
65788
66262
|
unit: "V",
|
|
65789
66263
|
deadband: 1,
|
|
65790
66264
|
minIntervalMs: 3e4
|
|
65791
66265
|
},
|
|
65792
|
-
|
|
66266
|
+
current: {
|
|
65793
66267
|
kind: "gauge",
|
|
65794
66268
|
unit: "A",
|
|
65795
66269
|
deadband: .05,
|
|
65796
66270
|
minIntervalMs: 3e4
|
|
65797
66271
|
},
|
|
65798
|
-
|
|
66272
|
+
apparentPower: {
|
|
65799
66273
|
kind: "gauge",
|
|
65800
66274
|
unit: "VA",
|
|
65801
66275
|
deadband: 1,
|
|
@@ -65845,9 +66319,6 @@ var PresenceStatusSchema = object({
|
|
|
65845
66319
|
location: string().nullable(),
|
|
65846
66320
|
/** GPS coordinates when available. Null otherwise. */
|
|
65847
66321
|
gps: GpsLocationSchema.nullable(),
|
|
65848
|
-
/** Optional battery level of the tracking device (0..100). Null
|
|
65849
|
-
* when not reported. */
|
|
65850
|
-
batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
65851
66322
|
/** Ms epoch when the slice was last updated. */
|
|
65852
66323
|
lastChangedAt: number()
|
|
65853
66324
|
});
|
|
@@ -65876,14 +66347,7 @@ var presenceCapability = {
|
|
|
65876
66347
|
* `scripts/check-runtime-state-durability.ts`.
|
|
65877
66348
|
*/
|
|
65878
66349
|
durability: "restored",
|
|
65879
|
-
|
|
65880
|
-
* History (D850): recorded series.
|
|
65881
|
-
*/
|
|
65882
|
-
history: { fields: { batteryPercent: {
|
|
65883
|
-
kind: "gauge",
|
|
65884
|
-
unit: "%",
|
|
65885
|
-
deadband: 1
|
|
65886
|
-
} } },
|
|
66350
|
+
history: "none",
|
|
65887
66351
|
/** Clock fields: written, but excluded from the compare that decides
|
|
65888
66352
|
* whether persisting is worth a SQLite commit. */
|
|
65889
66353
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -65898,7 +66362,7 @@ var presenceCapability = {
|
|
|
65898
66362
|
*/
|
|
65899
66363
|
var PressureSensorStatusSchema = object({
|
|
65900
66364
|
/** Current pressure in hPa. `null` when the sample was refused (D393). */
|
|
65901
|
-
|
|
66365
|
+
pressure: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
|
|
65902
66366
|
/** Ms epoch when the slice was last updated. */
|
|
65903
66367
|
lastFetchedAt: number()
|
|
65904
66368
|
});
|
|
@@ -65924,7 +66388,7 @@ var pressureSensorCapability = {
|
|
|
65924
66388
|
/**
|
|
65925
66389
|
* History (D850): recorded series.
|
|
65926
66390
|
*/
|
|
65927
|
-
history: { fields: {
|
|
66391
|
+
history: { fields: { pressure: {
|
|
65928
66392
|
kind: "gauge",
|
|
65929
66393
|
unit: "hPa",
|
|
65930
66394
|
deadband: .1
|
|
@@ -70127,7 +70591,7 @@ var tamperCapability = {
|
|
|
70127
70591
|
*/
|
|
70128
70592
|
var TemperatureSensorStatusSchema = object({
|
|
70129
70593
|
/** Current temperature in Celsius. `null` when the sample was refused (D393). */
|
|
70130
|
-
|
|
70594
|
+
temperature: number().nullable().meta(readingMeta("temperature", {
|
|
70131
70595
|
precision: 1,
|
|
70132
70596
|
label: "Temperature"
|
|
70133
70597
|
})),
|
|
@@ -70156,7 +70620,7 @@ var temperatureSensorCapability = {
|
|
|
70156
70620
|
/**
|
|
70157
70621
|
* History (D850): recorded series.
|
|
70158
70622
|
*/
|
|
70159
|
-
history: { fields: {
|
|
70623
|
+
history: { fields: { temperature: {
|
|
70160
70624
|
kind: "gauge",
|
|
70161
70625
|
unit: "°C",
|
|
70162
70626
|
deadband: .1
|
|
@@ -70453,7 +70917,7 @@ var VacuumControlStatusSchema = object({
|
|
|
70453
70917
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
70454
70918
|
availableFanSpeeds: array(string()),
|
|
70455
70919
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
70456
|
-
|
|
70920
|
+
progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
70457
70921
|
/** Current error code (0 / null = no error). */
|
|
70458
70922
|
errorCode: number().nullable().meta(readingMeta("none")),
|
|
70459
70923
|
/** Human label for {@link errorCode}, or null when none / undecodable. */
|
|
@@ -72255,7 +72719,7 @@ var BaseDevice = class {
|
|
|
72255
72719
|
* `device-local-state.ts`. Drivers access via:
|
|
72256
72720
|
*
|
|
72257
72721
|
* `this.state.battery.sleeping = true` // patches the battery slice
|
|
72258
|
-
* `const pct = this.state.battery.
|
|
72722
|
+
* `const pct = this.state.battery.level` // reads the battery slice
|
|
72259
72723
|
* `this.state.deviceStatus.online = true` // mirrors `markOnline(true)`
|
|
72260
72724
|
*
|
|
72261
72725
|
* Adding a new cap with `runtimeState:` automatically extends this
|
|
@@ -72295,7 +72759,7 @@ var BaseDevice = class {
|
|
|
72295
72759
|
* shape; drivers don't redeclare it, they just write through.
|
|
72296
72760
|
*
|
|
72297
72761
|
* Read: `this.runtimeState.getCapState('battery')` →
|
|
72298
|
-
* `{
|
|
72762
|
+
* `{level, charging, sleeping, lastUpdated}` for any
|
|
72299
72763
|
* provider that registers `batteryCapability`.
|
|
72300
72764
|
* Write: `this.runtimeState.setCapState('battery', { … })`.
|
|
72301
72765
|
*
|
|
@@ -73469,6 +73933,104 @@ Object.freeze({
|
|
|
73469
73933
|
access: "create",
|
|
73470
73934
|
role: "admin"
|
|
73471
73935
|
},
|
|
73936
|
+
"actions.create": {
|
|
73937
|
+
capName: "actions",
|
|
73938
|
+
capScope: "system",
|
|
73939
|
+
addonId: null,
|
|
73940
|
+
access: "create",
|
|
73941
|
+
role: "admin"
|
|
73942
|
+
},
|
|
73943
|
+
"actions.delete": {
|
|
73944
|
+
capName: "actions",
|
|
73945
|
+
capScope: "system",
|
|
73946
|
+
addonId: null,
|
|
73947
|
+
access: "delete",
|
|
73948
|
+
role: "admin"
|
|
73949
|
+
},
|
|
73950
|
+
"actions.get": {
|
|
73951
|
+
capName: "actions",
|
|
73952
|
+
capScope: "system",
|
|
73953
|
+
addonId: null,
|
|
73954
|
+
access: "view",
|
|
73955
|
+
role: "viewer"
|
|
73956
|
+
},
|
|
73957
|
+
"actions.getLinks": {
|
|
73958
|
+
capName: "actions",
|
|
73959
|
+
capScope: "system",
|
|
73960
|
+
addonId: null,
|
|
73961
|
+
access: "view",
|
|
73962
|
+
role: "admin"
|
|
73963
|
+
},
|
|
73964
|
+
"actions.getTraces": {
|
|
73965
|
+
capName: "actions",
|
|
73966
|
+
capScope: "system",
|
|
73967
|
+
addonId: null,
|
|
73968
|
+
access: "view",
|
|
73969
|
+
role: "admin"
|
|
73970
|
+
},
|
|
73971
|
+
"actions.list": {
|
|
73972
|
+
capName: "actions",
|
|
73973
|
+
capScope: "system",
|
|
73974
|
+
addonId: null,
|
|
73975
|
+
access: "view",
|
|
73976
|
+
role: "admin"
|
|
73977
|
+
},
|
|
73978
|
+
"actions.listForCamera": {
|
|
73979
|
+
capName: "actions",
|
|
73980
|
+
capScope: "system",
|
|
73981
|
+
addonId: null,
|
|
73982
|
+
access: "view",
|
|
73983
|
+
role: "viewer"
|
|
73984
|
+
},
|
|
73985
|
+
"actions.run": {
|
|
73986
|
+
capName: "actions",
|
|
73987
|
+
capScope: "system",
|
|
73988
|
+
addonId: null,
|
|
73989
|
+
access: "create",
|
|
73990
|
+
role: "viewer"
|
|
73991
|
+
},
|
|
73992
|
+
"actions.setLinks": {
|
|
73993
|
+
capName: "actions",
|
|
73994
|
+
capScope: "system",
|
|
73995
|
+
addonId: null,
|
|
73996
|
+
access: "create",
|
|
73997
|
+
role: "admin"
|
|
73998
|
+
},
|
|
73999
|
+
"actions.stop": {
|
|
74000
|
+
capName: "actions",
|
|
74001
|
+
capScope: "system",
|
|
74002
|
+
addonId: null,
|
|
74003
|
+
access: "create",
|
|
74004
|
+
role: "admin"
|
|
74005
|
+
},
|
|
74006
|
+
"actions.update": {
|
|
74007
|
+
capName: "actions",
|
|
74008
|
+
capScope: "system",
|
|
74009
|
+
addonId: null,
|
|
74010
|
+
access: "create",
|
|
74011
|
+
role: "admin"
|
|
74012
|
+
},
|
|
74013
|
+
"actionSource.listActions": {
|
|
74014
|
+
capName: "action-source",
|
|
74015
|
+
capScope: "system",
|
|
74016
|
+
addonId: null,
|
|
74017
|
+
access: "view",
|
|
74018
|
+
role: "admin"
|
|
74019
|
+
},
|
|
74020
|
+
"actionSource.runAction": {
|
|
74021
|
+
capName: "action-source",
|
|
74022
|
+
capScope: "system",
|
|
74023
|
+
addonId: null,
|
|
74024
|
+
access: "create",
|
|
74025
|
+
role: "admin"
|
|
74026
|
+
},
|
|
74027
|
+
"actionSource.stopAction": {
|
|
74028
|
+
capName: "action-source",
|
|
74029
|
+
capScope: "system",
|
|
74030
|
+
addonId: null,
|
|
74031
|
+
access: "create",
|
|
74032
|
+
role: "admin"
|
|
74033
|
+
},
|
|
73472
74034
|
"addonPages.listPages": {
|
|
73473
74035
|
capName: "addon-pages",
|
|
73474
74036
|
capScope: "system",
|
|
@@ -74750,6 +75312,13 @@ Object.freeze({
|
|
|
74750
75312
|
access: "view",
|
|
74751
75313
|
role: "admin"
|
|
74752
75314
|
},
|
|
75315
|
+
"coreBlocks.getAutomationRunState": {
|
|
75316
|
+
capName: "core-blocks",
|
|
75317
|
+
capScope: "system",
|
|
75318
|
+
addonId: null,
|
|
75319
|
+
access: "view",
|
|
75320
|
+
role: "admin"
|
|
75321
|
+
},
|
|
74753
75322
|
"coreBlocks.getBlockSettings": {
|
|
74754
75323
|
capName: "core-blocks",
|
|
74755
75324
|
capScope: "system",
|
|
@@ -74771,6 +75340,13 @@ Object.freeze({
|
|
|
74771
75340
|
access: "view",
|
|
74772
75341
|
role: "admin"
|
|
74773
75342
|
},
|
|
75343
|
+
"coreBlocks.getTraces": {
|
|
75344
|
+
capName: "core-blocks",
|
|
75345
|
+
capScope: "system",
|
|
75346
|
+
addonId: null,
|
|
75347
|
+
access: "view",
|
|
75348
|
+
role: "admin"
|
|
75349
|
+
},
|
|
74774
75350
|
"coreBlocks.getTypeDefs": {
|
|
74775
75351
|
capName: "core-blocks",
|
|
74776
75352
|
capScope: "system",
|
|
@@ -74806,6 +75382,13 @@ Object.freeze({
|
|
|
74806
75382
|
access: "create",
|
|
74807
75383
|
role: "admin"
|
|
74808
75384
|
},
|
|
75385
|
+
"coreBlocks.reportAutomationRun": {
|
|
75386
|
+
capName: "core-blocks",
|
|
75387
|
+
capScope: "system",
|
|
75388
|
+
addonId: null,
|
|
75389
|
+
access: "create",
|
|
75390
|
+
role: "admin"
|
|
75391
|
+
},
|
|
74809
75392
|
"coreBlocks.restart": {
|
|
74810
75393
|
capName: "core-blocks",
|
|
74811
75394
|
capScope: "system",
|
|
@@ -83379,7 +83962,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83379
83962
|
label: t("Full brightness", "Luminosità massima"),
|
|
83380
83963
|
phrase: t("Set {device} to full brightness", "Porta {device} alla massima luminosità"),
|
|
83381
83964
|
icon: "sun",
|
|
83382
|
-
args: {
|
|
83965
|
+
args: { level: 100 }
|
|
83383
83966
|
},
|
|
83384
83967
|
{
|
|
83385
83968
|
id: "brightness.half",
|
|
@@ -83387,7 +83970,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83387
83970
|
label: t("Half brightness", "Luminosità a metà"),
|
|
83388
83971
|
phrase: t("Dim {device} to half", "Abbassa {device} a metà luminosità"),
|
|
83389
83972
|
icon: "sun-dim",
|
|
83390
|
-
args: {
|
|
83973
|
+
args: { level: 50 }
|
|
83391
83974
|
},
|
|
83392
83975
|
{
|
|
83393
83976
|
id: "brightness.off",
|
|
@@ -83395,16 +83978,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83395
83978
|
label: t("Brightness off", "Luminosità a zero"),
|
|
83396
83979
|
phrase: t("Dim {device} to zero", "Abbassa {device} a zero"),
|
|
83397
83980
|
icon: "lightbulb-off",
|
|
83398
|
-
args: {
|
|
83981
|
+
args: { level: 0 }
|
|
83399
83982
|
},
|
|
83400
83983
|
{
|
|
83401
83984
|
id: "brightness.set",
|
|
83402
83985
|
method: "setBrightness",
|
|
83403
83986
|
label: t("Set brightness", "Imposta la luminosità"),
|
|
83404
|
-
phrase: t("Set the brightness of {device} to {
|
|
83987
|
+
phrase: t("Set the brightness of {device} to {level}", "Imposta la luminosità di {device} a {level}"),
|
|
83405
83988
|
icon: "sun-medium",
|
|
83406
83989
|
openArgs: [{
|
|
83407
|
-
key: "
|
|
83990
|
+
key: "level",
|
|
83408
83991
|
label: PERCENT,
|
|
83409
83992
|
offer: {
|
|
83410
83993
|
kind: "number",
|
|
@@ -83418,13 +84001,13 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83418
84001
|
],
|
|
83419
84002
|
state: [{
|
|
83420
84003
|
kind: "numeric",
|
|
83421
|
-
field: "
|
|
84004
|
+
field: "level",
|
|
83422
84005
|
quantity: t("the brightness", "la luminosità"),
|
|
83423
84006
|
label: t("Brightness", "Luminosità"),
|
|
83424
84007
|
unit: "%",
|
|
83425
84008
|
icon: "sun"
|
|
83426
84009
|
}],
|
|
83427
|
-
events: { onBrightnessChanged: { notOperatorFacing: "the `
|
|
84010
|
+
events: { onBrightnessChanged: { notOperatorFacing: "the `level` state trigger reads the same change" } }
|
|
83428
84011
|
},
|
|
83429
84012
|
color: {
|
|
83430
84013
|
scope: "device",
|
|
@@ -83438,7 +84021,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83438
84021
|
icon: "sun",
|
|
83439
84022
|
args: { color: {
|
|
83440
84023
|
mode: "mired",
|
|
83441
|
-
|
|
84024
|
+
colorTemperature: 370
|
|
83442
84025
|
} }
|
|
83443
84026
|
},
|
|
83444
84027
|
{
|
|
@@ -83449,7 +84032,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
83449
84032
|
icon: "snowflake",
|
|
83450
84033
|
args: { color: {
|
|
83451
84034
|
mode: "mired",
|
|
83452
|
-
|
|
84035
|
+
colorTemperature: 200
|
|
83453
84036
|
} }
|
|
83454
84037
|
},
|
|
83455
84038
|
{
|
|
@@ -84063,7 +84646,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
84063
84646
|
label: t("Fan off", "Ventilatore spento"),
|
|
84064
84647
|
phrase: t("Stop {device}", "Ferma {device}"),
|
|
84065
84648
|
icon: "power-off",
|
|
84066
|
-
args: {
|
|
84649
|
+
args: { speed: 0 }
|
|
84067
84650
|
},
|
|
84068
84651
|
{
|
|
84069
84652
|
id: "fan.full",
|
|
@@ -84071,16 +84654,16 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
84071
84654
|
label: t("Fan full", "Ventilatore al massimo"),
|
|
84072
84655
|
phrase: t("Run {device} at full speed", "Porta {device} alla massima velocità"),
|
|
84073
84656
|
icon: "fan",
|
|
84074
|
-
args: {
|
|
84657
|
+
args: { speed: 100 }
|
|
84075
84658
|
},
|
|
84076
84659
|
{
|
|
84077
84660
|
id: "fan.speed",
|
|
84078
84661
|
method: "setPercentage",
|
|
84079
84662
|
label: t("Set speed", "Imposta la velocità"),
|
|
84080
|
-
phrase: t("Set the speed of {device} to {
|
|
84663
|
+
phrase: t("Set the speed of {device} to {speed}", "Imposta la velocità di {device} al {speed}"),
|
|
84081
84664
|
icon: "fan",
|
|
84082
84665
|
openArgs: [{
|
|
84083
|
-
key: "
|
|
84666
|
+
key: "speed",
|
|
84084
84667
|
label: t("Speed", "Velocità"),
|
|
84085
84668
|
offer: {
|
|
84086
84669
|
kind: "number",
|
|
@@ -84142,7 +84725,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
84142
84725
|
],
|
|
84143
84726
|
state: [{
|
|
84144
84727
|
kind: "numeric",
|
|
84145
|
-
field: "
|
|
84728
|
+
field: "speed",
|
|
84146
84729
|
quantity: t("the speed", "la velocità"),
|
|
84147
84730
|
label: t("Speed", "Velocità"),
|
|
84148
84731
|
unit: "%",
|
|
@@ -84940,7 +85523,7 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
84940
85523
|
},
|
|
84941
85524
|
{
|
|
84942
85525
|
kind: "numeric",
|
|
84943
|
-
field: "
|
|
85526
|
+
field: "progress",
|
|
84944
85527
|
quantity: t("the cycle progress", "l’avanzamento del lavaggio"),
|
|
84945
85528
|
label: t("Progress", "Avanzamento"),
|
|
84946
85529
|
unit: "%",
|
|
@@ -85298,10 +85881,10 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
85298
85881
|
id: "media.seek",
|
|
85299
85882
|
method: "seek",
|
|
85300
85883
|
label: t("Seek", "Vai al punto"),
|
|
85301
|
-
phrase: t("Move {device} to {
|
|
85884
|
+
phrase: t("Move {device} to {position}", "Porta {device} al punto {position}"),
|
|
85302
85885
|
icon: "fast-forward",
|
|
85303
85886
|
openArgs: [{
|
|
85304
|
-
key: "
|
|
85887
|
+
key: "position",
|
|
85305
85888
|
label: t("Position", "Posizione"),
|
|
85306
85889
|
offer: {
|
|
85307
85890
|
kind: "number",
|
|
@@ -86350,7 +86933,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86350
86933
|
state: [
|
|
86351
86934
|
{
|
|
86352
86935
|
kind: "numeric",
|
|
86353
|
-
field: "
|
|
86936
|
+
field: "co2",
|
|
86354
86937
|
quantity: t("the CO₂", "la CO₂"),
|
|
86355
86938
|
label: t("CO₂", "CO₂"),
|
|
86356
86939
|
unit: "ppm",
|
|
@@ -86358,7 +86941,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86358
86941
|
},
|
|
86359
86942
|
{
|
|
86360
86943
|
kind: "numeric",
|
|
86361
|
-
field: "
|
|
86944
|
+
field: "voc",
|
|
86362
86945
|
quantity: t("the VOC level", "il livello di COV"),
|
|
86363
86946
|
label: t("VOC", "COV"),
|
|
86364
86947
|
unit: "ppb",
|
|
@@ -86394,7 +86977,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86394
86977
|
noun: t("Light level", "Luminosità ambiente"),
|
|
86395
86978
|
state: [{
|
|
86396
86979
|
kind: "numeric",
|
|
86397
|
-
field: "
|
|
86980
|
+
field: "illuminance",
|
|
86398
86981
|
quantity: t("the light level", "la luminosità"),
|
|
86399
86982
|
label: t("Illuminance", "Illuminamento"),
|
|
86400
86983
|
unit: "lx",
|
|
@@ -86597,7 +87180,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86597
87180
|
noun: t("Humidity", "Umidità"),
|
|
86598
87181
|
state: [{
|
|
86599
87182
|
kind: "numeric",
|
|
86600
|
-
field: "
|
|
87183
|
+
field: "humidity",
|
|
86601
87184
|
quantity: t("the humidity", "l’umidità"),
|
|
86602
87185
|
label: t("Humidity", "Umidità"),
|
|
86603
87186
|
unit: "%",
|
|
@@ -86645,7 +87228,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86645
87228
|
state: [
|
|
86646
87229
|
{
|
|
86647
87230
|
kind: "numeric",
|
|
86648
|
-
field: "
|
|
87231
|
+
field: "power",
|
|
86649
87232
|
quantity: t("the power draw", "il consumo"),
|
|
86650
87233
|
label: t("Power", "Potenza"),
|
|
86651
87234
|
unit: "W",
|
|
@@ -86653,7 +87236,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86653
87236
|
},
|
|
86654
87237
|
{
|
|
86655
87238
|
kind: "numeric",
|
|
86656
|
-
field: "
|
|
87239
|
+
field: "energy",
|
|
86657
87240
|
quantity: t("the energy used", "l’energia consumata"),
|
|
86658
87241
|
label: t("Energy", "Energia"),
|
|
86659
87242
|
unit: "kWh",
|
|
@@ -86661,7 +87244,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86661
87244
|
},
|
|
86662
87245
|
{
|
|
86663
87246
|
kind: "numeric",
|
|
86664
|
-
field: "
|
|
87247
|
+
field: "voltage",
|
|
86665
87248
|
quantity: t("the voltage", "la tensione"),
|
|
86666
87249
|
label: t("Voltage", "Tensione"),
|
|
86667
87250
|
unit: "V",
|
|
@@ -86669,7 +87252,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86669
87252
|
},
|
|
86670
87253
|
{
|
|
86671
87254
|
kind: "numeric",
|
|
86672
|
-
field: "
|
|
87255
|
+
field: "current",
|
|
86673
87256
|
quantity: t("the current", "la corrente"),
|
|
86674
87257
|
label: t("Current", "Corrente"),
|
|
86675
87258
|
unit: "A",
|
|
@@ -86686,13 +87269,6 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86686
87269
|
label: t("Where", "Posizione"),
|
|
86687
87270
|
phrase: t("When {device} is at {value}", "Quando {device} è in {value}"),
|
|
86688
87271
|
icon: "map-pin"
|
|
86689
|
-
}, {
|
|
86690
|
-
kind: "numeric",
|
|
86691
|
-
field: "batteryPercent",
|
|
86692
|
-
quantity: t("the phone battery", "la batteria del telefono"),
|
|
86693
|
-
label: t("Battery", "Batteria"),
|
|
86694
|
-
unit: "%",
|
|
86695
|
-
icon: "battery"
|
|
86696
87272
|
}]
|
|
86697
87273
|
},
|
|
86698
87274
|
"pressure-sensor": {
|
|
@@ -86700,7 +87276,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86700
87276
|
noun: t("Pressure", "Pressione"),
|
|
86701
87277
|
state: [{
|
|
86702
87278
|
kind: "numeric",
|
|
86703
|
-
field: "
|
|
87279
|
+
field: "pressure",
|
|
86704
87280
|
quantity: t("the pressure", "la pressione"),
|
|
86705
87281
|
label: t("Pressure", "Pressione"),
|
|
86706
87282
|
unit: "hPa",
|
|
@@ -86736,7 +87312,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86736
87312
|
noun: t("Temperature", "Temperatura"),
|
|
86737
87313
|
state: [{
|
|
86738
87314
|
kind: "numeric",
|
|
86739
|
-
field: "
|
|
87315
|
+
field: "temperature",
|
|
86740
87316
|
quantity: t("the temperature", "la temperatura"),
|
|
86741
87317
|
label: t("Temperature", "Temperatura"),
|
|
86742
87318
|
unit: "°C",
|
|
@@ -86807,7 +87383,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86807
87383
|
state: [
|
|
86808
87384
|
{
|
|
86809
87385
|
kind: "numeric",
|
|
86810
|
-
field: "
|
|
87386
|
+
field: "level",
|
|
86811
87387
|
quantity: t("the battery level", "il livello della batteria"),
|
|
86812
87388
|
label: t("Battery", "Batteria"),
|
|
86813
87389
|
unit: "%",
|
|
@@ -86849,7 +87425,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86849
87425
|
icon: "battery-charging"
|
|
86850
87426
|
}
|
|
86851
87427
|
],
|
|
86852
|
-
events: { onStatusChanged: { notOperatorFacing: "the
|
|
87428
|
+
events: { onStatusChanged: { notOperatorFacing: "the level / sleeping / charging state triggers each read one field of this change" } },
|
|
86853
87429
|
extraEvents: [{
|
|
86854
87430
|
category: EventCategory.DeviceAwake,
|
|
86855
87431
|
label: t("Woke up", "Risvegliato"),
|
|
@@ -86867,7 +87443,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
86867
87443
|
noun: t("Network link", "Collegamento di rete"),
|
|
86868
87444
|
state: [{
|
|
86869
87445
|
kind: "numeric",
|
|
86870
|
-
field: "
|
|
87446
|
+
field: "signal",
|
|
86871
87447
|
quantity: t("the signal strength", "l’intensità del segnale"),
|
|
86872
87448
|
label: t("Signal", "Segnale"),
|
|
86873
87449
|
unit: "%",
|
|
@@ -86960,6 +87536,8 @@ var ML = "model and training machinery — no device action";
|
|
|
86960
87536
|
var INTERNAL = "internal plumbing between addons — never operator-facing";
|
|
86961
87537
|
/** Every system-scoped cap, with why it is not a device's vocabulary. */
|
|
86962
87538
|
var SYSTEM_CAP_VOCABULARY = {
|
|
87539
|
+
"action-source": system(INTERNAL),
|
|
87540
|
+
actions: system("declared actions — run from the Actions page and from the cameras that link them"),
|
|
86963
87541
|
"addon-pages": system(UI_PLUMBING),
|
|
86964
87542
|
"addon-pages-source": system(UI_PLUMBING),
|
|
86965
87543
|
"addon-routes": system(UI_PLUMBING),
|
|
@@ -87308,6 +87886,31 @@ Object.freeze({
|
|
|
87308
87886
|
form: "single",
|
|
87309
87887
|
optional: false
|
|
87310
87888
|
}],
|
|
87889
|
+
"actions.get": [{
|
|
87890
|
+
name: "deviceId",
|
|
87891
|
+
form: "single",
|
|
87892
|
+
optional: true
|
|
87893
|
+
}],
|
|
87894
|
+
"actions.getLinks": [{
|
|
87895
|
+
name: "deviceId",
|
|
87896
|
+
form: "single",
|
|
87897
|
+
optional: false
|
|
87898
|
+
}],
|
|
87899
|
+
"actions.listForCamera": [{
|
|
87900
|
+
name: "deviceId",
|
|
87901
|
+
form: "single",
|
|
87902
|
+
optional: false
|
|
87903
|
+
}],
|
|
87904
|
+
"actions.run": [{
|
|
87905
|
+
name: "deviceId",
|
|
87906
|
+
form: "single",
|
|
87907
|
+
optional: true
|
|
87908
|
+
}],
|
|
87909
|
+
"actions.setLinks": [{
|
|
87910
|
+
name: "deviceId",
|
|
87911
|
+
form: "single",
|
|
87912
|
+
optional: false
|
|
87913
|
+
}],
|
|
87311
87914
|
"addonSettings.getDeviceSettings": [{
|
|
87312
87915
|
name: "deviceId",
|
|
87313
87916
|
form: "single",
|
|
@@ -91440,6 +92043,7 @@ DEFAULT_NATIVE_LEASE_SETTINGS.activityMs;
|
|
|
91440
92043
|
DEFAULT_NATIVE_LEASE_SETTINGS.tileBudgetMb;
|
|
91441
92044
|
DEFAULT_NATIVE_LEASE_SETTINGS.sceneBudgetMb;
|
|
91442
92045
|
DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
92046
|
+
String.raw`(?<=^|["'(\s>,\[{])`;
|
|
91443
92047
|
var MB = 1024 * 1024;
|
|
91444
92048
|
1024 * MB, 3072 * MB;
|
|
91445
92049
|
//#endregion
|
|
@@ -200809,7 +201413,7 @@ var FloodlightAccessory = class extends BaseDevice {
|
|
|
200809
201413
|
lastChangedAt: ts
|
|
200810
201414
|
});
|
|
200811
201415
|
if (brightness !== void 0) this.setCapSlice(brightnessCapability, {
|
|
200812
|
-
|
|
201416
|
+
level: brightness,
|
|
200813
201417
|
lastChangedAt: ts
|
|
200814
201418
|
});
|
|
200815
201419
|
this.hasFetchedFromFirmware = true;
|
|
@@ -200928,7 +201532,7 @@ var FloodlightAccessory = class extends BaseDevice {
|
|
|
200928
201532
|
}
|
|
200929
201533
|
brightnessView() {
|
|
200930
201534
|
return this.getCapSlice(brightnessCapability) ?? {
|
|
200931
|
-
|
|
201535
|
+
level: 100,
|
|
200932
201536
|
lastChangedAt: 0
|
|
200933
201537
|
};
|
|
200934
201538
|
}
|
|
@@ -200953,19 +201557,19 @@ var FloodlightAccessory = class extends BaseDevice {
|
|
|
200953
201557
|
registerBrightnessCap() {
|
|
200954
201558
|
this.ctx.registerNativeCap(brightnessCapability, {
|
|
200955
201559
|
getStatus: async () => this.brightnessView(),
|
|
200956
|
-
setBrightness: async ({ deviceId, percentage }) => {
|
|
201560
|
+
setBrightness: async ({ deviceId, level: percentage }) => {
|
|
200957
201561
|
if (deviceId !== this.id) return;
|
|
200958
201562
|
const value = Math.max(0, Math.min(100, percentage));
|
|
200959
201563
|
if (this.switchView().on) await (await this.api).setWhiteLedState(this.channel, void 0, value);
|
|
200960
201564
|
this.setCapSlice(brightnessCapability, {
|
|
200961
|
-
|
|
201565
|
+
level: value,
|
|
200962
201566
|
lastChangedAt: Date.now()
|
|
200963
201567
|
});
|
|
200964
201568
|
this.lastSetAtMs = Date.now();
|
|
200965
201569
|
}
|
|
200966
201570
|
});
|
|
200967
201571
|
this.setCapSlice(brightnessCapability, {
|
|
200968
|
-
|
|
201572
|
+
level: 100,
|
|
200969
201573
|
lastChangedAt: 0
|
|
200970
201574
|
});
|
|
200971
201575
|
}
|
|
@@ -201641,13 +202245,13 @@ function mapNetworkReadout(readout, now) {
|
|
|
201641
202245
|
const type = linkTypeOf(readout);
|
|
201642
202246
|
const raw = readout.wifiSignal;
|
|
201643
202247
|
const wireless = type === "wifi" || type === "cellular";
|
|
201644
|
-
const
|
|
202248
|
+
const signal = wireless ? signalPercentOf(raw) : null;
|
|
201645
202249
|
const rssiDbm = wireless && raw !== void 0 && Number.isFinite(raw) && raw < 0 ? raw : void 0;
|
|
201646
202250
|
const ssid = wireless && readout.ssid !== void 0 && readout.ssid !== "" ? readout.ssid : void 0;
|
|
201647
202251
|
return {
|
|
201648
202252
|
type,
|
|
201649
|
-
|
|
201650
|
-
...rssiDbm !== void 0 ? { rssiDbm } : {},
|
|
202253
|
+
signal,
|
|
202254
|
+
...rssiDbm !== void 0 ? { rssi: rssiDbm } : {},
|
|
201651
202255
|
...ssid !== void 0 ? { ssid } : {},
|
|
201652
202256
|
lastUpdated: now
|
|
201653
202257
|
};
|
|
@@ -204890,7 +205494,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
204890
205494
|
*/
|
|
204891
205495
|
mapBatteryInfo(info) {
|
|
204892
205496
|
return {
|
|
204893
|
-
|
|
205497
|
+
level: typeof info.batteryPercent === "number" ? Math.max(0, Math.min(100, Math.round(info.batteryPercent))) : this.state.battery.level ?? null,
|
|
204894
205498
|
charging: reportsPowerSource(info) ? deriveChargingSource(info.adapterStatus, info.chargeStatus) : this.state.battery.charging ?? "unknown",
|
|
204895
205499
|
sleeping: info.sleeping === true || this.sleeping,
|
|
204896
205500
|
lastUpdated: Date.now()
|
|
@@ -205026,7 +205630,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
205026
205630
|
}
|
|
205027
205631
|
});
|
|
205028
205632
|
if (this.getCapSlice(batteryCapability) === null) this.setCapSlice(batteryCapability, {
|
|
205029
|
-
|
|
205633
|
+
level: null,
|
|
205030
205634
|
charging: "none",
|
|
205031
205635
|
sleeping: false,
|
|
205032
205636
|
lastUpdated: Date.now()
|
|
@@ -205254,7 +205858,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
205254
205858
|
});
|
|
205255
205859
|
this.setCapSlice(batteryCapability, {
|
|
205256
205860
|
...this.state.battery,
|
|
205257
|
-
|
|
205861
|
+
level: mapped.level,
|
|
205258
205862
|
charging: mapped.charging,
|
|
205259
205863
|
lastUpdated: Date.now()
|
|
205260
205864
|
});
|