@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.js
CHANGED
|
@@ -30,7 +30,7 @@ node_fs = __toESM(node_fs);
|
|
|
30
30
|
let node_path = require("node:path");
|
|
31
31
|
node_path = __toESM(node_path);
|
|
32
32
|
let node_url = require("node:url");
|
|
33
|
-
//#region ../types/dist/event-category-
|
|
33
|
+
//#region ../types/dist/event-category-DHXxB8t9.mjs
|
|
34
34
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
35
35
|
EventCategory["SystemBoot"] = "system.boot";
|
|
36
36
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -326,7 +326,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
326
326
|
* TRANSITION into that state (never per dispatch), and the node is dropped
|
|
327
327
|
* from the placement candidate set for as long as it holds.
|
|
328
328
|
*
|
|
329
|
-
* This exists because the state was previously invisible:
|
|
329
|
+
* This exists because the state was previously invisible: agent-a
|
|
330
330
|
* absorbed 283k inference errors in a day while still being handed cameras,
|
|
331
331
|
* and nothing in the system said so.
|
|
332
332
|
*
|
|
@@ -5598,7 +5598,7 @@ var ZodIssueCode = {
|
|
|
5598
5598
|
var ZodFirstPartyTypeKind;
|
|
5599
5599
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5600
5600
|
//#endregion
|
|
5601
|
-
//#region ../types/dist/sleep-
|
|
5601
|
+
//#region ../types/dist/sleep-BErAxhul.mjs
|
|
5602
5602
|
/**
|
|
5603
5603
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5604
5604
|
* window to float samples (D455).
|
|
@@ -9260,7 +9260,7 @@ var viewerUiCapability = {
|
|
|
9260
9260
|
* `getStaticDir` leaks a hub filesystem path.
|
|
9261
9261
|
*
|
|
9262
9262
|
* ⚠ Checked before gating: the VIEWER app IS used by a non-admin user
|
|
9263
|
-
* (`
|
|
9263
|
+
* (`bob`), but it never calls `viewerUi.*` over tRPC. The static SPA
|
|
9264
9264
|
* it loads is served by the plain `GET /viewer/*` Fastify route in
|
|
9265
9265
|
* `main.ts`, which reads `staticDir`/`indexPath` from a module-level
|
|
9266
9266
|
* cache populated ONCE at boot via `capRegistry.getSingletonForNode`
|
|
@@ -9335,6 +9335,1980 @@ method(object({ deviceId: number() }), array(StreamSourceEntrySchema)), method(o
|
|
|
9335
9335
|
kind: "mutation",
|
|
9336
9336
|
auth: "admin"
|
|
9337
9337
|
}), method(object({ deviceId: number() }), unknown().nullable()), method(object({ deviceId: number() }), RawStateResultSchema.nullable(), { auth: "protected" });
|
|
9338
|
+
Object.freeze({ "doorbell": "lastPressedAt" });
|
|
9339
|
+
/** Every capability name, so addon code can check a name without the schema graph. */
|
|
9340
|
+
var CAP_NAMES = Object.freeze([
|
|
9341
|
+
"accessories",
|
|
9342
|
+
"addon-pages",
|
|
9343
|
+
"addon-pages-source",
|
|
9344
|
+
"addon-routes",
|
|
9345
|
+
"addon-settings",
|
|
9346
|
+
"addon-widgets",
|
|
9347
|
+
"addon-widgets-source",
|
|
9348
|
+
"addons",
|
|
9349
|
+
"admin-ui",
|
|
9350
|
+
"air-quality-sensor",
|
|
9351
|
+
"alarm-panel",
|
|
9352
|
+
"alerts",
|
|
9353
|
+
"ambient-light-sensor",
|
|
9354
|
+
"audio-analysis",
|
|
9355
|
+
"audio-analyzer",
|
|
9356
|
+
"audio-codec",
|
|
9357
|
+
"audio-metrics",
|
|
9358
|
+
"auth-provider",
|
|
9359
|
+
"automation-control",
|
|
9360
|
+
"backup",
|
|
9361
|
+
"battery",
|
|
9362
|
+
"binary",
|
|
9363
|
+
"brightness",
|
|
9364
|
+
"broker",
|
|
9365
|
+
"button",
|
|
9366
|
+
"calendar-source",
|
|
9367
|
+
"calendars",
|
|
9368
|
+
"camera-credentials",
|
|
9369
|
+
"camera-grid-layout",
|
|
9370
|
+
"camera-pipeline-config",
|
|
9371
|
+
"camera-streams",
|
|
9372
|
+
"carbon-monoxide",
|
|
9373
|
+
"climate-control",
|
|
9374
|
+
"color",
|
|
9375
|
+
"composer",
|
|
9376
|
+
"connection-test",
|
|
9377
|
+
"connectivity",
|
|
9378
|
+
"consumables",
|
|
9379
|
+
"contact",
|
|
9380
|
+
"control",
|
|
9381
|
+
"core-blocks",
|
|
9382
|
+
"cover",
|
|
9383
|
+
"custom-model-registry",
|
|
9384
|
+
"data-store-provider",
|
|
9385
|
+
"database-snapshot",
|
|
9386
|
+
"day-night",
|
|
9387
|
+
"decoder",
|
|
9388
|
+
"detection-pipeline",
|
|
9389
|
+
"device-admin-link",
|
|
9390
|
+
"device-adoption",
|
|
9391
|
+
"device-credentials",
|
|
9392
|
+
"device-discovery",
|
|
9393
|
+
"device-export",
|
|
9394
|
+
"device-extension",
|
|
9395
|
+
"device-history",
|
|
9396
|
+
"device-manager",
|
|
9397
|
+
"device-ops",
|
|
9398
|
+
"device-provider",
|
|
9399
|
+
"device-removal-hook",
|
|
9400
|
+
"device-state",
|
|
9401
|
+
"device-status",
|
|
9402
|
+
"dishwasher",
|
|
9403
|
+
"display-palette",
|
|
9404
|
+
"doorbell",
|
|
9405
|
+
"embedding-encoder",
|
|
9406
|
+
"enum-sensor",
|
|
9407
|
+
"event-emitter",
|
|
9408
|
+
"face-gallery",
|
|
9409
|
+
"failure-contribution",
|
|
9410
|
+
"fan-control",
|
|
9411
|
+
"feature-probe",
|
|
9412
|
+
"filesystem-browse",
|
|
9413
|
+
"flood",
|
|
9414
|
+
"gas",
|
|
9415
|
+
"heating-valve",
|
|
9416
|
+
"humidifier",
|
|
9417
|
+
"humidity-sensor",
|
|
9418
|
+
"image",
|
|
9419
|
+
"image-settings",
|
|
9420
|
+
"integrations",
|
|
9421
|
+
"intercom",
|
|
9422
|
+
"keychain",
|
|
9423
|
+
"keychain-admin",
|
|
9424
|
+
"lawn-mower-control",
|
|
9425
|
+
"llm",
|
|
9426
|
+
"llm-runtime",
|
|
9427
|
+
"load-contribution",
|
|
9428
|
+
"local-network",
|
|
9429
|
+
"lock-control",
|
|
9430
|
+
"log-channels",
|
|
9431
|
+
"log-destination",
|
|
9432
|
+
"login-method",
|
|
9433
|
+
"media-player",
|
|
9434
|
+
"mesh-network",
|
|
9435
|
+
"metrics-provider",
|
|
9436
|
+
"model-convert",
|
|
9437
|
+
"model-distributor",
|
|
9438
|
+
"motion",
|
|
9439
|
+
"motion-detection",
|
|
9440
|
+
"motion-trigger",
|
|
9441
|
+
"motion-zones",
|
|
9442
|
+
"mqtt-broker",
|
|
9443
|
+
"native-object-detection",
|
|
9444
|
+
"navigation",
|
|
9445
|
+
"network-access",
|
|
9446
|
+
"network-link",
|
|
9447
|
+
"network-quality",
|
|
9448
|
+
"node-certificates",
|
|
9449
|
+
"nodes",
|
|
9450
|
+
"notification-output",
|
|
9451
|
+
"notification-rules",
|
|
9452
|
+
"notifier",
|
|
9453
|
+
"numeric-sensor",
|
|
9454
|
+
"oauth-integration",
|
|
9455
|
+
"oidc-connections",
|
|
9456
|
+
"osd",
|
|
9457
|
+
"osd-manager",
|
|
9458
|
+
"pet-feeder",
|
|
9459
|
+
"pipeline-analytics",
|
|
9460
|
+
"pipeline-executor",
|
|
9461
|
+
"pipeline-orchestrator",
|
|
9462
|
+
"pipeline-runner",
|
|
9463
|
+
"plate-gallery",
|
|
9464
|
+
"platform-probe",
|
|
9465
|
+
"power-meter",
|
|
9466
|
+
"presence",
|
|
9467
|
+
"pressure-sensor",
|
|
9468
|
+
"privacy-mask",
|
|
9469
|
+
"ptz",
|
|
9470
|
+
"ptz-autotrack",
|
|
9471
|
+
"reboot",
|
|
9472
|
+
"record-entries",
|
|
9473
|
+
"recording",
|
|
9474
|
+
"recording-archive",
|
|
9475
|
+
"recording-export",
|
|
9476
|
+
"recording-onboard",
|
|
9477
|
+
"recording-signal",
|
|
9478
|
+
"records",
|
|
9479
|
+
"running-state",
|
|
9480
|
+
"scene-monitor",
|
|
9481
|
+
"script-runner",
|
|
9482
|
+
"server-management",
|
|
9483
|
+
"settings-store",
|
|
9484
|
+
"smoke",
|
|
9485
|
+
"smtp-provider",
|
|
9486
|
+
"snapshot",
|
|
9487
|
+
"sso-bridge",
|
|
9488
|
+
"storage",
|
|
9489
|
+
"storage-admin",
|
|
9490
|
+
"storage-evictable",
|
|
9491
|
+
"storage-migration",
|
|
9492
|
+
"storage-occupancy",
|
|
9493
|
+
"storage-provider",
|
|
9494
|
+
"stream-broker",
|
|
9495
|
+
"stream-catalog",
|
|
9496
|
+
"stream-params",
|
|
9497
|
+
"stream-signals",
|
|
9498
|
+
"switch",
|
|
9499
|
+
"system",
|
|
9500
|
+
"tamper",
|
|
9501
|
+
"temperature-sensor",
|
|
9502
|
+
"terminal-session",
|
|
9503
|
+
"toast",
|
|
9504
|
+
"training",
|
|
9505
|
+
"training-provider",
|
|
9506
|
+
"turn-provider",
|
|
9507
|
+
"update",
|
|
9508
|
+
"user-management",
|
|
9509
|
+
"user-passkeys",
|
|
9510
|
+
"vacuum-control",
|
|
9511
|
+
"valve",
|
|
9512
|
+
"vector-store",
|
|
9513
|
+
"vibration",
|
|
9514
|
+
"videoclips",
|
|
9515
|
+
"viewer-ui",
|
|
9516
|
+
"water-heater",
|
|
9517
|
+
"weather",
|
|
9518
|
+
"webrtc-session",
|
|
9519
|
+
"zone-analytics",
|
|
9520
|
+
"zone-rules",
|
|
9521
|
+
"zones"
|
|
9522
|
+
]);
|
|
9523
|
+
Object.freeze({
|
|
9524
|
+
"air-quality-sensor": [
|
|
9525
|
+
{
|
|
9526
|
+
"path": "co2Ppm",
|
|
9527
|
+
"valueType": "number"
|
|
9528
|
+
},
|
|
9529
|
+
{
|
|
9530
|
+
"path": "vocPpb",
|
|
9531
|
+
"valueType": "number"
|
|
9532
|
+
},
|
|
9533
|
+
{
|
|
9534
|
+
"path": "pm25",
|
|
9535
|
+
"valueType": "number"
|
|
9536
|
+
},
|
|
9537
|
+
{
|
|
9538
|
+
"path": "pm10",
|
|
9539
|
+
"valueType": "number"
|
|
9540
|
+
},
|
|
9541
|
+
{
|
|
9542
|
+
"path": "aqi",
|
|
9543
|
+
"valueType": "number"
|
|
9544
|
+
},
|
|
9545
|
+
{
|
|
9546
|
+
"path": "unit",
|
|
9547
|
+
"valueType": "string"
|
|
9548
|
+
},
|
|
9549
|
+
{
|
|
9550
|
+
"path": "precision",
|
|
9551
|
+
"valueType": "number"
|
|
9552
|
+
}
|
|
9553
|
+
],
|
|
9554
|
+
"alarm-panel": [
|
|
9555
|
+
{
|
|
9556
|
+
"path": "state",
|
|
9557
|
+
"valueType": "enum",
|
|
9558
|
+
"enumValues": [
|
|
9559
|
+
"disarmed",
|
|
9560
|
+
"armed_home",
|
|
9561
|
+
"armed_away",
|
|
9562
|
+
"armed_night",
|
|
9563
|
+
"armed_vacation",
|
|
9564
|
+
"armed_custom_bypass",
|
|
9565
|
+
"arming",
|
|
9566
|
+
"disarming",
|
|
9567
|
+
"pending",
|
|
9568
|
+
"triggered"
|
|
9569
|
+
]
|
|
9570
|
+
},
|
|
9571
|
+
{
|
|
9572
|
+
"path": "targetMode",
|
|
9573
|
+
"valueType": "enum",
|
|
9574
|
+
"enumValues": [
|
|
9575
|
+
"home",
|
|
9576
|
+
"away",
|
|
9577
|
+
"night",
|
|
9578
|
+
"vacation",
|
|
9579
|
+
"custom_bypass"
|
|
9580
|
+
]
|
|
9581
|
+
},
|
|
9582
|
+
{
|
|
9583
|
+
"path": "requiresCode",
|
|
9584
|
+
"valueType": "boolean"
|
|
9585
|
+
}
|
|
9586
|
+
],
|
|
9587
|
+
"ambient-light-sensor": [
|
|
9588
|
+
{
|
|
9589
|
+
"path": "lux",
|
|
9590
|
+
"valueType": "number"
|
|
9591
|
+
},
|
|
9592
|
+
{
|
|
9593
|
+
"path": "unit",
|
|
9594
|
+
"valueType": "string"
|
|
9595
|
+
},
|
|
9596
|
+
{
|
|
9597
|
+
"path": "precision",
|
|
9598
|
+
"valueType": "number"
|
|
9599
|
+
}
|
|
9600
|
+
],
|
|
9601
|
+
"audio-metrics": [
|
|
9602
|
+
{
|
|
9603
|
+
"path": "ts",
|
|
9604
|
+
"valueType": "number"
|
|
9605
|
+
},
|
|
9606
|
+
{
|
|
9607
|
+
"path": "windowSec",
|
|
9608
|
+
"valueType": "number"
|
|
9609
|
+
},
|
|
9610
|
+
{
|
|
9611
|
+
"path": "level.rms",
|
|
9612
|
+
"valueType": "number"
|
|
9613
|
+
},
|
|
9614
|
+
{
|
|
9615
|
+
"path": "level.dbfs",
|
|
9616
|
+
"valueType": "number"
|
|
9617
|
+
},
|
|
9618
|
+
{
|
|
9619
|
+
"path": "peakDbfs",
|
|
9620
|
+
"valueType": "number"
|
|
9621
|
+
},
|
|
9622
|
+
{
|
|
9623
|
+
"path": "avgDbfs",
|
|
9624
|
+
"valueType": "number"
|
|
9625
|
+
},
|
|
9626
|
+
{
|
|
9627
|
+
"path": "current.className",
|
|
9628
|
+
"valueType": "string"
|
|
9629
|
+
},
|
|
9630
|
+
{
|
|
9631
|
+
"path": "current.score",
|
|
9632
|
+
"valueType": "number"
|
|
9633
|
+
},
|
|
9634
|
+
{
|
|
9635
|
+
"path": "current.timestamp",
|
|
9636
|
+
"valueType": "number"
|
|
9637
|
+
}
|
|
9638
|
+
],
|
|
9639
|
+
"automation-control": [
|
|
9640
|
+
{
|
|
9641
|
+
"path": "enabled",
|
|
9642
|
+
"valueType": "boolean"
|
|
9643
|
+
},
|
|
9644
|
+
{
|
|
9645
|
+
"path": "isRunning",
|
|
9646
|
+
"valueType": "boolean"
|
|
9647
|
+
},
|
|
9648
|
+
{
|
|
9649
|
+
"path": "lastTriggeredAt",
|
|
9650
|
+
"valueType": "number"
|
|
9651
|
+
},
|
|
9652
|
+
{
|
|
9653
|
+
"path": "lastError",
|
|
9654
|
+
"valueType": "string"
|
|
9655
|
+
}
|
|
9656
|
+
],
|
|
9657
|
+
"battery": [
|
|
9658
|
+
{
|
|
9659
|
+
"path": "percentage",
|
|
9660
|
+
"valueType": "number"
|
|
9661
|
+
},
|
|
9662
|
+
{
|
|
9663
|
+
"path": "charging",
|
|
9664
|
+
"valueType": "enum",
|
|
9665
|
+
"enumValues": [
|
|
9666
|
+
"dc",
|
|
9667
|
+
"solar",
|
|
9668
|
+
"none",
|
|
9669
|
+
"unknown"
|
|
9670
|
+
]
|
|
9671
|
+
},
|
|
9672
|
+
{
|
|
9673
|
+
"path": "sleeping",
|
|
9674
|
+
"valueType": "boolean"
|
|
9675
|
+
},
|
|
9676
|
+
{
|
|
9677
|
+
"path": "lastUpdated",
|
|
9678
|
+
"valueType": "number"
|
|
9679
|
+
},
|
|
9680
|
+
{
|
|
9681
|
+
"path": "lastContactAt",
|
|
9682
|
+
"valueType": "number"
|
|
9683
|
+
},
|
|
9684
|
+
{
|
|
9685
|
+
"path": "lastFullRefreshAt",
|
|
9686
|
+
"valueType": "number"
|
|
9687
|
+
},
|
|
9688
|
+
{
|
|
9689
|
+
"path": "binary",
|
|
9690
|
+
"valueType": "boolean"
|
|
9691
|
+
}
|
|
9692
|
+
],
|
|
9693
|
+
"binary": [{
|
|
9694
|
+
"path": "on",
|
|
9695
|
+
"valueType": "boolean"
|
|
9696
|
+
}],
|
|
9697
|
+
"brightness": [{
|
|
9698
|
+
"path": "percentage",
|
|
9699
|
+
"valueType": "number"
|
|
9700
|
+
}],
|
|
9701
|
+
"broker": [{
|
|
9702
|
+
"path": "brokerCount",
|
|
9703
|
+
"valueType": "number"
|
|
9704
|
+
}, {
|
|
9705
|
+
"path": "connectedCount",
|
|
9706
|
+
"valueType": "number"
|
|
9707
|
+
}],
|
|
9708
|
+
"camera-credentials": [
|
|
9709
|
+
{
|
|
9710
|
+
"path": "host",
|
|
9711
|
+
"valueType": "string"
|
|
9712
|
+
},
|
|
9713
|
+
{
|
|
9714
|
+
"path": "port",
|
|
9715
|
+
"valueType": "number"
|
|
9716
|
+
},
|
|
9717
|
+
{
|
|
9718
|
+
"path": "onvifPort",
|
|
9719
|
+
"valueType": "number"
|
|
9720
|
+
},
|
|
9721
|
+
{
|
|
9722
|
+
"path": "rtspPort",
|
|
9723
|
+
"valueType": "number"
|
|
9724
|
+
},
|
|
9725
|
+
{
|
|
9726
|
+
"path": "https",
|
|
9727
|
+
"valueType": "boolean"
|
|
9728
|
+
},
|
|
9729
|
+
{
|
|
9730
|
+
"path": "hasUsername",
|
|
9731
|
+
"valueType": "boolean"
|
|
9732
|
+
},
|
|
9733
|
+
{
|
|
9734
|
+
"path": "hasPassword",
|
|
9735
|
+
"valueType": "boolean"
|
|
9736
|
+
},
|
|
9737
|
+
{
|
|
9738
|
+
"path": "onvifProfile",
|
|
9739
|
+
"valueType": "string"
|
|
9740
|
+
}
|
|
9741
|
+
],
|
|
9742
|
+
"camera-streams": [
|
|
9743
|
+
{
|
|
9744
|
+
"path": "online",
|
|
9745
|
+
"valueType": "boolean"
|
|
9746
|
+
},
|
|
9747
|
+
{
|
|
9748
|
+
"path": "slotStatuses.high",
|
|
9749
|
+
"valueType": "enum",
|
|
9750
|
+
"enumValues": [
|
|
9751
|
+
"unassigned",
|
|
9752
|
+
"idle",
|
|
9753
|
+
"connecting",
|
|
9754
|
+
"streaming",
|
|
9755
|
+
"error"
|
|
9756
|
+
]
|
|
9757
|
+
},
|
|
9758
|
+
{
|
|
9759
|
+
"path": "slotStatuses.mid",
|
|
9760
|
+
"valueType": "enum",
|
|
9761
|
+
"enumValues": [
|
|
9762
|
+
"unassigned",
|
|
9763
|
+
"idle",
|
|
9764
|
+
"connecting",
|
|
9765
|
+
"streaming",
|
|
9766
|
+
"error"
|
|
9767
|
+
]
|
|
9768
|
+
},
|
|
9769
|
+
{
|
|
9770
|
+
"path": "slotStatuses.low",
|
|
9771
|
+
"valueType": "enum",
|
|
9772
|
+
"enumValues": [
|
|
9773
|
+
"unassigned",
|
|
9774
|
+
"idle",
|
|
9775
|
+
"connecting",
|
|
9776
|
+
"streaming",
|
|
9777
|
+
"error"
|
|
9778
|
+
]
|
|
9779
|
+
},
|
|
9780
|
+
{
|
|
9781
|
+
"path": "slotErrors.high",
|
|
9782
|
+
"valueType": "string"
|
|
9783
|
+
},
|
|
9784
|
+
{
|
|
9785
|
+
"path": "slotErrors.mid",
|
|
9786
|
+
"valueType": "string"
|
|
9787
|
+
},
|
|
9788
|
+
{
|
|
9789
|
+
"path": "slotErrors.low",
|
|
9790
|
+
"valueType": "string"
|
|
9791
|
+
}
|
|
9792
|
+
],
|
|
9793
|
+
"carbon-monoxide": [{
|
|
9794
|
+
"path": "detected",
|
|
9795
|
+
"valueType": "boolean"
|
|
9796
|
+
}],
|
|
9797
|
+
"climate-control": [
|
|
9798
|
+
{
|
|
9799
|
+
"path": "mode",
|
|
9800
|
+
"valueType": "enum",
|
|
9801
|
+
"enumValues": [
|
|
9802
|
+
"off",
|
|
9803
|
+
"heat",
|
|
9804
|
+
"cool",
|
|
9805
|
+
"auto",
|
|
9806
|
+
"heat_cool",
|
|
9807
|
+
"fan_only",
|
|
9808
|
+
"dry"
|
|
9809
|
+
]
|
|
9810
|
+
},
|
|
9811
|
+
{
|
|
9812
|
+
"path": "fanMode",
|
|
9813
|
+
"valueType": "string"
|
|
9814
|
+
},
|
|
9815
|
+
{
|
|
9816
|
+
"path": "preset",
|
|
9817
|
+
"valueType": "string"
|
|
9818
|
+
},
|
|
9819
|
+
{
|
|
9820
|
+
"path": "target",
|
|
9821
|
+
"valueType": "number"
|
|
9822
|
+
},
|
|
9823
|
+
{
|
|
9824
|
+
"path": "targetHigh",
|
|
9825
|
+
"valueType": "number"
|
|
9826
|
+
},
|
|
9827
|
+
{
|
|
9828
|
+
"path": "targetLow",
|
|
9829
|
+
"valueType": "number"
|
|
9830
|
+
},
|
|
9831
|
+
{
|
|
9832
|
+
"path": "targetHumidity",
|
|
9833
|
+
"valueType": "number"
|
|
9834
|
+
},
|
|
9835
|
+
{
|
|
9836
|
+
"path": "currentTemp",
|
|
9837
|
+
"valueType": "number"
|
|
9838
|
+
},
|
|
9839
|
+
{
|
|
9840
|
+
"path": "currentHumidity",
|
|
9841
|
+
"valueType": "number"
|
|
9842
|
+
},
|
|
9843
|
+
{
|
|
9844
|
+
"path": "swingVertical",
|
|
9845
|
+
"valueType": "boolean"
|
|
9846
|
+
},
|
|
9847
|
+
{
|
|
9848
|
+
"path": "swingHorizontal",
|
|
9849
|
+
"valueType": "boolean"
|
|
9850
|
+
},
|
|
9851
|
+
{
|
|
9852
|
+
"path": "minTemp",
|
|
9853
|
+
"valueType": "number"
|
|
9854
|
+
},
|
|
9855
|
+
{
|
|
9856
|
+
"path": "maxTemp",
|
|
9857
|
+
"valueType": "number"
|
|
9858
|
+
},
|
|
9859
|
+
{
|
|
9860
|
+
"path": "tempStep",
|
|
9861
|
+
"valueType": "number"
|
|
9862
|
+
}
|
|
9863
|
+
],
|
|
9864
|
+
"color": [
|
|
9865
|
+
{
|
|
9866
|
+
"path": "mode",
|
|
9867
|
+
"valueType": "enum",
|
|
9868
|
+
"enumValues": [
|
|
9869
|
+
"rgb",
|
|
9870
|
+
"hsv",
|
|
9871
|
+
"mired"
|
|
9872
|
+
]
|
|
9873
|
+
},
|
|
9874
|
+
{
|
|
9875
|
+
"path": "rgb.r",
|
|
9876
|
+
"valueType": "number"
|
|
9877
|
+
},
|
|
9878
|
+
{
|
|
9879
|
+
"path": "rgb.g",
|
|
9880
|
+
"valueType": "number"
|
|
9881
|
+
},
|
|
9882
|
+
{
|
|
9883
|
+
"path": "rgb.b",
|
|
9884
|
+
"valueType": "number"
|
|
9885
|
+
},
|
|
9886
|
+
{
|
|
9887
|
+
"path": "hsv.h",
|
|
9888
|
+
"valueType": "number"
|
|
9889
|
+
},
|
|
9890
|
+
{
|
|
9891
|
+
"path": "hsv.s",
|
|
9892
|
+
"valueType": "number"
|
|
9893
|
+
},
|
|
9894
|
+
{
|
|
9895
|
+
"path": "hsv.v",
|
|
9896
|
+
"valueType": "number"
|
|
9897
|
+
},
|
|
9898
|
+
{
|
|
9899
|
+
"path": "mireds",
|
|
9900
|
+
"valueType": "number"
|
|
9901
|
+
}
|
|
9902
|
+
],
|
|
9903
|
+
"connectivity": [{
|
|
9904
|
+
"path": "connected",
|
|
9905
|
+
"valueType": "boolean"
|
|
9906
|
+
}],
|
|
9907
|
+
"contact": [{
|
|
9908
|
+
"path": "entryOpen",
|
|
9909
|
+
"valueType": "boolean"
|
|
9910
|
+
}],
|
|
9911
|
+
"control": [
|
|
9912
|
+
{
|
|
9913
|
+
"path": "kind",
|
|
9914
|
+
"valueType": "enum",
|
|
9915
|
+
"enumValues": [
|
|
9916
|
+
"numeric",
|
|
9917
|
+
"select",
|
|
9918
|
+
"text",
|
|
9919
|
+
"datetime"
|
|
9920
|
+
]
|
|
9921
|
+
},
|
|
9922
|
+
{
|
|
9923
|
+
"path": "unit",
|
|
9924
|
+
"valueType": "string"
|
|
9925
|
+
},
|
|
9926
|
+
{
|
|
9927
|
+
"path": "min",
|
|
9928
|
+
"valueType": "number"
|
|
9929
|
+
},
|
|
9930
|
+
{
|
|
9931
|
+
"path": "max",
|
|
9932
|
+
"valueType": "number"
|
|
9933
|
+
},
|
|
9934
|
+
{
|
|
9935
|
+
"path": "step",
|
|
9936
|
+
"valueType": "number"
|
|
9937
|
+
},
|
|
9938
|
+
{
|
|
9939
|
+
"path": "precision",
|
|
9940
|
+
"valueType": "number"
|
|
9941
|
+
},
|
|
9942
|
+
{
|
|
9943
|
+
"path": "format",
|
|
9944
|
+
"valueType": "enum",
|
|
9945
|
+
"enumValues": [
|
|
9946
|
+
"date",
|
|
9947
|
+
"time",
|
|
9948
|
+
"datetime"
|
|
9949
|
+
]
|
|
9950
|
+
}
|
|
9951
|
+
],
|
|
9952
|
+
"cover": [
|
|
9953
|
+
{
|
|
9954
|
+
"path": "state",
|
|
9955
|
+
"valueType": "enum",
|
|
9956
|
+
"enumValues": [
|
|
9957
|
+
"open",
|
|
9958
|
+
"opening",
|
|
9959
|
+
"closing",
|
|
9960
|
+
"closed",
|
|
9961
|
+
"stopped"
|
|
9962
|
+
]
|
|
9963
|
+
},
|
|
9964
|
+
{
|
|
9965
|
+
"path": "position",
|
|
9966
|
+
"valueType": "number"
|
|
9967
|
+
},
|
|
9968
|
+
{
|
|
9969
|
+
"path": "tiltPosition",
|
|
9970
|
+
"valueType": "number"
|
|
9971
|
+
}
|
|
9972
|
+
],
|
|
9973
|
+
"day-night": [
|
|
9974
|
+
{
|
|
9975
|
+
"path": "mode",
|
|
9976
|
+
"valueType": "enum",
|
|
9977
|
+
"enumValues": [
|
|
9978
|
+
"auto",
|
|
9979
|
+
"day",
|
|
9980
|
+
"night",
|
|
9981
|
+
"schedule"
|
|
9982
|
+
]
|
|
9983
|
+
},
|
|
9984
|
+
{
|
|
9985
|
+
"path": "sensitivity",
|
|
9986
|
+
"valueType": "number"
|
|
9987
|
+
},
|
|
9988
|
+
{
|
|
9989
|
+
"path": "switchDelaySec",
|
|
9990
|
+
"valueType": "number"
|
|
9991
|
+
}
|
|
9992
|
+
],
|
|
9993
|
+
"device-adoption": [
|
|
9994
|
+
{
|
|
9995
|
+
"path": "lastDiscoveryAt",
|
|
9996
|
+
"valueType": "number"
|
|
9997
|
+
},
|
|
9998
|
+
{
|
|
9999
|
+
"path": "candidateCount",
|
|
10000
|
+
"valueType": "number"
|
|
10001
|
+
},
|
|
10002
|
+
{
|
|
10003
|
+
"path": "adoptedCount",
|
|
10004
|
+
"valueType": "number"
|
|
10005
|
+
},
|
|
10006
|
+
{
|
|
10007
|
+
"path": "lastError",
|
|
10008
|
+
"valueType": "string"
|
|
10009
|
+
}
|
|
10010
|
+
],
|
|
10011
|
+
"device-discovery": [{
|
|
10012
|
+
"path": "lastDiscoveryAt",
|
|
10013
|
+
"valueType": "number"
|
|
10014
|
+
}, {
|
|
10015
|
+
"path": "lastError",
|
|
10016
|
+
"valueType": "string"
|
|
10017
|
+
}],
|
|
10018
|
+
"device-export": [
|
|
10019
|
+
{
|
|
10020
|
+
"path": "linkState",
|
|
10021
|
+
"valueType": "enum",
|
|
10022
|
+
"enumValues": [
|
|
10023
|
+
"unlinked",
|
|
10024
|
+
"linked",
|
|
10025
|
+
"error"
|
|
10026
|
+
]
|
|
10027
|
+
},
|
|
10028
|
+
{
|
|
10029
|
+
"path": "exposedDeviceCount",
|
|
10030
|
+
"valueType": "number"
|
|
10031
|
+
},
|
|
10032
|
+
{
|
|
10033
|
+
"path": "error",
|
|
10034
|
+
"valueType": "string"
|
|
10035
|
+
},
|
|
10036
|
+
{
|
|
10037
|
+
"path": "setup.qr",
|
|
10038
|
+
"valueType": "string"
|
|
10039
|
+
},
|
|
10040
|
+
{
|
|
10041
|
+
"path": "setup.note",
|
|
10042
|
+
"valueType": "string"
|
|
10043
|
+
}
|
|
10044
|
+
],
|
|
10045
|
+
"device-status": [{
|
|
10046
|
+
"path": "online",
|
|
10047
|
+
"valueType": "boolean"
|
|
10048
|
+
}],
|
|
10049
|
+
"dishwasher": [
|
|
10050
|
+
{
|
|
10051
|
+
"path": "availability",
|
|
10052
|
+
"valueType": "enum",
|
|
10053
|
+
"enumValues": [
|
|
10054
|
+
"available",
|
|
10055
|
+
"offline",
|
|
10056
|
+
"description-missing"
|
|
10057
|
+
]
|
|
10058
|
+
},
|
|
10059
|
+
{
|
|
10060
|
+
"path": "state",
|
|
10061
|
+
"valueType": "enum",
|
|
10062
|
+
"enumValues": [
|
|
10063
|
+
"idle",
|
|
10064
|
+
"running",
|
|
10065
|
+
"paused",
|
|
10066
|
+
"finished",
|
|
10067
|
+
"error",
|
|
10068
|
+
"unavailable"
|
|
10069
|
+
]
|
|
10070
|
+
},
|
|
10071
|
+
{
|
|
10072
|
+
"path": "operationState",
|
|
10073
|
+
"valueType": "enum",
|
|
10074
|
+
"enumValues": [
|
|
10075
|
+
"Inactive",
|
|
10076
|
+
"Ready",
|
|
10077
|
+
"DelayedStart",
|
|
10078
|
+
"Run",
|
|
10079
|
+
"Pause",
|
|
10080
|
+
"ActionRequired",
|
|
10081
|
+
"Finished",
|
|
10082
|
+
"Error",
|
|
10083
|
+
"Aborting"
|
|
10084
|
+
]
|
|
10085
|
+
},
|
|
10086
|
+
{
|
|
10087
|
+
"path": "program",
|
|
10088
|
+
"valueType": "string"
|
|
10089
|
+
},
|
|
10090
|
+
{
|
|
10091
|
+
"path": "selectedProgram",
|
|
10092
|
+
"valueType": "string"
|
|
10093
|
+
},
|
|
10094
|
+
{
|
|
10095
|
+
"path": "remainingSeconds",
|
|
10096
|
+
"valueType": "number"
|
|
10097
|
+
},
|
|
10098
|
+
{
|
|
10099
|
+
"path": "delayedStartSeconds",
|
|
10100
|
+
"valueType": "number"
|
|
10101
|
+
},
|
|
10102
|
+
{
|
|
10103
|
+
"path": "progressPercent",
|
|
10104
|
+
"valueType": "number"
|
|
10105
|
+
},
|
|
10106
|
+
{
|
|
10107
|
+
"path": "doorOpen",
|
|
10108
|
+
"valueType": "boolean"
|
|
10109
|
+
},
|
|
10110
|
+
{
|
|
10111
|
+
"path": "doorLocked",
|
|
10112
|
+
"valueType": "boolean"
|
|
10113
|
+
},
|
|
10114
|
+
{
|
|
10115
|
+
"path": "remoteStartAllowed",
|
|
10116
|
+
"valueType": "boolean"
|
|
10117
|
+
},
|
|
10118
|
+
{
|
|
10119
|
+
"path": "remoteControlActive",
|
|
10120
|
+
"valueType": "boolean"
|
|
10121
|
+
},
|
|
10122
|
+
{
|
|
10123
|
+
"path": "localControlActive",
|
|
10124
|
+
"valueType": "boolean"
|
|
10125
|
+
},
|
|
10126
|
+
{
|
|
10127
|
+
"path": "powerOn",
|
|
10128
|
+
"valueType": "boolean"
|
|
10129
|
+
},
|
|
10130
|
+
{
|
|
10131
|
+
"path": "powerState",
|
|
10132
|
+
"valueType": "string"
|
|
10133
|
+
},
|
|
10134
|
+
{
|
|
10135
|
+
"path": "filterCleaningDue",
|
|
10136
|
+
"valueType": "boolean"
|
|
10137
|
+
},
|
|
10138
|
+
{
|
|
10139
|
+
"path": "machineCareDue",
|
|
10140
|
+
"valueType": "boolean"
|
|
10141
|
+
},
|
|
10142
|
+
{
|
|
10143
|
+
"path": "machineCareRemainingRuns",
|
|
10144
|
+
"valueType": "number"
|
|
10145
|
+
},
|
|
10146
|
+
{
|
|
10147
|
+
"path": "halfLoad",
|
|
10148
|
+
"valueType": "boolean"
|
|
10149
|
+
},
|
|
10150
|
+
{
|
|
10151
|
+
"path": "hygienePlus",
|
|
10152
|
+
"valueType": "boolean"
|
|
10153
|
+
},
|
|
10154
|
+
{
|
|
10155
|
+
"path": "extraDry",
|
|
10156
|
+
"valueType": "boolean"
|
|
10157
|
+
},
|
|
10158
|
+
{
|
|
10159
|
+
"path": "intensiveZone",
|
|
10160
|
+
"valueType": "boolean"
|
|
10161
|
+
},
|
|
10162
|
+
{
|
|
10163
|
+
"path": "varioSpeedPlus",
|
|
10164
|
+
"valueType": "boolean"
|
|
10165
|
+
},
|
|
10166
|
+
{
|
|
10167
|
+
"path": "childLock",
|
|
10168
|
+
"valueType": "boolean"
|
|
10169
|
+
},
|
|
10170
|
+
{
|
|
10171
|
+
"path": "errorCode",
|
|
10172
|
+
"valueType": "number"
|
|
10173
|
+
},
|
|
10174
|
+
{
|
|
10175
|
+
"path": "errorLabel",
|
|
10176
|
+
"valueType": "string"
|
|
10177
|
+
}
|
|
10178
|
+
],
|
|
10179
|
+
"doorbell": [{
|
|
10180
|
+
"path": "lastPressedAt",
|
|
10181
|
+
"valueType": "number"
|
|
10182
|
+
}, {
|
|
10183
|
+
"path": "pressCountSinceStart",
|
|
10184
|
+
"valueType": "number"
|
|
10185
|
+
}],
|
|
10186
|
+
"enum-sensor": [{
|
|
10187
|
+
"path": "value",
|
|
10188
|
+
"valueType": "string"
|
|
10189
|
+
}, {
|
|
10190
|
+
"path": "format",
|
|
10191
|
+
"valueType": "enum",
|
|
10192
|
+
"enumValues": [
|
|
10193
|
+
"date",
|
|
10194
|
+
"time",
|
|
10195
|
+
"datetime"
|
|
10196
|
+
]
|
|
10197
|
+
}],
|
|
10198
|
+
"event-emitter": [
|
|
10199
|
+
{
|
|
10200
|
+
"path": "lastEvent.deviceId",
|
|
10201
|
+
"valueType": "number"
|
|
10202
|
+
},
|
|
10203
|
+
{
|
|
10204
|
+
"path": "lastEvent.eventType",
|
|
10205
|
+
"valueType": "string"
|
|
10206
|
+
},
|
|
10207
|
+
{
|
|
10208
|
+
"path": "lastEvent.timestamp",
|
|
10209
|
+
"valueType": "number"
|
|
10210
|
+
},
|
|
10211
|
+
{
|
|
10212
|
+
"path": "lastEvent.seq",
|
|
10213
|
+
"valueType": "number"
|
|
10214
|
+
},
|
|
10215
|
+
{
|
|
10216
|
+
"path": "eventCountSinceStart",
|
|
10217
|
+
"valueType": "number"
|
|
10218
|
+
}
|
|
10219
|
+
],
|
|
10220
|
+
"fan-control": [
|
|
10221
|
+
{
|
|
10222
|
+
"path": "percentage",
|
|
10223
|
+
"valueType": "number"
|
|
10224
|
+
},
|
|
10225
|
+
{
|
|
10226
|
+
"path": "percentageStep",
|
|
10227
|
+
"valueType": "number"
|
|
10228
|
+
},
|
|
10229
|
+
{
|
|
10230
|
+
"path": "preset",
|
|
10231
|
+
"valueType": "string"
|
|
10232
|
+
},
|
|
10233
|
+
{
|
|
10234
|
+
"path": "direction",
|
|
10235
|
+
"valueType": "enum",
|
|
10236
|
+
"enumValues": ["forward", "reverse"]
|
|
10237
|
+
},
|
|
10238
|
+
{
|
|
10239
|
+
"path": "oscillating",
|
|
10240
|
+
"valueType": "boolean"
|
|
10241
|
+
}
|
|
10242
|
+
],
|
|
10243
|
+
"feature-probe": [
|
|
10244
|
+
{
|
|
10245
|
+
"path": "deviceType",
|
|
10246
|
+
"valueType": "string"
|
|
10247
|
+
},
|
|
10248
|
+
{
|
|
10249
|
+
"path": "model",
|
|
10250
|
+
"valueType": "string"
|
|
10251
|
+
},
|
|
10252
|
+
{
|
|
10253
|
+
"path": "channelCount",
|
|
10254
|
+
"valueType": "number"
|
|
10255
|
+
},
|
|
10256
|
+
{
|
|
10257
|
+
"path": "lastProbedAt",
|
|
10258
|
+
"valueType": "number"
|
|
10259
|
+
}
|
|
10260
|
+
],
|
|
10261
|
+
"flood": [{
|
|
10262
|
+
"path": "flooded",
|
|
10263
|
+
"valueType": "boolean"
|
|
10264
|
+
}],
|
|
10265
|
+
"gas": [{
|
|
10266
|
+
"path": "detected",
|
|
10267
|
+
"valueType": "boolean"
|
|
10268
|
+
}],
|
|
10269
|
+
"heating-valve": [{
|
|
10270
|
+
"path": "position",
|
|
10271
|
+
"valueType": "number"
|
|
10272
|
+
}],
|
|
10273
|
+
"humidifier": [
|
|
10274
|
+
{
|
|
10275
|
+
"path": "on",
|
|
10276
|
+
"valueType": "boolean"
|
|
10277
|
+
},
|
|
10278
|
+
{
|
|
10279
|
+
"path": "currentHumidity",
|
|
10280
|
+
"valueType": "number"
|
|
10281
|
+
},
|
|
10282
|
+
{
|
|
10283
|
+
"path": "targetHumidity",
|
|
10284
|
+
"valueType": "number"
|
|
10285
|
+
},
|
|
10286
|
+
{
|
|
10287
|
+
"path": "mode",
|
|
10288
|
+
"valueType": "string"
|
|
10289
|
+
},
|
|
10290
|
+
{
|
|
10291
|
+
"path": "action",
|
|
10292
|
+
"valueType": "string"
|
|
10293
|
+
},
|
|
10294
|
+
{
|
|
10295
|
+
"path": "minHumidity",
|
|
10296
|
+
"valueType": "number"
|
|
10297
|
+
},
|
|
10298
|
+
{
|
|
10299
|
+
"path": "maxHumidity",
|
|
10300
|
+
"valueType": "number"
|
|
10301
|
+
}
|
|
10302
|
+
],
|
|
10303
|
+
"humidity-sensor": [
|
|
10304
|
+
{
|
|
10305
|
+
"path": "percent",
|
|
10306
|
+
"valueType": "number"
|
|
10307
|
+
},
|
|
10308
|
+
{
|
|
10309
|
+
"path": "unit",
|
|
10310
|
+
"valueType": "string"
|
|
10311
|
+
},
|
|
10312
|
+
{
|
|
10313
|
+
"path": "precision",
|
|
10314
|
+
"valueType": "number"
|
|
10315
|
+
}
|
|
10316
|
+
],
|
|
10317
|
+
"image": [{
|
|
10318
|
+
"path": "url",
|
|
10319
|
+
"valueType": "string"
|
|
10320
|
+
}, {
|
|
10321
|
+
"path": "lastUpdated",
|
|
10322
|
+
"valueType": "number"
|
|
10323
|
+
}],
|
|
10324
|
+
"image-settings": [
|
|
10325
|
+
{
|
|
10326
|
+
"path": "brightness",
|
|
10327
|
+
"valueType": "number"
|
|
10328
|
+
},
|
|
10329
|
+
{
|
|
10330
|
+
"path": "contrast",
|
|
10331
|
+
"valueType": "number"
|
|
10332
|
+
},
|
|
10333
|
+
{
|
|
10334
|
+
"path": "saturation",
|
|
10335
|
+
"valueType": "number"
|
|
10336
|
+
},
|
|
10337
|
+
{
|
|
10338
|
+
"path": "sharpness",
|
|
10339
|
+
"valueType": "number"
|
|
10340
|
+
},
|
|
10341
|
+
{
|
|
10342
|
+
"path": "mirror",
|
|
10343
|
+
"valueType": "boolean"
|
|
10344
|
+
},
|
|
10345
|
+
{
|
|
10346
|
+
"path": "flip",
|
|
10347
|
+
"valueType": "boolean"
|
|
10348
|
+
},
|
|
10349
|
+
{
|
|
10350
|
+
"path": "rotate",
|
|
10351
|
+
"valueType": "enum",
|
|
10352
|
+
"enumValues": [
|
|
10353
|
+
"0",
|
|
10354
|
+
"90",
|
|
10355
|
+
"180",
|
|
10356
|
+
"270"
|
|
10357
|
+
]
|
|
10358
|
+
},
|
|
10359
|
+
{
|
|
10360
|
+
"path": "whiteBalance",
|
|
10361
|
+
"valueType": "enum",
|
|
10362
|
+
"enumValues": ["auto", "manual"]
|
|
10363
|
+
},
|
|
10364
|
+
{
|
|
10365
|
+
"path": "warmth",
|
|
10366
|
+
"valueType": "number"
|
|
10367
|
+
},
|
|
10368
|
+
{
|
|
10369
|
+
"path": "exposureMode",
|
|
10370
|
+
"valueType": "enum",
|
|
10371
|
+
"enumValues": ["auto", "manual"]
|
|
10372
|
+
},
|
|
10373
|
+
{
|
|
10374
|
+
"path": "backlightMode",
|
|
10375
|
+
"valueType": "enum",
|
|
10376
|
+
"enumValues": [
|
|
10377
|
+
"off",
|
|
10378
|
+
"blc",
|
|
10379
|
+
"wdr",
|
|
10380
|
+
"hlc"
|
|
10381
|
+
]
|
|
10382
|
+
}
|
|
10383
|
+
],
|
|
10384
|
+
"intercom": [
|
|
10385
|
+
{
|
|
10386
|
+
"path": "talking",
|
|
10387
|
+
"valueType": "boolean"
|
|
10388
|
+
},
|
|
10389
|
+
{
|
|
10390
|
+
"path": "lastSessionAt",
|
|
10391
|
+
"valueType": "number"
|
|
10392
|
+
},
|
|
10393
|
+
{
|
|
10394
|
+
"path": "ability.sampleRate",
|
|
10395
|
+
"valueType": "number"
|
|
10396
|
+
},
|
|
10397
|
+
{
|
|
10398
|
+
"path": "ability.duplex",
|
|
10399
|
+
"valueType": "enum",
|
|
10400
|
+
"enumValues": ["half", "full"]
|
|
10401
|
+
},
|
|
10402
|
+
{
|
|
10403
|
+
"path": "ability.maxBacklogMs",
|
|
10404
|
+
"valueType": "number"
|
|
10405
|
+
}
|
|
10406
|
+
],
|
|
10407
|
+
"lawn-mower-control": [
|
|
10408
|
+
{
|
|
10409
|
+
"path": "activity",
|
|
10410
|
+
"valueType": "enum",
|
|
10411
|
+
"enumValues": [
|
|
10412
|
+
"idle",
|
|
10413
|
+
"mowing",
|
|
10414
|
+
"paused",
|
|
10415
|
+
"docked",
|
|
10416
|
+
"error"
|
|
10417
|
+
]
|
|
10418
|
+
},
|
|
10419
|
+
{
|
|
10420
|
+
"path": "batteryLevel",
|
|
10421
|
+
"valueType": "number"
|
|
10422
|
+
},
|
|
10423
|
+
{
|
|
10424
|
+
"path": "progressPercent",
|
|
10425
|
+
"valueType": "number"
|
|
10426
|
+
},
|
|
10427
|
+
{
|
|
10428
|
+
"path": "currentCode",
|
|
10429
|
+
"valueType": "number"
|
|
10430
|
+
},
|
|
10431
|
+
{
|
|
10432
|
+
"path": "currentCodeLabel",
|
|
10433
|
+
"valueType": "string"
|
|
10434
|
+
},
|
|
10435
|
+
{
|
|
10436
|
+
"path": "severity",
|
|
10437
|
+
"valueType": "enum",
|
|
10438
|
+
"enumValues": [
|
|
10439
|
+
"info",
|
|
10440
|
+
"warning",
|
|
10441
|
+
"error"
|
|
10442
|
+
]
|
|
10443
|
+
}
|
|
10444
|
+
],
|
|
10445
|
+
"lock-control": [{
|
|
10446
|
+
"path": "state",
|
|
10447
|
+
"valueType": "enum",
|
|
10448
|
+
"enumValues": [
|
|
10449
|
+
"locked",
|
|
10450
|
+
"unlocked",
|
|
10451
|
+
"locking",
|
|
10452
|
+
"unlocking",
|
|
10453
|
+
"jammed"
|
|
10454
|
+
]
|
|
10455
|
+
}],
|
|
10456
|
+
"media-player": [
|
|
10457
|
+
{
|
|
10458
|
+
"path": "state",
|
|
10459
|
+
"valueType": "enum",
|
|
10460
|
+
"enumValues": [
|
|
10461
|
+
"off",
|
|
10462
|
+
"on",
|
|
10463
|
+
"idle",
|
|
10464
|
+
"playing",
|
|
10465
|
+
"paused",
|
|
10466
|
+
"buffering",
|
|
10467
|
+
"standby"
|
|
10468
|
+
]
|
|
10469
|
+
},
|
|
10470
|
+
{
|
|
10471
|
+
"path": "volumeLevel",
|
|
10472
|
+
"valueType": "number"
|
|
10473
|
+
},
|
|
10474
|
+
{
|
|
10475
|
+
"path": "isMuted",
|
|
10476
|
+
"valueType": "boolean"
|
|
10477
|
+
},
|
|
10478
|
+
{
|
|
10479
|
+
"path": "source",
|
|
10480
|
+
"valueType": "string"
|
|
10481
|
+
},
|
|
10482
|
+
{
|
|
10483
|
+
"path": "currentMedia.type",
|
|
10484
|
+
"valueType": "string"
|
|
10485
|
+
},
|
|
10486
|
+
{
|
|
10487
|
+
"path": "currentMedia.title",
|
|
10488
|
+
"valueType": "string"
|
|
10489
|
+
},
|
|
10490
|
+
{
|
|
10491
|
+
"path": "currentMedia.artist",
|
|
10492
|
+
"valueType": "string"
|
|
10493
|
+
},
|
|
10494
|
+
{
|
|
10495
|
+
"path": "currentMedia.album",
|
|
10496
|
+
"valueType": "string"
|
|
10497
|
+
},
|
|
10498
|
+
{
|
|
10499
|
+
"path": "currentMedia.imageUrl",
|
|
10500
|
+
"valueType": "string"
|
|
10501
|
+
},
|
|
10502
|
+
{
|
|
10503
|
+
"path": "positionMs",
|
|
10504
|
+
"valueType": "number"
|
|
10505
|
+
},
|
|
10506
|
+
{
|
|
10507
|
+
"path": "durationMs",
|
|
10508
|
+
"valueType": "number"
|
|
10509
|
+
},
|
|
10510
|
+
{
|
|
10511
|
+
"path": "shuffle",
|
|
10512
|
+
"valueType": "boolean"
|
|
10513
|
+
},
|
|
10514
|
+
{
|
|
10515
|
+
"path": "repeat",
|
|
10516
|
+
"valueType": "enum",
|
|
10517
|
+
"enumValues": [
|
|
10518
|
+
"off",
|
|
10519
|
+
"all",
|
|
10520
|
+
"one"
|
|
10521
|
+
]
|
|
10522
|
+
}
|
|
10523
|
+
],
|
|
10524
|
+
"motion": [
|
|
10525
|
+
{
|
|
10526
|
+
"path": "detected",
|
|
10527
|
+
"valueType": "boolean"
|
|
10528
|
+
},
|
|
10529
|
+
{
|
|
10530
|
+
"path": "lastDetectedAt",
|
|
10531
|
+
"valueType": "number"
|
|
10532
|
+
},
|
|
10533
|
+
{
|
|
10534
|
+
"path": "autoClearAfterMs",
|
|
10535
|
+
"valueType": "number"
|
|
10536
|
+
}
|
|
10537
|
+
],
|
|
10538
|
+
"motion-trigger": [{
|
|
10539
|
+
"path": "enabled",
|
|
10540
|
+
"valueType": "boolean"
|
|
10541
|
+
}],
|
|
10542
|
+
"motion-zones": [{
|
|
10543
|
+
"path": "enabled",
|
|
10544
|
+
"valueType": "boolean"
|
|
10545
|
+
}, {
|
|
10546
|
+
"path": "sensitivity",
|
|
10547
|
+
"valueType": "number"
|
|
10548
|
+
}],
|
|
10549
|
+
"mqtt-broker": [{
|
|
10550
|
+
"path": "brokerCount",
|
|
10551
|
+
"valueType": "number"
|
|
10552
|
+
}, {
|
|
10553
|
+
"path": "embeddedRunning",
|
|
10554
|
+
"valueType": "boolean"
|
|
10555
|
+
}],
|
|
10556
|
+
"native-object-detection": [{
|
|
10557
|
+
"path": "enabled",
|
|
10558
|
+
"valueType": "boolean"
|
|
10559
|
+
}],
|
|
10560
|
+
"navigation": [
|
|
10561
|
+
{
|
|
10562
|
+
"path": "mode",
|
|
10563
|
+
"valueType": "enum",
|
|
10564
|
+
"enumValues": [
|
|
10565
|
+
"idle",
|
|
10566
|
+
"cleaning",
|
|
10567
|
+
"spot",
|
|
10568
|
+
"following",
|
|
10569
|
+
"goto",
|
|
10570
|
+
"returning",
|
|
10571
|
+
"paused",
|
|
10572
|
+
"unknown"
|
|
10573
|
+
]
|
|
10574
|
+
},
|
|
10575
|
+
{
|
|
10576
|
+
"path": "following",
|
|
10577
|
+
"valueType": "boolean"
|
|
10578
|
+
},
|
|
10579
|
+
{
|
|
10580
|
+
"path": "flash",
|
|
10581
|
+
"valueType": "boolean"
|
|
10582
|
+
},
|
|
10583
|
+
{
|
|
10584
|
+
"path": "lightMode",
|
|
10585
|
+
"valueType": "enum",
|
|
10586
|
+
"enumValues": ["auto", "manual"]
|
|
10587
|
+
},
|
|
10588
|
+
{
|
|
10589
|
+
"path": "lightLevel",
|
|
10590
|
+
"valueType": "number"
|
|
10591
|
+
}
|
|
10592
|
+
],
|
|
10593
|
+
"network-link": [
|
|
10594
|
+
{
|
|
10595
|
+
"path": "type",
|
|
10596
|
+
"valueType": "enum",
|
|
10597
|
+
"enumValues": [
|
|
10598
|
+
"wifi",
|
|
10599
|
+
"ethernet",
|
|
10600
|
+
"cellular",
|
|
10601
|
+
"unknown"
|
|
10602
|
+
]
|
|
10603
|
+
},
|
|
10604
|
+
{
|
|
10605
|
+
"path": "signalPercent",
|
|
10606
|
+
"valueType": "number"
|
|
10607
|
+
},
|
|
10608
|
+
{
|
|
10609
|
+
"path": "rssiDbm",
|
|
10610
|
+
"valueType": "number"
|
|
10611
|
+
},
|
|
10612
|
+
{
|
|
10613
|
+
"path": "ssid",
|
|
10614
|
+
"valueType": "string"
|
|
10615
|
+
},
|
|
10616
|
+
{
|
|
10617
|
+
"path": "lastUpdated",
|
|
10618
|
+
"valueType": "number"
|
|
10619
|
+
}
|
|
10620
|
+
],
|
|
10621
|
+
"notifier": [
|
|
10622
|
+
{
|
|
10623
|
+
"path": "lastSentAt",
|
|
10624
|
+
"valueType": "number"
|
|
10625
|
+
},
|
|
10626
|
+
{
|
|
10627
|
+
"path": "lastError",
|
|
10628
|
+
"valueType": "string"
|
|
10629
|
+
},
|
|
10630
|
+
{
|
|
10631
|
+
"path": "queueDepth",
|
|
10632
|
+
"valueType": "number"
|
|
10633
|
+
},
|
|
10634
|
+
{
|
|
10635
|
+
"path": "supports.image",
|
|
10636
|
+
"valueType": "boolean"
|
|
10637
|
+
},
|
|
10638
|
+
{
|
|
10639
|
+
"path": "supports.priority",
|
|
10640
|
+
"valueType": "boolean"
|
|
10641
|
+
},
|
|
10642
|
+
{
|
|
10643
|
+
"path": "supports.data",
|
|
10644
|
+
"valueType": "boolean"
|
|
10645
|
+
},
|
|
10646
|
+
{
|
|
10647
|
+
"path": "supports.actions",
|
|
10648
|
+
"valueType": "boolean"
|
|
10649
|
+
},
|
|
10650
|
+
{
|
|
10651
|
+
"path": "supports.recipients",
|
|
10652
|
+
"valueType": "boolean"
|
|
10653
|
+
}
|
|
10654
|
+
],
|
|
10655
|
+
"numeric-sensor": [
|
|
10656
|
+
{
|
|
10657
|
+
"path": "value",
|
|
10658
|
+
"valueType": "number"
|
|
10659
|
+
},
|
|
10660
|
+
{
|
|
10661
|
+
"path": "unit",
|
|
10662
|
+
"valueType": "string"
|
|
10663
|
+
},
|
|
10664
|
+
{
|
|
10665
|
+
"path": "precision",
|
|
10666
|
+
"valueType": "number"
|
|
10667
|
+
}
|
|
10668
|
+
],
|
|
10669
|
+
"pet-feeder": [
|
|
10670
|
+
{
|
|
10671
|
+
"path": "foodLevel",
|
|
10672
|
+
"valueType": "number"
|
|
10673
|
+
},
|
|
10674
|
+
{
|
|
10675
|
+
"path": "food1",
|
|
10676
|
+
"valueType": "number"
|
|
10677
|
+
},
|
|
10678
|
+
{
|
|
10679
|
+
"path": "food2",
|
|
10680
|
+
"valueType": "number"
|
|
10681
|
+
},
|
|
10682
|
+
{
|
|
10683
|
+
"path": "lowFood",
|
|
10684
|
+
"valueType": "boolean"
|
|
10685
|
+
},
|
|
10686
|
+
{
|
|
10687
|
+
"path": "batteryPower",
|
|
10688
|
+
"valueType": "number"
|
|
10689
|
+
},
|
|
10690
|
+
{
|
|
10691
|
+
"path": "desiccantLeftDays",
|
|
10692
|
+
"valueType": "number"
|
|
10693
|
+
},
|
|
10694
|
+
{
|
|
10695
|
+
"path": "feeding",
|
|
10696
|
+
"valueType": "boolean"
|
|
10697
|
+
},
|
|
10698
|
+
{
|
|
10699
|
+
"path": "status",
|
|
10700
|
+
"valueType": "enum",
|
|
10701
|
+
"enumValues": [
|
|
10702
|
+
"normal",
|
|
10703
|
+
"offline",
|
|
10704
|
+
"on_batteries"
|
|
10705
|
+
]
|
|
10706
|
+
},
|
|
10707
|
+
{
|
|
10708
|
+
"path": "error",
|
|
10709
|
+
"valueType": "string"
|
|
10710
|
+
},
|
|
10711
|
+
{
|
|
10712
|
+
"path": "errorCode",
|
|
10713
|
+
"valueType": "number"
|
|
10714
|
+
},
|
|
10715
|
+
{
|
|
10716
|
+
"path": "isDualHopper",
|
|
10717
|
+
"valueType": "boolean"
|
|
10718
|
+
},
|
|
10719
|
+
{
|
|
10720
|
+
"path": "childLock",
|
|
10721
|
+
"valueType": "boolean"
|
|
10722
|
+
},
|
|
10723
|
+
{
|
|
10724
|
+
"path": "indicatorLight",
|
|
10725
|
+
"valueType": "boolean"
|
|
10726
|
+
},
|
|
10727
|
+
{
|
|
10728
|
+
"path": "feedSound",
|
|
10729
|
+
"valueType": "boolean"
|
|
10730
|
+
},
|
|
10731
|
+
{
|
|
10732
|
+
"path": "volume",
|
|
10733
|
+
"valueType": "number"
|
|
10734
|
+
}
|
|
10735
|
+
],
|
|
10736
|
+
"power-meter": [
|
|
10737
|
+
{
|
|
10738
|
+
"path": "watts",
|
|
10739
|
+
"valueType": "number"
|
|
10740
|
+
},
|
|
10741
|
+
{
|
|
10742
|
+
"path": "kwhTotal",
|
|
10743
|
+
"valueType": "number"
|
|
10744
|
+
},
|
|
10745
|
+
{
|
|
10746
|
+
"path": "volts",
|
|
10747
|
+
"valueType": "number"
|
|
10748
|
+
},
|
|
10749
|
+
{
|
|
10750
|
+
"path": "amps",
|
|
10751
|
+
"valueType": "number"
|
|
10752
|
+
},
|
|
10753
|
+
{
|
|
10754
|
+
"path": "va",
|
|
10755
|
+
"valueType": "number"
|
|
10756
|
+
},
|
|
10757
|
+
{
|
|
10758
|
+
"path": "powerFactor",
|
|
10759
|
+
"valueType": "number"
|
|
10760
|
+
},
|
|
10761
|
+
{
|
|
10762
|
+
"path": "unit",
|
|
10763
|
+
"valueType": "string"
|
|
10764
|
+
},
|
|
10765
|
+
{
|
|
10766
|
+
"path": "precision",
|
|
10767
|
+
"valueType": "number"
|
|
10768
|
+
}
|
|
10769
|
+
],
|
|
10770
|
+
"presence": [
|
|
10771
|
+
{
|
|
10772
|
+
"path": "state",
|
|
10773
|
+
"valueType": "string"
|
|
10774
|
+
},
|
|
10775
|
+
{
|
|
10776
|
+
"path": "location",
|
|
10777
|
+
"valueType": "string"
|
|
10778
|
+
},
|
|
10779
|
+
{
|
|
10780
|
+
"path": "gps.latitude",
|
|
10781
|
+
"valueType": "number"
|
|
10782
|
+
},
|
|
10783
|
+
{
|
|
10784
|
+
"path": "gps.longitude",
|
|
10785
|
+
"valueType": "number"
|
|
10786
|
+
},
|
|
10787
|
+
{
|
|
10788
|
+
"path": "gps.accuracyMeters",
|
|
10789
|
+
"valueType": "number"
|
|
10790
|
+
},
|
|
10791
|
+
{
|
|
10792
|
+
"path": "batteryPercent",
|
|
10793
|
+
"valueType": "number"
|
|
10794
|
+
}
|
|
10795
|
+
],
|
|
10796
|
+
"pressure-sensor": [
|
|
10797
|
+
{
|
|
10798
|
+
"path": "hpa",
|
|
10799
|
+
"valueType": "number"
|
|
10800
|
+
},
|
|
10801
|
+
{
|
|
10802
|
+
"path": "unit",
|
|
10803
|
+
"valueType": "string"
|
|
10804
|
+
},
|
|
10805
|
+
{
|
|
10806
|
+
"path": "precision",
|
|
10807
|
+
"valueType": "number"
|
|
10808
|
+
}
|
|
10809
|
+
],
|
|
10810
|
+
"privacy-mask": [{
|
|
10811
|
+
"path": "enabled",
|
|
10812
|
+
"valueType": "boolean"
|
|
10813
|
+
}, {
|
|
10814
|
+
"path": "audioEnabled",
|
|
10815
|
+
"valueType": "boolean"
|
|
10816
|
+
}],
|
|
10817
|
+
"ptz": [
|
|
10818
|
+
{
|
|
10819
|
+
"path": "pan",
|
|
10820
|
+
"valueType": "number"
|
|
10821
|
+
},
|
|
10822
|
+
{
|
|
10823
|
+
"path": "tilt",
|
|
10824
|
+
"valueType": "number"
|
|
10825
|
+
},
|
|
10826
|
+
{
|
|
10827
|
+
"path": "zoom",
|
|
10828
|
+
"valueType": "number"
|
|
10829
|
+
},
|
|
10830
|
+
{
|
|
10831
|
+
"path": "autofocus",
|
|
10832
|
+
"valueType": "boolean"
|
|
10833
|
+
}
|
|
10834
|
+
],
|
|
10835
|
+
"ptz-autotrack": [
|
|
10836
|
+
{
|
|
10837
|
+
"path": "enabled",
|
|
10838
|
+
"valueType": "boolean"
|
|
10839
|
+
},
|
|
10840
|
+
{
|
|
10841
|
+
"path": "currentSettings.targetType",
|
|
10842
|
+
"valueType": "string"
|
|
10843
|
+
},
|
|
10844
|
+
{
|
|
10845
|
+
"path": "currentSettings.stopDelaySeconds",
|
|
10846
|
+
"valueType": "number"
|
|
10847
|
+
},
|
|
10848
|
+
{
|
|
10849
|
+
"path": "currentSettings.disappearDelaySeconds",
|
|
10850
|
+
"valueType": "number"
|
|
10851
|
+
}
|
|
10852
|
+
],
|
|
10853
|
+
"recording-archive": [
|
|
10854
|
+
{
|
|
10855
|
+
"path": "deviceId",
|
|
10856
|
+
"valueType": "number"
|
|
10857
|
+
},
|
|
10858
|
+
{
|
|
10859
|
+
"path": "enabled",
|
|
10860
|
+
"valueType": "boolean"
|
|
10861
|
+
},
|
|
10862
|
+
{
|
|
10863
|
+
"path": "activeMode",
|
|
10864
|
+
"valueType": "enum",
|
|
10865
|
+
"enumValues": [
|
|
10866
|
+
"off",
|
|
10867
|
+
"events",
|
|
10868
|
+
"continuous",
|
|
10869
|
+
"on-device-decision"
|
|
10870
|
+
]
|
|
10871
|
+
},
|
|
10872
|
+
{
|
|
10873
|
+
"path": "nodeId",
|
|
10874
|
+
"valueType": "string"
|
|
10875
|
+
},
|
|
10876
|
+
{
|
|
10877
|
+
"path": "storageBytes",
|
|
10878
|
+
"valueType": "number"
|
|
10879
|
+
}
|
|
10880
|
+
],
|
|
10881
|
+
"recording-onboard": [
|
|
10882
|
+
{
|
|
10883
|
+
"path": "primaryTrackId",
|
|
10884
|
+
"valueType": "string"
|
|
10885
|
+
},
|
|
10886
|
+
{
|
|
10887
|
+
"path": "enabled",
|
|
10888
|
+
"valueType": "boolean"
|
|
10889
|
+
},
|
|
10890
|
+
{
|
|
10891
|
+
"path": "overwriteWhenFull",
|
|
10892
|
+
"valueType": "boolean"
|
|
10893
|
+
},
|
|
10894
|
+
{
|
|
10895
|
+
"path": "preRecordSec",
|
|
10896
|
+
"valueType": "number"
|
|
10897
|
+
},
|
|
10898
|
+
{
|
|
10899
|
+
"path": "postRecordSec",
|
|
10900
|
+
"valueType": "number"
|
|
10901
|
+
},
|
|
10902
|
+
{
|
|
10903
|
+
"path": "segmentMinutes",
|
|
10904
|
+
"valueType": "number"
|
|
10905
|
+
},
|
|
10906
|
+
{
|
|
10907
|
+
"path": "unreadableWindows",
|
|
10908
|
+
"valueType": "number"
|
|
10909
|
+
},
|
|
10910
|
+
{
|
|
10911
|
+
"path": "recordingToNowhere",
|
|
10912
|
+
"valueType": "boolean"
|
|
10913
|
+
}
|
|
10914
|
+
],
|
|
10915
|
+
"recording-signal": [{
|
|
10916
|
+
"path": "active",
|
|
10917
|
+
"valueType": "boolean"
|
|
10918
|
+
}, {
|
|
10919
|
+
"path": "reason",
|
|
10920
|
+
"valueType": "string"
|
|
10921
|
+
}],
|
|
10922
|
+
"running-state": [
|
|
10923
|
+
{
|
|
10924
|
+
"path": "running",
|
|
10925
|
+
"valueType": "boolean"
|
|
10926
|
+
},
|
|
10927
|
+
{
|
|
10928
|
+
"path": "since",
|
|
10929
|
+
"valueType": "number"
|
|
10930
|
+
},
|
|
10931
|
+
{
|
|
10932
|
+
"path": "source",
|
|
10933
|
+
"valueType": "enum",
|
|
10934
|
+
"enumValues": ["native", "assigned"]
|
|
10935
|
+
},
|
|
10936
|
+
{
|
|
10937
|
+
"path": "phase",
|
|
10938
|
+
"valueType": "string"
|
|
10939
|
+
}
|
|
10940
|
+
],
|
|
10941
|
+
"script-runner": [
|
|
10942
|
+
{
|
|
10943
|
+
"path": "isRunning",
|
|
10944
|
+
"valueType": "boolean"
|
|
10945
|
+
},
|
|
10946
|
+
{
|
|
10947
|
+
"path": "lastRunAt",
|
|
10948
|
+
"valueType": "number"
|
|
10949
|
+
},
|
|
10950
|
+
{
|
|
10951
|
+
"path": "lastRunSuccess",
|
|
10952
|
+
"valueType": "boolean"
|
|
10953
|
+
},
|
|
10954
|
+
{
|
|
10955
|
+
"path": "lastError",
|
|
10956
|
+
"valueType": "string"
|
|
10957
|
+
}
|
|
10958
|
+
],
|
|
10959
|
+
"smoke": [{
|
|
10960
|
+
"path": "detected",
|
|
10961
|
+
"valueType": "boolean"
|
|
10962
|
+
}],
|
|
10963
|
+
"snapshot": [
|
|
10964
|
+
{
|
|
10965
|
+
"path": "lastCapturedAt",
|
|
10966
|
+
"valueType": "number"
|
|
10967
|
+
},
|
|
10968
|
+
{
|
|
10969
|
+
"path": "cacheAgeMs",
|
|
10970
|
+
"valueType": "number"
|
|
10971
|
+
},
|
|
10972
|
+
{
|
|
10973
|
+
"path": "lastBytes",
|
|
10974
|
+
"valueType": "number"
|
|
10975
|
+
},
|
|
10976
|
+
{
|
|
10977
|
+
"path": "lastStreamId",
|
|
10978
|
+
"valueType": "string"
|
|
10979
|
+
}
|
|
10980
|
+
],
|
|
10981
|
+
"stream-params": [
|
|
10982
|
+
{
|
|
10983
|
+
"path": "main.width",
|
|
10984
|
+
"valueType": "number"
|
|
10985
|
+
},
|
|
10986
|
+
{
|
|
10987
|
+
"path": "main.height",
|
|
10988
|
+
"valueType": "number"
|
|
10989
|
+
},
|
|
10990
|
+
{
|
|
10991
|
+
"path": "main.codec",
|
|
10992
|
+
"valueType": "enum",
|
|
10993
|
+
"enumValues": ["h264", "h265"]
|
|
10994
|
+
},
|
|
10995
|
+
{
|
|
10996
|
+
"path": "main.framerate",
|
|
10997
|
+
"valueType": "number"
|
|
10998
|
+
},
|
|
10999
|
+
{
|
|
11000
|
+
"path": "main.bitrate",
|
|
11001
|
+
"valueType": "number"
|
|
11002
|
+
},
|
|
11003
|
+
{
|
|
11004
|
+
"path": "main.bitrateMode",
|
|
11005
|
+
"valueType": "enum",
|
|
11006
|
+
"enumValues": ["vbr", "cbr"]
|
|
11007
|
+
},
|
|
11008
|
+
{
|
|
11009
|
+
"path": "main.encoderProfile",
|
|
11010
|
+
"valueType": "enum",
|
|
11011
|
+
"enumValues": [
|
|
11012
|
+
"high",
|
|
11013
|
+
"main",
|
|
11014
|
+
"baseline"
|
|
11015
|
+
]
|
|
11016
|
+
},
|
|
11017
|
+
{
|
|
11018
|
+
"path": "main.gop",
|
|
11019
|
+
"valueType": "number"
|
|
11020
|
+
},
|
|
11021
|
+
{
|
|
11022
|
+
"path": "main.audio",
|
|
11023
|
+
"valueType": "boolean"
|
|
11024
|
+
},
|
|
11025
|
+
{
|
|
11026
|
+
"path": "sub.width",
|
|
11027
|
+
"valueType": "number"
|
|
11028
|
+
},
|
|
11029
|
+
{
|
|
11030
|
+
"path": "sub.height",
|
|
11031
|
+
"valueType": "number"
|
|
11032
|
+
},
|
|
11033
|
+
{
|
|
11034
|
+
"path": "sub.codec",
|
|
11035
|
+
"valueType": "enum",
|
|
11036
|
+
"enumValues": ["h264", "h265"]
|
|
11037
|
+
},
|
|
11038
|
+
{
|
|
11039
|
+
"path": "sub.framerate",
|
|
11040
|
+
"valueType": "number"
|
|
11041
|
+
},
|
|
11042
|
+
{
|
|
11043
|
+
"path": "sub.bitrate",
|
|
11044
|
+
"valueType": "number"
|
|
11045
|
+
},
|
|
11046
|
+
{
|
|
11047
|
+
"path": "sub.bitrateMode",
|
|
11048
|
+
"valueType": "enum",
|
|
11049
|
+
"enumValues": ["vbr", "cbr"]
|
|
11050
|
+
},
|
|
11051
|
+
{
|
|
11052
|
+
"path": "sub.encoderProfile",
|
|
11053
|
+
"valueType": "enum",
|
|
11054
|
+
"enumValues": [
|
|
11055
|
+
"high",
|
|
11056
|
+
"main",
|
|
11057
|
+
"baseline"
|
|
11058
|
+
]
|
|
11059
|
+
},
|
|
11060
|
+
{
|
|
11061
|
+
"path": "sub.gop",
|
|
11062
|
+
"valueType": "number"
|
|
11063
|
+
},
|
|
11064
|
+
{
|
|
11065
|
+
"path": "sub.audio",
|
|
11066
|
+
"valueType": "boolean"
|
|
11067
|
+
},
|
|
11068
|
+
{
|
|
11069
|
+
"path": "ext.width",
|
|
11070
|
+
"valueType": "number"
|
|
11071
|
+
},
|
|
11072
|
+
{
|
|
11073
|
+
"path": "ext.height",
|
|
11074
|
+
"valueType": "number"
|
|
11075
|
+
},
|
|
11076
|
+
{
|
|
11077
|
+
"path": "ext.codec",
|
|
11078
|
+
"valueType": "enum",
|
|
11079
|
+
"enumValues": ["h264", "h265"]
|
|
11080
|
+
},
|
|
11081
|
+
{
|
|
11082
|
+
"path": "ext.framerate",
|
|
11083
|
+
"valueType": "number"
|
|
11084
|
+
},
|
|
11085
|
+
{
|
|
11086
|
+
"path": "ext.bitrate",
|
|
11087
|
+
"valueType": "number"
|
|
11088
|
+
},
|
|
11089
|
+
{
|
|
11090
|
+
"path": "ext.bitrateMode",
|
|
11091
|
+
"valueType": "enum",
|
|
11092
|
+
"enumValues": ["vbr", "cbr"]
|
|
11093
|
+
},
|
|
11094
|
+
{
|
|
11095
|
+
"path": "ext.encoderProfile",
|
|
11096
|
+
"valueType": "enum",
|
|
11097
|
+
"enumValues": [
|
|
11098
|
+
"high",
|
|
11099
|
+
"main",
|
|
11100
|
+
"baseline"
|
|
11101
|
+
]
|
|
11102
|
+
},
|
|
11103
|
+
{
|
|
11104
|
+
"path": "ext.gop",
|
|
11105
|
+
"valueType": "number"
|
|
11106
|
+
},
|
|
11107
|
+
{
|
|
11108
|
+
"path": "ext.audio",
|
|
11109
|
+
"valueType": "boolean"
|
|
11110
|
+
}
|
|
11111
|
+
],
|
|
11112
|
+
"switch": [{
|
|
11113
|
+
"path": "on",
|
|
11114
|
+
"valueType": "boolean"
|
|
11115
|
+
}],
|
|
11116
|
+
"tamper": [{
|
|
11117
|
+
"path": "tampered",
|
|
11118
|
+
"valueType": "boolean"
|
|
11119
|
+
}],
|
|
11120
|
+
"temperature-sensor": [
|
|
11121
|
+
{
|
|
11122
|
+
"path": "celsius",
|
|
11123
|
+
"valueType": "number"
|
|
11124
|
+
},
|
|
11125
|
+
{
|
|
11126
|
+
"path": "unit",
|
|
11127
|
+
"valueType": "string"
|
|
11128
|
+
},
|
|
11129
|
+
{
|
|
11130
|
+
"path": "precision",
|
|
11131
|
+
"valueType": "number"
|
|
11132
|
+
}
|
|
11133
|
+
],
|
|
11134
|
+
"update": [
|
|
11135
|
+
{
|
|
11136
|
+
"path": "currentVersion",
|
|
11137
|
+
"valueType": "string"
|
|
11138
|
+
},
|
|
11139
|
+
{
|
|
11140
|
+
"path": "availableVersion",
|
|
11141
|
+
"valueType": "string"
|
|
11142
|
+
},
|
|
11143
|
+
{
|
|
11144
|
+
"path": "updatable",
|
|
11145
|
+
"valueType": "boolean"
|
|
11146
|
+
},
|
|
11147
|
+
{
|
|
11148
|
+
"path": "state",
|
|
11149
|
+
"valueType": "string"
|
|
11150
|
+
},
|
|
11151
|
+
{
|
|
11152
|
+
"path": "inProgress",
|
|
11153
|
+
"valueType": "boolean"
|
|
11154
|
+
}
|
|
11155
|
+
],
|
|
11156
|
+
"vacuum-control": [
|
|
11157
|
+
{
|
|
11158
|
+
"path": "state",
|
|
11159
|
+
"valueType": "enum",
|
|
11160
|
+
"enumValues": [
|
|
11161
|
+
"idle",
|
|
11162
|
+
"cleaning",
|
|
11163
|
+
"paused",
|
|
11164
|
+
"returning",
|
|
11165
|
+
"docked",
|
|
11166
|
+
"drying",
|
|
11167
|
+
"error"
|
|
11168
|
+
]
|
|
11169
|
+
},
|
|
11170
|
+
{
|
|
11171
|
+
"path": "batteryLevel",
|
|
11172
|
+
"valueType": "number"
|
|
11173
|
+
},
|
|
11174
|
+
{
|
|
11175
|
+
"path": "fanSpeed",
|
|
11176
|
+
"valueType": "string"
|
|
11177
|
+
},
|
|
11178
|
+
{
|
|
11179
|
+
"path": "progressPercent",
|
|
11180
|
+
"valueType": "number"
|
|
11181
|
+
},
|
|
11182
|
+
{
|
|
11183
|
+
"path": "errorCode",
|
|
11184
|
+
"valueType": "number"
|
|
11185
|
+
},
|
|
11186
|
+
{
|
|
11187
|
+
"path": "errorLabel",
|
|
11188
|
+
"valueType": "string"
|
|
11189
|
+
}
|
|
11190
|
+
],
|
|
11191
|
+
"valve": [{
|
|
11192
|
+
"path": "state",
|
|
11193
|
+
"valueType": "enum",
|
|
11194
|
+
"enumValues": [
|
|
11195
|
+
"open",
|
|
11196
|
+
"opening",
|
|
11197
|
+
"closing",
|
|
11198
|
+
"closed",
|
|
11199
|
+
"stopped"
|
|
11200
|
+
]
|
|
11201
|
+
}, {
|
|
11202
|
+
"path": "position",
|
|
11203
|
+
"valueType": "number"
|
|
11204
|
+
}],
|
|
11205
|
+
"vibration": [{
|
|
11206
|
+
"path": "detected",
|
|
11207
|
+
"valueType": "boolean"
|
|
11208
|
+
}],
|
|
11209
|
+
"water-heater": [
|
|
11210
|
+
{
|
|
11211
|
+
"path": "currentTemp",
|
|
11212
|
+
"valueType": "number"
|
|
11213
|
+
},
|
|
11214
|
+
{
|
|
11215
|
+
"path": "targetTemp",
|
|
11216
|
+
"valueType": "number"
|
|
11217
|
+
},
|
|
11218
|
+
{
|
|
11219
|
+
"path": "operationMode",
|
|
11220
|
+
"valueType": "string"
|
|
11221
|
+
},
|
|
11222
|
+
{
|
|
11223
|
+
"path": "away",
|
|
11224
|
+
"valueType": "boolean"
|
|
11225
|
+
},
|
|
11226
|
+
{
|
|
11227
|
+
"path": "minTemp",
|
|
11228
|
+
"valueType": "number"
|
|
11229
|
+
},
|
|
11230
|
+
{
|
|
11231
|
+
"path": "maxTemp",
|
|
11232
|
+
"valueType": "number"
|
|
11233
|
+
}
|
|
11234
|
+
],
|
|
11235
|
+
"weather": [
|
|
11236
|
+
{
|
|
11237
|
+
"path": "condition",
|
|
11238
|
+
"valueType": "string"
|
|
11239
|
+
},
|
|
11240
|
+
{
|
|
11241
|
+
"path": "temperature",
|
|
11242
|
+
"valueType": "number"
|
|
11243
|
+
},
|
|
11244
|
+
{
|
|
11245
|
+
"path": "temperatureUnit",
|
|
11246
|
+
"valueType": "string"
|
|
11247
|
+
},
|
|
11248
|
+
{
|
|
11249
|
+
"path": "humidity",
|
|
11250
|
+
"valueType": "number"
|
|
11251
|
+
},
|
|
11252
|
+
{
|
|
11253
|
+
"path": "pressure",
|
|
11254
|
+
"valueType": "number"
|
|
11255
|
+
},
|
|
11256
|
+
{
|
|
11257
|
+
"path": "pressureUnit",
|
|
11258
|
+
"valueType": "string"
|
|
11259
|
+
},
|
|
11260
|
+
{
|
|
11261
|
+
"path": "windSpeed",
|
|
11262
|
+
"valueType": "number"
|
|
11263
|
+
},
|
|
11264
|
+
{
|
|
11265
|
+
"path": "windSpeedUnit",
|
|
11266
|
+
"valueType": "string"
|
|
11267
|
+
},
|
|
11268
|
+
{
|
|
11269
|
+
"path": "windBearing",
|
|
11270
|
+
"valueType": "number"
|
|
11271
|
+
}
|
|
11272
|
+
],
|
|
11273
|
+
"zone-analytics": [
|
|
11274
|
+
{
|
|
11275
|
+
"path": "ts",
|
|
11276
|
+
"valueType": "number"
|
|
11277
|
+
},
|
|
11278
|
+
{
|
|
11279
|
+
"path": "frameWidth",
|
|
11280
|
+
"valueType": "number"
|
|
11281
|
+
},
|
|
11282
|
+
{
|
|
11283
|
+
"path": "frameHeight",
|
|
11284
|
+
"valueType": "number"
|
|
11285
|
+
},
|
|
11286
|
+
{
|
|
11287
|
+
"path": "frame.totalObjects",
|
|
11288
|
+
"valueType": "number"
|
|
11289
|
+
},
|
|
11290
|
+
{
|
|
11291
|
+
"path": "frame.standingObjects",
|
|
11292
|
+
"valueType": "number"
|
|
11293
|
+
},
|
|
11294
|
+
{
|
|
11295
|
+
"path": "frame.transientObjects",
|
|
11296
|
+
"valueType": "number"
|
|
11297
|
+
},
|
|
11298
|
+
{
|
|
11299
|
+
"path": "unzoned.totalObjects",
|
|
11300
|
+
"valueType": "number"
|
|
11301
|
+
},
|
|
11302
|
+
{
|
|
11303
|
+
"path": "unzoned.standingObjects",
|
|
11304
|
+
"valueType": "number"
|
|
11305
|
+
},
|
|
11306
|
+
{
|
|
11307
|
+
"path": "unzoned.transientObjects",
|
|
11308
|
+
"valueType": "number"
|
|
11309
|
+
}
|
|
11310
|
+
]
|
|
11311
|
+
});
|
|
9338
11312
|
object({
|
|
9339
11313
|
code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
|
|
9340
11314
|
params: record(string(), union([string(), number()])).optional()
|
|
@@ -9717,7 +11691,7 @@ function errMsg$2(err) {
|
|
|
9717
11691
|
return String(err);
|
|
9718
11692
|
}
|
|
9719
11693
|
//#endregion
|
|
9720
|
-
//#region ../types/dist/composition-
|
|
11694
|
+
//#region ../types/dist/composition-kEl9mevu.mjs
|
|
9721
11695
|
/**
|
|
9722
11696
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
9723
11697
|
*
|
|
@@ -13393,7 +15367,7 @@ var LogChannelDescriptorSchema = object({
|
|
|
13393
15367
|
* `true` is a PROMISE with two halves, and both must hold: the gate is
|
|
13394
15368
|
* consulted with the numeric device id, AND every line the channel admits
|
|
13395
15369
|
* carries `tags: { deviceId }` with that same numeric id. The second half is
|
|
13396
|
-
* what makes `| json | deviceId="
|
|
15370
|
+
* what makes `| json | deviceId="102"` work in Loki — `loki-payload.ts`
|
|
13397
15371
|
* keeps `deviceId` out of the stream labels for cardinality, so the tag in
|
|
13398
15372
|
* the body is the only way to filter.
|
|
13399
15373
|
*
|
|
@@ -13600,7 +15574,7 @@ var ModelVariantGroupSchema = object({
|
|
|
13600
15574
|
precision: _enum(["fp32", "int8"]).optional(),
|
|
13601
15575
|
/**
|
|
13602
15576
|
* Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
|
|
13603
|
-
* an alternate training of the same family (
|
|
15577
|
+
* an alternate training of the same family (plugin catalog `relu_test`); chip
|
|
13604
15578
|
* label is "Test".
|
|
13605
15579
|
*/
|
|
13606
15580
|
optimization: _enum(["standard", "test"]).optional(),
|
|
@@ -13852,8 +15826,8 @@ var ModelCatalogEntrySchema = object({
|
|
|
13852
15826
|
provider: ModelProviderIdSchema.optional(),
|
|
13853
15827
|
/**
|
|
13854
15828
|
* Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
|
|
13855
|
-
* applies (
|
|
13856
|
-
* labels already ARE the CamStack macros (
|
|
15829
|
+
* applies (plus catalog / COCO public catalog). Set on a custom model whose raw
|
|
15830
|
+
* labels already ARE the CamStack macros (plugin catalog identity map).
|
|
13857
15831
|
*/
|
|
13858
15832
|
classMap: DetectionCatalogClassMapSchema.optional(),
|
|
13859
15833
|
/**
|
|
@@ -16879,7 +18853,7 @@ method(object({
|
|
|
16879
18853
|
* `1` is real time and is the ONLY value that allows the copy branch —
|
|
16880
18854
|
* anything else forces `libx264` over the window. That was priced
|
|
16881
18855
|
* before it was chosen: a per-event burst measured at 0.23 s and 254 KB
|
|
16882
|
-
* on a real
|
|
18856
|
+
* on a real 101 720p cut, against 922 KB for the copy it replaces. A
|
|
16883
18857
|
* re-encode is capped at 720p (`EVENT_CLIP_ENCODE_MAX_WIDTH`), because
|
|
16884
18858
|
* once the decode is forced the width stops being free.
|
|
16885
18859
|
*/
|
|
@@ -17299,6 +19273,7 @@ var CompositionRunStatusSchema = _enum([
|
|
|
17299
19273
|
"starting",
|
|
17300
19274
|
"running",
|
|
17301
19275
|
"degraded",
|
|
19276
|
+
"incomplete",
|
|
17302
19277
|
"failed"
|
|
17303
19278
|
]);
|
|
17304
19279
|
var CompositionFieldStateKindSchema = _enum([
|
|
@@ -17512,6 +19487,7 @@ var CoreBlockStatusSchema = _enum([
|
|
|
17512
19487
|
"starting",
|
|
17513
19488
|
"running",
|
|
17514
19489
|
"degraded",
|
|
19490
|
+
"incomplete",
|
|
17515
19491
|
"failed"
|
|
17516
19492
|
]);
|
|
17517
19493
|
/** path → TypeScript source for a multi-file block. */
|
|
@@ -39435,7 +41411,7 @@ var PRIMARY_CATEGORIES = new Set(ENTRIES.map((e) => e.primaryCategory));
|
|
|
39435
41411
|
* `locationKey` is ALWAYS {@link locationIconKey} of the label — never the
|
|
39436
41412
|
* operator's casing. The registry matches labels trimmed + case-insensitively
|
|
39437
41413
|
* everywhere (`addLocation`, `removeLocation`, `renameLocation`), and a
|
|
39438
|
-
* case-only rename (`
|
|
41414
|
+
* case-only rename (`kitchen` → `Kitchen`) is a real edit this repo supports; a
|
|
39439
41415
|
* map keyed on the displayed casing would orphan its entry on exactly that
|
|
39440
41416
|
* edit. Consumers join by keying their own label through `locationIconKey`.
|
|
39441
41417
|
*/
|
|
@@ -39460,7 +41436,7 @@ var LocationDescriptionAssignmentSchema = object({
|
|
|
39460
41436
|
/**
|
|
39461
41437
|
* A SITE ZONE — a named part of the property that several locations belong to.
|
|
39462
41438
|
*
|
|
39463
|
-
* "
|
|
41439
|
+
* "Night zone" holds every bedroom; "Zona giorno" the living room and the
|
|
39464
41440
|
* kitchen. A camera belongs to exactly one location, and a location to at most
|
|
39465
41441
|
* one zone, so a camera's zone is derived and never stored on the device: the
|
|
39466
41442
|
* whole point of this entity is that grouping rooms touches no device row.
|
|
@@ -39489,7 +41465,7 @@ var LocationDescriptionAssignmentSchema = object({
|
|
|
39489
41465
|
* the locations inside it.
|
|
39490
41466
|
*
|
|
39491
41467
|
* The LABEL is carried alongside the key because the key is lossy on purpose —
|
|
39492
|
-
* a surface must show "
|
|
41468
|
+
* a surface must show "Night zone", not "night zone". Locations are carried
|
|
39493
41469
|
* here, rather than left to a second call, because every consumer wants both
|
|
39494
41470
|
* at once and a viewer that asked twice could render a zone whose membership
|
|
39495
41471
|
* it has not fetched yet.
|
|
@@ -41602,8 +43578,8 @@ var LoadContributionSchema = object({
|
|
|
41602
43578
|
"unattributable"
|
|
41603
43579
|
]),
|
|
41604
43580
|
/**
|
|
41605
|
-
* What ONE entry is, in the contributor's own words — `
|
|
41606
|
-
* `
|
|
43581
|
+
* What ONE entry is, in the contributor's own words — `101/high`,
|
|
43582
|
+
* `102/native`, `cuda:0 shared pool`. Free text because the unit differs per
|
|
41607
43583
|
* family and inventing a common one would lose the only information that
|
|
41608
43584
|
* makes two entries for the same camera distinguishable.
|
|
41609
43585
|
*/
|
|
@@ -43251,6 +45227,649 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
43251
45227
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
43252
45228
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
43253
45229
|
/**
|
|
45230
|
+
* Palette entry ids (D939). Audio is the one gradient; `audio-*` leaves are
|
|
45231
|
+
* not entries. `heatmapScrub` is a mark, not an event kind.
|
|
45232
|
+
*/
|
|
45233
|
+
var PALETTE_ENTRY_IDS = [
|
|
45234
|
+
"motion",
|
|
45235
|
+
"audio",
|
|
45236
|
+
"recording",
|
|
45237
|
+
"live",
|
|
45238
|
+
"heatmapScrub",
|
|
45239
|
+
"person",
|
|
45240
|
+
"vehicle",
|
|
45241
|
+
"animal",
|
|
45242
|
+
"package",
|
|
45243
|
+
"sensor",
|
|
45244
|
+
"control",
|
|
45245
|
+
"face",
|
|
45246
|
+
"plate",
|
|
45247
|
+
"car",
|
|
45248
|
+
"truck",
|
|
45249
|
+
"bus",
|
|
45250
|
+
"motorcycle",
|
|
45251
|
+
"bicycle",
|
|
45252
|
+
"airplane",
|
|
45253
|
+
"boat",
|
|
45254
|
+
"train",
|
|
45255
|
+
"bird",
|
|
45256
|
+
"dog",
|
|
45257
|
+
"cat",
|
|
45258
|
+
"horse",
|
|
45259
|
+
"sheep",
|
|
45260
|
+
"cow",
|
|
45261
|
+
"elephant",
|
|
45262
|
+
"bear",
|
|
45263
|
+
"zebra",
|
|
45264
|
+
"giraffe",
|
|
45265
|
+
"package-delivered",
|
|
45266
|
+
"package-picked-up",
|
|
45267
|
+
"suitcase",
|
|
45268
|
+
"backpack",
|
|
45269
|
+
"handbag",
|
|
45270
|
+
"contact",
|
|
45271
|
+
"motion-sensor",
|
|
45272
|
+
"smoke",
|
|
45273
|
+
"flood",
|
|
45274
|
+
"gas",
|
|
45275
|
+
"carbon-monoxide",
|
|
45276
|
+
"vibration",
|
|
45277
|
+
"tamper",
|
|
45278
|
+
"presence",
|
|
45279
|
+
"enum-sensor",
|
|
45280
|
+
"device-event",
|
|
45281
|
+
"lock",
|
|
45282
|
+
"cover",
|
|
45283
|
+
"switch",
|
|
45284
|
+
"siren",
|
|
45285
|
+
"button",
|
|
45286
|
+
"doorbell"
|
|
45287
|
+
];
|
|
45288
|
+
var AUDIO_ENTRY_ID = "audio";
|
|
45289
|
+
/** Six rungs, quiet → loud. The opaque end is the entry's hex. */
|
|
45290
|
+
var AUDIO_GRADIENT_ALPHAS = [
|
|
45291
|
+
.3,
|
|
45292
|
+
.42,
|
|
45293
|
+
.55,
|
|
45294
|
+
.7,
|
|
45295
|
+
.85,
|
|
45296
|
+
1
|
|
45297
|
+
];
|
|
45298
|
+
var PALETTE_PRESET_IDS = [
|
|
45299
|
+
"camstack",
|
|
45300
|
+
"high-contrast",
|
|
45301
|
+
"okabe-ito"
|
|
45302
|
+
];
|
|
45303
|
+
function isPaletteEntryId(id) {
|
|
45304
|
+
return PALETTE_ENTRY_IDS.includes(id);
|
|
45305
|
+
}
|
|
45306
|
+
function isPalettePresetId(id) {
|
|
45307
|
+
return PALETTE_PRESET_IDS.includes(id);
|
|
45308
|
+
}
|
|
45309
|
+
/**
|
|
45310
|
+
* CIEDE2000 and WCAG contrast for the display palette (D939).
|
|
45311
|
+
*
|
|
45312
|
+
* One implementation, shared by the hub validator, the admin editor and
|
|
45313
|
+
* (phase 2) the viewer. The arithmetic matches the viewer's `src/theme/cie.ts`.
|
|
45314
|
+
*/
|
|
45315
|
+
/** Page backgrounds the contrast rule is measured against. */
|
|
45316
|
+
var PALETTE_BACKGROUNDS = {
|
|
45317
|
+
dark: "#0c0a09",
|
|
45318
|
+
light: "#fafaf9"
|
|
45319
|
+
};
|
|
45320
|
+
/** Marks that are not event kinds and share the raised distance floor. */
|
|
45321
|
+
var PALETTE_MARK_PAIR = ["live", "heatmapScrub"];
|
|
45322
|
+
var HEX = /^#[0-9a-fA-F]{6}$/;
|
|
45323
|
+
function srgbChannel(hex, start) {
|
|
45324
|
+
return Number.parseInt(hex.slice(start, start + 2), 16);
|
|
45325
|
+
}
|
|
45326
|
+
function srgbToLin(channel) {
|
|
45327
|
+
const x = channel / 255;
|
|
45328
|
+
return x <= .04045 ? x / 12.92 : ((x + .055) / 1.055) ** 2.4;
|
|
45329
|
+
}
|
|
45330
|
+
function relativeLuminance(hex) {
|
|
45331
|
+
const r = srgbToLin(srgbChannel(hex, 1));
|
|
45332
|
+
const g = srgbToLin(srgbChannel(hex, 3));
|
|
45333
|
+
const b = srgbToLin(srgbChannel(hex, 5));
|
|
45334
|
+
return .2126 * r + .7152 * g + .0722 * b;
|
|
45335
|
+
}
|
|
45336
|
+
/** WCAG contrast ratio of two `#rrggbb` colours. Non-hex returns 0. */
|
|
45337
|
+
function contrastRatio(a, b) {
|
|
45338
|
+
if (!HEX.test(a) || !HEX.test(b)) return 0;
|
|
45339
|
+
const hi = Math.max(relativeLuminance(a), relativeLuminance(b));
|
|
45340
|
+
const lo = Math.min(relativeLuminance(a), relativeLuminance(b));
|
|
45341
|
+
return (hi + .05) / (lo + .05);
|
|
45342
|
+
}
|
|
45343
|
+
function xyzToLab(hex) {
|
|
45344
|
+
const r = srgbToLin(srgbChannel(hex, 1));
|
|
45345
|
+
const g = srgbToLin(srgbChannel(hex, 3));
|
|
45346
|
+
const bl = srgbToLin(srgbChannel(hex, 5));
|
|
45347
|
+
const x = .4124564 * r + .3575761 * g + .1804375 * bl;
|
|
45348
|
+
const y = .2126729 * r + .7151522 * g + .072175 * bl;
|
|
45349
|
+
const z = .0193339 * r + .119192 * g + .9503041 * bl;
|
|
45350
|
+
const f = (t) => t > .008856 ? Math.cbrt(t) : 7.787 * t + 16 / 116;
|
|
45351
|
+
const fx = f(x / .95047);
|
|
45352
|
+
const fy = f(y);
|
|
45353
|
+
const fz = f(z / 1.08883);
|
|
45354
|
+
return {
|
|
45355
|
+
L: 116 * fy - 16,
|
|
45356
|
+
a: 500 * (fx - fy),
|
|
45357
|
+
b: 200 * (fy - fz)
|
|
45358
|
+
};
|
|
45359
|
+
}
|
|
45360
|
+
function hueDeg(ap, b) {
|
|
45361
|
+
if (ap === 0 && b === 0) return 0;
|
|
45362
|
+
const ang = Math.atan2(b, ap) * 180 / Math.PI;
|
|
45363
|
+
return ang < 0 ? ang + 360 : ang;
|
|
45364
|
+
}
|
|
45365
|
+
/** CIEDE2000. Non-hex returns 0 so a bad swatch fails the distinctness rule. */
|
|
45366
|
+
function deltaE00(hex1, hex2) {
|
|
45367
|
+
if (!HEX.test(hex1) || !HEX.test(hex2)) return 0;
|
|
45368
|
+
const lab1 = xyzToLab(hex1);
|
|
45369
|
+
const lab2 = xyzToLab(hex2);
|
|
45370
|
+
const cab7 = ((Math.hypot(lab1.a, lab1.b) + Math.hypot(lab2.a, lab2.b)) / 2) ** 7;
|
|
45371
|
+
const g = .5 * (1 - Math.sqrt(cab7 / (cab7 + 25 ** 7)));
|
|
45372
|
+
const a1p = (1 + g) * lab1.a;
|
|
45373
|
+
const a2p = (1 + g) * lab2.a;
|
|
45374
|
+
const c1p = Math.hypot(a1p, lab1.b);
|
|
45375
|
+
const c2p = Math.hypot(a2p, lab2.b);
|
|
45376
|
+
const h1p = hueDeg(a1p, lab1.b);
|
|
45377
|
+
const h2p = hueDeg(a2p, lab2.b);
|
|
45378
|
+
let dhp = 0;
|
|
45379
|
+
if (c1p * c2p !== 0) {
|
|
45380
|
+
dhp = h2p - h1p;
|
|
45381
|
+
if (dhp > 180) dhp -= 360;
|
|
45382
|
+
else if (dhp < -180) dhp += 360;
|
|
45383
|
+
}
|
|
45384
|
+
const dHp = 2 * Math.sqrt(c1p * c2p) * Math.sin(dhp * Math.PI / 360);
|
|
45385
|
+
const lbp = (lab1.L + lab2.L) / 2;
|
|
45386
|
+
const cbp = (c1p + c2p) / 2;
|
|
45387
|
+
let hbp = h1p + h2p;
|
|
45388
|
+
if (c1p * c2p !== 0) {
|
|
45389
|
+
if (Math.abs(h1p - h2p) > 180) hbp += hbp < 360 ? 360 : -360;
|
|
45390
|
+
hbp /= 2;
|
|
45391
|
+
}
|
|
45392
|
+
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);
|
|
45393
|
+
const dTheta = 30 * Math.exp(-(((hbp - 275) / 25) ** 2));
|
|
45394
|
+
const cbp7 = cbp ** 7;
|
|
45395
|
+
const rc = 2 * Math.sqrt(cbp7 / (cbp7 + 25 ** 7));
|
|
45396
|
+
const sl = 1 + .015 * (lbp - 50) ** 2 / Math.sqrt(20 + (lbp - 50) ** 2);
|
|
45397
|
+
const sc = 1 + .045 * cbp;
|
|
45398
|
+
const sh = 1 + .015 * cbp * t;
|
|
45399
|
+
const rt = -Math.sin(2 * dTheta * Math.PI / 180) * rc;
|
|
45400
|
+
const dLp = lab2.L - lab1.L;
|
|
45401
|
+
const dCp = c2p - c1p;
|
|
45402
|
+
return Math.sqrt((dLp / sl) ** 2 + (dCp / sc) ** 2 + (dHp / sh) ** 2 + rt * (dCp / sc) * (dHp / sh));
|
|
45403
|
+
}
|
|
45404
|
+
/** Frozen palette tables (D939). The spec refuses a table that breaks the rule. */
|
|
45405
|
+
var CAMSTACK_HEX = {
|
|
45406
|
+
motion: "#d946ef",
|
|
45407
|
+
audio: "#059eb8",
|
|
45408
|
+
recording: "#ef4444",
|
|
45409
|
+
live: "#8d7a00",
|
|
45410
|
+
heatmapScrub: "#4b32ff",
|
|
45411
|
+
person: "#11a64c",
|
|
45412
|
+
vehicle: "#3b82f6",
|
|
45413
|
+
animal: "#ea6a09",
|
|
45414
|
+
package: "#924667",
|
|
45415
|
+
sensor: "#624bbc",
|
|
45416
|
+
control: "#944d24",
|
|
45417
|
+
face: "#ed4f8d",
|
|
45418
|
+
plate: "#4b7027",
|
|
45419
|
+
car: "#9684cf",
|
|
45420
|
+
truck: "#0f9b89",
|
|
45421
|
+
bus: "#a734a9",
|
|
45422
|
+
motorcycle: "#c1133a",
|
|
45423
|
+
bicycle: "#0e6a9b",
|
|
45424
|
+
airplane: "#7c9928",
|
|
45425
|
+
boat: "#b17933",
|
|
45426
|
+
train: "#ad6ca3",
|
|
45427
|
+
bird: "#0f7c55",
|
|
45428
|
+
dog: "#c82700",
|
|
45429
|
+
cat: "#7268f2",
|
|
45430
|
+
horse: "#cb795e",
|
|
45431
|
+
sheep: "#b8636b",
|
|
45432
|
+
cow: "#cb2969",
|
|
45433
|
+
elephant: "#1158d2",
|
|
45434
|
+
bear: "#8d5e00",
|
|
45435
|
+
zebra: "#0097d6",
|
|
45436
|
+
giraffe: "#8f61bb",
|
|
45437
|
+
"package-delivered": "#cd3f9b",
|
|
45438
|
+
"package-picked-up": "#388a08",
|
|
45439
|
+
suitcase: "#666800",
|
|
45440
|
+
backpack: "#ec5022",
|
|
45441
|
+
handbag: "#a76ef8",
|
|
45442
|
+
contact: "#ab5a49",
|
|
45443
|
+
"motion-sensor": "#b95d1a",
|
|
45444
|
+
smoke: "#dd3858",
|
|
45445
|
+
flood: "#b31e7d",
|
|
45446
|
+
gas: "#5b70b5",
|
|
45447
|
+
"carbon-monoxide": "#7b4e8e",
|
|
45448
|
+
vibration: "#e65bba",
|
|
45449
|
+
tamper: "#98464b",
|
|
45450
|
+
presence: "#3a9468",
|
|
45451
|
+
"enum-sensor": "#7885f8",
|
|
45452
|
+
"device-event": "#8c43c8",
|
|
45453
|
+
lock: "#649653",
|
|
45454
|
+
cover: "#c67597",
|
|
45455
|
+
switch: "#7a812a",
|
|
45456
|
+
siren: "#ac5d7f",
|
|
45457
|
+
button: "#b276cd",
|
|
45458
|
+
doorbell: "#0087ab"
|
|
45459
|
+
};
|
|
45460
|
+
var CAMSTACK_FALLBACK = [
|
|
45461
|
+
"#b34dc7",
|
|
45462
|
+
"#1d7d34",
|
|
45463
|
+
"#db6b6c",
|
|
45464
|
+
"#a43d29",
|
|
45465
|
+
"#0e6ee6",
|
|
45466
|
+
"#29a10b",
|
|
45467
|
+
"#a98731",
|
|
45468
|
+
"#0181c6"
|
|
45469
|
+
];
|
|
45470
|
+
var HIGH_CONTRAST_HEX = {
|
|
45471
|
+
motion: "#964360",
|
|
45472
|
+
audio: "#23a132",
|
|
45473
|
+
recording: "#2494ca",
|
|
45474
|
+
live: "#bd7e2b",
|
|
45475
|
+
heatmapScrub: "#ad6eea",
|
|
45476
|
+
person: "#62611e",
|
|
45477
|
+
vehicle: "#f4534c",
|
|
45478
|
+
animal: "#1556cd",
|
|
45479
|
+
package: "#9c4415",
|
|
45480
|
+
sensor: "#066c48",
|
|
45481
|
+
control: "#f2479f",
|
|
45482
|
+
face: "#139d8a",
|
|
45483
|
+
plate: "#909024",
|
|
45484
|
+
car: "#8e35ab",
|
|
45485
|
+
truck: "#bd0b2b",
|
|
45486
|
+
bus: "#7a88ca",
|
|
45487
|
+
motorcycle: "#e26725",
|
|
45488
|
+
bicycle: "#a6679b",
|
|
45489
|
+
airplane: "#7c5720",
|
|
45490
|
+
boat: "#467a1b",
|
|
45491
|
+
train: "#6f65a4",
|
|
45492
|
+
bird: "#cb717f",
|
|
45493
|
+
dog: "#c62490",
|
|
45494
|
+
cat: "#b36850",
|
|
45495
|
+
horse: "#1872ac",
|
|
45496
|
+
sheep: "#927939",
|
|
45497
|
+
cow: "#428a5c",
|
|
45498
|
+
elephant: "#d41160",
|
|
45499
|
+
bear: "#799453",
|
|
45500
|
+
zebra: "#a85455",
|
|
45501
|
+
giraffe: "#746be8",
|
|
45502
|
+
"package-delivered": "#824a80",
|
|
45503
|
+
"package-picked-up": "#614ac1",
|
|
45504
|
+
suitcase: "#2f77f3",
|
|
45505
|
+
backpack: "#fa476d",
|
|
45506
|
+
handbag: "#c14cbe",
|
|
45507
|
+
contact: "#c83921",
|
|
45508
|
+
"motion-sensor": "#a07ebd",
|
|
45509
|
+
smoke: "#a25b13",
|
|
45510
|
+
flood: "#526bab",
|
|
45511
|
+
gas: "#924938",
|
|
45512
|
+
"carbon-monoxide": "#bb7e53",
|
|
45513
|
+
vibration: "#b66182",
|
|
45514
|
+
tamper: "#3c6931",
|
|
45515
|
+
presence: "#6c851d",
|
|
45516
|
+
"enum-sensor": "#ad2d48",
|
|
45517
|
+
"device-event": "#5e9b04",
|
|
45518
|
+
lock: "#00a062",
|
|
45519
|
+
cover: "#ad8624",
|
|
45520
|
+
switch: "#d05259",
|
|
45521
|
+
siren: "#cd67b3",
|
|
45522
|
+
button: "#c9746a",
|
|
45523
|
+
doorbell: "#338eeb"
|
|
45524
|
+
};
|
|
45525
|
+
var HIGH_CONTRAST_FALLBACK = [
|
|
45526
|
+
"#817f3b",
|
|
45527
|
+
"#a0733e",
|
|
45528
|
+
"#8658b2",
|
|
45529
|
+
"#956301",
|
|
45530
|
+
"#bc652d",
|
|
45531
|
+
"#647331",
|
|
45532
|
+
"#a14c9e",
|
|
45533
|
+
"#d14e71"
|
|
45534
|
+
];
|
|
45535
|
+
var OKABE_ITO_HEX = {
|
|
45536
|
+
motion: "#b88128",
|
|
45537
|
+
audio: "#1096c8",
|
|
45538
|
+
recording: "#009e73",
|
|
45539
|
+
live: "#9c8c22",
|
|
45540
|
+
heatmapScrub: "#0072b2",
|
|
45541
|
+
person: "#d55e00",
|
|
45542
|
+
vehicle: "#c0739f",
|
|
45543
|
+
animal: "#226d18",
|
|
45544
|
+
package: "#91446c",
|
|
45545
|
+
sensor: "#217b56",
|
|
45546
|
+
control: "#648647",
|
|
45547
|
+
face: "#c22998",
|
|
45548
|
+
plate: "#fa4575",
|
|
45549
|
+
car: "#956301",
|
|
45550
|
+
truck: "#2f77f3",
|
|
45551
|
+
bus: "#7a4e86",
|
|
45552
|
+
motorcycle: "#f54597",
|
|
45553
|
+
bicycle: "#bb3e75",
|
|
45554
|
+
airplane: "#e054c0",
|
|
45555
|
+
boat: "#457942",
|
|
45556
|
+
train: "#867afa",
|
|
45557
|
+
bird: "#88914c",
|
|
45558
|
+
dog: "#1556cd",
|
|
45559
|
+
cat: "#71702c",
|
|
45560
|
+
horse: "#9b4fa4",
|
|
45561
|
+
sheep: "#c0559d",
|
|
45562
|
+
cow: "#d14f65",
|
|
45563
|
+
elephant: "#98470f",
|
|
45564
|
+
bear: "#595896",
|
|
45565
|
+
zebra: "#96790e",
|
|
45566
|
+
giraffe: "#cb717b",
|
|
45567
|
+
"package-delivered": "#139d8a",
|
|
45568
|
+
"package-picked-up": "#906ead",
|
|
45569
|
+
suitcase: "#d02939",
|
|
45570
|
+
backpack: "#d41160",
|
|
45571
|
+
handbag: "#f64f54",
|
|
45572
|
+
contact: "#7258d2",
|
|
45573
|
+
"motion-sensor": "#b66182",
|
|
45574
|
+
smoke: "#627abb",
|
|
45575
|
+
flood: "#b86ae4",
|
|
45576
|
+
gas: "#a95261",
|
|
45577
|
+
"carbon-monoxide": "#c65d3c",
|
|
45578
|
+
vibration: "#7a40b7",
|
|
45579
|
+
tamper: "#914b34",
|
|
45580
|
+
presence: "#9481c3",
|
|
45581
|
+
"enum-sensor": "#ac6d47",
|
|
45582
|
+
"device-event": "#7b6fce",
|
|
45583
|
+
lock: "#c67662",
|
|
45584
|
+
cover: "#a6564d",
|
|
45585
|
+
switch: "#ad2c4e",
|
|
45586
|
+
siren: "#348e08",
|
|
45587
|
+
button: "#d27303",
|
|
45588
|
+
doorbell: "#55770f"
|
|
45589
|
+
};
|
|
45590
|
+
var OKABE_ITO_FALLBACK = [
|
|
45591
|
+
"#9a3784",
|
|
45592
|
+
"#a7392c",
|
|
45593
|
+
"#409d50",
|
|
45594
|
+
"#6987e7",
|
|
45595
|
+
"#ee5b3d",
|
|
45596
|
+
"#c0430d",
|
|
45597
|
+
"#af79b3",
|
|
45598
|
+
"#4b6628"
|
|
45599
|
+
];
|
|
45600
|
+
/**
|
|
45601
|
+
* The display palette (D939). One table of colours, three presets, one
|
|
45602
|
+
* validator. Taxonomy colours and every consumer read this — there is no
|
|
45603
|
+
* second hex table.
|
|
45604
|
+
*/
|
|
45605
|
+
var paletteHexSchema = string().regex(/^#[0-9a-f]{6}$/);
|
|
45606
|
+
var paletteSwatchSchema = discriminatedUnion("form", [object({
|
|
45607
|
+
form: literal("solid"),
|
|
45608
|
+
hex: paletteHexSchema
|
|
45609
|
+
}), object({
|
|
45610
|
+
form: literal("gradient"),
|
|
45611
|
+
hex: paletteHexSchema,
|
|
45612
|
+
alphas: array(number().gt(0).lte(1)).length(AUDIO_GRADIENT_ALPHAS.length)
|
|
45613
|
+
})]);
|
|
45614
|
+
var paletteReadySchema = object({
|
|
45615
|
+
status: literal("ready"),
|
|
45616
|
+
presetId: _enum(PALETTE_PRESET_IDS),
|
|
45617
|
+
customized: boolean(),
|
|
45618
|
+
source: _enum(["stored", "unconfigured"]),
|
|
45619
|
+
swatches: record(string(), paletteSwatchSchema),
|
|
45620
|
+
fallbacks: array(paletteHexSchema).length(8)
|
|
45621
|
+
});
|
|
45622
|
+
var paletteResultSchema = discriminatedUnion("status", [paletteReadySchema, object({
|
|
45623
|
+
status: literal("unknown"),
|
|
45624
|
+
reason: string()
|
|
45625
|
+
})]);
|
|
45626
|
+
var setPaletteInputSchema = union([object({ presetId: string() }), object({
|
|
45627
|
+
presetId: string(),
|
|
45628
|
+
overrides: record(string(), paletteSwatchSchema)
|
|
45629
|
+
})]);
|
|
45630
|
+
var storedPaletteSchema = object({
|
|
45631
|
+
presetId: string(),
|
|
45632
|
+
overrides: record(string(), paletteSwatchSchema)
|
|
45633
|
+
});
|
|
45634
|
+
function solid(hex) {
|
|
45635
|
+
return {
|
|
45636
|
+
form: "solid",
|
|
45637
|
+
hex
|
|
45638
|
+
};
|
|
45639
|
+
}
|
|
45640
|
+
function audioGradient(hex) {
|
|
45641
|
+
return {
|
|
45642
|
+
form: "gradient",
|
|
45643
|
+
hex,
|
|
45644
|
+
alphas: [...AUDIO_GRADIENT_ALPHAS]
|
|
45645
|
+
};
|
|
45646
|
+
}
|
|
45647
|
+
function swatchesFrom(hexes) {
|
|
45648
|
+
const out = {};
|
|
45649
|
+
for (const id of PALETTE_ENTRY_IDS) {
|
|
45650
|
+
const hex = hexes[id];
|
|
45651
|
+
if (hex === void 0) throw new Error(`palette table missing ${id}`);
|
|
45652
|
+
out[id] = id === "audio" ? audioGradient(hex) : solid(hex);
|
|
45653
|
+
}
|
|
45654
|
+
return out;
|
|
45655
|
+
}
|
|
45656
|
+
function preset(id, name, hexes, fallbacks) {
|
|
45657
|
+
return {
|
|
45658
|
+
id,
|
|
45659
|
+
name,
|
|
45660
|
+
swatches: swatchesFrom(hexes),
|
|
45661
|
+
fallbacks
|
|
45662
|
+
};
|
|
45663
|
+
}
|
|
45664
|
+
var DISPLAY_PRESETS = [
|
|
45665
|
+
preset("camstack", "CamStack", CAMSTACK_HEX, CAMSTACK_FALLBACK),
|
|
45666
|
+
preset("high-contrast", "High contrast", HIGH_CONTRAST_HEX, HIGH_CONTRAST_FALLBACK),
|
|
45667
|
+
preset("okabe-ito", "Colour-blind safe", OKABE_ITO_HEX, OKABE_ITO_FALLBACK)
|
|
45668
|
+
];
|
|
45669
|
+
function presetById(id) {
|
|
45670
|
+
return DISPLAY_PRESETS.find((item) => item.id === id);
|
|
45671
|
+
}
|
|
45672
|
+
function bundledCamstack() {
|
|
45673
|
+
const presetRow = presetById("camstack");
|
|
45674
|
+
if (presetRow === void 0) throw new Error("CamStack preset missing");
|
|
45675
|
+
return readyOf(presetRow, "unconfigured", false);
|
|
45676
|
+
}
|
|
45677
|
+
function readyOf(row, source, customized) {
|
|
45678
|
+
return {
|
|
45679
|
+
status: "ready",
|
|
45680
|
+
presetId: row.id,
|
|
45681
|
+
customized,
|
|
45682
|
+
source,
|
|
45683
|
+
swatches: row.swatches,
|
|
45684
|
+
fallbacks: [...row.fallbacks]
|
|
45685
|
+
};
|
|
45686
|
+
}
|
|
45687
|
+
function namedColours(swatches, fallbacks) {
|
|
45688
|
+
const rows = [];
|
|
45689
|
+
for (const id of PALETTE_ENTRY_IDS) {
|
|
45690
|
+
const swatch = swatches[id];
|
|
45691
|
+
if (swatch !== void 0) rows.push({
|
|
45692
|
+
name: id,
|
|
45693
|
+
hex: swatch.hex
|
|
45694
|
+
});
|
|
45695
|
+
}
|
|
45696
|
+
fallbacks.forEach((hex, index) => {
|
|
45697
|
+
rows.push({
|
|
45698
|
+
name: `fallback-${index}`,
|
|
45699
|
+
hex
|
|
45700
|
+
});
|
|
45701
|
+
});
|
|
45702
|
+
return rows;
|
|
45703
|
+
}
|
|
45704
|
+
function gradientViolations(swatches) {
|
|
45705
|
+
const audio = swatches[AUDIO_ENTRY_ID];
|
|
45706
|
+
if (audio === void 0) return [];
|
|
45707
|
+
if (audio.form !== "gradient") return [{
|
|
45708
|
+
code: "bad-gradient",
|
|
45709
|
+
entry: AUDIO_ENTRY_ID
|
|
45710
|
+
}];
|
|
45711
|
+
return AUDIO_GRADIENT_ALPHAS.every((alpha, index) => audio.alphas[index] === alpha) ? [] : [{
|
|
45712
|
+
code: "bad-gradient",
|
|
45713
|
+
entry: AUDIO_ENTRY_ID
|
|
45714
|
+
}];
|
|
45715
|
+
}
|
|
45716
|
+
function isMarkPair(left, right) {
|
|
45717
|
+
const marks = PALETTE_MARK_PAIR;
|
|
45718
|
+
return marks.includes(left) && marks.includes(right);
|
|
45719
|
+
}
|
|
45720
|
+
/** Refuse a palette whose entries are not pairwise distinct on both themes. */
|
|
45721
|
+
function validatePalette(swatches, fallbacks) {
|
|
45722
|
+
const violations = [];
|
|
45723
|
+
for (const id of PALETTE_ENTRY_IDS) if (swatches[id] === void 0) violations.push({
|
|
45724
|
+
code: "missing-entry",
|
|
45725
|
+
entry: id
|
|
45726
|
+
});
|
|
45727
|
+
for (const key of Object.keys(swatches)) if (!isPaletteEntryId(key)) violations.push({
|
|
45728
|
+
code: "unknown-entry",
|
|
45729
|
+
entry: key
|
|
45730
|
+
});
|
|
45731
|
+
if (fallbacks.length !== 8) violations.push({ code: "bad-fallbacks" });
|
|
45732
|
+
violations.push(...gradientViolations(swatches));
|
|
45733
|
+
const rows = namedColours(swatches, fallbacks);
|
|
45734
|
+
for (let i = 0; i < rows.length; i++) for (let j = i + 1; j < rows.length; j++) {
|
|
45735
|
+
const left = rows[i];
|
|
45736
|
+
const right = rows[j];
|
|
45737
|
+
if (left === void 0 || right === void 0) continue;
|
|
45738
|
+
const deltaE = deltaE00(left.hex, right.hex);
|
|
45739
|
+
if (deltaE < (isMarkPair(left.name, right.name) ? 20 : 7)) violations.push({
|
|
45740
|
+
code: "too-close",
|
|
45741
|
+
left: left.name,
|
|
45742
|
+
right: right.name,
|
|
45743
|
+
deltaE
|
|
45744
|
+
});
|
|
45745
|
+
}
|
|
45746
|
+
for (const row of rows) for (const background of ["dark", "light"]) {
|
|
45747
|
+
const contrast = contrastRatio(row.hex, PALETTE_BACKGROUNDS[background]);
|
|
45748
|
+
if (contrast < 3) violations.push({
|
|
45749
|
+
code: "low-contrast",
|
|
45750
|
+
entry: row.name,
|
|
45751
|
+
background,
|
|
45752
|
+
contrast
|
|
45753
|
+
});
|
|
45754
|
+
}
|
|
45755
|
+
return violations.length === 0 ? { ok: true } : {
|
|
45756
|
+
ok: false,
|
|
45757
|
+
violations
|
|
45758
|
+
};
|
|
45759
|
+
}
|
|
45760
|
+
function formatPaletteViolation(violation) {
|
|
45761
|
+
switch (violation.code) {
|
|
45762
|
+
case "too-close": return `${violation.left} vs ${violation.right} (ΔE ${violation.deltaE.toFixed(1)})`;
|
|
45763
|
+
case "low-contrast": return `${violation.entry} on ${violation.background} (${violation.contrast.toFixed(1)}:1)`;
|
|
45764
|
+
case "missing-entry": return `${violation.entry} is missing`;
|
|
45765
|
+
case "unknown-entry": return `${violation.entry} is not a palette entry`;
|
|
45766
|
+
case "bad-gradient": return `${violation.entry} gradient is not the six canonical steps`;
|
|
45767
|
+
case "bad-fallbacks": return "fallback list must hold eight colours";
|
|
45768
|
+
case "unknown-preset": return `${violation.presetId} is not a preset`;
|
|
45769
|
+
}
|
|
45770
|
+
}
|
|
45771
|
+
function formatPaletteViolations(violations) {
|
|
45772
|
+
return violations.map(formatPaletteViolation).join("; ");
|
|
45773
|
+
}
|
|
45774
|
+
var PaletteRejectedError = class extends Error {
|
|
45775
|
+
violations;
|
|
45776
|
+
constructor(violations) {
|
|
45777
|
+
super(formatPaletteViolations(violations));
|
|
45778
|
+
this.name = "PaletteRejectedError";
|
|
45779
|
+
this.violations = violations;
|
|
45780
|
+
}
|
|
45781
|
+
};
|
|
45782
|
+
function hashFallback(kind, fallbacks) {
|
|
45783
|
+
let hash = 0;
|
|
45784
|
+
for (let i = 0; i < kind.length; i++) hash = hash * 31 + (kind.codePointAt(i) ?? 0) >>> 0;
|
|
45785
|
+
const hex = fallbacks[hash % fallbacks.length];
|
|
45786
|
+
if (hex === void 0) throw new Error("display palette has no fallback colour");
|
|
45787
|
+
return hex;
|
|
45788
|
+
}
|
|
45789
|
+
/** Colour a kind paints with. Audio leaves share the audio gradient's hex. */
|
|
45790
|
+
function paintHex(swatches, fallbacks, kind) {
|
|
45791
|
+
const key = kind.trim().toLowerCase();
|
|
45792
|
+
if (key.startsWith("audio-")) {
|
|
45793
|
+
const audio = swatches[AUDIO_ENTRY_ID];
|
|
45794
|
+
return audio !== void 0 ? audio.hex : hashFallback(key, fallbacks);
|
|
45795
|
+
}
|
|
45796
|
+
const direct = swatches[key];
|
|
45797
|
+
if (direct !== void 0) return direct.hex;
|
|
45798
|
+
return hashFallback(key, fallbacks);
|
|
45799
|
+
}
|
|
45800
|
+
function mergeOverrides(base, overrides) {
|
|
45801
|
+
return {
|
|
45802
|
+
...base,
|
|
45803
|
+
...overrides
|
|
45804
|
+
};
|
|
45805
|
+
}
|
|
45806
|
+
function overridesOf(input) {
|
|
45807
|
+
return "overrides" in input ? input.overrides : {};
|
|
45808
|
+
}
|
|
45809
|
+
/** The palette a `setPalette` input would store. Invalid input is a refusal. */
|
|
45810
|
+
function paletteFromInput(input) {
|
|
45811
|
+
const row = presetById(input.presetId);
|
|
45812
|
+
if (row === void 0 || !isPalettePresetId(input.presetId)) throw new PaletteRejectedError([{
|
|
45813
|
+
code: "unknown-preset",
|
|
45814
|
+
presetId: input.presetId
|
|
45815
|
+
}]);
|
|
45816
|
+
const overrides = overridesOf(input);
|
|
45817
|
+
const swatches = mergeOverrides(row.swatches, overrides);
|
|
45818
|
+
const verdict = validatePalette(swatches, row.fallbacks);
|
|
45819
|
+
if (!verdict.ok) throw new PaletteRejectedError(verdict.violations);
|
|
45820
|
+
const customized = Object.keys(overrides).length > 0;
|
|
45821
|
+
return {
|
|
45822
|
+
status: "ready",
|
|
45823
|
+
presetId: row.id,
|
|
45824
|
+
customized,
|
|
45825
|
+
source: "stored",
|
|
45826
|
+
swatches,
|
|
45827
|
+
fallbacks: [...row.fallbacks]
|
|
45828
|
+
};
|
|
45829
|
+
}
|
|
45830
|
+
function isEmptyRecord(value) {
|
|
45831
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length === 0;
|
|
45832
|
+
}
|
|
45833
|
+
/**
|
|
45834
|
+
* Interpret a settings blob. A missing row is the bundled preset and says so.
|
|
45835
|
+
* A blob that does not parse, names an unknown preset, or fails the rule is
|
|
45836
|
+
* `unknown` — never the default wearing the stored preset's name.
|
|
45837
|
+
*/
|
|
45838
|
+
function paletteFromStored(value) {
|
|
45839
|
+
if (value === void 0 || value === null || isEmptyRecord(value)) return bundledCamstack();
|
|
45840
|
+
const parsed = storedPaletteSchema.safeParse(value);
|
|
45841
|
+
if (!parsed.success) return {
|
|
45842
|
+
status: "unknown",
|
|
45843
|
+
reason: "stored palette is unreadable"
|
|
45844
|
+
};
|
|
45845
|
+
const row = presetById(parsed.data.presetId);
|
|
45846
|
+
if (row === void 0) return {
|
|
45847
|
+
status: "unknown",
|
|
45848
|
+
reason: `unknown preset ${parsed.data.presetId}`
|
|
45849
|
+
};
|
|
45850
|
+
const swatches = mergeOverrides(row.swatches, parsed.data.overrides);
|
|
45851
|
+
const verdict = validatePalette(swatches, row.fallbacks);
|
|
45852
|
+
if (!verdict.ok) return {
|
|
45853
|
+
status: "unknown",
|
|
45854
|
+
reason: formatPaletteViolations(verdict.violations)
|
|
45855
|
+
};
|
|
45856
|
+
const customized = Object.keys(parsed.data.overrides).length > 0;
|
|
45857
|
+
return {
|
|
45858
|
+
status: "ready",
|
|
45859
|
+
presetId: row.id,
|
|
45860
|
+
customized,
|
|
45861
|
+
source: "stored",
|
|
45862
|
+
swatches,
|
|
45863
|
+
fallbacks: [...row.fallbacks]
|
|
45864
|
+
};
|
|
45865
|
+
}
|
|
45866
|
+
function storedFromReady(ready, overrides) {
|
|
45867
|
+
return {
|
|
45868
|
+
presetId: ready.presetId,
|
|
45869
|
+
overrides: { ...overrides }
|
|
45870
|
+
};
|
|
45871
|
+
}
|
|
45872
|
+
/**
|
|
43254
45873
|
* Unified event-kind taxonomy — THE single source of truth for
|
|
43255
45874
|
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
43256
45875
|
* icon }`.
|
|
@@ -43264,109 +45883,88 @@ for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set
|
|
|
43264
45883
|
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
43265
45884
|
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
43266
45885
|
*
|
|
43267
|
-
* The DATA (serializable —
|
|
43268
|
-
* `@camstack/types`.
|
|
43269
|
-
*
|
|
43270
|
-
*
|
|
43271
|
-
*
|
|
45886
|
+
* The DATA (serializable — parentKind / iconId / labelKey) lives here in
|
|
45887
|
+
* `@camstack/types`. Colour is NOT a second table: each entry's `color` is
|
|
45888
|
+
* the bundled CamStack display palette (D939). The effective cluster palette
|
|
45889
|
+
* is the `display-palette` capability. The UI-side mapping `iconId → lucide
|
|
45890
|
+
* component` and `labelKey → t()` lives in `@camstack/ui-library`.
|
|
43272
45891
|
*
|
|
43273
45892
|
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
43274
45893
|
*/
|
|
43275
|
-
var
|
|
43276
|
-
|
|
43277
|
-
|
|
43278
|
-
|
|
43279
|
-
|
|
43280
|
-
|
|
43281
|
-
|
|
43282
|
-
|
|
43283
|
-
|
|
43284
|
-
|
|
43285
|
-
};
|
|
43286
|
-
var DETECTION_SUB_COLORS = {
|
|
43287
|
-
car: "#f59e0b",
|
|
43288
|
-
truck: "#d97706",
|
|
43289
|
-
bus: "#b45309",
|
|
43290
|
-
motorcycle: "#eab308",
|
|
43291
|
-
bicycle: "#ca8a04",
|
|
43292
|
-
airplane: "#60a5fa",
|
|
43293
|
-
boat: "#2563eb",
|
|
43294
|
-
train: "#1d4ed8",
|
|
43295
|
-
bird: "#14b8a6",
|
|
43296
|
-
dog: "#84cc16",
|
|
43297
|
-
cat: "#f97316",
|
|
43298
|
-
horse: "#a16207",
|
|
43299
|
-
sheep: "#a3a3a3",
|
|
43300
|
-
cow: "#78716c",
|
|
43301
|
-
elephant: "#6b7280",
|
|
43302
|
-
bear: "#7c2d12",
|
|
43303
|
-
zebra: "#404040",
|
|
43304
|
-
giraffe: "#d4a373"
|
|
43305
|
-
};
|
|
45894
|
+
var BUNDLED_PALETTE = bundledCamstack();
|
|
45895
|
+
function kindColor(kind) {
|
|
45896
|
+
return paintHex(BUNDLED_PALETTE.swatches, BUNDLED_PALETTE.fallbacks, kind);
|
|
45897
|
+
}
|
|
45898
|
+
function firstFallback(fallbacks) {
|
|
45899
|
+
const hex = fallbacks[0];
|
|
45900
|
+
if (hex === void 0) throw new Error("display palette has no fallback colour");
|
|
45901
|
+
return hex;
|
|
45902
|
+
}
|
|
45903
|
+
firstFallback(BUNDLED_PALETTE.fallbacks);
|
|
43306
45904
|
function titleCase(id) {
|
|
43307
45905
|
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
43308
45906
|
}
|
|
43309
45907
|
var entries = /* @__PURE__ */ new Map();
|
|
43310
|
-
function macro(kind, category,
|
|
45908
|
+
function macro(kind, category, iconId, label) {
|
|
43311
45909
|
entries.set(kind, {
|
|
43312
45910
|
kind,
|
|
43313
45911
|
parentKind: null,
|
|
43314
45912
|
level: "macro",
|
|
43315
45913
|
category,
|
|
43316
|
-
color,
|
|
45914
|
+
color: kindColor(kind),
|
|
43317
45915
|
iconId,
|
|
43318
45916
|
labelKey: `eventKind.${kind}`,
|
|
43319
45917
|
label
|
|
43320
45918
|
});
|
|
43321
45919
|
}
|
|
43322
|
-
function sub(kind, parentKind, category,
|
|
45920
|
+
function sub(kind, parentKind, category, iconId, label) {
|
|
43323
45921
|
entries.set(kind, {
|
|
43324
45922
|
kind,
|
|
43325
45923
|
parentKind,
|
|
43326
45924
|
level: "sub",
|
|
43327
45925
|
category,
|
|
43328
|
-
color,
|
|
45926
|
+
color: kindColor(kind),
|
|
43329
45927
|
iconId,
|
|
43330
45928
|
labelKey: `eventKind.${kind}`,
|
|
43331
45929
|
label
|
|
43332
45930
|
});
|
|
43333
45931
|
}
|
|
43334
|
-
macro("motion", "motion",
|
|
43335
|
-
macro("audio", "audio",
|
|
43336
|
-
macro("person", "detection",
|
|
43337
|
-
macro("vehicle", "detection",
|
|
43338
|
-
macro("animal", "detection",
|
|
43339
|
-
macro("package", "package",
|
|
43340
|
-
macro("sensor", "sensor",
|
|
43341
|
-
macro("control", "control",
|
|
45932
|
+
macro("motion", "motion", "motion", "Motion");
|
|
45933
|
+
macro("audio", "audio", "audio", "Audio");
|
|
45934
|
+
macro("person", "detection", "person", "Person");
|
|
45935
|
+
macro("vehicle", "detection", "vehicle", "Vehicle");
|
|
45936
|
+
macro("animal", "detection", "animal", "Animal");
|
|
45937
|
+
macro("package", "package", "package", "Package");
|
|
45938
|
+
macro("sensor", "sensor", "sensor", "Sensor");
|
|
45939
|
+
macro("control", "control", "control", "Control");
|
|
43342
45940
|
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
43343
45941
|
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
43344
45942
|
if (entries.has(cocoClass)) continue;
|
|
43345
|
-
sub(cocoClass, macroClass, "detection",
|
|
43346
|
-
}
|
|
43347
|
-
sub("package-delivered", "package", "package",
|
|
43348
|
-
sub("package-picked-up", "package", "package",
|
|
43349
|
-
sub("contact", "sensor", "sensor", "
|
|
43350
|
-
sub("motion-sensor", "sensor", "sensor",
|
|
43351
|
-
sub("smoke", "sensor", "sensor", "
|
|
43352
|
-
sub("flood", "sensor", "sensor", "
|
|
43353
|
-
sub("gas", "sensor", "sensor", "
|
|
43354
|
-
sub("carbon-monoxide", "sensor", "sensor", "
|
|
43355
|
-
sub("vibration", "sensor", "sensor", "
|
|
43356
|
-
sub("tamper", "sensor", "sensor", "
|
|
43357
|
-
sub("presence", "sensor", "sensor", "
|
|
43358
|
-
sub("enum-sensor", "sensor", "sensor",
|
|
43359
|
-
sub("device-event", "sensor", "sensor", "
|
|
43360
|
-
sub("lock", "control", "control", "
|
|
43361
|
-
sub("cover", "control", "control", "
|
|
43362
|
-
sub("switch", "control", "control",
|
|
43363
|
-
sub("siren", "control", "control", "
|
|
43364
|
-
sub("button", "control", "control", "
|
|
43365
|
-
sub("doorbell", "control", "control", "
|
|
45943
|
+
sub(cocoClass, macroClass, "detection", cocoClass, titleCase(cocoClass));
|
|
45944
|
+
}
|
|
45945
|
+
sub("package-delivered", "package", "package", "package", "Package delivered");
|
|
45946
|
+
sub("package-picked-up", "package", "package", "package", "Package picked up");
|
|
45947
|
+
sub("contact", "sensor", "sensor", "door", "Contact");
|
|
45948
|
+
sub("motion-sensor", "sensor", "sensor", "pir", "Motion sensor");
|
|
45949
|
+
sub("smoke", "sensor", "sensor", "smoke", "Smoke");
|
|
45950
|
+
sub("flood", "sensor", "sensor", "water", "Water leak");
|
|
45951
|
+
sub("gas", "sensor", "sensor", "gas", "Gas");
|
|
45952
|
+
sub("carbon-monoxide", "sensor", "sensor", "smoke", "Carbon monoxide");
|
|
45953
|
+
sub("vibration", "sensor", "sensor", "vibration", "Vibration");
|
|
45954
|
+
sub("tamper", "sensor", "sensor", "tamper", "Tamper");
|
|
45955
|
+
sub("presence", "sensor", "sensor", "presence", "Presence");
|
|
45956
|
+
sub("enum-sensor", "sensor", "sensor", "generic", "Sensor state");
|
|
45957
|
+
sub("device-event", "sensor", "sensor", "button", "Device event");
|
|
45958
|
+
sub("lock", "control", "control", "lock", "Lock");
|
|
45959
|
+
sub("cover", "control", "control", "door", "Cover");
|
|
45960
|
+
sub("switch", "control", "control", "switch", "Switch");
|
|
45961
|
+
sub("siren", "control", "control", "siren", "Siren");
|
|
45962
|
+
sub("button", "control", "control", "button", "Button");
|
|
45963
|
+
sub("doorbell", "control", "control", "doorbell", "Doorbell");
|
|
43366
45964
|
for (const l of AUDIO_MACRO_LABELS) {
|
|
43367
45965
|
const kind = `audio-${l.id}`;
|
|
43368
45966
|
if (entries.has(kind)) continue;
|
|
43369
|
-
sub(kind, "audio", "audio",
|
|
45967
|
+
sub(kind, "audio", "audio", kind, l.name);
|
|
43370
45968
|
}
|
|
43371
45969
|
/** The complete taxonomy dictionary, keyed by kind. */
|
|
43372
45970
|
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
@@ -44209,7 +46807,7 @@ var NcConditionsSchema = object({
|
|
|
44209
46807
|
* with the list under it is worse than no switch (D62).
|
|
44210
46808
|
*
|
|
44211
46809
|
* MEMBERS ARE FACE-GALLERY `Identity.id`s (uuid), not display names. A name is
|
|
44212
|
-
* renameable, and a rule authored on "
|
|
46810
|
+
* renameable, and a rule authored on "Alice" went silently dark the moment
|
|
44213
46811
|
* the operator fixed the spelling. The id reaches the record on
|
|
44214
46812
|
* `LabelAttribution.identityId`; the name is what the editor shows and what
|
|
44215
46813
|
* `{{label}}` renders.
|
|
@@ -44760,7 +47358,7 @@ var NcRulePatchSchema = NcRuleInputSchema.partial().extend({
|
|
|
44760
47358
|
* A rule scoped to one camera and one zone silently became a rule that
|
|
44761
47359
|
* matches EVERY event on EVERY camera, and lost its `media` policy
|
|
44762
47360
|
* (zoneCrop / gif / clip / frame) and its `priority` at the same time. Seen
|
|
44763
|
-
* live on 2026-08-12: a rule scoped to device
|
|
47361
|
+
* live on 2026-08-12: a rule scoped to device 102 fired on 104 and 101
|
|
44764
47362
|
* within a minute of a two-field patch.
|
|
44765
47363
|
*
|
|
44766
47364
|
* So every defaulted field is re-declared here WITHOUT its default. The
|
|
@@ -46623,7 +49221,7 @@ var LabelAttributionSchema = object({
|
|
|
46623
49221
|
* `Identity.id` or a plate-gallery `Vehicle.id` (both `randomUUID`).
|
|
46624
49222
|
*
|
|
46625
49223
|
* The text alone is a DISPLAY NAME, and a display name is renameable: a
|
|
46626
|
-
* notification rule authored on "
|
|
49224
|
+
* notification rule authored on "Alice" stopped matching the moment the
|
|
46627
49225
|
* operator fixed the spelling in the gallery, and nothing said so. The id is
|
|
46628
49226
|
* the thing that does not move, so it is what a rule matches on
|
|
46629
49227
|
* (`NcConditions.identities`) and the text is what a human is shown.
|
|
@@ -49275,7 +51873,7 @@ var pipelineExecutorCapability = {
|
|
|
49275
51873
|
/**
|
|
49276
51874
|
* Root-supplied detections for the tree's ROOT step (D730). Set by
|
|
49277
51875
|
* `runDetailSubtree` when the camera's root model supplies a crop-kind
|
|
49278
|
-
* step (a
|
|
51876
|
+
* step (a plus catalog `license_plate` for `plate-detection`): the step is
|
|
49279
51877
|
* NOT inferred, these boxes are its output, and its children (the plate
|
|
49280
51878
|
* reader) run on them through their own crop policy. Boxes are in the
|
|
49281
51879
|
* PIXELS of the image this call carries. Absent ⇒ the root step runs.
|
|
@@ -51043,7 +53641,7 @@ var RunnerCameraConfigSchema = object({
|
|
|
51043
53641
|
* detection session that asks for history. What shipped was a last-moment
|
|
51044
53642
|
* discard — `FrameSlot`'s throttle compares wall clocks, and ~4 s of media
|
|
51045
53643
|
* arriving inside a few hundred ms of wall clock looks to it like one frame's
|
|
51046
|
-
* worth. Device
|
|
53644
|
+
* worth. Device 102, 2026-09-08: a re-run of the SAME model over the stored
|
|
51047
53645
|
* recording scored the subject `vehicle 0.5669` — above the 0.50 floor —
|
|
51048
53646
|
* 1.68 s BEFORE the live track was born, on a frame that was in the pre-roll,
|
|
51049
53647
|
* was decoded, and was freed.
|
|
@@ -53698,7 +56296,7 @@ method(_void(), ProviderInfoSchema, { auth: "admin" }), method(object({ config:
|
|
|
53698
56296
|
* The signals a device can emit to WAKE its own stream.
|
|
53699
56297
|
*
|
|
53700
56298
|
* A camera whose stream is built on demand sleeps until something asks for it,
|
|
53701
|
-
* and "something" cannot be a consumer that is merely attached — a
|
|
56299
|
+
* and "something" cannot be a consumer that is merely attached — a external-catalog
|
|
53702
56300
|
* puller holds a session open for ever, and treating that as demand would keep
|
|
53703
56301
|
* a battery camera awake for ever, which is the whole thing the battery is for
|
|
53704
56302
|
* (D173). So the wake has to come from the CAMERA: an event it noticed by
|
|
@@ -54385,7 +56983,7 @@ var ClipSchema = object({
|
|
|
54385
56983
|
* {@link MAX_CLIP_EVENT_IDS}. Empty on footage-only clips.
|
|
54386
56984
|
*
|
|
54387
56985
|
* Bounded because it is not a payload the surface pages through: one visit on
|
|
54388
|
-
* device
|
|
56986
|
+
* device 101 carried 2 345 ids, and `eventIds` was 99% of a 153 KB
|
|
54389
56987
|
* camera-day. Read {@link eventCount} for the true total.
|
|
54390
56988
|
*/
|
|
54391
56989
|
eventIds: array(string()).optional(),
|
|
@@ -54530,7 +57128,7 @@ var ClipPlaybackSchema = object({
|
|
|
54530
57128
|
* camera has no recordings", which is the defect this whole line of work is
|
|
54531
57129
|
* about: a battery camera nobody woke (`sleeping`), a camera that could not be
|
|
54532
57130
|
* reached at all (`unreachable`, also what a provider that THREW reports), a
|
|
54533
|
-
* camera whose SD card is not mounted (`no-storage`, measured on
|
|
57131
|
+
* camera whose SD card is not mounted (`no-storage`, measured on 106 —
|
|
54534
57132
|
* `HddInfo mount 0`, honestly nothing to list rather than "no clips"), and a
|
|
54535
57133
|
* camera whose OWN index disagrees with its OWN calendar (`index-empty`,
|
|
54536
57134
|
* measured on 618: the calendar marks 3–20 September, days 6–20 list zero
|
|
@@ -54795,7 +57393,7 @@ DeviceType.Camera, method(object({
|
|
|
54795
57393
|
*
|
|
54796
57394
|
* It was optional, documented as "absent means the device's BOUND
|
|
54797
57395
|
* provider, which is CamStack on every camera". No code implemented
|
|
54798
|
-
* that. Measured on the live hub 2026-09-20 — device
|
|
57396
|
+
* that. Measured on the live hub 2026-09-20 — device 107, bound to
|
|
54799
57397
|
* `recorder` AND `provider-reolink` — a bare call with `limit: 3`
|
|
54800
57398
|
* answered SIX rows, three from each source, merged newest-first:
|
|
54801
57399
|
* `device-collection-dispatch.ts` simply left the fan-out un-narrowed,
|
|
@@ -55873,7 +58471,10 @@ object({
|
|
|
55873
58471
|
DeviceType.Sensor;
|
|
55874
58472
|
object({
|
|
55875
58473
|
/** Current illuminance in lux (lx). */
|
|
55876
|
-
lux: number().min(0)
|
|
58474
|
+
lux: number().min(0).meta({
|
|
58475
|
+
unit: "lx",
|
|
58476
|
+
label: "Illuminance"
|
|
58477
|
+
}),
|
|
55877
58478
|
/** Ms epoch when the slice was last updated. */
|
|
55878
58479
|
lastFetchedAt: number(),
|
|
55879
58480
|
/** Live display unit from the upstream source (e.g. HA
|
|
@@ -56029,7 +58630,10 @@ var BatteryStatusSchema = object({
|
|
|
56029
58630
|
* Consumers must SKIP a null rather than coerce it — `battery-band` already
|
|
56030
58631
|
* declines to band a non-finite reading, which is the correct shape.
|
|
56031
58632
|
*/
|
|
56032
|
-
percentage: number().min(0).max(100).nullable()
|
|
58633
|
+
percentage: number().min(0).max(100).nullable().meta({
|
|
58634
|
+
unit: "%",
|
|
58635
|
+
label: "Charge"
|
|
58636
|
+
}),
|
|
56033
58637
|
/**
|
|
56034
58638
|
* Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
|
|
56035
58639
|
* Reolink-specific for the Solar Panel 2 accessory (will become
|
|
@@ -56048,13 +58652,13 @@ var BatteryStatusSchema = object({
|
|
|
56048
58652
|
"solar",
|
|
56049
58653
|
"none",
|
|
56050
58654
|
"unknown"
|
|
56051
|
-
]),
|
|
58655
|
+
]).meta({ label: "Charging source" }),
|
|
56052
58656
|
/**
|
|
56053
58657
|
* True when the camera firmware has gone into low-power mode. Battery
|
|
56054
58658
|
* providers MUST avoid polling during sleep — reading the battery
|
|
56055
58659
|
* wakes the camera up and drains charge.
|
|
56056
58660
|
*/
|
|
56057
|
-
sleeping: boolean(),
|
|
58661
|
+
sleeping: boolean().meta({ label: "Sleeping" }),
|
|
56058
58662
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
56059
58663
|
lastUpdated: number(),
|
|
56060
58664
|
/**
|
|
@@ -56094,7 +58698,7 @@ var BatteryStatusSchema = object({
|
|
|
56094
58698
|
* sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
|
|
56095
58699
|
* misleading exact percentage. Absent/false → genuine 0–100 % reading.
|
|
56096
58700
|
*/
|
|
56097
|
-
binary: boolean().optional()
|
|
58701
|
+
binary: boolean().optional().meta({ label: "Binary indicator" })
|
|
56098
58702
|
});
|
|
56099
58703
|
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat;
|
|
56100
58704
|
method(object({
|
|
@@ -56109,7 +58713,7 @@ method(object({
|
|
|
56109
58713
|
status: BatteryStatusSchema
|
|
56110
58714
|
});
|
|
56111
58715
|
object({
|
|
56112
|
-
on: boolean(),
|
|
58716
|
+
on: boolean().meta({ label: "On" }),
|
|
56113
58717
|
/** Ms epoch of the last transition. 0 if never observed. */
|
|
56114
58718
|
lastChangedAt: number()
|
|
56115
58719
|
});
|
|
@@ -56367,7 +58971,7 @@ var GridLayoutCellSchema = object({
|
|
|
56367
58971
|
*
|
|
56368
58972
|
* A grid's `high` composes its sources' `high` and its `low` their `low`, so a
|
|
56369
58973
|
* profile is on offer only when EVERY source can serve it. The refusal NAMES
|
|
56370
|
-
* the sources, because "this grid has no low" is not a finding — "
|
|
58974
|
+
* the sources, because "this grid has no low" is not a finding — "101 has no
|
|
56371
58975
|
* low" is, and it is the one an operator can act on.
|
|
56372
58976
|
*/
|
|
56373
58977
|
var GridProfileOfferSchema = object({
|
|
@@ -56999,6 +59603,39 @@ DeviceType.Camera, method(object({ deviceId: number() }), DayNightOptionsSchema)
|
|
|
56999
59603
|
auth: "admin"
|
|
57000
59604
|
});
|
|
57001
59605
|
/**
|
|
59606
|
+
* display-palette — the cluster's one colour table (D939).
|
|
59607
|
+
*
|
|
59608
|
+
* Hub singleton. `getPalette` reports `unknown` when the settings store
|
|
59609
|
+
* cannot be read; it does not pretend the bundled preset was stored.
|
|
59610
|
+
* `setPalette` refuses a palette that fails the ΔE / contrast rule and names
|
|
59611
|
+
* the pairs.
|
|
59612
|
+
*/
|
|
59613
|
+
var presetSummarySchema = object({
|
|
59614
|
+
id: string(),
|
|
59615
|
+
name: string(),
|
|
59616
|
+
swatches: record(string(), paletteSwatchSchema),
|
|
59617
|
+
fallbacks: array(string())
|
|
59618
|
+
});
|
|
59619
|
+
var displayPaletteCapability = {
|
|
59620
|
+
name: "display-palette",
|
|
59621
|
+
scope: "system",
|
|
59622
|
+
mode: "singleton",
|
|
59623
|
+
methods: {
|
|
59624
|
+
getPalette: method(_void(), paletteResultSchema, {
|
|
59625
|
+
auth: "protected",
|
|
59626
|
+
role: "viewer"
|
|
59627
|
+
}),
|
|
59628
|
+
listPresets: method(_void(), array(presetSummarySchema).readonly(), {
|
|
59629
|
+
auth: "protected",
|
|
59630
|
+
role: "viewer"
|
|
59631
|
+
}),
|
|
59632
|
+
setPalette: method(setPaletteInputSchema, paletteReadySchema, {
|
|
59633
|
+
kind: "mutation",
|
|
59634
|
+
auth: "admin"
|
|
59635
|
+
})
|
|
59636
|
+
}
|
|
59637
|
+
};
|
|
59638
|
+
/**
|
|
57002
59639
|
* Generic device-level status snapshot. Auto-registered by `BaseDevice`
|
|
57003
59640
|
* for every device, regardless of provider — the kernel needs a uniform
|
|
57004
59641
|
* cap-keyed slice for the basic device flags every consumer expects to
|
|
@@ -57894,7 +60531,10 @@ DeviceType.Humidifier, method(object({
|
|
|
57894
60531
|
});
|
|
57895
60532
|
object({
|
|
57896
60533
|
/** Current relative humidity, 0..100. */
|
|
57897
|
-
percent: number().min(0).max(100)
|
|
60534
|
+
percent: number().min(0).max(100).meta({
|
|
60535
|
+
unit: "%",
|
|
60536
|
+
label: "Humidity"
|
|
60537
|
+
}),
|
|
57898
60538
|
/** Ms epoch when the slice was last updated. */
|
|
57899
60539
|
lastFetchedAt: number(),
|
|
57900
60540
|
/** Live display unit from the upstream source (e.g. HA
|
|
@@ -61412,9 +64052,15 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
61412
64052
|
});
|
|
61413
64053
|
object({
|
|
61414
64054
|
/** Instantaneous power draw in watts. */
|
|
61415
|
-
watts: number().optional()
|
|
64055
|
+
watts: number().optional().meta({
|
|
64056
|
+
unit: "W",
|
|
64057
|
+
label: "Power"
|
|
64058
|
+
}),
|
|
61416
64059
|
/** Cumulative energy in kilowatt-hours since the meter was reset. */
|
|
61417
|
-
kwhTotal: number().optional()
|
|
64060
|
+
kwhTotal: number().optional().meta({
|
|
64061
|
+
unit: "kWh",
|
|
64062
|
+
label: "Energy"
|
|
64063
|
+
}),
|
|
61418
64064
|
/** Voltage in volts. */
|
|
61419
64065
|
volts: number().optional(),
|
|
61420
64066
|
/** Current in amperes. */
|
|
@@ -61733,9 +64379,9 @@ var PtzOptionsSchema = object({
|
|
|
61733
64379
|
* Reolink preset 0, Hikvision preset '1', Dahua preset 1 -- and on this fleet
|
|
61734
64380
|
* not one of the three cameras honours its own:
|
|
61735
64381
|
*
|
|
61736
|
-
*
|
|
61737
|
-
* 1438
|
|
61738
|
-
* 3836
|
|
64382
|
+
* 107 Camera camera Carol (reolink) preset 0 holds "stanza"
|
|
64383
|
+
* 1438 Camera dispensa (hikvision) preset 1 holds "Credenza"
|
|
64384
|
+
* 3836 Camera studio (amcrest) preset 1 holds "Preset1"
|
|
61739
64385
|
*
|
|
61740
64386
|
* So `goHome` meant "go wherever the operator happened to save in slot 0 or 1",
|
|
61741
64387
|
* and two of the three swallowed the failure in a bare `catch`. For autotrack
|
|
@@ -61882,7 +64528,7 @@ object({
|
|
|
61882
64528
|
running: boolean().nullable(),
|
|
61883
64529
|
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
61884
64530
|
since: number().nullable(),
|
|
61885
|
-
source: RunningStateSourceSchema,
|
|
64531
|
+
source: RunningStateSourceSchema.meta({ label: "Source" }),
|
|
61886
64532
|
phase: string().nullable(),
|
|
61887
64533
|
/** null until a reading has been published (D393). */
|
|
61888
64534
|
lastFetchedAt: number().nullable()
|
|
@@ -61935,7 +64581,7 @@ var RecordingAvailabilitySchema = object({
|
|
|
61935
64581
|
* would look identical. But the answer used to say nothing about that, so a
|
|
61936
64582
|
* caller asking "what can I export?" read the single preferred profile as
|
|
61937
64583
|
* the only one that exists — on this deployment every camera records `high`
|
|
61938
|
-
* AND `low`, the low tree holding 14 GB for camera
|
|
64584
|
+
* AND `low`, the low tree holding 14 GB for camera 101 alone, and the export
|
|
61939
64585
|
* UI could not see it.
|
|
61940
64586
|
*
|
|
61941
64587
|
* Cheap: it is the same shallow directory read the profile CHOICE already
|
|
@@ -62034,7 +64680,7 @@ var RecordingSourceOptionsSchema = object({
|
|
|
62034
64680
|
* `sparse` = gaps are the absence of one, and must be drawn as such.
|
|
62035
64681
|
*
|
|
62036
64682
|
* Not an onboard-only concession: measured 2026-09-24, OUR bar covers 98.8 %
|
|
62037
|
-
* of
|
|
64683
|
+
* of 107's day and 1.2 % of 1436's. It is a fact about a (source, camera)
|
|
62038
64684
|
* pair, and ours answers it per camera from `deriveRecordingMode`. */
|
|
62039
64685
|
coverage: _enum(["continuous", "sparse"]),
|
|
62040
64686
|
/** Where the playhead may be put.
|
|
@@ -62110,7 +64756,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(RecordingSourceS
|
|
|
62110
64756
|
* merely discouraged (D554 amended).
|
|
62111
64757
|
*
|
|
62112
64758
|
* It was learned the expensive way on `videoclips.listClips`: measured
|
|
62113
|
-
* on the live hub 2026-09-20, device
|
|
64759
|
+
* on the live hub 2026-09-20, device 107 bound to `recorder` AND
|
|
62114
64760
|
* `provider-reolink`, a bare call with `limit: 3` answered SIX rows,
|
|
62115
64761
|
* three from each source, merged — `device-collection-dispatch.ts`
|
|
62116
64762
|
* leaves an unpinned fan-out un-narrowed, so absence buys the union the
|
|
@@ -62711,7 +65357,7 @@ var ExportSpeedSchema = number().min(.25).max(32);
|
|
|
62711
65357
|
* on a 10 h window holding 29,393 s of footage every range landed late by the
|
|
62712
65358
|
* gap accumulated before it — up to 6,607 s, well past EOF. Nothing matched,
|
|
62713
65359
|
* the video was a uniform timelapse, and the log line reported the five ranges
|
|
62714
|
-
* that had been ASKED for (2026-08-13, export `57d14363`, camera
|
|
65360
|
+
* that had been ASKED for (2026-08-13, export `57d14363`, camera 101).
|
|
62715
65361
|
*
|
|
62716
65362
|
* Relative and not absolute epoch, because an absolute epoch would make every
|
|
62717
65363
|
* call site responsible for the same subtraction.
|
|
@@ -63379,7 +66025,7 @@ getStatus: method(object({ deviceId: number() }), RecordingSignalStatusSchema) }
|
|
|
63379
66025
|
* which put a "Scenes" tab on one camera's detail page. That is the wrong shape
|
|
63380
66026
|
* for the thing: a scene is a standing question about the property ("is the bin
|
|
63381
66027
|
* still out"), and the operator's question is "which of my scenes have tripped",
|
|
63382
|
-
* across every camera at once — not "what does camera
|
|
66028
|
+
* across every camera at once — not "what does camera 102 think". Buried one
|
|
63383
66029
|
* camera deep it also could not be found. The surface is now a top-level admin
|
|
63384
66030
|
* page (`/scenes`, `pages/Scenes.tsx`) that lists every scene on every camera and
|
|
63385
66031
|
* picks the camera inside the create flow, the same shape Events and Faces have.
|
|
@@ -63962,7 +66608,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), StreamParamsOptionsSch
|
|
|
63962
66608
|
auth: "admin"
|
|
63963
66609
|
}), method(object({ deviceId: number() }), unknown().nullable());
|
|
63964
66610
|
object({
|
|
63965
|
-
on: boolean(),
|
|
66611
|
+
on: boolean().meta({ label: "On" }),
|
|
63966
66612
|
/** Ms epoch of the last state change. Useful for UI "X minutes ago". */
|
|
63967
66613
|
lastChangedAt: number()
|
|
63968
66614
|
});
|
|
@@ -64525,7 +67171,10 @@ object({
|
|
|
64525
67171
|
DeviceType.Sensor;
|
|
64526
67172
|
object({
|
|
64527
67173
|
/** Current temperature in Celsius. */
|
|
64528
|
-
celsius: number()
|
|
67174
|
+
celsius: number().meta({
|
|
67175
|
+
unit: "°C",
|
|
67176
|
+
label: "Temperature"
|
|
67177
|
+
}),
|
|
64529
67178
|
/** Ms epoch when the slice was last updated (push or poll). */
|
|
64530
67179
|
lastFetchedAt: number(),
|
|
64531
67180
|
/** Live display unit from the upstream source (e.g. HA
|
|
@@ -65733,6 +68382,10 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
|
|
|
65733
68382
|
auth: "admin"
|
|
65734
68383
|
});
|
|
65735
68384
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
68385
|
+
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;
|
|
68386
|
+
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
68387
|
+
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
68388
|
+
new Set(CAP_NAMES);
|
|
65736
68389
|
Object.freeze({
|
|
65737
68390
|
person: .5,
|
|
65738
68391
|
vehicle: .5,
|
|
@@ -68732,6 +71385,27 @@ Object.freeze({
|
|
|
68732
71385
|
access: "create",
|
|
68733
71386
|
role: "viewer"
|
|
68734
71387
|
},
|
|
71388
|
+
"displayPalette.getPalette": {
|
|
71389
|
+
capName: "display-palette",
|
|
71390
|
+
capScope: "system",
|
|
71391
|
+
addonId: null,
|
|
71392
|
+
access: "view",
|
|
71393
|
+
role: "viewer"
|
|
71394
|
+
},
|
|
71395
|
+
"displayPalette.listPresets": {
|
|
71396
|
+
capName: "display-palette",
|
|
71397
|
+
capScope: "system",
|
|
71398
|
+
addonId: null,
|
|
71399
|
+
access: "view",
|
|
71400
|
+
role: "viewer"
|
|
71401
|
+
},
|
|
71402
|
+
"displayPalette.setPalette": {
|
|
71403
|
+
capName: "display-palette",
|
|
71404
|
+
capScope: "system",
|
|
71405
|
+
addonId: null,
|
|
71406
|
+
access: "create",
|
|
71407
|
+
role: "admin"
|
|
71408
|
+
},
|
|
68735
71409
|
"doorbell.getStatus": {
|
|
68736
71410
|
capName: "doorbell",
|
|
68737
71411
|
capScope: "device",
|
|
@@ -78649,7 +81323,7 @@ var SENSOR_CAP_VOCABULARY = {
|
|
|
78649
81323
|
state: [{
|
|
78650
81324
|
kind: "boolean",
|
|
78651
81325
|
field: "on",
|
|
78652
|
-
label: t("
|
|
81326
|
+
label: t("On", "Acceso"),
|
|
78653
81327
|
whenTrue: t("When {device} turns active", "Quando {device} si attiva"),
|
|
78654
81328
|
whenFalse: t("When {device} turns inactive", "Quando {device} si disattiva"),
|
|
78655
81329
|
icon: "toggle-right"
|
|
@@ -79188,6 +81862,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
79188
81862
|
"device-provider": system(INTERNAL),
|
|
79189
81863
|
"device-removal-hook": system(INTERNAL),
|
|
79190
81864
|
"device-state": system("the runtime-state mirror every trigger already reads through"),
|
|
81865
|
+
"display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
|
|
79191
81866
|
"embedding-encoder": system(ML),
|
|
79192
81867
|
"face-gallery": system("the face gallery — curated on its own page"),
|
|
79193
81868
|
"failure-contribution": system(INTERNAL),
|
|
@@ -82197,7 +84872,6 @@ var BucketAccumulator = class {
|
|
|
82197
84872
|
}
|
|
82198
84873
|
};
|
|
82199
84874
|
DeviceType.Camera;
|
|
82200
|
-
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;
|
|
82201
84875
|
/**
|
|
82202
84876
|
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
82203
84877
|
* `z.infer`, they do not restate the shape.
|
|
@@ -82286,7 +84960,6 @@ object({
|
|
|
82286
84960
|
]),
|
|
82287
84961
|
reason: string().nullable()
|
|
82288
84962
|
});
|
|
82289
|
-
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
82290
84963
|
var G711_SCALE_CORRECTION_DB = {
|
|
82291
84964
|
PCMU: 20 * Math.log10(4),
|
|
82292
84965
|
PCMA: 20 * Math.log10(8)
|
|
@@ -82659,7 +85332,7 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
82659
85332
|
{
|
|
82660
85333
|
name: "summaryStreams",
|
|
82661
85334
|
label: "Summary: streams offline",
|
|
82662
|
-
example: "
|
|
85335
|
+
example: "Front door (high) — since 06:40",
|
|
82663
85336
|
kinds: ["stream-offline", "stream-online"]
|
|
82664
85337
|
},
|
|
82665
85338
|
{
|
|
@@ -82677,13 +85350,13 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
82677
85350
|
{
|
|
82678
85351
|
name: "summaryDetection",
|
|
82679
85352
|
label: "Summary: cameras detecting nothing",
|
|
82680
|
-
example: "
|
|
85353
|
+
example: "Front door — since 05:10",
|
|
82681
85354
|
kinds: ["detection-blind"]
|
|
82682
85355
|
},
|
|
82683
85356
|
{
|
|
82684
85357
|
name: "summaryNodes",
|
|
82685
85358
|
label: "Summary: nodes",
|
|
82686
|
-
example: "
|
|
85359
|
+
example: "agent-a — offline since 03:00",
|
|
82687
85360
|
kinds: [
|
|
82688
85361
|
"node-offline",
|
|
82689
85362
|
"node-online",
|
|
@@ -87139,7 +89812,7 @@ function validateJumpTargets(inferenceDevices, enabledAvailableKeys) {
|
|
|
87139
89812
|
* A **Coral Edge TPU (`edgetpu`)** is an accelerator like the rest and is
|
|
87140
89813
|
* enabled by default (D912, superseding D39). The 2026-08-01 incident that made
|
|
87141
89814
|
* it opt-in (a Coral nobody enabled took an equal share of the rotation, ran a
|
|
87142
|
-
* weaker SSD and left camera
|
|
89815
|
+
* weaker SSD and left camera 101 at 2.4 fps) is answered by speed-proportional
|
|
87143
89816
|
* automatic weights — Auto tune sizes the Coral at its default YOLOv9-s 320
|
|
87144
89817
|
* Edge TPU build with the measured latency — and by that default model, which
|
|
87145
89818
|
* is YOLOv9 like the rest. An explicit stored `enabled:false` still wins.
|
|
@@ -90789,7 +93462,7 @@ var CameraStatusService = class {
|
|
|
90789
93462
|
* means "we could not look" from a `null` that means "there is nothing
|
|
90790
93463
|
* there"; the `warn` is what makes the next hang findable at all. The line
|
|
90791
93464
|
* carries `tags.deviceId` with the numeric id because the question is always
|
|
90792
|
-
* per-camera ("why is
|
|
93465
|
+
* per-camera ("why is 105 worse than 101?") and a line without the tag
|
|
90793
93466
|
* cannot be grouped to answer it.
|
|
90794
93467
|
*/
|
|
90795
93468
|
recordDegraded(sink, deviceId, stage, reason, elapsedMs, extraMeta = {}) {
|
|
@@ -91089,7 +93762,7 @@ var CameraStatusService = class {
|
|
|
91089
93762
|
*
|
|
91090
93763
|
* In the last two the returned list is `[]`, and `[]` was once handed to the
|
|
91091
93764
|
* payload as the positive claim "the operator has switched nothing off".
|
|
91092
|
-
* Measured on the live hub 2026-08-08: `getCameraStatus(
|
|
93765
|
+
* Measured on the live hub 2026-08-08: `getCameraStatus(105)` said
|
|
91093
93766
|
* `switchedOff: []` at the very moment `stream-broker` AND `recording` were
|
|
91094
93767
|
* switched off by the operator — the camera read as BROKEN because it was
|
|
91095
93768
|
* switched OFF. The list stays empty (a guess would put a permanent "off"
|
|
@@ -91276,7 +93949,7 @@ function readPrivacyMaskFacts(v) {
|
|
|
91276
93949
|
*
|
|
91277
93950
|
* Measured on the live hub, 2026-08-08: seven of the eight sources answered in
|
|
91278
93951
|
* 5–15ms on every camera. The eighth, `privacyMask.getStatus`, probes the
|
|
91279
|
-
* camera itself and took 3.1–3.6s on device
|
|
93952
|
+
* camera itself and took 3.1–3.6s on device 105 on every single call (18s under
|
|
91280
93953
|
* load) — so a bound generous enough to make the fast sources safe still has to
|
|
91281
93954
|
* be willing to drop the slow one, because waiting for it costs the other six.
|
|
91282
93955
|
*/
|
|
@@ -92582,7 +95255,7 @@ async function reconcileOnboardForwarding(input, deps) {
|
|
|
92582
95255
|
* never cause a video transcode, and on this fleet the motion rung IS a
|
|
92583
95256
|
* `derived:*` transcode. The caller therefore hands the resolved audio stream
|
|
92584
95257
|
* in {@link WatchdogAudioSource} — reading `motionStreamId` here would label
|
|
92585
|
-
* and RECOVER the wrong stream, which is how camera
|
|
95258
|
+
* and RECOVER the wrong stream, which is how camera 108's audio stage watched
|
|
92586
95259
|
* a plane the analyser was not listening to.
|
|
92587
95260
|
*
|
|
92588
95261
|
* `pipelineEnabled === false` (the `object-detection` switch, D62/ADR-0109)
|
|
@@ -92711,7 +95384,7 @@ var DetectionWiringController = class {
|
|
|
92711
95384
|
* silently loses `BATTERY_DEVICE_PROFILE` and `audioMode` falls back to
|
|
92712
95385
|
* `'always-on'` — which subscribes the audio-analyzer, which is demand on
|
|
92713
95386
|
* the substream, which dials the camera and WAKES it. Measured on the live
|
|
92714
|
-
* hub: 3 of 12 detection passes on device
|
|
95387
|
+
* hub: 3 of 12 detection passes on device 106 did exactly that, each right
|
|
92715
95388
|
* after a `provider-reolink` restart.
|
|
92716
95389
|
*
|
|
92717
95390
|
* So this reports UNKNOWN (`null`) distinctly from "no features" (`[]`), and
|
|
@@ -94170,7 +96843,7 @@ function decideSessionClose(input) {
|
|
|
94170
96843
|
* straight to the floor check; the hold, the cap and the track-freshness read
|
|
94171
96844
|
* all lived inside the COOLDOWN TIMER's body. On a camera that emits an
|
|
94172
96845
|
* explicit low edge — which is every camera — the timer body never ran.
|
|
94173
|
-
* Measured on device
|
|
96846
|
+
* Measured on device 102 over 24 h, 503 paired sessions: **502 closed on
|
|
94174
96847
|
* `motion_cleared`**, 1 on the cooldown, 0 on `maxSessionHoldMs`, and the
|
|
94175
96848
|
* "held open" branch fired **0 times**. Median session life 10 221 ms against a
|
|
94176
96849
|
* 10 000 ms floor — not a duration, a floor. 71.5% of the tracks that died in
|
|
@@ -99030,7 +101703,7 @@ var RECHECK_REASON = "orchestrator-recheck";
|
|
|
99030
101703
|
/**
|
|
99031
101704
|
* D691 — the EARLY LOOK. An occupancy edge commits only on a sample that lands
|
|
99032
101705
|
* after its sustain window, and a departure's session usually closes before
|
|
99033
|
-
* that (the car drives off, motion clears):
|
|
101706
|
+
* that (the car drives off, motion clears): 102 on 2026-10-01 closed 1.3 s
|
|
99034
101707
|
* before its 29 s sustain ended and the edge waited 4 min 52 s for the cadence
|
|
99035
101708
|
* above. The notification centre, which alone knows a flip is pending, asks
|
|
99036
101709
|
* for ONE look at the sustain's end ({@link OccupancyRecheckController.requestEarlyLook});
|
|
@@ -99802,7 +102475,7 @@ function countRunningByNode(placements) {
|
|
|
99802
102475
|
* 57.6% under 5 s, and **820 of 822 closes were the hub's explicit
|
|
99803
102476
|
* `motion_cleared` falling edge** — which closed the session instantly, so
|
|
99804
102477
|
* `motionCooldownMs` / the track hold / `maxSessionHoldMs` decided 2 closes in
|
|
99805
|
-
* total. Camera
|
|
102478
|
+
* total. Camera 104 opened and closed 249 sessions in 25 minutes; every close
|
|
99806
102479
|
* dropped its assignment and every reopen re-elected a node, which is the
|
|
99807
102480
|
* 2-3 second flicker the operator reported on the placement column — and a full
|
|
99808
102481
|
* detach+attach round trip per flicker.
|
|
@@ -100173,7 +102846,7 @@ var SessionDispatchController = class {
|
|
|
100173
102846
|
* Close an ACTIVE detection session so the next motion event re-dispatches
|
|
100174
102847
|
* it fresh — used by `assignPipeline` when the operator pins a session-mode
|
|
100175
102848
|
* camera to a node OTHER than the one its session currently runs on (the
|
|
100176
|
-
* cam-
|
|
102849
|
+
* cam-104 case: a busy camera's session never cools down, so without this
|
|
100177
102850
|
* the stale pre-pin placement survived indefinitely).
|
|
100178
102851
|
*
|
|
100179
102852
|
* Deliberately NOT `stopForDevice`: the camera must stay ARMED —
|
|
@@ -100279,7 +102952,7 @@ var SessionDispatchController = class {
|
|
|
100279
102952
|
* SAME rule the fallback timer uses ({@link resolveSessionLifecycleLocked}).
|
|
100280
102953
|
* It no longer bypasses the hold and the cap: it used to, and that made
|
|
100281
102954
|
* both unreachable on every camera that emits a falling edge — 502 of
|
|
100282
|
-
* 503 closes on device
|
|
102955
|
+
* 503 closes on device 102 in 24 h. An explicit clear still wins over
|
|
100283
102956
|
* the cooldown; it does not win over a subject that is still there.
|
|
100284
102957
|
*
|
|
100285
102958
|
* LIVE as of Task 2: `startDetection` no longer standing-attaches on-motion
|
|
@@ -100728,7 +103401,7 @@ var SessionDispatchController = class {
|
|
|
100728
103401
|
* falling edge, the `cooldown_expired` fallback timer, and the re-ask of a
|
|
100729
103402
|
* close this method itself deferred. That is the fix — the hold, the
|
|
100730
103403
|
* freshness read and `maxSessionHoldMs` used to live inside the COOLDOWN
|
|
100731
|
-
* TIMER's body, so a falling edge reached none of them. On device
|
|
103404
|
+
* TIMER's body, so a falling edge reached none of them. On device 102, 24 h,
|
|
100732
103405
|
* 503 sessions: 502 closes were falling edges, the hold branch fired 0
|
|
100733
103406
|
* times, `maxSessionHoldMs` fired 0 times, and the session-duration
|
|
100734
103407
|
* distribution collapsed onto {@link MIN_SESSION_OPEN_MS} — median 10 221 ms
|
|
@@ -100803,7 +103476,7 @@ var SessionDispatchController = class {
|
|
|
100803
103476
|
* **This branch drops work, so it says so.** Closing a session detaches the
|
|
100804
103477
|
* runner: every track still live on that camera dies here, mid-life, with no
|
|
100805
103478
|
* `end` key-event and no chance of ever reaching the stationary registry's
|
|
100806
|
-
* promotion window. It used to log one bare sentence. Measured on device
|
|
103479
|
+
* promotion window. It used to log one bare sentence. Measured on device 102
|
|
100807
103480
|
* over 24 h it killed **223 live tracks across 503 closes (0.44 per close)**,
|
|
100808
103481
|
* 95% of which had been motionless for at least a second, and not one line
|
|
100809
103482
|
* named a single one of them — the gap had to be reconstructed by
|
|
@@ -101416,9 +104089,9 @@ var ZoneRulesProvider = class {
|
|
|
101416
104089
|
* so a camera whose runtime-state row had never been written (or had
|
|
101417
104090
|
* been reset) had no `zones` slice at all, and every mirror-only
|
|
101418
104091
|
* consumer concluded "this camera has no zones" — forever, because no
|
|
101419
|
-
* mutation was coming. Live cost (camera
|
|
101420
|
-
* 2026-08-12): `zones.listZones {
|
|
101421
|
-
* while `deviceState.getCapSlice {
|
|
104092
|
+
* mutation was coming. Live cost (camera 102 'Parking',
|
|
104093
|
+
* 2026-08-12): `zones.listZones {102}` returned 'Parking pat'
|
|
104094
|
+
* while `deviceState.getCapSlice {102,'zones'}` returned `null`;
|
|
101422
104095
|
* occupancy dropped all three parked cars into `unzoned`, its zone
|
|
101423
104096
|
* rule could never fire, and the admin Zones tab — which reads the
|
|
101424
104097
|
* same mirror — showed "No zones yet".
|
|
@@ -101882,7 +104555,7 @@ async function buildOrchestratorControllers(deps) {
|
|
|
101882
104555
|
* false negative on every COLD broker: `getStats()` answers `audio: null`
|
|
101883
104556
|
* until a track is observed, and dispatch normally runs while the stream is
|
|
101884
104557
|
* idle. So the audio stage armed only for cameras that happened to be hot at
|
|
101885
|
-
* dispatch — which is why camera
|
|
104558
|
+
* dispatch — which is why camera 108's derived stream delivered zero audio
|
|
101886
104559
|
* chunks for four days without a single watchdog line. A stage armed on a
|
|
101887
104560
|
* camera that turns out to have no audio is BOUNDED: the watchdog disarms a
|
|
101888
104561
|
* stage that never produced one signal, with one line.
|
|
@@ -103064,6 +105737,112 @@ function deriveRuntimeSettings(config) {
|
|
|
103064
105737
|
};
|
|
103065
105738
|
}
|
|
103066
105739
|
//#endregion
|
|
105740
|
+
//#region src/display-palette-provider.ts
|
|
105741
|
+
/**
|
|
105742
|
+
* Display palette provider (D939, D940). The pipeline orchestrator owns
|
|
105743
|
+
* this cluster setting. The document is one key in the addon's store, so
|
|
105744
|
+
* a write does not replace the orchestrator's other settings. An
|
|
105745
|
+
* unreadable store is `unknown`, never the bundled preset.
|
|
105746
|
+
*/
|
|
105747
|
+
/** Key inside the orchestrator's addon store. Not a settings-schema field. */
|
|
105748
|
+
var DISPLAY_PALETTE_STORE_KEY = "displayPalette";
|
|
105749
|
+
function createDisplayPaletteProvider(settings, logger) {
|
|
105750
|
+
return {
|
|
105751
|
+
getPalette: async () => readPalette(settings, logger),
|
|
105752
|
+
listPresets: async () => DISPLAY_PRESETS.map((row) => ({
|
|
105753
|
+
id: row.id,
|
|
105754
|
+
name: row.name,
|
|
105755
|
+
swatches: row.swatches,
|
|
105756
|
+
fallbacks: [...row.fallbacks]
|
|
105757
|
+
})),
|
|
105758
|
+
setPalette: async (input) => writePalette(settings, logger, input)
|
|
105759
|
+
};
|
|
105760
|
+
}
|
|
105761
|
+
async function readPalette(settings, logger) {
|
|
105762
|
+
if (settings === void 0) {
|
|
105763
|
+
logger.warn("display-palette: settings store cannot be read three ways");
|
|
105764
|
+
return {
|
|
105765
|
+
status: "unknown",
|
|
105766
|
+
reason: "settings store cannot be read"
|
|
105767
|
+
};
|
|
105768
|
+
}
|
|
105769
|
+
const readKey = settings.readAddonStoreKeyResult;
|
|
105770
|
+
if (readKey !== void 0) return readByKey(settings, readKey, logger);
|
|
105771
|
+
const read = settings.readAddonStoreResult;
|
|
105772
|
+
if (read === void 0) {
|
|
105773
|
+
logger.warn("display-palette: settings store cannot be read three ways");
|
|
105774
|
+
return {
|
|
105775
|
+
status: "unknown",
|
|
105776
|
+
reason: "settings store cannot be read"
|
|
105777
|
+
};
|
|
105778
|
+
}
|
|
105779
|
+
return readByStore(settings, read, logger);
|
|
105780
|
+
}
|
|
105781
|
+
async function readByKey(settings, readKey, logger) {
|
|
105782
|
+
let result;
|
|
105783
|
+
try {
|
|
105784
|
+
result = await readKey.call(settings, DISPLAY_PALETTE_STORE_KEY);
|
|
105785
|
+
} catch (err) {
|
|
105786
|
+
return readThrew(logger, err);
|
|
105787
|
+
}
|
|
105788
|
+
if (result.kind === "unreadable") {
|
|
105789
|
+
logger.warn("display-palette: settings unreadable", { meta: { error: result.error } });
|
|
105790
|
+
return {
|
|
105791
|
+
status: "unknown",
|
|
105792
|
+
reason: result.error ?? "settings store cannot be read"
|
|
105793
|
+
};
|
|
105794
|
+
}
|
|
105795
|
+
if (result.kind === "absent") return bundledCamstack();
|
|
105796
|
+
return interpretStored(logger, result.value);
|
|
105797
|
+
}
|
|
105798
|
+
async function readByStore(settings, read, logger) {
|
|
105799
|
+
let result;
|
|
105800
|
+
try {
|
|
105801
|
+
result = await read.call(settings);
|
|
105802
|
+
} catch (err) {
|
|
105803
|
+
return readThrew(logger, err);
|
|
105804
|
+
}
|
|
105805
|
+
if (result.kind === "failed") {
|
|
105806
|
+
logger.warn("display-palette: settings unreadable", { meta: { error: result.error } });
|
|
105807
|
+
return {
|
|
105808
|
+
status: "unknown",
|
|
105809
|
+
reason: result.error
|
|
105810
|
+
};
|
|
105811
|
+
}
|
|
105812
|
+
if (result.kind === "missing") return bundledCamstack();
|
|
105813
|
+
return interpretStored(logger, result.value[DISPLAY_PALETTE_STORE_KEY]);
|
|
105814
|
+
}
|
|
105815
|
+
function readThrew(logger, err) {
|
|
105816
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
105817
|
+
logger.warn("display-palette: settings read threw", { meta: { error } });
|
|
105818
|
+
return {
|
|
105819
|
+
status: "unknown",
|
|
105820
|
+
reason: "settings store read failed"
|
|
105821
|
+
};
|
|
105822
|
+
}
|
|
105823
|
+
function interpretStored(logger, value) {
|
|
105824
|
+
const palette = paletteFromStored(value);
|
|
105825
|
+
if (palette.status === "unknown") logger.warn("display-palette: stored palette is not usable", { meta: { reason: palette.reason } });
|
|
105826
|
+
return palette;
|
|
105827
|
+
}
|
|
105828
|
+
async function writePalette(settings, logger, input) {
|
|
105829
|
+
let ready;
|
|
105830
|
+
try {
|
|
105831
|
+
ready = paletteFromInput(input);
|
|
105832
|
+
} catch (err) {
|
|
105833
|
+
if (err instanceof PaletteRejectedError) logger.info("display-palette: refused", { meta: { reason: err.message } });
|
|
105834
|
+
throw err;
|
|
105835
|
+
}
|
|
105836
|
+
const write = settings?.writeAddonStore;
|
|
105837
|
+
if (settings === void 0 || write === void 0) {
|
|
105838
|
+
logger.warn("display-palette: settings store cannot be written");
|
|
105839
|
+
throw new Error("display-palette: settings store cannot be written");
|
|
105840
|
+
}
|
|
105841
|
+
const overrides = "overrides" in input ? input.overrides : {};
|
|
105842
|
+
await write.call(settings, { [DISPLAY_PALETTE_STORE_KEY]: storedFromReady(ready, overrides) });
|
|
105843
|
+
return ready;
|
|
105844
|
+
}
|
|
105845
|
+
//#endregion
|
|
103067
105846
|
//#region src/viewer-ui-provider.ts
|
|
103068
105847
|
/**
|
|
103069
105848
|
* viewer-ui provider — the pipeline-orchestrator serves the CamStack viewer web
|
|
@@ -104520,6 +107299,10 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
104520
107299
|
{
|
|
104521
107300
|
capability: viewerUiCapability,
|
|
104522
107301
|
provider: createViewerUiProvider()
|
|
107302
|
+
},
|
|
107303
|
+
{
|
|
107304
|
+
capability: displayPaletteCapability,
|
|
107305
|
+
provider: createDisplayPaletteProvider(this.ctx.settings, this.ctx.logger)
|
|
104523
107306
|
}
|
|
104524
107307
|
],
|
|
104525
107308
|
customActions: pipelineOrchestratorActions,
|
|
@@ -105414,7 +108197,7 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
105414
108197
|
* Which nodes can still infer. Refreshed by
|
|
105415
108198
|
* {@link resolveEligibleInferenceDevices}; read synchronously by both
|
|
105416
108199
|
* dispatch paths so a node whose every enabled accelerator vanished stops
|
|
105417
|
-
* receiving cameras.
|
|
108200
|
+
* receiving cameras. agent-a was handed cameras for a whole day in
|
|
105418
108201
|
* exactly that state.
|
|
105419
108202
|
*/
|
|
105420
108203
|
nodeInferenceUsability = new NodeInferenceUsabilityMirror();
|