@camstack/addon-training 0.1.108 → 0.1.110
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/{MotionZonesSettings-9m904uxm.mjs → MotionZonesSettings-D4s4e-dn.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-DDk1oMby.mjs → PrivacyMaskSettings-BtdwrmHQ.mjs} +2 -2
- package/dist/{SceneMonitorEditor-Dsq9Dzqm.mjs → SceneMonitorEditor-DOX6WQaZ.mjs} +2 -2
- package/dist/_stub.js +1399 -1365
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-Bz804aB6.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-C3SgLMLF.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CmVZHQ-k.mjs +26 -0
- package/dist/{dist-B8XLeyRL.js → dist-BSSYC9T8.js} +803 -64
- package/dist/{dist-BycZdx08.mjs → dist-De0e9-YH.mjs} +803 -64
- package/dist/{hostInit-CcF5kCoS.mjs → hostInit-DjLtjT-_.mjs} +2 -2
- package/dist/index.js +1 -1
- package/dist/orchestrator/training.addon.js +1 -1
- package/dist/orchestrator/training.addon.mjs +1 -1
- package/dist/{player-overlays-eJNV-UU-.mjs → player-overlays-C_B-yc3g.mjs} +1 -1
- package/dist/providers/modal/training-modal.addon.js +1 -1
- package/dist/providers/modal/training-modal.addon.mjs +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-DlCVUok5.mjs → responsive-YANRyril.mjs} +1 -1
- package/dist/{scene-monitor-copy-D3BXN-0E.mjs → scene-monitor-copy-B0w92y1z.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-9YL8IM8w.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-CosY3aLX.mjs} +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CjEDvlSM.mjs +0 -26
|
@@ -5621,7 +5621,7 @@ var ZodIssueCode = {
|
|
|
5621
5621
|
var ZodFirstPartyTypeKind;
|
|
5622
5622
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5623
5623
|
//#endregion
|
|
5624
|
-
//#region ../types/dist/sleep-
|
|
5624
|
+
//#region ../types/dist/sleep-63gM_1JR.mjs
|
|
5625
5625
|
/**
|
|
5626
5626
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5627
5627
|
* window to float samples (D455).
|
|
@@ -9149,6 +9149,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9149
9149
|
"recording-signal",
|
|
9150
9150
|
"records",
|
|
9151
9151
|
"remote",
|
|
9152
|
+
"remote-layout-components",
|
|
9152
9153
|
"running-state",
|
|
9153
9154
|
"scene-monitor",
|
|
9154
9155
|
"script-runner",
|
|
@@ -15885,6 +15886,478 @@ object({
|
|
|
15885
15886
|
path: ["expr"]
|
|
15886
15887
|
});
|
|
15887
15888
|
});
|
|
15889
|
+
/**
|
|
15890
|
+
* Identity envelope for a device's upstream-system metadata.
|
|
15891
|
+
*
|
|
15892
|
+
* Two jobs:
|
|
15893
|
+
*
|
|
15894
|
+
* 1. **Dispatch key.** `id` is the natural identifier the SOURCE system
|
|
15895
|
+
* uses to address this device (HA `entity_id`, Reolink MAC, ONVIF
|
|
15896
|
+
* WS-Discovery endpoint UUID, …). Provider code keeps a
|
|
15897
|
+
* `Map<sourceInfo.id, IDevice>` to route inbound push events in O(1)
|
|
15898
|
+
* without round-tripping through `stableId` / `id` mappings.
|
|
15899
|
+
*
|
|
15900
|
+
* 2. **Stability bridge.** `uniqueId` is the *immutable* upstream id when
|
|
15901
|
+
* one exists (HA `entity.unique_id`, Reolink MAC again — same as `id`
|
|
15902
|
+
* for vendors where MAC is the natural key). For systems where the
|
|
15903
|
+
* live dispatch key can be renamed (HA `entity_id` can be edited),
|
|
15904
|
+
* providers detect renames by matching `uniqueId` and patch `id`
|
|
15905
|
+
* in-place so dispatch keeps working.
|
|
15906
|
+
*
|
|
15907
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
15908
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
15909
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
15910
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
15911
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
15912
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
15913
|
+
*
|
|
15914
|
+
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
15915
|
+
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
15916
|
+
* details, …). Providers control what lands here.
|
|
15917
|
+
*/
|
|
15918
|
+
var SourceInfoSchema = object({
|
|
15919
|
+
/** Live dispatch key — mutable when the source system allows rename. */
|
|
15920
|
+
id: string(),
|
|
15921
|
+
/** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
|
|
15922
|
+
system: string(),
|
|
15923
|
+
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
15924
|
+
* Used to detect rename when `id` changes. */
|
|
15925
|
+
uniqueId: string().optional(),
|
|
15926
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
15927
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
15928
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
15929
|
+
dateTimeShape: _enum([
|
|
15930
|
+
"date",
|
|
15931
|
+
"time",
|
|
15932
|
+
"datetime"
|
|
15933
|
+
]).optional(),
|
|
15934
|
+
/** Provider-specific extras that don't fit the structured slots.
|
|
15935
|
+
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
15936
|
+
* attribute blobs (would explode the meta JSON column). */
|
|
15937
|
+
raw: record(string(), unknown()).optional()
|
|
15938
|
+
});
|
|
15939
|
+
/**
|
|
15940
|
+
* Frozen unit → spec table. `•` in the doc marks each dimension's canonical
|
|
15941
|
+
* unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
|
|
15942
|
+
* `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
|
|
15943
|
+
* decimals). K derives from `°C = K − 273.15`.
|
|
15944
|
+
*/
|
|
15945
|
+
var UNIT_TABLE = {
|
|
15946
|
+
"°C": {
|
|
15947
|
+
dimension: "temperature",
|
|
15948
|
+
factor: 1,
|
|
15949
|
+
offset: 0
|
|
15950
|
+
},
|
|
15951
|
+
"°F": {
|
|
15952
|
+
dimension: "temperature",
|
|
15953
|
+
factor: 5 / 9,
|
|
15954
|
+
offset: -160 / 9
|
|
15955
|
+
},
|
|
15956
|
+
K: {
|
|
15957
|
+
dimension: "temperature",
|
|
15958
|
+
factor: 1,
|
|
15959
|
+
offset: -273.15
|
|
15960
|
+
},
|
|
15961
|
+
hPa: {
|
|
15962
|
+
dimension: "pressure",
|
|
15963
|
+
factor: 1,
|
|
15964
|
+
offset: 0
|
|
15965
|
+
},
|
|
15966
|
+
kPa: {
|
|
15967
|
+
dimension: "pressure",
|
|
15968
|
+
factor: 10,
|
|
15969
|
+
offset: 0
|
|
15970
|
+
},
|
|
15971
|
+
Pa: {
|
|
15972
|
+
dimension: "pressure",
|
|
15973
|
+
factor: .01,
|
|
15974
|
+
offset: 0
|
|
15975
|
+
},
|
|
15976
|
+
mbar: {
|
|
15977
|
+
dimension: "pressure",
|
|
15978
|
+
factor: 1,
|
|
15979
|
+
offset: 0
|
|
15980
|
+
},
|
|
15981
|
+
bar: {
|
|
15982
|
+
dimension: "pressure",
|
|
15983
|
+
factor: 1e3,
|
|
15984
|
+
offset: 0
|
|
15985
|
+
},
|
|
15986
|
+
inHg: {
|
|
15987
|
+
dimension: "pressure",
|
|
15988
|
+
factor: 33.8639,
|
|
15989
|
+
offset: 0
|
|
15990
|
+
},
|
|
15991
|
+
mmHg: {
|
|
15992
|
+
dimension: "pressure",
|
|
15993
|
+
factor: 1.33322,
|
|
15994
|
+
offset: 0
|
|
15995
|
+
},
|
|
15996
|
+
psi: {
|
|
15997
|
+
dimension: "pressure",
|
|
15998
|
+
factor: 68.9476,
|
|
15999
|
+
offset: 0
|
|
16000
|
+
},
|
|
16001
|
+
"m/s": {
|
|
16002
|
+
dimension: "speed",
|
|
16003
|
+
factor: 1,
|
|
16004
|
+
offset: 0
|
|
16005
|
+
},
|
|
16006
|
+
"km/h": {
|
|
16007
|
+
dimension: "speed",
|
|
16008
|
+
factor: 1 / 3.6,
|
|
16009
|
+
offset: 0
|
|
16010
|
+
},
|
|
16011
|
+
mph: {
|
|
16012
|
+
dimension: "speed",
|
|
16013
|
+
factor: .44704,
|
|
16014
|
+
offset: 0
|
|
16015
|
+
},
|
|
16016
|
+
kn: {
|
|
16017
|
+
dimension: "speed",
|
|
16018
|
+
factor: .514444,
|
|
16019
|
+
offset: 0
|
|
16020
|
+
},
|
|
16021
|
+
"mm/h": {
|
|
16022
|
+
dimension: "precipitation-rate",
|
|
16023
|
+
factor: 1,
|
|
16024
|
+
offset: 0
|
|
16025
|
+
},
|
|
16026
|
+
"in/h": {
|
|
16027
|
+
dimension: "precipitation-rate",
|
|
16028
|
+
factor: 25.4,
|
|
16029
|
+
offset: 0
|
|
16030
|
+
},
|
|
16031
|
+
m: {
|
|
16032
|
+
dimension: "length",
|
|
16033
|
+
factor: 1,
|
|
16034
|
+
offset: 0
|
|
16035
|
+
},
|
|
16036
|
+
mm: {
|
|
16037
|
+
dimension: "length",
|
|
16038
|
+
factor: .001,
|
|
16039
|
+
offset: 0
|
|
16040
|
+
},
|
|
16041
|
+
cm: {
|
|
16042
|
+
dimension: "length",
|
|
16043
|
+
factor: .01,
|
|
16044
|
+
offset: 0
|
|
16045
|
+
},
|
|
16046
|
+
km: {
|
|
16047
|
+
dimension: "length",
|
|
16048
|
+
factor: 1e3,
|
|
16049
|
+
offset: 0
|
|
16050
|
+
},
|
|
16051
|
+
in: {
|
|
16052
|
+
dimension: "length",
|
|
16053
|
+
factor: .0254,
|
|
16054
|
+
offset: 0
|
|
16055
|
+
},
|
|
16056
|
+
ft: {
|
|
16057
|
+
dimension: "length",
|
|
16058
|
+
factor: .3048,
|
|
16059
|
+
offset: 0
|
|
16060
|
+
},
|
|
16061
|
+
mi: {
|
|
16062
|
+
dimension: "length",
|
|
16063
|
+
factor: 1609.344,
|
|
16064
|
+
offset: 0
|
|
16065
|
+
},
|
|
16066
|
+
"m²": {
|
|
16067
|
+
dimension: "area",
|
|
16068
|
+
factor: 1,
|
|
16069
|
+
offset: 0
|
|
16070
|
+
},
|
|
16071
|
+
lx: {
|
|
16072
|
+
dimension: "illuminance",
|
|
16073
|
+
factor: 1,
|
|
16074
|
+
offset: 0
|
|
16075
|
+
},
|
|
16076
|
+
"W/m²": {
|
|
16077
|
+
dimension: "irradiance",
|
|
16078
|
+
factor: 1,
|
|
16079
|
+
offset: 0
|
|
16080
|
+
},
|
|
16081
|
+
W: {
|
|
16082
|
+
dimension: "power",
|
|
16083
|
+
factor: 1,
|
|
16084
|
+
offset: 0
|
|
16085
|
+
},
|
|
16086
|
+
kW: {
|
|
16087
|
+
dimension: "power",
|
|
16088
|
+
factor: 1e3,
|
|
16089
|
+
offset: 0
|
|
16090
|
+
},
|
|
16091
|
+
VA: {
|
|
16092
|
+
dimension: "apparent-power",
|
|
16093
|
+
factor: 1,
|
|
16094
|
+
offset: 0
|
|
16095
|
+
},
|
|
16096
|
+
Wh: {
|
|
16097
|
+
dimension: "energy",
|
|
16098
|
+
factor: 1,
|
|
16099
|
+
offset: 0
|
|
16100
|
+
},
|
|
16101
|
+
kWh: {
|
|
16102
|
+
dimension: "energy",
|
|
16103
|
+
factor: 1e3,
|
|
16104
|
+
offset: 0
|
|
16105
|
+
},
|
|
16106
|
+
MWh: {
|
|
16107
|
+
dimension: "energy",
|
|
16108
|
+
factor: 1e6,
|
|
16109
|
+
offset: 0
|
|
16110
|
+
},
|
|
16111
|
+
V: {
|
|
16112
|
+
dimension: "voltage",
|
|
16113
|
+
factor: 1,
|
|
16114
|
+
offset: 0
|
|
16115
|
+
},
|
|
16116
|
+
mV: {
|
|
16117
|
+
dimension: "voltage",
|
|
16118
|
+
factor: .001,
|
|
16119
|
+
offset: 0
|
|
16120
|
+
},
|
|
16121
|
+
A: {
|
|
16122
|
+
dimension: "current",
|
|
16123
|
+
factor: 1,
|
|
16124
|
+
offset: 0
|
|
16125
|
+
},
|
|
16126
|
+
mA: {
|
|
16127
|
+
dimension: "current",
|
|
16128
|
+
factor: .001,
|
|
16129
|
+
offset: 0
|
|
16130
|
+
},
|
|
16131
|
+
ppm: {
|
|
16132
|
+
dimension: "concentration-volume",
|
|
16133
|
+
factor: 1,
|
|
16134
|
+
offset: 0
|
|
16135
|
+
},
|
|
16136
|
+
ppb: {
|
|
16137
|
+
dimension: "concentration-volume",
|
|
16138
|
+
factor: .001,
|
|
16139
|
+
offset: 0
|
|
16140
|
+
},
|
|
16141
|
+
"µg/m³": {
|
|
16142
|
+
dimension: "concentration-mass",
|
|
16143
|
+
factor: 1,
|
|
16144
|
+
offset: 0
|
|
16145
|
+
},
|
|
16146
|
+
"mg/m³": {
|
|
16147
|
+
dimension: "concentration-mass",
|
|
16148
|
+
factor: 1e3,
|
|
16149
|
+
offset: 0
|
|
16150
|
+
},
|
|
16151
|
+
kg: {
|
|
16152
|
+
dimension: "mass",
|
|
16153
|
+
factor: 1,
|
|
16154
|
+
offset: 0
|
|
16155
|
+
},
|
|
16156
|
+
g: {
|
|
16157
|
+
dimension: "mass",
|
|
16158
|
+
factor: .001,
|
|
16159
|
+
offset: 0
|
|
16160
|
+
},
|
|
16161
|
+
lb: {
|
|
16162
|
+
dimension: "mass",
|
|
16163
|
+
factor: .453592,
|
|
16164
|
+
offset: 0
|
|
16165
|
+
},
|
|
16166
|
+
oz: {
|
|
16167
|
+
dimension: "mass",
|
|
16168
|
+
factor: .0283495,
|
|
16169
|
+
offset: 0
|
|
16170
|
+
},
|
|
16171
|
+
"%": {
|
|
16172
|
+
dimension: "percentage",
|
|
16173
|
+
factor: 1,
|
|
16174
|
+
offset: 0
|
|
16175
|
+
},
|
|
16176
|
+
L: {
|
|
16177
|
+
dimension: "volume",
|
|
16178
|
+
factor: 1,
|
|
16179
|
+
offset: 0
|
|
16180
|
+
},
|
|
16181
|
+
mL: {
|
|
16182
|
+
dimension: "volume",
|
|
16183
|
+
factor: .001,
|
|
16184
|
+
offset: 0
|
|
16185
|
+
},
|
|
16186
|
+
gal: {
|
|
16187
|
+
dimension: "volume",
|
|
16188
|
+
factor: 3.785411784,
|
|
16189
|
+
offset: 0
|
|
16190
|
+
},
|
|
16191
|
+
s: {
|
|
16192
|
+
dimension: "duration",
|
|
16193
|
+
factor: 1,
|
|
16194
|
+
offset: 0
|
|
16195
|
+
},
|
|
16196
|
+
ms: {
|
|
16197
|
+
dimension: "duration",
|
|
16198
|
+
factor: .001,
|
|
16199
|
+
offset: 0
|
|
16200
|
+
},
|
|
16201
|
+
min: {
|
|
16202
|
+
dimension: "duration",
|
|
16203
|
+
factor: 60,
|
|
16204
|
+
offset: 0
|
|
16205
|
+
},
|
|
16206
|
+
h: {
|
|
16207
|
+
dimension: "duration",
|
|
16208
|
+
factor: 3600,
|
|
16209
|
+
offset: 0
|
|
16210
|
+
},
|
|
16211
|
+
d: {
|
|
16212
|
+
dimension: "duration",
|
|
16213
|
+
factor: 86400,
|
|
16214
|
+
offset: 0
|
|
16215
|
+
},
|
|
16216
|
+
B: {
|
|
16217
|
+
dimension: "information",
|
|
16218
|
+
factor: 1,
|
|
16219
|
+
offset: 0
|
|
16220
|
+
},
|
|
16221
|
+
KiB: {
|
|
16222
|
+
dimension: "information",
|
|
16223
|
+
factor: 1024,
|
|
16224
|
+
offset: 0
|
|
16225
|
+
},
|
|
16226
|
+
MiB: {
|
|
16227
|
+
dimension: "information",
|
|
16228
|
+
factor: 1024 ** 2,
|
|
16229
|
+
offset: 0
|
|
16230
|
+
},
|
|
16231
|
+
GiB: {
|
|
16232
|
+
dimension: "information",
|
|
16233
|
+
factor: 1024 ** 3,
|
|
16234
|
+
offset: 0
|
|
16235
|
+
},
|
|
16236
|
+
TiB: {
|
|
16237
|
+
dimension: "information",
|
|
16238
|
+
factor: 1024 ** 4,
|
|
16239
|
+
offset: 0
|
|
16240
|
+
},
|
|
16241
|
+
kB: {
|
|
16242
|
+
dimension: "information",
|
|
16243
|
+
factor: 1e3,
|
|
16244
|
+
offset: 0
|
|
16245
|
+
},
|
|
16246
|
+
MB: {
|
|
16247
|
+
dimension: "information",
|
|
16248
|
+
factor: 1e6,
|
|
16249
|
+
offset: 0
|
|
16250
|
+
},
|
|
16251
|
+
GB: {
|
|
16252
|
+
dimension: "information",
|
|
16253
|
+
factor: 1e9,
|
|
16254
|
+
offset: 0
|
|
16255
|
+
},
|
|
16256
|
+
"°": {
|
|
16257
|
+
dimension: "angle",
|
|
16258
|
+
factor: 1,
|
|
16259
|
+
offset: 0
|
|
16260
|
+
},
|
|
16261
|
+
dBFS: {
|
|
16262
|
+
dimension: "sound-level",
|
|
16263
|
+
factor: 1,
|
|
16264
|
+
offset: 0
|
|
16265
|
+
},
|
|
16266
|
+
dBm: {
|
|
16267
|
+
dimension: "signal-level",
|
|
16268
|
+
factor: 1,
|
|
16269
|
+
offset: 0
|
|
16270
|
+
},
|
|
16271
|
+
mired: {
|
|
16272
|
+
dimension: "colour-temperature",
|
|
16273
|
+
factor: 1,
|
|
16274
|
+
offset: 0
|
|
16275
|
+
},
|
|
16276
|
+
kbps: {
|
|
16277
|
+
dimension: "bitrate",
|
|
16278
|
+
factor: 1,
|
|
16279
|
+
offset: 0
|
|
16280
|
+
},
|
|
16281
|
+
Mbps: {
|
|
16282
|
+
dimension: "bitrate",
|
|
16283
|
+
factor: 1e3,
|
|
16284
|
+
offset: 0
|
|
16285
|
+
},
|
|
16286
|
+
fps: {
|
|
16287
|
+
dimension: "rate",
|
|
16288
|
+
factor: 1,
|
|
16289
|
+
offset: 0
|
|
16290
|
+
}
|
|
16291
|
+
};
|
|
16292
|
+
/** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
|
|
16293
|
+
function specFor(unit) {
|
|
16294
|
+
return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
|
|
16295
|
+
}
|
|
16296
|
+
/** Value in `spec`'s unit → its dimension's canonical unit. */
|
|
16297
|
+
function toCanonical(value, spec) {
|
|
16298
|
+
return value * spec.factor + spec.offset;
|
|
16299
|
+
}
|
|
16300
|
+
/** Canonical-unit value → the unit described by `spec`. */
|
|
16301
|
+
function fromCanonical(canonical, spec) {
|
|
16302
|
+
return (canonical - spec.offset) / spec.factor;
|
|
16303
|
+
}
|
|
16304
|
+
/**
|
|
16305
|
+
* Graceful variant for the render path: returns the converted value, or
|
|
16306
|
+
* `undefined` when the conversion is refused (unknown unit / cross-dimension).
|
|
16307
|
+
* Never throws — a render caller falls back to the raw value + source unit.
|
|
16308
|
+
*/
|
|
16309
|
+
function tryConvertUnit(value, from, to) {
|
|
16310
|
+
if (from === to) return value;
|
|
16311
|
+
const fromSpec = specFor(from);
|
|
16312
|
+
if (!fromSpec) return void 0;
|
|
16313
|
+
const toSpec = specFor(to);
|
|
16314
|
+
if (!toSpec) return void 0;
|
|
16315
|
+
if (fromSpec.dimension !== toSpec.dimension) return void 0;
|
|
16316
|
+
return fromCanonical(toCanonical(value, fromSpec), toSpec);
|
|
16317
|
+
}
|
|
16318
|
+
/**
|
|
16319
|
+
* A number a person types for a physical quantity — the input side of the
|
|
16320
|
+
* value + unit contract (D972).
|
|
16321
|
+
*
|
|
16322
|
+
* Readings are stored in the base unit of their quantity (D944); a cap method
|
|
16323
|
+
* param is stored in the unit its input schema DECLARES (`paramMeta`). The
|
|
16324
|
+
* wire pair {@link QuantityValue} says "this number is expressed in this
|
|
16325
|
+
* unit"; {@link convertQuantityInput} brings it to the stored unit and refuses,
|
|
16326
|
+
* with a typed {@link QuantityUnitError}, a unit that cannot be that quantity.
|
|
16327
|
+
*/
|
|
16328
|
+
/** A unit that cannot be applied to the number it was given with. */
|
|
16329
|
+
var QuantityUnitError = class extends Error {
|
|
16330
|
+
code;
|
|
16331
|
+
constructor(code, message) {
|
|
16332
|
+
super(`[${code}] ${message}`);
|
|
16333
|
+
this.name = "QuantityUnitError";
|
|
16334
|
+
this.code = code;
|
|
16335
|
+
}
|
|
16336
|
+
};
|
|
16337
|
+
/** The wire pair: `value` is expressed in `unit`. */
|
|
16338
|
+
var QuantityValueSchema = object({
|
|
16339
|
+
value: number(),
|
|
16340
|
+
unit: string().min(1)
|
|
16341
|
+
});
|
|
16342
|
+
/**
|
|
16343
|
+
* Zod `.meta()` bag for a cap METHOD param that is a physical quantity — the
|
|
16344
|
+
* input-side twin of `readingMeta`. The value is carried in `unit` (a gram
|
|
16345
|
+
* portion stays in grams); the unit must belong to the quantity, checked once
|
|
16346
|
+
* when the cap is declared.
|
|
16347
|
+
*/
|
|
16348
|
+
function paramMeta(declared) {
|
|
16349
|
+
const base = baseUnitOf(declared.quantity);
|
|
16350
|
+
if (base === void 0) throw new QuantityUnitError("unknown-unit", `quantity "${declared.quantity}" has no unit`);
|
|
16351
|
+
if (tryConvertUnit(1, declared.unit, base) === void 0) throw new QuantityUnitError("cross-dimension", `"${declared.unit}" is not a unit of ${declared.quantity}`);
|
|
16352
|
+
return {
|
|
16353
|
+
quantity: declared.quantity,
|
|
16354
|
+
unit: declared.unit
|
|
16355
|
+
};
|
|
16356
|
+
}
|
|
16357
|
+
object({
|
|
16358
|
+
quantity: ReadingQuantitySchema,
|
|
16359
|
+
unit: string().min(1)
|
|
16360
|
+
});
|
|
15888
16361
|
/** How a leaf compares a device field to a value. Derived from the field's
|
|
15889
16362
|
* `kind` in `deviceManager.getWireableFields`, never hand-maintained. */
|
|
15890
16363
|
var AutomationConditionOperatorSchema = _enum([
|
|
@@ -15907,8 +16380,10 @@ var AutomationConditionLeafSchema = object({
|
|
|
15907
16380
|
string(),
|
|
15908
16381
|
number(),
|
|
15909
16382
|
boolean(),
|
|
15910
|
-
array(union([string(), number()]))
|
|
15911
|
-
|
|
16383
|
+
array(union([string(), number()])),
|
|
16384
|
+
QuantityValueSchema
|
|
16385
|
+
]),
|
|
16386
|
+
unit: string().min(1).optional()
|
|
15912
16387
|
});
|
|
15913
16388
|
var AutomationConditionStationaryPresentSchema = object({
|
|
15914
16389
|
kind: literal("stationary-present"),
|
|
@@ -16061,7 +16536,13 @@ var AutomationCapStepSchema = object({
|
|
|
16061
16536
|
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
16062
16537
|
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
16063
16538
|
* the expression leaf. */
|
|
16064
|
-
args: record(string(), unknown()).optional()
|
|
16539
|
+
args: record(string(), unknown()).optional(),
|
|
16540
|
+
/**
|
|
16541
|
+
* The unit the person picked per arg (display only). `args` always hold the
|
|
16542
|
+
* value in the unit the method's input DECLARES (`paramMeta`); on a write an
|
|
16543
|
+
* arg may be a {@link QuantityValue}, which the save boundary converts.
|
|
16544
|
+
*/
|
|
16545
|
+
argUnits: record(string(), string().min(1)).optional()
|
|
16065
16546
|
});
|
|
16066
16547
|
/**
|
|
16067
16548
|
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
@@ -16441,6 +16922,16 @@ object({
|
|
|
16441
16922
|
lastRunAt: number().nullable(),
|
|
16442
16923
|
lastError: string().nullable()
|
|
16443
16924
|
});
|
|
16925
|
+
/** A bare number accepted as a base unit — the save succeeded, say so. */
|
|
16926
|
+
var UnitWarningSchema = object({
|
|
16927
|
+
/** Where in the saved record, e.g. `conditions.children.0` or `steps.2.args.grams`. */
|
|
16928
|
+
path: string(),
|
|
16929
|
+
deviceId: number().int().optional(),
|
|
16930
|
+
field: string(),
|
|
16931
|
+
value: number(),
|
|
16932
|
+
assumedUnit: string(),
|
|
16933
|
+
message: string()
|
|
16934
|
+
});
|
|
16444
16935
|
/**
|
|
16445
16936
|
* notification-output — canonical, capability-gated notification delivery.
|
|
16446
16937
|
*
|
|
@@ -21785,56 +22276,6 @@ var DeviceAdminLinkSchema = object({
|
|
|
21785
22276
|
});
|
|
21786
22277
|
method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema.nullable(), { auth: "admin" });
|
|
21787
22278
|
/**
|
|
21788
|
-
* Identity envelope for a device's upstream-system metadata.
|
|
21789
|
-
*
|
|
21790
|
-
* Two jobs:
|
|
21791
|
-
*
|
|
21792
|
-
* 1. **Dispatch key.** `id` is the natural identifier the SOURCE system
|
|
21793
|
-
* uses to address this device (HA `entity_id`, Reolink MAC, ONVIF
|
|
21794
|
-
* WS-Discovery endpoint UUID, …). Provider code keeps a
|
|
21795
|
-
* `Map<sourceInfo.id, IDevice>` to route inbound push events in O(1)
|
|
21796
|
-
* without round-tripping through `stableId` / `id` mappings.
|
|
21797
|
-
*
|
|
21798
|
-
* 2. **Stability bridge.** `uniqueId` is the *immutable* upstream id when
|
|
21799
|
-
* one exists (HA `entity.unique_id`, Reolink MAC again — same as `id`
|
|
21800
|
-
* for vendors where MAC is the natural key). For systems where the
|
|
21801
|
-
* live dispatch key can be renamed (HA `entity_id` can be edited),
|
|
21802
|
-
* providers detect renames by matching `uniqueId` and patch `id`
|
|
21803
|
-
* in-place so dispatch keeps working.
|
|
21804
|
-
*
|
|
21805
|
-
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
21806
|
-
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
21807
|
-
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
21808
|
-
* neither is repeated on each sample. The `device_class` tag is an
|
|
21809
|
-
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
21810
|
-
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
21811
|
-
*
|
|
21812
|
-
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
21813
|
-
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
21814
|
-
* details, …). Providers control what lands here.
|
|
21815
|
-
*/
|
|
21816
|
-
var SourceInfoSchema = object({
|
|
21817
|
-
/** Live dispatch key — mutable when the source system allows rename. */
|
|
21818
|
-
id: string(),
|
|
21819
|
-
/** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
|
|
21820
|
-
system: string(),
|
|
21821
|
-
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
21822
|
-
* Used to detect rename when `id` changes. */
|
|
21823
|
-
uniqueId: string().optional(),
|
|
21824
|
-
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
21825
|
-
quantity: ReadingQuantitySchema.optional(),
|
|
21826
|
-
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
21827
|
-
dateTimeShape: _enum([
|
|
21828
|
-
"date",
|
|
21829
|
-
"time",
|
|
21830
|
-
"datetime"
|
|
21831
|
-
]).optional(),
|
|
21832
|
-
/** Provider-specific extras that don't fit the structured slots.
|
|
21833
|
-
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
21834
|
-
* attribute blobs (would explode the meta JSON column). */
|
|
21835
|
-
raw: record(string(), unknown()).optional()
|
|
21836
|
-
});
|
|
21837
|
-
/**
|
|
21838
22279
|
* device-discovery — device-scoped capability for parents that host /
|
|
21839
22280
|
* enumerate child devices (Reolink Hub / NVR, ONVIF gateway, future
|
|
21840
22281
|
* integrations). The parent advertises a list of discoverable children,
|
|
@@ -57841,13 +58282,19 @@ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
|
57841
58282
|
}), method(ActionIdInput, _void(), {
|
|
57842
58283
|
kind: "mutation",
|
|
57843
58284
|
auth: "admin"
|
|
57844
|
-
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({
|
|
58285
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({
|
|
58286
|
+
action: ActionEntrySchema,
|
|
58287
|
+
warnings: array(UnitWarningSchema).optional()
|
|
58288
|
+
}), {
|
|
57845
58289
|
kind: "mutation",
|
|
57846
58290
|
auth: "admin"
|
|
57847
58291
|
}), method(object({
|
|
57848
58292
|
actionId: string().min(1),
|
|
57849
58293
|
action: ActionInputSchema.partial()
|
|
57850
|
-
}), object({
|
|
58294
|
+
}), object({
|
|
58295
|
+
action: ActionEntrySchema,
|
|
58296
|
+
warnings: array(UnitWarningSchema).optional()
|
|
58297
|
+
}), {
|
|
57851
58298
|
kind: "mutation",
|
|
57852
58299
|
auth: "admin"
|
|
57853
58300
|
}), method(ActionIdInput, _void(), {
|
|
@@ -58153,6 +58600,30 @@ object({
|
|
|
58153
58600
|
at: number()
|
|
58154
58601
|
}).nullable()
|
|
58155
58602
|
});
|
|
58603
|
+
var RemoteButtonShapeSchema = _enum([
|
|
58604
|
+
"rect",
|
|
58605
|
+
"rounded",
|
|
58606
|
+
"round",
|
|
58607
|
+
"pill"
|
|
58608
|
+
]);
|
|
58609
|
+
var RemoteButtonToneSchema = _enum([
|
|
58610
|
+
"neutral",
|
|
58611
|
+
"accent",
|
|
58612
|
+
"danger",
|
|
58613
|
+
"red",
|
|
58614
|
+
"green",
|
|
58615
|
+
"yellow",
|
|
58616
|
+
"blue"
|
|
58617
|
+
]);
|
|
58618
|
+
var RemoteGroupFrameSchema = _enum([
|
|
58619
|
+
"none",
|
|
58620
|
+
"panel",
|
|
58621
|
+
"divider",
|
|
58622
|
+
"dpad",
|
|
58623
|
+
"rocker-v",
|
|
58624
|
+
"rocker-h",
|
|
58625
|
+
"keypad"
|
|
58626
|
+
]);
|
|
58156
58627
|
var RemoteLayoutButtonSchema = object({
|
|
58157
58628
|
id: string().min(1).max(40),
|
|
58158
58629
|
/** 0-based grid position. */
|
|
@@ -58162,12 +58633,94 @@ var RemoteLayoutButtonSchema = object({
|
|
|
58162
58633
|
colSpan: number().int().min(1).max(24),
|
|
58163
58634
|
icon: string().min(1).max(60).optional(),
|
|
58164
58635
|
label: string().min(1).max(40).optional(),
|
|
58165
|
-
role: RemoteRoleSchema
|
|
58636
|
+
role: RemoteRoleSchema,
|
|
58637
|
+
/** Absent = the plain rendering every layout had before shapes existed. */
|
|
58638
|
+
shape: RemoteButtonShapeSchema.optional(),
|
|
58639
|
+
tone: RemoteButtonToneSchema.optional(),
|
|
58640
|
+
/** The group this button belongs to; it must lie inside that group's rectangle. */
|
|
58641
|
+
groupId: string().min(1).max(40).optional()
|
|
58642
|
+
});
|
|
58643
|
+
/**
|
|
58644
|
+
* A rectangle of the grid that moves as ONE thing and is drawn with a frame: a
|
|
58645
|
+
* titled panel, a section divider, a D-pad ring. `componentId` names the palette
|
|
58646
|
+
* entry it came from (informational: the layout is self-contained).
|
|
58647
|
+
*/
|
|
58648
|
+
var RemoteLayoutGroupSchema = object({
|
|
58649
|
+
id: string().min(1).max(40),
|
|
58650
|
+
componentId: string().min(1).max(80),
|
|
58651
|
+
frame: RemoteGroupFrameSchema,
|
|
58652
|
+
row: number().int().min(0).max(24),
|
|
58653
|
+
col: number().int().min(0).max(24),
|
|
58654
|
+
rowSpan: number().int().min(1).max(24),
|
|
58655
|
+
colSpan: number().int().min(1).max(24),
|
|
58656
|
+
title: string().min(1).max(40).optional()
|
|
58166
58657
|
});
|
|
58658
|
+
function rectsOverlap(a, b) {
|
|
58659
|
+
return a.row < b.row + b.rowSpan && b.row < a.row + a.rowSpan && a.col < b.col + b.colSpan && b.col < a.col + a.colSpan;
|
|
58660
|
+
}
|
|
58661
|
+
function rectContains(outer, inner) {
|
|
58662
|
+
return inner.row >= outer.row && inner.col >= outer.col && inner.row + inner.rowSpan <= outer.row + outer.rowSpan && inner.col + inner.colSpan <= outer.col + outer.colSpan;
|
|
58663
|
+
}
|
|
58664
|
+
/**
|
|
58665
|
+
* The group rules of a layout: inside the grid, no two groups overlap, a
|
|
58666
|
+
* member lies inside its group, a divider holds nothing, and a button that is
|
|
58667
|
+
* not a member never sits inside someone else's rectangle (a group moves as
|
|
58668
|
+
* one thing, so a stray key under it would be left behind).
|
|
58669
|
+
*/
|
|
58670
|
+
function refineGroups(grid, ctx) {
|
|
58671
|
+
const groups = grid.groups ?? [];
|
|
58672
|
+
const byId = /* @__PURE__ */ new Map();
|
|
58673
|
+
const fail = (message, path) => {
|
|
58674
|
+
ctx.addIssue({
|
|
58675
|
+
code: "custom",
|
|
58676
|
+
message,
|
|
58677
|
+
path
|
|
58678
|
+
});
|
|
58679
|
+
};
|
|
58680
|
+
groups.forEach((group, index) => {
|
|
58681
|
+
if (byId.has(group.id)) fail(`group id "${group.id}" is used twice`, [
|
|
58682
|
+
"groups",
|
|
58683
|
+
index,
|
|
58684
|
+
"id"
|
|
58685
|
+
]);
|
|
58686
|
+
byId.set(group.id, group);
|
|
58687
|
+
if (group.row + group.rowSpan > grid.rows || group.col + group.colSpan > grid.columns) fail(`group "${group.id}" leaves the grid`, ["groups", index]);
|
|
58688
|
+
for (let other = 0; other < index; other += 1) {
|
|
58689
|
+
const earlier = groups[other];
|
|
58690
|
+
if (earlier !== void 0 && rectsOverlap(earlier, group)) {
|
|
58691
|
+
fail(`groups "${earlier.id}" and "${group.id}" overlap`, ["groups", index]);
|
|
58692
|
+
return;
|
|
58693
|
+
}
|
|
58694
|
+
}
|
|
58695
|
+
});
|
|
58696
|
+
grid.buttons.forEach((button, index) => {
|
|
58697
|
+
if (button.groupId !== void 0) {
|
|
58698
|
+
const group = byId.get(button.groupId);
|
|
58699
|
+
if (group === void 0) {
|
|
58700
|
+
fail(`button "${button.id}" names the unknown group "${button.groupId}"`, [
|
|
58701
|
+
"buttons",
|
|
58702
|
+
index,
|
|
58703
|
+
"groupId"
|
|
58704
|
+
]);
|
|
58705
|
+
return;
|
|
58706
|
+
}
|
|
58707
|
+
if (group.frame === "divider") fail(`a divider group ("${group.id}") holds no buttons`, [
|
|
58708
|
+
"buttons",
|
|
58709
|
+
index,
|
|
58710
|
+
"groupId"
|
|
58711
|
+
]);
|
|
58712
|
+
if (!rectContains(group, button)) fail(`button "${button.id}" lies outside its group "${group.id}"`, ["buttons", index]);
|
|
58713
|
+
return;
|
|
58714
|
+
}
|
|
58715
|
+
const foreign = groups.find((group) => rectsOverlap(group, button));
|
|
58716
|
+
if (foreign !== void 0) fail(`button "${button.id}" lies inside group "${foreign.id}" but is not a member`, ["buttons", index]);
|
|
58717
|
+
});
|
|
58718
|
+
}
|
|
58167
58719
|
object({
|
|
58168
58720
|
columns: number().int().min(1).max(24),
|
|
58169
58721
|
rows: number().int().min(1).max(24),
|
|
58170
|
-
buttons: array(RemoteLayoutButtonSchema).max(200)
|
|
58722
|
+
buttons: array(RemoteLayoutButtonSchema).max(200),
|
|
58723
|
+
groups: array(RemoteLayoutGroupSchema).max(50).optional()
|
|
58171
58724
|
}).superRefine((grid, ctx) => {
|
|
58172
58725
|
const ids = /* @__PURE__ */ new Set();
|
|
58173
58726
|
const taken = /* @__PURE__ */ new Map();
|
|
@@ -58204,6 +58757,7 @@ object({
|
|
|
58204
58757
|
taken.set(cell, button.id);
|
|
58205
58758
|
}
|
|
58206
58759
|
});
|
|
58760
|
+
refineGroups(grid, ctx);
|
|
58207
58761
|
});
|
|
58208
58762
|
var RemoteBoundCommandSchema = object({
|
|
58209
58763
|
role: RemoteRoleSchema,
|
|
@@ -58335,6 +58889,91 @@ method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSche
|
|
|
58335
58889
|
kind: "mutation",
|
|
58336
58890
|
auth: "admin"
|
|
58337
58891
|
});
|
|
58892
|
+
var RemoteComponentCategorySchema = _enum([
|
|
58893
|
+
"power",
|
|
58894
|
+
"navigation",
|
|
58895
|
+
"volume",
|
|
58896
|
+
"numbers",
|
|
58897
|
+
"media",
|
|
58898
|
+
"colour",
|
|
58899
|
+
"apps",
|
|
58900
|
+
"layout"
|
|
58901
|
+
]);
|
|
58902
|
+
/** `<namespace>:<name>`, both lowercase slugs — `core:dpad`, `<addonId>:<name>`. */
|
|
58903
|
+
var COMPONENT_ID_RE = /^[a-z0-9][a-z0-9_.-]*:[a-z0-9][a-z0-9_-]*$/;
|
|
58904
|
+
var RemoteComponentButtonSchema = object({
|
|
58905
|
+
/** Joined to the instance id when the component is inserted. */
|
|
58906
|
+
idSuffix: string().regex(/^[a-z0-9][a-z0-9_-]{0,19}$/, { message: "a short lowercase slug" }),
|
|
58907
|
+
row: number().int().min(0).max(24),
|
|
58908
|
+
col: number().int().min(0).max(24),
|
|
58909
|
+
rowSpan: number().int().min(1).max(24),
|
|
58910
|
+
colSpan: number().int().min(1).max(24),
|
|
58911
|
+
role: RemoteRoleSchema,
|
|
58912
|
+
icon: string().min(1).max(60).optional(),
|
|
58913
|
+
label: string().min(1).max(40).optional(),
|
|
58914
|
+
shape: RemoteButtonShapeSchema.optional(),
|
|
58915
|
+
tone: RemoteButtonToneSchema.optional()
|
|
58916
|
+
});
|
|
58917
|
+
var RemoteLayoutComponentSchema = object({
|
|
58918
|
+
id: string().max(80).regex(COMPONENT_ID_RE, { message: "<namespace>:<name>, lowercase" }),
|
|
58919
|
+
name: string().min(1).max(60),
|
|
58920
|
+
nameI18n: object({
|
|
58921
|
+
en: string().min(1).max(60),
|
|
58922
|
+
it: string().min(1).max(60)
|
|
58923
|
+
}).optional(),
|
|
58924
|
+
/** A display icon key, resolved by the UI like a button icon. */
|
|
58925
|
+
icon: string().min(1).max(60),
|
|
58926
|
+
category: RemoteComponentCategorySchema,
|
|
58927
|
+
size: object({
|
|
58928
|
+
rows: number().int().min(1).max(24),
|
|
58929
|
+
cols: number().int().min(1).max(24)
|
|
58930
|
+
}),
|
|
58931
|
+
/** The frame drawn around the whole component, or null for loose buttons. */
|
|
58932
|
+
group: object({
|
|
58933
|
+
frame: RemoteGroupFrameSchema,
|
|
58934
|
+
title: string().min(1).max(40).optional()
|
|
58935
|
+
}).nullable(),
|
|
58936
|
+
buttons: array(RemoteComponentButtonSchema).max(40)
|
|
58937
|
+
}).superRefine((component, ctx) => {
|
|
58938
|
+
const suffixes = /* @__PURE__ */ new Set();
|
|
58939
|
+
component.buttons.forEach((button, index) => {
|
|
58940
|
+
if (suffixes.has(button.idSuffix)) ctx.addIssue({
|
|
58941
|
+
code: "custom",
|
|
58942
|
+
message: `button "${button.idSuffix}" is listed twice`,
|
|
58943
|
+
path: [
|
|
58944
|
+
"buttons",
|
|
58945
|
+
index,
|
|
58946
|
+
"idSuffix"
|
|
58947
|
+
]
|
|
58948
|
+
});
|
|
58949
|
+
suffixes.add(button.idSuffix);
|
|
58950
|
+
if (button.row + button.rowSpan > component.size.rows || button.col + button.colSpan > component.size.cols) {
|
|
58951
|
+
ctx.addIssue({
|
|
58952
|
+
code: "custom",
|
|
58953
|
+
message: `button "${button.idSuffix}" leaves the component`,
|
|
58954
|
+
path: ["buttons", index]
|
|
58955
|
+
});
|
|
58956
|
+
return;
|
|
58957
|
+
}
|
|
58958
|
+
for (let other = 0; other < index; other += 1) {
|
|
58959
|
+
const earlier = component.buttons[other];
|
|
58960
|
+
if (earlier !== void 0 && rectsOverlap(earlier, button)) {
|
|
58961
|
+
ctx.addIssue({
|
|
58962
|
+
code: "custom",
|
|
58963
|
+
message: `buttons "${earlier.idSuffix}" and "${button.idSuffix}" overlap`,
|
|
58964
|
+
path: ["buttons", index]
|
|
58965
|
+
});
|
|
58966
|
+
return;
|
|
58967
|
+
}
|
|
58968
|
+
}
|
|
58969
|
+
});
|
|
58970
|
+
if (component.group?.frame === "divider" && component.buttons.length > 0) ctx.addIssue({
|
|
58971
|
+
code: "custom",
|
|
58972
|
+
message: "a divider component holds no buttons",
|
|
58973
|
+
path: ["buttons"]
|
|
58974
|
+
});
|
|
58975
|
+
});
|
|
58976
|
+
method(object({}), array(RemoteLayoutComponentSchema), { auth: "protected" });
|
|
58338
58977
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
58339
58978
|
kind: "mutation",
|
|
58340
58979
|
auth: "protected"
|
|
@@ -62494,6 +63133,14 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
62494
63133
|
"on_batteries"
|
|
62495
63134
|
]);
|
|
62496
63135
|
var gramsPortion = number().int().min(4).max(200);
|
|
63136
|
+
/** A portion REQUESTED of the feeder is a mass the method takes in GRAMS (the
|
|
63137
|
+
* hardware's own unit). The bounds are grams; a caller entering another unit
|
|
63138
|
+
* converts to grams first (`paramMeta`, D972). The STATUS fields above stay
|
|
63139
|
+
* plain grams — they are not readings in the kilogram base. */
|
|
63140
|
+
var gramsParam = gramsPortion.meta(paramMeta({
|
|
63141
|
+
quantity: "mass",
|
|
63142
|
+
unit: "g"
|
|
63143
|
+
}));
|
|
62497
63144
|
object({
|
|
62498
63145
|
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
62499
63146
|
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
@@ -62568,9 +63215,9 @@ object({
|
|
|
62568
63215
|
});
|
|
62569
63216
|
DeviceType.PetFeeder, method(object({
|
|
62570
63217
|
deviceId: number().int().nonnegative(),
|
|
62571
|
-
grams:
|
|
62572
|
-
hopper1:
|
|
62573
|
-
hopper2:
|
|
63218
|
+
grams: gramsParam.optional(),
|
|
63219
|
+
hopper1: gramsParam.optional(),
|
|
63220
|
+
hopper2: gramsParam.optional()
|
|
62574
63221
|
}), _void(), {
|
|
62575
63222
|
kind: "mutation",
|
|
62576
63223
|
auth: "protected"
|
|
@@ -67364,6 +68011,87 @@ var trainingCapability = {
|
|
|
67364
68011
|
})
|
|
67365
68012
|
}
|
|
67366
68013
|
};
|
|
68014
|
+
var btn = (idSuffix, row, col, init) => ({
|
|
68015
|
+
idSuffix,
|
|
68016
|
+
row,
|
|
68017
|
+
col,
|
|
68018
|
+
rowSpan: 1,
|
|
68019
|
+
colSpan: 1,
|
|
68020
|
+
...init
|
|
68021
|
+
});
|
|
68022
|
+
function rocker(id, name, it, frame, title, buttons, size) {
|
|
68023
|
+
return {
|
|
68024
|
+
id,
|
|
68025
|
+
name,
|
|
68026
|
+
nameI18n: {
|
|
68027
|
+
en: name,
|
|
68028
|
+
it
|
|
68029
|
+
},
|
|
68030
|
+
icon: frame === "rocker-v" ? "chevrons-up-down" : "chevrons-left-right",
|
|
68031
|
+
category: id.includes("channel") || id.includes("volume") ? "volume" : "navigation",
|
|
68032
|
+
size,
|
|
68033
|
+
group: title === null ? { frame } : {
|
|
68034
|
+
frame,
|
|
68035
|
+
title
|
|
68036
|
+
},
|
|
68037
|
+
buttons
|
|
68038
|
+
};
|
|
68039
|
+
}
|
|
68040
|
+
btn("power", 0, 0, {
|
|
68041
|
+
role: "power",
|
|
68042
|
+
shape: "round",
|
|
68043
|
+
tone: "danger"
|
|
68044
|
+
}), btn("up", 0, 1, { role: "up" }), btn("left", 1, 0, { role: "left" }), btn("ok", 1, 1, {
|
|
68045
|
+
role: "ok",
|
|
68046
|
+
shape: "round",
|
|
68047
|
+
tone: "accent"
|
|
68048
|
+
}), btn("right", 1, 2, { role: "right" }), btn("down", 2, 1, { role: "down" }), rocker("core:rocker-volume-v", "Volume rocker", "Bilanciere volume", "rocker-v", "VOL", [btn("up", 0, 0, {
|
|
68049
|
+
role: "volume_up",
|
|
68050
|
+
shape: "pill"
|
|
68051
|
+
}), btn("down", 1, 0, {
|
|
68052
|
+
role: "volume_down",
|
|
68053
|
+
shape: "pill"
|
|
68054
|
+
})], {
|
|
68055
|
+
rows: 2,
|
|
68056
|
+
cols: 1
|
|
68057
|
+
}), rocker("core:rocker-channel-v", "Channel rocker", "Bilanciere canali", "rocker-v", "CH", [btn("up", 0, 0, {
|
|
68058
|
+
role: "channel_up",
|
|
68059
|
+
shape: "pill"
|
|
68060
|
+
}), btn("down", 1, 0, {
|
|
68061
|
+
role: "channel_down",
|
|
68062
|
+
shape: "pill"
|
|
68063
|
+
})], {
|
|
68064
|
+
rows: 2,
|
|
68065
|
+
cols: 1
|
|
68066
|
+
}), rocker("core:rocker-h", "Minus / plus rocker", "Bilanciere meno / più", "rocker-h", null, [btn("minus", 0, 0, {
|
|
68067
|
+
role: "custom:minus",
|
|
68068
|
+
label: "−",
|
|
68069
|
+
shape: "pill"
|
|
68070
|
+
}), btn("plus", 0, 1, {
|
|
68071
|
+
role: "custom:plus",
|
|
68072
|
+
label: "+",
|
|
68073
|
+
shape: "pill"
|
|
68074
|
+
})], {
|
|
68075
|
+
rows: 1,
|
|
68076
|
+
cols: 2
|
|
68077
|
+
}), [...Array.from({ length: 9 }, (_, i) => btn(`d${i + 1}`, Math.floor(i / 3), i % 3, { role: `digit_${i + 1}` })), btn("d0", 3, 1, { role: "digit_0" })], btn("red", 0, 0, {
|
|
68078
|
+
role: "custom:color_red",
|
|
68079
|
+
tone: "red"
|
|
68080
|
+
}), btn("green", 0, 1, {
|
|
68081
|
+
role: "custom:color_green",
|
|
68082
|
+
tone: "green"
|
|
68083
|
+
}), btn("yellow", 0, 2, {
|
|
68084
|
+
role: "custom:color_yellow",
|
|
68085
|
+
tone: "yellow"
|
|
68086
|
+
}), btn("blue", 0, 3, {
|
|
68087
|
+
role: "custom:color_blue",
|
|
68088
|
+
tone: "blue"
|
|
68089
|
+
}), btn("rewind", 0, 0, { role: "rewind" }), btn("play", 0, 1, { role: "play" }), btn("pause", 0, 2, { role: "pause" }), btn("forward", 0, 3, { role: "fast_forward" }), btn("stop", 0, 4, { role: "stop" }), [
|
|
68090
|
+
1,
|
|
68091
|
+
2,
|
|
68092
|
+
3,
|
|
68093
|
+
4
|
|
68094
|
+
].map((n) => btn(`app${n}`, 0, n - 1, { role: `custom:app_slot_${n}` })), btn("back", 0, 0, { role: "back" }), btn("home", 0, 1, { role: "home" }), btn("menu", 0, 2, { role: "menu" });
|
|
67367
68095
|
discriminatedUnion("kind", [object({
|
|
67368
68096
|
kind: literal("raw"),
|
|
67369
68097
|
timings: array(number().int()),
|
|
@@ -75228,6 +75956,13 @@ Object.freeze({
|
|
|
75228
75956
|
access: "create",
|
|
75229
75957
|
role: "admin"
|
|
75230
75958
|
},
|
|
75959
|
+
"remoteLayoutComponents.listComponents": {
|
|
75960
|
+
capName: "remote-layout-components",
|
|
75961
|
+
capScope: "system",
|
|
75962
|
+
addonId: null,
|
|
75963
|
+
access: "view",
|
|
75964
|
+
role: "admin"
|
|
75965
|
+
},
|
|
75231
75966
|
"runningState.getStatus": {
|
|
75232
75967
|
capName: "running-state",
|
|
75233
75968
|
capScope: "device",
|
|
@@ -79271,7 +80006,8 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
79271
80006
|
min: 4,
|
|
79272
80007
|
max: 200,
|
|
79273
80008
|
step: 1,
|
|
79274
|
-
unit: "g"
|
|
80009
|
+
unit: "g",
|
|
80010
|
+
quantity: "mass"
|
|
79275
80011
|
},
|
|
79276
80012
|
optional: true
|
|
79277
80013
|
}]
|
|
@@ -79290,7 +80026,8 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
79290
80026
|
min: 4,
|
|
79291
80027
|
max: 200,
|
|
79292
80028
|
step: 1,
|
|
79293
|
-
unit: "g"
|
|
80029
|
+
unit: "g",
|
|
80030
|
+
quantity: "mass"
|
|
79294
80031
|
},
|
|
79295
80032
|
optional: true
|
|
79296
80033
|
}, {
|
|
@@ -79301,7 +80038,8 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
79301
80038
|
min: 4,
|
|
79302
80039
|
max: 200,
|
|
79303
80040
|
step: 1,
|
|
79304
|
-
unit: "g"
|
|
80041
|
+
unit: "g",
|
|
80042
|
+
quantity: "mass"
|
|
79305
80043
|
},
|
|
79306
80044
|
optional: true
|
|
79307
80045
|
}]
|
|
@@ -81401,6 +82139,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
81401
82139
|
"recording-export": system("recording exports — requested from the timeline, not an automation step"),
|
|
81402
82140
|
records: system(INTERNAL),
|
|
81403
82141
|
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
82142
|
+
"remote-layout-components": system("the palette of the remote template editor — read-only data, never actuated"),
|
|
81404
82143
|
"server-management": system(CLUSTER),
|
|
81405
82144
|
"settings-store": system(INTERNAL),
|
|
81406
82145
|
"smtp-provider": system(INTERNAL),
|