@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
|
@@ -5588,7 +5588,7 @@ var ZodIssueCode = {
|
|
|
5588
5588
|
var ZodFirstPartyTypeKind;
|
|
5589
5589
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5590
5590
|
//#endregion
|
|
5591
|
-
//#region ../types/dist/sleep-
|
|
5591
|
+
//#region ../types/dist/sleep-63gM_1JR.mjs
|
|
5592
5592
|
/**
|
|
5593
5593
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5594
5594
|
* window to float samples (D455).
|
|
@@ -9116,6 +9116,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9116
9116
|
"recording-signal",
|
|
9117
9117
|
"records",
|
|
9118
9118
|
"remote",
|
|
9119
|
+
"remote-layout-components",
|
|
9119
9120
|
"running-state",
|
|
9120
9121
|
"scene-monitor",
|
|
9121
9122
|
"script-runner",
|
|
@@ -15852,6 +15853,478 @@ object({
|
|
|
15852
15853
|
path: ["expr"]
|
|
15853
15854
|
});
|
|
15854
15855
|
});
|
|
15856
|
+
/**
|
|
15857
|
+
* Identity envelope for a device's upstream-system metadata.
|
|
15858
|
+
*
|
|
15859
|
+
* Two jobs:
|
|
15860
|
+
*
|
|
15861
|
+
* 1. **Dispatch key.** `id` is the natural identifier the SOURCE system
|
|
15862
|
+
* uses to address this device (HA `entity_id`, Reolink MAC, ONVIF
|
|
15863
|
+
* WS-Discovery endpoint UUID, …). Provider code keeps a
|
|
15864
|
+
* `Map<sourceInfo.id, IDevice>` to route inbound push events in O(1)
|
|
15865
|
+
* without round-tripping through `stableId` / `id` mappings.
|
|
15866
|
+
*
|
|
15867
|
+
* 2. **Stability bridge.** `uniqueId` is the *immutable* upstream id when
|
|
15868
|
+
* one exists (HA `entity.unique_id`, Reolink MAC again — same as `id`
|
|
15869
|
+
* for vendors where MAC is the natural key). For systems where the
|
|
15870
|
+
* live dispatch key can be renamed (HA `entity_id` can be edited),
|
|
15871
|
+
* providers detect renames by matching `uniqueId` and patch `id`
|
|
15872
|
+
* in-place so dispatch keeps working.
|
|
15873
|
+
*
|
|
15874
|
+
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
15875
|
+
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
15876
|
+
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
15877
|
+
* neither is repeated on each sample. The `device_class` tag is an
|
|
15878
|
+
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
15879
|
+
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
15880
|
+
*
|
|
15881
|
+
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
15882
|
+
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
15883
|
+
* details, …). Providers control what lands here.
|
|
15884
|
+
*/
|
|
15885
|
+
var SourceInfoSchema = object({
|
|
15886
|
+
/** Live dispatch key — mutable when the source system allows rename. */
|
|
15887
|
+
id: string(),
|
|
15888
|
+
/** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
|
|
15889
|
+
system: string(),
|
|
15890
|
+
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
15891
|
+
* Used to detect rename when `id` changes. */
|
|
15892
|
+
uniqueId: string().optional(),
|
|
15893
|
+
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
15894
|
+
quantity: ReadingQuantitySchema.optional(),
|
|
15895
|
+
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
15896
|
+
dateTimeShape: _enum([
|
|
15897
|
+
"date",
|
|
15898
|
+
"time",
|
|
15899
|
+
"datetime"
|
|
15900
|
+
]).optional(),
|
|
15901
|
+
/** Provider-specific extras that don't fit the structured slots.
|
|
15902
|
+
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
15903
|
+
* attribute blobs (would explode the meta JSON column). */
|
|
15904
|
+
raw: record(string(), unknown()).optional()
|
|
15905
|
+
});
|
|
15906
|
+
/**
|
|
15907
|
+
* Frozen unit → spec table. `•` in the doc marks each dimension's canonical
|
|
15908
|
+
* unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
|
|
15909
|
+
* `factor = 5/9`, `offset = -160/9` (kept as exact expressions, not rounded
|
|
15910
|
+
* decimals). K derives from `°C = K − 273.15`.
|
|
15911
|
+
*/
|
|
15912
|
+
var UNIT_TABLE = {
|
|
15913
|
+
"°C": {
|
|
15914
|
+
dimension: "temperature",
|
|
15915
|
+
factor: 1,
|
|
15916
|
+
offset: 0
|
|
15917
|
+
},
|
|
15918
|
+
"°F": {
|
|
15919
|
+
dimension: "temperature",
|
|
15920
|
+
factor: 5 / 9,
|
|
15921
|
+
offset: -160 / 9
|
|
15922
|
+
},
|
|
15923
|
+
K: {
|
|
15924
|
+
dimension: "temperature",
|
|
15925
|
+
factor: 1,
|
|
15926
|
+
offset: -273.15
|
|
15927
|
+
},
|
|
15928
|
+
hPa: {
|
|
15929
|
+
dimension: "pressure",
|
|
15930
|
+
factor: 1,
|
|
15931
|
+
offset: 0
|
|
15932
|
+
},
|
|
15933
|
+
kPa: {
|
|
15934
|
+
dimension: "pressure",
|
|
15935
|
+
factor: 10,
|
|
15936
|
+
offset: 0
|
|
15937
|
+
},
|
|
15938
|
+
Pa: {
|
|
15939
|
+
dimension: "pressure",
|
|
15940
|
+
factor: .01,
|
|
15941
|
+
offset: 0
|
|
15942
|
+
},
|
|
15943
|
+
mbar: {
|
|
15944
|
+
dimension: "pressure",
|
|
15945
|
+
factor: 1,
|
|
15946
|
+
offset: 0
|
|
15947
|
+
},
|
|
15948
|
+
bar: {
|
|
15949
|
+
dimension: "pressure",
|
|
15950
|
+
factor: 1e3,
|
|
15951
|
+
offset: 0
|
|
15952
|
+
},
|
|
15953
|
+
inHg: {
|
|
15954
|
+
dimension: "pressure",
|
|
15955
|
+
factor: 33.8639,
|
|
15956
|
+
offset: 0
|
|
15957
|
+
},
|
|
15958
|
+
mmHg: {
|
|
15959
|
+
dimension: "pressure",
|
|
15960
|
+
factor: 1.33322,
|
|
15961
|
+
offset: 0
|
|
15962
|
+
},
|
|
15963
|
+
psi: {
|
|
15964
|
+
dimension: "pressure",
|
|
15965
|
+
factor: 68.9476,
|
|
15966
|
+
offset: 0
|
|
15967
|
+
},
|
|
15968
|
+
"m/s": {
|
|
15969
|
+
dimension: "speed",
|
|
15970
|
+
factor: 1,
|
|
15971
|
+
offset: 0
|
|
15972
|
+
},
|
|
15973
|
+
"km/h": {
|
|
15974
|
+
dimension: "speed",
|
|
15975
|
+
factor: 1 / 3.6,
|
|
15976
|
+
offset: 0
|
|
15977
|
+
},
|
|
15978
|
+
mph: {
|
|
15979
|
+
dimension: "speed",
|
|
15980
|
+
factor: .44704,
|
|
15981
|
+
offset: 0
|
|
15982
|
+
},
|
|
15983
|
+
kn: {
|
|
15984
|
+
dimension: "speed",
|
|
15985
|
+
factor: .514444,
|
|
15986
|
+
offset: 0
|
|
15987
|
+
},
|
|
15988
|
+
"mm/h": {
|
|
15989
|
+
dimension: "precipitation-rate",
|
|
15990
|
+
factor: 1,
|
|
15991
|
+
offset: 0
|
|
15992
|
+
},
|
|
15993
|
+
"in/h": {
|
|
15994
|
+
dimension: "precipitation-rate",
|
|
15995
|
+
factor: 25.4,
|
|
15996
|
+
offset: 0
|
|
15997
|
+
},
|
|
15998
|
+
m: {
|
|
15999
|
+
dimension: "length",
|
|
16000
|
+
factor: 1,
|
|
16001
|
+
offset: 0
|
|
16002
|
+
},
|
|
16003
|
+
mm: {
|
|
16004
|
+
dimension: "length",
|
|
16005
|
+
factor: .001,
|
|
16006
|
+
offset: 0
|
|
16007
|
+
},
|
|
16008
|
+
cm: {
|
|
16009
|
+
dimension: "length",
|
|
16010
|
+
factor: .01,
|
|
16011
|
+
offset: 0
|
|
16012
|
+
},
|
|
16013
|
+
km: {
|
|
16014
|
+
dimension: "length",
|
|
16015
|
+
factor: 1e3,
|
|
16016
|
+
offset: 0
|
|
16017
|
+
},
|
|
16018
|
+
in: {
|
|
16019
|
+
dimension: "length",
|
|
16020
|
+
factor: .0254,
|
|
16021
|
+
offset: 0
|
|
16022
|
+
},
|
|
16023
|
+
ft: {
|
|
16024
|
+
dimension: "length",
|
|
16025
|
+
factor: .3048,
|
|
16026
|
+
offset: 0
|
|
16027
|
+
},
|
|
16028
|
+
mi: {
|
|
16029
|
+
dimension: "length",
|
|
16030
|
+
factor: 1609.344,
|
|
16031
|
+
offset: 0
|
|
16032
|
+
},
|
|
16033
|
+
"m²": {
|
|
16034
|
+
dimension: "area",
|
|
16035
|
+
factor: 1,
|
|
16036
|
+
offset: 0
|
|
16037
|
+
},
|
|
16038
|
+
lx: {
|
|
16039
|
+
dimension: "illuminance",
|
|
16040
|
+
factor: 1,
|
|
16041
|
+
offset: 0
|
|
16042
|
+
},
|
|
16043
|
+
"W/m²": {
|
|
16044
|
+
dimension: "irradiance",
|
|
16045
|
+
factor: 1,
|
|
16046
|
+
offset: 0
|
|
16047
|
+
},
|
|
16048
|
+
W: {
|
|
16049
|
+
dimension: "power",
|
|
16050
|
+
factor: 1,
|
|
16051
|
+
offset: 0
|
|
16052
|
+
},
|
|
16053
|
+
kW: {
|
|
16054
|
+
dimension: "power",
|
|
16055
|
+
factor: 1e3,
|
|
16056
|
+
offset: 0
|
|
16057
|
+
},
|
|
16058
|
+
VA: {
|
|
16059
|
+
dimension: "apparent-power",
|
|
16060
|
+
factor: 1,
|
|
16061
|
+
offset: 0
|
|
16062
|
+
},
|
|
16063
|
+
Wh: {
|
|
16064
|
+
dimension: "energy",
|
|
16065
|
+
factor: 1,
|
|
16066
|
+
offset: 0
|
|
16067
|
+
},
|
|
16068
|
+
kWh: {
|
|
16069
|
+
dimension: "energy",
|
|
16070
|
+
factor: 1e3,
|
|
16071
|
+
offset: 0
|
|
16072
|
+
},
|
|
16073
|
+
MWh: {
|
|
16074
|
+
dimension: "energy",
|
|
16075
|
+
factor: 1e6,
|
|
16076
|
+
offset: 0
|
|
16077
|
+
},
|
|
16078
|
+
V: {
|
|
16079
|
+
dimension: "voltage",
|
|
16080
|
+
factor: 1,
|
|
16081
|
+
offset: 0
|
|
16082
|
+
},
|
|
16083
|
+
mV: {
|
|
16084
|
+
dimension: "voltage",
|
|
16085
|
+
factor: .001,
|
|
16086
|
+
offset: 0
|
|
16087
|
+
},
|
|
16088
|
+
A: {
|
|
16089
|
+
dimension: "current",
|
|
16090
|
+
factor: 1,
|
|
16091
|
+
offset: 0
|
|
16092
|
+
},
|
|
16093
|
+
mA: {
|
|
16094
|
+
dimension: "current",
|
|
16095
|
+
factor: .001,
|
|
16096
|
+
offset: 0
|
|
16097
|
+
},
|
|
16098
|
+
ppm: {
|
|
16099
|
+
dimension: "concentration-volume",
|
|
16100
|
+
factor: 1,
|
|
16101
|
+
offset: 0
|
|
16102
|
+
},
|
|
16103
|
+
ppb: {
|
|
16104
|
+
dimension: "concentration-volume",
|
|
16105
|
+
factor: .001,
|
|
16106
|
+
offset: 0
|
|
16107
|
+
},
|
|
16108
|
+
"µg/m³": {
|
|
16109
|
+
dimension: "concentration-mass",
|
|
16110
|
+
factor: 1,
|
|
16111
|
+
offset: 0
|
|
16112
|
+
},
|
|
16113
|
+
"mg/m³": {
|
|
16114
|
+
dimension: "concentration-mass",
|
|
16115
|
+
factor: 1e3,
|
|
16116
|
+
offset: 0
|
|
16117
|
+
},
|
|
16118
|
+
kg: {
|
|
16119
|
+
dimension: "mass",
|
|
16120
|
+
factor: 1,
|
|
16121
|
+
offset: 0
|
|
16122
|
+
},
|
|
16123
|
+
g: {
|
|
16124
|
+
dimension: "mass",
|
|
16125
|
+
factor: .001,
|
|
16126
|
+
offset: 0
|
|
16127
|
+
},
|
|
16128
|
+
lb: {
|
|
16129
|
+
dimension: "mass",
|
|
16130
|
+
factor: .453592,
|
|
16131
|
+
offset: 0
|
|
16132
|
+
},
|
|
16133
|
+
oz: {
|
|
16134
|
+
dimension: "mass",
|
|
16135
|
+
factor: .0283495,
|
|
16136
|
+
offset: 0
|
|
16137
|
+
},
|
|
16138
|
+
"%": {
|
|
16139
|
+
dimension: "percentage",
|
|
16140
|
+
factor: 1,
|
|
16141
|
+
offset: 0
|
|
16142
|
+
},
|
|
16143
|
+
L: {
|
|
16144
|
+
dimension: "volume",
|
|
16145
|
+
factor: 1,
|
|
16146
|
+
offset: 0
|
|
16147
|
+
},
|
|
16148
|
+
mL: {
|
|
16149
|
+
dimension: "volume",
|
|
16150
|
+
factor: .001,
|
|
16151
|
+
offset: 0
|
|
16152
|
+
},
|
|
16153
|
+
gal: {
|
|
16154
|
+
dimension: "volume",
|
|
16155
|
+
factor: 3.785411784,
|
|
16156
|
+
offset: 0
|
|
16157
|
+
},
|
|
16158
|
+
s: {
|
|
16159
|
+
dimension: "duration",
|
|
16160
|
+
factor: 1,
|
|
16161
|
+
offset: 0
|
|
16162
|
+
},
|
|
16163
|
+
ms: {
|
|
16164
|
+
dimension: "duration",
|
|
16165
|
+
factor: .001,
|
|
16166
|
+
offset: 0
|
|
16167
|
+
},
|
|
16168
|
+
min: {
|
|
16169
|
+
dimension: "duration",
|
|
16170
|
+
factor: 60,
|
|
16171
|
+
offset: 0
|
|
16172
|
+
},
|
|
16173
|
+
h: {
|
|
16174
|
+
dimension: "duration",
|
|
16175
|
+
factor: 3600,
|
|
16176
|
+
offset: 0
|
|
16177
|
+
},
|
|
16178
|
+
d: {
|
|
16179
|
+
dimension: "duration",
|
|
16180
|
+
factor: 86400,
|
|
16181
|
+
offset: 0
|
|
16182
|
+
},
|
|
16183
|
+
B: {
|
|
16184
|
+
dimension: "information",
|
|
16185
|
+
factor: 1,
|
|
16186
|
+
offset: 0
|
|
16187
|
+
},
|
|
16188
|
+
KiB: {
|
|
16189
|
+
dimension: "information",
|
|
16190
|
+
factor: 1024,
|
|
16191
|
+
offset: 0
|
|
16192
|
+
},
|
|
16193
|
+
MiB: {
|
|
16194
|
+
dimension: "information",
|
|
16195
|
+
factor: 1024 ** 2,
|
|
16196
|
+
offset: 0
|
|
16197
|
+
},
|
|
16198
|
+
GiB: {
|
|
16199
|
+
dimension: "information",
|
|
16200
|
+
factor: 1024 ** 3,
|
|
16201
|
+
offset: 0
|
|
16202
|
+
},
|
|
16203
|
+
TiB: {
|
|
16204
|
+
dimension: "information",
|
|
16205
|
+
factor: 1024 ** 4,
|
|
16206
|
+
offset: 0
|
|
16207
|
+
},
|
|
16208
|
+
kB: {
|
|
16209
|
+
dimension: "information",
|
|
16210
|
+
factor: 1e3,
|
|
16211
|
+
offset: 0
|
|
16212
|
+
},
|
|
16213
|
+
MB: {
|
|
16214
|
+
dimension: "information",
|
|
16215
|
+
factor: 1e6,
|
|
16216
|
+
offset: 0
|
|
16217
|
+
},
|
|
16218
|
+
GB: {
|
|
16219
|
+
dimension: "information",
|
|
16220
|
+
factor: 1e9,
|
|
16221
|
+
offset: 0
|
|
16222
|
+
},
|
|
16223
|
+
"°": {
|
|
16224
|
+
dimension: "angle",
|
|
16225
|
+
factor: 1,
|
|
16226
|
+
offset: 0
|
|
16227
|
+
},
|
|
16228
|
+
dBFS: {
|
|
16229
|
+
dimension: "sound-level",
|
|
16230
|
+
factor: 1,
|
|
16231
|
+
offset: 0
|
|
16232
|
+
},
|
|
16233
|
+
dBm: {
|
|
16234
|
+
dimension: "signal-level",
|
|
16235
|
+
factor: 1,
|
|
16236
|
+
offset: 0
|
|
16237
|
+
},
|
|
16238
|
+
mired: {
|
|
16239
|
+
dimension: "colour-temperature",
|
|
16240
|
+
factor: 1,
|
|
16241
|
+
offset: 0
|
|
16242
|
+
},
|
|
16243
|
+
kbps: {
|
|
16244
|
+
dimension: "bitrate",
|
|
16245
|
+
factor: 1,
|
|
16246
|
+
offset: 0
|
|
16247
|
+
},
|
|
16248
|
+
Mbps: {
|
|
16249
|
+
dimension: "bitrate",
|
|
16250
|
+
factor: 1e3,
|
|
16251
|
+
offset: 0
|
|
16252
|
+
},
|
|
16253
|
+
fps: {
|
|
16254
|
+
dimension: "rate",
|
|
16255
|
+
factor: 1,
|
|
16256
|
+
offset: 0
|
|
16257
|
+
}
|
|
16258
|
+
};
|
|
16259
|
+
/** Resolve a unit's `UnitSpec`, or `undefined` when the spelling is unknown. */
|
|
16260
|
+
function specFor(unit) {
|
|
16261
|
+
return Object.hasOwn(UNIT_TABLE, unit) ? UNIT_TABLE[unit] : void 0;
|
|
16262
|
+
}
|
|
16263
|
+
/** Value in `spec`'s unit → its dimension's canonical unit. */
|
|
16264
|
+
function toCanonical(value, spec) {
|
|
16265
|
+
return value * spec.factor + spec.offset;
|
|
16266
|
+
}
|
|
16267
|
+
/** Canonical-unit value → the unit described by `spec`. */
|
|
16268
|
+
function fromCanonical(canonical, spec) {
|
|
16269
|
+
return (canonical - spec.offset) / spec.factor;
|
|
16270
|
+
}
|
|
16271
|
+
/**
|
|
16272
|
+
* Graceful variant for the render path: returns the converted value, or
|
|
16273
|
+
* `undefined` when the conversion is refused (unknown unit / cross-dimension).
|
|
16274
|
+
* Never throws — a render caller falls back to the raw value + source unit.
|
|
16275
|
+
*/
|
|
16276
|
+
function tryConvertUnit(value, from, to) {
|
|
16277
|
+
if (from === to) return value;
|
|
16278
|
+
const fromSpec = specFor(from);
|
|
16279
|
+
if (!fromSpec) return void 0;
|
|
16280
|
+
const toSpec = specFor(to);
|
|
16281
|
+
if (!toSpec) return void 0;
|
|
16282
|
+
if (fromSpec.dimension !== toSpec.dimension) return void 0;
|
|
16283
|
+
return fromCanonical(toCanonical(value, fromSpec), toSpec);
|
|
16284
|
+
}
|
|
16285
|
+
/**
|
|
16286
|
+
* A number a person types for a physical quantity — the input side of the
|
|
16287
|
+
* value + unit contract (D972).
|
|
16288
|
+
*
|
|
16289
|
+
* Readings are stored in the base unit of their quantity (D944); a cap method
|
|
16290
|
+
* param is stored in the unit its input schema DECLARES (`paramMeta`). The
|
|
16291
|
+
* wire pair {@link QuantityValue} says "this number is expressed in this
|
|
16292
|
+
* unit"; {@link convertQuantityInput} brings it to the stored unit and refuses,
|
|
16293
|
+
* with a typed {@link QuantityUnitError}, a unit that cannot be that quantity.
|
|
16294
|
+
*/
|
|
16295
|
+
/** A unit that cannot be applied to the number it was given with. */
|
|
16296
|
+
var QuantityUnitError = class extends Error {
|
|
16297
|
+
code;
|
|
16298
|
+
constructor(code, message) {
|
|
16299
|
+
super(`[${code}] ${message}`);
|
|
16300
|
+
this.name = "QuantityUnitError";
|
|
16301
|
+
this.code = code;
|
|
16302
|
+
}
|
|
16303
|
+
};
|
|
16304
|
+
/** The wire pair: `value` is expressed in `unit`. */
|
|
16305
|
+
var QuantityValueSchema = object({
|
|
16306
|
+
value: number(),
|
|
16307
|
+
unit: string().min(1)
|
|
16308
|
+
});
|
|
16309
|
+
/**
|
|
16310
|
+
* Zod `.meta()` bag for a cap METHOD param that is a physical quantity — the
|
|
16311
|
+
* input-side twin of `readingMeta`. The value is carried in `unit` (a gram
|
|
16312
|
+
* portion stays in grams); the unit must belong to the quantity, checked once
|
|
16313
|
+
* when the cap is declared.
|
|
16314
|
+
*/
|
|
16315
|
+
function paramMeta(declared) {
|
|
16316
|
+
const base = baseUnitOf(declared.quantity);
|
|
16317
|
+
if (base === void 0) throw new QuantityUnitError("unknown-unit", `quantity "${declared.quantity}" has no unit`);
|
|
16318
|
+
if (tryConvertUnit(1, declared.unit, base) === void 0) throw new QuantityUnitError("cross-dimension", `"${declared.unit}" is not a unit of ${declared.quantity}`);
|
|
16319
|
+
return {
|
|
16320
|
+
quantity: declared.quantity,
|
|
16321
|
+
unit: declared.unit
|
|
16322
|
+
};
|
|
16323
|
+
}
|
|
16324
|
+
object({
|
|
16325
|
+
quantity: ReadingQuantitySchema,
|
|
16326
|
+
unit: string().min(1)
|
|
16327
|
+
});
|
|
15855
16328
|
/** How a leaf compares a device field to a value. Derived from the field's
|
|
15856
16329
|
* `kind` in `deviceManager.getWireableFields`, never hand-maintained. */
|
|
15857
16330
|
var AutomationConditionOperatorSchema = _enum([
|
|
@@ -15874,8 +16347,10 @@ var AutomationConditionLeafSchema = object({
|
|
|
15874
16347
|
string(),
|
|
15875
16348
|
number(),
|
|
15876
16349
|
boolean(),
|
|
15877
|
-
array(union([string(), number()]))
|
|
15878
|
-
|
|
16350
|
+
array(union([string(), number()])),
|
|
16351
|
+
QuantityValueSchema
|
|
16352
|
+
]),
|
|
16353
|
+
unit: string().min(1).optional()
|
|
15879
16354
|
});
|
|
15880
16355
|
var AutomationConditionStationaryPresentSchema = object({
|
|
15881
16356
|
kind: literal("stationary-present"),
|
|
@@ -16028,7 +16503,13 @@ var AutomationCapStepSchema = object({
|
|
|
16028
16503
|
/** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
|
|
16029
16504
|
* SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
|
|
16030
16505
|
* the expression leaf. */
|
|
16031
|
-
args: record(string(), unknown()).optional()
|
|
16506
|
+
args: record(string(), unknown()).optional(),
|
|
16507
|
+
/**
|
|
16508
|
+
* The unit the person picked per arg (display only). `args` always hold the
|
|
16509
|
+
* value in the unit the method's input DECLARES (`paramMeta`); on a write an
|
|
16510
|
+
* arg may be a {@link QuantityValue}, which the save boundary converts.
|
|
16511
|
+
*/
|
|
16512
|
+
argUnits: record(string(), string().min(1)).optional()
|
|
16032
16513
|
});
|
|
16033
16514
|
/**
|
|
16034
16515
|
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
@@ -16408,6 +16889,16 @@ object({
|
|
|
16408
16889
|
lastRunAt: number().nullable(),
|
|
16409
16890
|
lastError: string().nullable()
|
|
16410
16891
|
});
|
|
16892
|
+
/** A bare number accepted as a base unit — the save succeeded, say so. */
|
|
16893
|
+
var UnitWarningSchema = object({
|
|
16894
|
+
/** Where in the saved record, e.g. `conditions.children.0` or `steps.2.args.grams`. */
|
|
16895
|
+
path: string(),
|
|
16896
|
+
deviceId: number().int().optional(),
|
|
16897
|
+
field: string(),
|
|
16898
|
+
value: number(),
|
|
16899
|
+
assumedUnit: string(),
|
|
16900
|
+
message: string()
|
|
16901
|
+
});
|
|
16411
16902
|
/**
|
|
16412
16903
|
* notification-output — canonical, capability-gated notification delivery.
|
|
16413
16904
|
*
|
|
@@ -21752,56 +22243,6 @@ var DeviceAdminLinkSchema = object({
|
|
|
21752
22243
|
});
|
|
21753
22244
|
method(object({ deviceId: number().int().nonnegative() }), DeviceAdminLinkSchema.nullable(), { auth: "admin" });
|
|
21754
22245
|
/**
|
|
21755
|
-
* Identity envelope for a device's upstream-system metadata.
|
|
21756
|
-
*
|
|
21757
|
-
* Two jobs:
|
|
21758
|
-
*
|
|
21759
|
-
* 1. **Dispatch key.** `id` is the natural identifier the SOURCE system
|
|
21760
|
-
* uses to address this device (HA `entity_id`, Reolink MAC, ONVIF
|
|
21761
|
-
* WS-Discovery endpoint UUID, …). Provider code keeps a
|
|
21762
|
-
* `Map<sourceInfo.id, IDevice>` to route inbound push events in O(1)
|
|
21763
|
-
* without round-tripping through `stableId` / `id` mappings.
|
|
21764
|
-
*
|
|
21765
|
-
* 2. **Stability bridge.** `uniqueId` is the *immutable* upstream id when
|
|
21766
|
-
* one exists (HA `entity.unique_id`, Reolink MAC again — same as `id`
|
|
21767
|
-
* for vendors where MAC is the natural key). For systems where the
|
|
21768
|
-
* live dispatch key can be renamed (HA `entity_id` can be edited),
|
|
21769
|
-
* providers detect renames by matching `uniqueId` and patch `id`
|
|
21770
|
-
* in-place so dispatch keeps working.
|
|
21771
|
-
*
|
|
21772
|
-
* **Display unit and precision are NOT stored here.** They are a read-time
|
|
21773
|
-
* preference (D944). A polymorphic reading stores its `quantity` here once,
|
|
21774
|
-
* at adopt, and a date/time value stores `dateTimeShape` the same way —
|
|
21775
|
-
* neither is repeated on each sample. The `device_class` tag is an
|
|
21776
|
-
* HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
|
|
21777
|
-
* to derive the CamStack `DeviceRole`; it is never stored after that point.
|
|
21778
|
-
*
|
|
21779
|
-
* The `raw` escape hatch carries provider-specific attributes that don't
|
|
21780
|
-
* fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
|
|
21781
|
-
* details, …). Providers control what lands here.
|
|
21782
|
-
*/
|
|
21783
|
-
var SourceInfoSchema = object({
|
|
21784
|
-
/** Live dispatch key — mutable when the source system allows rename. */
|
|
21785
|
-
id: string(),
|
|
21786
|
-
/** Source system tag — e.g. 'homeassistant' | 'reolink' | 'onvif'. */
|
|
21787
|
-
system: string(),
|
|
21788
|
-
/** Immutable upstream identifier when available (HA `unique_id`, … ).
|
|
21789
|
-
* Used to detect rename when `id` changes. */
|
|
21790
|
-
uniqueId: string().optional(),
|
|
21791
|
-
/** Quantity of a polymorphic reading, written once at adopt (D944). */
|
|
21792
|
-
quantity: ReadingQuantitySchema.optional(),
|
|
21793
|
-
/** Date / time / datetime shape of a string reading, written once at adopt. */
|
|
21794
|
-
dateTimeShape: _enum([
|
|
21795
|
-
"date",
|
|
21796
|
-
"time",
|
|
21797
|
-
"datetime"
|
|
21798
|
-
]).optional(),
|
|
21799
|
-
/** Provider-specific extras that don't fit the structured slots.
|
|
21800
|
-
* Whitelist what goes here per provider — do NOT dump entire HA
|
|
21801
|
-
* attribute blobs (would explode the meta JSON column). */
|
|
21802
|
-
raw: record(string(), unknown()).optional()
|
|
21803
|
-
});
|
|
21804
|
-
/**
|
|
21805
22246
|
* device-discovery — device-scoped capability for parents that host /
|
|
21806
22247
|
* enumerate child devices (Reolink Hub / NVR, ONVIF gateway, future
|
|
21807
22248
|
* integrations). The parent advertises a list of discoverable children,
|
|
@@ -57808,13 +58249,19 @@ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
|
57808
58249
|
}), method(ActionIdInput, _void(), {
|
|
57809
58250
|
kind: "mutation",
|
|
57810
58251
|
auth: "admin"
|
|
57811
|
-
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({
|
|
58252
|
+
}), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({
|
|
58253
|
+
action: ActionEntrySchema,
|
|
58254
|
+
warnings: array(UnitWarningSchema).optional()
|
|
58255
|
+
}), {
|
|
57812
58256
|
kind: "mutation",
|
|
57813
58257
|
auth: "admin"
|
|
57814
58258
|
}), method(object({
|
|
57815
58259
|
actionId: string().min(1),
|
|
57816
58260
|
action: ActionInputSchema.partial()
|
|
57817
|
-
}), object({
|
|
58261
|
+
}), object({
|
|
58262
|
+
action: ActionEntrySchema,
|
|
58263
|
+
warnings: array(UnitWarningSchema).optional()
|
|
58264
|
+
}), {
|
|
57818
58265
|
kind: "mutation",
|
|
57819
58266
|
auth: "admin"
|
|
57820
58267
|
}), method(ActionIdInput, _void(), {
|
|
@@ -58120,6 +58567,30 @@ object({
|
|
|
58120
58567
|
at: number()
|
|
58121
58568
|
}).nullable()
|
|
58122
58569
|
});
|
|
58570
|
+
var RemoteButtonShapeSchema = _enum([
|
|
58571
|
+
"rect",
|
|
58572
|
+
"rounded",
|
|
58573
|
+
"round",
|
|
58574
|
+
"pill"
|
|
58575
|
+
]);
|
|
58576
|
+
var RemoteButtonToneSchema = _enum([
|
|
58577
|
+
"neutral",
|
|
58578
|
+
"accent",
|
|
58579
|
+
"danger",
|
|
58580
|
+
"red",
|
|
58581
|
+
"green",
|
|
58582
|
+
"yellow",
|
|
58583
|
+
"blue"
|
|
58584
|
+
]);
|
|
58585
|
+
var RemoteGroupFrameSchema = _enum([
|
|
58586
|
+
"none",
|
|
58587
|
+
"panel",
|
|
58588
|
+
"divider",
|
|
58589
|
+
"dpad",
|
|
58590
|
+
"rocker-v",
|
|
58591
|
+
"rocker-h",
|
|
58592
|
+
"keypad"
|
|
58593
|
+
]);
|
|
58123
58594
|
var RemoteLayoutButtonSchema = object({
|
|
58124
58595
|
id: string().min(1).max(40),
|
|
58125
58596
|
/** 0-based grid position. */
|
|
@@ -58129,12 +58600,94 @@ var RemoteLayoutButtonSchema = object({
|
|
|
58129
58600
|
colSpan: number().int().min(1).max(24),
|
|
58130
58601
|
icon: string().min(1).max(60).optional(),
|
|
58131
58602
|
label: string().min(1).max(40).optional(),
|
|
58132
|
-
role: RemoteRoleSchema
|
|
58603
|
+
role: RemoteRoleSchema,
|
|
58604
|
+
/** Absent = the plain rendering every layout had before shapes existed. */
|
|
58605
|
+
shape: RemoteButtonShapeSchema.optional(),
|
|
58606
|
+
tone: RemoteButtonToneSchema.optional(),
|
|
58607
|
+
/** The group this button belongs to; it must lie inside that group's rectangle. */
|
|
58608
|
+
groupId: string().min(1).max(40).optional()
|
|
58609
|
+
});
|
|
58610
|
+
/**
|
|
58611
|
+
* A rectangle of the grid that moves as ONE thing and is drawn with a frame: a
|
|
58612
|
+
* titled panel, a section divider, a D-pad ring. `componentId` names the palette
|
|
58613
|
+
* entry it came from (informational: the layout is self-contained).
|
|
58614
|
+
*/
|
|
58615
|
+
var RemoteLayoutGroupSchema = object({
|
|
58616
|
+
id: string().min(1).max(40),
|
|
58617
|
+
componentId: string().min(1).max(80),
|
|
58618
|
+
frame: RemoteGroupFrameSchema,
|
|
58619
|
+
row: number().int().min(0).max(24),
|
|
58620
|
+
col: number().int().min(0).max(24),
|
|
58621
|
+
rowSpan: number().int().min(1).max(24),
|
|
58622
|
+
colSpan: number().int().min(1).max(24),
|
|
58623
|
+
title: string().min(1).max(40).optional()
|
|
58133
58624
|
});
|
|
58625
|
+
function rectsOverlap(a, b) {
|
|
58626
|
+
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;
|
|
58627
|
+
}
|
|
58628
|
+
function rectContains(outer, inner) {
|
|
58629
|
+
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;
|
|
58630
|
+
}
|
|
58631
|
+
/**
|
|
58632
|
+
* The group rules of a layout: inside the grid, no two groups overlap, a
|
|
58633
|
+
* member lies inside its group, a divider holds nothing, and a button that is
|
|
58634
|
+
* not a member never sits inside someone else's rectangle (a group moves as
|
|
58635
|
+
* one thing, so a stray key under it would be left behind).
|
|
58636
|
+
*/
|
|
58637
|
+
function refineGroups(grid, ctx) {
|
|
58638
|
+
const groups = grid.groups ?? [];
|
|
58639
|
+
const byId = /* @__PURE__ */ new Map();
|
|
58640
|
+
const fail = (message, path) => {
|
|
58641
|
+
ctx.addIssue({
|
|
58642
|
+
code: "custom",
|
|
58643
|
+
message,
|
|
58644
|
+
path
|
|
58645
|
+
});
|
|
58646
|
+
};
|
|
58647
|
+
groups.forEach((group, index) => {
|
|
58648
|
+
if (byId.has(group.id)) fail(`group id "${group.id}" is used twice`, [
|
|
58649
|
+
"groups",
|
|
58650
|
+
index,
|
|
58651
|
+
"id"
|
|
58652
|
+
]);
|
|
58653
|
+
byId.set(group.id, group);
|
|
58654
|
+
if (group.row + group.rowSpan > grid.rows || group.col + group.colSpan > grid.columns) fail(`group "${group.id}" leaves the grid`, ["groups", index]);
|
|
58655
|
+
for (let other = 0; other < index; other += 1) {
|
|
58656
|
+
const earlier = groups[other];
|
|
58657
|
+
if (earlier !== void 0 && rectsOverlap(earlier, group)) {
|
|
58658
|
+
fail(`groups "${earlier.id}" and "${group.id}" overlap`, ["groups", index]);
|
|
58659
|
+
return;
|
|
58660
|
+
}
|
|
58661
|
+
}
|
|
58662
|
+
});
|
|
58663
|
+
grid.buttons.forEach((button, index) => {
|
|
58664
|
+
if (button.groupId !== void 0) {
|
|
58665
|
+
const group = byId.get(button.groupId);
|
|
58666
|
+
if (group === void 0) {
|
|
58667
|
+
fail(`button "${button.id}" names the unknown group "${button.groupId}"`, [
|
|
58668
|
+
"buttons",
|
|
58669
|
+
index,
|
|
58670
|
+
"groupId"
|
|
58671
|
+
]);
|
|
58672
|
+
return;
|
|
58673
|
+
}
|
|
58674
|
+
if (group.frame === "divider") fail(`a divider group ("${group.id}") holds no buttons`, [
|
|
58675
|
+
"buttons",
|
|
58676
|
+
index,
|
|
58677
|
+
"groupId"
|
|
58678
|
+
]);
|
|
58679
|
+
if (!rectContains(group, button)) fail(`button "${button.id}" lies outside its group "${group.id}"`, ["buttons", index]);
|
|
58680
|
+
return;
|
|
58681
|
+
}
|
|
58682
|
+
const foreign = groups.find((group) => rectsOverlap(group, button));
|
|
58683
|
+
if (foreign !== void 0) fail(`button "${button.id}" lies inside group "${foreign.id}" but is not a member`, ["buttons", index]);
|
|
58684
|
+
});
|
|
58685
|
+
}
|
|
58134
58686
|
object({
|
|
58135
58687
|
columns: number().int().min(1).max(24),
|
|
58136
58688
|
rows: number().int().min(1).max(24),
|
|
58137
|
-
buttons: array(RemoteLayoutButtonSchema).max(200)
|
|
58689
|
+
buttons: array(RemoteLayoutButtonSchema).max(200),
|
|
58690
|
+
groups: array(RemoteLayoutGroupSchema).max(50).optional()
|
|
58138
58691
|
}).superRefine((grid, ctx) => {
|
|
58139
58692
|
const ids = /* @__PURE__ */ new Set();
|
|
58140
58693
|
const taken = /* @__PURE__ */ new Map();
|
|
@@ -58171,6 +58724,7 @@ object({
|
|
|
58171
58724
|
taken.set(cell, button.id);
|
|
58172
58725
|
}
|
|
58173
58726
|
});
|
|
58727
|
+
refineGroups(grid, ctx);
|
|
58174
58728
|
});
|
|
58175
58729
|
var RemoteBoundCommandSchema = object({
|
|
58176
58730
|
role: RemoteRoleSchema,
|
|
@@ -58302,6 +58856,91 @@ method(object({ kind: TemplateKindSchema.optional() }), array(TemplateRecordSche
|
|
|
58302
58856
|
kind: "mutation",
|
|
58303
58857
|
auth: "admin"
|
|
58304
58858
|
});
|
|
58859
|
+
var RemoteComponentCategorySchema = _enum([
|
|
58860
|
+
"power",
|
|
58861
|
+
"navigation",
|
|
58862
|
+
"volume",
|
|
58863
|
+
"numbers",
|
|
58864
|
+
"media",
|
|
58865
|
+
"colour",
|
|
58866
|
+
"apps",
|
|
58867
|
+
"layout"
|
|
58868
|
+
]);
|
|
58869
|
+
/** `<namespace>:<name>`, both lowercase slugs — `core:dpad`, `<addonId>:<name>`. */
|
|
58870
|
+
var COMPONENT_ID_RE = /^[a-z0-9][a-z0-9_.-]*:[a-z0-9][a-z0-9_-]*$/;
|
|
58871
|
+
var RemoteComponentButtonSchema = object({
|
|
58872
|
+
/** Joined to the instance id when the component is inserted. */
|
|
58873
|
+
idSuffix: string().regex(/^[a-z0-9][a-z0-9_-]{0,19}$/, { message: "a short lowercase slug" }),
|
|
58874
|
+
row: number().int().min(0).max(24),
|
|
58875
|
+
col: number().int().min(0).max(24),
|
|
58876
|
+
rowSpan: number().int().min(1).max(24),
|
|
58877
|
+
colSpan: number().int().min(1).max(24),
|
|
58878
|
+
role: RemoteRoleSchema,
|
|
58879
|
+
icon: string().min(1).max(60).optional(),
|
|
58880
|
+
label: string().min(1).max(40).optional(),
|
|
58881
|
+
shape: RemoteButtonShapeSchema.optional(),
|
|
58882
|
+
tone: RemoteButtonToneSchema.optional()
|
|
58883
|
+
});
|
|
58884
|
+
var RemoteLayoutComponentSchema = object({
|
|
58885
|
+
id: string().max(80).regex(COMPONENT_ID_RE, { message: "<namespace>:<name>, lowercase" }),
|
|
58886
|
+
name: string().min(1).max(60),
|
|
58887
|
+
nameI18n: object({
|
|
58888
|
+
en: string().min(1).max(60),
|
|
58889
|
+
it: string().min(1).max(60)
|
|
58890
|
+
}).optional(),
|
|
58891
|
+
/** A display icon key, resolved by the UI like a button icon. */
|
|
58892
|
+
icon: string().min(1).max(60),
|
|
58893
|
+
category: RemoteComponentCategorySchema,
|
|
58894
|
+
size: object({
|
|
58895
|
+
rows: number().int().min(1).max(24),
|
|
58896
|
+
cols: number().int().min(1).max(24)
|
|
58897
|
+
}),
|
|
58898
|
+
/** The frame drawn around the whole component, or null for loose buttons. */
|
|
58899
|
+
group: object({
|
|
58900
|
+
frame: RemoteGroupFrameSchema,
|
|
58901
|
+
title: string().min(1).max(40).optional()
|
|
58902
|
+
}).nullable(),
|
|
58903
|
+
buttons: array(RemoteComponentButtonSchema).max(40)
|
|
58904
|
+
}).superRefine((component, ctx) => {
|
|
58905
|
+
const suffixes = /* @__PURE__ */ new Set();
|
|
58906
|
+
component.buttons.forEach((button, index) => {
|
|
58907
|
+
if (suffixes.has(button.idSuffix)) ctx.addIssue({
|
|
58908
|
+
code: "custom",
|
|
58909
|
+
message: `button "${button.idSuffix}" is listed twice`,
|
|
58910
|
+
path: [
|
|
58911
|
+
"buttons",
|
|
58912
|
+
index,
|
|
58913
|
+
"idSuffix"
|
|
58914
|
+
]
|
|
58915
|
+
});
|
|
58916
|
+
suffixes.add(button.idSuffix);
|
|
58917
|
+
if (button.row + button.rowSpan > component.size.rows || button.col + button.colSpan > component.size.cols) {
|
|
58918
|
+
ctx.addIssue({
|
|
58919
|
+
code: "custom",
|
|
58920
|
+
message: `button "${button.idSuffix}" leaves the component`,
|
|
58921
|
+
path: ["buttons", index]
|
|
58922
|
+
});
|
|
58923
|
+
return;
|
|
58924
|
+
}
|
|
58925
|
+
for (let other = 0; other < index; other += 1) {
|
|
58926
|
+
const earlier = component.buttons[other];
|
|
58927
|
+
if (earlier !== void 0 && rectsOverlap(earlier, button)) {
|
|
58928
|
+
ctx.addIssue({
|
|
58929
|
+
code: "custom",
|
|
58930
|
+
message: `buttons "${earlier.idSuffix}" and "${button.idSuffix}" overlap`,
|
|
58931
|
+
path: ["buttons", index]
|
|
58932
|
+
});
|
|
58933
|
+
return;
|
|
58934
|
+
}
|
|
58935
|
+
}
|
|
58936
|
+
});
|
|
58937
|
+
if (component.group?.frame === "divider" && component.buttons.length > 0) ctx.addIssue({
|
|
58938
|
+
code: "custom",
|
|
58939
|
+
message: "a divider component holds no buttons",
|
|
58940
|
+
path: ["buttons"]
|
|
58941
|
+
});
|
|
58942
|
+
});
|
|
58943
|
+
method(object({}), array(RemoteLayoutComponentSchema), { auth: "protected" });
|
|
58305
58944
|
DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
58306
58945
|
kind: "mutation",
|
|
58307
58946
|
auth: "protected"
|
|
@@ -62461,6 +63100,14 @@ var PetFeederDeviceStatusSchema = _enum([
|
|
|
62461
63100
|
"on_batteries"
|
|
62462
63101
|
]);
|
|
62463
63102
|
var gramsPortion = number().int().min(4).max(200);
|
|
63103
|
+
/** A portion REQUESTED of the feeder is a mass the method takes in GRAMS (the
|
|
63104
|
+
* hardware's own unit). The bounds are grams; a caller entering another unit
|
|
63105
|
+
* converts to grams first (`paramMeta`, D972). The STATUS fields above stay
|
|
63106
|
+
* plain grams — they are not readings in the kilogram base. */
|
|
63107
|
+
var gramsParam = gramsPortion.meta(paramMeta({
|
|
63108
|
+
quantity: "mass",
|
|
63109
|
+
unit: "g"
|
|
63110
|
+
}));
|
|
62464
63111
|
object({
|
|
62465
63112
|
/** Food in the TANK (hopper), as the feeder's own sensor reports it
|
|
62466
63113
|
* (`state.food`). A coarse level code, not grams — `0` is empty. The
|
|
@@ -62535,9 +63182,9 @@ object({
|
|
|
62535
63182
|
});
|
|
62536
63183
|
DeviceType.PetFeeder, method(object({
|
|
62537
63184
|
deviceId: number().int().nonnegative(),
|
|
62538
|
-
grams:
|
|
62539
|
-
hopper1:
|
|
62540
|
-
hopper2:
|
|
63185
|
+
grams: gramsParam.optional(),
|
|
63186
|
+
hopper1: gramsParam.optional(),
|
|
63187
|
+
hopper2: gramsParam.optional()
|
|
62541
63188
|
}), _void(), {
|
|
62542
63189
|
kind: "mutation",
|
|
62543
63190
|
auth: "protected"
|
|
@@ -67331,6 +67978,87 @@ var trainingCapability = {
|
|
|
67331
67978
|
})
|
|
67332
67979
|
}
|
|
67333
67980
|
};
|
|
67981
|
+
var btn = (idSuffix, row, col, init) => ({
|
|
67982
|
+
idSuffix,
|
|
67983
|
+
row,
|
|
67984
|
+
col,
|
|
67985
|
+
rowSpan: 1,
|
|
67986
|
+
colSpan: 1,
|
|
67987
|
+
...init
|
|
67988
|
+
});
|
|
67989
|
+
function rocker(id, name, it, frame, title, buttons, size) {
|
|
67990
|
+
return {
|
|
67991
|
+
id,
|
|
67992
|
+
name,
|
|
67993
|
+
nameI18n: {
|
|
67994
|
+
en: name,
|
|
67995
|
+
it
|
|
67996
|
+
},
|
|
67997
|
+
icon: frame === "rocker-v" ? "chevrons-up-down" : "chevrons-left-right",
|
|
67998
|
+
category: id.includes("channel") || id.includes("volume") ? "volume" : "navigation",
|
|
67999
|
+
size,
|
|
68000
|
+
group: title === null ? { frame } : {
|
|
68001
|
+
frame,
|
|
68002
|
+
title
|
|
68003
|
+
},
|
|
68004
|
+
buttons
|
|
68005
|
+
};
|
|
68006
|
+
}
|
|
68007
|
+
btn("power", 0, 0, {
|
|
68008
|
+
role: "power",
|
|
68009
|
+
shape: "round",
|
|
68010
|
+
tone: "danger"
|
|
68011
|
+
}), btn("up", 0, 1, { role: "up" }), btn("left", 1, 0, { role: "left" }), btn("ok", 1, 1, {
|
|
68012
|
+
role: "ok",
|
|
68013
|
+
shape: "round",
|
|
68014
|
+
tone: "accent"
|
|
68015
|
+
}), 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, {
|
|
68016
|
+
role: "volume_up",
|
|
68017
|
+
shape: "pill"
|
|
68018
|
+
}), btn("down", 1, 0, {
|
|
68019
|
+
role: "volume_down",
|
|
68020
|
+
shape: "pill"
|
|
68021
|
+
})], {
|
|
68022
|
+
rows: 2,
|
|
68023
|
+
cols: 1
|
|
68024
|
+
}), rocker("core:rocker-channel-v", "Channel rocker", "Bilanciere canali", "rocker-v", "CH", [btn("up", 0, 0, {
|
|
68025
|
+
role: "channel_up",
|
|
68026
|
+
shape: "pill"
|
|
68027
|
+
}), btn("down", 1, 0, {
|
|
68028
|
+
role: "channel_down",
|
|
68029
|
+
shape: "pill"
|
|
68030
|
+
})], {
|
|
68031
|
+
rows: 2,
|
|
68032
|
+
cols: 1
|
|
68033
|
+
}), rocker("core:rocker-h", "Minus / plus rocker", "Bilanciere meno / più", "rocker-h", null, [btn("minus", 0, 0, {
|
|
68034
|
+
role: "custom:minus",
|
|
68035
|
+
label: "−",
|
|
68036
|
+
shape: "pill"
|
|
68037
|
+
}), btn("plus", 0, 1, {
|
|
68038
|
+
role: "custom:plus",
|
|
68039
|
+
label: "+",
|
|
68040
|
+
shape: "pill"
|
|
68041
|
+
})], {
|
|
68042
|
+
rows: 1,
|
|
68043
|
+
cols: 2
|
|
68044
|
+
}), [...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, {
|
|
68045
|
+
role: "custom:color_red",
|
|
68046
|
+
tone: "red"
|
|
68047
|
+
}), btn("green", 0, 1, {
|
|
68048
|
+
role: "custom:color_green",
|
|
68049
|
+
tone: "green"
|
|
68050
|
+
}), btn("yellow", 0, 2, {
|
|
68051
|
+
role: "custom:color_yellow",
|
|
68052
|
+
tone: "yellow"
|
|
68053
|
+
}), btn("blue", 0, 3, {
|
|
68054
|
+
role: "custom:color_blue",
|
|
68055
|
+
tone: "blue"
|
|
68056
|
+
}), 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" }), [
|
|
68057
|
+
1,
|
|
68058
|
+
2,
|
|
68059
|
+
3,
|
|
68060
|
+
4
|
|
68061
|
+
].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" });
|
|
67334
68062
|
discriminatedUnion("kind", [object({
|
|
67335
68063
|
kind: literal("raw"),
|
|
67336
68064
|
timings: array(number().int()),
|
|
@@ -75195,6 +75923,13 @@ Object.freeze({
|
|
|
75195
75923
|
access: "create",
|
|
75196
75924
|
role: "admin"
|
|
75197
75925
|
},
|
|
75926
|
+
"remoteLayoutComponents.listComponents": {
|
|
75927
|
+
capName: "remote-layout-components",
|
|
75928
|
+
capScope: "system",
|
|
75929
|
+
addonId: null,
|
|
75930
|
+
access: "view",
|
|
75931
|
+
role: "admin"
|
|
75932
|
+
},
|
|
75198
75933
|
"runningState.getStatus": {
|
|
75199
75934
|
capName: "running-state",
|
|
75200
75935
|
capScope: "device",
|
|
@@ -79238,7 +79973,8 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
79238
79973
|
min: 4,
|
|
79239
79974
|
max: 200,
|
|
79240
79975
|
step: 1,
|
|
79241
|
-
unit: "g"
|
|
79976
|
+
unit: "g",
|
|
79977
|
+
quantity: "mass"
|
|
79242
79978
|
},
|
|
79243
79979
|
optional: true
|
|
79244
79980
|
}]
|
|
@@ -79257,7 +79993,8 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
79257
79993
|
min: 4,
|
|
79258
79994
|
max: 200,
|
|
79259
79995
|
step: 1,
|
|
79260
|
-
unit: "g"
|
|
79996
|
+
unit: "g",
|
|
79997
|
+
quantity: "mass"
|
|
79261
79998
|
},
|
|
79262
79999
|
optional: true
|
|
79263
80000
|
}, {
|
|
@@ -79268,7 +80005,8 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
79268
80005
|
min: 4,
|
|
79269
80006
|
max: 200,
|
|
79270
80007
|
step: 1,
|
|
79271
|
-
unit: "g"
|
|
80008
|
+
unit: "g",
|
|
80009
|
+
quantity: "mass"
|
|
79272
80010
|
},
|
|
79273
80011
|
optional: true
|
|
79274
80012
|
}]
|
|
@@ -81368,6 +82106,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
81368
82106
|
"recording-export": system("recording exports — requested from the timeline, not an automation step"),
|
|
81369
82107
|
records: system(INTERNAL),
|
|
81370
82108
|
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
82109
|
+
"remote-layout-components": system("the palette of the remote template editor — read-only data, never actuated"),
|
|
81371
82110
|
"server-management": system(CLUSTER),
|
|
81372
82111
|
"settings-store": system(INTERNAL),
|
|
81373
82112
|
"smtp-provider": system(INTERNAL),
|