@camstack/addon-model-studio 1.1.322 → 1.1.324
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-DIoKHy61.mjs → MotionZonesSettings-BFSzpDlc.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-SkRUYyni.mjs → PrivacyMaskSettings-bzbS1q77.mjs} +4 -4
- package/dist/{SceneMonitorEditor-CB_GHDb6.mjs → SceneMonitorEditor-5jtlWR_n.mjs} +3 -3
- package/dist/_stub.js +1298 -1264
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-onE-V79z.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DMLYtwXQ.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D8h8qfbd.mjs +26 -0
- package/dist/{hostInit-DvZygcN-.mjs → hostInit-BQhIepOe.mjs} +2 -2
- package/dist/model-studio.addon.js +803 -64
- package/dist/model-studio.addon.mjs +803 -64
- package/dist/{player-overlays-_zERIZfO.mjs → player-overlays-DwnklNvS.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-CFFPG77U.mjs → responsive-DFhiWOST.mjs} +1 -1
- package/dist/{scene-monitor-copy-DEJ23ZZg.mjs → scene-monitor-copy-DVaiZyk_.mjs} +1 -1
- package/dist/{square-Prn9rHwz.mjs → square-CL1GZCDy.mjs} +1 -1
- package/dist/{trash-2-Ddf3KFsK.mjs → trash-2-Bs4Zqar1.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DDvX_rph.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-B3z4_zyV.mjs} +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Dt_IlI_h.mjs +0 -26
|
@@ -5850,7 +5850,7 @@ var ZodIssueCode = {
|
|
|
5850
5850
|
var ZodFirstPartyTypeKind;
|
|
5851
5851
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5852
5852
|
//#endregion
|
|
5853
|
-
//#region ../types/dist/sleep-
|
|
5853
|
+
//#region ../types/dist/sleep-63gM_1JR.mjs
|
|
5854
5854
|
/**
|
|
5855
5855
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5856
5856
|
* window to float samples (D455).
|
|
@@ -9211,6 +9211,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9211
9211
|
"recording-signal",
|
|
9212
9212
|
"records",
|
|
9213
9213
|
"remote",
|
|
9214
|
+
"remote-layout-components",
|
|
9214
9215
|
"running-state",
|
|
9215
9216
|
"scene-monitor",
|
|
9216
9217
|
"script-runner",
|
|
@@ -16068,6 +16069,478 @@ object({
|
|
|
16068
16069
|
path: ["expr"]
|
|
16069
16070
|
});
|
|
16070
16071
|
});
|
|
16072
|
+
/**
|
|
16073
|
+
* Identity envelope for a device's upstream-system metadata.
|
|
16074
|
+
*
|
|
16075
|
+
* Two jobs:
|
|
16076
|
+
*
|
|
16077
|
+
* 1. **Dispatch key.** `id` is the natural identifier the SOURCE system
|
|
16078
|
+
* uses to address this device (HA `entity_id`, Reolink MAC, ONVIF
|
|
16079
|
+
* WS-Discovery endpoint UUID, …). Provider code keeps a
|
|
16080
|
+
* `Map<sourceInfo.id, IDevice>` to route inbound push events in O(1)
|
|
16081
|
+
* without round-tripping through `stableId` / `id` mappings.
|
|
16082
|
+
*
|
|
16083
|
+
* 2. **Stability bridge.** `uniqueId` is the *immutable* upstream id when
|
|
16084
|
+
* one exists (HA `entity.unique_id`, Reolink MAC again — same as `id`
|
|
16085
|
+
* for vendors where MAC is the natural key). For systems where the
|
|
16086
|
+
* live dispatch key can be renamed (HA `entity_id` can be edited),
|
|
16087
|
+
* providers detect renames by matching `uniqueId` and patch `id`
|
|
16088
|
+
* in-place so dispatch keeps working.
|
|
16089
|
+
*
|
|
16090
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
16091
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
16092
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
16093
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
16094
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
16095
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
16096
|
+
*
|
|
16097
|
+
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
16098
|
+
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
16099
|
+
* details, …). Providers control what lands here.
|
|
16100
|
+
*/
|
|
16101
|
+
var SourceInfoSchema = object({
|
|
16102
|
+
/** Live dispatch key — mutable when the source system allows rename. */
|
|
16103
|
+
id: string(),
|
|
16104
|
+
/** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
|
|
16105
|
+
system: string(),
|
|
16106
|
+
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
16107
|
+
* Used to detect rename when `id` changes. */
|
|
16108
|
+
uniqueId: string().optional(),
|
|
16109
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
16110
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
16111
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
16112
|
+
dateTimeShape: _enum([
|
|
16113
|
+
"date",
|
|
16114
|
+
"time",
|
|
16115
|
+
"datetime"
|
|
16116
|
+
]).optional(),
|
|
16117
|
+
/** Provider-specific extras that don't fit the structured slots.
|
|
16118
|
+
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
16119
|
+
* attribute blobs (would explode the meta JSON column). */
|
|
16120
|
+
raw: record(string(), unknown()).optional()
|
|
16121
|
+
});
|
|
16122
|
+
/**
|
|
16123
|
+
* Frozen unit → spec table. `•` in the doc marks each dimension's canonical
|
|
16124
|
+
* unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
|
|
16125
|
+
* `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
|
|
16126
|
+
* decimals). K derives from `°C = K − 273.15`.
|
|
16127
|
+
*/
|
|
16128
|
+
var UNIT_TABLE = {
|
|
16129
|
+
"°C": {
|
|
16130
|
+
dimension: "temperature",
|
|
16131
|
+
factor: 1,
|
|
16132
|
+
offset: 0
|
|
16133
|
+
},
|
|
16134
|
+
"°F": {
|
|
16135
|
+
dimension: "temperature",
|
|
16136
|
+
factor: 5 / 9,
|
|
16137
|
+
offset: -160 / 9
|
|
16138
|
+
},
|
|
16139
|
+
K: {
|
|
16140
|
+
dimension: "temperature",
|
|
16141
|
+
factor: 1,
|
|
16142
|
+
offset: -273.15
|
|
16143
|
+
},
|
|
16144
|
+
hPa: {
|
|
16145
|
+
dimension: "pressure",
|
|
16146
|
+
factor: 1,
|
|
16147
|
+
offset: 0
|
|
16148
|
+
},
|
|
16149
|
+
kPa: {
|
|
16150
|
+
dimension: "pressure",
|
|
16151
|
+
factor: 10,
|
|
16152
|
+
offset: 0
|
|
16153
|
+
},
|
|
16154
|
+
Pa: {
|
|
16155
|
+
dimension: "pressure",
|
|
16156
|
+
factor: .01,
|
|
16157
|
+
offset: 0
|
|
16158
|
+
},
|
|
16159
|
+
mbar: {
|
|
16160
|
+
dimension: "pressure",
|
|
16161
|
+
factor: 1,
|
|
16162
|
+
offset: 0
|
|
16163
|
+
},
|
|
16164
|
+
bar: {
|
|
16165
|
+
dimension: "pressure",
|
|
16166
|
+
factor: 1e3,
|
|
16167
|
+
offset: 0
|
|
16168
|
+
},
|
|
16169
|
+
inHg: {
|
|
16170
|
+
dimension: "pressure",
|
|
16171
|
+
factor: 33.8639,
|
|
16172
|
+
offset: 0
|
|
16173
|
+
},
|
|
16174
|
+
mmHg: {
|
|
16175
|
+
dimension: "pressure",
|
|
16176
|
+
factor: 1.33322,
|
|
16177
|
+
offset: 0
|
|
16178
|
+
},
|
|
16179
|
+
psi: {
|
|
16180
|
+
dimension: "pressure",
|
|
16181
|
+
factor: 68.9476,
|
|
16182
|
+
offset: 0
|
|
16183
|
+
},
|
|
16184
|
+
"m/s": {
|
|
16185
|
+
dimension: "speed",
|
|
16186
|
+
factor: 1,
|
|
16187
|
+
offset: 0
|
|
16188
|
+
},
|
|
16189
|
+
"km/h": {
|
|
16190
|
+
dimension: "speed",
|
|
16191
|
+
factor: 1 / 3.6,
|
|
16192
|
+
offset: 0
|
|
16193
|
+
},
|
|
16194
|
+
mph: {
|
|
16195
|
+
dimension: "speed",
|
|
16196
|
+
factor: .44704,
|
|
16197
|
+
offset: 0
|
|
16198
|
+
},
|
|
16199
|
+
kn: {
|
|
16200
|
+
dimension: "speed",
|
|
16201
|
+
factor: .514444,
|
|
16202
|
+
offset: 0
|
|
16203
|
+
},
|
|
16204
|
+
"mm/h": {
|
|
16205
|
+
dimension: "precipitation-rate",
|
|
16206
|
+
factor: 1,
|
|
16207
|
+
offset: 0
|
|
16208
|
+
},
|
|
16209
|
+
"in/h": {
|
|
16210
|
+
dimension: "precipitation-rate",
|
|
16211
|
+
factor: 25.4,
|
|
16212
|
+
offset: 0
|
|
16213
|
+
},
|
|
16214
|
+
m: {
|
|
16215
|
+
dimension: "length",
|
|
16216
|
+
factor: 1,
|
|
16217
|
+
offset: 0
|
|
16218
|
+
},
|
|
16219
|
+
mm: {
|
|
16220
|
+
dimension: "length",
|
|
16221
|
+
factor: .001,
|
|
16222
|
+
offset: 0
|
|
16223
|
+
},
|
|
16224
|
+
cm: {
|
|
16225
|
+
dimension: "length",
|
|
16226
|
+
factor: .01,
|
|
16227
|
+
offset: 0
|
|
16228
|
+
},
|
|
16229
|
+
km: {
|
|
16230
|
+
dimension: "length",
|
|
16231
|
+
factor: 1e3,
|
|
16232
|
+
offset: 0
|
|
16233
|
+
},
|
|
16234
|
+
in: {
|
|
16235
|
+
dimension: "length",
|
|
16236
|
+
factor: .0254,
|
|
16237
|
+
offset: 0
|
|
16238
|
+
},
|
|
16239
|
+
ft: {
|
|
16240
|
+
dimension: "length",
|
|
16241
|
+
factor: .3048,
|
|
16242
|
+
offset: 0
|
|
16243
|
+
},
|
|
16244
|
+
mi: {
|
|
16245
|
+
dimension: "length",
|
|
16246
|
+
factor: 1609.344,
|
|
16247
|
+
offset: 0
|
|
16248
|
+
},
|
|
16249
|
+
"m²": {
|
|
16250
|
+
dimension: "area",
|
|
16251
|
+
factor: 1,
|
|
16252
|
+
offset: 0
|
|
16253
|
+
},
|
|
16254
|
+
lx: {
|
|
16255
|
+
dimension: "illuminance",
|
|
16256
|
+
factor: 1,
|
|
16257
|
+
offset: 0
|
|
16258
|
+
},
|
|
16259
|
+
"W/m²": {
|
|
16260
|
+
dimension: "irradiance",
|
|
16261
|
+
factor: 1,
|
|
16262
|
+
offset: 0
|
|
16263
|
+
},
|
|
16264
|
+
W: {
|
|
16265
|
+
dimension: "power",
|
|
16266
|
+
factor: 1,
|
|
16267
|
+
offset: 0
|
|
16268
|
+
},
|
|
16269
|
+
kW: {
|
|
16270
|
+
dimension: "power",
|
|
16271
|
+
factor: 1e3,
|
|
16272
|
+
offset: 0
|
|
16273
|
+
},
|
|
16274
|
+
VA: {
|
|
16275
|
+
dimension: "apparent-power",
|
|
16276
|
+
factor: 1,
|
|
16277
|
+
offset: 0
|
|
16278
|
+
},
|
|
16279
|
+
Wh: {
|
|
16280
|
+
dimension: "energy",
|
|
16281
|
+
factor: 1,
|
|
16282
|
+
offset: 0
|
|
16283
|
+
},
|
|
16284
|
+
kWh: {
|
|
16285
|
+
dimension: "energy",
|
|
16286
|
+
factor: 1e3,
|
|
16287
|
+
offset: 0
|
|
16288
|
+
},
|
|
16289
|
+
MWh: {
|
|
16290
|
+
dimension: "energy",
|
|
16291
|
+
factor: 1e6,
|
|
16292
|
+
offset: 0
|
|
16293
|
+
},
|
|
16294
|
+
V: {
|
|
16295
|
+
dimension: "voltage",
|
|
16296
|
+
factor: 1,
|
|
16297
|
+
offset: 0
|
|
16298
|
+
},
|
|
16299
|
+
mV: {
|
|
16300
|
+
dimension: "voltage",
|
|
16301
|
+
factor: .001,
|
|
16302
|
+
offset: 0
|
|
16303
|
+
},
|
|
16304
|
+
A: {
|
|
16305
|
+
dimension: "current",
|
|
16306
|
+
factor: 1,
|
|
16307
|
+
offset: 0
|
|
16308
|
+
},
|
|
16309
|
+
mA: {
|
|
16310
|
+
dimension: "current",
|
|
16311
|
+
factor: .001,
|
|
16312
|
+
offset: 0
|
|
16313
|
+
},
|
|
16314
|
+
ppm: {
|
|
16315
|
+
dimension: "concentration-volume",
|
|
16316
|
+
factor: 1,
|
|
16317
|
+
offset: 0
|
|
16318
|
+
},
|
|
16319
|
+
ppb: {
|
|
16320
|
+
dimension: "concentration-volume",
|
|
16321
|
+
factor: .001,
|
|
16322
|
+
offset: 0
|
|
16323
|
+
},
|
|
16324
|
+
"µg/m³": {
|
|
16325
|
+
dimension: "concentration-mass",
|
|
16326
|
+
factor: 1,
|
|
16327
|
+
offset: 0
|
|
16328
|
+
},
|
|
16329
|
+
"mg/m³": {
|
|
16330
|
+
dimension: "concentration-mass",
|
|
16331
|
+
factor: 1e3,
|
|
16332
|
+
offset: 0
|
|
16333
|
+
},
|
|
16334
|
+
kg: {
|
|
16335
|
+
dimension: "mass",
|
|
16336
|
+
factor: 1,
|
|
16337
|
+
offset: 0
|
|
16338
|
+
},
|
|
16339
|
+
g: {
|
|
16340
|
+
dimension: "mass",
|
|
16341
|
+
factor: .001,
|
|
16342
|
+
offset: 0
|
|
16343
|
+
},
|
|
16344
|
+
lb: {
|
|
16345
|
+
dimension: "mass",
|
|
16346
|
+
factor: .453592,
|
|
16347
|
+
offset: 0
|
|
16348
|
+
},
|
|
16349
|
+
oz: {
|
|
16350
|
+
dimension: "mass",
|
|
16351
|
+
factor: .0283495,
|
|
16352
|
+
offset: 0
|
|
16353
|
+
},
|
|
16354
|
+
"%": {
|
|
16355
|
+
dimension: "percentage",
|
|
16356
|
+
factor: 1,
|
|
16357
|
+
offset: 0
|
|
16358
|
+
},
|
|
16359
|
+
L: {
|
|
16360
|
+
dimension: "volume",
|
|
16361
|
+
factor: 1,
|
|
16362
|
+
offset: 0
|
|
16363
|
+
},
|
|
16364
|
+
mL: {
|
|
16365
|
+
dimension: "volume",
|
|
16366
|
+
factor: .001,
|
|
16367
|
+
offset: 0
|
|
16368
|
+
},
|
|
16369
|
+
gal: {
|
|
16370
|
+
dimension: "volume",
|
|
16371
|
+
factor: 3.785411784,
|
|
16372
|
+
offset: 0
|
|
16373
|
+
},
|
|
16374
|
+
s: {
|
|
16375
|
+
dimension: "duration",
|
|
16376
|
+
factor: 1,
|
|
16377
|
+
offset: 0
|
|
16378
|
+
},
|
|
16379
|
+
ms: {
|
|
16380
|
+
dimension: "duration",
|
|
16381
|
+
factor: .001,
|
|
16382
|
+
offset: 0
|
|
16383
|
+
},
|
|
16384
|
+
min: {
|
|
16385
|
+
dimension: "duration",
|
|
16386
|
+
factor: 60,
|
|
16387
|
+
offset: 0
|
|
16388
|
+
},
|
|
16389
|
+
h: {
|
|
16390
|
+
dimension: "duration",
|
|
16391
|
+
factor: 3600,
|
|
16392
|
+
offset: 0
|
|
16393
|
+
},
|
|
16394
|
+
d: {
|
|
16395
|
+
dimension: "duration",
|
|
16396
|
+
factor: 86400,
|
|
16397
|
+
offset: 0
|
|
16398
|
+
},
|
|
16399
|
+
B: {
|
|
16400
|
+
dimension: "information",
|
|
16401
|
+
factor: 1,
|
|
16402
|
+
offset: 0
|
|
16403
|
+
},
|
|
16404
|
+
KiB: {
|
|
16405
|
+
dimension: "information",
|
|
16406
|
+
factor: 1024,
|
|
16407
|
+
offset: 0
|
|
16408
|
+
},
|
|
16409
|
+
MiB: {
|
|
16410
|
+
dimension: "information",
|
|
16411
|
+
factor: 1024 ** 2,
|
|
16412
|
+
offset: 0
|
|
16413
|
+
},
|
|
16414
|
+
GiB: {
|
|
16415
|
+
dimension: "information",
|
|
16416
|
+
factor: 1024 ** 3,
|
|
16417
|
+
offset: 0
|
|
16418
|
+
},
|
|
16419
|
+
TiB: {
|
|
16420
|
+
dimension: "information",
|
|
16421
|
+
factor: 1024 ** 4,
|
|
16422
|
+
offset: 0
|
|
16423
|
+
},
|
|
16424
|
+
kB: {
|
|
16425
|
+
dimension: "information",
|
|
16426
|
+
factor: 1e3,
|
|
16427
|
+
offset: 0
|
|
16428
|
+
},
|
|
16429
|
+
MB: {
|
|
16430
|
+
dimension: "information",
|
|
16431
|
+
factor: 1e6,
|
|
16432
|
+
offset: 0
|
|
16433
|
+
},
|
|
16434
|
+
GB: {
|
|
16435
|
+
dimension: "information",
|
|
16436
|
+
factor: 1e9,
|
|
16437
|
+
offset: 0
|
|
16438
|
+
},
|
|
16439
|
+
"°": {
|
|
16440
|
+
dimension: "angle",
|
|
16441
|
+
factor: 1,
|
|
16442
|
+
offset: 0
|
|
16443
|
+
},
|
|
16444
|
+
dBFS: {
|
|
16445
|
+
dimension: "sound-level",
|
|
16446
|
+
factor: 1,
|
|
16447
|
+
offset: 0
|
|
16448
|
+
},
|
|
16449
|
+
dBm: {
|
|
16450
|
+
dimension: "signal-level",
|
|
16451
|
+
factor: 1,
|
|
16452
|
+
offset: 0
|
|
16453
|
+
},
|
|
16454
|
+
mired: {
|
|
16455
|
+
dimension: "colour-temperature",
|
|
16456
|
+
factor: 1,
|
|
16457
|
+
offset: 0
|
|
16458
|
+
},
|
|
16459
|
+
kbps: {
|
|
16460
|
+
dimension: "bitrate",
|
|
16461
|
+
factor: 1,
|
|
16462
|
+
offset: 0
|
|
16463
|
+
},
|
|
16464
|
+
Mbps: {
|
|
16465
|
+
dimension: "bitrate",
|
|
16466
|
+
factor: 1e3,
|
|
16467
|
+
offset: 0
|
|
16468
|
+
},
|
|
16469
|
+
fps: {
|
|
16470
|
+
dimension: "rate",
|
|
16471
|
+
factor: 1,
|
|
16472
|
+
offset: 0
|
|
16473
|
+
}
|
|
16474
|
+
};
|
|
16475
|
+
/** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
|
|
16476
|
+
function specFor(unit) {
|
|
16477
|
+
return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
|
|
16478
|
+
}
|
|
16479
|
+
/** Value in `spec`'s unit → its dimension's canonical unit. */
|
|
16480
|
+
function toCanonical(value, spec) {
|
|
16481
|
+
return value * spec.factor + spec.offset;
|
|
16482
|
+
}
|
|
16483
|
+
/** Canonical-unit value → the unit described by `spec`. */
|
|
16484
|
+
function fromCanonical(canonical, spec) {
|
|
16485
|
+
return (canonical - spec.offset) / spec.factor;
|
|
16486
|
+
}
|
|
16487
|
+
/**
|
|
16488
|
+
* Graceful variant for the render path: returns the converted value, or
|
|
16489
|
+
* `undefined` when the conversion is refused (unknown unit / cross-dimension).
|
|
16490
|
+
* Never throws — a render caller falls back to the raw value + source unit.
|
|
16491
|
+
*/
|
|
16492
|
+
function tryConvertUnit(value, from, to) {
|
|
16493
|
+
if (from === to) return value;
|
|
16494
|
+
const fromSpec = specFor(from);
|
|
16495
|
+
if (!fromSpec) return void 0;
|
|
16496
|
+
const toSpec = specFor(to);
|
|
16497
|
+
if (!toSpec) return void 0;
|
|
16498
|
+
if (fromSpec.dimension !== toSpec.dimension) return void 0;
|
|
16499
|
+
return fromCanonical(toCanonical(value, fromSpec), toSpec);
|
|
16500
|
+
}
|
|
16501
|
+
/**
|
|
16502
|
+
* A number a person types for a physical quantity — the input side of the
|
|
16503
|
+
* value + unit contract (D972).
|
|
16504
|
+
*
|
|
16505
|
+
* Readings are stored in the base unit of their quantity (D944); a cap method
|
|
16506
|
+
* param is stored in the unit its input schema DECLARES (`paramMeta`). The
|
|
16507
|
+
* wire pair {@link QuantityValue} says "this number is expressed in this
|
|
16508
|
+
* unit"; {@link convertQuantityInput} brings it to the stored unit and refuses,
|
|
16509
|
+
* with a typed {@link QuantityUnitError}, a unit that cannot be that quantity.
|
|
16510
|
+
*/
|
|
16511
|
+
/** A unit that cannot be applied to the number it was given with. */
|
|
16512
|
+
var QuantityUnitError = class extends Error {
|
|
16513
|
+
code;
|
|
16514
|
+
constructor(code, message) {
|
|
16515
|
+
super(`[${code}] ${message}`);
|
|
16516
|
+
this.name = "QuantityUnitError";
|
|
16517
|
+
this.code = code;
|
|
16518
|
+
}
|
|
16519
|
+
};
|
|
16520
|
+
/** The wire pair: `value` is expressed in `unit`. */
|
|
16521
|
+
var QuantityValueSchema = object({
|
|
16522
|
+
value: number(),
|
|
16523
|
+
unit: string().min(1)
|
|
16524
|
+
});
|
|
16525
|
+
/**
|
|
16526
|
+
* Zod `.meta()` bag for a cap METHOD param that is a physical quantity — the
|
|
16527
|
+
* input-side twin of `readingMeta`. The value is carried in `unit` (a gram
|
|
16528
|
+
* portion stays in grams); the unit must belong to the quantity, checked once
|
|
16529
|
+
* when the cap is declared.
|
|
16530
|
+
*/
|
|
16531
|
+
function paramMeta(declared) {
|
|
16532
|
+
const base = baseUnitOf(declared.quantity);
|
|
16533
|
+
if (base === void 0) throw new QuantityUnitError("unknown-unit", `quantity "${declared.quantity}" has no unit`);
|
|
16534
|
+
if (tryConvertUnit(1, declared.unit, base) === void 0) throw new QuantityUnitError("cross-dimension", `"${declared.unit}" is not a unit of ${declared.quantity}`);
|
|
16535
|
+
return {
|
|
16536
|
+
quantity: declared.quantity,
|
|
16537
|
+
unit: declared.unit
|
|
16538
|
+
};
|
|
16539
|
+
}
|
|
16540
|
+
object({
|
|
16541
|
+
quantity: ReadingQuantitySchema,
|
|
16542
|
+
unit: string().min(1)
|
|
16543
|
+
});
|
|
16071
16544
|
/** How a leaf compares a device field to a value. Derived from the field's
|
|
16072
16545
|
* `kind` in `deviceManager.getWireableFields`, never hand-maintained. */
|
|
16073
16546
|
var AutomationConditionOperatorSchema = _enum([
|
|
@@ -16090,8 +16563,10 @@ var AutomationConditionLeafSchema = object({
|
|
|
16090
16563
|
string(),
|
|
16091
16564
|
number(),
|
|
16092
16565
|
boolean(),
|
|
16093
|
-
array(union([string(), number()]))
|
|
16094
|
-
|
|
16566
|
+
array(union([string(), number()])),
|
|
16567
|
+
QuantityValueSchema
|
|
16568
|
+
]),
|
|
16569
|
+
unit: string().min(1).optional()
|
|
16095
16570
|
});
|
|
16096
16571
|
var AutomationConditionStationaryPresentSchema = object({
|
|
16097
16572
|
kind: literal("stationary-present"),
|
|
@@ -16244,7 +16719,13 @@ var AutomationCapStepSchema = object({
|
|
|
16244
16719
|
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
16245
16720
|
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
16246
16721
|
* the expression leaf. */
|
|
16247
|
-
args: record(string(), unknown()).optional()
|
|
16722
|
+
args: record(string(), unknown()).optional(),
|
|
16723
|
+
/**
|
|
16724
|
+
* The unit the person picked per arg (display only). `args` always hold the
|
|
16725
|
+
* value in the unit the method's input DECLARES (`paramMeta`); on a write an
|
|
16726
|
+
* arg may be a {@link QuantityValue}, which the save boundary converts.
|
|
16727
|
+
*/
|
|
16728
|
+
argUnits: record(string(), string().min(1)).optional()
|
|
16248
16729
|
});
|
|
16249
16730
|
/**
|
|
16250
16731
|
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
@@ -16624,6 +17105,16 @@ object({
|
|
|
16624
17105
|
lastRunAt: number().nullable(),
|
|
16625
17106
|
lastError: string().nullable()
|
|
16626
17107
|
});
|
|
17108
|
+
/** A bare number accepted as a base unit — the save succeeded, say so. */
|
|
17109
|
+
var UnitWarningSchema = object({
|
|
17110
|
+
/** Where in the saved record, e.g. `conditions.children.0` or `steps.2.args.grams`. */
|
|
17111
|
+
path: string(),
|
|
17112
|
+
deviceId: number().int().optional(),
|
|
17113
|
+
field: string(),
|
|
17114
|
+
value: number(),
|
|
17115
|
+
assumedUnit: string(),
|
|
17116
|
+
message: string()
|
|
17117
|
+
});
|
|
16627
17118
|
/**
|
|
16628
17119
|
* notification-output — canonical, capability-gated notification delivery.
|
|
16629
17120
|
*
|
|
@@ -21996,56 +22487,6 @@ var DeviceAdminLinkSchema = object({
|
|
|
21996
22487
|
});
|
|
21997
22488
|
method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema.nullable(), { auth: "admin" });
|
|
21998
22489
|
/**
|
|
21999
|
-
* Identity envelope for a device's upstream-system metadata.
|
|
22000
|
-
*
|
|
22001
|
-
* Two jobs:
|
|
22002
|
-
*
|
|
22003
|
-
* 1. **Dispatch key.** `id` is the natural identifier the SOURCE system
|
|
22004
|
-
* uses to address this device (HA `entity_id`, Reolink MAC, ONVIF
|
|
22005
|
-
* WS-Discovery endpoint UUID, …). Provider code keeps a
|
|
22006
|
-
* `Map<sourceInfo.id, IDevice>` to route inbound push events in O(1)
|
|
22007
|
-
* without round-tripping through `stableId` / `id` mappings.
|
|
22008
|
-
*
|
|
22009
|
-
* 2. **Stability bridge.** `uniqueId` is the *immutable* upstream id when
|
|
22010
|
-
* one exists (HA `entity.unique_id`, Reolink MAC again — same as `id`
|
|
22011
|
-
* for vendors where MAC is the natural key). For systems where the
|
|
22012
|
-
* live dispatch key can be renamed (HA `entity_id` can be edited),
|
|
22013
|
-
* providers detect renames by matching `uniqueId` and patch `id`
|
|
22014
|
-
* in-place so dispatch keeps working.
|
|
22015
|
-
*
|
|
22016
|
-
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
22017
|
-
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
22018
|
-
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
22019
|
-
* neither is repeated on each sample. The `device_class` tag is an
|
|
22020
|
-
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
22021
|
-
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
22022
|
-
*
|
|
22023
|
-
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
22024
|
-
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
22025
|
-
* details, …). Providers control what lands here.
|
|
22026
|
-
*/
|
|
22027
|
-
var SourceInfoSchema = object({
|
|
22028
|
-
/** Live dispatch key — mutable when the source system allows rename. */
|
|
22029
|
-
id: string(),
|
|
22030
|
-
/** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
|
|
22031
|
-
system: string(),
|
|
22032
|
-
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
22033
|
-
* Used to detect rename when `id` changes. */
|
|
22034
|
-
uniqueId: string().optional(),
|
|
22035
|
-
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
22036
|
-
quantity: ReadingQuantitySchema.optional(),
|
|
22037
|
-
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
22038
|
-
dateTimeShape: _enum([
|
|
22039
|
-
"date",
|
|
22040
|
-
"time",
|
|
22041
|
-
"datetime"
|
|
22042
|
-
]).optional(),
|
|
22043
|
-
/** Provider-specific extras that don't fit the structured slots.
|
|
22044
|
-
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
22045
|
-
* attribute blobs (would explode the meta JSON column). */
|
|
22046
|
-
raw: record(string(), unknown()).optional()
|
|
22047
|
-
});
|
|
22048
|
-
/**
|
|
22049
22490
|
* device-discovery — device-scoped capability for parents that host /
|
|
22050
22491
|
* enumerate child devices (Reolink Hub / NVR, ONVIF gateway, future
|
|
22051
22492
|
* integrations). The parent advertises a list of discoverable children,
|
|
@@ -58058,13 +58499,19 @@ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
|
58058
58499
|
}), method(ActionIdInput, _void(), {
|
|
58059
58500
|
kind: "mutation",
|
|
58060
58501
|
auth: "admin"
|
|
58061
|
-
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({
|
|
58502
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({
|
|
58503
|
+
action: ActionEntrySchema,
|
|
58504
|
+
warnings: array(UnitWarningSchema).optional()
|
|
58505
|
+
}), {
|
|
58062
58506
|
kind: "mutation",
|
|
58063
58507
|
auth: "admin"
|
|
58064
58508
|
}), method(object({
|
|
58065
58509
|
actionId: string().min(1),
|
|
58066
58510
|
action: ActionInputSchema.partial()
|
|
58067
|
-
}), object({
|
|
58511
|
+
}), object({
|
|
58512
|
+
action: ActionEntrySchema,
|
|
58513
|
+
warnings: array(UnitWarningSchema).optional()
|
|
58514
|
+
}), {
|
|
58068
58515
|
kind: "mutation",
|
|
58069
58516
|
auth: "admin"
|
|
58070
58517
|
}), method(ActionIdInput, _void(), {
|
|
@@ -58370,6 +58817,30 @@ object({
|
|
|
58370
58817
|
at: number()
|
|
58371
58818
|
}).nullable()
|
|
58372
58819
|
});
|
|
58820
|
+
var RemoteButtonShapeSchema = _enum([
|
|
58821
|
+
"rect",
|
|
58822
|
+
"rounded",
|
|
58823
|
+
"round",
|
|
58824
|
+
"pill"
|
|
58825
|
+
]);
|
|
58826
|
+
var RemoteButtonToneSchema = _enum([
|
|
58827
|
+
"neutral",
|
|
58828
|
+
"accent",
|
|
58829
|
+
"danger",
|
|
58830
|
+
"red",
|
|
58831
|
+
"green",
|
|
58832
|
+
"yellow",
|
|
58833
|
+
"blue"
|
|
58834
|
+
]);
|
|
58835
|
+
var RemoteGroupFrameSchema = _enum([
|
|
58836
|
+
"none",
|
|
58837
|
+
"panel",
|
|
58838
|
+
"divider",
|
|
58839
|
+
"dpad",
|
|
58840
|
+
"rocker-v",
|
|
58841
|
+
"rocker-h",
|
|
58842
|
+
"keypad"
|
|
58843
|
+
]);
|
|
58373
58844
|
var RemoteLayoutButtonSchema = object({
|
|
58374
58845
|
id: string().min(1).max(40),
|
|
58375
58846
|
/** 0-based grid position. */
|
|
@@ -58379,12 +58850,94 @@ var RemoteLayoutButtonSchema = object({
|
|
|
58379
58850
|
colSpan: number().int().min(1).max(24),
|
|
58380
58851
|
icon: string().min(1).max(60).optional(),
|
|
58381
58852
|
label: string().min(1).max(40).optional(),
|
|
58382
|
-
role: RemoteRoleSchema
|
|
58853
|
+
role: RemoteRoleSchema,
|
|
58854
|
+
/** Absent = the plain rendering every layout had before shapes existed. */
|
|
58855
|
+
shape: RemoteButtonShapeSchema.optional(),
|
|
58856
|
+
tone: RemoteButtonToneSchema.optional(),
|
|
58857
|
+
/** The group this button belongs to; it must lie inside that group's rectangle. */
|
|
58858
|
+
groupId: string().min(1).max(40).optional()
|
|
58859
|
+
});
|
|
58860
|
+
/**
|
|
58861
|
+
* A rectangle of the grid that moves as ONE thing and is drawn with a frame: a
|
|
58862
|
+
* titled panel, a section divider, a D-pad ring. `componentId` names the palette
|
|
58863
|
+
* entry it came from (informational: the layout is self-contained).
|
|
58864
|
+
*/
|
|
58865
|
+
var RemoteLayoutGroupSchema = object({
|
|
58866
|
+
id: string().min(1).max(40),
|
|
58867
|
+
componentId: string().min(1).max(80),
|
|
58868
|
+
frame: RemoteGroupFrameSchema,
|
|
58869
|
+
row: number().int().min(0).max(24),
|
|
58870
|
+
col: number().int().min(0).max(24),
|
|
58871
|
+
rowSpan: number().int().min(1).max(24),
|
|
58872
|
+
colSpan: number().int().min(1).max(24),
|
|
58873
|
+
title: string().min(1).max(40).optional()
|
|
58383
58874
|
});
|
|
58875
|
+
function rectsOverlap(a, b) {
|
|
58876
|
+
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;
|
|
58877
|
+
}
|
|
58878
|
+
function rectContains(outer, inner) {
|
|
58879
|
+
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;
|
|
58880
|
+
}
|
|
58881
|
+
/**
|
|
58882
|
+
* The group rules of a layout: inside the grid, no two groups overlap, a
|
|
58883
|
+
* member lies inside its group, a divider holds nothing, and a button that is
|
|
58884
|
+
* not a member never sits inside someone else's rectangle (a group moves as
|
|
58885
|
+
* one thing, so a stray key under it would be left behind).
|
|
58886
|
+
*/
|
|
58887
|
+
function refineGroups(grid, ctx) {
|
|
58888
|
+
const groups = grid.groups ?? [];
|
|
58889
|
+
const byId = /* @__PURE__ */ new Map();
|
|
58890
|
+
const fail = (message, path) => {
|
|
58891
|
+
ctx.addIssue({
|
|
58892
|
+
code: "custom",
|
|
58893
|
+
message,
|
|
58894
|
+
path
|
|
58895
|
+
});
|
|
58896
|
+
};
|
|
58897
|
+
groups.forEach((group, index) => {
|
|
58898
|
+
if (byId.has(group.id)) fail(`group id "${group.id}" is used twice`, [
|
|
58899
|
+
"groups",
|
|
58900
|
+
index,
|
|
58901
|
+
"id"
|
|
58902
|
+
]);
|
|
58903
|
+
byId.set(group.id, group);
|
|
58904
|
+
if (group.row + group.rowSpan > grid.rows || group.col + group.colSpan > grid.columns) fail(`group "${group.id}" leaves the grid`, ["groups", index]);
|
|
58905
|
+
for (let other = 0; other < index; other += 1) {
|
|
58906
|
+
const earlier = groups[other];
|
|
58907
|
+
if (earlier !== void 0 && rectsOverlap(earlier, group)) {
|
|
58908
|
+
fail(`groups "${earlier.id}" and "${group.id}" overlap`, ["groups", index]);
|
|
58909
|
+
return;
|
|
58910
|
+
}
|
|
58911
|
+
}
|
|
58912
|
+
});
|
|
58913
|
+
grid.buttons.forEach((button, index) => {
|
|
58914
|
+
if (button.groupId !== void 0) {
|
|
58915
|
+
const group = byId.get(button.groupId);
|
|
58916
|
+
if (group === void 0) {
|
|
58917
|
+
fail(`button "${button.id}" names the unknown group "${button.groupId}"`, [
|
|
58918
|
+
"buttons",
|
|
58919
|
+
index,
|
|
58920
|
+
"groupId"
|
|
58921
|
+
]);
|
|
58922
|
+
return;
|
|
58923
|
+
}
|
|
58924
|
+
if (group.frame === "divider") fail(`a divider group ("${group.id}") holds no buttons`, [
|
|
58925
|
+
"buttons",
|
|
58926
|
+
index,
|
|
58927
|
+
"groupId"
|
|
58928
|
+
]);
|
|
58929
|
+
if (!rectContains(group, button)) fail(`button "${button.id}" lies outside its group "${group.id}"`, ["buttons", index]);
|
|
58930
|
+
return;
|
|
58931
|
+
}
|
|
58932
|
+
const foreign = groups.find((group) => rectsOverlap(group, button));
|
|
58933
|
+
if (foreign !== void 0) fail(`button "${button.id}" lies inside group "${foreign.id}" but is not a member`, ["buttons", index]);
|
|
58934
|
+
});
|
|
58935
|
+
}
|
|
58384
58936
|
object({
|
|
58385
58937
|
columns: number().int().min(1).max(24),
|
|
58386
58938
|
rows: number().int().min(1).max(24),
|
|
58387
|
-
buttons: array(RemoteLayoutButtonSchema).max(200)
|
|
58939
|
+
buttons: array(RemoteLayoutButtonSchema).max(200),
|
|
58940
|
+
groups: array(RemoteLayoutGroupSchema).max(50).optional()
|
|
58388
58941
|
}).superRefine((grid, ctx) => {
|
|
58389
58942
|
const ids = /* @__PURE__ */ new Set();
|
|
58390
58943
|
const taken = /* @__PURE__ */ new Map();
|
|
@@ -58421,6 +58974,7 @@ object({
|
|
|
58421
58974
|
taken.set(cell, button.id);
|
|
58422
58975
|
}
|
|
58423
58976
|
});
|
|
58977
|
+
refineGroups(grid, ctx);
|
|
58424
58978
|
});
|
|
58425
58979
|
var RemoteBoundCommandSchema = object({
|
|
58426
58980
|
role: RemoteRoleSchema,
|
|
@@ -58552,6 +59106,91 @@ method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSche
|
|
|
58552
59106
|
kind: "mutation",
|
|
58553
59107
|
auth: "admin"
|
|
58554
59108
|
});
|
|
59109
|
+
var RemoteComponentCategorySchema = _enum([
|
|
59110
|
+
"power",
|
|
59111
|
+
"navigation",
|
|
59112
|
+
"volume",
|
|
59113
|
+
"numbers",
|
|
59114
|
+
"media",
|
|
59115
|
+
"colour",
|
|
59116
|
+
"apps",
|
|
59117
|
+
"layout"
|
|
59118
|
+
]);
|
|
59119
|
+
/** `<namespace>:<name>`, both lowercase slugs — `core:dpad`, `<addonId>:<name>`. */
|
|
59120
|
+
var COMPONENT_ID_RE = /^[a-z0-9][a-z0-9_.-]*:[a-z0-9][a-z0-9_-]*$/;
|
|
59121
|
+
var RemoteComponentButtonSchema = object({
|
|
59122
|
+
/** Joined to the instance id when the component is inserted. */
|
|
59123
|
+
idSuffix: string().regex(/^[a-z0-9][a-z0-9_-]{0,19}$/, { message: "a short lowercase slug" }),
|
|
59124
|
+
row: number().int().min(0).max(24),
|
|
59125
|
+
col: number().int().min(0).max(24),
|
|
59126
|
+
rowSpan: number().int().min(1).max(24),
|
|
59127
|
+
colSpan: number().int().min(1).max(24),
|
|
59128
|
+
role: RemoteRoleSchema,
|
|
59129
|
+
icon: string().min(1).max(60).optional(),
|
|
59130
|
+
label: string().min(1).max(40).optional(),
|
|
59131
|
+
shape: RemoteButtonShapeSchema.optional(),
|
|
59132
|
+
tone: RemoteButtonToneSchema.optional()
|
|
59133
|
+
});
|
|
59134
|
+
var RemoteLayoutComponentSchema = object({
|
|
59135
|
+
id: string().max(80).regex(COMPONENT_ID_RE, { message: "<namespace>:<name>, lowercase" }),
|
|
59136
|
+
name: string().min(1).max(60),
|
|
59137
|
+
nameI18n: object({
|
|
59138
|
+
en: string().min(1).max(60),
|
|
59139
|
+
it: string().min(1).max(60)
|
|
59140
|
+
}).optional(),
|
|
59141
|
+
/** A display icon key, resolved by the UI like a button icon. */
|
|
59142
|
+
icon: string().min(1).max(60),
|
|
59143
|
+
category: RemoteComponentCategorySchema,
|
|
59144
|
+
size: object({
|
|
59145
|
+
rows: number().int().min(1).max(24),
|
|
59146
|
+
cols: number().int().min(1).max(24)
|
|
59147
|
+
}),
|
|
59148
|
+
/** The frame drawn around the whole component, or null for loose buttons. */
|
|
59149
|
+
group: object({
|
|
59150
|
+
frame: RemoteGroupFrameSchema,
|
|
59151
|
+
title: string().min(1).max(40).optional()
|
|
59152
|
+
}).nullable(),
|
|
59153
|
+
buttons: array(RemoteComponentButtonSchema).max(40)
|
|
59154
|
+
}).superRefine((component, ctx) => {
|
|
59155
|
+
const suffixes = /* @__PURE__ */ new Set();
|
|
59156
|
+
component.buttons.forEach((button, index) => {
|
|
59157
|
+
if (suffixes.has(button.idSuffix)) ctx.addIssue({
|
|
59158
|
+
code: "custom",
|
|
59159
|
+
message: `button "${button.idSuffix}" is listed twice`,
|
|
59160
|
+
path: [
|
|
59161
|
+
"buttons",
|
|
59162
|
+
index,
|
|
59163
|
+
"idSuffix"
|
|
59164
|
+
]
|
|
59165
|
+
});
|
|
59166
|
+
suffixes.add(button.idSuffix);
|
|
59167
|
+
if (button.row + button.rowSpan > component.size.rows || button.col + button.colSpan > component.size.cols) {
|
|
59168
|
+
ctx.addIssue({
|
|
59169
|
+
code: "custom",
|
|
59170
|
+
message: `button "${button.idSuffix}" leaves the component`,
|
|
59171
|
+
path: ["buttons", index]
|
|
59172
|
+
});
|
|
59173
|
+
return;
|
|
59174
|
+
}
|
|
59175
|
+
for (let other = 0; other < index; other += 1) {
|
|
59176
|
+
const earlier = component.buttons[other];
|
|
59177
|
+
if (earlier !== void 0 && rectsOverlap(earlier, button)) {
|
|
59178
|
+
ctx.addIssue({
|
|
59179
|
+
code: "custom",
|
|
59180
|
+
message: `buttons "${earlier.idSuffix}" and "${button.idSuffix}" overlap`,
|
|
59181
|
+
path: ["buttons", index]
|
|
59182
|
+
});
|
|
59183
|
+
return;
|
|
59184
|
+
}
|
|
59185
|
+
}
|
|
59186
|
+
});
|
|
59187
|
+
if (component.group?.frame === "divider" && component.buttons.length > 0) ctx.addIssue({
|
|
59188
|
+
code: "custom",
|
|
59189
|
+
message: "a divider component holds no buttons",
|
|
59190
|
+
path: ["buttons"]
|
|
59191
|
+
});
|
|
59192
|
+
});
|
|
59193
|
+
method(object({}), array(RemoteLayoutComponentSchema), { auth: "protected" });
|
|
58555
59194
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
58556
59195
|
kind: "mutation",
|
|
58557
59196
|
auth: "protected"
|
|
@@ -62711,6 +63350,14 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
62711
63350
|
"on_batteries"
|
|
62712
63351
|
]);
|
|
62713
63352
|
var gramsPortion = number().int().min(4).max(200);
|
|
63353
|
+
/** A portion REQUESTED of the feeder is a mass the method takes in GRAMS (the
|
|
63354
|
+
* hardware's own unit). The bounds are grams; a caller entering another unit
|
|
63355
|
+
* converts to grams first (`paramMeta`, D972). The STATUS fields above stay
|
|
63356
|
+
* plain grams — they are not readings in the kilogram base. */
|
|
63357
|
+
var gramsParam = gramsPortion.meta(paramMeta({
|
|
63358
|
+
quantity: "mass",
|
|
63359
|
+
unit: "g"
|
|
63360
|
+
}));
|
|
62714
63361
|
object({
|
|
62715
63362
|
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
62716
63363
|
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
@@ -62785,9 +63432,9 @@ object({
|
|
|
62785
63432
|
});
|
|
62786
63433
|
DeviceType.PetFeeder, method(object({
|
|
62787
63434
|
deviceId: number().int().nonnegative(),
|
|
62788
|
-
grams:
|
|
62789
|
-
hopper1:
|
|
62790
|
-
hopper2:
|
|
63435
|
+
grams: gramsParam.optional(),
|
|
63436
|
+
hopper1: gramsParam.optional(),
|
|
63437
|
+
hopper2: gramsParam.optional()
|
|
62791
63438
|
}), _void(), {
|
|
62792
63439
|
kind: "mutation",
|
|
62793
63440
|
auth: "protected"
|
|
@@ -67479,6 +68126,87 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
67479
68126
|
kind: "mutation",
|
|
67480
68127
|
auth: "admin"
|
|
67481
68128
|
});
|
|
68129
|
+
var btn = (idSuffix, row, col, init) => ({
|
|
68130
|
+
idSuffix,
|
|
68131
|
+
row,
|
|
68132
|
+
col,
|
|
68133
|
+
rowSpan: 1,
|
|
68134
|
+
colSpan: 1,
|
|
68135
|
+
...init
|
|
68136
|
+
});
|
|
68137
|
+
function rocker(id, name, it, frame, title, buttons, size) {
|
|
68138
|
+
return {
|
|
68139
|
+
id,
|
|
68140
|
+
name,
|
|
68141
|
+
nameI18n: {
|
|
68142
|
+
en: name,
|
|
68143
|
+
it
|
|
68144
|
+
},
|
|
68145
|
+
icon: frame === "rocker-v" ? "chevrons-up-down" : "chevrons-left-right",
|
|
68146
|
+
category: id.includes("channel") || id.includes("volume") ? "volume" : "navigation",
|
|
68147
|
+
size,
|
|
68148
|
+
group: title === null ? { frame } : {
|
|
68149
|
+
frame,
|
|
68150
|
+
title
|
|
68151
|
+
},
|
|
68152
|
+
buttons
|
|
68153
|
+
};
|
|
68154
|
+
}
|
|
68155
|
+
btn("power", 0, 0, {
|
|
68156
|
+
role: "power",
|
|
68157
|
+
shape: "round",
|
|
68158
|
+
tone: "danger"
|
|
68159
|
+
}), btn("up", 0, 1, { role: "up" }), btn("left", 1, 0, { role: "left" }), btn("ok", 1, 1, {
|
|
68160
|
+
role: "ok",
|
|
68161
|
+
shape: "round",
|
|
68162
|
+
tone: "accent"
|
|
68163
|
+
}), 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, {
|
|
68164
|
+
role: "volume_up",
|
|
68165
|
+
shape: "pill"
|
|
68166
|
+
}), btn("down", 1, 0, {
|
|
68167
|
+
role: "volume_down",
|
|
68168
|
+
shape: "pill"
|
|
68169
|
+
})], {
|
|
68170
|
+
rows: 2,
|
|
68171
|
+
cols: 1
|
|
68172
|
+
}), rocker("core:rocker-channel-v", "Channel rocker", "Bilanciere canali", "rocker-v", "CH", [btn("up", 0, 0, {
|
|
68173
|
+
role: "channel_up",
|
|
68174
|
+
shape: "pill"
|
|
68175
|
+
}), btn("down", 1, 0, {
|
|
68176
|
+
role: "channel_down",
|
|
68177
|
+
shape: "pill"
|
|
68178
|
+
})], {
|
|
68179
|
+
rows: 2,
|
|
68180
|
+
cols: 1
|
|
68181
|
+
}), rocker("core:rocker-h", "Minus / plus rocker", "Bilanciere meno / più", "rocker-h", null, [btn("minus", 0, 0, {
|
|
68182
|
+
role: "custom:minus",
|
|
68183
|
+
label: "−",
|
|
68184
|
+
shape: "pill"
|
|
68185
|
+
}), btn("plus", 0, 1, {
|
|
68186
|
+
role: "custom:plus",
|
|
68187
|
+
label: "+",
|
|
68188
|
+
shape: "pill"
|
|
68189
|
+
})], {
|
|
68190
|
+
rows: 1,
|
|
68191
|
+
cols: 2
|
|
68192
|
+
}), [...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, {
|
|
68193
|
+
role: "custom:color_red",
|
|
68194
|
+
tone: "red"
|
|
68195
|
+
}), btn("green", 0, 1, {
|
|
68196
|
+
role: "custom:color_green",
|
|
68197
|
+
tone: "green"
|
|
68198
|
+
}), btn("yellow", 0, 2, {
|
|
68199
|
+
role: "custom:color_yellow",
|
|
68200
|
+
tone: "yellow"
|
|
68201
|
+
}), btn("blue", 0, 3, {
|
|
68202
|
+
role: "custom:color_blue",
|
|
68203
|
+
tone: "blue"
|
|
68204
|
+
}), 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" }), [
|
|
68205
|
+
1,
|
|
68206
|
+
2,
|
|
68207
|
+
3,
|
|
68208
|
+
4
|
|
68209
|
+
].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" });
|
|
67482
68210
|
discriminatedUnion("kind", [object({
|
|
67483
68211
|
kind: literal("raw"),
|
|
67484
68212
|
timings: array(number().int()),
|
|
@@ -75441,6 +76169,13 @@ Object.freeze({
|
|
|
75441
76169
|
access: "create",
|
|
75442
76170
|
role: "admin"
|
|
75443
76171
|
},
|
|
76172
|
+
"remoteLayoutComponents.listComponents": {
|
|
76173
|
+
capName: "remote-layout-components",
|
|
76174
|
+
capScope: "system",
|
|
76175
|
+
addonId: null,
|
|
76176
|
+
access: "view",
|
|
76177
|
+
role: "admin"
|
|
76178
|
+
},
|
|
75444
76179
|
"runningState.getStatus": {
|
|
75445
76180
|
capName: "running-state",
|
|
75446
76181
|
capScope: "device",
|
|
@@ -79484,7 +80219,8 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
79484
80219
|
min: 4,
|
|
79485
80220
|
max: 200,
|
|
79486
80221
|
step: 1,
|
|
79487
|
-
unit: "g"
|
|
80222
|
+
unit: "g",
|
|
80223
|
+
quantity: "mass"
|
|
79488
80224
|
},
|
|
79489
80225
|
optional: true
|
|
79490
80226
|
}]
|
|
@@ -79503,7 +80239,8 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
79503
80239
|
min: 4,
|
|
79504
80240
|
max: 200,
|
|
79505
80241
|
step: 1,
|
|
79506
|
-
unit: "g"
|
|
80242
|
+
unit: "g",
|
|
80243
|
+
quantity: "mass"
|
|
79507
80244
|
},
|
|
79508
80245
|
optional: true
|
|
79509
80246
|
}, {
|
|
@@ -79514,7 +80251,8 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
79514
80251
|
min: 4,
|
|
79515
80252
|
max: 200,
|
|
79516
80253
|
step: 1,
|
|
79517
|
-
unit: "g"
|
|
80254
|
+
unit: "g",
|
|
80255
|
+
quantity: "mass"
|
|
79518
80256
|
},
|
|
79519
80257
|
optional: true
|
|
79520
80258
|
}]
|
|
@@ -81614,6 +82352,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
81614
82352
|
"recording-export": system("recording exports — requested from the timeline, not an automation step"),
|
|
81615
82353
|
records: system(INTERNAL),
|
|
81616
82354
|
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
82355
|
+
"remote-layout-components": system("the palette of the remote template editor — read-only data, never actuated"),
|
|
81617
82356
|
"server-management": system(CLUSTER),
|
|
81618
82357
|
"settings-store": system(INTERNAL),
|
|
81619
82358
|
"smtp-provider": system(INTERNAL),
|