@camstack/addon-pipeline-orchestrator 1.2.626 → 1.2.628
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/viewer/_expo/static/js/web/__common-163c8c9d580e1ed65a82e210e457d9e4.js +4 -4
- package/assets/viewer/_expo/static/js/web/__common-a465d4a66f5773164f88445ca3126ea7.js +4 -4
- package/assets/viewer/embed/assets/index-DqLzhEZ4.js +2 -2
- package/dist/_stub.js +2 -2
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-CgmNXxjG.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-D80kWqs3.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BKwlDxqb.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BbK27IRf.mjs +26 -0
- package/dist/{hostInit-DCfHeLoh.mjs → hostInit-C__mhGsK.mjs} +3 -3
- package/dist/index.js +2922 -139
- package/dist/index.mjs +2922 -139
- package/dist/remoteEntry.js +1 -1
- package/package.json +4 -1
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-tzzi8EPR.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BvrkWanW.mjs +0 -26
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
//#region ../types/dist/event-category-
|
|
5
|
+
//#region ../types/dist/event-category-DHXxB8t9.mjs
|
|
6
6
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
7
7
|
EventCategory["SystemBoot"] = "system.boot";
|
|
8
8
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -298,7 +298,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
298
298
|
* TRANSITION into that state (never per dispatch), and the node is dropped
|
|
299
299
|
* from the placement candidate set for as long as it holds.
|
|
300
300
|
*
|
|
301
|
-
* This exists because the state was previously invisible:
|
|
301
|
+
* This exists because the state was previously invisible: agent-a
|
|
302
302
|
* absorbed 283k inference errors in a day while still being handed cameras,
|
|
303
303
|
* and nothing in the system said so.
|
|
304
304
|
*
|
|
@@ -5570,7 +5570,7 @@ var ZodIssueCode = {
|
|
|
5570
5570
|
var ZodFirstPartyTypeKind;
|
|
5571
5571
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5572
5572
|
//#endregion
|
|
5573
|
-
//#region ../types/dist/sleep-
|
|
5573
|
+
//#region ../types/dist/sleep-BErAxhul.mjs
|
|
5574
5574
|
/**
|
|
5575
5575
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5576
5576
|
* window to float samples (D455).
|
|
@@ -9232,7 +9232,7 @@ var viewerUiCapability = {
|
|
|
9232
9232
|
* `getStaticDir` leaks a hub filesystem path.
|
|
9233
9233
|
*
|
|
9234
9234
|
* ⚠ Checked before gating: the VIEWER app IS used by a non-admin user
|
|
9235
|
-
* (`
|
|
9235
|
+
* (`bob`), but it never calls `viewerUi.*` over tRPC. The static SPA
|
|
9236
9236
|
* it loads is served by the plain `GET /viewer/*` Fastify route in
|
|
9237
9237
|
* `main.ts`, which reads `staticDir`/`indexPath` from a module-level
|
|
9238
9238
|
* cache populated ONCE at boot via `capRegistry.getSingletonForNode`
|
|
@@ -9307,6 +9307,1980 @@ method(object({ deviceId: number() }), array(StreamSourceEntrySchema)), method(o
|
|
|
9307
9307
|
kind: "mutation",
|
|
9308
9308
|
auth: "admin"
|
|
9309
9309
|
}), method(object({ deviceId: number() }), unknown().nullable()), method(object({ deviceId: number() }), RawStateResultSchema.nullable(), { auth: "protected" });
|
|
9310
|
+
Object.freeze({ "doorbell": "lastPressedAt" });
|
|
9311
|
+
/** Every capability name, so addon code can check a name without the schema graph. */
|
|
9312
|
+
var CAP_NAMES = Object.freeze([
|
|
9313
|
+
"accessories",
|
|
9314
|
+
"addon-pages",
|
|
9315
|
+
"addon-pages-source",
|
|
9316
|
+
"addon-routes",
|
|
9317
|
+
"addon-settings",
|
|
9318
|
+
"addon-widgets",
|
|
9319
|
+
"addon-widgets-source",
|
|
9320
|
+
"addons",
|
|
9321
|
+
"admin-ui",
|
|
9322
|
+
"air-quality-sensor",
|
|
9323
|
+
"alarm-panel",
|
|
9324
|
+
"alerts",
|
|
9325
|
+
"ambient-light-sensor",
|
|
9326
|
+
"audio-analysis",
|
|
9327
|
+
"audio-analyzer",
|
|
9328
|
+
"audio-codec",
|
|
9329
|
+
"audio-metrics",
|
|
9330
|
+
"auth-provider",
|
|
9331
|
+
"automation-control",
|
|
9332
|
+
"backup",
|
|
9333
|
+
"battery",
|
|
9334
|
+
"binary",
|
|
9335
|
+
"brightness",
|
|
9336
|
+
"broker",
|
|
9337
|
+
"button",
|
|
9338
|
+
"calendar-source",
|
|
9339
|
+
"calendars",
|
|
9340
|
+
"camera-credentials",
|
|
9341
|
+
"camera-grid-layout",
|
|
9342
|
+
"camera-pipeline-config",
|
|
9343
|
+
"camera-streams",
|
|
9344
|
+
"carbon-monoxide",
|
|
9345
|
+
"climate-control",
|
|
9346
|
+
"color",
|
|
9347
|
+
"composer",
|
|
9348
|
+
"connection-test",
|
|
9349
|
+
"connectivity",
|
|
9350
|
+
"consumables",
|
|
9351
|
+
"contact",
|
|
9352
|
+
"control",
|
|
9353
|
+
"core-blocks",
|
|
9354
|
+
"cover",
|
|
9355
|
+
"custom-model-registry",
|
|
9356
|
+
"data-store-provider",
|
|
9357
|
+
"database-snapshot",
|
|
9358
|
+
"day-night",
|
|
9359
|
+
"decoder",
|
|
9360
|
+
"detection-pipeline",
|
|
9361
|
+
"device-admin-link",
|
|
9362
|
+
"device-adoption",
|
|
9363
|
+
"device-credentials",
|
|
9364
|
+
"device-discovery",
|
|
9365
|
+
"device-export",
|
|
9366
|
+
"device-extension",
|
|
9367
|
+
"device-history",
|
|
9368
|
+
"device-manager",
|
|
9369
|
+
"device-ops",
|
|
9370
|
+
"device-provider",
|
|
9371
|
+
"device-removal-hook",
|
|
9372
|
+
"device-state",
|
|
9373
|
+
"device-status",
|
|
9374
|
+
"dishwasher",
|
|
9375
|
+
"display-palette",
|
|
9376
|
+
"doorbell",
|
|
9377
|
+
"embedding-encoder",
|
|
9378
|
+
"enum-sensor",
|
|
9379
|
+
"event-emitter",
|
|
9380
|
+
"face-gallery",
|
|
9381
|
+
"failure-contribution",
|
|
9382
|
+
"fan-control",
|
|
9383
|
+
"feature-probe",
|
|
9384
|
+
"filesystem-browse",
|
|
9385
|
+
"flood",
|
|
9386
|
+
"gas",
|
|
9387
|
+
"heating-valve",
|
|
9388
|
+
"humidifier",
|
|
9389
|
+
"humidity-sensor",
|
|
9390
|
+
"image",
|
|
9391
|
+
"image-settings",
|
|
9392
|
+
"integrations",
|
|
9393
|
+
"intercom",
|
|
9394
|
+
"keychain",
|
|
9395
|
+
"keychain-admin",
|
|
9396
|
+
"lawn-mower-control",
|
|
9397
|
+
"llm",
|
|
9398
|
+
"llm-runtime",
|
|
9399
|
+
"load-contribution",
|
|
9400
|
+
"local-network",
|
|
9401
|
+
"lock-control",
|
|
9402
|
+
"log-channels",
|
|
9403
|
+
"log-destination",
|
|
9404
|
+
"login-method",
|
|
9405
|
+
"media-player",
|
|
9406
|
+
"mesh-network",
|
|
9407
|
+
"metrics-provider",
|
|
9408
|
+
"model-convert",
|
|
9409
|
+
"model-distributor",
|
|
9410
|
+
"motion",
|
|
9411
|
+
"motion-detection",
|
|
9412
|
+
"motion-trigger",
|
|
9413
|
+
"motion-zones",
|
|
9414
|
+
"mqtt-broker",
|
|
9415
|
+
"native-object-detection",
|
|
9416
|
+
"navigation",
|
|
9417
|
+
"network-access",
|
|
9418
|
+
"network-link",
|
|
9419
|
+
"network-quality",
|
|
9420
|
+
"node-certificates",
|
|
9421
|
+
"nodes",
|
|
9422
|
+
"notification-output",
|
|
9423
|
+
"notification-rules",
|
|
9424
|
+
"notifier",
|
|
9425
|
+
"numeric-sensor",
|
|
9426
|
+
"oauth-integration",
|
|
9427
|
+
"oidc-connections",
|
|
9428
|
+
"osd",
|
|
9429
|
+
"osd-manager",
|
|
9430
|
+
"pet-feeder",
|
|
9431
|
+
"pipeline-analytics",
|
|
9432
|
+
"pipeline-executor",
|
|
9433
|
+
"pipeline-orchestrator",
|
|
9434
|
+
"pipeline-runner",
|
|
9435
|
+
"plate-gallery",
|
|
9436
|
+
"platform-probe",
|
|
9437
|
+
"power-meter",
|
|
9438
|
+
"presence",
|
|
9439
|
+
"pressure-sensor",
|
|
9440
|
+
"privacy-mask",
|
|
9441
|
+
"ptz",
|
|
9442
|
+
"ptz-autotrack",
|
|
9443
|
+
"reboot",
|
|
9444
|
+
"record-entries",
|
|
9445
|
+
"recording",
|
|
9446
|
+
"recording-archive",
|
|
9447
|
+
"recording-export",
|
|
9448
|
+
"recording-onboard",
|
|
9449
|
+
"recording-signal",
|
|
9450
|
+
"records",
|
|
9451
|
+
"running-state",
|
|
9452
|
+
"scene-monitor",
|
|
9453
|
+
"script-runner",
|
|
9454
|
+
"server-management",
|
|
9455
|
+
"settings-store",
|
|
9456
|
+
"smoke",
|
|
9457
|
+
"smtp-provider",
|
|
9458
|
+
"snapshot",
|
|
9459
|
+
"sso-bridge",
|
|
9460
|
+
"storage",
|
|
9461
|
+
"storage-admin",
|
|
9462
|
+
"storage-evictable",
|
|
9463
|
+
"storage-migration",
|
|
9464
|
+
"storage-occupancy",
|
|
9465
|
+
"storage-provider",
|
|
9466
|
+
"stream-broker",
|
|
9467
|
+
"stream-catalog",
|
|
9468
|
+
"stream-params",
|
|
9469
|
+
"stream-signals",
|
|
9470
|
+
"switch",
|
|
9471
|
+
"system",
|
|
9472
|
+
"tamper",
|
|
9473
|
+
"temperature-sensor",
|
|
9474
|
+
"terminal-session",
|
|
9475
|
+
"toast",
|
|
9476
|
+
"training",
|
|
9477
|
+
"training-provider",
|
|
9478
|
+
"turn-provider",
|
|
9479
|
+
"update",
|
|
9480
|
+
"user-management",
|
|
9481
|
+
"user-passkeys",
|
|
9482
|
+
"vacuum-control",
|
|
9483
|
+
"valve",
|
|
9484
|
+
"vector-store",
|
|
9485
|
+
"vibration",
|
|
9486
|
+
"videoclips",
|
|
9487
|
+
"viewer-ui",
|
|
9488
|
+
"water-heater",
|
|
9489
|
+
"weather",
|
|
9490
|
+
"webrtc-session",
|
|
9491
|
+
"zone-analytics",
|
|
9492
|
+
"zone-rules",
|
|
9493
|
+
"zones"
|
|
9494
|
+
]);
|
|
9495
|
+
Object.freeze({
|
|
9496
|
+
"air-quality-sensor": [
|
|
9497
|
+
{
|
|
9498
|
+
"path": "co2Ppm",
|
|
9499
|
+
"valueType": "number"
|
|
9500
|
+
},
|
|
9501
|
+
{
|
|
9502
|
+
"path": "vocPpb",
|
|
9503
|
+
"valueType": "number"
|
|
9504
|
+
},
|
|
9505
|
+
{
|
|
9506
|
+
"path": "pm25",
|
|
9507
|
+
"valueType": "number"
|
|
9508
|
+
},
|
|
9509
|
+
{
|
|
9510
|
+
"path": "pm10",
|
|
9511
|
+
"valueType": "number"
|
|
9512
|
+
},
|
|
9513
|
+
{
|
|
9514
|
+
"path": "aqi",
|
|
9515
|
+
"valueType": "number"
|
|
9516
|
+
},
|
|
9517
|
+
{
|
|
9518
|
+
"path": "unit",
|
|
9519
|
+
"valueType": "string"
|
|
9520
|
+
},
|
|
9521
|
+
{
|
|
9522
|
+
"path": "precision",
|
|
9523
|
+
"valueType": "number"
|
|
9524
|
+
}
|
|
9525
|
+
],
|
|
9526
|
+
"alarm-panel": [
|
|
9527
|
+
{
|
|
9528
|
+
"path": "state",
|
|
9529
|
+
"valueType": "enum",
|
|
9530
|
+
"enumValues": [
|
|
9531
|
+
"disarmed",
|
|
9532
|
+
"armed_home",
|
|
9533
|
+
"armed_away",
|
|
9534
|
+
"armed_night",
|
|
9535
|
+
"armed_vacation",
|
|
9536
|
+
"armed_custom_bypass",
|
|
9537
|
+
"arming",
|
|
9538
|
+
"disarming",
|
|
9539
|
+
"pending",
|
|
9540
|
+
"triggered"
|
|
9541
|
+
]
|
|
9542
|
+
},
|
|
9543
|
+
{
|
|
9544
|
+
"path": "targetMode",
|
|
9545
|
+
"valueType": "enum",
|
|
9546
|
+
"enumValues": [
|
|
9547
|
+
"home",
|
|
9548
|
+
"away",
|
|
9549
|
+
"night",
|
|
9550
|
+
"vacation",
|
|
9551
|
+
"custom_bypass"
|
|
9552
|
+
]
|
|
9553
|
+
},
|
|
9554
|
+
{
|
|
9555
|
+
"path": "requiresCode",
|
|
9556
|
+
"valueType": "boolean"
|
|
9557
|
+
}
|
|
9558
|
+
],
|
|
9559
|
+
"ambient-light-sensor": [
|
|
9560
|
+
{
|
|
9561
|
+
"path": "lux",
|
|
9562
|
+
"valueType": "number"
|
|
9563
|
+
},
|
|
9564
|
+
{
|
|
9565
|
+
"path": "unit",
|
|
9566
|
+
"valueType": "string"
|
|
9567
|
+
},
|
|
9568
|
+
{
|
|
9569
|
+
"path": "precision",
|
|
9570
|
+
"valueType": "number"
|
|
9571
|
+
}
|
|
9572
|
+
],
|
|
9573
|
+
"audio-metrics": [
|
|
9574
|
+
{
|
|
9575
|
+
"path": "ts",
|
|
9576
|
+
"valueType": "number"
|
|
9577
|
+
},
|
|
9578
|
+
{
|
|
9579
|
+
"path": "windowSec",
|
|
9580
|
+
"valueType": "number"
|
|
9581
|
+
},
|
|
9582
|
+
{
|
|
9583
|
+
"path": "level.rms",
|
|
9584
|
+
"valueType": "number"
|
|
9585
|
+
},
|
|
9586
|
+
{
|
|
9587
|
+
"path": "level.dbfs",
|
|
9588
|
+
"valueType": "number"
|
|
9589
|
+
},
|
|
9590
|
+
{
|
|
9591
|
+
"path": "peakDbfs",
|
|
9592
|
+
"valueType": "number"
|
|
9593
|
+
},
|
|
9594
|
+
{
|
|
9595
|
+
"path": "avgDbfs",
|
|
9596
|
+
"valueType": "number"
|
|
9597
|
+
},
|
|
9598
|
+
{
|
|
9599
|
+
"path": "current.className",
|
|
9600
|
+
"valueType": "string"
|
|
9601
|
+
},
|
|
9602
|
+
{
|
|
9603
|
+
"path": "current.score",
|
|
9604
|
+
"valueType": "number"
|
|
9605
|
+
},
|
|
9606
|
+
{
|
|
9607
|
+
"path": "current.timestamp",
|
|
9608
|
+
"valueType": "number"
|
|
9609
|
+
}
|
|
9610
|
+
],
|
|
9611
|
+
"automation-control": [
|
|
9612
|
+
{
|
|
9613
|
+
"path": "enabled",
|
|
9614
|
+
"valueType": "boolean"
|
|
9615
|
+
},
|
|
9616
|
+
{
|
|
9617
|
+
"path": "isRunning",
|
|
9618
|
+
"valueType": "boolean"
|
|
9619
|
+
},
|
|
9620
|
+
{
|
|
9621
|
+
"path": "lastTriggeredAt",
|
|
9622
|
+
"valueType": "number"
|
|
9623
|
+
},
|
|
9624
|
+
{
|
|
9625
|
+
"path": "lastError",
|
|
9626
|
+
"valueType": "string"
|
|
9627
|
+
}
|
|
9628
|
+
],
|
|
9629
|
+
"battery": [
|
|
9630
|
+
{
|
|
9631
|
+
"path": "percentage",
|
|
9632
|
+
"valueType": "number"
|
|
9633
|
+
},
|
|
9634
|
+
{
|
|
9635
|
+
"path": "charging",
|
|
9636
|
+
"valueType": "enum",
|
|
9637
|
+
"enumValues": [
|
|
9638
|
+
"dc",
|
|
9639
|
+
"solar",
|
|
9640
|
+
"none",
|
|
9641
|
+
"unknown"
|
|
9642
|
+
]
|
|
9643
|
+
},
|
|
9644
|
+
{
|
|
9645
|
+
"path": "sleeping",
|
|
9646
|
+
"valueType": "boolean"
|
|
9647
|
+
},
|
|
9648
|
+
{
|
|
9649
|
+
"path": "lastUpdated",
|
|
9650
|
+
"valueType": "number"
|
|
9651
|
+
},
|
|
9652
|
+
{
|
|
9653
|
+
"path": "lastContactAt",
|
|
9654
|
+
"valueType": "number"
|
|
9655
|
+
},
|
|
9656
|
+
{
|
|
9657
|
+
"path": "lastFullRefreshAt",
|
|
9658
|
+
"valueType": "number"
|
|
9659
|
+
},
|
|
9660
|
+
{
|
|
9661
|
+
"path": "binary",
|
|
9662
|
+
"valueType": "boolean"
|
|
9663
|
+
}
|
|
9664
|
+
],
|
|
9665
|
+
"binary": [{
|
|
9666
|
+
"path": "on",
|
|
9667
|
+
"valueType": "boolean"
|
|
9668
|
+
}],
|
|
9669
|
+
"brightness": [{
|
|
9670
|
+
"path": "percentage",
|
|
9671
|
+
"valueType": "number"
|
|
9672
|
+
}],
|
|
9673
|
+
"broker": [{
|
|
9674
|
+
"path": "brokerCount",
|
|
9675
|
+
"valueType": "number"
|
|
9676
|
+
}, {
|
|
9677
|
+
"path": "connectedCount",
|
|
9678
|
+
"valueType": "number"
|
|
9679
|
+
}],
|
|
9680
|
+
"camera-credentials": [
|
|
9681
|
+
{
|
|
9682
|
+
"path": "host",
|
|
9683
|
+
"valueType": "string"
|
|
9684
|
+
},
|
|
9685
|
+
{
|
|
9686
|
+
"path": "port",
|
|
9687
|
+
"valueType": "number"
|
|
9688
|
+
},
|
|
9689
|
+
{
|
|
9690
|
+
"path": "onvifPort",
|
|
9691
|
+
"valueType": "number"
|
|
9692
|
+
},
|
|
9693
|
+
{
|
|
9694
|
+
"path": "rtspPort",
|
|
9695
|
+
"valueType": "number"
|
|
9696
|
+
},
|
|
9697
|
+
{
|
|
9698
|
+
"path": "https",
|
|
9699
|
+
"valueType": "boolean"
|
|
9700
|
+
},
|
|
9701
|
+
{
|
|
9702
|
+
"path": "hasUsername",
|
|
9703
|
+
"valueType": "boolean"
|
|
9704
|
+
},
|
|
9705
|
+
{
|
|
9706
|
+
"path": "hasPassword",
|
|
9707
|
+
"valueType": "boolean"
|
|
9708
|
+
},
|
|
9709
|
+
{
|
|
9710
|
+
"path": "onvifProfile",
|
|
9711
|
+
"valueType": "string"
|
|
9712
|
+
}
|
|
9713
|
+
],
|
|
9714
|
+
"camera-streams": [
|
|
9715
|
+
{
|
|
9716
|
+
"path": "online",
|
|
9717
|
+
"valueType": "boolean"
|
|
9718
|
+
},
|
|
9719
|
+
{
|
|
9720
|
+
"path": "slotStatuses.high",
|
|
9721
|
+
"valueType": "enum",
|
|
9722
|
+
"enumValues": [
|
|
9723
|
+
"unassigned",
|
|
9724
|
+
"idle",
|
|
9725
|
+
"connecting",
|
|
9726
|
+
"streaming",
|
|
9727
|
+
"error"
|
|
9728
|
+
]
|
|
9729
|
+
},
|
|
9730
|
+
{
|
|
9731
|
+
"path": "slotStatuses.mid",
|
|
9732
|
+
"valueType": "enum",
|
|
9733
|
+
"enumValues": [
|
|
9734
|
+
"unassigned",
|
|
9735
|
+
"idle",
|
|
9736
|
+
"connecting",
|
|
9737
|
+
"streaming",
|
|
9738
|
+
"error"
|
|
9739
|
+
]
|
|
9740
|
+
},
|
|
9741
|
+
{
|
|
9742
|
+
"path": "slotStatuses.low",
|
|
9743
|
+
"valueType": "enum",
|
|
9744
|
+
"enumValues": [
|
|
9745
|
+
"unassigned",
|
|
9746
|
+
"idle",
|
|
9747
|
+
"connecting",
|
|
9748
|
+
"streaming",
|
|
9749
|
+
"error"
|
|
9750
|
+
]
|
|
9751
|
+
},
|
|
9752
|
+
{
|
|
9753
|
+
"path": "slotErrors.high",
|
|
9754
|
+
"valueType": "string"
|
|
9755
|
+
},
|
|
9756
|
+
{
|
|
9757
|
+
"path": "slotErrors.mid",
|
|
9758
|
+
"valueType": "string"
|
|
9759
|
+
},
|
|
9760
|
+
{
|
|
9761
|
+
"path": "slotErrors.low",
|
|
9762
|
+
"valueType": "string"
|
|
9763
|
+
}
|
|
9764
|
+
],
|
|
9765
|
+
"carbon-monoxide": [{
|
|
9766
|
+
"path": "detected",
|
|
9767
|
+
"valueType": "boolean"
|
|
9768
|
+
}],
|
|
9769
|
+
"climate-control": [
|
|
9770
|
+
{
|
|
9771
|
+
"path": "mode",
|
|
9772
|
+
"valueType": "enum",
|
|
9773
|
+
"enumValues": [
|
|
9774
|
+
"off",
|
|
9775
|
+
"heat",
|
|
9776
|
+
"cool",
|
|
9777
|
+
"auto",
|
|
9778
|
+
"heat_cool",
|
|
9779
|
+
"fan_only",
|
|
9780
|
+
"dry"
|
|
9781
|
+
]
|
|
9782
|
+
},
|
|
9783
|
+
{
|
|
9784
|
+
"path": "fanMode",
|
|
9785
|
+
"valueType": "string"
|
|
9786
|
+
},
|
|
9787
|
+
{
|
|
9788
|
+
"path": "preset",
|
|
9789
|
+
"valueType": "string"
|
|
9790
|
+
},
|
|
9791
|
+
{
|
|
9792
|
+
"path": "target",
|
|
9793
|
+
"valueType": "number"
|
|
9794
|
+
},
|
|
9795
|
+
{
|
|
9796
|
+
"path": "targetHigh",
|
|
9797
|
+
"valueType": "number"
|
|
9798
|
+
},
|
|
9799
|
+
{
|
|
9800
|
+
"path": "targetLow",
|
|
9801
|
+
"valueType": "number"
|
|
9802
|
+
},
|
|
9803
|
+
{
|
|
9804
|
+
"path": "targetHumidity",
|
|
9805
|
+
"valueType": "number"
|
|
9806
|
+
},
|
|
9807
|
+
{
|
|
9808
|
+
"path": "currentTemp",
|
|
9809
|
+
"valueType": "number"
|
|
9810
|
+
},
|
|
9811
|
+
{
|
|
9812
|
+
"path": "currentHumidity",
|
|
9813
|
+
"valueType": "number"
|
|
9814
|
+
},
|
|
9815
|
+
{
|
|
9816
|
+
"path": "swingVertical",
|
|
9817
|
+
"valueType": "boolean"
|
|
9818
|
+
},
|
|
9819
|
+
{
|
|
9820
|
+
"path": "swingHorizontal",
|
|
9821
|
+
"valueType": "boolean"
|
|
9822
|
+
},
|
|
9823
|
+
{
|
|
9824
|
+
"path": "minTemp",
|
|
9825
|
+
"valueType": "number"
|
|
9826
|
+
},
|
|
9827
|
+
{
|
|
9828
|
+
"path": "maxTemp",
|
|
9829
|
+
"valueType": "number"
|
|
9830
|
+
},
|
|
9831
|
+
{
|
|
9832
|
+
"path": "tempStep",
|
|
9833
|
+
"valueType": "number"
|
|
9834
|
+
}
|
|
9835
|
+
],
|
|
9836
|
+
"color": [
|
|
9837
|
+
{
|
|
9838
|
+
"path": "mode",
|
|
9839
|
+
"valueType": "enum",
|
|
9840
|
+
"enumValues": [
|
|
9841
|
+
"rgb",
|
|
9842
|
+
"hsv",
|
|
9843
|
+
"mired"
|
|
9844
|
+
]
|
|
9845
|
+
},
|
|
9846
|
+
{
|
|
9847
|
+
"path": "rgb.r",
|
|
9848
|
+
"valueType": "number"
|
|
9849
|
+
},
|
|
9850
|
+
{
|
|
9851
|
+
"path": "rgb.g",
|
|
9852
|
+
"valueType": "number"
|
|
9853
|
+
},
|
|
9854
|
+
{
|
|
9855
|
+
"path": "rgb.b",
|
|
9856
|
+
"valueType": "number"
|
|
9857
|
+
},
|
|
9858
|
+
{
|
|
9859
|
+
"path": "hsv.h",
|
|
9860
|
+
"valueType": "number"
|
|
9861
|
+
},
|
|
9862
|
+
{
|
|
9863
|
+
"path": "hsv.s",
|
|
9864
|
+
"valueType": "number"
|
|
9865
|
+
},
|
|
9866
|
+
{
|
|
9867
|
+
"path": "hsv.v",
|
|
9868
|
+
"valueType": "number"
|
|
9869
|
+
},
|
|
9870
|
+
{
|
|
9871
|
+
"path": "mireds",
|
|
9872
|
+
"valueType": "number"
|
|
9873
|
+
}
|
|
9874
|
+
],
|
|
9875
|
+
"connectivity": [{
|
|
9876
|
+
"path": "connected",
|
|
9877
|
+
"valueType": "boolean"
|
|
9878
|
+
}],
|
|
9879
|
+
"contact": [{
|
|
9880
|
+
"path": "entryOpen",
|
|
9881
|
+
"valueType": "boolean"
|
|
9882
|
+
}],
|
|
9883
|
+
"control": [
|
|
9884
|
+
{
|
|
9885
|
+
"path": "kind",
|
|
9886
|
+
"valueType": "enum",
|
|
9887
|
+
"enumValues": [
|
|
9888
|
+
"numeric",
|
|
9889
|
+
"select",
|
|
9890
|
+
"text",
|
|
9891
|
+
"datetime"
|
|
9892
|
+
]
|
|
9893
|
+
},
|
|
9894
|
+
{
|
|
9895
|
+
"path": "unit",
|
|
9896
|
+
"valueType": "string"
|
|
9897
|
+
},
|
|
9898
|
+
{
|
|
9899
|
+
"path": "min",
|
|
9900
|
+
"valueType": "number"
|
|
9901
|
+
},
|
|
9902
|
+
{
|
|
9903
|
+
"path": "max",
|
|
9904
|
+
"valueType": "number"
|
|
9905
|
+
},
|
|
9906
|
+
{
|
|
9907
|
+
"path": "step",
|
|
9908
|
+
"valueType": "number"
|
|
9909
|
+
},
|
|
9910
|
+
{
|
|
9911
|
+
"path": "precision",
|
|
9912
|
+
"valueType": "number"
|
|
9913
|
+
},
|
|
9914
|
+
{
|
|
9915
|
+
"path": "format",
|
|
9916
|
+
"valueType": "enum",
|
|
9917
|
+
"enumValues": [
|
|
9918
|
+
"date",
|
|
9919
|
+
"time",
|
|
9920
|
+
"datetime"
|
|
9921
|
+
]
|
|
9922
|
+
}
|
|
9923
|
+
],
|
|
9924
|
+
"cover": [
|
|
9925
|
+
{
|
|
9926
|
+
"path": "state",
|
|
9927
|
+
"valueType": "enum",
|
|
9928
|
+
"enumValues": [
|
|
9929
|
+
"open",
|
|
9930
|
+
"opening",
|
|
9931
|
+
"closing",
|
|
9932
|
+
"closed",
|
|
9933
|
+
"stopped"
|
|
9934
|
+
]
|
|
9935
|
+
},
|
|
9936
|
+
{
|
|
9937
|
+
"path": "position",
|
|
9938
|
+
"valueType": "number"
|
|
9939
|
+
},
|
|
9940
|
+
{
|
|
9941
|
+
"path": "tiltPosition",
|
|
9942
|
+
"valueType": "number"
|
|
9943
|
+
}
|
|
9944
|
+
],
|
|
9945
|
+
"day-night": [
|
|
9946
|
+
{
|
|
9947
|
+
"path": "mode",
|
|
9948
|
+
"valueType": "enum",
|
|
9949
|
+
"enumValues": [
|
|
9950
|
+
"auto",
|
|
9951
|
+
"day",
|
|
9952
|
+
"night",
|
|
9953
|
+
"schedule"
|
|
9954
|
+
]
|
|
9955
|
+
},
|
|
9956
|
+
{
|
|
9957
|
+
"path": "sensitivity",
|
|
9958
|
+
"valueType": "number"
|
|
9959
|
+
},
|
|
9960
|
+
{
|
|
9961
|
+
"path": "switchDelaySec",
|
|
9962
|
+
"valueType": "number"
|
|
9963
|
+
}
|
|
9964
|
+
],
|
|
9965
|
+
"device-adoption": [
|
|
9966
|
+
{
|
|
9967
|
+
"path": "lastDiscoveryAt",
|
|
9968
|
+
"valueType": "number"
|
|
9969
|
+
},
|
|
9970
|
+
{
|
|
9971
|
+
"path": "candidateCount",
|
|
9972
|
+
"valueType": "number"
|
|
9973
|
+
},
|
|
9974
|
+
{
|
|
9975
|
+
"path": "adoptedCount",
|
|
9976
|
+
"valueType": "number"
|
|
9977
|
+
},
|
|
9978
|
+
{
|
|
9979
|
+
"path": "lastError",
|
|
9980
|
+
"valueType": "string"
|
|
9981
|
+
}
|
|
9982
|
+
],
|
|
9983
|
+
"device-discovery": [{
|
|
9984
|
+
"path": "lastDiscoveryAt",
|
|
9985
|
+
"valueType": "number"
|
|
9986
|
+
}, {
|
|
9987
|
+
"path": "lastError",
|
|
9988
|
+
"valueType": "string"
|
|
9989
|
+
}],
|
|
9990
|
+
"device-export": [
|
|
9991
|
+
{
|
|
9992
|
+
"path": "linkState",
|
|
9993
|
+
"valueType": "enum",
|
|
9994
|
+
"enumValues": [
|
|
9995
|
+
"unlinked",
|
|
9996
|
+
"linked",
|
|
9997
|
+
"error"
|
|
9998
|
+
]
|
|
9999
|
+
},
|
|
10000
|
+
{
|
|
10001
|
+
"path": "exposedDeviceCount",
|
|
10002
|
+
"valueType": "number"
|
|
10003
|
+
},
|
|
10004
|
+
{
|
|
10005
|
+
"path": "error",
|
|
10006
|
+
"valueType": "string"
|
|
10007
|
+
},
|
|
10008
|
+
{
|
|
10009
|
+
"path": "setup.qr",
|
|
10010
|
+
"valueType": "string"
|
|
10011
|
+
},
|
|
10012
|
+
{
|
|
10013
|
+
"path": "setup.note",
|
|
10014
|
+
"valueType": "string"
|
|
10015
|
+
}
|
|
10016
|
+
],
|
|
10017
|
+
"device-status": [{
|
|
10018
|
+
"path": "online",
|
|
10019
|
+
"valueType": "boolean"
|
|
10020
|
+
}],
|
|
10021
|
+
"dishwasher": [
|
|
10022
|
+
{
|
|
10023
|
+
"path": "availability",
|
|
10024
|
+
"valueType": "enum",
|
|
10025
|
+
"enumValues": [
|
|
10026
|
+
"available",
|
|
10027
|
+
"offline",
|
|
10028
|
+
"description-missing"
|
|
10029
|
+
]
|
|
10030
|
+
},
|
|
10031
|
+
{
|
|
10032
|
+
"path": "state",
|
|
10033
|
+
"valueType": "enum",
|
|
10034
|
+
"enumValues": [
|
|
10035
|
+
"idle",
|
|
10036
|
+
"running",
|
|
10037
|
+
"paused",
|
|
10038
|
+
"finished",
|
|
10039
|
+
"error",
|
|
10040
|
+
"unavailable"
|
|
10041
|
+
]
|
|
10042
|
+
},
|
|
10043
|
+
{
|
|
10044
|
+
"path": "operationState",
|
|
10045
|
+
"valueType": "enum",
|
|
10046
|
+
"enumValues": [
|
|
10047
|
+
"Inactive",
|
|
10048
|
+
"Ready",
|
|
10049
|
+
"DelayedStart",
|
|
10050
|
+
"Run",
|
|
10051
|
+
"Pause",
|
|
10052
|
+
"ActionRequired",
|
|
10053
|
+
"Finished",
|
|
10054
|
+
"Error",
|
|
10055
|
+
"Aborting"
|
|
10056
|
+
]
|
|
10057
|
+
},
|
|
10058
|
+
{
|
|
10059
|
+
"path": "program",
|
|
10060
|
+
"valueType": "string"
|
|
10061
|
+
},
|
|
10062
|
+
{
|
|
10063
|
+
"path": "selectedProgram",
|
|
10064
|
+
"valueType": "string"
|
|
10065
|
+
},
|
|
10066
|
+
{
|
|
10067
|
+
"path": "remainingSeconds",
|
|
10068
|
+
"valueType": "number"
|
|
10069
|
+
},
|
|
10070
|
+
{
|
|
10071
|
+
"path": "delayedStartSeconds",
|
|
10072
|
+
"valueType": "number"
|
|
10073
|
+
},
|
|
10074
|
+
{
|
|
10075
|
+
"path": "progressPercent",
|
|
10076
|
+
"valueType": "number"
|
|
10077
|
+
},
|
|
10078
|
+
{
|
|
10079
|
+
"path": "doorOpen",
|
|
10080
|
+
"valueType": "boolean"
|
|
10081
|
+
},
|
|
10082
|
+
{
|
|
10083
|
+
"path": "doorLocked",
|
|
10084
|
+
"valueType": "boolean"
|
|
10085
|
+
},
|
|
10086
|
+
{
|
|
10087
|
+
"path": "remoteStartAllowed",
|
|
10088
|
+
"valueType": "boolean"
|
|
10089
|
+
},
|
|
10090
|
+
{
|
|
10091
|
+
"path": "remoteControlActive",
|
|
10092
|
+
"valueType": "boolean"
|
|
10093
|
+
},
|
|
10094
|
+
{
|
|
10095
|
+
"path": "localControlActive",
|
|
10096
|
+
"valueType": "boolean"
|
|
10097
|
+
},
|
|
10098
|
+
{
|
|
10099
|
+
"path": "powerOn",
|
|
10100
|
+
"valueType": "boolean"
|
|
10101
|
+
},
|
|
10102
|
+
{
|
|
10103
|
+
"path": "powerState",
|
|
10104
|
+
"valueType": "string"
|
|
10105
|
+
},
|
|
10106
|
+
{
|
|
10107
|
+
"path": "filterCleaningDue",
|
|
10108
|
+
"valueType": "boolean"
|
|
10109
|
+
},
|
|
10110
|
+
{
|
|
10111
|
+
"path": "machineCareDue",
|
|
10112
|
+
"valueType": "boolean"
|
|
10113
|
+
},
|
|
10114
|
+
{
|
|
10115
|
+
"path": "machineCareRemainingRuns",
|
|
10116
|
+
"valueType": "number"
|
|
10117
|
+
},
|
|
10118
|
+
{
|
|
10119
|
+
"path": "halfLoad",
|
|
10120
|
+
"valueType": "boolean"
|
|
10121
|
+
},
|
|
10122
|
+
{
|
|
10123
|
+
"path": "hygienePlus",
|
|
10124
|
+
"valueType": "boolean"
|
|
10125
|
+
},
|
|
10126
|
+
{
|
|
10127
|
+
"path": "extraDry",
|
|
10128
|
+
"valueType": "boolean"
|
|
10129
|
+
},
|
|
10130
|
+
{
|
|
10131
|
+
"path": "intensiveZone",
|
|
10132
|
+
"valueType": "boolean"
|
|
10133
|
+
},
|
|
10134
|
+
{
|
|
10135
|
+
"path": "varioSpeedPlus",
|
|
10136
|
+
"valueType": "boolean"
|
|
10137
|
+
},
|
|
10138
|
+
{
|
|
10139
|
+
"path": "childLock",
|
|
10140
|
+
"valueType": "boolean"
|
|
10141
|
+
},
|
|
10142
|
+
{
|
|
10143
|
+
"path": "errorCode",
|
|
10144
|
+
"valueType": "number"
|
|
10145
|
+
},
|
|
10146
|
+
{
|
|
10147
|
+
"path": "errorLabel",
|
|
10148
|
+
"valueType": "string"
|
|
10149
|
+
}
|
|
10150
|
+
],
|
|
10151
|
+
"doorbell": [{
|
|
10152
|
+
"path": "lastPressedAt",
|
|
10153
|
+
"valueType": "number"
|
|
10154
|
+
}, {
|
|
10155
|
+
"path": "pressCountSinceStart",
|
|
10156
|
+
"valueType": "number"
|
|
10157
|
+
}],
|
|
10158
|
+
"enum-sensor": [{
|
|
10159
|
+
"path": "value",
|
|
10160
|
+
"valueType": "string"
|
|
10161
|
+
}, {
|
|
10162
|
+
"path": "format",
|
|
10163
|
+
"valueType": "enum",
|
|
10164
|
+
"enumValues": [
|
|
10165
|
+
"date",
|
|
10166
|
+
"time",
|
|
10167
|
+
"datetime"
|
|
10168
|
+
]
|
|
10169
|
+
}],
|
|
10170
|
+
"event-emitter": [
|
|
10171
|
+
{
|
|
10172
|
+
"path": "lastEvent.deviceId",
|
|
10173
|
+
"valueType": "number"
|
|
10174
|
+
},
|
|
10175
|
+
{
|
|
10176
|
+
"path": "lastEvent.eventType",
|
|
10177
|
+
"valueType": "string"
|
|
10178
|
+
},
|
|
10179
|
+
{
|
|
10180
|
+
"path": "lastEvent.timestamp",
|
|
10181
|
+
"valueType": "number"
|
|
10182
|
+
},
|
|
10183
|
+
{
|
|
10184
|
+
"path": "lastEvent.seq",
|
|
10185
|
+
"valueType": "number"
|
|
10186
|
+
},
|
|
10187
|
+
{
|
|
10188
|
+
"path": "eventCountSinceStart",
|
|
10189
|
+
"valueType": "number"
|
|
10190
|
+
}
|
|
10191
|
+
],
|
|
10192
|
+
"fan-control": [
|
|
10193
|
+
{
|
|
10194
|
+
"path": "percentage",
|
|
10195
|
+
"valueType": "number"
|
|
10196
|
+
},
|
|
10197
|
+
{
|
|
10198
|
+
"path": "percentageStep",
|
|
10199
|
+
"valueType": "number"
|
|
10200
|
+
},
|
|
10201
|
+
{
|
|
10202
|
+
"path": "preset",
|
|
10203
|
+
"valueType": "string"
|
|
10204
|
+
},
|
|
10205
|
+
{
|
|
10206
|
+
"path": "direction",
|
|
10207
|
+
"valueType": "enum",
|
|
10208
|
+
"enumValues": ["forward", "reverse"]
|
|
10209
|
+
},
|
|
10210
|
+
{
|
|
10211
|
+
"path": "oscillating",
|
|
10212
|
+
"valueType": "boolean"
|
|
10213
|
+
}
|
|
10214
|
+
],
|
|
10215
|
+
"feature-probe": [
|
|
10216
|
+
{
|
|
10217
|
+
"path": "deviceType",
|
|
10218
|
+
"valueType": "string"
|
|
10219
|
+
},
|
|
10220
|
+
{
|
|
10221
|
+
"path": "model",
|
|
10222
|
+
"valueType": "string"
|
|
10223
|
+
},
|
|
10224
|
+
{
|
|
10225
|
+
"path": "channelCount",
|
|
10226
|
+
"valueType": "number"
|
|
10227
|
+
},
|
|
10228
|
+
{
|
|
10229
|
+
"path": "lastProbedAt",
|
|
10230
|
+
"valueType": "number"
|
|
10231
|
+
}
|
|
10232
|
+
],
|
|
10233
|
+
"flood": [{
|
|
10234
|
+
"path": "flooded",
|
|
10235
|
+
"valueType": "boolean"
|
|
10236
|
+
}],
|
|
10237
|
+
"gas": [{
|
|
10238
|
+
"path": "detected",
|
|
10239
|
+
"valueType": "boolean"
|
|
10240
|
+
}],
|
|
10241
|
+
"heating-valve": [{
|
|
10242
|
+
"path": "position",
|
|
10243
|
+
"valueType": "number"
|
|
10244
|
+
}],
|
|
10245
|
+
"humidifier": [
|
|
10246
|
+
{
|
|
10247
|
+
"path": "on",
|
|
10248
|
+
"valueType": "boolean"
|
|
10249
|
+
},
|
|
10250
|
+
{
|
|
10251
|
+
"path": "currentHumidity",
|
|
10252
|
+
"valueType": "number"
|
|
10253
|
+
},
|
|
10254
|
+
{
|
|
10255
|
+
"path": "targetHumidity",
|
|
10256
|
+
"valueType": "number"
|
|
10257
|
+
},
|
|
10258
|
+
{
|
|
10259
|
+
"path": "mode",
|
|
10260
|
+
"valueType": "string"
|
|
10261
|
+
},
|
|
10262
|
+
{
|
|
10263
|
+
"path": "action",
|
|
10264
|
+
"valueType": "string"
|
|
10265
|
+
},
|
|
10266
|
+
{
|
|
10267
|
+
"path": "minHumidity",
|
|
10268
|
+
"valueType": "number"
|
|
10269
|
+
},
|
|
10270
|
+
{
|
|
10271
|
+
"path": "maxHumidity",
|
|
10272
|
+
"valueType": "number"
|
|
10273
|
+
}
|
|
10274
|
+
],
|
|
10275
|
+
"humidity-sensor": [
|
|
10276
|
+
{
|
|
10277
|
+
"path": "percent",
|
|
10278
|
+
"valueType": "number"
|
|
10279
|
+
},
|
|
10280
|
+
{
|
|
10281
|
+
"path": "unit",
|
|
10282
|
+
"valueType": "string"
|
|
10283
|
+
},
|
|
10284
|
+
{
|
|
10285
|
+
"path": "precision",
|
|
10286
|
+
"valueType": "number"
|
|
10287
|
+
}
|
|
10288
|
+
],
|
|
10289
|
+
"image": [{
|
|
10290
|
+
"path": "url",
|
|
10291
|
+
"valueType": "string"
|
|
10292
|
+
}, {
|
|
10293
|
+
"path": "lastUpdated",
|
|
10294
|
+
"valueType": "number"
|
|
10295
|
+
}],
|
|
10296
|
+
"image-settings": [
|
|
10297
|
+
{
|
|
10298
|
+
"path": "brightness",
|
|
10299
|
+
"valueType": "number"
|
|
10300
|
+
},
|
|
10301
|
+
{
|
|
10302
|
+
"path": "contrast",
|
|
10303
|
+
"valueType": "number"
|
|
10304
|
+
},
|
|
10305
|
+
{
|
|
10306
|
+
"path": "saturation",
|
|
10307
|
+
"valueType": "number"
|
|
10308
|
+
},
|
|
10309
|
+
{
|
|
10310
|
+
"path": "sharpness",
|
|
10311
|
+
"valueType": "number"
|
|
10312
|
+
},
|
|
10313
|
+
{
|
|
10314
|
+
"path": "mirror",
|
|
10315
|
+
"valueType": "boolean"
|
|
10316
|
+
},
|
|
10317
|
+
{
|
|
10318
|
+
"path": "flip",
|
|
10319
|
+
"valueType": "boolean"
|
|
10320
|
+
},
|
|
10321
|
+
{
|
|
10322
|
+
"path": "rotate",
|
|
10323
|
+
"valueType": "enum",
|
|
10324
|
+
"enumValues": [
|
|
10325
|
+
"0",
|
|
10326
|
+
"90",
|
|
10327
|
+
"180",
|
|
10328
|
+
"270"
|
|
10329
|
+
]
|
|
10330
|
+
},
|
|
10331
|
+
{
|
|
10332
|
+
"path": "whiteBalance",
|
|
10333
|
+
"valueType": "enum",
|
|
10334
|
+
"enumValues": ["auto", "manual"]
|
|
10335
|
+
},
|
|
10336
|
+
{
|
|
10337
|
+
"path": "warmth",
|
|
10338
|
+
"valueType": "number"
|
|
10339
|
+
},
|
|
10340
|
+
{
|
|
10341
|
+
"path": "exposureMode",
|
|
10342
|
+
"valueType": "enum",
|
|
10343
|
+
"enumValues": ["auto", "manual"]
|
|
10344
|
+
},
|
|
10345
|
+
{
|
|
10346
|
+
"path": "backlightMode",
|
|
10347
|
+
"valueType": "enum",
|
|
10348
|
+
"enumValues": [
|
|
10349
|
+
"off",
|
|
10350
|
+
"blc",
|
|
10351
|
+
"wdr",
|
|
10352
|
+
"hlc"
|
|
10353
|
+
]
|
|
10354
|
+
}
|
|
10355
|
+
],
|
|
10356
|
+
"intercom": [
|
|
10357
|
+
{
|
|
10358
|
+
"path": "talking",
|
|
10359
|
+
"valueType": "boolean"
|
|
10360
|
+
},
|
|
10361
|
+
{
|
|
10362
|
+
"path": "lastSessionAt",
|
|
10363
|
+
"valueType": "number"
|
|
10364
|
+
},
|
|
10365
|
+
{
|
|
10366
|
+
"path": "ability.sampleRate",
|
|
10367
|
+
"valueType": "number"
|
|
10368
|
+
},
|
|
10369
|
+
{
|
|
10370
|
+
"path": "ability.duplex",
|
|
10371
|
+
"valueType": "enum",
|
|
10372
|
+
"enumValues": ["half", "full"]
|
|
10373
|
+
},
|
|
10374
|
+
{
|
|
10375
|
+
"path": "ability.maxBacklogMs",
|
|
10376
|
+
"valueType": "number"
|
|
10377
|
+
}
|
|
10378
|
+
],
|
|
10379
|
+
"lawn-mower-control": [
|
|
10380
|
+
{
|
|
10381
|
+
"path": "activity",
|
|
10382
|
+
"valueType": "enum",
|
|
10383
|
+
"enumValues": [
|
|
10384
|
+
"idle",
|
|
10385
|
+
"mowing",
|
|
10386
|
+
"paused",
|
|
10387
|
+
"docked",
|
|
10388
|
+
"error"
|
|
10389
|
+
]
|
|
10390
|
+
},
|
|
10391
|
+
{
|
|
10392
|
+
"path": "batteryLevel",
|
|
10393
|
+
"valueType": "number"
|
|
10394
|
+
},
|
|
10395
|
+
{
|
|
10396
|
+
"path": "progressPercent",
|
|
10397
|
+
"valueType": "number"
|
|
10398
|
+
},
|
|
10399
|
+
{
|
|
10400
|
+
"path": "currentCode",
|
|
10401
|
+
"valueType": "number"
|
|
10402
|
+
},
|
|
10403
|
+
{
|
|
10404
|
+
"path": "currentCodeLabel",
|
|
10405
|
+
"valueType": "string"
|
|
10406
|
+
},
|
|
10407
|
+
{
|
|
10408
|
+
"path": "severity",
|
|
10409
|
+
"valueType": "enum",
|
|
10410
|
+
"enumValues": [
|
|
10411
|
+
"info",
|
|
10412
|
+
"warning",
|
|
10413
|
+
"error"
|
|
10414
|
+
]
|
|
10415
|
+
}
|
|
10416
|
+
],
|
|
10417
|
+
"lock-control": [{
|
|
10418
|
+
"path": "state",
|
|
10419
|
+
"valueType": "enum",
|
|
10420
|
+
"enumValues": [
|
|
10421
|
+
"locked",
|
|
10422
|
+
"unlocked",
|
|
10423
|
+
"locking",
|
|
10424
|
+
"unlocking",
|
|
10425
|
+
"jammed"
|
|
10426
|
+
]
|
|
10427
|
+
}],
|
|
10428
|
+
"media-player": [
|
|
10429
|
+
{
|
|
10430
|
+
"path": "state",
|
|
10431
|
+
"valueType": "enum",
|
|
10432
|
+
"enumValues": [
|
|
10433
|
+
"off",
|
|
10434
|
+
"on",
|
|
10435
|
+
"idle",
|
|
10436
|
+
"playing",
|
|
10437
|
+
"paused",
|
|
10438
|
+
"buffering",
|
|
10439
|
+
"standby"
|
|
10440
|
+
]
|
|
10441
|
+
},
|
|
10442
|
+
{
|
|
10443
|
+
"path": "volumeLevel",
|
|
10444
|
+
"valueType": "number"
|
|
10445
|
+
},
|
|
10446
|
+
{
|
|
10447
|
+
"path": "isMuted",
|
|
10448
|
+
"valueType": "boolean"
|
|
10449
|
+
},
|
|
10450
|
+
{
|
|
10451
|
+
"path": "source",
|
|
10452
|
+
"valueType": "string"
|
|
10453
|
+
},
|
|
10454
|
+
{
|
|
10455
|
+
"path": "currentMedia.type",
|
|
10456
|
+
"valueType": "string"
|
|
10457
|
+
},
|
|
10458
|
+
{
|
|
10459
|
+
"path": "currentMedia.title",
|
|
10460
|
+
"valueType": "string"
|
|
10461
|
+
},
|
|
10462
|
+
{
|
|
10463
|
+
"path": "currentMedia.artist",
|
|
10464
|
+
"valueType": "string"
|
|
10465
|
+
},
|
|
10466
|
+
{
|
|
10467
|
+
"path": "currentMedia.album",
|
|
10468
|
+
"valueType": "string"
|
|
10469
|
+
},
|
|
10470
|
+
{
|
|
10471
|
+
"path": "currentMedia.imageUrl",
|
|
10472
|
+
"valueType": "string"
|
|
10473
|
+
},
|
|
10474
|
+
{
|
|
10475
|
+
"path": "positionMs",
|
|
10476
|
+
"valueType": "number"
|
|
10477
|
+
},
|
|
10478
|
+
{
|
|
10479
|
+
"path": "durationMs",
|
|
10480
|
+
"valueType": "number"
|
|
10481
|
+
},
|
|
10482
|
+
{
|
|
10483
|
+
"path": "shuffle",
|
|
10484
|
+
"valueType": "boolean"
|
|
10485
|
+
},
|
|
10486
|
+
{
|
|
10487
|
+
"path": "repeat",
|
|
10488
|
+
"valueType": "enum",
|
|
10489
|
+
"enumValues": [
|
|
10490
|
+
"off",
|
|
10491
|
+
"all",
|
|
10492
|
+
"one"
|
|
10493
|
+
]
|
|
10494
|
+
}
|
|
10495
|
+
],
|
|
10496
|
+
"motion": [
|
|
10497
|
+
{
|
|
10498
|
+
"path": "detected",
|
|
10499
|
+
"valueType": "boolean"
|
|
10500
|
+
},
|
|
10501
|
+
{
|
|
10502
|
+
"path": "lastDetectedAt",
|
|
10503
|
+
"valueType": "number"
|
|
10504
|
+
},
|
|
10505
|
+
{
|
|
10506
|
+
"path": "autoClearAfterMs",
|
|
10507
|
+
"valueType": "number"
|
|
10508
|
+
}
|
|
10509
|
+
],
|
|
10510
|
+
"motion-trigger": [{
|
|
10511
|
+
"path": "enabled",
|
|
10512
|
+
"valueType": "boolean"
|
|
10513
|
+
}],
|
|
10514
|
+
"motion-zones": [{
|
|
10515
|
+
"path": "enabled",
|
|
10516
|
+
"valueType": "boolean"
|
|
10517
|
+
}, {
|
|
10518
|
+
"path": "sensitivity",
|
|
10519
|
+
"valueType": "number"
|
|
10520
|
+
}],
|
|
10521
|
+
"mqtt-broker": [{
|
|
10522
|
+
"path": "brokerCount",
|
|
10523
|
+
"valueType": "number"
|
|
10524
|
+
}, {
|
|
10525
|
+
"path": "embeddedRunning",
|
|
10526
|
+
"valueType": "boolean"
|
|
10527
|
+
}],
|
|
10528
|
+
"native-object-detection": [{
|
|
10529
|
+
"path": "enabled",
|
|
10530
|
+
"valueType": "boolean"
|
|
10531
|
+
}],
|
|
10532
|
+
"navigation": [
|
|
10533
|
+
{
|
|
10534
|
+
"path": "mode",
|
|
10535
|
+
"valueType": "enum",
|
|
10536
|
+
"enumValues": [
|
|
10537
|
+
"idle",
|
|
10538
|
+
"cleaning",
|
|
10539
|
+
"spot",
|
|
10540
|
+
"following",
|
|
10541
|
+
"goto",
|
|
10542
|
+
"returning",
|
|
10543
|
+
"paused",
|
|
10544
|
+
"unknown"
|
|
10545
|
+
]
|
|
10546
|
+
},
|
|
10547
|
+
{
|
|
10548
|
+
"path": "following",
|
|
10549
|
+
"valueType": "boolean"
|
|
10550
|
+
},
|
|
10551
|
+
{
|
|
10552
|
+
"path": "flash",
|
|
10553
|
+
"valueType": "boolean"
|
|
10554
|
+
},
|
|
10555
|
+
{
|
|
10556
|
+
"path": "lightMode",
|
|
10557
|
+
"valueType": "enum",
|
|
10558
|
+
"enumValues": ["auto", "manual"]
|
|
10559
|
+
},
|
|
10560
|
+
{
|
|
10561
|
+
"path": "lightLevel",
|
|
10562
|
+
"valueType": "number"
|
|
10563
|
+
}
|
|
10564
|
+
],
|
|
10565
|
+
"network-link": [
|
|
10566
|
+
{
|
|
10567
|
+
"path": "type",
|
|
10568
|
+
"valueType": "enum",
|
|
10569
|
+
"enumValues": [
|
|
10570
|
+
"wifi",
|
|
10571
|
+
"ethernet",
|
|
10572
|
+
"cellular",
|
|
10573
|
+
"unknown"
|
|
10574
|
+
]
|
|
10575
|
+
},
|
|
10576
|
+
{
|
|
10577
|
+
"path": "signalPercent",
|
|
10578
|
+
"valueType": "number"
|
|
10579
|
+
},
|
|
10580
|
+
{
|
|
10581
|
+
"path": "rssiDbm",
|
|
10582
|
+
"valueType": "number"
|
|
10583
|
+
},
|
|
10584
|
+
{
|
|
10585
|
+
"path": "ssid",
|
|
10586
|
+
"valueType": "string"
|
|
10587
|
+
},
|
|
10588
|
+
{
|
|
10589
|
+
"path": "lastUpdated",
|
|
10590
|
+
"valueType": "number"
|
|
10591
|
+
}
|
|
10592
|
+
],
|
|
10593
|
+
"notifier": [
|
|
10594
|
+
{
|
|
10595
|
+
"path": "lastSentAt",
|
|
10596
|
+
"valueType": "number"
|
|
10597
|
+
},
|
|
10598
|
+
{
|
|
10599
|
+
"path": "lastError",
|
|
10600
|
+
"valueType": "string"
|
|
10601
|
+
},
|
|
10602
|
+
{
|
|
10603
|
+
"path": "queueDepth",
|
|
10604
|
+
"valueType": "number"
|
|
10605
|
+
},
|
|
10606
|
+
{
|
|
10607
|
+
"path": "supports.image",
|
|
10608
|
+
"valueType": "boolean"
|
|
10609
|
+
},
|
|
10610
|
+
{
|
|
10611
|
+
"path": "supports.priority",
|
|
10612
|
+
"valueType": "boolean"
|
|
10613
|
+
},
|
|
10614
|
+
{
|
|
10615
|
+
"path": "supports.data",
|
|
10616
|
+
"valueType": "boolean"
|
|
10617
|
+
},
|
|
10618
|
+
{
|
|
10619
|
+
"path": "supports.actions",
|
|
10620
|
+
"valueType": "boolean"
|
|
10621
|
+
},
|
|
10622
|
+
{
|
|
10623
|
+
"path": "supports.recipients",
|
|
10624
|
+
"valueType": "boolean"
|
|
10625
|
+
}
|
|
10626
|
+
],
|
|
10627
|
+
"numeric-sensor": [
|
|
10628
|
+
{
|
|
10629
|
+
"path": "value",
|
|
10630
|
+
"valueType": "number"
|
|
10631
|
+
},
|
|
10632
|
+
{
|
|
10633
|
+
"path": "unit",
|
|
10634
|
+
"valueType": "string"
|
|
10635
|
+
},
|
|
10636
|
+
{
|
|
10637
|
+
"path": "precision",
|
|
10638
|
+
"valueType": "number"
|
|
10639
|
+
}
|
|
10640
|
+
],
|
|
10641
|
+
"pet-feeder": [
|
|
10642
|
+
{
|
|
10643
|
+
"path": "foodLevel",
|
|
10644
|
+
"valueType": "number"
|
|
10645
|
+
},
|
|
10646
|
+
{
|
|
10647
|
+
"path": "food1",
|
|
10648
|
+
"valueType": "number"
|
|
10649
|
+
},
|
|
10650
|
+
{
|
|
10651
|
+
"path": "food2",
|
|
10652
|
+
"valueType": "number"
|
|
10653
|
+
},
|
|
10654
|
+
{
|
|
10655
|
+
"path": "lowFood",
|
|
10656
|
+
"valueType": "boolean"
|
|
10657
|
+
},
|
|
10658
|
+
{
|
|
10659
|
+
"path": "batteryPower",
|
|
10660
|
+
"valueType": "number"
|
|
10661
|
+
},
|
|
10662
|
+
{
|
|
10663
|
+
"path": "desiccantLeftDays",
|
|
10664
|
+
"valueType": "number"
|
|
10665
|
+
},
|
|
10666
|
+
{
|
|
10667
|
+
"path": "feeding",
|
|
10668
|
+
"valueType": "boolean"
|
|
10669
|
+
},
|
|
10670
|
+
{
|
|
10671
|
+
"path": "status",
|
|
10672
|
+
"valueType": "enum",
|
|
10673
|
+
"enumValues": [
|
|
10674
|
+
"normal",
|
|
10675
|
+
"offline",
|
|
10676
|
+
"on_batteries"
|
|
10677
|
+
]
|
|
10678
|
+
},
|
|
10679
|
+
{
|
|
10680
|
+
"path": "error",
|
|
10681
|
+
"valueType": "string"
|
|
10682
|
+
},
|
|
10683
|
+
{
|
|
10684
|
+
"path": "errorCode",
|
|
10685
|
+
"valueType": "number"
|
|
10686
|
+
},
|
|
10687
|
+
{
|
|
10688
|
+
"path": "isDualHopper",
|
|
10689
|
+
"valueType": "boolean"
|
|
10690
|
+
},
|
|
10691
|
+
{
|
|
10692
|
+
"path": "childLock",
|
|
10693
|
+
"valueType": "boolean"
|
|
10694
|
+
},
|
|
10695
|
+
{
|
|
10696
|
+
"path": "indicatorLight",
|
|
10697
|
+
"valueType": "boolean"
|
|
10698
|
+
},
|
|
10699
|
+
{
|
|
10700
|
+
"path": "feedSound",
|
|
10701
|
+
"valueType": "boolean"
|
|
10702
|
+
},
|
|
10703
|
+
{
|
|
10704
|
+
"path": "volume",
|
|
10705
|
+
"valueType": "number"
|
|
10706
|
+
}
|
|
10707
|
+
],
|
|
10708
|
+
"power-meter": [
|
|
10709
|
+
{
|
|
10710
|
+
"path": "watts",
|
|
10711
|
+
"valueType": "number"
|
|
10712
|
+
},
|
|
10713
|
+
{
|
|
10714
|
+
"path": "kwhTotal",
|
|
10715
|
+
"valueType": "number"
|
|
10716
|
+
},
|
|
10717
|
+
{
|
|
10718
|
+
"path": "volts",
|
|
10719
|
+
"valueType": "number"
|
|
10720
|
+
},
|
|
10721
|
+
{
|
|
10722
|
+
"path": "amps",
|
|
10723
|
+
"valueType": "number"
|
|
10724
|
+
},
|
|
10725
|
+
{
|
|
10726
|
+
"path": "va",
|
|
10727
|
+
"valueType": "number"
|
|
10728
|
+
},
|
|
10729
|
+
{
|
|
10730
|
+
"path": "powerFactor",
|
|
10731
|
+
"valueType": "number"
|
|
10732
|
+
},
|
|
10733
|
+
{
|
|
10734
|
+
"path": "unit",
|
|
10735
|
+
"valueType": "string"
|
|
10736
|
+
},
|
|
10737
|
+
{
|
|
10738
|
+
"path": "precision",
|
|
10739
|
+
"valueType": "number"
|
|
10740
|
+
}
|
|
10741
|
+
],
|
|
10742
|
+
"presence": [
|
|
10743
|
+
{
|
|
10744
|
+
"path": "state",
|
|
10745
|
+
"valueType": "string"
|
|
10746
|
+
},
|
|
10747
|
+
{
|
|
10748
|
+
"path": "location",
|
|
10749
|
+
"valueType": "string"
|
|
10750
|
+
},
|
|
10751
|
+
{
|
|
10752
|
+
"path": "gps.latitude",
|
|
10753
|
+
"valueType": "number"
|
|
10754
|
+
},
|
|
10755
|
+
{
|
|
10756
|
+
"path": "gps.longitude",
|
|
10757
|
+
"valueType": "number"
|
|
10758
|
+
},
|
|
10759
|
+
{
|
|
10760
|
+
"path": "gps.accuracyMeters",
|
|
10761
|
+
"valueType": "number"
|
|
10762
|
+
},
|
|
10763
|
+
{
|
|
10764
|
+
"path": "batteryPercent",
|
|
10765
|
+
"valueType": "number"
|
|
10766
|
+
}
|
|
10767
|
+
],
|
|
10768
|
+
"pressure-sensor": [
|
|
10769
|
+
{
|
|
10770
|
+
"path": "hpa",
|
|
10771
|
+
"valueType": "number"
|
|
10772
|
+
},
|
|
10773
|
+
{
|
|
10774
|
+
"path": "unit",
|
|
10775
|
+
"valueType": "string"
|
|
10776
|
+
},
|
|
10777
|
+
{
|
|
10778
|
+
"path": "precision",
|
|
10779
|
+
"valueType": "number"
|
|
10780
|
+
}
|
|
10781
|
+
],
|
|
10782
|
+
"privacy-mask": [{
|
|
10783
|
+
"path": "enabled",
|
|
10784
|
+
"valueType": "boolean"
|
|
10785
|
+
}, {
|
|
10786
|
+
"path": "audioEnabled",
|
|
10787
|
+
"valueType": "boolean"
|
|
10788
|
+
}],
|
|
10789
|
+
"ptz": [
|
|
10790
|
+
{
|
|
10791
|
+
"path": "pan",
|
|
10792
|
+
"valueType": "number"
|
|
10793
|
+
},
|
|
10794
|
+
{
|
|
10795
|
+
"path": "tilt",
|
|
10796
|
+
"valueType": "number"
|
|
10797
|
+
},
|
|
10798
|
+
{
|
|
10799
|
+
"path": "zoom",
|
|
10800
|
+
"valueType": "number"
|
|
10801
|
+
},
|
|
10802
|
+
{
|
|
10803
|
+
"path": "autofocus",
|
|
10804
|
+
"valueType": "boolean"
|
|
10805
|
+
}
|
|
10806
|
+
],
|
|
10807
|
+
"ptz-autotrack": [
|
|
10808
|
+
{
|
|
10809
|
+
"path": "enabled",
|
|
10810
|
+
"valueType": "boolean"
|
|
10811
|
+
},
|
|
10812
|
+
{
|
|
10813
|
+
"path": "currentSettings.targetType",
|
|
10814
|
+
"valueType": "string"
|
|
10815
|
+
},
|
|
10816
|
+
{
|
|
10817
|
+
"path": "currentSettings.stopDelaySeconds",
|
|
10818
|
+
"valueType": "number"
|
|
10819
|
+
},
|
|
10820
|
+
{
|
|
10821
|
+
"path": "currentSettings.disappearDelaySeconds",
|
|
10822
|
+
"valueType": "number"
|
|
10823
|
+
}
|
|
10824
|
+
],
|
|
10825
|
+
"recording-archive": [
|
|
10826
|
+
{
|
|
10827
|
+
"path": "deviceId",
|
|
10828
|
+
"valueType": "number"
|
|
10829
|
+
},
|
|
10830
|
+
{
|
|
10831
|
+
"path": "enabled",
|
|
10832
|
+
"valueType": "boolean"
|
|
10833
|
+
},
|
|
10834
|
+
{
|
|
10835
|
+
"path": "activeMode",
|
|
10836
|
+
"valueType": "enum",
|
|
10837
|
+
"enumValues": [
|
|
10838
|
+
"off",
|
|
10839
|
+
"events",
|
|
10840
|
+
"continuous",
|
|
10841
|
+
"on-device-decision"
|
|
10842
|
+
]
|
|
10843
|
+
},
|
|
10844
|
+
{
|
|
10845
|
+
"path": "nodeId",
|
|
10846
|
+
"valueType": "string"
|
|
10847
|
+
},
|
|
10848
|
+
{
|
|
10849
|
+
"path": "storageBytes",
|
|
10850
|
+
"valueType": "number"
|
|
10851
|
+
}
|
|
10852
|
+
],
|
|
10853
|
+
"recording-onboard": [
|
|
10854
|
+
{
|
|
10855
|
+
"path": "primaryTrackId",
|
|
10856
|
+
"valueType": "string"
|
|
10857
|
+
},
|
|
10858
|
+
{
|
|
10859
|
+
"path": "enabled",
|
|
10860
|
+
"valueType": "boolean"
|
|
10861
|
+
},
|
|
10862
|
+
{
|
|
10863
|
+
"path": "overwriteWhenFull",
|
|
10864
|
+
"valueType": "boolean"
|
|
10865
|
+
},
|
|
10866
|
+
{
|
|
10867
|
+
"path": "preRecordSec",
|
|
10868
|
+
"valueType": "number"
|
|
10869
|
+
},
|
|
10870
|
+
{
|
|
10871
|
+
"path": "postRecordSec",
|
|
10872
|
+
"valueType": "number"
|
|
10873
|
+
},
|
|
10874
|
+
{
|
|
10875
|
+
"path": "segmentMinutes",
|
|
10876
|
+
"valueType": "number"
|
|
10877
|
+
},
|
|
10878
|
+
{
|
|
10879
|
+
"path": "unreadableWindows",
|
|
10880
|
+
"valueType": "number"
|
|
10881
|
+
},
|
|
10882
|
+
{
|
|
10883
|
+
"path": "recordingToNowhere",
|
|
10884
|
+
"valueType": "boolean"
|
|
10885
|
+
}
|
|
10886
|
+
],
|
|
10887
|
+
"recording-signal": [{
|
|
10888
|
+
"path": "active",
|
|
10889
|
+
"valueType": "boolean"
|
|
10890
|
+
}, {
|
|
10891
|
+
"path": "reason",
|
|
10892
|
+
"valueType": "string"
|
|
10893
|
+
}],
|
|
10894
|
+
"running-state": [
|
|
10895
|
+
{
|
|
10896
|
+
"path": "running",
|
|
10897
|
+
"valueType": "boolean"
|
|
10898
|
+
},
|
|
10899
|
+
{
|
|
10900
|
+
"path": "since",
|
|
10901
|
+
"valueType": "number"
|
|
10902
|
+
},
|
|
10903
|
+
{
|
|
10904
|
+
"path": "source",
|
|
10905
|
+
"valueType": "enum",
|
|
10906
|
+
"enumValues": ["native", "assigned"]
|
|
10907
|
+
},
|
|
10908
|
+
{
|
|
10909
|
+
"path": "phase",
|
|
10910
|
+
"valueType": "string"
|
|
10911
|
+
}
|
|
10912
|
+
],
|
|
10913
|
+
"script-runner": [
|
|
10914
|
+
{
|
|
10915
|
+
"path": "isRunning",
|
|
10916
|
+
"valueType": "boolean"
|
|
10917
|
+
},
|
|
10918
|
+
{
|
|
10919
|
+
"path": "lastRunAt",
|
|
10920
|
+
"valueType": "number"
|
|
10921
|
+
},
|
|
10922
|
+
{
|
|
10923
|
+
"path": "lastRunSuccess",
|
|
10924
|
+
"valueType": "boolean"
|
|
10925
|
+
},
|
|
10926
|
+
{
|
|
10927
|
+
"path": "lastError",
|
|
10928
|
+
"valueType": "string"
|
|
10929
|
+
}
|
|
10930
|
+
],
|
|
10931
|
+
"smoke": [{
|
|
10932
|
+
"path": "detected",
|
|
10933
|
+
"valueType": "boolean"
|
|
10934
|
+
}],
|
|
10935
|
+
"snapshot": [
|
|
10936
|
+
{
|
|
10937
|
+
"path": "lastCapturedAt",
|
|
10938
|
+
"valueType": "number"
|
|
10939
|
+
},
|
|
10940
|
+
{
|
|
10941
|
+
"path": "cacheAgeMs",
|
|
10942
|
+
"valueType": "number"
|
|
10943
|
+
},
|
|
10944
|
+
{
|
|
10945
|
+
"path": "lastBytes",
|
|
10946
|
+
"valueType": "number"
|
|
10947
|
+
},
|
|
10948
|
+
{
|
|
10949
|
+
"path": "lastStreamId",
|
|
10950
|
+
"valueType": "string"
|
|
10951
|
+
}
|
|
10952
|
+
],
|
|
10953
|
+
"stream-params": [
|
|
10954
|
+
{
|
|
10955
|
+
"path": "main.width",
|
|
10956
|
+
"valueType": "number"
|
|
10957
|
+
},
|
|
10958
|
+
{
|
|
10959
|
+
"path": "main.height",
|
|
10960
|
+
"valueType": "number"
|
|
10961
|
+
},
|
|
10962
|
+
{
|
|
10963
|
+
"path": "main.codec",
|
|
10964
|
+
"valueType": "enum",
|
|
10965
|
+
"enumValues": ["h264", "h265"]
|
|
10966
|
+
},
|
|
10967
|
+
{
|
|
10968
|
+
"path": "main.framerate",
|
|
10969
|
+
"valueType": "number"
|
|
10970
|
+
},
|
|
10971
|
+
{
|
|
10972
|
+
"path": "main.bitrate",
|
|
10973
|
+
"valueType": "number"
|
|
10974
|
+
},
|
|
10975
|
+
{
|
|
10976
|
+
"path": "main.bitrateMode",
|
|
10977
|
+
"valueType": "enum",
|
|
10978
|
+
"enumValues": ["vbr", "cbr"]
|
|
10979
|
+
},
|
|
10980
|
+
{
|
|
10981
|
+
"path": "main.encoderProfile",
|
|
10982
|
+
"valueType": "enum",
|
|
10983
|
+
"enumValues": [
|
|
10984
|
+
"high",
|
|
10985
|
+
"main",
|
|
10986
|
+
"baseline"
|
|
10987
|
+
]
|
|
10988
|
+
},
|
|
10989
|
+
{
|
|
10990
|
+
"path": "main.gop",
|
|
10991
|
+
"valueType": "number"
|
|
10992
|
+
},
|
|
10993
|
+
{
|
|
10994
|
+
"path": "main.audio",
|
|
10995
|
+
"valueType": "boolean"
|
|
10996
|
+
},
|
|
10997
|
+
{
|
|
10998
|
+
"path": "sub.width",
|
|
10999
|
+
"valueType": "number"
|
|
11000
|
+
},
|
|
11001
|
+
{
|
|
11002
|
+
"path": "sub.height",
|
|
11003
|
+
"valueType": "number"
|
|
11004
|
+
},
|
|
11005
|
+
{
|
|
11006
|
+
"path": "sub.codec",
|
|
11007
|
+
"valueType": "enum",
|
|
11008
|
+
"enumValues": ["h264", "h265"]
|
|
11009
|
+
},
|
|
11010
|
+
{
|
|
11011
|
+
"path": "sub.framerate",
|
|
11012
|
+
"valueType": "number"
|
|
11013
|
+
},
|
|
11014
|
+
{
|
|
11015
|
+
"path": "sub.bitrate",
|
|
11016
|
+
"valueType": "number"
|
|
11017
|
+
},
|
|
11018
|
+
{
|
|
11019
|
+
"path": "sub.bitrateMode",
|
|
11020
|
+
"valueType": "enum",
|
|
11021
|
+
"enumValues": ["vbr", "cbr"]
|
|
11022
|
+
},
|
|
11023
|
+
{
|
|
11024
|
+
"path": "sub.encoderProfile",
|
|
11025
|
+
"valueType": "enum",
|
|
11026
|
+
"enumValues": [
|
|
11027
|
+
"high",
|
|
11028
|
+
"main",
|
|
11029
|
+
"baseline"
|
|
11030
|
+
]
|
|
11031
|
+
},
|
|
11032
|
+
{
|
|
11033
|
+
"path": "sub.gop",
|
|
11034
|
+
"valueType": "number"
|
|
11035
|
+
},
|
|
11036
|
+
{
|
|
11037
|
+
"path": "sub.audio",
|
|
11038
|
+
"valueType": "boolean"
|
|
11039
|
+
},
|
|
11040
|
+
{
|
|
11041
|
+
"path": "ext.width",
|
|
11042
|
+
"valueType": "number"
|
|
11043
|
+
},
|
|
11044
|
+
{
|
|
11045
|
+
"path": "ext.height",
|
|
11046
|
+
"valueType": "number"
|
|
11047
|
+
},
|
|
11048
|
+
{
|
|
11049
|
+
"path": "ext.codec",
|
|
11050
|
+
"valueType": "enum",
|
|
11051
|
+
"enumValues": ["h264", "h265"]
|
|
11052
|
+
},
|
|
11053
|
+
{
|
|
11054
|
+
"path": "ext.framerate",
|
|
11055
|
+
"valueType": "number"
|
|
11056
|
+
},
|
|
11057
|
+
{
|
|
11058
|
+
"path": "ext.bitrate",
|
|
11059
|
+
"valueType": "number"
|
|
11060
|
+
},
|
|
11061
|
+
{
|
|
11062
|
+
"path": "ext.bitrateMode",
|
|
11063
|
+
"valueType": "enum",
|
|
11064
|
+
"enumValues": ["vbr", "cbr"]
|
|
11065
|
+
},
|
|
11066
|
+
{
|
|
11067
|
+
"path": "ext.encoderProfile",
|
|
11068
|
+
"valueType": "enum",
|
|
11069
|
+
"enumValues": [
|
|
11070
|
+
"high",
|
|
11071
|
+
"main",
|
|
11072
|
+
"baseline"
|
|
11073
|
+
]
|
|
11074
|
+
},
|
|
11075
|
+
{
|
|
11076
|
+
"path": "ext.gop",
|
|
11077
|
+
"valueType": "number"
|
|
11078
|
+
},
|
|
11079
|
+
{
|
|
11080
|
+
"path": "ext.audio",
|
|
11081
|
+
"valueType": "boolean"
|
|
11082
|
+
}
|
|
11083
|
+
],
|
|
11084
|
+
"switch": [{
|
|
11085
|
+
"path": "on",
|
|
11086
|
+
"valueType": "boolean"
|
|
11087
|
+
}],
|
|
11088
|
+
"tamper": [{
|
|
11089
|
+
"path": "tampered",
|
|
11090
|
+
"valueType": "boolean"
|
|
11091
|
+
}],
|
|
11092
|
+
"temperature-sensor": [
|
|
11093
|
+
{
|
|
11094
|
+
"path": "celsius",
|
|
11095
|
+
"valueType": "number"
|
|
11096
|
+
},
|
|
11097
|
+
{
|
|
11098
|
+
"path": "unit",
|
|
11099
|
+
"valueType": "string"
|
|
11100
|
+
},
|
|
11101
|
+
{
|
|
11102
|
+
"path": "precision",
|
|
11103
|
+
"valueType": "number"
|
|
11104
|
+
}
|
|
11105
|
+
],
|
|
11106
|
+
"update": [
|
|
11107
|
+
{
|
|
11108
|
+
"path": "currentVersion",
|
|
11109
|
+
"valueType": "string"
|
|
11110
|
+
},
|
|
11111
|
+
{
|
|
11112
|
+
"path": "availableVersion",
|
|
11113
|
+
"valueType": "string"
|
|
11114
|
+
},
|
|
11115
|
+
{
|
|
11116
|
+
"path": "updatable",
|
|
11117
|
+
"valueType": "boolean"
|
|
11118
|
+
},
|
|
11119
|
+
{
|
|
11120
|
+
"path": "state",
|
|
11121
|
+
"valueType": "string"
|
|
11122
|
+
},
|
|
11123
|
+
{
|
|
11124
|
+
"path": "inProgress",
|
|
11125
|
+
"valueType": "boolean"
|
|
11126
|
+
}
|
|
11127
|
+
],
|
|
11128
|
+
"vacuum-control": [
|
|
11129
|
+
{
|
|
11130
|
+
"path": "state",
|
|
11131
|
+
"valueType": "enum",
|
|
11132
|
+
"enumValues": [
|
|
11133
|
+
"idle",
|
|
11134
|
+
"cleaning",
|
|
11135
|
+
"paused",
|
|
11136
|
+
"returning",
|
|
11137
|
+
"docked",
|
|
11138
|
+
"drying",
|
|
11139
|
+
"error"
|
|
11140
|
+
]
|
|
11141
|
+
},
|
|
11142
|
+
{
|
|
11143
|
+
"path": "batteryLevel",
|
|
11144
|
+
"valueType": "number"
|
|
11145
|
+
},
|
|
11146
|
+
{
|
|
11147
|
+
"path": "fanSpeed",
|
|
11148
|
+
"valueType": "string"
|
|
11149
|
+
},
|
|
11150
|
+
{
|
|
11151
|
+
"path": "progressPercent",
|
|
11152
|
+
"valueType": "number"
|
|
11153
|
+
},
|
|
11154
|
+
{
|
|
11155
|
+
"path": "errorCode",
|
|
11156
|
+
"valueType": "number"
|
|
11157
|
+
},
|
|
11158
|
+
{
|
|
11159
|
+
"path": "errorLabel",
|
|
11160
|
+
"valueType": "string"
|
|
11161
|
+
}
|
|
11162
|
+
],
|
|
11163
|
+
"valve": [{
|
|
11164
|
+
"path": "state",
|
|
11165
|
+
"valueType": "enum",
|
|
11166
|
+
"enumValues": [
|
|
11167
|
+
"open",
|
|
11168
|
+
"opening",
|
|
11169
|
+
"closing",
|
|
11170
|
+
"closed",
|
|
11171
|
+
"stopped"
|
|
11172
|
+
]
|
|
11173
|
+
}, {
|
|
11174
|
+
"path": "position",
|
|
11175
|
+
"valueType": "number"
|
|
11176
|
+
}],
|
|
11177
|
+
"vibration": [{
|
|
11178
|
+
"path": "detected",
|
|
11179
|
+
"valueType": "boolean"
|
|
11180
|
+
}],
|
|
11181
|
+
"water-heater": [
|
|
11182
|
+
{
|
|
11183
|
+
"path": "currentTemp",
|
|
11184
|
+
"valueType": "number"
|
|
11185
|
+
},
|
|
11186
|
+
{
|
|
11187
|
+
"path": "targetTemp",
|
|
11188
|
+
"valueType": "number"
|
|
11189
|
+
},
|
|
11190
|
+
{
|
|
11191
|
+
"path": "operationMode",
|
|
11192
|
+
"valueType": "string"
|
|
11193
|
+
},
|
|
11194
|
+
{
|
|
11195
|
+
"path": "away",
|
|
11196
|
+
"valueType": "boolean"
|
|
11197
|
+
},
|
|
11198
|
+
{
|
|
11199
|
+
"path": "minTemp",
|
|
11200
|
+
"valueType": "number"
|
|
11201
|
+
},
|
|
11202
|
+
{
|
|
11203
|
+
"path": "maxTemp",
|
|
11204
|
+
"valueType": "number"
|
|
11205
|
+
}
|
|
11206
|
+
],
|
|
11207
|
+
"weather": [
|
|
11208
|
+
{
|
|
11209
|
+
"path": "condition",
|
|
11210
|
+
"valueType": "string"
|
|
11211
|
+
},
|
|
11212
|
+
{
|
|
11213
|
+
"path": "temperature",
|
|
11214
|
+
"valueType": "number"
|
|
11215
|
+
},
|
|
11216
|
+
{
|
|
11217
|
+
"path": "temperatureUnit",
|
|
11218
|
+
"valueType": "string"
|
|
11219
|
+
},
|
|
11220
|
+
{
|
|
11221
|
+
"path": "humidity",
|
|
11222
|
+
"valueType": "number"
|
|
11223
|
+
},
|
|
11224
|
+
{
|
|
11225
|
+
"path": "pressure",
|
|
11226
|
+
"valueType": "number"
|
|
11227
|
+
},
|
|
11228
|
+
{
|
|
11229
|
+
"path": "pressureUnit",
|
|
11230
|
+
"valueType": "string"
|
|
11231
|
+
},
|
|
11232
|
+
{
|
|
11233
|
+
"path": "windSpeed",
|
|
11234
|
+
"valueType": "number"
|
|
11235
|
+
},
|
|
11236
|
+
{
|
|
11237
|
+
"path": "windSpeedUnit",
|
|
11238
|
+
"valueType": "string"
|
|
11239
|
+
},
|
|
11240
|
+
{
|
|
11241
|
+
"path": "windBearing",
|
|
11242
|
+
"valueType": "number"
|
|
11243
|
+
}
|
|
11244
|
+
],
|
|
11245
|
+
"zone-analytics": [
|
|
11246
|
+
{
|
|
11247
|
+
"path": "ts",
|
|
11248
|
+
"valueType": "number"
|
|
11249
|
+
},
|
|
11250
|
+
{
|
|
11251
|
+
"path": "frameWidth",
|
|
11252
|
+
"valueType": "number"
|
|
11253
|
+
},
|
|
11254
|
+
{
|
|
11255
|
+
"path": "frameHeight",
|
|
11256
|
+
"valueType": "number"
|
|
11257
|
+
},
|
|
11258
|
+
{
|
|
11259
|
+
"path": "frame.totalObjects",
|
|
11260
|
+
"valueType": "number"
|
|
11261
|
+
},
|
|
11262
|
+
{
|
|
11263
|
+
"path": "frame.standingObjects",
|
|
11264
|
+
"valueType": "number"
|
|
11265
|
+
},
|
|
11266
|
+
{
|
|
11267
|
+
"path": "frame.transientObjects",
|
|
11268
|
+
"valueType": "number"
|
|
11269
|
+
},
|
|
11270
|
+
{
|
|
11271
|
+
"path": "unzoned.totalObjects",
|
|
11272
|
+
"valueType": "number"
|
|
11273
|
+
},
|
|
11274
|
+
{
|
|
11275
|
+
"path": "unzoned.standingObjects",
|
|
11276
|
+
"valueType": "number"
|
|
11277
|
+
},
|
|
11278
|
+
{
|
|
11279
|
+
"path": "unzoned.transientObjects",
|
|
11280
|
+
"valueType": "number"
|
|
11281
|
+
}
|
|
11282
|
+
]
|
|
11283
|
+
});
|
|
9310
11284
|
object({
|
|
9311
11285
|
code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
|
|
9312
11286
|
params: record(string(), union([string(), number()])).optional()
|
|
@@ -9689,7 +11663,7 @@ function errMsg$2(err) {
|
|
|
9689
11663
|
return String(err);
|
|
9690
11664
|
}
|
|
9691
11665
|
//#endregion
|
|
9692
|
-
//#region ../types/dist/composition-
|
|
11666
|
+
//#region ../types/dist/composition-kEl9mevu.mjs
|
|
9693
11667
|
/**
|
|
9694
11668
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
9695
11669
|
*
|
|
@@ -13365,7 +15339,7 @@ var LogChannelDescriptorSchema = object({
|
|
|
13365
15339
|
* `true` is a PROMISE with two halves, and both must hold: the gate is
|
|
13366
15340
|
* consulted with the numeric device id, AND every line the channel admits
|
|
13367
15341
|
* carries `tags: { deviceId }` with that same numeric id. The second half is
|
|
13368
|
-
* what makes `| json | deviceId="
|
|
15342
|
+
* what makes `| json | deviceId="102"` work in Loki — `loki-payload.ts`
|
|
13369
15343
|
* keeps `deviceId` out of the stream labels for cardinality, so the tag in
|
|
13370
15344
|
* the body is the only way to filter.
|
|
13371
15345
|
*
|
|
@@ -13572,7 +15546,7 @@ var ModelVariantGroupSchema = object({
|
|
|
13572
15546
|
precision: _enum(["fp32", "int8"]).optional(),
|
|
13573
15547
|
/**
|
|
13574
15548
|
* Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
|
|
13575
|
-
* an alternate training of the same family (
|
|
15549
|
+
* an alternate training of the same family (plugin catalog `relu_test`); chip
|
|
13576
15550
|
* label is "Test".
|
|
13577
15551
|
*/
|
|
13578
15552
|
optimization: _enum(["standard", "test"]).optional(),
|
|
@@ -13824,8 +15798,8 @@ var ModelCatalogEntrySchema = object({
|
|
|
13824
15798
|
provider: ModelProviderIdSchema.optional(),
|
|
13825
15799
|
/**
|
|
13826
15800
|
* Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
|
|
13827
|
-
* applies (
|
|
13828
|
-
* labels already ARE the CamStack macros (
|
|
15801
|
+
* applies (plus catalog / COCO public catalog). Set on a custom model whose raw
|
|
15802
|
+
* labels already ARE the CamStack macros (plugin catalog identity map).
|
|
13829
15803
|
*/
|
|
13830
15804
|
classMap: DetectionCatalogClassMapSchema.optional(),
|
|
13831
15805
|
/**
|
|
@@ -16851,7 +18825,7 @@ method(object({
|
|
|
16851
18825
|
* `1` is real time and is the ONLY value that allows the copy branch —
|
|
16852
18826
|
* anything else forces `libx264` over the window. That was priced
|
|
16853
18827
|
* before it was chosen: a per-event burst measured at 0.23 s and 254 KB
|
|
16854
|
-
* on a real
|
|
18828
|
+
* on a real 101 720p cut, against 922 KB for the copy it replaces. A
|
|
16855
18829
|
* re-encode is capped at 720p (`EVENT_CLIP_ENCODE_MAX_WIDTH`), because
|
|
16856
18830
|
* once the decode is forced the width stops being free.
|
|
16857
18831
|
*/
|
|
@@ -17271,6 +19245,7 @@ var CompositionRunStatusSchema = _enum([
|
|
|
17271
19245
|
"starting",
|
|
17272
19246
|
"running",
|
|
17273
19247
|
"degraded",
|
|
19248
|
+
"incomplete",
|
|
17274
19249
|
"failed"
|
|
17275
19250
|
]);
|
|
17276
19251
|
var CompositionFieldStateKindSchema = _enum([
|
|
@@ -17484,6 +19459,7 @@ var CoreBlockStatusSchema = _enum([
|
|
|
17484
19459
|
"starting",
|
|
17485
19460
|
"running",
|
|
17486
19461
|
"degraded",
|
|
19462
|
+
"incomplete",
|
|
17487
19463
|
"failed"
|
|
17488
19464
|
]);
|
|
17489
19465
|
/** path → TypeScript source for a multi-file block. */
|
|
@@ -39407,7 +41383,7 @@ var PRIMARY_CATEGORIES = new Set(ENTRIES.map((e) => e.primaryCategory));
|
|
|
39407
41383
|
* `locationKey` is ALWAYS {@link locationIconKey} of the label — never the
|
|
39408
41384
|
* operator's casing. The registry matches labels trimmed + case-insensitively
|
|
39409
41385
|
* everywhere (`addLocation`, `removeLocation`, `renameLocation`), and a
|
|
39410
|
-
* case-only rename (`
|
|
41386
|
+
* case-only rename (`kitchen` → `Kitchen`) is a real edit this repo supports; a
|
|
39411
41387
|
* map keyed on the displayed casing would orphan its entry on exactly that
|
|
39412
41388
|
* edit. Consumers join by keying their own label through `locationIconKey`.
|
|
39413
41389
|
*/
|
|
@@ -39432,7 +41408,7 @@ var LocationDescriptionAssignmentSchema = object({
|
|
|
39432
41408
|
/**
|
|
39433
41409
|
* A SITE ZONE — a named part of the property that several locations belong to.
|
|
39434
41410
|
*
|
|
39435
|
-
* "
|
|
41411
|
+
* "Night zone" holds every bedroom; "Zona giorno" the living room and the
|
|
39436
41412
|
* kitchen. A camera belongs to exactly one location, and a location to at most
|
|
39437
41413
|
* one zone, so a camera's zone is derived and never stored on the device: the
|
|
39438
41414
|
* whole point of this entity is that grouping rooms touches no device row.
|
|
@@ -39461,7 +41437,7 @@ var LocationDescriptionAssignmentSchema = object({
|
|
|
39461
41437
|
* the locations inside it.
|
|
39462
41438
|
*
|
|
39463
41439
|
* The LABEL is carried alongside the key because the key is lossy on purpose —
|
|
39464
|
-
* a surface must show "
|
|
41440
|
+
* a surface must show "Night zone", not "night zone". Locations are carried
|
|
39465
41441
|
* here, rather than left to a second call, because every consumer wants both
|
|
39466
41442
|
* at once and a viewer that asked twice could render a zone whose membership
|
|
39467
41443
|
* it has not fetched yet.
|
|
@@ -41574,8 +43550,8 @@ var LoadContributionSchema = object({
|
|
|
41574
43550
|
"unattributable"
|
|
41575
43551
|
]),
|
|
41576
43552
|
/**
|
|
41577
|
-
* What ONE entry is, in the contributor's own words — `
|
|
41578
|
-
* `
|
|
43553
|
+
* What ONE entry is, in the contributor's own words — `101/high`,
|
|
43554
|
+
* `102/native`, `cuda:0 shared pool`. Free text because the unit differs per
|
|
41579
43555
|
* family and inventing a common one would lose the only information that
|
|
41580
43556
|
* makes two entries for the same camera distinguishable.
|
|
41581
43557
|
*/
|
|
@@ -43223,6 +45199,649 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
43223
45199
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
43224
45200
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
43225
45201
|
/**
|
|
45202
|
+
* Palette entry ids (D939). Audio is the one gradient; `audio-*` leaves are
|
|
45203
|
+
* not entries. `heatmapScrub` is a mark, not an event kind.
|
|
45204
|
+
*/
|
|
45205
|
+
var PALETTE_ENTRY_IDS = [
|
|
45206
|
+
"motion",
|
|
45207
|
+
"audio",
|
|
45208
|
+
"recording",
|
|
45209
|
+
"live",
|
|
45210
|
+
"heatmapScrub",
|
|
45211
|
+
"person",
|
|
45212
|
+
"vehicle",
|
|
45213
|
+
"animal",
|
|
45214
|
+
"package",
|
|
45215
|
+
"sensor",
|
|
45216
|
+
"control",
|
|
45217
|
+
"face",
|
|
45218
|
+
"plate",
|
|
45219
|
+
"car",
|
|
45220
|
+
"truck",
|
|
45221
|
+
"bus",
|
|
45222
|
+
"motorcycle",
|
|
45223
|
+
"bicycle",
|
|
45224
|
+
"airplane",
|
|
45225
|
+
"boat",
|
|
45226
|
+
"train",
|
|
45227
|
+
"bird",
|
|
45228
|
+
"dog",
|
|
45229
|
+
"cat",
|
|
45230
|
+
"horse",
|
|
45231
|
+
"sheep",
|
|
45232
|
+
"cow",
|
|
45233
|
+
"elephant",
|
|
45234
|
+
"bear",
|
|
45235
|
+
"zebra",
|
|
45236
|
+
"giraffe",
|
|
45237
|
+
"package-delivered",
|
|
45238
|
+
"package-picked-up",
|
|
45239
|
+
"suitcase",
|
|
45240
|
+
"backpack",
|
|
45241
|
+
"handbag",
|
|
45242
|
+
"contact",
|
|
45243
|
+
"motion-sensor",
|
|
45244
|
+
"smoke",
|
|
45245
|
+
"flood",
|
|
45246
|
+
"gas",
|
|
45247
|
+
"carbon-monoxide",
|
|
45248
|
+
"vibration",
|
|
45249
|
+
"tamper",
|
|
45250
|
+
"presence",
|
|
45251
|
+
"enum-sensor",
|
|
45252
|
+
"device-event",
|
|
45253
|
+
"lock",
|
|
45254
|
+
"cover",
|
|
45255
|
+
"switch",
|
|
45256
|
+
"siren",
|
|
45257
|
+
"button",
|
|
45258
|
+
"doorbell"
|
|
45259
|
+
];
|
|
45260
|
+
var AUDIO_ENTRY_ID = "audio";
|
|
45261
|
+
/** Six rungs, quiet → loud. The opaque end is the entry's hex. */
|
|
45262
|
+
var AUDIO_GRADIENT_ALPHAS = [
|
|
45263
|
+
.3,
|
|
45264
|
+
.42,
|
|
45265
|
+
.55,
|
|
45266
|
+
.7,
|
|
45267
|
+
.85,
|
|
45268
|
+
1
|
|
45269
|
+
];
|
|
45270
|
+
var PALETTE_PRESET_IDS = [
|
|
45271
|
+
"camstack",
|
|
45272
|
+
"high-contrast",
|
|
45273
|
+
"okabe-ito"
|
|
45274
|
+
];
|
|
45275
|
+
function isPaletteEntryId(id) {
|
|
45276
|
+
return PALETTE_ENTRY_IDS.includes(id);
|
|
45277
|
+
}
|
|
45278
|
+
function isPalettePresetId(id) {
|
|
45279
|
+
return PALETTE_PRESET_IDS.includes(id);
|
|
45280
|
+
}
|
|
45281
|
+
/**
|
|
45282
|
+
* CIEDE2000 and WCAG contrast for the display palette (D939).
|
|
45283
|
+
*
|
|
45284
|
+
* One implementation, shared by the hub validator, the admin editor and
|
|
45285
|
+
* (phase 2) the viewer. The arithmetic matches the viewer's `src/theme/cie.ts`.
|
|
45286
|
+
*/
|
|
45287
|
+
/** Page backgrounds the contrast rule is measured against. */
|
|
45288
|
+
var PALETTE_BACKGROUNDS = {
|
|
45289
|
+
dark: "#0c0a09",
|
|
45290
|
+
light: "#fafaf9"
|
|
45291
|
+
};
|
|
45292
|
+
/** Marks that are not event kinds and share the raised distance floor. */
|
|
45293
|
+
var PALETTE_MARK_PAIR = ["live", "heatmapScrub"];
|
|
45294
|
+
var HEX = /^#[0-9a-fA-F]{6}$/;
|
|
45295
|
+
function srgbChannel(hex, start) {
|
|
45296
|
+
return Number.parseInt(hex.slice(start, start + 2), 16);
|
|
45297
|
+
}
|
|
45298
|
+
function srgbToLin(channel) {
|
|
45299
|
+
const x = channel / 255;
|
|
45300
|
+
return x <= .04045 ? x / 12.92 : ((x + .055) / 1.055) ** 2.4;
|
|
45301
|
+
}
|
|
45302
|
+
function relativeLuminance(hex) {
|
|
45303
|
+
const r = srgbToLin(srgbChannel(hex, 1));
|
|
45304
|
+
const g = srgbToLin(srgbChannel(hex, 3));
|
|
45305
|
+
const b = srgbToLin(srgbChannel(hex, 5));
|
|
45306
|
+
return .2126 * r + .7152 * g + .0722 * b;
|
|
45307
|
+
}
|
|
45308
|
+
/** WCAG contrast ratio of two `#rrggbb` colours. Non-hex returns 0. */
|
|
45309
|
+
function contrastRatio(a, b) {
|
|
45310
|
+
if (!HEX.test(a) || !HEX.test(b)) return 0;
|
|
45311
|
+
const hi = Math.max(relativeLuminance(a), relativeLuminance(b));
|
|
45312
|
+
const lo = Math.min(relativeLuminance(a), relativeLuminance(b));
|
|
45313
|
+
return (hi + .05) / (lo + .05);
|
|
45314
|
+
}
|
|
45315
|
+
function xyzToLab(hex) {
|
|
45316
|
+
const r = srgbToLin(srgbChannel(hex, 1));
|
|
45317
|
+
const g = srgbToLin(srgbChannel(hex, 3));
|
|
45318
|
+
const bl = srgbToLin(srgbChannel(hex, 5));
|
|
45319
|
+
const x = .4124564 * r + .3575761 * g + .1804375 * bl;
|
|
45320
|
+
const y = .2126729 * r + .7151522 * g + .072175 * bl;
|
|
45321
|
+
const z = .0193339 * r + .119192 * g + .9503041 * bl;
|
|
45322
|
+
const f = (t) => t > .008856 ? Math.cbrt(t) : 7.787 * t + 16 / 116;
|
|
45323
|
+
const fx = f(x / .95047);
|
|
45324
|
+
const fy = f(y);
|
|
45325
|
+
const fz = f(z / 1.08883);
|
|
45326
|
+
return {
|
|
45327
|
+
L: 116 * fy - 16,
|
|
45328
|
+
a: 500 * (fx - fy),
|
|
45329
|
+
b: 200 * (fy - fz)
|
|
45330
|
+
};
|
|
45331
|
+
}
|
|
45332
|
+
function hueDeg(ap, b) {
|
|
45333
|
+
if (ap === 0 && b === 0) return 0;
|
|
45334
|
+
const ang = Math.atan2(b, ap) * 180 / Math.PI;
|
|
45335
|
+
return ang < 0 ? ang + 360 : ang;
|
|
45336
|
+
}
|
|
45337
|
+
/** CIEDE2000. Non-hex returns 0 so a bad swatch fails the distinctness rule. */
|
|
45338
|
+
function deltaE00(hex1, hex2) {
|
|
45339
|
+
if (!HEX.test(hex1) || !HEX.test(hex2)) return 0;
|
|
45340
|
+
const lab1 = xyzToLab(hex1);
|
|
45341
|
+
const lab2 = xyzToLab(hex2);
|
|
45342
|
+
const cab7 = ((Math.hypot(lab1.a, lab1.b) + Math.hypot(lab2.a, lab2.b)) / 2) ** 7;
|
|
45343
|
+
const g = .5 * (1 - Math.sqrt(cab7 / (cab7 + 25 ** 7)));
|
|
45344
|
+
const a1p = (1 + g) * lab1.a;
|
|
45345
|
+
const a2p = (1 + g) * lab2.a;
|
|
45346
|
+
const c1p = Math.hypot(a1p, lab1.b);
|
|
45347
|
+
const c2p = Math.hypot(a2p, lab2.b);
|
|
45348
|
+
const h1p = hueDeg(a1p, lab1.b);
|
|
45349
|
+
const h2p = hueDeg(a2p, lab2.b);
|
|
45350
|
+
let dhp = 0;
|
|
45351
|
+
if (c1p * c2p !== 0) {
|
|
45352
|
+
dhp = h2p - h1p;
|
|
45353
|
+
if (dhp > 180) dhp -= 360;
|
|
45354
|
+
else if (dhp < -180) dhp += 360;
|
|
45355
|
+
}
|
|
45356
|
+
const dHp = 2 * Math.sqrt(c1p * c2p) * Math.sin(dhp * Math.PI / 360);
|
|
45357
|
+
const lbp = (lab1.L + lab2.L) / 2;
|
|
45358
|
+
const cbp = (c1p + c2p) / 2;
|
|
45359
|
+
let hbp = h1p + h2p;
|
|
45360
|
+
if (c1p * c2p !== 0) {
|
|
45361
|
+
if (Math.abs(h1p - h2p) > 180) hbp += hbp < 360 ? 360 : -360;
|
|
45362
|
+
hbp /= 2;
|
|
45363
|
+
}
|
|
45364
|
+
const t = 1 - .17 * Math.cos((hbp - 30) * Math.PI / 180) + .24 * Math.cos(2 * hbp * Math.PI / 180) + .32 * Math.cos((3 * hbp + 6) * Math.PI / 180) - .2 * Math.cos((4 * hbp - 63) * Math.PI / 180);
|
|
45365
|
+
const dTheta = 30 * Math.exp(-(((hbp - 275) / 25) ** 2));
|
|
45366
|
+
const cbp7 = cbp ** 7;
|
|
45367
|
+
const rc = 2 * Math.sqrt(cbp7 / (cbp7 + 25 ** 7));
|
|
45368
|
+
const sl = 1 + .015 * (lbp - 50) ** 2 / Math.sqrt(20 + (lbp - 50) ** 2);
|
|
45369
|
+
const sc = 1 + .045 * cbp;
|
|
45370
|
+
const sh = 1 + .015 * cbp * t;
|
|
45371
|
+
const rt = -Math.sin(2 * dTheta * Math.PI / 180) * rc;
|
|
45372
|
+
const dLp = lab2.L - lab1.L;
|
|
45373
|
+
const dCp = c2p - c1p;
|
|
45374
|
+
return Math.sqrt((dLp / sl) ** 2 + (dCp / sc) ** 2 + (dHp / sh) ** 2 + rt * (dCp / sc) * (dHp / sh));
|
|
45375
|
+
}
|
|
45376
|
+
/** Frozen palette tables (D939). The spec refuses a table that breaks the rule. */
|
|
45377
|
+
var CAMSTACK_HEX = {
|
|
45378
|
+
motion: "#d946ef",
|
|
45379
|
+
audio: "#059eb8",
|
|
45380
|
+
recording: "#ef4444",
|
|
45381
|
+
live: "#8d7a00",
|
|
45382
|
+
heatmapScrub: "#4b32ff",
|
|
45383
|
+
person: "#11a64c",
|
|
45384
|
+
vehicle: "#3b82f6",
|
|
45385
|
+
animal: "#ea6a09",
|
|
45386
|
+
package: "#924667",
|
|
45387
|
+
sensor: "#624bbc",
|
|
45388
|
+
control: "#944d24",
|
|
45389
|
+
face: "#ed4f8d",
|
|
45390
|
+
plate: "#4b7027",
|
|
45391
|
+
car: "#9684cf",
|
|
45392
|
+
truck: "#0f9b89",
|
|
45393
|
+
bus: "#a734a9",
|
|
45394
|
+
motorcycle: "#c1133a",
|
|
45395
|
+
bicycle: "#0e6a9b",
|
|
45396
|
+
airplane: "#7c9928",
|
|
45397
|
+
boat: "#b17933",
|
|
45398
|
+
train: "#ad6ca3",
|
|
45399
|
+
bird: "#0f7c55",
|
|
45400
|
+
dog: "#c82700",
|
|
45401
|
+
cat: "#7268f2",
|
|
45402
|
+
horse: "#cb795e",
|
|
45403
|
+
sheep: "#b8636b",
|
|
45404
|
+
cow: "#cb2969",
|
|
45405
|
+
elephant: "#1158d2",
|
|
45406
|
+
bear: "#8d5e00",
|
|
45407
|
+
zebra: "#0097d6",
|
|
45408
|
+
giraffe: "#8f61bb",
|
|
45409
|
+
"package-delivered": "#cd3f9b",
|
|
45410
|
+
"package-picked-up": "#388a08",
|
|
45411
|
+
suitcase: "#666800",
|
|
45412
|
+
backpack: "#ec5022",
|
|
45413
|
+
handbag: "#a76ef8",
|
|
45414
|
+
contact: "#ab5a49",
|
|
45415
|
+
"motion-sensor": "#b95d1a",
|
|
45416
|
+
smoke: "#dd3858",
|
|
45417
|
+
flood: "#b31e7d",
|
|
45418
|
+
gas: "#5b70b5",
|
|
45419
|
+
"carbon-monoxide": "#7b4e8e",
|
|
45420
|
+
vibration: "#e65bba",
|
|
45421
|
+
tamper: "#98464b",
|
|
45422
|
+
presence: "#3a9468",
|
|
45423
|
+
"enum-sensor": "#7885f8",
|
|
45424
|
+
"device-event": "#8c43c8",
|
|
45425
|
+
lock: "#649653",
|
|
45426
|
+
cover: "#c67597",
|
|
45427
|
+
switch: "#7a812a",
|
|
45428
|
+
siren: "#ac5d7f",
|
|
45429
|
+
button: "#b276cd",
|
|
45430
|
+
doorbell: "#0087ab"
|
|
45431
|
+
};
|
|
45432
|
+
var CAMSTACK_FALLBACK = [
|
|
45433
|
+
"#b34dc7",
|
|
45434
|
+
"#1d7d34",
|
|
45435
|
+
"#db6b6c",
|
|
45436
|
+
"#a43d29",
|
|
45437
|
+
"#0e6ee6",
|
|
45438
|
+
"#29a10b",
|
|
45439
|
+
"#a98731",
|
|
45440
|
+
"#0181c6"
|
|
45441
|
+
];
|
|
45442
|
+
var HIGH_CONTRAST_HEX = {
|
|
45443
|
+
motion: "#964360",
|
|
45444
|
+
audio: "#23a132",
|
|
45445
|
+
recording: "#2494ca",
|
|
45446
|
+
live: "#bd7e2b",
|
|
45447
|
+
heatmapScrub: "#ad6eea",
|
|
45448
|
+
person: "#62611e",
|
|
45449
|
+
vehicle: "#f4534c",
|
|
45450
|
+
animal: "#1556cd",
|
|
45451
|
+
package: "#9c4415",
|
|
45452
|
+
sensor: "#066c48",
|
|
45453
|
+
control: "#f2479f",
|
|
45454
|
+
face: "#139d8a",
|
|
45455
|
+
plate: "#909024",
|
|
45456
|
+
car: "#8e35ab",
|
|
45457
|
+
truck: "#bd0b2b",
|
|
45458
|
+
bus: "#7a88ca",
|
|
45459
|
+
motorcycle: "#e26725",
|
|
45460
|
+
bicycle: "#a6679b",
|
|
45461
|
+
airplane: "#7c5720",
|
|
45462
|
+
boat: "#467a1b",
|
|
45463
|
+
train: "#6f65a4",
|
|
45464
|
+
bird: "#cb717f",
|
|
45465
|
+
dog: "#c62490",
|
|
45466
|
+
cat: "#b36850",
|
|
45467
|
+
horse: "#1872ac",
|
|
45468
|
+
sheep: "#927939",
|
|
45469
|
+
cow: "#428a5c",
|
|
45470
|
+
elephant: "#d41160",
|
|
45471
|
+
bear: "#799453",
|
|
45472
|
+
zebra: "#a85455",
|
|
45473
|
+
giraffe: "#746be8",
|
|
45474
|
+
"package-delivered": "#824a80",
|
|
45475
|
+
"package-picked-up": "#614ac1",
|
|
45476
|
+
suitcase: "#2f77f3",
|
|
45477
|
+
backpack: "#fa476d",
|
|
45478
|
+
handbag: "#c14cbe",
|
|
45479
|
+
contact: "#c83921",
|
|
45480
|
+
"motion-sensor": "#a07ebd",
|
|
45481
|
+
smoke: "#a25b13",
|
|
45482
|
+
flood: "#526bab",
|
|
45483
|
+
gas: "#924938",
|
|
45484
|
+
"carbon-monoxide": "#bb7e53",
|
|
45485
|
+
vibration: "#b66182",
|
|
45486
|
+
tamper: "#3c6931",
|
|
45487
|
+
presence: "#6c851d",
|
|
45488
|
+
"enum-sensor": "#ad2d48",
|
|
45489
|
+
"device-event": "#5e9b04",
|
|
45490
|
+
lock: "#00a062",
|
|
45491
|
+
cover: "#ad8624",
|
|
45492
|
+
switch: "#d05259",
|
|
45493
|
+
siren: "#cd67b3",
|
|
45494
|
+
button: "#c9746a",
|
|
45495
|
+
doorbell: "#338eeb"
|
|
45496
|
+
};
|
|
45497
|
+
var HIGH_CONTRAST_FALLBACK = [
|
|
45498
|
+
"#817f3b",
|
|
45499
|
+
"#a0733e",
|
|
45500
|
+
"#8658b2",
|
|
45501
|
+
"#956301",
|
|
45502
|
+
"#bc652d",
|
|
45503
|
+
"#647331",
|
|
45504
|
+
"#a14c9e",
|
|
45505
|
+
"#d14e71"
|
|
45506
|
+
];
|
|
45507
|
+
var OKABE_ITO_HEX = {
|
|
45508
|
+
motion: "#b88128",
|
|
45509
|
+
audio: "#1096c8",
|
|
45510
|
+
recording: "#009e73",
|
|
45511
|
+
live: "#9c8c22",
|
|
45512
|
+
heatmapScrub: "#0072b2",
|
|
45513
|
+
person: "#d55e00",
|
|
45514
|
+
vehicle: "#c0739f",
|
|
45515
|
+
animal: "#226d18",
|
|
45516
|
+
package: "#91446c",
|
|
45517
|
+
sensor: "#217b56",
|
|
45518
|
+
control: "#648647",
|
|
45519
|
+
face: "#c22998",
|
|
45520
|
+
plate: "#fa4575",
|
|
45521
|
+
car: "#956301",
|
|
45522
|
+
truck: "#2f77f3",
|
|
45523
|
+
bus: "#7a4e86",
|
|
45524
|
+
motorcycle: "#f54597",
|
|
45525
|
+
bicycle: "#bb3e75",
|
|
45526
|
+
airplane: "#e054c0",
|
|
45527
|
+
boat: "#457942",
|
|
45528
|
+
train: "#867afa",
|
|
45529
|
+
bird: "#88914c",
|
|
45530
|
+
dog: "#1556cd",
|
|
45531
|
+
cat: "#71702c",
|
|
45532
|
+
horse: "#9b4fa4",
|
|
45533
|
+
sheep: "#c0559d",
|
|
45534
|
+
cow: "#d14f65",
|
|
45535
|
+
elephant: "#98470f",
|
|
45536
|
+
bear: "#595896",
|
|
45537
|
+
zebra: "#96790e",
|
|
45538
|
+
giraffe: "#cb717b",
|
|
45539
|
+
"package-delivered": "#139d8a",
|
|
45540
|
+
"package-picked-up": "#906ead",
|
|
45541
|
+
suitcase: "#d02939",
|
|
45542
|
+
backpack: "#d41160",
|
|
45543
|
+
handbag: "#f64f54",
|
|
45544
|
+
contact: "#7258d2",
|
|
45545
|
+
"motion-sensor": "#b66182",
|
|
45546
|
+
smoke: "#627abb",
|
|
45547
|
+
flood: "#b86ae4",
|
|
45548
|
+
gas: "#a95261",
|
|
45549
|
+
"carbon-monoxide": "#c65d3c",
|
|
45550
|
+
vibration: "#7a40b7",
|
|
45551
|
+
tamper: "#914b34",
|
|
45552
|
+
presence: "#9481c3",
|
|
45553
|
+
"enum-sensor": "#ac6d47",
|
|
45554
|
+
"device-event": "#7b6fce",
|
|
45555
|
+
lock: "#c67662",
|
|
45556
|
+
cover: "#a6564d",
|
|
45557
|
+
switch: "#ad2c4e",
|
|
45558
|
+
siren: "#348e08",
|
|
45559
|
+
button: "#d27303",
|
|
45560
|
+
doorbell: "#55770f"
|
|
45561
|
+
};
|
|
45562
|
+
var OKABE_ITO_FALLBACK = [
|
|
45563
|
+
"#9a3784",
|
|
45564
|
+
"#a7392c",
|
|
45565
|
+
"#409d50",
|
|
45566
|
+
"#6987e7",
|
|
45567
|
+
"#ee5b3d",
|
|
45568
|
+
"#c0430d",
|
|
45569
|
+
"#af79b3",
|
|
45570
|
+
"#4b6628"
|
|
45571
|
+
];
|
|
45572
|
+
/**
|
|
45573
|
+
* The display palette (D939). One table of colours, three presets, one
|
|
45574
|
+
* validator. Taxonomy colours and every consumer read this — there is no
|
|
45575
|
+
* second hex table.
|
|
45576
|
+
*/
|
|
45577
|
+
var paletteHexSchema = string().regex(/^#[0-9a-f]{6}$/);
|
|
45578
|
+
var paletteSwatchSchema = discriminatedUnion("form", [object({
|
|
45579
|
+
form: literal("solid"),
|
|
45580
|
+
hex: paletteHexSchema
|
|
45581
|
+
}), object({
|
|
45582
|
+
form: literal("gradient"),
|
|
45583
|
+
hex: paletteHexSchema,
|
|
45584
|
+
alphas: array(number().gt(0).lte(1)).length(AUDIO_GRADIENT_ALPHAS.length)
|
|
45585
|
+
})]);
|
|
45586
|
+
var paletteReadySchema = object({
|
|
45587
|
+
status: literal("ready"),
|
|
45588
|
+
presetId: _enum(PALETTE_PRESET_IDS),
|
|
45589
|
+
customized: boolean(),
|
|
45590
|
+
source: _enum(["stored", "unconfigured"]),
|
|
45591
|
+
swatches: record(string(), paletteSwatchSchema),
|
|
45592
|
+
fallbacks: array(paletteHexSchema).length(8)
|
|
45593
|
+
});
|
|
45594
|
+
var paletteResultSchema = discriminatedUnion("status", [paletteReadySchema, object({
|
|
45595
|
+
status: literal("unknown"),
|
|
45596
|
+
reason: string()
|
|
45597
|
+
})]);
|
|
45598
|
+
var setPaletteInputSchema = union([object({ presetId: string() }), object({
|
|
45599
|
+
presetId: string(),
|
|
45600
|
+
overrides: record(string(), paletteSwatchSchema)
|
|
45601
|
+
})]);
|
|
45602
|
+
var storedPaletteSchema = object({
|
|
45603
|
+
presetId: string(),
|
|
45604
|
+
overrides: record(string(), paletteSwatchSchema)
|
|
45605
|
+
});
|
|
45606
|
+
function solid(hex) {
|
|
45607
|
+
return {
|
|
45608
|
+
form: "solid",
|
|
45609
|
+
hex
|
|
45610
|
+
};
|
|
45611
|
+
}
|
|
45612
|
+
function audioGradient(hex) {
|
|
45613
|
+
return {
|
|
45614
|
+
form: "gradient",
|
|
45615
|
+
hex,
|
|
45616
|
+
alphas: [...AUDIO_GRADIENT_ALPHAS]
|
|
45617
|
+
};
|
|
45618
|
+
}
|
|
45619
|
+
function swatchesFrom(hexes) {
|
|
45620
|
+
const out = {};
|
|
45621
|
+
for (const id of PALETTE_ENTRY_IDS) {
|
|
45622
|
+
const hex = hexes[id];
|
|
45623
|
+
if (hex === void 0) throw new Error(`palette table missing ${id}`);
|
|
45624
|
+
out[id] = id === "audio" ? audioGradient(hex) : solid(hex);
|
|
45625
|
+
}
|
|
45626
|
+
return out;
|
|
45627
|
+
}
|
|
45628
|
+
function preset(id, name, hexes, fallbacks) {
|
|
45629
|
+
return {
|
|
45630
|
+
id,
|
|
45631
|
+
name,
|
|
45632
|
+
swatches: swatchesFrom(hexes),
|
|
45633
|
+
fallbacks
|
|
45634
|
+
};
|
|
45635
|
+
}
|
|
45636
|
+
var DISPLAY_PRESETS = [
|
|
45637
|
+
preset("camstack", "CamStack", CAMSTACK_HEX, CAMSTACK_FALLBACK),
|
|
45638
|
+
preset("high-contrast", "High contrast", HIGH_CONTRAST_HEX, HIGH_CONTRAST_FALLBACK),
|
|
45639
|
+
preset("okabe-ito", "Colour-blind safe", OKABE_ITO_HEX, OKABE_ITO_FALLBACK)
|
|
45640
|
+
];
|
|
45641
|
+
function presetById(id) {
|
|
45642
|
+
return DISPLAY_PRESETS.find((item) => item.id === id);
|
|
45643
|
+
}
|
|
45644
|
+
function bundledCamstack() {
|
|
45645
|
+
const presetRow = presetById("camstack");
|
|
45646
|
+
if (presetRow === void 0) throw new Error("CamStack preset missing");
|
|
45647
|
+
return readyOf(presetRow, "unconfigured", false);
|
|
45648
|
+
}
|
|
45649
|
+
function readyOf(row, source, customized) {
|
|
45650
|
+
return {
|
|
45651
|
+
status: "ready",
|
|
45652
|
+
presetId: row.id,
|
|
45653
|
+
customized,
|
|
45654
|
+
source,
|
|
45655
|
+
swatches: row.swatches,
|
|
45656
|
+
fallbacks: [...row.fallbacks]
|
|
45657
|
+
};
|
|
45658
|
+
}
|
|
45659
|
+
function namedColours(swatches, fallbacks) {
|
|
45660
|
+
const rows = [];
|
|
45661
|
+
for (const id of PALETTE_ENTRY_IDS) {
|
|
45662
|
+
const swatch = swatches[id];
|
|
45663
|
+
if (swatch !== void 0) rows.push({
|
|
45664
|
+
name: id,
|
|
45665
|
+
hex: swatch.hex
|
|
45666
|
+
});
|
|
45667
|
+
}
|
|
45668
|
+
fallbacks.forEach((hex, index) => {
|
|
45669
|
+
rows.push({
|
|
45670
|
+
name: `fallback-${index}`,
|
|
45671
|
+
hex
|
|
45672
|
+
});
|
|
45673
|
+
});
|
|
45674
|
+
return rows;
|
|
45675
|
+
}
|
|
45676
|
+
function gradientViolations(swatches) {
|
|
45677
|
+
const audio = swatches[AUDIO_ENTRY_ID];
|
|
45678
|
+
if (audio === void 0) return [];
|
|
45679
|
+
if (audio.form !== "gradient") return [{
|
|
45680
|
+
code: "bad-gradient",
|
|
45681
|
+
entry: AUDIO_ENTRY_ID
|
|
45682
|
+
}];
|
|
45683
|
+
return AUDIO_GRADIENT_ALPHAS.every((alpha, index) => audio.alphas[index] === alpha) ? [] : [{
|
|
45684
|
+
code: "bad-gradient",
|
|
45685
|
+
entry: AUDIO_ENTRY_ID
|
|
45686
|
+
}];
|
|
45687
|
+
}
|
|
45688
|
+
function isMarkPair(left, right) {
|
|
45689
|
+
const marks = PALETTE_MARK_PAIR;
|
|
45690
|
+
return marks.includes(left) && marks.includes(right);
|
|
45691
|
+
}
|
|
45692
|
+
/** Refuse a palette whose entries are not pairwise distinct on both themes. */
|
|
45693
|
+
function validatePalette(swatches, fallbacks) {
|
|
45694
|
+
const violations = [];
|
|
45695
|
+
for (const id of PALETTE_ENTRY_IDS) if (swatches[id] === void 0) violations.push({
|
|
45696
|
+
code: "missing-entry",
|
|
45697
|
+
entry: id
|
|
45698
|
+
});
|
|
45699
|
+
for (const key of Object.keys(swatches)) if (!isPaletteEntryId(key)) violations.push({
|
|
45700
|
+
code: "unknown-entry",
|
|
45701
|
+
entry: key
|
|
45702
|
+
});
|
|
45703
|
+
if (fallbacks.length !== 8) violations.push({ code: "bad-fallbacks" });
|
|
45704
|
+
violations.push(...gradientViolations(swatches));
|
|
45705
|
+
const rows = namedColours(swatches, fallbacks);
|
|
45706
|
+
for (let i = 0; i < rows.length; i++) for (let j = i + 1; j < rows.length; j++) {
|
|
45707
|
+
const left = rows[i];
|
|
45708
|
+
const right = rows[j];
|
|
45709
|
+
if (left === void 0 || right === void 0) continue;
|
|
45710
|
+
const deltaE = deltaE00(left.hex, right.hex);
|
|
45711
|
+
if (deltaE < (isMarkPair(left.name, right.name) ? 20 : 7)) violations.push({
|
|
45712
|
+
code: "too-close",
|
|
45713
|
+
left: left.name,
|
|
45714
|
+
right: right.name,
|
|
45715
|
+
deltaE
|
|
45716
|
+
});
|
|
45717
|
+
}
|
|
45718
|
+
for (const row of rows) for (const background of ["dark", "light"]) {
|
|
45719
|
+
const contrast = contrastRatio(row.hex, PALETTE_BACKGROUNDS[background]);
|
|
45720
|
+
if (contrast < 3) violations.push({
|
|
45721
|
+
code: "low-contrast",
|
|
45722
|
+
entry: row.name,
|
|
45723
|
+
background,
|
|
45724
|
+
contrast
|
|
45725
|
+
});
|
|
45726
|
+
}
|
|
45727
|
+
return violations.length === 0 ? { ok: true } : {
|
|
45728
|
+
ok: false,
|
|
45729
|
+
violations
|
|
45730
|
+
};
|
|
45731
|
+
}
|
|
45732
|
+
function formatPaletteViolation(violation) {
|
|
45733
|
+
switch (violation.code) {
|
|
45734
|
+
case "too-close": return `${violation.left} vs ${violation.right} (ΔE ${violation.deltaE.toFixed(1)})`;
|
|
45735
|
+
case "low-contrast": return `${violation.entry} on ${violation.background} (${violation.contrast.toFixed(1)}:1)`;
|
|
45736
|
+
case "missing-entry": return `${violation.entry} is missing`;
|
|
45737
|
+
case "unknown-entry": return `${violation.entry} is not a palette entry`;
|
|
45738
|
+
case "bad-gradient": return `${violation.entry} gradient is not the six canonical steps`;
|
|
45739
|
+
case "bad-fallbacks": return "fallback list must hold eight colours";
|
|
45740
|
+
case "unknown-preset": return `${violation.presetId} is not a preset`;
|
|
45741
|
+
}
|
|
45742
|
+
}
|
|
45743
|
+
function formatPaletteViolations(violations) {
|
|
45744
|
+
return violations.map(formatPaletteViolation).join("; ");
|
|
45745
|
+
}
|
|
45746
|
+
var PaletteRejectedError = class extends Error {
|
|
45747
|
+
violations;
|
|
45748
|
+
constructor(violations) {
|
|
45749
|
+
super(formatPaletteViolations(violations));
|
|
45750
|
+
this.name = "PaletteRejectedError";
|
|
45751
|
+
this.violations = violations;
|
|
45752
|
+
}
|
|
45753
|
+
};
|
|
45754
|
+
function hashFallback(kind, fallbacks) {
|
|
45755
|
+
let hash = 0;
|
|
45756
|
+
for (let i = 0; i < kind.length; i++) hash = hash * 31 + (kind.codePointAt(i) ?? 0) >>> 0;
|
|
45757
|
+
const hex = fallbacks[hash % fallbacks.length];
|
|
45758
|
+
if (hex === void 0) throw new Error("display palette has no fallback colour");
|
|
45759
|
+
return hex;
|
|
45760
|
+
}
|
|
45761
|
+
/** Colour a kind paints with. Audio leaves share the audio gradient's hex. */
|
|
45762
|
+
function paintHex(swatches, fallbacks, kind) {
|
|
45763
|
+
const key = kind.trim().toLowerCase();
|
|
45764
|
+
if (key.startsWith("audio-")) {
|
|
45765
|
+
const audio = swatches[AUDIO_ENTRY_ID];
|
|
45766
|
+
return audio !== void 0 ? audio.hex : hashFallback(key, fallbacks);
|
|
45767
|
+
}
|
|
45768
|
+
const direct = swatches[key];
|
|
45769
|
+
if (direct !== void 0) return direct.hex;
|
|
45770
|
+
return hashFallback(key, fallbacks);
|
|
45771
|
+
}
|
|
45772
|
+
function mergeOverrides(base, overrides) {
|
|
45773
|
+
return {
|
|
45774
|
+
...base,
|
|
45775
|
+
...overrides
|
|
45776
|
+
};
|
|
45777
|
+
}
|
|
45778
|
+
function overridesOf(input) {
|
|
45779
|
+
return "overrides" in input ? input.overrides : {};
|
|
45780
|
+
}
|
|
45781
|
+
/** The palette a `setPalette` input would store. Invalid input is a refusal. */
|
|
45782
|
+
function paletteFromInput(input) {
|
|
45783
|
+
const row = presetById(input.presetId);
|
|
45784
|
+
if (row === void 0 || !isPalettePresetId(input.presetId)) throw new PaletteRejectedError([{
|
|
45785
|
+
code: "unknown-preset",
|
|
45786
|
+
presetId: input.presetId
|
|
45787
|
+
}]);
|
|
45788
|
+
const overrides = overridesOf(input);
|
|
45789
|
+
const swatches = mergeOverrides(row.swatches, overrides);
|
|
45790
|
+
const verdict = validatePalette(swatches, row.fallbacks);
|
|
45791
|
+
if (!verdict.ok) throw new PaletteRejectedError(verdict.violations);
|
|
45792
|
+
const customized = Object.keys(overrides).length > 0;
|
|
45793
|
+
return {
|
|
45794
|
+
status: "ready",
|
|
45795
|
+
presetId: row.id,
|
|
45796
|
+
customized,
|
|
45797
|
+
source: "stored",
|
|
45798
|
+
swatches,
|
|
45799
|
+
fallbacks: [...row.fallbacks]
|
|
45800
|
+
};
|
|
45801
|
+
}
|
|
45802
|
+
function isEmptyRecord(value) {
|
|
45803
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length === 0;
|
|
45804
|
+
}
|
|
45805
|
+
/**
|
|
45806
|
+
* Interpret a settings blob. A missing row is the bundled preset and says so.
|
|
45807
|
+
* A blob that does not parse, names an unknown preset, or fails the rule is
|
|
45808
|
+
* `unknown` — never the default wearing the stored preset's name.
|
|
45809
|
+
*/
|
|
45810
|
+
function paletteFromStored(value) {
|
|
45811
|
+
if (value === void 0 || value === null || isEmptyRecord(value)) return bundledCamstack();
|
|
45812
|
+
const parsed = storedPaletteSchema.safeParse(value);
|
|
45813
|
+
if (!parsed.success) return {
|
|
45814
|
+
status: "unknown",
|
|
45815
|
+
reason: "stored palette is unreadable"
|
|
45816
|
+
};
|
|
45817
|
+
const row = presetById(parsed.data.presetId);
|
|
45818
|
+
if (row === void 0) return {
|
|
45819
|
+
status: "unknown",
|
|
45820
|
+
reason: `unknown preset ${parsed.data.presetId}`
|
|
45821
|
+
};
|
|
45822
|
+
const swatches = mergeOverrides(row.swatches, parsed.data.overrides);
|
|
45823
|
+
const verdict = validatePalette(swatches, row.fallbacks);
|
|
45824
|
+
if (!verdict.ok) return {
|
|
45825
|
+
status: "unknown",
|
|
45826
|
+
reason: formatPaletteViolations(verdict.violations)
|
|
45827
|
+
};
|
|
45828
|
+
const customized = Object.keys(parsed.data.overrides).length > 0;
|
|
45829
|
+
return {
|
|
45830
|
+
status: "ready",
|
|
45831
|
+
presetId: row.id,
|
|
45832
|
+
customized,
|
|
45833
|
+
source: "stored",
|
|
45834
|
+
swatches,
|
|
45835
|
+
fallbacks: [...row.fallbacks]
|
|
45836
|
+
};
|
|
45837
|
+
}
|
|
45838
|
+
function storedFromReady(ready, overrides) {
|
|
45839
|
+
return {
|
|
45840
|
+
presetId: ready.presetId,
|
|
45841
|
+
overrides: { ...overrides }
|
|
45842
|
+
};
|
|
45843
|
+
}
|
|
45844
|
+
/**
|
|
43226
45845
|
* Unified event-kind taxonomy — THE single source of truth for
|
|
43227
45846
|
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
43228
45847
|
* icon }`.
|
|
@@ -43236,109 +45855,88 @@ for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set
|
|
|
43236
45855
|
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
43237
45856
|
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
43238
45857
|
*
|
|
43239
|
-
* The DATA (serializable —
|
|
43240
|
-
* `@camstack/types`.
|
|
43241
|
-
*
|
|
43242
|
-
*
|
|
43243
|
-
*
|
|
45858
|
+
* The DATA (serializable — parentKind / iconId / labelKey) lives here in
|
|
45859
|
+
* `@camstack/types`. Colour is NOT a second table: each entry's `color` is
|
|
45860
|
+
* the bundled CamStack display palette (D939). The effective cluster palette
|
|
45861
|
+
* is the `display-palette` capability. The UI-side mapping `iconId → lucide
|
|
45862
|
+
* component` and `labelKey → t()` lives in `@camstack/ui-library`.
|
|
43244
45863
|
*
|
|
43245
45864
|
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
43246
45865
|
*/
|
|
43247
|
-
var
|
|
43248
|
-
|
|
43249
|
-
|
|
43250
|
-
|
|
43251
|
-
|
|
43252
|
-
|
|
43253
|
-
|
|
43254
|
-
|
|
43255
|
-
|
|
43256
|
-
|
|
43257
|
-
};
|
|
43258
|
-
var DETECTION_SUB_COLORS = {
|
|
43259
|
-
car: "#f59e0b",
|
|
43260
|
-
truck: "#d97706",
|
|
43261
|
-
bus: "#b45309",
|
|
43262
|
-
motorcycle: "#eab308",
|
|
43263
|
-
bicycle: "#ca8a04",
|
|
43264
|
-
airplane: "#60a5fa",
|
|
43265
|
-
boat: "#2563eb",
|
|
43266
|
-
train: "#1d4ed8",
|
|
43267
|
-
bird: "#14b8a6",
|
|
43268
|
-
dog: "#84cc16",
|
|
43269
|
-
cat: "#f97316",
|
|
43270
|
-
horse: "#a16207",
|
|
43271
|
-
sheep: "#a3a3a3",
|
|
43272
|
-
cow: "#78716c",
|
|
43273
|
-
elephant: "#6b7280",
|
|
43274
|
-
bear: "#7c2d12",
|
|
43275
|
-
zebra: "#404040",
|
|
43276
|
-
giraffe: "#d4a373"
|
|
43277
|
-
};
|
|
45866
|
+
var BUNDLED_PALETTE = bundledCamstack();
|
|
45867
|
+
function kindColor(kind) {
|
|
45868
|
+
return paintHex(BUNDLED_PALETTE.swatches, BUNDLED_PALETTE.fallbacks, kind);
|
|
45869
|
+
}
|
|
45870
|
+
function firstFallback(fallbacks) {
|
|
45871
|
+
const hex = fallbacks[0];
|
|
45872
|
+
if (hex === void 0) throw new Error("display palette has no fallback colour");
|
|
45873
|
+
return hex;
|
|
45874
|
+
}
|
|
45875
|
+
firstFallback(BUNDLED_PALETTE.fallbacks);
|
|
43278
45876
|
function titleCase(id) {
|
|
43279
45877
|
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
43280
45878
|
}
|
|
43281
45879
|
var entries = /* @__PURE__ */ new Map();
|
|
43282
|
-
function macro(kind, category,
|
|
45880
|
+
function macro(kind, category, iconId, label) {
|
|
43283
45881
|
entries.set(kind, {
|
|
43284
45882
|
kind,
|
|
43285
45883
|
parentKind: null,
|
|
43286
45884
|
level: "macro",
|
|
43287
45885
|
category,
|
|
43288
|
-
color,
|
|
45886
|
+
color: kindColor(kind),
|
|
43289
45887
|
iconId,
|
|
43290
45888
|
labelKey: `eventKind.${kind}`,
|
|
43291
45889
|
label
|
|
43292
45890
|
});
|
|
43293
45891
|
}
|
|
43294
|
-
function sub(kind, parentKind, category,
|
|
45892
|
+
function sub(kind, parentKind, category, iconId, label) {
|
|
43295
45893
|
entries.set(kind, {
|
|
43296
45894
|
kind,
|
|
43297
45895
|
parentKind,
|
|
43298
45896
|
level: "sub",
|
|
43299
45897
|
category,
|
|
43300
|
-
color,
|
|
45898
|
+
color: kindColor(kind),
|
|
43301
45899
|
iconId,
|
|
43302
45900
|
labelKey: `eventKind.${kind}`,
|
|
43303
45901
|
label
|
|
43304
45902
|
});
|
|
43305
45903
|
}
|
|
43306
|
-
macro("motion", "motion",
|
|
43307
|
-
macro("audio", "audio",
|
|
43308
|
-
macro("person", "detection",
|
|
43309
|
-
macro("vehicle", "detection",
|
|
43310
|
-
macro("animal", "detection",
|
|
43311
|
-
macro("package", "package",
|
|
43312
|
-
macro("sensor", "sensor",
|
|
43313
|
-
macro("control", "control",
|
|
45904
|
+
macro("motion", "motion", "motion", "Motion");
|
|
45905
|
+
macro("audio", "audio", "audio", "Audio");
|
|
45906
|
+
macro("person", "detection", "person", "Person");
|
|
45907
|
+
macro("vehicle", "detection", "vehicle", "Vehicle");
|
|
45908
|
+
macro("animal", "detection", "animal", "Animal");
|
|
45909
|
+
macro("package", "package", "package", "Package");
|
|
45910
|
+
macro("sensor", "sensor", "sensor", "Sensor");
|
|
45911
|
+
macro("control", "control", "control", "Control");
|
|
43314
45912
|
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
43315
45913
|
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
43316
45914
|
if (entries.has(cocoClass)) continue;
|
|
43317
|
-
sub(cocoClass, macroClass, "detection",
|
|
43318
|
-
}
|
|
43319
|
-
sub("package-delivered", "package", "package",
|
|
43320
|
-
sub("package-picked-up", "package", "package",
|
|
43321
|
-
sub("contact", "sensor", "sensor", "
|
|
43322
|
-
sub("motion-sensor", "sensor", "sensor",
|
|
43323
|
-
sub("smoke", "sensor", "sensor", "
|
|
43324
|
-
sub("flood", "sensor", "sensor", "
|
|
43325
|
-
sub("gas", "sensor", "sensor", "
|
|
43326
|
-
sub("carbon-monoxide", "sensor", "sensor", "
|
|
43327
|
-
sub("vibration", "sensor", "sensor", "
|
|
43328
|
-
sub("tamper", "sensor", "sensor", "
|
|
43329
|
-
sub("presence", "sensor", "sensor", "
|
|
43330
|
-
sub("enum-sensor", "sensor", "sensor",
|
|
43331
|
-
sub("device-event", "sensor", "sensor", "
|
|
43332
|
-
sub("lock", "control", "control", "
|
|
43333
|
-
sub("cover", "control", "control", "
|
|
43334
|
-
sub("switch", "control", "control",
|
|
43335
|
-
sub("siren", "control", "control", "
|
|
43336
|
-
sub("button", "control", "control", "
|
|
43337
|
-
sub("doorbell", "control", "control", "
|
|
45915
|
+
sub(cocoClass, macroClass, "detection", cocoClass, titleCase(cocoClass));
|
|
45916
|
+
}
|
|
45917
|
+
sub("package-delivered", "package", "package", "package", "Package delivered");
|
|
45918
|
+
sub("package-picked-up", "package", "package", "package", "Package picked up");
|
|
45919
|
+
sub("contact", "sensor", "sensor", "door", "Contact");
|
|
45920
|
+
sub("motion-sensor", "sensor", "sensor", "pir", "Motion sensor");
|
|
45921
|
+
sub("smoke", "sensor", "sensor", "smoke", "Smoke");
|
|
45922
|
+
sub("flood", "sensor", "sensor", "water", "Water leak");
|
|
45923
|
+
sub("gas", "sensor", "sensor", "gas", "Gas");
|
|
45924
|
+
sub("carbon-monoxide", "sensor", "sensor", "smoke", "Carbon monoxide");
|
|
45925
|
+
sub("vibration", "sensor", "sensor", "vibration", "Vibration");
|
|
45926
|
+
sub("tamper", "sensor", "sensor", "tamper", "Tamper");
|
|
45927
|
+
sub("presence", "sensor", "sensor", "presence", "Presence");
|
|
45928
|
+
sub("enum-sensor", "sensor", "sensor", "generic", "Sensor state");
|
|
45929
|
+
sub("device-event", "sensor", "sensor", "button", "Device event");
|
|
45930
|
+
sub("lock", "control", "control", "lock", "Lock");
|
|
45931
|
+
sub("cover", "control", "control", "door", "Cover");
|
|
45932
|
+
sub("switch", "control", "control", "switch", "Switch");
|
|
45933
|
+
sub("siren", "control", "control", "siren", "Siren");
|
|
45934
|
+
sub("button", "control", "control", "button", "Button");
|
|
45935
|
+
sub("doorbell", "control", "control", "doorbell", "Doorbell");
|
|
43338
45936
|
for (const l of AUDIO_MACRO_LABELS) {
|
|
43339
45937
|
const kind = `audio-${l.id}`;
|
|
43340
45938
|
if (entries.has(kind)) continue;
|
|
43341
|
-
sub(kind, "audio", "audio",
|
|
45939
|
+
sub(kind, "audio", "audio", kind, l.name);
|
|
43342
45940
|
}
|
|
43343
45941
|
/** The complete taxonomy dictionary, keyed by kind. */
|
|
43344
45942
|
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
@@ -44181,7 +46779,7 @@ var NcConditionsSchema = object({
|
|
|
44181
46779
|
* with the list under it is worse than no switch (D62).
|
|
44182
46780
|
*
|
|
44183
46781
|
* MEMBERS ARE FACE-GALLERY `Identity.id`s (uuid), not display names. A name is
|
|
44184
|
-
* renameable, and a rule authored on "
|
|
46782
|
+
* renameable, and a rule authored on "Alice" went silently dark the moment
|
|
44185
46783
|
* the operator fixed the spelling. The id reaches the record on
|
|
44186
46784
|
* `LabelAttribution.identityId`; the name is what the editor shows and what
|
|
44187
46785
|
* `{{label}}` renders.
|
|
@@ -44732,7 +47330,7 @@ var NcRulePatchSchema = NcRuleInputSchema.partial().extend({
|
|
|
44732
47330
|
* A rule scoped to one camera and one zone silently became a rule that
|
|
44733
47331
|
* matches EVERY event on EVERY camera, and lost its `media` policy
|
|
44734
47332
|
* (zoneCrop / gif / clip / frame) and its `priority` at the same time. Seen
|
|
44735
|
-
* live on 2026-08-12: a rule scoped to device
|
|
47333
|
+
* live on 2026-08-12: a rule scoped to device 102 fired on 104 and 101
|
|
44736
47334
|
* within a minute of a two-field patch.
|
|
44737
47335
|
*
|
|
44738
47336
|
* So every defaulted field is re-declared here WITHOUT its default. The
|
|
@@ -46595,7 +49193,7 @@ var LabelAttributionSchema = object({
|
|
|
46595
49193
|
* `Identity.id` or a plate-gallery `Vehicle.id` (both `randomUUID`).
|
|
46596
49194
|
*
|
|
46597
49195
|
* The text alone is a DISPLAY NAME, and a display name is renameable: a
|
|
46598
|
-
* notification rule authored on "
|
|
49196
|
+
* notification rule authored on "Alice" stopped matching the moment the
|
|
46599
49197
|
* operator fixed the spelling in the gallery, and nothing said so. The id is
|
|
46600
49198
|
* the thing that does not move, so it is what a rule matches on
|
|
46601
49199
|
* (`NcConditions.identities`) and the text is what a human is shown.
|
|
@@ -49247,7 +51845,7 @@ var pipelineExecutorCapability = {
|
|
|
49247
51845
|
/**
|
|
49248
51846
|
* Root-supplied detections for the tree's ROOT step (D730). Set by
|
|
49249
51847
|
* `runDetailSubtree` when the camera's root model supplies a crop-kind
|
|
49250
|
-
* step (a
|
|
51848
|
+
* step (a plus catalog `license_plate` for `plate-detection`): the step is
|
|
49251
51849
|
* NOT inferred, these boxes are its output, and its children (the plate
|
|
49252
51850
|
* reader) run on them through their own crop policy. Boxes are in the
|
|
49253
51851
|
* PIXELS of the image this call carries. Absent ⇒ the root step runs.
|
|
@@ -51015,7 +53613,7 @@ var RunnerCameraConfigSchema = object({
|
|
|
51015
53613
|
* detection session that asks for history. What shipped was a last-moment
|
|
51016
53614
|
* discard — `FrameSlot`'s throttle compares wall clocks, and ~4 s of media
|
|
51017
53615
|
* arriving inside a few hundred ms of wall clock looks to it like one frame's
|
|
51018
|
-
* worth. Device
|
|
53616
|
+
* worth. Device 102, 2026-09-08: a re-run of the SAME model over the stored
|
|
51019
53617
|
* recording scored the subject `vehicle 0.5669` — above the 0.50 floor —
|
|
51020
53618
|
* 1.68 s BEFORE the live track was born, on a frame that was in the pre-roll,
|
|
51021
53619
|
* was decoded, and was freed.
|
|
@@ -53670,7 +56268,7 @@ method(_void(), ProviderInfoSchema, { auth: "admin" }), method(object({ config:
|
|
|
53670
56268
|
* The signals a device can emit to WAKE its own stream.
|
|
53671
56269
|
*
|
|
53672
56270
|
* A camera whose stream is built on demand sleeps until something asks for it,
|
|
53673
|
-
* and "something" cannot be a consumer that is merely attached — a
|
|
56271
|
+
* and "something" cannot be a consumer that is merely attached — a external-catalog
|
|
53674
56272
|
* puller holds a session open for ever, and treating that as demand would keep
|
|
53675
56273
|
* a battery camera awake for ever, which is the whole thing the battery is for
|
|
53676
56274
|
* (D173). So the wake has to come from the CAMERA: an event it noticed by
|
|
@@ -54357,7 +56955,7 @@ var ClipSchema = object({
|
|
|
54357
56955
|
* {@link MAX_CLIP_EVENT_IDS}. Empty on footage-only clips.
|
|
54358
56956
|
*
|
|
54359
56957
|
* Bounded because it is not a payload the surface pages through: one visit on
|
|
54360
|
-
* device
|
|
56958
|
+
* device 101 carried 2 345 ids, and `eventIds` was 99% of a 153 KB
|
|
54361
56959
|
* camera-day. Read {@link eventCount} for the true total.
|
|
54362
56960
|
*/
|
|
54363
56961
|
eventIds: array(string()).optional(),
|
|
@@ -54502,7 +57100,7 @@ var ClipPlaybackSchema = object({
|
|
|
54502
57100
|
* camera has no recordings", which is the defect this whole line of work is
|
|
54503
57101
|
* about: a battery camera nobody woke (`sleeping`), a camera that could not be
|
|
54504
57102
|
* reached at all (`unreachable`, also what a provider that THREW reports), a
|
|
54505
|
-
* camera whose SD card is not mounted (`no-storage`, measured on
|
|
57103
|
+
* camera whose SD card is not mounted (`no-storage`, measured on 106 —
|
|
54506
57104
|
* `HddInfo mount 0`, honestly nothing to list rather than "no clips"), and a
|
|
54507
57105
|
* camera whose OWN index disagrees with its OWN calendar (`index-empty`,
|
|
54508
57106
|
* measured on 618: the calendar marks 3–20 September, days 6–20 list zero
|
|
@@ -54767,7 +57365,7 @@ DeviceType.Camera, method(object({
|
|
|
54767
57365
|
*
|
|
54768
57366
|
* It was optional, documented as "absent means the device's BOUND
|
|
54769
57367
|
* provider, which is CamStack on every camera". No code implemented
|
|
54770
|
-
* that. Measured on the live hub 2026-09-20 — device
|
|
57368
|
+
* that. Measured on the live hub 2026-09-20 — device 107, bound to
|
|
54771
57369
|
* `recorder` AND `provider-reolink` — a bare call with `limit: 3`
|
|
54772
57370
|
* answered SIX rows, three from each source, merged newest-first:
|
|
54773
57371
|
* `device-collection-dispatch.ts` simply left the fan-out un-narrowed,
|
|
@@ -55845,7 +58443,10 @@ object({
|
|
|
55845
58443
|
DeviceType.Sensor;
|
|
55846
58444
|
object({
|
|
55847
58445
|
/** Current illuminance in lux (lx). */
|
|
55848
|
-
lux: number().min(0)
|
|
58446
|
+
lux: number().min(0).meta({
|
|
58447
|
+
unit: "lx",
|
|
58448
|
+
label: "Illuminance"
|
|
58449
|
+
}),
|
|
55849
58450
|
/** Ms epoch when the slice was last updated. */
|
|
55850
58451
|
lastFetchedAt: number(),
|
|
55851
58452
|
/** Live display unit from the upstream source (e.g. HA
|
|
@@ -56001,7 +58602,10 @@ var BatteryStatusSchema = object({
|
|
|
56001
58602
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56002
58603
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56003
58604
|
*/
|
|
56004
|
-
percentage: number().min(0).max(100).nullable()
|
|
58605
|
+
percentage: number().min(0).max(100).nullable().meta({
|
|
58606
|
+
unit: "%",
|
|
58607
|
+
label: "Charge"
|
|
58608
|
+
}),
|
|
56005
58609
|
/**
|
|
56006
58610
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56007
58611
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56020,13 +58624,13 @@ var BatteryStatusSchema = object({
|
|
|
56020
58624
|
"solar",
|
|
56021
58625
|
"none",
|
|
56022
58626
|
"unknown"
|
|
56023
|
-
]),
|
|
58627
|
+
]).meta({ label: "Charging source" }),
|
|
56024
58628
|
/**
|
|
56025
58629
|
* True when the camera firmware has gone into low-power mode. Battery
|
|
56026
58630
|
* providers MUST avoid polling during sleep — reading the battery
|
|
56027
58631
|
* wakes the camera up and drains charge.
|
|
56028
58632
|
*/
|
|
56029
|
-
sleeping: boolean(),
|
|
58633
|
+
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56030
58634
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56031
58635
|
lastUpdated: number(),
|
|
56032
58636
|
/**
|
|
@@ -56066,7 +58670,7 @@ var BatteryStatusSchema = object({
|
|
|
56066
58670
|
* sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
|
|
56067
58671
|
* misleading exact percentage. Absent/false → genuine 0–100 % reading.
|
|
56068
58672
|
*/
|
|
56069
|
-
binary: boolean().optional()
|
|
58673
|
+
binary: boolean().optional().meta({ label: "Binary indicator" })
|
|
56070
58674
|
});
|
|
56071
58675
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat;
|
|
56072
58676
|
method(object({
|
|
@@ -56081,7 +58685,7 @@ method(object({
|
|
|
56081
58685
|
status: BatteryStatusSchema
|
|
56082
58686
|
});
|
|
56083
58687
|
object({
|
|
56084
|
-
on: boolean(),
|
|
58688
|
+
on: boolean().meta({ label: "On" }),
|
|
56085
58689
|
/** Ms epoch of the last transition. 0 if never observed. */
|
|
56086
58690
|
lastChangedAt: number()
|
|
56087
58691
|
});
|
|
@@ -56339,7 +58943,7 @@ var GridLayoutCellSchema = object({
|
|
|
56339
58943
|
*
|
|
56340
58944
|
* A grid's `high` composes its sources' `high` and its `low` their `low`, so a
|
|
56341
58945
|
* profile is on offer only when EVERY source can serve it. The refusal NAMES
|
|
56342
|
-
* the sources, because "this grid has no low" is not a finding — "
|
|
58946
|
+
* the sources, because "this grid has no low" is not a finding — "101 has no
|
|
56343
58947
|
* low" is, and it is the one an operator can act on.
|
|
56344
58948
|
*/
|
|
56345
58949
|
var GridProfileOfferSchema = object({
|
|
@@ -56971,6 +59575,39 @@ DeviceType.Camera, method(object({ deviceId: number() }), DayNightOptionsSchema)
|
|
|
56971
59575
|
auth: "admin"
|
|
56972
59576
|
});
|
|
56973
59577
|
/**
|
|
59578
|
+
* display-palette — the cluster's one colour table (D939).
|
|
59579
|
+
*
|
|
59580
|
+
* Hub singleton. `getPalette` reports `unknown` when the settings store
|
|
59581
|
+
* cannot be read; it does not pretend the bundled preset was stored.
|
|
59582
|
+
* `setPalette` refuses a palette that fails the ΔE / contrast rule and names
|
|
59583
|
+
* the pairs.
|
|
59584
|
+
*/
|
|
59585
|
+
var presetSummarySchema = object({
|
|
59586
|
+
id: string(),
|
|
59587
|
+
name: string(),
|
|
59588
|
+
swatches: record(string(), paletteSwatchSchema),
|
|
59589
|
+
fallbacks: array(string())
|
|
59590
|
+
});
|
|
59591
|
+
var displayPaletteCapability = {
|
|
59592
|
+
name: "display-palette",
|
|
59593
|
+
scope: "system",
|
|
59594
|
+
mode: "singleton",
|
|
59595
|
+
methods: {
|
|
59596
|
+
getPalette: method(_void(), paletteResultSchema, {
|
|
59597
|
+
auth: "protected",
|
|
59598
|
+
role: "viewer"
|
|
59599
|
+
}),
|
|
59600
|
+
listPresets: method(_void(), array(presetSummarySchema).readonly(), {
|
|
59601
|
+
auth: "protected",
|
|
59602
|
+
role: "viewer"
|
|
59603
|
+
}),
|
|
59604
|
+
setPalette: method(setPaletteInputSchema, paletteReadySchema, {
|
|
59605
|
+
kind: "mutation",
|
|
59606
|
+
auth: "admin"
|
|
59607
|
+
})
|
|
59608
|
+
}
|
|
59609
|
+
};
|
|
59610
|
+
/**
|
|
56974
59611
|
* Generic device-level status snapshot. Auto-registered by `BaseDevice`
|
|
56975
59612
|
* for every device, regardless of provider — the kernel needs a uniform
|
|
56976
59613
|
* cap-keyed slice for the basic device flags every consumer expects to
|
|
@@ -57866,7 +60503,10 @@ DeviceType.Humidifier, method(object({
|
|
|
57866
60503
|
});
|
|
57867
60504
|
object({
|
|
57868
60505
|
/** Current relative humidity, 0..100. */
|
|
57869
|
-
percent: number().min(0).max(100)
|
|
60506
|
+
percent: number().min(0).max(100).meta({
|
|
60507
|
+
unit: "%",
|
|
60508
|
+
label: "Humidity"
|
|
60509
|
+
}),
|
|
57870
60510
|
/** Ms epoch when the slice was last updated. */
|
|
57871
60511
|
lastFetchedAt: number(),
|
|
57872
60512
|
/** Live display unit from the upstream source (e.g. HA
|
|
@@ -61384,9 +64024,15 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
61384
64024
|
});
|
|
61385
64025
|
object({
|
|
61386
64026
|
/** Instantaneous power draw in watts. */
|
|
61387
|
-
watts: number().optional()
|
|
64027
|
+
watts: number().optional().meta({
|
|
64028
|
+
unit: "W",
|
|
64029
|
+
label: "Power"
|
|
64030
|
+
}),
|
|
61388
64031
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
61389
|
-
kwhTotal: number().optional()
|
|
64032
|
+
kwhTotal: number().optional().meta({
|
|
64033
|
+
unit: "kWh",
|
|
64034
|
+
label: "Energy"
|
|
64035
|
+
}),
|
|
61390
64036
|
/** Voltage in volts. */
|
|
61391
64037
|
volts: number().optional(),
|
|
61392
64038
|
/** Current in amperes. */
|
|
@@ -61705,9 +64351,9 @@ var PtzOptionsSchema = object({
|
|
|
61705
64351
|
* Reolink preset 0, Hikvision preset '1', Dahua preset 1 -- and on this fleet
|
|
61706
64352
|
* not one of the three cameras honours its own:
|
|
61707
64353
|
*
|
|
61708
|
-
*
|
|
61709
|
-
* 1438
|
|
61710
|
-
* 3836
|
|
64354
|
+
* 107 Camera camera Carol (reolink) preset 0 holds "stanza"
|
|
64355
|
+
* 1438 Camera dispensa (hikvision) preset 1 holds "Credenza"
|
|
64356
|
+
* 3836 Camera studio (amcrest) preset 1 holds "Preset1"
|
|
61711
64357
|
*
|
|
61712
64358
|
* So `goHome` meant "go wherever the operator happened to save in slot 0 or 1",
|
|
61713
64359
|
* and two of the three swallowed the failure in a bare `catch`. For autotrack
|
|
@@ -61854,7 +64500,7 @@ object({
|
|
|
61854
64500
|
running: boolean().nullable(),
|
|
61855
64501
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
61856
64502
|
since: number().nullable(),
|
|
61857
|
-
source: RunningStateSourceSchema,
|
|
64503
|
+
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
61858
64504
|
phase: string().nullable(),
|
|
61859
64505
|
/** null until a reading has been published (D393). */
|
|
61860
64506
|
lastFetchedAt: number().nullable()
|
|
@@ -61907,7 +64553,7 @@ var RecordingAvailabilitySchema = object({
|
|
|
61907
64553
|
* would look identical. But the answer used to say nothing about that, so a
|
|
61908
64554
|
* caller asking "what can I export?" read the single preferred profile as
|
|
61909
64555
|
* the only one that exists — on this deployment every camera records `high`
|
|
61910
|
-
* AND `low`, the low tree holding 14 GB for camera
|
|
64556
|
+
* AND `low`, the low tree holding 14 GB for camera 101 alone, and the export
|
|
61911
64557
|
* UI could not see it.
|
|
61912
64558
|
*
|
|
61913
64559
|
* Cheap: it is the same shallow directory read the profile CHOICE already
|
|
@@ -62006,7 +64652,7 @@ var RecordingSourceOptionsSchema = object({
|
|
|
62006
64652
|
* `sparse` = gaps are the absence of one, and must be drawn as such.
|
|
62007
64653
|
*
|
|
62008
64654
|
* Not an onboard-only concession: measured 2026-09-24, OUR bar covers 98.8 %
|
|
62009
|
-
* of
|
|
64655
|
+
* of 107's day and 1.2 % of 1436's. It is a fact about a (source, camera)
|
|
62010
64656
|
* pair, and ours answers it per camera from `deriveRecordingMode`. */
|
|
62011
64657
|
coverage: _enum(["continuous", "sparse"]),
|
|
62012
64658
|
/** Where the playhead may be put.
|
|
@@ -62082,7 +64728,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(RecordingSourceS
|
|
|
62082
64728
|
* merely discouraged (D554 amended).
|
|
62083
64729
|
*
|
|
62084
64730
|
* It was learned the expensive way on `videoclips.listClips`: measured
|
|
62085
|
-
* on the live hub 2026-09-20, device
|
|
64731
|
+
* on the live hub 2026-09-20, device 107 bound to `recorder` AND
|
|
62086
64732
|
* `provider-reolink`, a bare call with `limit: 3` answered SIX rows,
|
|
62087
64733
|
* three from each source, merged — `device-collection-dispatch.ts`
|
|
62088
64734
|
* leaves an unpinned fan-out un-narrowed, so absence buys the union the
|
|
@@ -62683,7 +65329,7 @@ var ExportSpeedSchema = number().min(.25).max(32);
|
|
|
62683
65329
|
* on a 10 h window holding 29,393 s of footage every range landed late by the
|
|
62684
65330
|
* gap accumulated before it — up to 6,607 s, well past EOF. Nothing matched,
|
|
62685
65331
|
* the video was a uniform timelapse, and the log line reported the five ranges
|
|
62686
|
-
* that had been ASKED for (2026-08-13, export `57d14363`, camera
|
|
65332
|
+
* that had been ASKED for (2026-08-13, export `57d14363`, camera 101).
|
|
62687
65333
|
*
|
|
62688
65334
|
* Relative and not absolute epoch, because an absolute epoch would make every
|
|
62689
65335
|
* call site responsible for the same subtraction.
|
|
@@ -63351,7 +65997,7 @@ getStatus: method(object({ deviceId: number() }), RecordingSignalStatusSchema) }
|
|
|
63351
65997
|
* which put a "Scenes" tab on one camera's detail page. That is the wrong shape
|
|
63352
65998
|
* for the thing: a scene is a standing question about the property ("is the bin
|
|
63353
65999
|
* still out"), and the operator's question is "which of my scenes have tripped",
|
|
63354
|
-
* across every camera at once — not "what does camera
|
|
66000
|
+
* across every camera at once — not "what does camera 102 think". Buried one
|
|
63355
66001
|
* camera deep it also could not be found. The surface is now a top-level admin
|
|
63356
66002
|
* page (`/scenes`, `pages/Scenes.tsx`) that lists every scene on every camera and
|
|
63357
66003
|
* picks the camera inside the create flow, the same shape Events and Faces have.
|
|
@@ -63934,7 +66580,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), StreamParamsOptionsSch
|
|
|
63934
66580
|
auth: "admin"
|
|
63935
66581
|
}), method(object({ deviceId: number() }), unknown().nullable());
|
|
63936
66582
|
object({
|
|
63937
|
-
on: boolean(),
|
|
66583
|
+
on: boolean().meta({ label: "On" }),
|
|
63938
66584
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
63939
66585
|
lastChangedAt: number()
|
|
63940
66586
|
});
|
|
@@ -64497,7 +67143,10 @@ object({
|
|
|
64497
67143
|
DeviceType.Sensor;
|
|
64498
67144
|
object({
|
|
64499
67145
|
/** Current temperature in Celsius. */
|
|
64500
|
-
celsius: number()
|
|
67146
|
+
celsius: number().meta({
|
|
67147
|
+
unit: "°C",
|
|
67148
|
+
label: "Temperature"
|
|
67149
|
+
}),
|
|
64501
67150
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64502
67151
|
lastFetchedAt: number(),
|
|
64503
67152
|
/** Live display unit from the upstream source (e.g. HA
|
|
@@ -65705,6 +68354,10 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
65705
68354
|
auth: "admin"
|
|
65706
68355
|
});
|
|
65707
68356
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
68357
|
+
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;
|
|
68358
|
+
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
68359
|
+
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
68360
|
+
new Set(CAP_NAMES);
|
|
65708
68361
|
Object.freeze({
|
|
65709
68362
|
person: .5,
|
|
65710
68363
|
vehicle: .5,
|
|
@@ -68704,6 +71357,27 @@ Object.freeze({
|
|
|
68704
71357
|
access: "create",
|
|
68705
71358
|
role: "viewer"
|
|
68706
71359
|
},
|
|
71360
|
+
"displayPalette.getPalette": {
|
|
71361
|
+
capName: "display-palette",
|
|
71362
|
+
capScope: "system",
|
|
71363
|
+
addonId: null,
|
|
71364
|
+
access: "view",
|
|
71365
|
+
role: "viewer"
|
|
71366
|
+
},
|
|
71367
|
+
"displayPalette.listPresets": {
|
|
71368
|
+
capName: "display-palette",
|
|
71369
|
+
capScope: "system",
|
|
71370
|
+
addonId: null,
|
|
71371
|
+
access: "view",
|
|
71372
|
+
role: "viewer"
|
|
71373
|
+
},
|
|
71374
|
+
"displayPalette.setPalette": {
|
|
71375
|
+
capName: "display-palette",
|
|
71376
|
+
capScope: "system",
|
|
71377
|
+
addonId: null,
|
|
71378
|
+
access: "create",
|
|
71379
|
+
role: "admin"
|
|
71380
|
+
},
|
|
68707
71381
|
"doorbell.getStatus": {
|
|
68708
71382
|
capName: "doorbell",
|
|
68709
71383
|
capScope: "device",
|
|
@@ -78621,7 +81295,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78621
81295
|
state: [{
|
|
78622
81296
|
kind: "boolean",
|
|
78623
81297
|
field: "on",
|
|
78624
|
-
label: t("
|
|
81298
|
+
label: t("On", "Acceso"),
|
|
78625
81299
|
whenTrue: t("When {device} turns active", "Quando {device} si attiva"),
|
|
78626
81300
|
whenFalse: t("When {device} turns inactive", "Quando {device} si disattiva"),
|
|
78627
81301
|
icon: "toggle-right"
|
|
@@ -79160,6 +81834,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
79160
81834
|
"device-provider": system(INTERNAL),
|
|
79161
81835
|
"device-removal-hook": system(INTERNAL),
|
|
79162
81836
|
"device-state": system("the runtime-state mirror every trigger already reads through"),
|
|
81837
|
+
"display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
|
|
79163
81838
|
"embedding-encoder": system(ML),
|
|
79164
81839
|
"face-gallery": system("the face gallery — curated on its own page"),
|
|
79165
81840
|
"failure-contribution": system(INTERNAL),
|
|
@@ -82169,7 +84844,6 @@ var BucketAccumulator = class {
|
|
|
82169
84844
|
}
|
|
82170
84845
|
};
|
|
82171
84846
|
DeviceType.Camera;
|
|
82172
|
-
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;
|
|
82173
84847
|
/**
|
|
82174
84848
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
82175
84849
|
* `z.infer`, they do not restate the shape.
|
|
@@ -82258,7 +84932,6 @@ object({
|
|
|
82258
84932
|
]),
|
|
82259
84933
|
reason: string().nullable()
|
|
82260
84934
|
});
|
|
82261
|
-
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
82262
84935
|
var G711_SCALE_CORRECTION_DB = {
|
|
82263
84936
|
PCMU: 20 * Math.log10(4),
|
|
82264
84937
|
PCMA: 20 * Math.log10(8)
|
|
@@ -82631,7 +85304,7 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
82631
85304
|
{
|
|
82632
85305
|
name: "summaryStreams",
|
|
82633
85306
|
label: "Summary: streams offline",
|
|
82634
|
-
example: "
|
|
85307
|
+
example: "Front door (high) — since 06:40",
|
|
82635
85308
|
kinds: ["stream-offline", "stream-online"]
|
|
82636
85309
|
},
|
|
82637
85310
|
{
|
|
@@ -82649,13 +85322,13 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
82649
85322
|
{
|
|
82650
85323
|
name: "summaryDetection",
|
|
82651
85324
|
label: "Summary: cameras detecting nothing",
|
|
82652
|
-
example: "
|
|
85325
|
+
example: "Front door — since 05:10",
|
|
82653
85326
|
kinds: ["detection-blind"]
|
|
82654
85327
|
},
|
|
82655
85328
|
{
|
|
82656
85329
|
name: "summaryNodes",
|
|
82657
85330
|
label: "Summary: nodes",
|
|
82658
|
-
example: "
|
|
85331
|
+
example: "agent-a — offline since 03:00",
|
|
82659
85332
|
kinds: [
|
|
82660
85333
|
"node-offline",
|
|
82661
85334
|
"node-online",
|
|
@@ -87111,7 +89784,7 @@ function validateJumpTargets(inferenceDevices, enabledAvailableKeys) {
|
|
|
87111
89784
|
* A **Coral Edge TPU (`edgetpu`)** is an accelerator like the rest and is
|
|
87112
89785
|
* enabled by default (D912, superseding D39). The 2026-08-01 incident that made
|
|
87113
89786
|
* it opt-in (a Coral nobody enabled took an equal share of the rotation, ran a
|
|
87114
|
-
* weaker SSD and left camera
|
|
89787
|
+
* weaker SSD and left camera 101 at 2.4 fps) is answered by speed-proportional
|
|
87115
89788
|
* automatic weights — Auto tune sizes the Coral at its default YOLOv9-s 320
|
|
87116
89789
|
* Edge TPU build with the measured latency — and by that default model, which
|
|
87117
89790
|
* is YOLOv9 like the rest. An explicit stored `enabled:false` still wins.
|
|
@@ -90761,7 +93434,7 @@ var CameraStatusService = class {
|
|
|
90761
93434
|
* means "we could not look" from a `null` that means "there is nothing
|
|
90762
93435
|
* there"; the `warn` is what makes the next hang findable at all. The line
|
|
90763
93436
|
* carries `tags.deviceId` with the numeric id because the question is always
|
|
90764
|
-
* per-camera ("why is
|
|
93437
|
+
* per-camera ("why is 105 worse than 101?") and a line without the tag
|
|
90765
93438
|
* cannot be grouped to answer it.
|
|
90766
93439
|
*/
|
|
90767
93440
|
recordDegraded(sink, deviceId, stage, reason, elapsedMs, extraMeta = {}) {
|
|
@@ -91061,7 +93734,7 @@ var CameraStatusService = class {
|
|
|
91061
93734
|
*
|
|
91062
93735
|
* In the last two the returned list is `[]`, and `[]` was once handed to the
|
|
91063
93736
|
* payload as the positive claim "the operator has switched nothing off".
|
|
91064
|
-
* Measured on the live hub 2026-08-08: `getCameraStatus(
|
|
93737
|
+
* Measured on the live hub 2026-08-08: `getCameraStatus(105)` said
|
|
91065
93738
|
* `switchedOff: []` at the very moment `stream-broker` AND `recording` were
|
|
91066
93739
|
* switched off by the operator — the camera read as BROKEN because it was
|
|
91067
93740
|
* switched OFF. The list stays empty (a guess would put a permanent "off"
|
|
@@ -91248,7 +93921,7 @@ function readPrivacyMaskFacts(v) {
|
|
|
91248
93921
|
*
|
|
91249
93922
|
* Measured on the live hub, 2026-08-08: seven of the eight sources answered in
|
|
91250
93923
|
* 5–15ms on every camera. The eighth, `privacyMask.getStatus`, probes the
|
|
91251
|
-
* camera itself and took 3.1–3.6s on device
|
|
93924
|
+
* camera itself and took 3.1–3.6s on device 105 on every single call (18s under
|
|
91252
93925
|
* load) — so a bound generous enough to make the fast sources safe still has to
|
|
91253
93926
|
* be willing to drop the slow one, because waiting for it costs the other six.
|
|
91254
93927
|
*/
|
|
@@ -92554,7 +95227,7 @@ async function reconcileOnboardForwarding(input, deps) {
|
|
|
92554
95227
|
* never cause a video transcode, and on this fleet the motion rung IS a
|
|
92555
95228
|
* `derived:*` transcode. The caller therefore hands the resolved audio stream
|
|
92556
95229
|
* in {@link WatchdogAudioSource} — reading `motionStreamId` here would label
|
|
92557
|
-
* and RECOVER the wrong stream, which is how camera
|
|
95230
|
+
* and RECOVER the wrong stream, which is how camera 108's audio stage watched
|
|
92558
95231
|
* a plane the analyser was not listening to.
|
|
92559
95232
|
*
|
|
92560
95233
|
* `pipelineEnabled === false` (the `object-detection` switch, D62/ADR-0109)
|
|
@@ -92683,7 +95356,7 @@ var DetectionWiringController = class {
|
|
|
92683
95356
|
* silently loses `BATTERY_DEVICE_PROFILE` and `audioMode` falls back to
|
|
92684
95357
|
* `'always-on'` — which subscribes the audio-analyzer, which is demand on
|
|
92685
95358
|
* the substream, which dials the camera and WAKES it. Measured on the live
|
|
92686
|
-
* hub: 3 of 12 detection passes on device
|
|
95359
|
+
* hub: 3 of 12 detection passes on device 106 did exactly that, each right
|
|
92687
95360
|
* after a `provider-reolink` restart.
|
|
92688
95361
|
*
|
|
92689
95362
|
* So this reports UNKNOWN (`null`) distinctly from "no features" (`[]`), and
|
|
@@ -94142,7 +96815,7 @@ function decideSessionClose(input) {
|
|
|
94142
96815
|
* straight to the floor check; the hold, the cap and the track-freshness read
|
|
94143
96816
|
* all lived inside the COOLDOWN TIMER's body. On a camera that emits an
|
|
94144
96817
|
* explicit low edge — which is every camera — the timer body never ran.
|
|
94145
|
-
* Measured on device
|
|
96818
|
+
* Measured on device 102 over 24 h, 503 paired sessions: **502 closed on
|
|
94146
96819
|
* `motion_cleared`**, 1 on the cooldown, 0 on `maxSessionHoldMs`, and the
|
|
94147
96820
|
* "held open" branch fired **0 times**. Median session life 10 221 ms against a
|
|
94148
96821
|
* 10 000 ms floor — not a duration, a floor. 71.5% of the tracks that died in
|
|
@@ -99002,7 +101675,7 @@ var RECHECK_REASON = "orchestrator-recheck";
|
|
|
99002
101675
|
/**
|
|
99003
101676
|
* D691 — the EARLY LOOK. An occupancy edge commits only on a sample that lands
|
|
99004
101677
|
* after its sustain window, and a departure's session usually closes before
|
|
99005
|
-
* that (the car drives off, motion clears):
|
|
101678
|
+
* that (the car drives off, motion clears): 102 on 2026-10-01 closed 1.3 s
|
|
99006
101679
|
* before its 29 s sustain ended and the edge waited 4 min 52 s for the cadence
|
|
99007
101680
|
* above. The notification centre, which alone knows a flip is pending, asks
|
|
99008
101681
|
* for ONE look at the sustain's end ({@link OccupancyRecheckController.requestEarlyLook});
|
|
@@ -99774,7 +102447,7 @@ function countRunningByNode(placements) {
|
|
|
99774
102447
|
* 57.6% under 5 s, and **820 of 822 closes were the hub's explicit
|
|
99775
102448
|
* `motion_cleared` falling edge** — which closed the session instantly, so
|
|
99776
102449
|
* `motionCooldownMs` / the track hold / `maxSessionHoldMs` decided 2 closes in
|
|
99777
|
-
* total. Camera
|
|
102450
|
+
* total. Camera 104 opened and closed 249 sessions in 25 minutes; every close
|
|
99778
102451
|
* dropped its assignment and every reopen re-elected a node, which is the
|
|
99779
102452
|
* 2-3 second flicker the operator reported on the placement column — and a full
|
|
99780
102453
|
* detach+attach round trip per flicker.
|
|
@@ -100145,7 +102818,7 @@ var SessionDispatchController = class {
|
|
|
100145
102818
|
* Close an ACTIVE detection session so the next motion event re-dispatches
|
|
100146
102819
|
* it fresh — used by `assignPipeline` when the operator pins a session-mode
|
|
100147
102820
|
* camera to a node OTHER than the one its session currently runs on (the
|
|
100148
|
-
* cam-
|
|
102821
|
+
* cam-104 case: a busy camera's session never cools down, so without this
|
|
100149
102822
|
* the stale pre-pin placement survived indefinitely).
|
|
100150
102823
|
*
|
|
100151
102824
|
* Deliberately NOT `stopForDevice`: the camera must stay ARMED —
|
|
@@ -100251,7 +102924,7 @@ var SessionDispatchController = class {
|
|
|
100251
102924
|
* SAME rule the fallback timer uses ({@link resolveSessionLifecycleLocked}).
|
|
100252
102925
|
* It no longer bypasses the hold and the cap: it used to, and that made
|
|
100253
102926
|
* both unreachable on every camera that emits a falling edge — 502 of
|
|
100254
|
-
* 503 closes on device
|
|
102927
|
+
* 503 closes on device 102 in 24 h. An explicit clear still wins over
|
|
100255
102928
|
* the cooldown; it does not win over a subject that is still there.
|
|
100256
102929
|
*
|
|
100257
102930
|
* LIVE as of Task 2: `startDetection` no longer standing-attaches on-motion
|
|
@@ -100700,7 +103373,7 @@ var SessionDispatchController = class {
|
|
|
100700
103373
|
* falling edge, the `cooldown_expired` fallback timer, and the re-ask of a
|
|
100701
103374
|
* close this method itself deferred. That is the fix — the hold, the
|
|
100702
103375
|
* freshness read and `maxSessionHoldMs` used to live inside the COOLDOWN
|
|
100703
|
-
* TIMER's body, so a falling edge reached none of them. On device
|
|
103376
|
+
* TIMER's body, so a falling edge reached none of them. On device 102, 24 h,
|
|
100704
103377
|
* 503 sessions: 502 closes were falling edges, the hold branch fired 0
|
|
100705
103378
|
* times, `maxSessionHoldMs` fired 0 times, and the session-duration
|
|
100706
103379
|
* distribution collapsed onto {@link MIN_SESSION_OPEN_MS} — median 10 221 ms
|
|
@@ -100775,7 +103448,7 @@ var SessionDispatchController = class {
|
|
|
100775
103448
|
* **This branch drops work, so it says so.** Closing a session detaches the
|
|
100776
103449
|
* runner: every track still live on that camera dies here, mid-life, with no
|
|
100777
103450
|
* `end` key-event and no chance of ever reaching the stationary registry's
|
|
100778
|
-
* promotion window. It used to log one bare sentence. Measured on device
|
|
103451
|
+
* promotion window. It used to log one bare sentence. Measured on device 102
|
|
100779
103452
|
* over 24 h it killed **223 live tracks across 503 closes (0.44 per close)**,
|
|
100780
103453
|
* 95% of which had been motionless for at least a second, and not one line
|
|
100781
103454
|
* named a single one of them — the gap had to be reconstructed by
|
|
@@ -101388,9 +104061,9 @@ var ZoneRulesProvider = class {
|
|
|
101388
104061
|
* so a camera whose runtime-state row had never been written (or had
|
|
101389
104062
|
* been reset) had no `zones` slice at all, and every mirror-only
|
|
101390
104063
|
* consumer concluded "this camera has no zones" — forever, because no
|
|
101391
|
-
* mutation was coming. Live cost (camera
|
|
101392
|
-
* 2026-08-12): `zones.listZones {
|
|
101393
|
-
* while `deviceState.getCapSlice {
|
|
104064
|
+
* mutation was coming. Live cost (camera 102 'Parking',
|
|
104065
|
+
* 2026-08-12): `zones.listZones {102}` returned 'Parking pat'
|
|
104066
|
+
* while `deviceState.getCapSlice {102,'zones'}` returned `null`;
|
|
101394
104067
|
* occupancy dropped all three parked cars into `unzoned`, its zone
|
|
101395
104068
|
* rule could never fire, and the admin Zones tab — which reads the
|
|
101396
104069
|
* same mirror — showed "No zones yet".
|
|
@@ -101854,7 +104527,7 @@ async function buildOrchestratorControllers(deps) {
|
|
|
101854
104527
|
* false negative on every COLD broker: `getStats()` answers `audio: null`
|
|
101855
104528
|
* until a track is observed, and dispatch normally runs while the stream is
|
|
101856
104529
|
* idle. So the audio stage armed only for cameras that happened to be hot at
|
|
101857
|
-
* dispatch — which is why camera
|
|
104530
|
+
* dispatch — which is why camera 108's derived stream delivered zero audio
|
|
101858
104531
|
* chunks for four days without a single watchdog line. A stage armed on a
|
|
101859
104532
|
* camera that turns out to have no audio is BOUNDED: the watchdog disarms a
|
|
101860
104533
|
* stage that never produced one signal, with one line.
|
|
@@ -103036,6 +105709,112 @@ function deriveRuntimeSettings(config) {
|
|
|
103036
105709
|
};
|
|
103037
105710
|
}
|
|
103038
105711
|
//#endregion
|
|
105712
|
+
//#region src/display-palette-provider.ts
|
|
105713
|
+
/**
|
|
105714
|
+
* Display palette provider (D939, D940). The pipeline orchestrator owns
|
|
105715
|
+
* this cluster setting. The document is one key in the addon's store, so
|
|
105716
|
+
* a write does not replace the orchestrator's other settings. An
|
|
105717
|
+
* unreadable store is `unknown`, never the bundled preset.
|
|
105718
|
+
*/
|
|
105719
|
+
/** Key inside the orchestrator's addon store. Not a settings-schema field. */
|
|
105720
|
+
var DISPLAY_PALETTE_STORE_KEY = "displayPalette";
|
|
105721
|
+
function createDisplayPaletteProvider(settings, logger) {
|
|
105722
|
+
return {
|
|
105723
|
+
getPalette: async () => readPalette(settings, logger),
|
|
105724
|
+
listPresets: async () => DISPLAY_PRESETS.map((row) => ({
|
|
105725
|
+
id: row.id,
|
|
105726
|
+
name: row.name,
|
|
105727
|
+
swatches: row.swatches,
|
|
105728
|
+
fallbacks: [...row.fallbacks]
|
|
105729
|
+
})),
|
|
105730
|
+
setPalette: async (input) => writePalette(settings, logger, input)
|
|
105731
|
+
};
|
|
105732
|
+
}
|
|
105733
|
+
async function readPalette(settings, logger) {
|
|
105734
|
+
if (settings === void 0) {
|
|
105735
|
+
logger.warn("display-palette: settings store cannot be read three ways");
|
|
105736
|
+
return {
|
|
105737
|
+
status: "unknown",
|
|
105738
|
+
reason: "settings store cannot be read"
|
|
105739
|
+
};
|
|
105740
|
+
}
|
|
105741
|
+
const readKey = settings.readAddonStoreKeyResult;
|
|
105742
|
+
if (readKey !== void 0) return readByKey(settings, readKey, logger);
|
|
105743
|
+
const read = settings.readAddonStoreResult;
|
|
105744
|
+
if (read === void 0) {
|
|
105745
|
+
logger.warn("display-palette: settings store cannot be read three ways");
|
|
105746
|
+
return {
|
|
105747
|
+
status: "unknown",
|
|
105748
|
+
reason: "settings store cannot be read"
|
|
105749
|
+
};
|
|
105750
|
+
}
|
|
105751
|
+
return readByStore(settings, read, logger);
|
|
105752
|
+
}
|
|
105753
|
+
async function readByKey(settings, readKey, logger) {
|
|
105754
|
+
let result;
|
|
105755
|
+
try {
|
|
105756
|
+
result = await readKey.call(settings, DISPLAY_PALETTE_STORE_KEY);
|
|
105757
|
+
} catch (err) {
|
|
105758
|
+
return readThrew(logger, err);
|
|
105759
|
+
}
|
|
105760
|
+
if (result.kind === "unreadable") {
|
|
105761
|
+
logger.warn("display-palette: settings unreadable", { meta: { error: result.error } });
|
|
105762
|
+
return {
|
|
105763
|
+
status: "unknown",
|
|
105764
|
+
reason: result.error ?? "settings store cannot be read"
|
|
105765
|
+
};
|
|
105766
|
+
}
|
|
105767
|
+
if (result.kind === "absent") return bundledCamstack();
|
|
105768
|
+
return interpretStored(logger, result.value);
|
|
105769
|
+
}
|
|
105770
|
+
async function readByStore(settings, read, logger) {
|
|
105771
|
+
let result;
|
|
105772
|
+
try {
|
|
105773
|
+
result = await read.call(settings);
|
|
105774
|
+
} catch (err) {
|
|
105775
|
+
return readThrew(logger, err);
|
|
105776
|
+
}
|
|
105777
|
+
if (result.kind === "failed") {
|
|
105778
|
+
logger.warn("display-palette: settings unreadable", { meta: { error: result.error } });
|
|
105779
|
+
return {
|
|
105780
|
+
status: "unknown",
|
|
105781
|
+
reason: result.error
|
|
105782
|
+
};
|
|
105783
|
+
}
|
|
105784
|
+
if (result.kind === "missing") return bundledCamstack();
|
|
105785
|
+
return interpretStored(logger, result.value[DISPLAY_PALETTE_STORE_KEY]);
|
|
105786
|
+
}
|
|
105787
|
+
function readThrew(logger, err) {
|
|
105788
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
105789
|
+
logger.warn("display-palette: settings read threw", { meta: { error } });
|
|
105790
|
+
return {
|
|
105791
|
+
status: "unknown",
|
|
105792
|
+
reason: "settings store read failed"
|
|
105793
|
+
};
|
|
105794
|
+
}
|
|
105795
|
+
function interpretStored(logger, value) {
|
|
105796
|
+
const palette = paletteFromStored(value);
|
|
105797
|
+
if (palette.status === "unknown") logger.warn("display-palette: stored palette is not usable", { meta: { reason: palette.reason } });
|
|
105798
|
+
return palette;
|
|
105799
|
+
}
|
|
105800
|
+
async function writePalette(settings, logger, input) {
|
|
105801
|
+
let ready;
|
|
105802
|
+
try {
|
|
105803
|
+
ready = paletteFromInput(input);
|
|
105804
|
+
} catch (err) {
|
|
105805
|
+
if (err instanceof PaletteRejectedError) logger.info("display-palette: refused", { meta: { reason: err.message } });
|
|
105806
|
+
throw err;
|
|
105807
|
+
}
|
|
105808
|
+
const write = settings?.writeAddonStore;
|
|
105809
|
+
if (settings === void 0 || write === void 0) {
|
|
105810
|
+
logger.warn("display-palette: settings store cannot be written");
|
|
105811
|
+
throw new Error("display-palette: settings store cannot be written");
|
|
105812
|
+
}
|
|
105813
|
+
const overrides = "overrides" in input ? input.overrides : {};
|
|
105814
|
+
await write.call(settings, { [DISPLAY_PALETTE_STORE_KEY]: storedFromReady(ready, overrides) });
|
|
105815
|
+
return ready;
|
|
105816
|
+
}
|
|
105817
|
+
//#endregion
|
|
103039
105818
|
//#region src/viewer-ui-provider.ts
|
|
103040
105819
|
/**
|
|
103041
105820
|
* viewer-ui provider — the pipeline-orchestrator serves the CamStack viewer web
|
|
@@ -104492,6 +107271,10 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
104492
107271
|
{
|
|
104493
107272
|
capability: viewerUiCapability,
|
|
104494
107273
|
provider: createViewerUiProvider()
|
|
107274
|
+
},
|
|
107275
|
+
{
|
|
107276
|
+
capability: displayPaletteCapability,
|
|
107277
|
+
provider: createDisplayPaletteProvider(this.ctx.settings, this.ctx.logger)
|
|
104495
107278
|
}
|
|
104496
107279
|
],
|
|
104497
107280
|
customActions: pipelineOrchestratorActions,
|
|
@@ -105386,7 +108169,7 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
105386
108169
|
* Which nodes can still infer. Refreshed by
|
|
105387
108170
|
* {@link resolveEligibleInferenceDevices}; read synchronously by both
|
|
105388
108171
|
* dispatch paths so a node whose every enabled accelerator vanished stops
|
|
105389
|
-
* receiving cameras.
|
|
108172
|
+
* receiving cameras. agent-a was handed cameras for a whole day in
|
|
105390
108173
|
* exactly that state.
|
|
105391
108174
|
*/
|
|
105392
108175
|
nodeInferenceUsability = new NodeInferenceUsabilityMirror();
|