@camstack/addon-google-services 0.2.29 → 0.2.30

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