@camstack/addon-google-services 0.2.29 → 0.2.31

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.
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  let node_crypto = require("node:crypto");
6
- //#region ../types/dist/event-category-fDPduoeC.mjs
6
+ //#region ../types/dist/event-category-DHXxB8t9.mjs
7
7
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
8
8
  EventCategory["SystemBoot"] = "system.boot";
9
9
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -299,7 +299,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
299
299
  * TRANSITION into that state (never per dispatch), and the node is dropped
300
300
  * from the placement candidate set for as long as it holds.
301
301
  *
302
- * This exists because the state was previously invisible: little-unraid
302
+ * This exists because the state was previously invisible: agent-a
303
303
  * absorbed 283k inference errors in a day while still being handed cameras,
304
304
  * and nothing in the system said so.
305
305
  *
@@ -475,6 +475,10 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
475
475
  * on the device detail page.
476
476
  */
477
477
  EventCategory["DoorbellOnPressed"] = "doorbell.onPressed";
478
+ /** Mirrors `runningStateCapability.events.onStarted`. */
479
+ EventCategory["RunningStarted"] = "running.started";
480
+ /** Mirrors `runningStateCapability.events.onFinished`. */
481
+ EventCategory["RunningFinished"] = "running.finished";
478
482
  /**
479
483
  * Cap event fired by every device that registers the `event-emitter`
480
484
  * capability. Mirrors `eventEmitterCapability.events.onEvent`. Carries
@@ -5567,7 +5571,7 @@ var ZodIssueCode = {
5567
5571
  var ZodFirstPartyTypeKind;
5568
5572
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5569
5573
  //#endregion
5570
- //#region ../types/dist/sleep-CHIEEJkY.mjs
5574
+ //#region ../types/dist/sleep-BErAxhul.mjs
5571
5575
  /**
5572
5576
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5573
5577
  * window to float samples (D455).
@@ -5906,7 +5910,7 @@ Object.fromEntries([
5906
5910
  * `hydrateSchema` to skip the `value` injection for structural-only fields.
5907
5911
  */
5908
5912
  function isValuelessField(field) {
5909
- return field.type === "separator" || field.type === "info" || field.type === "qr-code" || field.type === "button" || field.type === "object-array" || field.type === "widget" || field.type === "addon-action-button" || field.type === "device-action-button";
5913
+ return field.type === "separator" || field.type === "info" || field.type === "qr-code" || field.type === "button" || field.type === "object-array" || field.type === "widget" || field.type === "addon-action-button" || field.type === "device-action-button" || field.type === "account-sign-in" || field.type === "secret-presence";
5910
5914
  }
5911
5915
  function hydrateSchema(schema, values, options = {}) {
5912
5916
  return {
@@ -8774,6 +8778,1980 @@ method(object({ deviceId: number() }), array(StreamSourceEntrySchema)), method(o
8774
8778
  kind: "mutation",
8775
8779
  auth: "admin"
8776
8780
  }), method(object({ deviceId: number() }), unknown().nullable()), method(object({ deviceId: number() }), RawStateResultSchema.nullable(), { auth: "protected" });
8781
+ Object.freeze({ "doorbell": "lastPressedAt" });
8782
+ /** Every capability name, so addon code can check a name without the schema graph. */
8783
+ var CAP_NAMES = Object.freeze([
8784
+ "accessories",
8785
+ "addon-pages",
8786
+ "addon-pages-source",
8787
+ "addon-routes",
8788
+ "addon-settings",
8789
+ "addon-widgets",
8790
+ "addon-widgets-source",
8791
+ "addons",
8792
+ "admin-ui",
8793
+ "air-quality-sensor",
8794
+ "alarm-panel",
8795
+ "alerts",
8796
+ "ambient-light-sensor",
8797
+ "audio-analysis",
8798
+ "audio-analyzer",
8799
+ "audio-codec",
8800
+ "audio-metrics",
8801
+ "auth-provider",
8802
+ "automation-control",
8803
+ "backup",
8804
+ "battery",
8805
+ "binary",
8806
+ "brightness",
8807
+ "broker",
8808
+ "button",
8809
+ "calendar-source",
8810
+ "calendars",
8811
+ "camera-credentials",
8812
+ "camera-grid-layout",
8813
+ "camera-pipeline-config",
8814
+ "camera-streams",
8815
+ "carbon-monoxide",
8816
+ "climate-control",
8817
+ "color",
8818
+ "composer",
8819
+ "connection-test",
8820
+ "connectivity",
8821
+ "consumables",
8822
+ "contact",
8823
+ "control",
8824
+ "core-blocks",
8825
+ "cover",
8826
+ "custom-model-registry",
8827
+ "data-store-provider",
8828
+ "database-snapshot",
8829
+ "day-night",
8830
+ "decoder",
8831
+ "detection-pipeline",
8832
+ "device-admin-link",
8833
+ "device-adoption",
8834
+ "device-credentials",
8835
+ "device-discovery",
8836
+ "device-export",
8837
+ "device-extension",
8838
+ "device-history",
8839
+ "device-manager",
8840
+ "device-ops",
8841
+ "device-provider",
8842
+ "device-removal-hook",
8843
+ "device-state",
8844
+ "device-status",
8845
+ "dishwasher",
8846
+ "display-palette",
8847
+ "doorbell",
8848
+ "embedding-encoder",
8849
+ "enum-sensor",
8850
+ "event-emitter",
8851
+ "face-gallery",
8852
+ "failure-contribution",
8853
+ "fan-control",
8854
+ "feature-probe",
8855
+ "filesystem-browse",
8856
+ "flood",
8857
+ "gas",
8858
+ "heating-valve",
8859
+ "humidifier",
8860
+ "humidity-sensor",
8861
+ "image",
8862
+ "image-settings",
8863
+ "integrations",
8864
+ "intercom",
8865
+ "keychain",
8866
+ "keychain-admin",
8867
+ "lawn-mower-control",
8868
+ "llm",
8869
+ "llm-runtime",
8870
+ "load-contribution",
8871
+ "local-network",
8872
+ "lock-control",
8873
+ "log-channels",
8874
+ "log-destination",
8875
+ "login-method",
8876
+ "media-player",
8877
+ "mesh-network",
8878
+ "metrics-provider",
8879
+ "model-convert",
8880
+ "model-distributor",
8881
+ "motion",
8882
+ "motion-detection",
8883
+ "motion-trigger",
8884
+ "motion-zones",
8885
+ "mqtt-broker",
8886
+ "native-object-detection",
8887
+ "navigation",
8888
+ "network-access",
8889
+ "network-link",
8890
+ "network-quality",
8891
+ "node-certificates",
8892
+ "nodes",
8893
+ "notification-output",
8894
+ "notification-rules",
8895
+ "notifier",
8896
+ "numeric-sensor",
8897
+ "oauth-integration",
8898
+ "oidc-connections",
8899
+ "osd",
8900
+ "osd-manager",
8901
+ "pet-feeder",
8902
+ "pipeline-analytics",
8903
+ "pipeline-executor",
8904
+ "pipeline-orchestrator",
8905
+ "pipeline-runner",
8906
+ "plate-gallery",
8907
+ "platform-probe",
8908
+ "power-meter",
8909
+ "presence",
8910
+ "pressure-sensor",
8911
+ "privacy-mask",
8912
+ "ptz",
8913
+ "ptz-autotrack",
8914
+ "reboot",
8915
+ "record-entries",
8916
+ "recording",
8917
+ "recording-archive",
8918
+ "recording-export",
8919
+ "recording-onboard",
8920
+ "recording-signal",
8921
+ "records",
8922
+ "running-state",
8923
+ "scene-monitor",
8924
+ "script-runner",
8925
+ "server-management",
8926
+ "settings-store",
8927
+ "smoke",
8928
+ "smtp-provider",
8929
+ "snapshot",
8930
+ "sso-bridge",
8931
+ "storage",
8932
+ "storage-admin",
8933
+ "storage-evictable",
8934
+ "storage-migration",
8935
+ "storage-occupancy",
8936
+ "storage-provider",
8937
+ "stream-broker",
8938
+ "stream-catalog",
8939
+ "stream-params",
8940
+ "stream-signals",
8941
+ "switch",
8942
+ "system",
8943
+ "tamper",
8944
+ "temperature-sensor",
8945
+ "terminal-session",
8946
+ "toast",
8947
+ "training",
8948
+ "training-provider",
8949
+ "turn-provider",
8950
+ "update",
8951
+ "user-management",
8952
+ "user-passkeys",
8953
+ "vacuum-control",
8954
+ "valve",
8955
+ "vector-store",
8956
+ "vibration",
8957
+ "videoclips",
8958
+ "viewer-ui",
8959
+ "water-heater",
8960
+ "weather",
8961
+ "webrtc-session",
8962
+ "zone-analytics",
8963
+ "zone-rules",
8964
+ "zones"
8965
+ ]);
8966
+ Object.freeze({
8967
+ "air-quality-sensor": [
8968
+ {
8969
+ "path": "co2Ppm",
8970
+ "valueType": "number"
8971
+ },
8972
+ {
8973
+ "path": "vocPpb",
8974
+ "valueType": "number"
8975
+ },
8976
+ {
8977
+ "path": "pm25",
8978
+ "valueType": "number"
8979
+ },
8980
+ {
8981
+ "path": "pm10",
8982
+ "valueType": "number"
8983
+ },
8984
+ {
8985
+ "path": "aqi",
8986
+ "valueType": "number"
8987
+ },
8988
+ {
8989
+ "path": "unit",
8990
+ "valueType": "string"
8991
+ },
8992
+ {
8993
+ "path": "precision",
8994
+ "valueType": "number"
8995
+ }
8996
+ ],
8997
+ "alarm-panel": [
8998
+ {
8999
+ "path": "state",
9000
+ "valueType": "enum",
9001
+ "enumValues": [
9002
+ "disarmed",
9003
+ "armed_home",
9004
+ "armed_away",
9005
+ "armed_night",
9006
+ "armed_vacation",
9007
+ "armed_custom_bypass",
9008
+ "arming",
9009
+ "disarming",
9010
+ "pending",
9011
+ "triggered"
9012
+ ]
9013
+ },
9014
+ {
9015
+ "path": "targetMode",
9016
+ "valueType": "enum",
9017
+ "enumValues": [
9018
+ "home",
9019
+ "away",
9020
+ "night",
9021
+ "vacation",
9022
+ "custom_bypass"
9023
+ ]
9024
+ },
9025
+ {
9026
+ "path": "requiresCode",
9027
+ "valueType": "boolean"
9028
+ }
9029
+ ],
9030
+ "ambient-light-sensor": [
9031
+ {
9032
+ "path": "lux",
9033
+ "valueType": "number"
9034
+ },
9035
+ {
9036
+ "path": "unit",
9037
+ "valueType": "string"
9038
+ },
9039
+ {
9040
+ "path": "precision",
9041
+ "valueType": "number"
9042
+ }
9043
+ ],
9044
+ "audio-metrics": [
9045
+ {
9046
+ "path": "ts",
9047
+ "valueType": "number"
9048
+ },
9049
+ {
9050
+ "path": "windowSec",
9051
+ "valueType": "number"
9052
+ },
9053
+ {
9054
+ "path": "level.rms",
9055
+ "valueType": "number"
9056
+ },
9057
+ {
9058
+ "path": "level.dbfs",
9059
+ "valueType": "number"
9060
+ },
9061
+ {
9062
+ "path": "peakDbfs",
9063
+ "valueType": "number"
9064
+ },
9065
+ {
9066
+ "path": "avgDbfs",
9067
+ "valueType": "number"
9068
+ },
9069
+ {
9070
+ "path": "current.className",
9071
+ "valueType": "string"
9072
+ },
9073
+ {
9074
+ "path": "current.score",
9075
+ "valueType": "number"
9076
+ },
9077
+ {
9078
+ "path": "current.timestamp",
9079
+ "valueType": "number"
9080
+ }
9081
+ ],
9082
+ "automation-control": [
9083
+ {
9084
+ "path": "enabled",
9085
+ "valueType": "boolean"
9086
+ },
9087
+ {
9088
+ "path": "isRunning",
9089
+ "valueType": "boolean"
9090
+ },
9091
+ {
9092
+ "path": "lastTriggeredAt",
9093
+ "valueType": "number"
9094
+ },
9095
+ {
9096
+ "path": "lastError",
9097
+ "valueType": "string"
9098
+ }
9099
+ ],
9100
+ "battery": [
9101
+ {
9102
+ "path": "percentage",
9103
+ "valueType": "number"
9104
+ },
9105
+ {
9106
+ "path": "charging",
9107
+ "valueType": "enum",
9108
+ "enumValues": [
9109
+ "dc",
9110
+ "solar",
9111
+ "none",
9112
+ "unknown"
9113
+ ]
9114
+ },
9115
+ {
9116
+ "path": "sleeping",
9117
+ "valueType": "boolean"
9118
+ },
9119
+ {
9120
+ "path": "lastUpdated",
9121
+ "valueType": "number"
9122
+ },
9123
+ {
9124
+ "path": "lastContactAt",
9125
+ "valueType": "number"
9126
+ },
9127
+ {
9128
+ "path": "lastFullRefreshAt",
9129
+ "valueType": "number"
9130
+ },
9131
+ {
9132
+ "path": "binary",
9133
+ "valueType": "boolean"
9134
+ }
9135
+ ],
9136
+ "binary": [{
9137
+ "path": "on",
9138
+ "valueType": "boolean"
9139
+ }],
9140
+ "brightness": [{
9141
+ "path": "percentage",
9142
+ "valueType": "number"
9143
+ }],
9144
+ "broker": [{
9145
+ "path": "brokerCount",
9146
+ "valueType": "number"
9147
+ }, {
9148
+ "path": "connectedCount",
9149
+ "valueType": "number"
9150
+ }],
9151
+ "camera-credentials": [
9152
+ {
9153
+ "path": "host",
9154
+ "valueType": "string"
9155
+ },
9156
+ {
9157
+ "path": "port",
9158
+ "valueType": "number"
9159
+ },
9160
+ {
9161
+ "path": "onvifPort",
9162
+ "valueType": "number"
9163
+ },
9164
+ {
9165
+ "path": "rtspPort",
9166
+ "valueType": "number"
9167
+ },
9168
+ {
9169
+ "path": "https",
9170
+ "valueType": "boolean"
9171
+ },
9172
+ {
9173
+ "path": "hasUsername",
9174
+ "valueType": "boolean"
9175
+ },
9176
+ {
9177
+ "path": "hasPassword",
9178
+ "valueType": "boolean"
9179
+ },
9180
+ {
9181
+ "path": "onvifProfile",
9182
+ "valueType": "string"
9183
+ }
9184
+ ],
9185
+ "camera-streams": [
9186
+ {
9187
+ "path": "online",
9188
+ "valueType": "boolean"
9189
+ },
9190
+ {
9191
+ "path": "slotStatuses.high",
9192
+ "valueType": "enum",
9193
+ "enumValues": [
9194
+ "unassigned",
9195
+ "idle",
9196
+ "connecting",
9197
+ "streaming",
9198
+ "error"
9199
+ ]
9200
+ },
9201
+ {
9202
+ "path": "slotStatuses.mid",
9203
+ "valueType": "enum",
9204
+ "enumValues": [
9205
+ "unassigned",
9206
+ "idle",
9207
+ "connecting",
9208
+ "streaming",
9209
+ "error"
9210
+ ]
9211
+ },
9212
+ {
9213
+ "path": "slotStatuses.low",
9214
+ "valueType": "enum",
9215
+ "enumValues": [
9216
+ "unassigned",
9217
+ "idle",
9218
+ "connecting",
9219
+ "streaming",
9220
+ "error"
9221
+ ]
9222
+ },
9223
+ {
9224
+ "path": "slotErrors.high",
9225
+ "valueType": "string"
9226
+ },
9227
+ {
9228
+ "path": "slotErrors.mid",
9229
+ "valueType": "string"
9230
+ },
9231
+ {
9232
+ "path": "slotErrors.low",
9233
+ "valueType": "string"
9234
+ }
9235
+ ],
9236
+ "carbon-monoxide": [{
9237
+ "path": "detected",
9238
+ "valueType": "boolean"
9239
+ }],
9240
+ "climate-control": [
9241
+ {
9242
+ "path": "mode",
9243
+ "valueType": "enum",
9244
+ "enumValues": [
9245
+ "off",
9246
+ "heat",
9247
+ "cool",
9248
+ "auto",
9249
+ "heat_cool",
9250
+ "fan_only",
9251
+ "dry"
9252
+ ]
9253
+ },
9254
+ {
9255
+ "path": "fanMode",
9256
+ "valueType": "string"
9257
+ },
9258
+ {
9259
+ "path": "preset",
9260
+ "valueType": "string"
9261
+ },
9262
+ {
9263
+ "path": "target",
9264
+ "valueType": "number"
9265
+ },
9266
+ {
9267
+ "path": "targetHigh",
9268
+ "valueType": "number"
9269
+ },
9270
+ {
9271
+ "path": "targetLow",
9272
+ "valueType": "number"
9273
+ },
9274
+ {
9275
+ "path": "targetHumidity",
9276
+ "valueType": "number"
9277
+ },
9278
+ {
9279
+ "path": "currentTemp",
9280
+ "valueType": "number"
9281
+ },
9282
+ {
9283
+ "path": "currentHumidity",
9284
+ "valueType": "number"
9285
+ },
9286
+ {
9287
+ "path": "swingVertical",
9288
+ "valueType": "boolean"
9289
+ },
9290
+ {
9291
+ "path": "swingHorizontal",
9292
+ "valueType": "boolean"
9293
+ },
9294
+ {
9295
+ "path": "minTemp",
9296
+ "valueType": "number"
9297
+ },
9298
+ {
9299
+ "path": "maxTemp",
9300
+ "valueType": "number"
9301
+ },
9302
+ {
9303
+ "path": "tempStep",
9304
+ "valueType": "number"
9305
+ }
9306
+ ],
9307
+ "color": [
9308
+ {
9309
+ "path": "mode",
9310
+ "valueType": "enum",
9311
+ "enumValues": [
9312
+ "rgb",
9313
+ "hsv",
9314
+ "mired"
9315
+ ]
9316
+ },
9317
+ {
9318
+ "path": "rgb.r",
9319
+ "valueType": "number"
9320
+ },
9321
+ {
9322
+ "path": "rgb.g",
9323
+ "valueType": "number"
9324
+ },
9325
+ {
9326
+ "path": "rgb.b",
9327
+ "valueType": "number"
9328
+ },
9329
+ {
9330
+ "path": "hsv.h",
9331
+ "valueType": "number"
9332
+ },
9333
+ {
9334
+ "path": "hsv.s",
9335
+ "valueType": "number"
9336
+ },
9337
+ {
9338
+ "path": "hsv.v",
9339
+ "valueType": "number"
9340
+ },
9341
+ {
9342
+ "path": "mireds",
9343
+ "valueType": "number"
9344
+ }
9345
+ ],
9346
+ "connectivity": [{
9347
+ "path": "connected",
9348
+ "valueType": "boolean"
9349
+ }],
9350
+ "contact": [{
9351
+ "path": "entryOpen",
9352
+ "valueType": "boolean"
9353
+ }],
9354
+ "control": [
9355
+ {
9356
+ "path": "kind",
9357
+ "valueType": "enum",
9358
+ "enumValues": [
9359
+ "numeric",
9360
+ "select",
9361
+ "text",
9362
+ "datetime"
9363
+ ]
9364
+ },
9365
+ {
9366
+ "path": "unit",
9367
+ "valueType": "string"
9368
+ },
9369
+ {
9370
+ "path": "min",
9371
+ "valueType": "number"
9372
+ },
9373
+ {
9374
+ "path": "max",
9375
+ "valueType": "number"
9376
+ },
9377
+ {
9378
+ "path": "step",
9379
+ "valueType": "number"
9380
+ },
9381
+ {
9382
+ "path": "precision",
9383
+ "valueType": "number"
9384
+ },
9385
+ {
9386
+ "path": "format",
9387
+ "valueType": "enum",
9388
+ "enumValues": [
9389
+ "date",
9390
+ "time",
9391
+ "datetime"
9392
+ ]
9393
+ }
9394
+ ],
9395
+ "cover": [
9396
+ {
9397
+ "path": "state",
9398
+ "valueType": "enum",
9399
+ "enumValues": [
9400
+ "open",
9401
+ "opening",
9402
+ "closing",
9403
+ "closed",
9404
+ "stopped"
9405
+ ]
9406
+ },
9407
+ {
9408
+ "path": "position",
9409
+ "valueType": "number"
9410
+ },
9411
+ {
9412
+ "path": "tiltPosition",
9413
+ "valueType": "number"
9414
+ }
9415
+ ],
9416
+ "day-night": [
9417
+ {
9418
+ "path": "mode",
9419
+ "valueType": "enum",
9420
+ "enumValues": [
9421
+ "auto",
9422
+ "day",
9423
+ "night",
9424
+ "schedule"
9425
+ ]
9426
+ },
9427
+ {
9428
+ "path": "sensitivity",
9429
+ "valueType": "number"
9430
+ },
9431
+ {
9432
+ "path": "switchDelaySec",
9433
+ "valueType": "number"
9434
+ }
9435
+ ],
9436
+ "device-adoption": [
9437
+ {
9438
+ "path": "lastDiscoveryAt",
9439
+ "valueType": "number"
9440
+ },
9441
+ {
9442
+ "path": "candidateCount",
9443
+ "valueType": "number"
9444
+ },
9445
+ {
9446
+ "path": "adoptedCount",
9447
+ "valueType": "number"
9448
+ },
9449
+ {
9450
+ "path": "lastError",
9451
+ "valueType": "string"
9452
+ }
9453
+ ],
9454
+ "device-discovery": [{
9455
+ "path": "lastDiscoveryAt",
9456
+ "valueType": "number"
9457
+ }, {
9458
+ "path": "lastError",
9459
+ "valueType": "string"
9460
+ }],
9461
+ "device-export": [
9462
+ {
9463
+ "path": "linkState",
9464
+ "valueType": "enum",
9465
+ "enumValues": [
9466
+ "unlinked",
9467
+ "linked",
9468
+ "error"
9469
+ ]
9470
+ },
9471
+ {
9472
+ "path": "exposedDeviceCount",
9473
+ "valueType": "number"
9474
+ },
9475
+ {
9476
+ "path": "error",
9477
+ "valueType": "string"
9478
+ },
9479
+ {
9480
+ "path": "setup.qr",
9481
+ "valueType": "string"
9482
+ },
9483
+ {
9484
+ "path": "setup.note",
9485
+ "valueType": "string"
9486
+ }
9487
+ ],
9488
+ "device-status": [{
9489
+ "path": "online",
9490
+ "valueType": "boolean"
9491
+ }],
9492
+ "dishwasher": [
9493
+ {
9494
+ "path": "availability",
9495
+ "valueType": "enum",
9496
+ "enumValues": [
9497
+ "available",
9498
+ "offline",
9499
+ "description-missing"
9500
+ ]
9501
+ },
9502
+ {
9503
+ "path": "state",
9504
+ "valueType": "enum",
9505
+ "enumValues": [
9506
+ "idle",
9507
+ "running",
9508
+ "paused",
9509
+ "finished",
9510
+ "error",
9511
+ "unavailable"
9512
+ ]
9513
+ },
9514
+ {
9515
+ "path": "operationState",
9516
+ "valueType": "enum",
9517
+ "enumValues": [
9518
+ "Inactive",
9519
+ "Ready",
9520
+ "DelayedStart",
9521
+ "Run",
9522
+ "Pause",
9523
+ "ActionRequired",
9524
+ "Finished",
9525
+ "Error",
9526
+ "Aborting"
9527
+ ]
9528
+ },
9529
+ {
9530
+ "path": "program",
9531
+ "valueType": "string"
9532
+ },
9533
+ {
9534
+ "path": "selectedProgram",
9535
+ "valueType": "string"
9536
+ },
9537
+ {
9538
+ "path": "remainingSeconds",
9539
+ "valueType": "number"
9540
+ },
9541
+ {
9542
+ "path": "delayedStartSeconds",
9543
+ "valueType": "number"
9544
+ },
9545
+ {
9546
+ "path": "progressPercent",
9547
+ "valueType": "number"
9548
+ },
9549
+ {
9550
+ "path": "doorOpen",
9551
+ "valueType": "boolean"
9552
+ },
9553
+ {
9554
+ "path": "doorLocked",
9555
+ "valueType": "boolean"
9556
+ },
9557
+ {
9558
+ "path": "remoteStartAllowed",
9559
+ "valueType": "boolean"
9560
+ },
9561
+ {
9562
+ "path": "remoteControlActive",
9563
+ "valueType": "boolean"
9564
+ },
9565
+ {
9566
+ "path": "localControlActive",
9567
+ "valueType": "boolean"
9568
+ },
9569
+ {
9570
+ "path": "powerOn",
9571
+ "valueType": "boolean"
9572
+ },
9573
+ {
9574
+ "path": "powerState",
9575
+ "valueType": "string"
9576
+ },
9577
+ {
9578
+ "path": "filterCleaningDue",
9579
+ "valueType": "boolean"
9580
+ },
9581
+ {
9582
+ "path": "machineCareDue",
9583
+ "valueType": "boolean"
9584
+ },
9585
+ {
9586
+ "path": "machineCareRemainingRuns",
9587
+ "valueType": "number"
9588
+ },
9589
+ {
9590
+ "path": "halfLoad",
9591
+ "valueType": "boolean"
9592
+ },
9593
+ {
9594
+ "path": "hygienePlus",
9595
+ "valueType": "boolean"
9596
+ },
9597
+ {
9598
+ "path": "extraDry",
9599
+ "valueType": "boolean"
9600
+ },
9601
+ {
9602
+ "path": "intensiveZone",
9603
+ "valueType": "boolean"
9604
+ },
9605
+ {
9606
+ "path": "varioSpeedPlus",
9607
+ "valueType": "boolean"
9608
+ },
9609
+ {
9610
+ "path": "childLock",
9611
+ "valueType": "boolean"
9612
+ },
9613
+ {
9614
+ "path": "errorCode",
9615
+ "valueType": "number"
9616
+ },
9617
+ {
9618
+ "path": "errorLabel",
9619
+ "valueType": "string"
9620
+ }
9621
+ ],
9622
+ "doorbell": [{
9623
+ "path": "lastPressedAt",
9624
+ "valueType": "number"
9625
+ }, {
9626
+ "path": "pressCountSinceStart",
9627
+ "valueType": "number"
9628
+ }],
9629
+ "enum-sensor": [{
9630
+ "path": "value",
9631
+ "valueType": "string"
9632
+ }, {
9633
+ "path": "format",
9634
+ "valueType": "enum",
9635
+ "enumValues": [
9636
+ "date",
9637
+ "time",
9638
+ "datetime"
9639
+ ]
9640
+ }],
9641
+ "event-emitter": [
9642
+ {
9643
+ "path": "lastEvent.deviceId",
9644
+ "valueType": "number"
9645
+ },
9646
+ {
9647
+ "path": "lastEvent.eventType",
9648
+ "valueType": "string"
9649
+ },
9650
+ {
9651
+ "path": "lastEvent.timestamp",
9652
+ "valueType": "number"
9653
+ },
9654
+ {
9655
+ "path": "lastEvent.seq",
9656
+ "valueType": "number"
9657
+ },
9658
+ {
9659
+ "path": "eventCountSinceStart",
9660
+ "valueType": "number"
9661
+ }
9662
+ ],
9663
+ "fan-control": [
9664
+ {
9665
+ "path": "percentage",
9666
+ "valueType": "number"
9667
+ },
9668
+ {
9669
+ "path": "percentageStep",
9670
+ "valueType": "number"
9671
+ },
9672
+ {
9673
+ "path": "preset",
9674
+ "valueType": "string"
9675
+ },
9676
+ {
9677
+ "path": "direction",
9678
+ "valueType": "enum",
9679
+ "enumValues": ["forward", "reverse"]
9680
+ },
9681
+ {
9682
+ "path": "oscillating",
9683
+ "valueType": "boolean"
9684
+ }
9685
+ ],
9686
+ "feature-probe": [
9687
+ {
9688
+ "path": "deviceType",
9689
+ "valueType": "string"
9690
+ },
9691
+ {
9692
+ "path": "model",
9693
+ "valueType": "string"
9694
+ },
9695
+ {
9696
+ "path": "channelCount",
9697
+ "valueType": "number"
9698
+ },
9699
+ {
9700
+ "path": "lastProbedAt",
9701
+ "valueType": "number"
9702
+ }
9703
+ ],
9704
+ "flood": [{
9705
+ "path": "flooded",
9706
+ "valueType": "boolean"
9707
+ }],
9708
+ "gas": [{
9709
+ "path": "detected",
9710
+ "valueType": "boolean"
9711
+ }],
9712
+ "heating-valve": [{
9713
+ "path": "position",
9714
+ "valueType": "number"
9715
+ }],
9716
+ "humidifier": [
9717
+ {
9718
+ "path": "on",
9719
+ "valueType": "boolean"
9720
+ },
9721
+ {
9722
+ "path": "currentHumidity",
9723
+ "valueType": "number"
9724
+ },
9725
+ {
9726
+ "path": "targetHumidity",
9727
+ "valueType": "number"
9728
+ },
9729
+ {
9730
+ "path": "mode",
9731
+ "valueType": "string"
9732
+ },
9733
+ {
9734
+ "path": "action",
9735
+ "valueType": "string"
9736
+ },
9737
+ {
9738
+ "path": "minHumidity",
9739
+ "valueType": "number"
9740
+ },
9741
+ {
9742
+ "path": "maxHumidity",
9743
+ "valueType": "number"
9744
+ }
9745
+ ],
9746
+ "humidity-sensor": [
9747
+ {
9748
+ "path": "percent",
9749
+ "valueType": "number"
9750
+ },
9751
+ {
9752
+ "path": "unit",
9753
+ "valueType": "string"
9754
+ },
9755
+ {
9756
+ "path": "precision",
9757
+ "valueType": "number"
9758
+ }
9759
+ ],
9760
+ "image": [{
9761
+ "path": "url",
9762
+ "valueType": "string"
9763
+ }, {
9764
+ "path": "lastUpdated",
9765
+ "valueType": "number"
9766
+ }],
9767
+ "image-settings": [
9768
+ {
9769
+ "path": "brightness",
9770
+ "valueType": "number"
9771
+ },
9772
+ {
9773
+ "path": "contrast",
9774
+ "valueType": "number"
9775
+ },
9776
+ {
9777
+ "path": "saturation",
9778
+ "valueType": "number"
9779
+ },
9780
+ {
9781
+ "path": "sharpness",
9782
+ "valueType": "number"
9783
+ },
9784
+ {
9785
+ "path": "mirror",
9786
+ "valueType": "boolean"
9787
+ },
9788
+ {
9789
+ "path": "flip",
9790
+ "valueType": "boolean"
9791
+ },
9792
+ {
9793
+ "path": "rotate",
9794
+ "valueType": "enum",
9795
+ "enumValues": [
9796
+ "0",
9797
+ "90",
9798
+ "180",
9799
+ "270"
9800
+ ]
9801
+ },
9802
+ {
9803
+ "path": "whiteBalance",
9804
+ "valueType": "enum",
9805
+ "enumValues": ["auto", "manual"]
9806
+ },
9807
+ {
9808
+ "path": "warmth",
9809
+ "valueType": "number"
9810
+ },
9811
+ {
9812
+ "path": "exposureMode",
9813
+ "valueType": "enum",
9814
+ "enumValues": ["auto", "manual"]
9815
+ },
9816
+ {
9817
+ "path": "backlightMode",
9818
+ "valueType": "enum",
9819
+ "enumValues": [
9820
+ "off",
9821
+ "blc",
9822
+ "wdr",
9823
+ "hlc"
9824
+ ]
9825
+ }
9826
+ ],
9827
+ "intercom": [
9828
+ {
9829
+ "path": "talking",
9830
+ "valueType": "boolean"
9831
+ },
9832
+ {
9833
+ "path": "lastSessionAt",
9834
+ "valueType": "number"
9835
+ },
9836
+ {
9837
+ "path": "ability.sampleRate",
9838
+ "valueType": "number"
9839
+ },
9840
+ {
9841
+ "path": "ability.duplex",
9842
+ "valueType": "enum",
9843
+ "enumValues": ["half", "full"]
9844
+ },
9845
+ {
9846
+ "path": "ability.maxBacklogMs",
9847
+ "valueType": "number"
9848
+ }
9849
+ ],
9850
+ "lawn-mower-control": [
9851
+ {
9852
+ "path": "activity",
9853
+ "valueType": "enum",
9854
+ "enumValues": [
9855
+ "idle",
9856
+ "mowing",
9857
+ "paused",
9858
+ "docked",
9859
+ "error"
9860
+ ]
9861
+ },
9862
+ {
9863
+ "path": "batteryLevel",
9864
+ "valueType": "number"
9865
+ },
9866
+ {
9867
+ "path": "progressPercent",
9868
+ "valueType": "number"
9869
+ },
9870
+ {
9871
+ "path": "currentCode",
9872
+ "valueType": "number"
9873
+ },
9874
+ {
9875
+ "path": "currentCodeLabel",
9876
+ "valueType": "string"
9877
+ },
9878
+ {
9879
+ "path": "severity",
9880
+ "valueType": "enum",
9881
+ "enumValues": [
9882
+ "info",
9883
+ "warning",
9884
+ "error"
9885
+ ]
9886
+ }
9887
+ ],
9888
+ "lock-control": [{
9889
+ "path": "state",
9890
+ "valueType": "enum",
9891
+ "enumValues": [
9892
+ "locked",
9893
+ "unlocked",
9894
+ "locking",
9895
+ "unlocking",
9896
+ "jammed"
9897
+ ]
9898
+ }],
9899
+ "media-player": [
9900
+ {
9901
+ "path": "state",
9902
+ "valueType": "enum",
9903
+ "enumValues": [
9904
+ "off",
9905
+ "on",
9906
+ "idle",
9907
+ "playing",
9908
+ "paused",
9909
+ "buffering",
9910
+ "standby"
9911
+ ]
9912
+ },
9913
+ {
9914
+ "path": "volumeLevel",
9915
+ "valueType": "number"
9916
+ },
9917
+ {
9918
+ "path": "isMuted",
9919
+ "valueType": "boolean"
9920
+ },
9921
+ {
9922
+ "path": "source",
9923
+ "valueType": "string"
9924
+ },
9925
+ {
9926
+ "path": "currentMedia.type",
9927
+ "valueType": "string"
9928
+ },
9929
+ {
9930
+ "path": "currentMedia.title",
9931
+ "valueType": "string"
9932
+ },
9933
+ {
9934
+ "path": "currentMedia.artist",
9935
+ "valueType": "string"
9936
+ },
9937
+ {
9938
+ "path": "currentMedia.album",
9939
+ "valueType": "string"
9940
+ },
9941
+ {
9942
+ "path": "currentMedia.imageUrl",
9943
+ "valueType": "string"
9944
+ },
9945
+ {
9946
+ "path": "positionMs",
9947
+ "valueType": "number"
9948
+ },
9949
+ {
9950
+ "path": "durationMs",
9951
+ "valueType": "number"
9952
+ },
9953
+ {
9954
+ "path": "shuffle",
9955
+ "valueType": "boolean"
9956
+ },
9957
+ {
9958
+ "path": "repeat",
9959
+ "valueType": "enum",
9960
+ "enumValues": [
9961
+ "off",
9962
+ "all",
9963
+ "one"
9964
+ ]
9965
+ }
9966
+ ],
9967
+ "motion": [
9968
+ {
9969
+ "path": "detected",
9970
+ "valueType": "boolean"
9971
+ },
9972
+ {
9973
+ "path": "lastDetectedAt",
9974
+ "valueType": "number"
9975
+ },
9976
+ {
9977
+ "path": "autoClearAfterMs",
9978
+ "valueType": "number"
9979
+ }
9980
+ ],
9981
+ "motion-trigger": [{
9982
+ "path": "enabled",
9983
+ "valueType": "boolean"
9984
+ }],
9985
+ "motion-zones": [{
9986
+ "path": "enabled",
9987
+ "valueType": "boolean"
9988
+ }, {
9989
+ "path": "sensitivity",
9990
+ "valueType": "number"
9991
+ }],
9992
+ "mqtt-broker": [{
9993
+ "path": "brokerCount",
9994
+ "valueType": "number"
9995
+ }, {
9996
+ "path": "embeddedRunning",
9997
+ "valueType": "boolean"
9998
+ }],
9999
+ "native-object-detection": [{
10000
+ "path": "enabled",
10001
+ "valueType": "boolean"
10002
+ }],
10003
+ "navigation": [
10004
+ {
10005
+ "path": "mode",
10006
+ "valueType": "enum",
10007
+ "enumValues": [
10008
+ "idle",
10009
+ "cleaning",
10010
+ "spot",
10011
+ "following",
10012
+ "goto",
10013
+ "returning",
10014
+ "paused",
10015
+ "unknown"
10016
+ ]
10017
+ },
10018
+ {
10019
+ "path": "following",
10020
+ "valueType": "boolean"
10021
+ },
10022
+ {
10023
+ "path": "flash",
10024
+ "valueType": "boolean"
10025
+ },
10026
+ {
10027
+ "path": "lightMode",
10028
+ "valueType": "enum",
10029
+ "enumValues": ["auto", "manual"]
10030
+ },
10031
+ {
10032
+ "path": "lightLevel",
10033
+ "valueType": "number"
10034
+ }
10035
+ ],
10036
+ "network-link": [
10037
+ {
10038
+ "path": "type",
10039
+ "valueType": "enum",
10040
+ "enumValues": [
10041
+ "wifi",
10042
+ "ethernet",
10043
+ "cellular",
10044
+ "unknown"
10045
+ ]
10046
+ },
10047
+ {
10048
+ "path": "signalPercent",
10049
+ "valueType": "number"
10050
+ },
10051
+ {
10052
+ "path": "rssiDbm",
10053
+ "valueType": "number"
10054
+ },
10055
+ {
10056
+ "path": "ssid",
10057
+ "valueType": "string"
10058
+ },
10059
+ {
10060
+ "path": "lastUpdated",
10061
+ "valueType": "number"
10062
+ }
10063
+ ],
10064
+ "notifier": [
10065
+ {
10066
+ "path": "lastSentAt",
10067
+ "valueType": "number"
10068
+ },
10069
+ {
10070
+ "path": "lastError",
10071
+ "valueType": "string"
10072
+ },
10073
+ {
10074
+ "path": "queueDepth",
10075
+ "valueType": "number"
10076
+ },
10077
+ {
10078
+ "path": "supports.image",
10079
+ "valueType": "boolean"
10080
+ },
10081
+ {
10082
+ "path": "supports.priority",
10083
+ "valueType": "boolean"
10084
+ },
10085
+ {
10086
+ "path": "supports.data",
10087
+ "valueType": "boolean"
10088
+ },
10089
+ {
10090
+ "path": "supports.actions",
10091
+ "valueType": "boolean"
10092
+ },
10093
+ {
10094
+ "path": "supports.recipients",
10095
+ "valueType": "boolean"
10096
+ }
10097
+ ],
10098
+ "numeric-sensor": [
10099
+ {
10100
+ "path": "value",
10101
+ "valueType": "number"
10102
+ },
10103
+ {
10104
+ "path": "unit",
10105
+ "valueType": "string"
10106
+ },
10107
+ {
10108
+ "path": "precision",
10109
+ "valueType": "number"
10110
+ }
10111
+ ],
10112
+ "pet-feeder": [
10113
+ {
10114
+ "path": "foodLevel",
10115
+ "valueType": "number"
10116
+ },
10117
+ {
10118
+ "path": "food1",
10119
+ "valueType": "number"
10120
+ },
10121
+ {
10122
+ "path": "food2",
10123
+ "valueType": "number"
10124
+ },
10125
+ {
10126
+ "path": "lowFood",
10127
+ "valueType": "boolean"
10128
+ },
10129
+ {
10130
+ "path": "batteryPower",
10131
+ "valueType": "number"
10132
+ },
10133
+ {
10134
+ "path": "desiccantLeftDays",
10135
+ "valueType": "number"
10136
+ },
10137
+ {
10138
+ "path": "feeding",
10139
+ "valueType": "boolean"
10140
+ },
10141
+ {
10142
+ "path": "status",
10143
+ "valueType": "enum",
10144
+ "enumValues": [
10145
+ "normal",
10146
+ "offline",
10147
+ "on_batteries"
10148
+ ]
10149
+ },
10150
+ {
10151
+ "path": "error",
10152
+ "valueType": "string"
10153
+ },
10154
+ {
10155
+ "path": "errorCode",
10156
+ "valueType": "number"
10157
+ },
10158
+ {
10159
+ "path": "isDualHopper",
10160
+ "valueType": "boolean"
10161
+ },
10162
+ {
10163
+ "path": "childLock",
10164
+ "valueType": "boolean"
10165
+ },
10166
+ {
10167
+ "path": "indicatorLight",
10168
+ "valueType": "boolean"
10169
+ },
10170
+ {
10171
+ "path": "feedSound",
10172
+ "valueType": "boolean"
10173
+ },
10174
+ {
10175
+ "path": "volume",
10176
+ "valueType": "number"
10177
+ }
10178
+ ],
10179
+ "power-meter": [
10180
+ {
10181
+ "path": "watts",
10182
+ "valueType": "number"
10183
+ },
10184
+ {
10185
+ "path": "kwhTotal",
10186
+ "valueType": "number"
10187
+ },
10188
+ {
10189
+ "path": "volts",
10190
+ "valueType": "number"
10191
+ },
10192
+ {
10193
+ "path": "amps",
10194
+ "valueType": "number"
10195
+ },
10196
+ {
10197
+ "path": "va",
10198
+ "valueType": "number"
10199
+ },
10200
+ {
10201
+ "path": "powerFactor",
10202
+ "valueType": "number"
10203
+ },
10204
+ {
10205
+ "path": "unit",
10206
+ "valueType": "string"
10207
+ },
10208
+ {
10209
+ "path": "precision",
10210
+ "valueType": "number"
10211
+ }
10212
+ ],
10213
+ "presence": [
10214
+ {
10215
+ "path": "state",
10216
+ "valueType": "string"
10217
+ },
10218
+ {
10219
+ "path": "location",
10220
+ "valueType": "string"
10221
+ },
10222
+ {
10223
+ "path": "gps.latitude",
10224
+ "valueType": "number"
10225
+ },
10226
+ {
10227
+ "path": "gps.longitude",
10228
+ "valueType": "number"
10229
+ },
10230
+ {
10231
+ "path": "gps.accuracyMeters",
10232
+ "valueType": "number"
10233
+ },
10234
+ {
10235
+ "path": "batteryPercent",
10236
+ "valueType": "number"
10237
+ }
10238
+ ],
10239
+ "pressure-sensor": [
10240
+ {
10241
+ "path": "hpa",
10242
+ "valueType": "number"
10243
+ },
10244
+ {
10245
+ "path": "unit",
10246
+ "valueType": "string"
10247
+ },
10248
+ {
10249
+ "path": "precision",
10250
+ "valueType": "number"
10251
+ }
10252
+ ],
10253
+ "privacy-mask": [{
10254
+ "path": "enabled",
10255
+ "valueType": "boolean"
10256
+ }, {
10257
+ "path": "audioEnabled",
10258
+ "valueType": "boolean"
10259
+ }],
10260
+ "ptz": [
10261
+ {
10262
+ "path": "pan",
10263
+ "valueType": "number"
10264
+ },
10265
+ {
10266
+ "path": "tilt",
10267
+ "valueType": "number"
10268
+ },
10269
+ {
10270
+ "path": "zoom",
10271
+ "valueType": "number"
10272
+ },
10273
+ {
10274
+ "path": "autofocus",
10275
+ "valueType": "boolean"
10276
+ }
10277
+ ],
10278
+ "ptz-autotrack": [
10279
+ {
10280
+ "path": "enabled",
10281
+ "valueType": "boolean"
10282
+ },
10283
+ {
10284
+ "path": "currentSettings.targetType",
10285
+ "valueType": "string"
10286
+ },
10287
+ {
10288
+ "path": "currentSettings.stopDelaySeconds",
10289
+ "valueType": "number"
10290
+ },
10291
+ {
10292
+ "path": "currentSettings.disappearDelaySeconds",
10293
+ "valueType": "number"
10294
+ }
10295
+ ],
10296
+ "recording-archive": [
10297
+ {
10298
+ "path": "deviceId",
10299
+ "valueType": "number"
10300
+ },
10301
+ {
10302
+ "path": "enabled",
10303
+ "valueType": "boolean"
10304
+ },
10305
+ {
10306
+ "path": "activeMode",
10307
+ "valueType": "enum",
10308
+ "enumValues": [
10309
+ "off",
10310
+ "events",
10311
+ "continuous",
10312
+ "on-device-decision"
10313
+ ]
10314
+ },
10315
+ {
10316
+ "path": "nodeId",
10317
+ "valueType": "string"
10318
+ },
10319
+ {
10320
+ "path": "storageBytes",
10321
+ "valueType": "number"
10322
+ }
10323
+ ],
10324
+ "recording-onboard": [
10325
+ {
10326
+ "path": "primaryTrackId",
10327
+ "valueType": "string"
10328
+ },
10329
+ {
10330
+ "path": "enabled",
10331
+ "valueType": "boolean"
10332
+ },
10333
+ {
10334
+ "path": "overwriteWhenFull",
10335
+ "valueType": "boolean"
10336
+ },
10337
+ {
10338
+ "path": "preRecordSec",
10339
+ "valueType": "number"
10340
+ },
10341
+ {
10342
+ "path": "postRecordSec",
10343
+ "valueType": "number"
10344
+ },
10345
+ {
10346
+ "path": "segmentMinutes",
10347
+ "valueType": "number"
10348
+ },
10349
+ {
10350
+ "path": "unreadableWindows",
10351
+ "valueType": "number"
10352
+ },
10353
+ {
10354
+ "path": "recordingToNowhere",
10355
+ "valueType": "boolean"
10356
+ }
10357
+ ],
10358
+ "recording-signal": [{
10359
+ "path": "active",
10360
+ "valueType": "boolean"
10361
+ }, {
10362
+ "path": "reason",
10363
+ "valueType": "string"
10364
+ }],
10365
+ "running-state": [
10366
+ {
10367
+ "path": "running",
10368
+ "valueType": "boolean"
10369
+ },
10370
+ {
10371
+ "path": "since",
10372
+ "valueType": "number"
10373
+ },
10374
+ {
10375
+ "path": "source",
10376
+ "valueType": "enum",
10377
+ "enumValues": ["native", "assigned"]
10378
+ },
10379
+ {
10380
+ "path": "phase",
10381
+ "valueType": "string"
10382
+ }
10383
+ ],
10384
+ "script-runner": [
10385
+ {
10386
+ "path": "isRunning",
10387
+ "valueType": "boolean"
10388
+ },
10389
+ {
10390
+ "path": "lastRunAt",
10391
+ "valueType": "number"
10392
+ },
10393
+ {
10394
+ "path": "lastRunSuccess",
10395
+ "valueType": "boolean"
10396
+ },
10397
+ {
10398
+ "path": "lastError",
10399
+ "valueType": "string"
10400
+ }
10401
+ ],
10402
+ "smoke": [{
10403
+ "path": "detected",
10404
+ "valueType": "boolean"
10405
+ }],
10406
+ "snapshot": [
10407
+ {
10408
+ "path": "lastCapturedAt",
10409
+ "valueType": "number"
10410
+ },
10411
+ {
10412
+ "path": "cacheAgeMs",
10413
+ "valueType": "number"
10414
+ },
10415
+ {
10416
+ "path": "lastBytes",
10417
+ "valueType": "number"
10418
+ },
10419
+ {
10420
+ "path": "lastStreamId",
10421
+ "valueType": "string"
10422
+ }
10423
+ ],
10424
+ "stream-params": [
10425
+ {
10426
+ "path": "main.width",
10427
+ "valueType": "number"
10428
+ },
10429
+ {
10430
+ "path": "main.height",
10431
+ "valueType": "number"
10432
+ },
10433
+ {
10434
+ "path": "main.codec",
10435
+ "valueType": "enum",
10436
+ "enumValues": ["h264", "h265"]
10437
+ },
10438
+ {
10439
+ "path": "main.framerate",
10440
+ "valueType": "number"
10441
+ },
10442
+ {
10443
+ "path": "main.bitrate",
10444
+ "valueType": "number"
10445
+ },
10446
+ {
10447
+ "path": "main.bitrateMode",
10448
+ "valueType": "enum",
10449
+ "enumValues": ["vbr", "cbr"]
10450
+ },
10451
+ {
10452
+ "path": "main.encoderProfile",
10453
+ "valueType": "enum",
10454
+ "enumValues": [
10455
+ "high",
10456
+ "main",
10457
+ "baseline"
10458
+ ]
10459
+ },
10460
+ {
10461
+ "path": "main.gop",
10462
+ "valueType": "number"
10463
+ },
10464
+ {
10465
+ "path": "main.audio",
10466
+ "valueType": "boolean"
10467
+ },
10468
+ {
10469
+ "path": "sub.width",
10470
+ "valueType": "number"
10471
+ },
10472
+ {
10473
+ "path": "sub.height",
10474
+ "valueType": "number"
10475
+ },
10476
+ {
10477
+ "path": "sub.codec",
10478
+ "valueType": "enum",
10479
+ "enumValues": ["h264", "h265"]
10480
+ },
10481
+ {
10482
+ "path": "sub.framerate",
10483
+ "valueType": "number"
10484
+ },
10485
+ {
10486
+ "path": "sub.bitrate",
10487
+ "valueType": "number"
10488
+ },
10489
+ {
10490
+ "path": "sub.bitrateMode",
10491
+ "valueType": "enum",
10492
+ "enumValues": ["vbr", "cbr"]
10493
+ },
10494
+ {
10495
+ "path": "sub.encoderProfile",
10496
+ "valueType": "enum",
10497
+ "enumValues": [
10498
+ "high",
10499
+ "main",
10500
+ "baseline"
10501
+ ]
10502
+ },
10503
+ {
10504
+ "path": "sub.gop",
10505
+ "valueType": "number"
10506
+ },
10507
+ {
10508
+ "path": "sub.audio",
10509
+ "valueType": "boolean"
10510
+ },
10511
+ {
10512
+ "path": "ext.width",
10513
+ "valueType": "number"
10514
+ },
10515
+ {
10516
+ "path": "ext.height",
10517
+ "valueType": "number"
10518
+ },
10519
+ {
10520
+ "path": "ext.codec",
10521
+ "valueType": "enum",
10522
+ "enumValues": ["h264", "h265"]
10523
+ },
10524
+ {
10525
+ "path": "ext.framerate",
10526
+ "valueType": "number"
10527
+ },
10528
+ {
10529
+ "path": "ext.bitrate",
10530
+ "valueType": "number"
10531
+ },
10532
+ {
10533
+ "path": "ext.bitrateMode",
10534
+ "valueType": "enum",
10535
+ "enumValues": ["vbr", "cbr"]
10536
+ },
10537
+ {
10538
+ "path": "ext.encoderProfile",
10539
+ "valueType": "enum",
10540
+ "enumValues": [
10541
+ "high",
10542
+ "main",
10543
+ "baseline"
10544
+ ]
10545
+ },
10546
+ {
10547
+ "path": "ext.gop",
10548
+ "valueType": "number"
10549
+ },
10550
+ {
10551
+ "path": "ext.audio",
10552
+ "valueType": "boolean"
10553
+ }
10554
+ ],
10555
+ "switch": [{
10556
+ "path": "on",
10557
+ "valueType": "boolean"
10558
+ }],
10559
+ "tamper": [{
10560
+ "path": "tampered",
10561
+ "valueType": "boolean"
10562
+ }],
10563
+ "temperature-sensor": [
10564
+ {
10565
+ "path": "celsius",
10566
+ "valueType": "number"
10567
+ },
10568
+ {
10569
+ "path": "unit",
10570
+ "valueType": "string"
10571
+ },
10572
+ {
10573
+ "path": "precision",
10574
+ "valueType": "number"
10575
+ }
10576
+ ],
10577
+ "update": [
10578
+ {
10579
+ "path": "currentVersion",
10580
+ "valueType": "string"
10581
+ },
10582
+ {
10583
+ "path": "availableVersion",
10584
+ "valueType": "string"
10585
+ },
10586
+ {
10587
+ "path": "updatable",
10588
+ "valueType": "boolean"
10589
+ },
10590
+ {
10591
+ "path": "state",
10592
+ "valueType": "string"
10593
+ },
10594
+ {
10595
+ "path": "inProgress",
10596
+ "valueType": "boolean"
10597
+ }
10598
+ ],
10599
+ "vacuum-control": [
10600
+ {
10601
+ "path": "state",
10602
+ "valueType": "enum",
10603
+ "enumValues": [
10604
+ "idle",
10605
+ "cleaning",
10606
+ "paused",
10607
+ "returning",
10608
+ "docked",
10609
+ "drying",
10610
+ "error"
10611
+ ]
10612
+ },
10613
+ {
10614
+ "path": "batteryLevel",
10615
+ "valueType": "number"
10616
+ },
10617
+ {
10618
+ "path": "fanSpeed",
10619
+ "valueType": "string"
10620
+ },
10621
+ {
10622
+ "path": "progressPercent",
10623
+ "valueType": "number"
10624
+ },
10625
+ {
10626
+ "path": "errorCode",
10627
+ "valueType": "number"
10628
+ },
10629
+ {
10630
+ "path": "errorLabel",
10631
+ "valueType": "string"
10632
+ }
10633
+ ],
10634
+ "valve": [{
10635
+ "path": "state",
10636
+ "valueType": "enum",
10637
+ "enumValues": [
10638
+ "open",
10639
+ "opening",
10640
+ "closing",
10641
+ "closed",
10642
+ "stopped"
10643
+ ]
10644
+ }, {
10645
+ "path": "position",
10646
+ "valueType": "number"
10647
+ }],
10648
+ "vibration": [{
10649
+ "path": "detected",
10650
+ "valueType": "boolean"
10651
+ }],
10652
+ "water-heater": [
10653
+ {
10654
+ "path": "currentTemp",
10655
+ "valueType": "number"
10656
+ },
10657
+ {
10658
+ "path": "targetTemp",
10659
+ "valueType": "number"
10660
+ },
10661
+ {
10662
+ "path": "operationMode",
10663
+ "valueType": "string"
10664
+ },
10665
+ {
10666
+ "path": "away",
10667
+ "valueType": "boolean"
10668
+ },
10669
+ {
10670
+ "path": "minTemp",
10671
+ "valueType": "number"
10672
+ },
10673
+ {
10674
+ "path": "maxTemp",
10675
+ "valueType": "number"
10676
+ }
10677
+ ],
10678
+ "weather": [
10679
+ {
10680
+ "path": "condition",
10681
+ "valueType": "string"
10682
+ },
10683
+ {
10684
+ "path": "temperature",
10685
+ "valueType": "number"
10686
+ },
10687
+ {
10688
+ "path": "temperatureUnit",
10689
+ "valueType": "string"
10690
+ },
10691
+ {
10692
+ "path": "humidity",
10693
+ "valueType": "number"
10694
+ },
10695
+ {
10696
+ "path": "pressure",
10697
+ "valueType": "number"
10698
+ },
10699
+ {
10700
+ "path": "pressureUnit",
10701
+ "valueType": "string"
10702
+ },
10703
+ {
10704
+ "path": "windSpeed",
10705
+ "valueType": "number"
10706
+ },
10707
+ {
10708
+ "path": "windSpeedUnit",
10709
+ "valueType": "string"
10710
+ },
10711
+ {
10712
+ "path": "windBearing",
10713
+ "valueType": "number"
10714
+ }
10715
+ ],
10716
+ "zone-analytics": [
10717
+ {
10718
+ "path": "ts",
10719
+ "valueType": "number"
10720
+ },
10721
+ {
10722
+ "path": "frameWidth",
10723
+ "valueType": "number"
10724
+ },
10725
+ {
10726
+ "path": "frameHeight",
10727
+ "valueType": "number"
10728
+ },
10729
+ {
10730
+ "path": "frame.totalObjects",
10731
+ "valueType": "number"
10732
+ },
10733
+ {
10734
+ "path": "frame.standingObjects",
10735
+ "valueType": "number"
10736
+ },
10737
+ {
10738
+ "path": "frame.transientObjects",
10739
+ "valueType": "number"
10740
+ },
10741
+ {
10742
+ "path": "unzoned.totalObjects",
10743
+ "valueType": "number"
10744
+ },
10745
+ {
10746
+ "path": "unzoned.standingObjects",
10747
+ "valueType": "number"
10748
+ },
10749
+ {
10750
+ "path": "unzoned.transientObjects",
10751
+ "valueType": "number"
10752
+ }
10753
+ ]
10754
+ });
8777
10755
  object({
8778
10756
  code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
8779
10757
  params: record(string(), union([string(), number()])).optional()
@@ -9136,7 +11114,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
9136
11114
  return DeviceRole;
9137
11115
  }({});
9138
11116
  //#endregion
9139
- //#region ../types/dist/composition-CB6PMT9p.mjs
11117
+ //#region ../types/dist/composition-kEl9mevu.mjs
9140
11118
  /**
9141
11119
  * The ffmpeg build every CamStack node downloads, per platform and arch.
9142
11120
  *
@@ -9196,7 +11174,7 @@ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac
9196
11174
  * ONE table for everyone who asks "is this device HIGH?": the
9197
11175
  * recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
9198
11176
  * sensor markers, the orchestrator's camera-sensors bridge and
9199
- * the sources of a composite doorbell (`doorbellFeatureSources`, D671).
11177
+ * the sources of a pulse (`compilePulseOverride`, D936).
9200
11178
  * A second copy would diverge at the first cap added, and the symptom — "the
9201
11179
  * sensor rings the doorbell but does not record" — is exactly D62.
9202
11180
  *
@@ -9437,6 +11415,20 @@ var table = {
9437
11415
  apply: () => {
9438
11416
  throw new ExpressionEvalError("count: stateful evaluation context is required");
9439
11417
  }
11418
+ },
11419
+ dwell: {
11420
+ minArgs: 3,
11421
+ maxArgs: 3,
11422
+ apply: () => {
11423
+ throw new ExpressionEvalError("dwell: stateful evaluation context is required");
11424
+ }
11425
+ },
11426
+ latchedAt: {
11427
+ minArgs: 1,
11428
+ maxArgs: 1,
11429
+ apply: () => {
11430
+ throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
11431
+ }
9440
11432
  }
9441
11433
  };
9442
11434
  Object.freeze(Object.assign(Object.create(null), table));
@@ -12454,7 +14446,7 @@ var LogChannelDescriptorSchema = object({
12454
14446
  * `true` is a PROMISE with two halves, and both must hold: the gate is
12455
14447
  * consulted with the numeric device id, AND every line the channel admits
12456
14448
  * carries `tags: { deviceId }` with that same numeric id. The second half is
12457
- * what makes `| json | deviceId="617"` work in Loki — `loki-payload.ts`
14449
+ * what makes `| json | deviceId="102"` work in Loki — `loki-payload.ts`
12458
14450
  * keeps `deviceId` out of the stream labels for cardinality, so the tag in
12459
14451
  * the body is the only way to filter.
12460
14452
  *
@@ -12642,7 +14634,7 @@ var ModelVariantGroupSchema = object({
12642
14634
  precision: _enum(["fp32", "int8"]).optional(),
12643
14635
  /**
12644
14636
  * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
12645
- * an alternate training of the same family (Scrypted `relu_test`); chip
14637
+ * an alternate training of the same family (plugin catalog `relu_test`); chip
12646
14638
  * label is "Test".
12647
14639
  */
12648
14640
  optimization: _enum(["standard", "test"]).optional(),
@@ -12894,8 +14886,8 @@ var ModelCatalogEntrySchema = object({
12894
14886
  provider: ModelProviderIdSchema.optional(),
12895
14887
  /**
12896
14888
  * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
12897
- * applies (Frigate / COCO public catalog). Set on a custom model whose raw
12898
- * labels already ARE the CamStack macros (Scrypted identity map).
14889
+ * applies (plus catalog / COCO public catalog). Set on a custom model whose raw
14890
+ * labels already ARE the CamStack macros (plugin catalog identity map).
12899
14891
  */
12900
14892
  classMap: DetectionCatalogClassMapSchema.optional(),
12901
14893
  /**
@@ -15932,7 +17924,7 @@ method(object({
15932
17924
  * `1` is real time and is the ONLY value that allows the copy branch —
15933
17925
  * anything else forces `libx264` over the window. That was priced
15934
17926
  * before it was chosen: a per-event burst measured at 0.23 s and 254 KB
15935
- * on a real 615 720p cut, against 922 KB for the copy it replaces. A
17927
+ * on a real 101 720p cut, against 922 KB for the copy it replaces. A
15936
17928
  * re-encode is capped at 720p (`EVENT_CLIP_ENCODE_MAX_WIDTH`), because
15937
17929
  * once the decode is forced the width stops being free.
15938
17930
  */
@@ -16352,6 +18344,7 @@ var CompositionRunStatusSchema = _enum([
16352
18344
  "starting",
16353
18345
  "running",
16354
18346
  "degraded",
18347
+ "incomplete",
16355
18348
  "failed"
16356
18349
  ]);
16357
18350
  var CompositionFieldStateKindSchema = _enum([
@@ -16401,6 +18394,13 @@ var ComposerUnreadableBlockSchema = object({
16401
18394
  /** The parse error, in the operator's words. */
16402
18395
  error: string()
16403
18396
  });
18397
+ /** A confirmed release the hub did not accept. `deviceId` is the claim's device. */
18398
+ var UnreleasedClaimSchema = object({
18399
+ deviceId: number().int(),
18400
+ capName: string(),
18401
+ owner: string(),
18402
+ error: string()
18403
+ });
16404
18404
  method(object({
16405
18405
  /** The shared Blocks integration; null until `core-blocks` has reconciled it. */
16406
18406
  integrationId: string().nullable(),
@@ -16410,7 +18410,13 @@ method(object({
16410
18410
  /** Operator restarts: rebuild these runtimes and re-resolve their sources. Stores nothing (D62). */
16411
18411
  restartBlockIds: array(string()),
16412
18412
  /** Composition rows that exist but do not parse: held, never withdrawn, reported failed. */
16413
- unreadableBlocks: array(ComposerUnreadableBlockSchema)
18413
+ unreadableBlocks: array(ComposerUnreadableBlockSchema),
18414
+ /**
18415
+ * Operator-confirmed deletions. Their claims are released on this apply,
18416
+ * before any replacement block claims. A block that merely vanished from the
18417
+ * snapshot is not listed here and still waits for two applies (D49).
18418
+ */
18419
+ retiredBlockIds: array(string()).optional()
16414
18420
  }), object({
16415
18421
  blocks: array(object({
16416
18422
  blockId: string(),
@@ -16422,7 +18428,13 @@ method(object({
16422
18428
  * integration unknown, its own rows unread or read empty once). An empty
16423
18429
  * apply the caller owes is paid off only by one the composer acted on (D49).
16424
18430
  */
16425
- acted: boolean()
18431
+ acted: boolean(),
18432
+ /**
18433
+ * Confirmed releases this apply tried and the hub did not accept. Empty when
18434
+ * every one landed (or there was nothing to hand back). Absent on a result
18435
+ * that never got that far.
18436
+ */
18437
+ unreleasedClaims: array(UnreleasedClaimSchema).optional()
16426
18438
  }), {
16427
18439
  kind: "mutation",
16428
18440
  auth: "admin"
@@ -16465,7 +18477,15 @@ Object.freeze({
16465
18477
  kind: "fixed",
16466
18478
  result: ["number", "null"]
16467
18479
  },
16468
- count: NUMBER
18480
+ count: NUMBER,
18481
+ dwell: {
18482
+ kind: "fixed",
18483
+ result: ["boolean", "null"]
18484
+ },
18485
+ latchedAt: {
18486
+ kind: "fixed",
18487
+ result: ["number", "null"]
18488
+ }
16469
18489
  });
16470
18490
  `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
16471
18491
  /**
@@ -16538,6 +18558,7 @@ var CoreBlockStatusSchema = _enum([
16538
18558
  "starting",
16539
18559
  "running",
16540
18560
  "degraded",
18561
+ "incomplete",
16541
18562
  "failed"
16542
18563
  ]);
16543
18564
  /** path → TypeScript source for a multi-file block. */
@@ -38461,7 +40482,7 @@ var PRIMARY_CATEGORIES = new Set(ENTRIES.map((e) => e.primaryCategory));
38461
40482
  * `locationKey` is ALWAYS {@link locationIconKey} of the label — never the
38462
40483
  * operator's casing. The registry matches labels trimmed + case-insensitively
38463
40484
  * everywhere (`addLocation`, `removeLocation`, `renameLocation`), and a
38464
- * case-only rename (`cucina` → `Cucina`) is a real edit this repo supports; a
40485
+ * case-only rename (`kitchen` → `Kitchen`) is a real edit this repo supports; a
38465
40486
  * map keyed on the displayed casing would orphan its entry on exactly that
38466
40487
  * edit. Consumers join by keying their own label through `locationIconKey`.
38467
40488
  */
@@ -38486,7 +40507,7 @@ var LocationDescriptionAssignmentSchema = object({
38486
40507
  /**
38487
40508
  * A SITE ZONE — a named part of the property that several locations belong to.
38488
40509
  *
38489
- * "Zona notte" holds every bedroom; "Zona giorno" the living room and the
40510
+ * "Night zone" holds every bedroom; "Zona giorno" the living room and the
38490
40511
  * kitchen. A camera belongs to exactly one location, and a location to at most
38491
40512
  * one zone, so a camera's zone is derived and never stored on the device: the
38492
40513
  * whole point of this entity is that grouping rooms touches no device row.
@@ -38515,7 +40536,7 @@ var LocationDescriptionAssignmentSchema = object({
38515
40536
  * the locations inside it.
38516
40537
  *
38517
40538
  * The LABEL is carried alongside the key because the key is lossy on purpose —
38518
- * a surface must show "Zona notte", not "zona notte". Locations are carried
40539
+ * a surface must show "Night zone", not "night zone". Locations are carried
38519
40540
  * here, rather than left to a second call, because every consumer wants both
38520
40541
  * at once and a viewer that asked twice could render a zone whose membership
38521
40542
  * it has not fetched yet.
@@ -40628,8 +42649,8 @@ var LoadContributionSchema = object({
40628
42649
  "unattributable"
40629
42650
  ]),
40630
42651
  /**
40631
- * What ONE entry is, in the contributor's own words — `615/high`,
40632
- * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
42652
+ * What ONE entry is, in the contributor's own words — `101/high`,
42653
+ * `102/native`, `cuda:0 shared pool`. Free text because the unit differs per
40633
42654
  * family and inventing a common one would lose the only information that
40634
42655
  * makes two entries for the same camera distinguishable.
40635
42656
  */
@@ -42277,6 +44298,381 @@ var _macroLookup = /* @__PURE__ */ new Map();
42277
44298
  for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
42278
44299
  for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
42279
44300
  /**
44301
+ * Palette entry ids (D939). Audio is the one gradient; `audio-*` leaves are
44302
+ * not entries. `heatmapScrub` is a mark, not an event kind.
44303
+ */
44304
+ var PALETTE_ENTRY_IDS = [
44305
+ "motion",
44306
+ "audio",
44307
+ "recording",
44308
+ "live",
44309
+ "heatmapScrub",
44310
+ "person",
44311
+ "vehicle",
44312
+ "animal",
44313
+ "package",
44314
+ "sensor",
44315
+ "control",
44316
+ "face",
44317
+ "plate",
44318
+ "car",
44319
+ "truck",
44320
+ "bus",
44321
+ "motorcycle",
44322
+ "bicycle",
44323
+ "airplane",
44324
+ "boat",
44325
+ "train",
44326
+ "bird",
44327
+ "dog",
44328
+ "cat",
44329
+ "horse",
44330
+ "sheep",
44331
+ "cow",
44332
+ "elephant",
44333
+ "bear",
44334
+ "zebra",
44335
+ "giraffe",
44336
+ "package-delivered",
44337
+ "package-picked-up",
44338
+ "suitcase",
44339
+ "backpack",
44340
+ "handbag",
44341
+ "contact",
44342
+ "motion-sensor",
44343
+ "smoke",
44344
+ "flood",
44345
+ "gas",
44346
+ "carbon-monoxide",
44347
+ "vibration",
44348
+ "tamper",
44349
+ "presence",
44350
+ "enum-sensor",
44351
+ "device-event",
44352
+ "lock",
44353
+ "cover",
44354
+ "switch",
44355
+ "siren",
44356
+ "button",
44357
+ "doorbell"
44358
+ ];
44359
+ var AUDIO_ENTRY_ID = "audio";
44360
+ /** Six rungs, quiet → loud. The opaque end is the entry's hex. */
44361
+ var AUDIO_GRADIENT_ALPHAS = [
44362
+ .3,
44363
+ .42,
44364
+ .55,
44365
+ .7,
44366
+ .85,
44367
+ 1
44368
+ ];
44369
+ var PALETTE_PRESET_IDS = [
44370
+ "camstack",
44371
+ "high-contrast",
44372
+ "okabe-ito"
44373
+ ];
44374
+ /** Frozen palette tables (D939). The spec refuses a table that breaks the rule. */
44375
+ var CAMSTACK_HEX = {
44376
+ motion: "#d946ef",
44377
+ audio: "#059eb8",
44378
+ recording: "#ef4444",
44379
+ live: "#8d7a00",
44380
+ heatmapScrub: "#4b32ff",
44381
+ person: "#11a64c",
44382
+ vehicle: "#3b82f6",
44383
+ animal: "#ea6a09",
44384
+ package: "#924667",
44385
+ sensor: "#624bbc",
44386
+ control: "#944d24",
44387
+ face: "#ed4f8d",
44388
+ plate: "#4b7027",
44389
+ car: "#9684cf",
44390
+ truck: "#0f9b89",
44391
+ bus: "#a734a9",
44392
+ motorcycle: "#c1133a",
44393
+ bicycle: "#0e6a9b",
44394
+ airplane: "#7c9928",
44395
+ boat: "#b17933",
44396
+ train: "#ad6ca3",
44397
+ bird: "#0f7c55",
44398
+ dog: "#c82700",
44399
+ cat: "#7268f2",
44400
+ horse: "#cb795e",
44401
+ sheep: "#b8636b",
44402
+ cow: "#cb2969",
44403
+ elephant: "#1158d2",
44404
+ bear: "#8d5e00",
44405
+ zebra: "#0097d6",
44406
+ giraffe: "#8f61bb",
44407
+ "package-delivered": "#cd3f9b",
44408
+ "package-picked-up": "#388a08",
44409
+ suitcase: "#666800",
44410
+ backpack: "#ec5022",
44411
+ handbag: "#a76ef8",
44412
+ contact: "#ab5a49",
44413
+ "motion-sensor": "#b95d1a",
44414
+ smoke: "#dd3858",
44415
+ flood: "#b31e7d",
44416
+ gas: "#5b70b5",
44417
+ "carbon-monoxide": "#7b4e8e",
44418
+ vibration: "#e65bba",
44419
+ tamper: "#98464b",
44420
+ presence: "#3a9468",
44421
+ "enum-sensor": "#7885f8",
44422
+ "device-event": "#8c43c8",
44423
+ lock: "#649653",
44424
+ cover: "#c67597",
44425
+ switch: "#7a812a",
44426
+ siren: "#ac5d7f",
44427
+ button: "#b276cd",
44428
+ doorbell: "#0087ab"
44429
+ };
44430
+ var CAMSTACK_FALLBACK = [
44431
+ "#b34dc7",
44432
+ "#1d7d34",
44433
+ "#db6b6c",
44434
+ "#a43d29",
44435
+ "#0e6ee6",
44436
+ "#29a10b",
44437
+ "#a98731",
44438
+ "#0181c6"
44439
+ ];
44440
+ var HIGH_CONTRAST_HEX = {
44441
+ motion: "#964360",
44442
+ audio: "#23a132",
44443
+ recording: "#2494ca",
44444
+ live: "#bd7e2b",
44445
+ heatmapScrub: "#ad6eea",
44446
+ person: "#62611e",
44447
+ vehicle: "#f4534c",
44448
+ animal: "#1556cd",
44449
+ package: "#9c4415",
44450
+ sensor: "#066c48",
44451
+ control: "#f2479f",
44452
+ face: "#139d8a",
44453
+ plate: "#909024",
44454
+ car: "#8e35ab",
44455
+ truck: "#bd0b2b",
44456
+ bus: "#7a88ca",
44457
+ motorcycle: "#e26725",
44458
+ bicycle: "#a6679b",
44459
+ airplane: "#7c5720",
44460
+ boat: "#467a1b",
44461
+ train: "#6f65a4",
44462
+ bird: "#cb717f",
44463
+ dog: "#c62490",
44464
+ cat: "#b36850",
44465
+ horse: "#1872ac",
44466
+ sheep: "#927939",
44467
+ cow: "#428a5c",
44468
+ elephant: "#d41160",
44469
+ bear: "#799453",
44470
+ zebra: "#a85455",
44471
+ giraffe: "#746be8",
44472
+ "package-delivered": "#824a80",
44473
+ "package-picked-up": "#614ac1",
44474
+ suitcase: "#2f77f3",
44475
+ backpack: "#fa476d",
44476
+ handbag: "#c14cbe",
44477
+ contact: "#c83921",
44478
+ "motion-sensor": "#a07ebd",
44479
+ smoke: "#a25b13",
44480
+ flood: "#526bab",
44481
+ gas: "#924938",
44482
+ "carbon-monoxide": "#bb7e53",
44483
+ vibration: "#b66182",
44484
+ tamper: "#3c6931",
44485
+ presence: "#6c851d",
44486
+ "enum-sensor": "#ad2d48",
44487
+ "device-event": "#5e9b04",
44488
+ lock: "#00a062",
44489
+ cover: "#ad8624",
44490
+ switch: "#d05259",
44491
+ siren: "#cd67b3",
44492
+ button: "#c9746a",
44493
+ doorbell: "#338eeb"
44494
+ };
44495
+ var HIGH_CONTRAST_FALLBACK = [
44496
+ "#817f3b",
44497
+ "#a0733e",
44498
+ "#8658b2",
44499
+ "#956301",
44500
+ "#bc652d",
44501
+ "#647331",
44502
+ "#a14c9e",
44503
+ "#d14e71"
44504
+ ];
44505
+ var OKABE_ITO_HEX = {
44506
+ motion: "#b88128",
44507
+ audio: "#1096c8",
44508
+ recording: "#009e73",
44509
+ live: "#9c8c22",
44510
+ heatmapScrub: "#0072b2",
44511
+ person: "#d55e00",
44512
+ vehicle: "#c0739f",
44513
+ animal: "#226d18",
44514
+ package: "#91446c",
44515
+ sensor: "#217b56",
44516
+ control: "#648647",
44517
+ face: "#c22998",
44518
+ plate: "#fa4575",
44519
+ car: "#956301",
44520
+ truck: "#2f77f3",
44521
+ bus: "#7a4e86",
44522
+ motorcycle: "#f54597",
44523
+ bicycle: "#bb3e75",
44524
+ airplane: "#e054c0",
44525
+ boat: "#457942",
44526
+ train: "#867afa",
44527
+ bird: "#88914c",
44528
+ dog: "#1556cd",
44529
+ cat: "#71702c",
44530
+ horse: "#9b4fa4",
44531
+ sheep: "#c0559d",
44532
+ cow: "#d14f65",
44533
+ elephant: "#98470f",
44534
+ bear: "#595896",
44535
+ zebra: "#96790e",
44536
+ giraffe: "#cb717b",
44537
+ "package-delivered": "#139d8a",
44538
+ "package-picked-up": "#906ead",
44539
+ suitcase: "#d02939",
44540
+ backpack: "#d41160",
44541
+ handbag: "#f64f54",
44542
+ contact: "#7258d2",
44543
+ "motion-sensor": "#b66182",
44544
+ smoke: "#627abb",
44545
+ flood: "#b86ae4",
44546
+ gas: "#a95261",
44547
+ "carbon-monoxide": "#c65d3c",
44548
+ vibration: "#7a40b7",
44549
+ tamper: "#914b34",
44550
+ presence: "#9481c3",
44551
+ "enum-sensor": "#ac6d47",
44552
+ "device-event": "#7b6fce",
44553
+ lock: "#c67662",
44554
+ cover: "#a6564d",
44555
+ switch: "#ad2c4e",
44556
+ siren: "#348e08",
44557
+ button: "#d27303",
44558
+ doorbell: "#55770f"
44559
+ };
44560
+ var OKABE_ITO_FALLBACK = [
44561
+ "#9a3784",
44562
+ "#a7392c",
44563
+ "#409d50",
44564
+ "#6987e7",
44565
+ "#ee5b3d",
44566
+ "#c0430d",
44567
+ "#af79b3",
44568
+ "#4b6628"
44569
+ ];
44570
+ /**
44571
+ * The display palette (D939). One table of colours, three presets, one
44572
+ * validator. Taxonomy colours and every consumer read this — there is no
44573
+ * second hex table.
44574
+ */
44575
+ var paletteHexSchema = string().regex(/^#[0-9a-f]{6}$/);
44576
+ var paletteSwatchSchema = discriminatedUnion("form", [object({
44577
+ form: literal("solid"),
44578
+ hex: paletteHexSchema
44579
+ }), object({
44580
+ form: literal("gradient"),
44581
+ hex: paletteHexSchema,
44582
+ alphas: array(number().gt(0).lte(1)).length(AUDIO_GRADIENT_ALPHAS.length)
44583
+ })]);
44584
+ var paletteReadySchema = object({
44585
+ status: literal("ready"),
44586
+ presetId: _enum(PALETTE_PRESET_IDS),
44587
+ customized: boolean(),
44588
+ source: _enum(["stored", "unconfigured"]),
44589
+ swatches: record(string(), paletteSwatchSchema),
44590
+ fallbacks: array(paletteHexSchema).length(8)
44591
+ });
44592
+ var paletteResultSchema = discriminatedUnion("status", [paletteReadySchema, object({
44593
+ status: literal("unknown"),
44594
+ reason: string()
44595
+ })]);
44596
+ var setPaletteInputSchema = union([object({ presetId: string() }), object({
44597
+ presetId: string(),
44598
+ overrides: record(string(), paletteSwatchSchema)
44599
+ })]);
44600
+ object({
44601
+ presetId: string(),
44602
+ overrides: record(string(), paletteSwatchSchema)
44603
+ });
44604
+ function solid(hex) {
44605
+ return {
44606
+ form: "solid",
44607
+ hex
44608
+ };
44609
+ }
44610
+ function audioGradient(hex) {
44611
+ return {
44612
+ form: "gradient",
44613
+ hex,
44614
+ alphas: [...AUDIO_GRADIENT_ALPHAS]
44615
+ };
44616
+ }
44617
+ function swatchesFrom(hexes) {
44618
+ const out = {};
44619
+ for (const id of PALETTE_ENTRY_IDS) {
44620
+ const hex = hexes[id];
44621
+ if (hex === void 0) throw new Error(`palette table missing ${id}`);
44622
+ out[id] = id === "audio" ? audioGradient(hex) : solid(hex);
44623
+ }
44624
+ return out;
44625
+ }
44626
+ function preset(id, name, hexes, fallbacks) {
44627
+ return {
44628
+ id,
44629
+ name,
44630
+ swatches: swatchesFrom(hexes),
44631
+ fallbacks
44632
+ };
44633
+ }
44634
+ var DISPLAY_PRESETS = [
44635
+ preset("camstack", "CamStack", CAMSTACK_HEX, CAMSTACK_FALLBACK),
44636
+ preset("high-contrast", "High contrast", HIGH_CONTRAST_HEX, HIGH_CONTRAST_FALLBACK),
44637
+ preset("okabe-ito", "Colour-blind safe", OKABE_ITO_HEX, OKABE_ITO_FALLBACK)
44638
+ ];
44639
+ function presetById(id) {
44640
+ return DISPLAY_PRESETS.find((item) => item.id === id);
44641
+ }
44642
+ function bundledCamstack() {
44643
+ const presetRow = presetById("camstack");
44644
+ if (presetRow === void 0) throw new Error("CamStack preset missing");
44645
+ return readyOf(presetRow, "unconfigured", false);
44646
+ }
44647
+ function readyOf(row, source, customized) {
44648
+ return {
44649
+ status: "ready",
44650
+ presetId: row.id,
44651
+ customized,
44652
+ source,
44653
+ swatches: row.swatches,
44654
+ fallbacks: [...row.fallbacks]
44655
+ };
44656
+ }
44657
+ function hashFallback(kind, fallbacks) {
44658
+ let hash = 0;
44659
+ for (let i = 0; i < kind.length; i++) hash = hash * 31 + (kind.codePointAt(i) ?? 0) >>> 0;
44660
+ const hex = fallbacks[hash % fallbacks.length];
44661
+ if (hex === void 0) throw new Error("display palette has no fallback colour");
44662
+ return hex;
44663
+ }
44664
+ /** Colour a kind paints with. Audio leaves share the audio gradient's hex. */
44665
+ function paintHex(swatches, fallbacks, kind) {
44666
+ const key = kind.trim().toLowerCase();
44667
+ if (key.startsWith("audio-")) {
44668
+ const audio = swatches[AUDIO_ENTRY_ID];
44669
+ return audio !== void 0 ? audio.hex : hashFallback(key, fallbacks);
44670
+ }
44671
+ const direct = swatches[key];
44672
+ if (direct !== void 0) return direct.hex;
44673
+ return hashFallback(key, fallbacks);
44674
+ }
44675
+ /**
42280
44676
  * Unified event-kind taxonomy — THE single source of truth for
42281
44677
  * `kind → { parentKind, category, level, color, iconId, labelKey, label,
42282
44678
  * icon }`.
@@ -42290,109 +44686,88 @@ for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set
42290
44686
  * - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
42291
44687
  * - the COCO / audio class maps (macro ↔ sub relationships)
42292
44688
  *
42293
- * The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
42294
- * `@camstack/types`. The UI-side mapping `iconId → lucide component` and
42295
- * `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
42296
- * color or an icon: they read this dictionary (server descriptors carry the
42297
- * fields inline; the client resolves color/icon/label from `iconId`/`kind`).
44689
+ * The DATA (serializable — parentKind / iconId / labelKey) lives here in
44690
+ * `@camstack/types`. Colour is NOT a second table: each entry's `color` is
44691
+ * the bundled CamStack display palette (D939). The effective cluster palette
44692
+ * is the `display-palette` capability. The UI-side mapping `iconId → lucide
44693
+ * component` and `labelKey → t()` lives in `@camstack/ui-library`.
42298
44694
  *
42299
44695
  * Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
42300
44696
  */
42301
- var TAXONOMY_COLORS = {
42302
- motion: "#f59e0b",
42303
- audio: "#06b6d4",
42304
- person: "#22c55e",
42305
- vehicle: "#3b82f6",
42306
- animal: "#f97316",
42307
- package: "#a855f7",
42308
- sensor: "#8b5cf6",
42309
- control: "#10b981",
42310
- genericDetection: "#64748b"
42311
- };
42312
- var DETECTION_SUB_COLORS = {
42313
- car: "#f59e0b",
42314
- truck: "#d97706",
42315
- bus: "#b45309",
42316
- motorcycle: "#eab308",
42317
- bicycle: "#ca8a04",
42318
- airplane: "#60a5fa",
42319
- boat: "#2563eb",
42320
- train: "#1d4ed8",
42321
- bird: "#14b8a6",
42322
- dog: "#84cc16",
42323
- cat: "#f97316",
42324
- horse: "#a16207",
42325
- sheep: "#a3a3a3",
42326
- cow: "#78716c",
42327
- elephant: "#6b7280",
42328
- bear: "#7c2d12",
42329
- zebra: "#404040",
42330
- giraffe: "#d4a373"
42331
- };
44697
+ var BUNDLED_PALETTE = bundledCamstack();
44698
+ function kindColor(kind) {
44699
+ return paintHex(BUNDLED_PALETTE.swatches, BUNDLED_PALETTE.fallbacks, kind);
44700
+ }
44701
+ function firstFallback(fallbacks) {
44702
+ const hex = fallbacks[0];
44703
+ if (hex === void 0) throw new Error("display palette has no fallback colour");
44704
+ return hex;
44705
+ }
44706
+ firstFallback(BUNDLED_PALETTE.fallbacks);
42332
44707
  function titleCase(id) {
42333
44708
  return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
42334
44709
  }
42335
44710
  var entries = /* @__PURE__ */ new Map();
42336
- function macro(kind, category, color, iconId, label) {
44711
+ function macro(kind, category, iconId, label) {
42337
44712
  entries.set(kind, {
42338
44713
  kind,
42339
44714
  parentKind: null,
42340
44715
  level: "macro",
42341
44716
  category,
42342
- color,
44717
+ color: kindColor(kind),
42343
44718
  iconId,
42344
44719
  labelKey: `eventKind.${kind}`,
42345
44720
  label
42346
44721
  });
42347
44722
  }
42348
- function sub(kind, parentKind, category, color, iconId, label) {
44723
+ function sub(kind, parentKind, category, iconId, label) {
42349
44724
  entries.set(kind, {
42350
44725
  kind,
42351
44726
  parentKind,
42352
44727
  level: "sub",
42353
44728
  category,
42354
- color,
44729
+ color: kindColor(kind),
42355
44730
  iconId,
42356
44731
  labelKey: `eventKind.${kind}`,
42357
44732
  label
42358
44733
  });
42359
44734
  }
42360
- macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
42361
- macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
42362
- macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
42363
- macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
42364
- macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
42365
- macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
42366
- macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
42367
- macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
44735
+ macro("motion", "motion", "motion", "Motion");
44736
+ macro("audio", "audio", "audio", "Audio");
44737
+ macro("person", "detection", "person", "Person");
44738
+ macro("vehicle", "detection", "vehicle", "Vehicle");
44739
+ macro("animal", "detection", "animal", "Animal");
44740
+ macro("package", "package", "package", "Package");
44741
+ macro("sensor", "sensor", "sensor", "Sensor");
44742
+ macro("control", "control", "control", "Control");
42368
44743
  for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
42369
44744
  if (macroClass !== "vehicle" && macroClass !== "animal") continue;
42370
44745
  if (entries.has(cocoClass)) continue;
42371
- sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
44746
+ sub(cocoClass, macroClass, "detection", cocoClass, titleCase(cocoClass));
42372
44747
  }
42373
- sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
42374
- sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
42375
- sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
42376
- sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
42377
- sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
42378
- sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
42379
- sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
42380
- sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
42381
- sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
42382
- sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
42383
- sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
42384
- sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
42385
- sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
42386
- sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
42387
- sub("cover", "control", "control", "#0ea5e9", "door", "Cover");
42388
- sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
42389
- sub("siren", "control", "control", "#dc2626", "siren", "Siren");
42390
- sub("button", "control", "control", "#10b981", "button", "Button");
42391
- sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
44748
+ sub("package-delivered", "package", "package", "package", "Package delivered");
44749
+ sub("package-picked-up", "package", "package", "package", "Package picked up");
44750
+ sub("contact", "sensor", "sensor", "door", "Contact");
44751
+ sub("motion-sensor", "sensor", "sensor", "pir", "Motion sensor");
44752
+ sub("smoke", "sensor", "sensor", "smoke", "Smoke");
44753
+ sub("flood", "sensor", "sensor", "water", "Water leak");
44754
+ sub("gas", "sensor", "sensor", "gas", "Gas");
44755
+ sub("carbon-monoxide", "sensor", "sensor", "smoke", "Carbon monoxide");
44756
+ sub("vibration", "sensor", "sensor", "vibration", "Vibration");
44757
+ sub("tamper", "sensor", "sensor", "tamper", "Tamper");
44758
+ sub("presence", "sensor", "sensor", "presence", "Presence");
44759
+ sub("enum-sensor", "sensor", "sensor", "generic", "Sensor state");
44760
+ sub("device-event", "sensor", "sensor", "button", "Device event");
44761
+ sub("lock", "control", "control", "lock", "Lock");
44762
+ sub("cover", "control", "control", "door", "Cover");
44763
+ sub("switch", "control", "control", "switch", "Switch");
44764
+ sub("siren", "control", "control", "siren", "Siren");
44765
+ sub("button", "control", "control", "button", "Button");
44766
+ sub("doorbell", "control", "control", "doorbell", "Doorbell");
42392
44767
  for (const l of AUDIO_MACRO_LABELS) {
42393
44768
  const kind = `audio-${l.id}`;
42394
44769
  if (entries.has(kind)) continue;
42395
- sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
44770
+ sub(kind, "audio", "audio", kind, l.name);
42396
44771
  }
42397
44772
  /** The complete taxonomy dictionary, keyed by kind. */
42398
44773
  var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
@@ -42659,9 +45034,6 @@ var NcSystemEventKindSchema = _enum([
42659
45034
  "device-battery-normal",
42660
45035
  "device-consumable-low",
42661
45036
  "device-consumable-normal",
42662
- "device-tank-low",
42663
- "device-tank-full",
42664
- "device-tank-normal",
42665
45037
  "stream-online",
42666
45038
  "stream-offline",
42667
45039
  "node-online",
@@ -42708,13 +45080,14 @@ var NcSystemEventKindSchema = _enum([
42708
45080
  "camera-enabled"
42709
45081
  ]);
42710
45082
  /** The legacy tail of {@link NcSystemEventKindSchema} — see its docblock. */
42711
- var NC_LEGACY_SYSTEM_EVENT_KINDS = new Set([
45083
+ var NC_LEGACY_SYSTEM_EVENT_KINDS = [
42712
45084
  "camera-online",
42713
45085
  "camera-offline",
42714
45086
  "camera-disabled",
42715
45087
  "camera-enabled"
42716
- ]);
42717
- NcSystemEventKindSchema.options.filter((kind) => !NC_LEGACY_SYSTEM_EVENT_KINDS.has(kind));
45088
+ ];
45089
+ var NC_LEGACY_SYSTEM_EVENT_KIND_SET = new Set(NC_LEGACY_SYSTEM_EVENT_KINDS);
45090
+ NcSystemEventKindSchema.options.filter((kind) => !NC_LEGACY_SYSTEM_EVENT_KIND_SET.has(kind));
42718
45091
  /**
42719
45092
  * The panel's transitions, as ONE list.
42720
45093
  *
@@ -43237,7 +45610,7 @@ var NcConditionsSchema = object({
43237
45610
  * with the list under it is worse than no switch (D62).
43238
45611
  *
43239
45612
  * MEMBERS ARE FACE-GALLERY `Identity.id`s (uuid), not display names. A name is
43240
- * renameable, and a rule authored on "Gianluca" went silently dark the moment
45613
+ * renameable, and a rule authored on "Alice" went silently dark the moment
43241
45614
  * the operator fixed the spelling. The id reaches the record on
43242
45615
  * `LabelAttribution.identityId`; the name is what the editor shows and what
43243
45616
  * `{{label}}` renders.
@@ -43788,7 +46161,7 @@ var NcRulePatchSchema = NcRuleInputSchema.partial().extend({
43788
46161
  * A rule scoped to one camera and one zone silently became a rule that
43789
46162
  * matches EVERY event on EVERY camera, and lost its `media` policy
43790
46163
  * (zoneCrop / gif / clip / frame) and its `priority` at the same time. Seen
43791
- * live on 2026-08-12: a rule scoped to device 617 fired on 590 and 615
46164
+ * live on 2026-08-12: a rule scoped to device 102 fired on 104 and 101
43792
46165
  * within a minute of a two-field patch.
43793
46166
  *
43794
46167
  * So every defaulted field is re-declared here WITHOUT its default. The
@@ -43833,18 +46206,11 @@ var NcRuleSchema = NcRuleInputSchema.extend({
43833
46206
  */
43834
46207
  disabledTargetIds: array(string()).default([])
43835
46208
  });
43836
- /**
43837
- * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
43838
- * report a still-true state. `addons` is the crash-looped addons only and
43839
- * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
43840
- * job is not an open state, and the alarm stays instant.
43841
- */
43842
46209
  var NcStateSummarySectionIdSchema = _enum([
43843
46210
  "device-state",
43844
46211
  "streams",
43845
46212
  "battery",
43846
46213
  "consumables",
43847
- "tanks",
43848
46214
  "detection-blind",
43849
46215
  "nodes",
43850
46216
  "addons",
@@ -45608,7 +47974,7 @@ var LabelAttributionSchema = object({
45608
47974
  * `Identity.id` or a plate-gallery `Vehicle.id` (both `randomUUID`).
45609
47975
  *
45610
47976
  * The text alone is a DISPLAY NAME, and a display name is renameable: a
45611
- * notification rule authored on "Gianluca" stopped matching the moment the
47977
+ * notification rule authored on "Alice" stopped matching the moment the
45612
47978
  * operator fixed the spelling in the gallery, and nothing said so. The id is
45613
47979
  * the thing that does not move, so it is what a rule matches on
45614
47980
  * (`NcConditions.identities`) and the text is what a human is shown.
@@ -48147,7 +50513,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
48147
50513
  /**
48148
50514
  * Root-supplied detections for the tree's ROOT step (D730). Set by
48149
50515
  * `runDetailSubtree` when the camera's root model supplies a crop-kind
48150
- * step (a Frigate+ `license_plate` for `plate-detection`): the step is
50516
+ * step (a plus catalog `license_plate` for `plate-detection`): the step is
48151
50517
  * NOT inferred, these boxes are its output, and its children (the plate
48152
50518
  * reader) run on them through their own crop policy. Boxes are in the
48153
50519
  * PIXELS of the image this call carries. Absent ⇒ the root step runs.
@@ -49780,7 +52146,7 @@ var RunnerCameraConfigSchema = object({
49780
52146
  * detection session that asks for history. What shipped was a last-moment
49781
52147
  * discard — `FrameSlot`'s throttle compares wall clocks, and ~4 s of media
49782
52148
  * arriving inside a few hundred ms of wall clock looks to it like one frame's
49783
- * worth. Device 617, 2026-09-08: a re-run of the SAME model over the stored
52149
+ * worth. Device 102, 2026-09-08: a re-run of the SAME model over the stored
49784
52150
  * recording scored the subject `vehicle 0.5669` — above the 0.50 floor —
49785
52151
  * 1.68 s BEFORE the live track was born, on a frame that was in the pre-roll,
49786
52152
  * was decoded, and was freed.
@@ -51823,7 +54189,7 @@ method(_void(), ProviderInfoSchema, { auth: "admin" }), method(object({ config:
51823
54189
  * The signals a device can emit to WAKE its own stream.
51824
54190
  *
51825
54191
  * A camera whose stream is built on demand sleeps until something asks for it,
51826
- * and "something" cannot be a consumer that is merely attached — a Frigate-style
54192
+ * and "something" cannot be a consumer that is merely attached — a external-catalog
51827
54193
  * puller holds a session open for ever, and treating that as demand would keep
51828
54194
  * a battery camera awake for ever, which is the whole thing the battery is for
51829
54195
  * (D173). So the wake has to come from the CAMERA: an event it noticed by
@@ -52510,7 +54876,7 @@ var ClipSchema = object({
52510
54876
  * {@link MAX_CLIP_EVENT_IDS}. Empty on footage-only clips.
52511
54877
  *
52512
54878
  * Bounded because it is not a payload the surface pages through: one visit on
52513
- * device 615 carried 2 345 ids, and `eventIds` was 99% of a 153 KB
54879
+ * device 101 carried 2 345 ids, and `eventIds` was 99% of a 153 KB
52514
54880
  * camera-day. Read {@link eventCount} for the true total.
52515
54881
  */
52516
54882
  eventIds: array(string()).optional(),
@@ -52655,7 +55021,7 @@ var ClipPlaybackSchema = object({
52655
55021
  * camera has no recordings", which is the defect this whole line of work is
52656
55022
  * about: a battery camera nobody woke (`sleeping`), a camera that could not be
52657
55023
  * reached at all (`unreachable`, also what a provider that THREW reports), a
52658
- * camera whose SD card is not mounted (`no-storage`, measured on 640 —
55024
+ * camera whose SD card is not mounted (`no-storage`, measured on 106 —
52659
55025
  * `HddInfo mount 0`, honestly nothing to list rather than "no clips"), and a
52660
55026
  * camera whose OWN index disagrees with its OWN calendar (`index-empty`,
52661
55027
  * measured on 618: the calendar marks 3–20 September, days 6–20 list zero
@@ -52920,7 +55286,7 @@ DeviceType.Camera, method(object({
52920
55286
  *
52921
55287
  * It was optional, documented as "absent means the device's BOUND
52922
55288
  * provider, which is CamStack on every camera". No code implemented
52923
- * that. Measured on the live hub 2026-09-20 — device 592, bound to
55289
+ * that. Measured on the live hub 2026-09-20 — device 107, bound to
52924
55290
  * `recorder` AND `provider-reolink` — a bare call with `limit: 3`
52925
55291
  * answered SIX rows, three from each source, merged newest-first:
52926
55292
  * `device-collection-dispatch.ts` simply left the fan-out un-narrowed,
@@ -53998,7 +56364,10 @@ object({
53998
56364
  DeviceType.Sensor;
53999
56365
  object({
54000
56366
  /** Current illuminance in lux (lx). */
54001
- lux: number().min(0),
56367
+ lux: number().min(0).meta({
56368
+ unit: "lx",
56369
+ label: "Illuminance"
56370
+ }),
54002
56371
  /** Ms epoch when the slice was last updated. */
54003
56372
  lastFetchedAt: number(),
54004
56373
  /** Live display unit from the upstream source (e.g. HA
@@ -54154,7 +56523,10 @@ var BatteryStatusSchema = object({
54154
56523
  * Consumers must SKIP a null rather than coerce it — `battery-band` already
54155
56524
  * declines to band a non-finite reading, which is the correct shape.
54156
56525
  */
54157
- percentage: number().min(0).max(100).nullable(),
56526
+ percentage: number().min(0).max(100).nullable().meta({
56527
+ unit: "%",
56528
+ label: "Charge"
56529
+ }),
54158
56530
  /**
54159
56531
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
54160
56532
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -54173,13 +56545,13 @@ var BatteryStatusSchema = object({
54173
56545
  "solar",
54174
56546
  "none",
54175
56547
  "unknown"
54176
- ]),
56548
+ ]).meta({ label: "Charging source" }),
54177
56549
  /**
54178
56550
  * True when the camera firmware has gone into low-power mode. Battery
54179
56551
  * providers MUST avoid polling during sleep — reading the battery
54180
56552
  * wakes the camera up and drains charge.
54181
56553
  */
54182
- sleeping: boolean(),
56554
+ sleeping: boolean().meta({ label: "Sleeping" }),
54183
56555
  /** Ms epoch of the last observation. Lets consumers reason about freshness. */
54184
56556
  lastUpdated: number(),
54185
56557
  /**
@@ -54219,9 +56591,10 @@ var BatteryStatusSchema = object({
54219
56591
  * sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
54220
56592
  * misleading exact percentage. Absent/false → genuine 0–100 % reading.
54221
56593
  */
54222
- binary: boolean().optional()
56594
+ binary: boolean().optional().meta({ label: "Binary indicator" })
54223
56595
  });
54224
- DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, method(object({
56596
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat;
56597
+ method(object({
54225
56598
  deviceId: number(),
54226
56599
  /** Bound on the wait. Sensible range 3000–10000ms. */
54227
56600
  timeoutMs: number().int().min(500).max(3e4).default(8e3)
@@ -54233,7 +56606,7 @@ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, Devi
54233
56606
  status: BatteryStatusSchema
54234
56607
  });
54235
56608
  object({
54236
- on: boolean(),
56609
+ on: boolean().meta({ label: "On" }),
54237
56610
  /** Ms epoch of the last transition. 0 if never observed. */
54238
56611
  lastChangedAt: number()
54239
56612
  });
@@ -54501,7 +56874,7 @@ var GridLayoutCellSchema = object({
54501
56874
  *
54502
56875
  * A grid's `high` composes its sources' `high` and its `low` their `low`, so a
54503
56876
  * profile is on offer only when EVERY source can serve it. The refusal NAMES
54504
- * the sources, because "this grid has no low" is not a finding — "615 has no
56877
+ * the sources, because "this grid has no low" is not a finding — "101 has no
54505
56878
  * low" is, and it is the one an operator can act on.
54506
56879
  */
54507
56880
  var GridProfileOfferSchema = object({
@@ -54940,6 +57313,7 @@ var ConsumablesStatusSchema = object({
54940
57313
  })),
54941
57314
  lastChangedAt: number()
54942
57315
  });
57316
+ Object.values(DeviceType), [...ConsumableRemainingUnitSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
54943
57317
  Object.values(DeviceType), method(object({
54944
57318
  deviceId: number().int().nonnegative(),
54945
57319
  key: string().min(1)
@@ -55132,6 +57506,30 @@ DeviceType.Camera, method(object({ deviceId: number() }), DayNightOptionsSchema)
55132
57506
  auth: "admin"
55133
57507
  });
55134
57508
  /**
57509
+ * display-palette — the cluster's one colour table (D939).
57510
+ *
57511
+ * Hub singleton. `getPalette` reports `unknown` when the settings store
57512
+ * cannot be read; it does not pretend the bundled preset was stored.
57513
+ * `setPalette` refuses a palette that fails the ΔE / contrast rule and names
57514
+ * the pairs.
57515
+ */
57516
+ var presetSummarySchema = object({
57517
+ id: string(),
57518
+ name: string(),
57519
+ swatches: record(string(), paletteSwatchSchema),
57520
+ fallbacks: array(string())
57521
+ });
57522
+ method(_void(), paletteResultSchema, {
57523
+ auth: "protected",
57524
+ role: "viewer"
57525
+ }), method(_void(), array(presetSummarySchema).readonly(), {
57526
+ auth: "protected",
57527
+ role: "viewer"
57528
+ }), method(setPaletteInputSchema, paletteReadySchema, {
57529
+ kind: "mutation",
57530
+ auth: "admin"
57531
+ });
57532
+ /**
55135
57533
  * Generic device-level status snapshot. Auto-registered by `BaseDevice`
55136
57534
  * for every device, regardless of provider — the kernel needs a uniform
55137
57535
  * cap-keyed slice for the basic device flags every consumer expects to
@@ -55411,6 +57809,7 @@ DeviceType.Dishwasher, method(object({
55411
57809
  kind: "mutation",
55412
57810
  auth: "protected"
55413
57811
  }), method(object({ deviceId: DeviceIdSchema }), DishwasherOptionsSchema, { auth: "protected" });
57812
+ DeviceType.Camera;
55414
57813
  object({
55415
57814
  /** Ms epoch of the last press. null = never observed since this provider started. */
55416
57815
  lastPressedAt: number().nullable(),
@@ -56026,7 +58425,10 @@ DeviceType.Humidifier, method(object({
56026
58425
  });
56027
58426
  object({
56028
58427
  /** Current relative humidity, 0..100. */
56029
- percent: number().min(0).max(100),
58428
+ percent: number().min(0).max(100).meta({
58429
+ unit: "%",
58430
+ label: "Humidity"
58431
+ }),
56030
58432
  /** Ms epoch when the slice was last updated. */
56031
58433
  lastFetchedAt: number(),
56032
58434
  /** Live display unit from the upstream source (e.g. HA
@@ -57203,6 +59605,7 @@ authKey: string().optional() }), object({
57203
59605
  /** Human-readable error when `ok: false`. */
57204
59606
  error: string().optional()
57205
59607
  }), { kind: "mutation" });
59608
+ DeviceType.Camera;
57206
59609
  object({
57207
59610
  detected: boolean(),
57208
59611
  /** Ms epoch of the last detected-true observation. Null if never detected. */
@@ -58802,9 +61205,15 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
58802
61205
  });
58803
61206
  object({
58804
61207
  /** Instantaneous power draw in watts. */
58805
- watts: number().optional(),
61208
+ watts: number().optional().meta({
61209
+ unit: "W",
61210
+ label: "Power"
61211
+ }),
58806
61212
  /** Cumulative energy in kilowatt-hours since the meter was reset. */
58807
- kwhTotal: number().optional(),
61213
+ kwhTotal: number().optional().meta({
61214
+ unit: "kWh",
61215
+ label: "Energy"
61216
+ }),
58808
61217
  /** Voltage in volts. */
58809
61218
  volts: number().optional(),
58810
61219
  /** Current in amperes. */
@@ -59123,9 +61532,9 @@ var PtzOptionsSchema = object({
59123
61532
  * Reolink preset 0, Hikvision preset '1', Dahua preset 1 -- and on this fleet
59124
61533
  * not one of the three cameras honours its own:
59125
61534
  *
59126
- * 592 Videocamera camera Daniel (reolink) preset 0 holds "stanza"
59127
- * 1438 Videocamera dispensa (hikvision) preset 1 holds "Credenza"
59128
- * 3836 Videocamera studio (amcrest) preset 1 holds "Preset1"
61535
+ * 107 Camera camera Carol (reolink) preset 0 holds "stanza"
61536
+ * 1438 Camera dispensa (hikvision) preset 1 holds "Credenza"
61537
+ * 3836 Camera studio (amcrest) preset 1 holds "Preset1"
59129
61538
  *
59130
61539
  * So `goHome` meant "go wherever the operator happened to save in slot 0 or 1",
59131
61540
  * and two of the three swallowed the failure in a bare `catch`. For autotrack
@@ -59266,6 +61675,24 @@ DeviceType.Camera, method(object({ deviceId: number() }), PtzAutotrackStatusSche
59266
61675
  deviceId: number(),
59267
61676
  status: PtzAutotrackStatusSchema
59268
61677
  });
61678
+ var RunningStateSourceSchema = _enum(["native", "assigned"]);
61679
+ object({
61680
+ /** null = unknown — never coerced to false (D393). */
61681
+ running: boolean().nullable(),
61682
+ /** Epoch ms the current boolean began; null while `running` is null. */
61683
+ since: number().nullable(),
61684
+ source: RunningStateSourceSchema.meta({ label: "Source" }),
61685
+ phase: string().nullable(),
61686
+ /** null until a reading has been published (D393). */
61687
+ lastFetchedAt: number().nullable()
61688
+ });
61689
+ object({
61690
+ deviceId: number(),
61691
+ since: number().nullable(),
61692
+ phase: string().nullable()
61693
+ });
61694
+ Object.values(DeviceType);
61695
+ DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
59269
61696
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
59270
61697
  kind: "mutation",
59271
61698
  auth: "admin"
@@ -59307,7 +61734,7 @@ var RecordingAvailabilitySchema = object({
59307
61734
  * would look identical. But the answer used to say nothing about that, so a
59308
61735
  * caller asking "what can I export?" read the single preferred profile as
59309
61736
  * the only one that exists — on this deployment every camera records `high`
59310
- * AND `low`, the low tree holding 14 GB for camera 615 alone, and the export
61737
+ * AND `low`, the low tree holding 14 GB for camera 101 alone, and the export
59311
61738
  * UI could not see it.
59312
61739
  *
59313
61740
  * Cheap: it is the same shallow directory read the profile CHOICE already
@@ -59406,7 +61833,7 @@ var RecordingSourceOptionsSchema = object({
59406
61833
  * `sparse` = gaps are the absence of one, and must be drawn as such.
59407
61834
  *
59408
61835
  * Not an onboard-only concession: measured 2026-09-24, OUR bar covers 98.8 %
59409
- * of 592's day and 1.2 % of 1436's. It is a fact about a (source, camera)
61836
+ * of 107's day and 1.2 % of 1436's. It is a fact about a (source, camera)
59410
61837
  * pair, and ours answers it per camera from `deriveRecordingMode`. */
59411
61838
  coverage: _enum(["continuous", "sparse"]),
59412
61839
  /** Where the playhead may be put.
@@ -59482,7 +61909,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(RecordingSourceS
59482
61909
  * merely discouraged (D554 amended).
59483
61910
  *
59484
61911
  * It was learned the expensive way on `videoclips.listClips`: measured
59485
- * on the live hub 2026-09-20, device 592 bound to `recorder` AND
61912
+ * on the live hub 2026-09-20, device 107 bound to `recorder` AND
59486
61913
  * `provider-reolink`, a bare call with `limit: 3` answered SIX rows,
59487
61914
  * three from each source, merged — `device-collection-dispatch.ts`
59488
61915
  * leaves an unpinned fan-out un-narrowed, so absence buys the union the
@@ -60083,7 +62510,7 @@ var ExportSpeedSchema = number().min(.25).max(32);
60083
62510
  * on a 10 h window holding 29,393 s of footage every range landed late by the
60084
62511
  * gap accumulated before it — up to 6,607 s, well past EOF. Nothing matched,
60085
62512
  * the video was a uniform timelapse, and the log line reported the five ranges
60086
- * that had been ASKED for (2026-08-13, export `57d14363`, camera 615).
62513
+ * that had been ASKED for (2026-08-13, export `57d14363`, camera 101).
60087
62514
  *
60088
62515
  * Relative and not absolute epoch, because an absolute epoch would make every
60089
62516
  * call site responsible for the same subtraction.
@@ -60717,7 +63144,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), RecordingSignalStatusS
60717
63144
  * which put a "Scenes" tab on one camera's detail page. That is the wrong shape
60718
63145
  * for the thing: a scene is a standing question about the property ("is the bin
60719
63146
  * still out"), and the operator's question is "which of my scenes have tripped",
60720
- * across every camera at once — not "what does camera 617 think". Buried one
63147
+ * across every camera at once — not "what does camera 102 think". Buried one
60721
63148
  * camera deep it also could not be found. The surface is now a top-level admin
60722
63149
  * page (`/scenes`, `pages/Scenes.tsx`) that lists every scene on every camera and
60723
63150
  * picks the camera inside the create flow, the same shape Events and Faces have.
@@ -61300,7 +63727,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), StreamParamsOptionsSch
61300
63727
  auth: "admin"
61301
63728
  }), method(object({ deviceId: number() }), unknown().nullable());
61302
63729
  object({
61303
- on: boolean(),
63730
+ on: boolean().meta({ label: "On" }),
61304
63731
  /** Ms epoch of the last state change. Useful for UI "X minutes ago". */
61305
63732
  lastChangedAt: number()
61306
63733
  });
@@ -61863,7 +64290,10 @@ object({
61863
64290
  DeviceType.Sensor;
61864
64291
  object({
61865
64292
  /** Current temperature in Celsius. */
61866
- celsius: number(),
64293
+ celsius: number().meta({
64294
+ unit: "°C",
64295
+ label: "Temperature"
64296
+ }),
61867
64297
  /** Ms epoch when the slice was last updated (push or poll). */
61868
64298
  lastFetchedAt: number(),
61869
64299
  /** Live display unit from the upstream source (e.g. HA
@@ -63011,6 +65441,10 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
63011
65441
  auth: "admin"
63012
65442
  });
63013
65443
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
65444
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Camera, DeviceType.Camera, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
65445
+ String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
65446
+ DeviceRole.BinarySensor, DeviceRole.MotionSensor;
65447
+ new Set(CAP_NAMES);
63014
65448
  Object.freeze({
63015
65449
  person: .5,
63016
65450
  vehicle: .5,
@@ -66010,6 +68444,27 @@ Object.freeze({
66010
68444
  access: "create",
66011
68445
  role: "viewer"
66012
68446
  },
68447
+ "displayPalette.getPalette": {
68448
+ capName: "display-palette",
68449
+ capScope: "system",
68450
+ addonId: null,
68451
+ access: "view",
68452
+ role: "viewer"
68453
+ },
68454
+ "displayPalette.listPresets": {
68455
+ capName: "display-palette",
68456
+ capScope: "system",
68457
+ addonId: null,
68458
+ access: "view",
68459
+ role: "viewer"
68460
+ },
68461
+ "displayPalette.setPalette": {
68462
+ capName: "display-palette",
68463
+ capScope: "system",
68464
+ addonId: null,
68465
+ access: "create",
68466
+ role: "admin"
68467
+ },
66013
68468
  "doorbell.getStatus": {
66014
68469
  capName: "doorbell",
66015
68470
  capScope: "device",
@@ -70560,6 +73015,13 @@ Object.freeze({
70560
73015
  access: "create",
70561
73016
  role: "admin"
70562
73017
  },
73018
+ "runningState.getStatus": {
73019
+ capName: "running-state",
73020
+ capScope: "device",
73021
+ addonId: null,
73022
+ access: "view",
73023
+ role: "viewer"
73024
+ },
70563
73025
  "sceneMonitor.captureReference": {
70564
73026
  capName: "scene-monitor",
70565
73027
  capScope: "device",
@@ -75274,6 +77736,32 @@ var APPLIANCE_CAP_VOCABULARY = {
75274
77736
  }],
75275
77737
  events: { onSent: { notOperatorFacing: "a delivery receipt of a send this system made — not a fact about the world" } }
75276
77738
  },
77739
+ "running-state": {
77740
+ scope: "device",
77741
+ noun: t("Running", "In funzione"),
77742
+ state: [{
77743
+ kind: "boolean",
77744
+ field: "running",
77745
+ label: t("Running", "In funzione"),
77746
+ whenTrue: t("When {device} starts", "Quando {device} inizia"),
77747
+ whenFalse: t("When {device} finishes", "Quando {device} finisce"),
77748
+ icon: "play"
77749
+ }],
77750
+ events: {
77751
+ onStarted: {
77752
+ category: EventCategory.RunningStarted,
77753
+ label: t("Started running", "Ha iniziato a funzionare"),
77754
+ phrase: t("When {device} starts running", "Quando {device} inizia a funzionare"),
77755
+ icon: "play"
77756
+ },
77757
+ onFinished: {
77758
+ category: EventCategory.RunningFinished,
77759
+ label: t("Finished", "Ha finito"),
77760
+ phrase: t("When {device} finishes", "Quando {device} finisce"),
77761
+ icon: "square"
77762
+ }
77763
+ }
77764
+ },
75277
77765
  update: {
75278
77766
  scope: "device",
75279
77767
  noun: t("Firmware update", "Aggiornamento firmware"),
@@ -75894,7 +78382,7 @@ var SENSOR_CAP_VOCABULARY = {
75894
78382
  state: [{
75895
78383
  kind: "boolean",
75896
78384
  field: "on",
75897
- label: t("Active", "Attivo"),
78385
+ label: t("On", "Acceso"),
75898
78386
  whenTrue: t("When {device} turns active", "Quando {device} si attiva"),
75899
78387
  whenFalse: t("When {device} turns inactive", "Quando {device} si disattiva"),
75900
78388
  icon: "toggle-right"
@@ -76433,6 +78921,7 @@ var SYSTEM_CAP_VOCABULARY = {
76433
78921
  "device-provider": system(INTERNAL),
76434
78922
  "device-removal-hook": system(INTERNAL),
76435
78923
  "device-state": system("the runtime-state mirror every trigger already reads through"),
78924
+ "display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
76436
78925
  "embedding-encoder": system(ML),
76437
78926
  "face-gallery": system("the face gallery — curated on its own page"),
76438
78927
  "failure-contribution": system(INTERNAL),
@@ -78814,6 +81303,11 @@ Object.freeze({
78814
81303
  form: "single",
78815
81304
  optional: true
78816
81305
  }],
81306
+ "runningState.getStatus": [{
81307
+ name: "deviceId",
81308
+ form: "single",
81309
+ optional: false
81310
+ }],
78817
81311
  "sceneMonitor.captureReference": [{
78818
81312
  name: "deviceId",
78819
81313
  form: "single",
@@ -79312,6 +81806,99 @@ Object.freeze({
79312
81806
  "smtp-provider": "email"
79313
81807
  });
79314
81808
  DeviceType.Camera;
81809
+ /**
81810
+ * A saved Customize assignment (D936). The schema is the type: callers use
81811
+ * `z.infer`, they do not restate the shape.
81812
+ */
81813
+ var OverrideSourceSchema = object({
81814
+ addonId: string().min(1),
81815
+ stableId: string().min(1),
81816
+ cap: string().min(1),
81817
+ fieldPath: string().min(1)
81818
+ });
81819
+ var CustomizeTransformDraftSchema = discriminatedUnion("kind", [
81820
+ object({ kind: literal("identity") }),
81821
+ object({ kind: literal("invert") }),
81822
+ object({
81823
+ kind: literal("threshold"),
81824
+ comparison: _enum(["gte", "lte"]),
81825
+ threshold: number(),
81826
+ startDwellMs: number().nonnegative(),
81827
+ stopDwellMs: number().nonnegative()
81828
+ }),
81829
+ object({
81830
+ kind: literal("linear"),
81831
+ scale: number(),
81832
+ offset: number(),
81833
+ clampMin: number().optional(),
81834
+ clampMax: number().optional()
81835
+ }),
81836
+ object({
81837
+ kind: literal("enum-map"),
81838
+ mapping: record(string(), string().nullable())
81839
+ }),
81840
+ object({ kind: literal("number") })
81841
+ ]);
81842
+ var ScalarOverrideDraftSchema = object({
81843
+ kind: literal("scalar"),
81844
+ cap: string().min(1),
81845
+ targetId: string().min(1),
81846
+ source: OverrideSourceSchema,
81847
+ transform: CustomizeTransformDraftSchema
81848
+ });
81849
+ var KeyedArrayOverrideDraftSchema = object({
81850
+ kind: literal("keyedArray"),
81851
+ cap: string().min(1),
81852
+ targetId: string().min(1),
81853
+ key: string().min(1),
81854
+ label: string().min(1),
81855
+ fieldPath: string().min(1),
81856
+ source: OverrideSourceSchema,
81857
+ transform: CustomizeTransformDraftSchema
81858
+ });
81859
+ var PulseOverrideDraftSchema = object({
81860
+ kind: literal("pulse"),
81861
+ cap: string().min(1),
81862
+ targetId: string().min(1),
81863
+ enabled: boolean(),
81864
+ debounceMs: number().nonnegative(),
81865
+ edges: array(_enum([
81866
+ "rising",
81867
+ "button",
81868
+ "native-event"
81869
+ ])).min(1).optional(),
81870
+ sources: array(OverrideSourceSchema).min(1)
81871
+ });
81872
+ var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
81873
+ "in-addition",
81874
+ "confirm",
81875
+ "replace"
81876
+ ]).optional() });
81877
+ discriminatedUnion("kind", [
81878
+ ScalarOverrideDraftSchema,
81879
+ KeyedArrayOverrideDraftSchema,
81880
+ PulseOverrideDraftSchema,
81881
+ object({
81882
+ kind: literal("span"),
81883
+ cap: string().min(1),
81884
+ targetId: string().min(1),
81885
+ timeoutMs: number().nonnegative(),
81886
+ cooldownMs: number().nonnegative().optional(),
81887
+ sources: array(SpanSourceDraftSchema)
81888
+ })
81889
+ ]);
81890
+ object({
81891
+ targetId: string().min(1),
81892
+ configured: boolean(),
81893
+ source: _enum(["native", "assigned"]),
81894
+ state: _enum([
81895
+ "active",
81896
+ "stale",
81897
+ "released",
81898
+ "unavailable"
81899
+ ]),
81900
+ reason: string().nullable()
81901
+ });
79315
81902
  var G711_SCALE_CORRECTION_DB = {
79316
81903
  PCMU: 20 * Math.log10(4),
79317
81904
  PCMA: 20 * Math.log10(8)
@@ -79364,40 +81951,7 @@ var NC_AUDIO_DEFAULTS = {
79364
81951
  samplingSeconds: 10
79365
81952
  };
79366
81953
  new Set(["devices", "classes"]);
79367
- /**
79368
- * WHICH narrowing filter speaks about WHICH system-event kind — one predicate,
79369
- * consumed by the rule ENGINE and by every rule EDITOR.
79370
- *
79371
- * ── The failure this file exists for ───────────────────────────────────────
79372
- * `NcSystemEventConditionSchema` carries four optional narrowing lists
79373
- * (`deviceIds`, `deviceTypes`, `nodeIds`, `packageNames`) beside a required
79374
- * `kinds` gate. They are not four filters over one vocabulary: each belongs to
79375
- * a FAMILY of kinds and is meaningless outside it. A node going away has no
79376
- * device type; a completed export has no package; `stream-offline` deliberately
79377
- * carries no device type at all (a stream belongs to a camera by construction).
79378
- *
79379
- * The engine applied all four to every kind, so a filter from one family failed
79380
- * a kind from another family CLOSED. The operator's live rule "Eventi di
79381
- * sistema" selected eleven kinds and set `deviceTypes: ['camera']` — the only
79382
- * way to say "only my cameras" about the two liveness kinds — and NINE of the
79383
- * eleven silently stopped being deliverable. Four days of history contained
79384
- * `device-online` and `device-offline` and nothing else, across a window in
79385
- * which agents were restarted and addons were updated.
79386
- *
79387
- * Both editors already computed this scoping, to decide which filter boxes to
79388
- * render; the cap's own docblock already promised it ("Narrow a `device-*` kind
79389
- * to these device TYPES"). Only the engine disagreed, and it disagreed in the
79390
- * destructive direction. So the rule is stated ONCE, here, and the engine and
79391
- * the editors are readers of it rather than three independent authors.
79392
- *
79393
- * ── The direction ─────────────────────────────────────────────────────────
79394
- * Out of family ⇒ the filter is IGNORED, never fail-closed. An editor that
79395
- * hides a box has already told the operator this filter does not speak about
79396
- * these kinds, so honouring it as an exclusion contradicts the only
79397
- * explanation the operator was ever given. Inside its family the filter still
79398
- * narrows, and still fails CLOSED on a subject that cannot produce the identity
79399
- * it tests (a device the mirror cannot name is not evidence of a camera).
79400
- */
81954
+ new Set(NC_LEGACY_SYSTEM_EVENT_KINDS);
79401
81955
  /**
79402
81956
  * Every filter, for the callers that must cover all of them (guards, tests).
79403
81957
  *
@@ -79423,9 +81977,6 @@ new Map(Object.entries({
79423
81977
  "device-battery-normal": "device-events",
79424
81978
  "device-consumable-low": "device-events",
79425
81979
  "device-consumable-normal": "device-events",
79426
- "device-tank-low": "device-events",
79427
- "device-tank-full": "device-events",
79428
- "device-tank-normal": "device-events",
79429
81980
  "stream-online": "device-events",
79430
81981
  "stream-offline": "device-events",
79431
81982
  "detection-blind": "device-events",
@@ -79502,16 +82053,6 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
79502
82053
  label: "Consumables",
79503
82054
  kinds: ["device-consumable-low", "device-consumable-normal"]
79504
82055
  },
79505
- {
79506
- id: "tanks",
79507
- family: "device-events",
79508
- label: "Tanks",
79509
- kinds: [
79510
- "device-tank-low",
79511
- "device-tank-full",
79512
- "device-tank-normal"
79513
- ]
79514
- },
79515
82056
  {
79516
82057
  id: "detection-blind",
79517
82058
  family: "device-events",
@@ -79669,11 +82210,6 @@ var RULE_BODY_ONLY = ["body"];
79669
82210
  var RULE_TEXT = ["title", "body"];
79670
82211
  var BATTERY = ["device-battery-low", "device-battery-normal"];
79671
82212
  var CONSUMABLE = ["device-consumable-low", "device-consumable-normal"];
79672
- var TANK = [
79673
- "device-tank-low",
79674
- "device-tank-full",
79675
- "device-tank-normal"
79676
- ];
79677
82213
  var ALERT_EPISODE = [
79678
82214
  "alert-critical",
79679
82215
  "alert-error",
@@ -79705,7 +82241,6 @@ var DEVICE_EVENTS = [
79705
82241
  "device-enabled",
79706
82242
  ...BATTERY,
79707
82243
  ...CONSUMABLE,
79708
- ...TANK,
79709
82244
  "stream-online",
79710
82245
  "stream-offline",
79711
82246
  "detection-blind",
@@ -79736,7 +82271,7 @@ var STATE_SUMMARY_SECTION_VARS = [
79736
82271
  {
79737
82272
  name: "summaryStreams",
79738
82273
  label: "Summary: streams offline",
79739
- example: "Ingresso (high) — since 06:40",
82274
+ example: "Front door (high) — since 06:40",
79740
82275
  kinds: ["stream-offline", "stream-online"]
79741
82276
  },
79742
82277
  {
@@ -79751,22 +82286,16 @@ var STATE_SUMMARY_SECTION_VARS = [
79751
82286
  example: "Robot — filter 10 %",
79752
82287
  kinds: CONSUMABLE
79753
82288
  },
79754
- {
79755
- name: "summaryTanks",
79756
- label: "Summary: tanks",
79757
- example: "Robot — clean water low",
79758
- kinds: TANK
79759
- },
79760
82289
  {
79761
82290
  name: "summaryDetection",
79762
82291
  label: "Summary: cameras detecting nothing",
79763
- example: "Ingresso — since 05:10",
82292
+ example: "Front door — since 05:10",
79764
82293
  kinds: ["detection-blind"]
79765
82294
  },
79766
82295
  {
79767
82296
  name: "summaryNodes",
79768
82297
  label: "Summary: nodes",
79769
- example: "little-unraid — offline since 03:00",
82298
+ example: "agent-a — offline since 03:00",
79770
82299
  kinds: [
79771
82300
  "node-offline",
79772
82301
  "node-online",
@@ -79872,8 +82401,7 @@ var STATE_SUMMARY_VARS = [
79872
82401
  ([...RULE_TEXT], [...COMBINED_ALARM]),
79873
82402
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
79874
82403
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
79875
- ([...RULE_TEXT], [...CONSUMABLE, ...TANK]),
79876
- ([...RULE_TEXT], [...TANK]),
82404
+ ([...RULE_TEXT], [...CONSUMABLE]),
79877
82405
  [...RULE_TEXT],
79878
82406
  ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
79879
82407
  ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
@@ -79977,15 +82505,6 @@ new Map([
79977
82505
  snapshotLabel: "Consumables low now",
79978
82506
  snapshotSection: "consumables"
79979
82507
  },
79980
- {
79981
- id: "tanks",
79982
- family: "device-events",
79983
- label: "Tanks (low or full / back to normal)",
79984
- bad: ["device-tank-low", "device-tank-full"],
79985
- recovery: ["device-tank-normal"],
79986
- snapshotLabel: "Tanks low or full now",
79987
- snapshotSection: "tanks"
79988
- },
79989
82508
  {
79990
82509
  id: "motion-noise",
79991
82510
  family: "device-events",