@camstack/types 1.2.399 → 1.2.401
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/dist/addon.js +1 -71
- package/dist/addon.mjs +1 -71
- package/dist/capabilities/addon-settings.cap.d.ts +5 -0
- package/dist/capabilities/capability-definition.d.ts +42 -1
- package/dist/capabilities/consumables.cap.d.ts +187 -14
- package/dist/capabilities/core-blocks.cap.d.ts +1 -0
- package/dist/capabilities/device-history.cap.d.ts +148 -0
- package/dist/capabilities/device-manager.cap.d.ts +4 -0
- package/dist/capabilities/dishwasher.cap.d.ts +3 -38
- package/dist/capabilities/index.d.ts +6 -6
- package/dist/capabilities/vacuum-control.cap.d.ts +5 -141
- package/dist/client.js +11 -4
- package/dist/client.mjs +11 -4
- package/dist/generated/addon-api.d.ts +14 -0
- package/dist/generated/addon-cap-facts.d.ts +1 -1
- package/dist/generated/history-catalog.d.ts +8 -2
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/system-proxy.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +441 -148
- package/dist/index.mjs +425 -147
- package/dist/interfaces/config-ui.d.ts +4 -2
- package/dist/pipeline/load-balancing/capacity-shares.d.ts +27 -0
- package/dist/pipeline/load-balancing/share-election.d.ts +46 -0
- package/dist/pipeline/node-benchmark/results.d.ts +16 -2
- package/dist/{sleep-DJFUfKvA.mjs → sleep-CUp20JkO.mjs} +10 -2
- package/dist/{sleep-CD18m9HF.js → sleep-DVovpDRU.js} +15 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_sleep = require("./sleep-
|
|
2
|
+
const require_sleep = require("./sleep-DVovpDRU.js");
|
|
3
3
|
const require_event_category = require("./event-category-7AwNbPjm.js");
|
|
4
4
|
const require_composition = require("./composition-eoYYVfOp.js");
|
|
5
5
|
const require_node_color = require("./node-color.js");
|
|
@@ -8450,7 +8450,11 @@ var ConfigSectionWithValuesSchema = zod.z.object({
|
|
|
8450
8450
|
zod.z.literal(4)
|
|
8451
8451
|
]).optional(),
|
|
8452
8452
|
tab: zod.z.string().optional(),
|
|
8453
|
-
location: zod.z.enum([
|
|
8453
|
+
location: zod.z.enum([
|
|
8454
|
+
"settings",
|
|
8455
|
+
"top-tab",
|
|
8456
|
+
"hero"
|
|
8457
|
+
]).optional(),
|
|
8454
8458
|
order: zod.z.number().optional(),
|
|
8455
8459
|
fields: zod.z.array(zod.z.any())
|
|
8456
8460
|
});
|
|
@@ -15114,6 +15118,56 @@ var TierStatusSchema = zod.z.object({
|
|
|
15114
15118
|
countedAt: zod.z.number().nullable()
|
|
15115
15119
|
});
|
|
15116
15120
|
/** Operator/diagnostic view: rows per tier, last runs, refusals and drops since boot. */
|
|
15121
|
+
/**
|
|
15122
|
+
* Why a series is orphan. `device-gone`: its device is absent from the
|
|
15123
|
+
* successful device listings (the departure clock). `undeclared`: its `cap:`
|
|
15124
|
+
* key is declared by no capability any more (a field a cap removed).
|
|
15125
|
+
*/
|
|
15126
|
+
var DeviceHistoryOrphanReasonSchema = zod.z.enum(["device-gone", "undeclared"]);
|
|
15127
|
+
/** Rows held per stored tier. */
|
|
15128
|
+
var TierRowsSchema = zod.z.object({
|
|
15129
|
+
raw: zod.z.number().int(),
|
|
15130
|
+
"5m": zod.z.number().int(),
|
|
15131
|
+
"1h": zod.z.number().int(),
|
|
15132
|
+
"1d": zod.z.number().int()
|
|
15133
|
+
});
|
|
15134
|
+
var OrphanSeriesSchema = zod.z.object({
|
|
15135
|
+
seriesId: zod.z.number().int(),
|
|
15136
|
+
deviceId: zod.z.number().int(),
|
|
15137
|
+
key: zod.z.string(),
|
|
15138
|
+
scope: zod.z.string(),
|
|
15139
|
+
/** The metric's display name; `null` when its metric row is gone too. */
|
|
15140
|
+
displayName: zod.z.string().nullable(),
|
|
15141
|
+
reason: DeviceHistoryOrphanReasonSchema,
|
|
15142
|
+
/** `device-gone`: since when the device has been absent; `null` otherwise. */
|
|
15143
|
+
missingSince: zod.z.number().nullable(),
|
|
15144
|
+
firstTs: zod.z.number(),
|
|
15145
|
+
lastTs: zod.z.number(),
|
|
15146
|
+
rows: TierRowsSchema
|
|
15147
|
+
});
|
|
15148
|
+
/** At most this many orphans are listed (with their row counts) per call. */
|
|
15149
|
+
var DEVICE_HISTORY_ORPHAN_LIST_MAX = 200;
|
|
15150
|
+
/** At most this many series are deleted per call. */
|
|
15151
|
+
var DEVICE_HISTORY_ORPHAN_DELETE_MAX = 50;
|
|
15152
|
+
var DeviceHistoryOrphanDeleteRefusalSchema = zod.z.enum([
|
|
15153
|
+
"not-found",
|
|
15154
|
+
"not-orphan",
|
|
15155
|
+
"failed"
|
|
15156
|
+
]);
|
|
15157
|
+
var OrphanDeleteEntrySchema = zod.z.discriminatedUnion("ok", [zod.z.object({
|
|
15158
|
+
seriesId: zod.z.number().int(),
|
|
15159
|
+
ok: zod.z.literal(true),
|
|
15160
|
+
deleted: TierRowsSchema
|
|
15161
|
+
}), zod.z.object({
|
|
15162
|
+
seriesId: zod.z.number().int(),
|
|
15163
|
+
ok: zod.z.literal(false),
|
|
15164
|
+
reason: DeviceHistoryOrphanDeleteRefusalSchema
|
|
15165
|
+
})]);
|
|
15166
|
+
var OrphanListSchema = zod.z.object({
|
|
15167
|
+
series: zod.z.array(OrphanSeriesSchema).readonly(),
|
|
15168
|
+
/** More orphans exist than {@link DEVICE_HISTORY_ORPHAN_LIST_MAX}. */
|
|
15169
|
+
truncated: zod.z.boolean()
|
|
15170
|
+
});
|
|
15117
15171
|
var DeviceHistoryStatusSchema = zod.z.object({
|
|
15118
15172
|
startedAt: zod.z.number(),
|
|
15119
15173
|
/** The store is declared, series loaded and the first reconcile has answered. */
|
|
@@ -15255,7 +15309,24 @@ var deviceHistoryCapability = {
|
|
|
15255
15309
|
kind: "mutation",
|
|
15256
15310
|
auth: "admin"
|
|
15257
15311
|
}),
|
|
15258
|
-
getStatus: require_sleep.method(zod.z.object({}), DeviceHistoryStatusSchema, { auth: "admin" })
|
|
15312
|
+
getStatus: require_sleep.method(zod.z.object({}), DeviceHistoryStatusSchema, { auth: "admin" }),
|
|
15313
|
+
/**
|
|
15314
|
+
* Device series no longer linked to a device (D917): the device is absent
|
|
15315
|
+
* from the listings, or the key is declared by no capability. REPORTED,
|
|
15316
|
+
* never purged by this judgement; each entry counts its rows per tier
|
|
15317
|
+
* (a primary-key range per series). Ordered by device, key, scope.
|
|
15318
|
+
*/
|
|
15319
|
+
listOrphanSeries: require_sleep.method(zod.z.object({}), OrphanListSchema, { auth: "admin" }),
|
|
15320
|
+
/**
|
|
15321
|
+
* Delete orphan series by id. Each id is re-judged NOW: a series that is
|
|
15322
|
+
* not orphan (its device came back) is refused `not-orphan`, an unknown id
|
|
15323
|
+
* `not-found`. Deletes tier by tier in the retention slices, then the
|
|
15324
|
+
* series row; one entry per id, in order.
|
|
15325
|
+
*/
|
|
15326
|
+
deleteOrphanSeries: require_sleep.method(zod.z.object({ seriesIds: zod.z.array(zod.z.number().int()).min(1).max(50) }), zod.z.object({ results: zod.z.array(OrphanDeleteEntrySchema).readonly() }), {
|
|
15327
|
+
kind: "mutation",
|
|
15328
|
+
auth: "admin"
|
|
15329
|
+
})
|
|
15259
15330
|
}
|
|
15260
15331
|
};
|
|
15261
15332
|
//#endregion
|
|
@@ -61209,17 +61280,88 @@ var connectivityCapability = {
|
|
|
61209
61280
|
//#endregion
|
|
61210
61281
|
//#region src/capabilities/consumables.cap.ts
|
|
61211
61282
|
/**
|
|
61212
|
-
* Generic device-consumables capability —
|
|
61213
|
-
*
|
|
61214
|
-
* descaling cycles,
|
|
61215
|
-
*
|
|
61216
|
-
*
|
|
61217
|
-
*
|
|
61283
|
+
* Generic device-consumables capability — the ONE place a device reports what
|
|
61284
|
+
* it uses up or fills: wear parts (vacuum filters/brushes, cartridges,
|
|
61285
|
+
* descaling cycles), supplies it draws from (a vacuum's clean-water tank and
|
|
61286
|
+
* detergent, a dishwasher's salt and rinse aid) and waste it collects (a dirty
|
|
61287
|
+
* water tank, a dust bin). Each item carries its remaining life or fill and an
|
|
61288
|
+
* optional "Replaced" reset action. Device-agnostic: any provider that knows
|
|
61289
|
+
* its device tracks consumables registers it; the provider names each item
|
|
61290
|
+
* verbatim and says which `kind` it is.
|
|
61291
|
+
*
|
|
61292
|
+
* The admin UI renders it as ONE collapsible section directly under the
|
|
61293
|
+
* device page's hero card (`placement: 'hero'`), for every device bound to
|
|
61294
|
+
* this cap — never drawn by a device type's hero card itself (D915).
|
|
61218
61295
|
*
|
|
61219
61296
|
* Like `childLayout`, the cap is INERT until a provider sets items: no
|
|
61220
61297
|
* provider populates it by guessing (no HA inference). The UI renders a
|
|
61221
61298
|
* "No consumables reported" placeholder when `items` is empty.
|
|
61222
61299
|
*/
|
|
61300
|
+
/**
|
|
61301
|
+
* What an item IS, which decides which direction is bad:
|
|
61302
|
+
* - `wear` — a part that wears out (a brush, a filter); low life is bad.
|
|
61303
|
+
* - `supply` — something the device draws from (clean water, detergent,
|
|
61304
|
+
* salt, rinse aid); low or empty is bad.
|
|
61305
|
+
* - `waste` — something the device fills (dirty water, a dust bin); full is
|
|
61306
|
+
* bad.
|
|
61307
|
+
* Absent = `wear`.
|
|
61308
|
+
*/
|
|
61309
|
+
var ConsumableKindSchema = zod.z.enum([
|
|
61310
|
+
"wear",
|
|
61311
|
+
"supply",
|
|
61312
|
+
"waste"
|
|
61313
|
+
]);
|
|
61314
|
+
/**
|
|
61315
|
+
* What an item LOOKS like, which decides how a client draws it — independent
|
|
61316
|
+
* of `kind`, which decides which direction is bad:
|
|
61317
|
+
* - `part` — a part that wears (a brush, a filter, a mop pad): a wear bar,
|
|
61318
|
+
* remaining time and a reset.
|
|
61319
|
+
* - `tank` — a container of liquid (clean water, dirty water): a fill gauge.
|
|
61320
|
+
* - `product` — something bought and refilled (detergent, salt, rinse aid):
|
|
61321
|
+
* a stepped level and "refill".
|
|
61322
|
+
* - `bin` — a container that collects waste (a dust bin): a fill gauge
|
|
61323
|
+
* that warns when full.
|
|
61324
|
+
* Absent = derived from the kind ({@link consumableFormOf}).
|
|
61325
|
+
*/
|
|
61326
|
+
var ConsumableFormSchema = zod.z.enum([
|
|
61327
|
+
"part",
|
|
61328
|
+
"tank",
|
|
61329
|
+
"product",
|
|
61330
|
+
"bin"
|
|
61331
|
+
]);
|
|
61332
|
+
/** The provider's own discrete verdict on an item. */
|
|
61333
|
+
var ConsumableStatusSchema = zod.z.enum([
|
|
61334
|
+
"ok",
|
|
61335
|
+
"low",
|
|
61336
|
+
"empty",
|
|
61337
|
+
"full",
|
|
61338
|
+
"replace"
|
|
61339
|
+
]);
|
|
61340
|
+
/**
|
|
61341
|
+
* The level vocabulary every client draws a consumable in (badge tone, bar
|
|
61342
|
+
* colour): derived from an item by its kind, level and status. `null` beside
|
|
61343
|
+
* it means unknown (D393).
|
|
61344
|
+
*/
|
|
61345
|
+
var ConsumableLevelSchema = zod.z.enum([
|
|
61346
|
+
"ok",
|
|
61347
|
+
"low",
|
|
61348
|
+
"empty",
|
|
61349
|
+
"full"
|
|
61350
|
+
]);
|
|
61351
|
+
/** The kind of an item, with the documented default for an absent one. */
|
|
61352
|
+
function consumableKindOf(item) {
|
|
61353
|
+
return item.kind ?? "wear";
|
|
61354
|
+
}
|
|
61355
|
+
/** The kind's default form: wear → part, waste → bin, supply → product. */
|
|
61356
|
+
var FORM_OF_KIND = {
|
|
61357
|
+
wear: "part",
|
|
61358
|
+
waste: "bin",
|
|
61359
|
+
supply: "product"
|
|
61360
|
+
};
|
|
61361
|
+
/** The form of an item: its own when the provider names one, else its kind's default. */
|
|
61362
|
+
function consumableFormOf(item) {
|
|
61363
|
+
return item.form ?? FORM_OF_KIND[consumableKindOf(item)];
|
|
61364
|
+
}
|
|
61223
61365
|
/** Units a remaining-life counter is reported in. Closed: the panel renders
|
|
61224
61366
|
* each. */
|
|
61225
61367
|
var ConsumableRemainingUnitSchema = zod.z.enum([
|
|
@@ -61234,18 +61376,23 @@ var ConsumableRemainingSchema = zod.z.object({
|
|
|
61234
61376
|
unit: ConsumableRemainingUnitSchema
|
|
61235
61377
|
});
|
|
61236
61378
|
/** A single consumable item. Either a continuous `level` (remaining
|
|
61237
|
-
* life
|
|
61238
|
-
*
|
|
61239
|
-
* mutually exclusive; a provider may
|
|
61379
|
+
* life %, or fill % for a `supply` / `waste` item) or a discrete `status`
|
|
61380
|
+
* may be known — both may be null when a provider only knows the item
|
|
61381
|
+
* exists. `level` and `status` are not mutually exclusive; a provider may
|
|
61382
|
+
* report both. */
|
|
61240
61383
|
var ConsumableItemSchema = zod.z.object({
|
|
61241
61384
|
/** Stable id, e.g. 'main-brush'. */
|
|
61242
61385
|
key: zod.z.string().min(1),
|
|
61243
61386
|
/** Display name. */
|
|
61244
61387
|
label: zod.z.string().min(1),
|
|
61245
|
-
/** Remaining life % when known (0..100). */
|
|
61388
|
+
/** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
|
|
61246
61389
|
level: zod.z.number().min(0).max(100).nullable(),
|
|
61247
|
-
/**
|
|
61248
|
-
status:
|
|
61390
|
+
/** The provider's discrete verdict when known (binary mode). */
|
|
61391
|
+
status: ConsumableStatusSchema.nullable(),
|
|
61392
|
+
/** What the item is — decides whether low or full is bad. Absent = `wear`. */
|
|
61393
|
+
kind: ConsumableKindSchema.optional(),
|
|
61394
|
+
/** How the item is drawn (part, tank, product, bin). Absent = derived from `kind`. */
|
|
61395
|
+
form: ConsumableFormSchema.optional(),
|
|
61249
61396
|
/** Ms epoch of the last replace, when known. */
|
|
61250
61397
|
lastResetAt: zod.z.number().nullable(),
|
|
61251
61398
|
/** Whether `reset()` is meaningful for this item. */
|
|
@@ -61268,7 +61415,7 @@ var consumablesCapability = {
|
|
|
61268
61415
|
kind: "widget",
|
|
61269
61416
|
widgetId: "host/consumables-panel",
|
|
61270
61417
|
tab: "consumables",
|
|
61271
|
-
|
|
61418
|
+
placement: "hero",
|
|
61272
61419
|
label: "Consumables",
|
|
61273
61420
|
order: 5
|
|
61274
61421
|
} },
|
|
@@ -61329,9 +61476,37 @@ reset: require_sleep.method(zod.z.object({
|
|
|
61329
61476
|
*/
|
|
61330
61477
|
durability: "restored",
|
|
61331
61478
|
/**
|
|
61332
|
-
* History (D850):
|
|
61479
|
+
* History (D850, D917): one series per (item field, item `key`) — the item key
|
|
61480
|
+
* is the series scope, the item `label` names it. A vacuum tank's fill, a
|
|
61481
|
+
* brush's remaining life and a dishwasher's salt are each recorded the moment
|
|
61482
|
+
* their provider reports them; an item that appears later gets its series.
|
|
61333
61483
|
*/
|
|
61334
|
-
history:
|
|
61484
|
+
history: {
|
|
61485
|
+
fields: {},
|
|
61486
|
+
items: {
|
|
61487
|
+
path: "items",
|
|
61488
|
+
key: "key",
|
|
61489
|
+
label: "label",
|
|
61490
|
+
fields: {
|
|
61491
|
+
level: {
|
|
61492
|
+
kind: "gauge",
|
|
61493
|
+
unit: "%",
|
|
61494
|
+
deadband: 2,
|
|
61495
|
+
displayName: "Level"
|
|
61496
|
+
},
|
|
61497
|
+
status: {
|
|
61498
|
+
kind: "enum",
|
|
61499
|
+
displayName: "Status"
|
|
61500
|
+
},
|
|
61501
|
+
"remaining.value": {
|
|
61502
|
+
kind: "gauge",
|
|
61503
|
+
unitFrom: "remaining.unit",
|
|
61504
|
+
deadband: 1,
|
|
61505
|
+
displayName: "Remaining"
|
|
61506
|
+
}
|
|
61507
|
+
}
|
|
61508
|
+
}
|
|
61509
|
+
},
|
|
61335
61510
|
/** Clocks, not content: a re-read that changed no item costs no commit. */
|
|
61336
61511
|
volatileStateFields: ["lastChangedAt", "lastFetchedAt"]
|
|
61337
61512
|
};
|
|
@@ -61804,8 +61979,9 @@ onStatusChanged: { data: zod.z.object({
|
|
|
61804
61979
|
//#endregion
|
|
61805
61980
|
//#region src/capabilities/dishwasher.cap.ts
|
|
61806
61981
|
/**
|
|
61807
|
-
* Smart-dishwasher cap — program lifecycle, door / remote-start gates
|
|
61808
|
-
*
|
|
61982
|
+
* Smart-dishwasher cap — program lifecycle, door / remote-start gates and
|
|
61983
|
+
* common program options. Salt and rinse aid are NOT here: they are items of
|
|
61984
|
+
* the device's `consumables` cap, like every other device's (D915).
|
|
61809
61985
|
*
|
|
61810
61986
|
* Sources: native Bosch Home Connect (`dishwasher` device type). Reusable
|
|
61811
61987
|
* by any integration that exposes the same program / option surface.
|
|
@@ -61853,11 +62029,6 @@ var DishwasherAvailabilitySchema = zod.z.enum([
|
|
|
61853
62029
|
"offline",
|
|
61854
62030
|
"description-missing"
|
|
61855
62031
|
]);
|
|
61856
|
-
var DishwasherConsumableLevelSchema = zod.z.enum([
|
|
61857
|
-
"ok",
|
|
61858
|
-
"low",
|
|
61859
|
-
"empty"
|
|
61860
|
-
]);
|
|
61861
62032
|
var DishwasherStatusSchema = zod.z.object({
|
|
61862
62033
|
availability: DishwasherAvailabilitySchema,
|
|
61863
62034
|
/** Coarse state for compact surfaces; `unavailable` whenever the appliance state is not known. */
|
|
@@ -61890,8 +62061,6 @@ var DishwasherStatusSchema = zod.z.object({
|
|
|
61890
62061
|
powerOn: zod.z.boolean().nullable(),
|
|
61891
62062
|
/** The raw power state (`On`, `Off`, `Standby`, …); null when not known. */
|
|
61892
62063
|
powerState: zod.z.string().nullable(),
|
|
61893
|
-
saltLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
61894
|
-
rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
61895
62064
|
/**
|
|
61896
62065
|
* True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
|
|
61897
62066
|
* combined care-and-filter reminder raised); false when every such reminder reads clear; null
|
|
@@ -73144,14 +73313,9 @@ var userManagementCapability = {
|
|
|
73144
73313
|
* validates it against the vacuum's own list. `locate` triggers the
|
|
73145
73314
|
* find-me chirp; `returnToBase` sends it home.
|
|
73146
73315
|
*
|
|
73147
|
-
*
|
|
73148
|
-
* `
|
|
73149
|
-
*
|
|
73150
|
-
* SHOULD populate whichever tanks the hardware has — leave a field `null`
|
|
73151
|
-
* only when the device has no such tank at all, and use a `TankStatus`
|
|
73152
|
-
* with both inner fields `null` when the tank exists but its level is
|
|
73153
|
-
* currently unknown. HA `vacuum.*` entities expose no per-tank telemetry,
|
|
73154
|
-
* so the HA provider leaves all four `null`.
|
|
73316
|
+
* Tanks (clean water, dirty water, detergent, dust bin) are NOT here: they
|
|
73317
|
+
* are `supply` / `waste` items of the device's `consumables` cap, like every
|
|
73318
|
+
* other device's consumables (D915).
|
|
73155
73319
|
*/
|
|
73156
73320
|
var VacuumStateSchema = zod.z.enum([
|
|
73157
73321
|
"idle",
|
|
@@ -73162,23 +73326,6 @@ var VacuumStateSchema = zod.z.enum([
|
|
|
73162
73326
|
"drying",
|
|
73163
73327
|
"error"
|
|
73164
73328
|
]);
|
|
73165
|
-
/**
|
|
73166
|
-
* One consumable / waste tank on a robot vacuum (clean-water, dirty-water,
|
|
73167
|
-
* detergent or dust-bin). A tank can report a numeric fill `level` (0..100),
|
|
73168
|
-
* a discrete `status` (binary-style hardware), or both. Both `null` means the
|
|
73169
|
-
* level is currently unknown; the OWNING field being `null` means the
|
|
73170
|
-
* hardware has no such tank at all.
|
|
73171
|
-
*/
|
|
73172
|
-
var TankStatusSchema = zod.z.object({
|
|
73173
|
-
/** Numeric fill 0..100 when the hardware reports a percentage; null otherwise. */
|
|
73174
|
-
level: zod.z.number().min(0).max(100).nullable(),
|
|
73175
|
-
/** Discrete state when the hardware is binary-mode; null otherwise. */
|
|
73176
|
-
status: zod.z.enum([
|
|
73177
|
-
"ok",
|
|
73178
|
-
"low",
|
|
73179
|
-
"full"
|
|
73180
|
-
]).nullable()
|
|
73181
|
-
});
|
|
73182
73329
|
var VacuumControlStatusSchema = zod.z.object({
|
|
73183
73330
|
/** Lifecycle state of the vacuum. */
|
|
73184
73331
|
state: VacuumStateSchema,
|
|
@@ -73190,14 +73337,6 @@ var VacuumControlStatusSchema = zod.z.object({
|
|
|
73190
73337
|
fanSpeed: zod.z.string().nullable(),
|
|
73191
73338
|
/** Speed tokens the hardware accepts — drives the UI selector. */
|
|
73192
73339
|
availableFanSpeeds: zod.z.array(zod.z.string()),
|
|
73193
|
-
/** Clean-water (mop) tank. Null when the hardware has no clean-water tank. */
|
|
73194
|
-
cleanWater: TankStatusSchema.nullable(),
|
|
73195
|
-
/** Dirty-water (recovery) tank. Null when the hardware has no dirty-water tank. */
|
|
73196
|
-
dirtyWater: TankStatusSchema.nullable(),
|
|
73197
|
-
/** Detergent tank. Null when the hardware has no detergent tank. */
|
|
73198
|
-
detergent: TankStatusSchema.nullable(),
|
|
73199
|
-
/** Dust bin. Null when the hardware has no dust bin. */
|
|
73200
|
-
dustBin: TankStatusSchema.nullable(),
|
|
73201
73340
|
/** 0..100 cleaning-completion percentage of the current task, or null. */
|
|
73202
73341
|
progressPercent: zod.z.number().min(0).max(100).nullable(),
|
|
73203
73342
|
/** Current error code (0 / null = no error). */
|
|
@@ -73259,35 +73398,14 @@ var vacuumControlCapability = {
|
|
|
73259
73398
|
*/
|
|
73260
73399
|
durability: "session",
|
|
73261
73400
|
/**
|
|
73262
|
-
* History (D850): recorded series.
|
|
73401
|
+
* History (D850): recorded series. The tanks moved to `consumables` (D915), whose
|
|
73402
|
+
* items are keyed by runtime ids and record no history.
|
|
73263
73403
|
*/
|
|
73264
|
-
history: { fields: {
|
|
73265
|
-
|
|
73266
|
-
|
|
73267
|
-
|
|
73268
|
-
|
|
73269
|
-
},
|
|
73270
|
-
"cleanWater.level": {
|
|
73271
|
-
kind: "gauge",
|
|
73272
|
-
unit: "%",
|
|
73273
|
-
deadband: 2
|
|
73274
|
-
},
|
|
73275
|
-
"dirtyWater.level": {
|
|
73276
|
-
kind: "gauge",
|
|
73277
|
-
unit: "%",
|
|
73278
|
-
deadband: 2
|
|
73279
|
-
},
|
|
73280
|
-
"detergent.level": {
|
|
73281
|
-
kind: "gauge",
|
|
73282
|
-
unit: "%",
|
|
73283
|
-
deadband: 2
|
|
73284
|
-
},
|
|
73285
|
-
"dustBin.level": {
|
|
73286
|
-
kind: "gauge",
|
|
73287
|
-
unit: "%",
|
|
73288
|
-
deadband: 2
|
|
73289
|
-
}
|
|
73290
|
-
} }
|
|
73404
|
+
history: { fields: { batteryLevel: {
|
|
73405
|
+
kind: "gauge",
|
|
73406
|
+
unit: "%",
|
|
73407
|
+
deadband: 2
|
|
73408
|
+
} } }
|
|
73291
73409
|
};
|
|
73292
73410
|
//#endregion
|
|
73293
73411
|
//#region src/capabilities/valve.cap.ts
|
|
@@ -79805,6 +79923,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
79805
79923
|
addonId: null,
|
|
79806
79924
|
access: "create"
|
|
79807
79925
|
},
|
|
79926
|
+
"deviceHistory.deleteOrphanSeries": {
|
|
79927
|
+
capName: "device-history",
|
|
79928
|
+
capScope: "system",
|
|
79929
|
+
addonId: null,
|
|
79930
|
+
access: "delete"
|
|
79931
|
+
},
|
|
79808
79932
|
"deviceHistory.getDeviceEnabled": {
|
|
79809
79933
|
capName: "device-history",
|
|
79810
79934
|
capScope: "system",
|
|
@@ -79823,6 +79947,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
79823
79947
|
addonId: null,
|
|
79824
79948
|
access: "view"
|
|
79825
79949
|
},
|
|
79950
|
+
"deviceHistory.listOrphanSeries": {
|
|
79951
|
+
capName: "device-history",
|
|
79952
|
+
capScope: "system",
|
|
79953
|
+
addonId: null,
|
|
79954
|
+
access: "view"
|
|
79955
|
+
},
|
|
79826
79956
|
"deviceHistory.listSeries": {
|
|
79827
79957
|
capName: "device-history",
|
|
79828
79958
|
capScope: "system",
|
|
@@ -93343,7 +93473,7 @@ var BucketAccumulator = class {
|
|
|
93343
93473
|
//#region src/generated/history-catalog.ts
|
|
93344
93474
|
/**
|
|
93345
93475
|
* Cap history catalog, projected from every `*.cap.ts` `history` block.
|
|
93346
|
-
* 40 caps with series (
|
|
93476
|
+
* 40 caps with series (73 series), 30 caps answered `'none'`.
|
|
93347
93477
|
* Field keys are `runtimeState` paths (`a.b` into fixed objects only).
|
|
93348
93478
|
*/
|
|
93349
93479
|
var HISTORY_CATALOG = {
|
|
@@ -93646,33 +93776,11 @@ var HISTORY_CATALOG = {
|
|
|
93646
93776
|
unit: "°C",
|
|
93647
93777
|
deadband: .1
|
|
93648
93778
|
} },
|
|
93649
|
-
"vacuum-control": {
|
|
93650
|
-
"
|
|
93651
|
-
|
|
93652
|
-
|
|
93653
|
-
|
|
93654
|
-
},
|
|
93655
|
-
"cleanWater.level": {
|
|
93656
|
-
kind: "gauge",
|
|
93657
|
-
unit: "%",
|
|
93658
|
-
deadband: 2
|
|
93659
|
-
},
|
|
93660
|
-
"dirtyWater.level": {
|
|
93661
|
-
kind: "gauge",
|
|
93662
|
-
unit: "%",
|
|
93663
|
-
deadband: 2
|
|
93664
|
-
},
|
|
93665
|
-
"detergent.level": {
|
|
93666
|
-
kind: "gauge",
|
|
93667
|
-
unit: "%",
|
|
93668
|
-
deadband: 2
|
|
93669
|
-
},
|
|
93670
|
-
"dustBin.level": {
|
|
93671
|
-
kind: "gauge",
|
|
93672
|
-
unit: "%",
|
|
93673
|
-
deadband: 2
|
|
93674
|
-
}
|
|
93675
|
-
},
|
|
93779
|
+
"vacuum-control": { "batteryLevel": {
|
|
93780
|
+
kind: "gauge",
|
|
93781
|
+
unit: "%",
|
|
93782
|
+
deadband: 2
|
|
93783
|
+
} },
|
|
93676
93784
|
"valve": { "position": {
|
|
93677
93785
|
kind: "gauge",
|
|
93678
93786
|
unit: "%",
|
|
@@ -93714,13 +93822,47 @@ var HISTORY_CATALOG = {
|
|
|
93714
93822
|
}
|
|
93715
93823
|
}
|
|
93716
93824
|
};
|
|
93825
|
+
/**
|
|
93826
|
+
* Keyed-array series (D917), projected from every `history.items` block:
|
|
93827
|
+
* 1 caps (3 item fields). The item key is the series SCOPE;
|
|
93828
|
+
* the series key is `cap:<capName>.<path>[].<field>`.
|
|
93829
|
+
*/
|
|
93830
|
+
var HISTORY_ITEM_CATALOG = { "consumables": {
|
|
93831
|
+
path: "items",
|
|
93832
|
+
key: "key",
|
|
93833
|
+
label: "label",
|
|
93834
|
+
fields: {
|
|
93835
|
+
"level": {
|
|
93836
|
+
kind: "gauge",
|
|
93837
|
+
unit: "%",
|
|
93838
|
+
deadband: 2,
|
|
93839
|
+
displayName: "Level"
|
|
93840
|
+
},
|
|
93841
|
+
"status": {
|
|
93842
|
+
kind: "enum",
|
|
93843
|
+
displayName: "Status",
|
|
93844
|
+
values: [
|
|
93845
|
+
"ok",
|
|
93846
|
+
"low",
|
|
93847
|
+
"empty",
|
|
93848
|
+
"full",
|
|
93849
|
+
"replace"
|
|
93850
|
+
]
|
|
93851
|
+
},
|
|
93852
|
+
"remaining.value": {
|
|
93853
|
+
kind: "gauge",
|
|
93854
|
+
unitFrom: "remaining.unit",
|
|
93855
|
+
deadband: 1,
|
|
93856
|
+
displayName: "Remaining"
|
|
93857
|
+
}
|
|
93858
|
+
}
|
|
93859
|
+
} };
|
|
93717
93860
|
/** Caps that declared `history: 'none'`, sorted. */
|
|
93718
93861
|
var HISTORY_NONE_CAPS = [
|
|
93719
93862
|
"audio-metrics",
|
|
93720
93863
|
"automation-control",
|
|
93721
93864
|
"camera-streams",
|
|
93722
93865
|
"color",
|
|
93723
|
-
"consumables",
|
|
93724
93866
|
"control",
|
|
93725
93867
|
"day-night",
|
|
93726
93868
|
"device-discovery",
|
|
@@ -94018,7 +94160,9 @@ function createSystemProxy(api) {
|
|
|
94018
94160
|
declareSeries: (input) => dispatch("deviceHistory", "declareSeries", "mutation", input),
|
|
94019
94161
|
record: (input) => dispatch("deviceHistory", "record", "mutation", input),
|
|
94020
94162
|
recordBuckets: (input) => dispatch("deviceHistory", "recordBuckets", "mutation", input),
|
|
94021
|
-
getStatus: (input) => dispatch("deviceHistory", "getStatus", "query", input)
|
|
94163
|
+
getStatus: (input) => dispatch("deviceHistory", "getStatus", "query", input),
|
|
94164
|
+
listOrphanSeries: (input) => dispatch("deviceHistory", "listOrphanSeries", "query", input),
|
|
94165
|
+
deleteOrphanSeries: (input) => dispatch("deviceHistory", "deleteOrphanSeries", "mutation", input)
|
|
94022
94166
|
},
|
|
94023
94167
|
deviceManager: {
|
|
94024
94168
|
allocateDeviceId: (input) => dispatch("deviceManager", "allocateDeviceId", "mutation", input),
|
|
@@ -97981,17 +98125,18 @@ var NC_TEMPLATE_VARS = [
|
|
|
97981
98125
|
{
|
|
97982
98126
|
name: "item",
|
|
97983
98127
|
label: "Consumable",
|
|
98128
|
+
description: "The device's own name for the item: a filter, a brush, the salt, a tank.",
|
|
97984
98129
|
example: "Filtro",
|
|
97985
98130
|
group: "system",
|
|
97986
98131
|
families: ["rule"],
|
|
97987
98132
|
fields: [...RULE_TEXT],
|
|
97988
98133
|
kinds: ["system"],
|
|
97989
|
-
systemEventKinds: [...CONSUMABLE]
|
|
98134
|
+
systemEventKinds: [...CONSUMABLE, ...TANK]
|
|
97990
98135
|
},
|
|
97991
98136
|
{
|
|
97992
98137
|
name: "tank",
|
|
97993
98138
|
label: "Tank",
|
|
97994
|
-
description: "Which tank:
|
|
98139
|
+
description: "Which tank, as a stable token: cleanWater, dirtyWater, detergent, dustBin, or the device key of any other supply (salt, rinse aid).",
|
|
97995
98140
|
example: "clean water",
|
|
97996
98141
|
group: "system",
|
|
97997
98142
|
families: ["rule"],
|
|
@@ -100912,28 +101057,33 @@ var DETECTOR_PERF = {
|
|
|
100912
101057
|
},
|
|
100913
101058
|
"amd-igpu": {
|
|
100914
101059
|
"yolov9t-320": {
|
|
100915
|
-
p50Ms:
|
|
100916
|
-
fps:
|
|
101060
|
+
p50Ms: 40,
|
|
101061
|
+
fps: 25,
|
|
100917
101062
|
measured: true
|
|
100918
101063
|
},
|
|
100919
101064
|
"yolov9t-640": {
|
|
100920
|
-
p50Ms:
|
|
100921
|
-
fps:
|
|
101065
|
+
p50Ms: 89,
|
|
101066
|
+
fps: 11,
|
|
100922
101067
|
measured: true
|
|
100923
101068
|
},
|
|
100924
101069
|
"yolov9s-320": {
|
|
100925
|
-
p50Ms:
|
|
100926
|
-
fps:
|
|
101070
|
+
p50Ms: 65,
|
|
101071
|
+
fps: 15,
|
|
100927
101072
|
measured: true
|
|
100928
101073
|
},
|
|
100929
101074
|
"yolov9s-640": {
|
|
100930
|
-
p50Ms:
|
|
100931
|
-
fps:
|
|
101075
|
+
p50Ms: 125,
|
|
101076
|
+
fps: 8,
|
|
100932
101077
|
measured: true
|
|
100933
101078
|
},
|
|
100934
101079
|
"yolov9m-320": {
|
|
100935
|
-
p50Ms:
|
|
100936
|
-
fps:
|
|
101080
|
+
p50Ms: 85,
|
|
101081
|
+
fps: 12,
|
|
101082
|
+
measured: true
|
|
101083
|
+
},
|
|
101084
|
+
"yolov9m-640": {
|
|
101085
|
+
p50Ms: 228,
|
|
101086
|
+
fps: 4,
|
|
100937
101087
|
measured: true
|
|
100938
101088
|
}
|
|
100939
101089
|
},
|
|
@@ -101371,15 +101521,23 @@ function byDeficit(a, b) {
|
|
|
101371
101521
|
function spareOf(c) {
|
|
101372
101522
|
return c.spare ?? Number.POSITIVE_INFINITY;
|
|
101373
101523
|
}
|
|
101374
|
-
function
|
|
101375
|
-
|
|
101524
|
+
function loadOf(c) {
|
|
101525
|
+
return Math.max(c.running, 0) + Math.max(c.recent ?? 0, 0);
|
|
101526
|
+
}
|
|
101527
|
+
/** Every candidate with its deficit, the turn holder first. */
|
|
101528
|
+
function scoreShares(candidates) {
|
|
101376
101529
|
const shareSum = candidates.reduce((s, c) => s + Math.max(c.share, 0), 0);
|
|
101377
|
-
const loadOf = (c) => Math.max(c.running, 0) + Math.max(c.recent ?? 0, 0);
|
|
101378
101530
|
const running = candidates.reduce((s, c) => s + loadOf(c), 0);
|
|
101379
|
-
|
|
101531
|
+
return candidates.map((candidate) => ({
|
|
101380
101532
|
candidate,
|
|
101381
101533
|
deficit: (shareSum > 0 ? Math.max(candidate.share, 0) / shareSum : 1 / candidates.length) * (running + 1) - loadOf(candidate)
|
|
101382
101534
|
})).toSorted(byDeficit);
|
|
101535
|
+
}
|
|
101536
|
+
function electByShare(candidates) {
|
|
101537
|
+
if (candidates.length === 0) return { kind: "none" };
|
|
101538
|
+
return electFromScored(scoreShares(candidates));
|
|
101539
|
+
}
|
|
101540
|
+
function electFromScored(scored) {
|
|
101383
101541
|
const turn = scored[0].candidate;
|
|
101384
101542
|
if (!turn.capped && !turn.saturated) return {
|
|
101385
101543
|
kind: "elected",
|
|
@@ -101403,6 +101561,55 @@ function electByShare(candidates) {
|
|
|
101403
101561
|
reason: "share"
|
|
101404
101562
|
};
|
|
101405
101563
|
}
|
|
101564
|
+
/**
|
|
101565
|
+
* Affinity (D916, amends D913): a camera's sessions are short and frequent, and
|
|
101566
|
+
* every election is a fresh one — with the recency memory rotating on purpose,
|
|
101567
|
+
* one camera hopped node on 11 of 14 sessions in ten minutes, each hop a stream
|
|
101568
|
+
* dial, a decode-worker fork and a cold pre-roll. The candidate a camera ran on
|
|
101569
|
+
* last is kept while its deficit is within {@link SHARE_AFFINITY_TOLERANCE_SESSIONS}
|
|
101570
|
+
* of the turn holder's, and while it has room (offered, not capped, not
|
|
101571
|
+
* drowning). It moves only when the share is really off — and because a kept
|
|
101572
|
+
* session still counts toward its candidate, the cumulative split still follows
|
|
101573
|
+
* the shares: no candidate runs more than about one session over its share
|
|
101574
|
+
* before its cameras leave.
|
|
101575
|
+
*/
|
|
101576
|
+
var SHARE_AFFINITY_TOLERANCE_SESSIONS = 1;
|
|
101577
|
+
function toScoredCandidate(s) {
|
|
101578
|
+
return {
|
|
101579
|
+
key: s.candidate.key,
|
|
101580
|
+
share: s.candidate.share,
|
|
101581
|
+
running: s.candidate.running,
|
|
101582
|
+
recent: s.candidate.recent ?? 0,
|
|
101583
|
+
deficit: s.deficit
|
|
101584
|
+
};
|
|
101585
|
+
}
|
|
101586
|
+
/** {@link electByShare}, keeping the previous candidate while the share allows it. */
|
|
101587
|
+
function electByShareWithAffinity(candidates, previousKey, toleranceSessions = 1) {
|
|
101588
|
+
const scored = candidates.length === 0 ? [] : scoreShares(candidates);
|
|
101589
|
+
const plain = scored.length === 0 ? { kind: "none" } : electFromScored(scored);
|
|
101590
|
+
const turnKey = plain.kind === "elected" ? plain.key : null;
|
|
101591
|
+
const result = (election, sticky, affinityReason) => ({
|
|
101592
|
+
election,
|
|
101593
|
+
sticky,
|
|
101594
|
+
affinityReason,
|
|
101595
|
+
previousKey,
|
|
101596
|
+
turnKey,
|
|
101597
|
+
scored: scored.map(toScoredCandidate)
|
|
101598
|
+
});
|
|
101599
|
+
if (previousKey === null) return result(plain, false, "no-previous");
|
|
101600
|
+
if (turnKey === previousKey) return result(plain, true, "previous-is-turn");
|
|
101601
|
+
const previous = scored.find((s) => s.candidate.key === previousKey);
|
|
101602
|
+
if (previous === void 0) return result(plain, false, "previous-ineligible");
|
|
101603
|
+
if (previous.candidate.capped || previous.candidate.saturated) return result(plain, false, "previous-no-room");
|
|
101604
|
+
const elected = scored.find((s) => s.candidate.key === turnKey);
|
|
101605
|
+
if (elected === void 0) return result(plain, false, "share-off");
|
|
101606
|
+
if (previous.deficit >= elected.deficit - toleranceSessions - DEFICIT_EPSILON) return result({
|
|
101607
|
+
kind: "elected",
|
|
101608
|
+
key: previousKey,
|
|
101609
|
+
reason: "share"
|
|
101610
|
+
}, true, "within-one-session");
|
|
101611
|
+
return result(plain, false, "share-off");
|
|
101612
|
+
}
|
|
101406
101613
|
//#endregion
|
|
101407
101614
|
//#region src/pipeline/load-balancing/effective-shares.ts
|
|
101408
101615
|
/**
|
|
@@ -101490,6 +101697,39 @@ function resolveEffectiveShares(input) {
|
|
|
101490
101697
|
* every enabled device it would be sized on is sized from `hardware`
|
|
101491
101698
|
* instead, and the answer says so per node — never a silent mix.
|
|
101492
101699
|
*/
|
|
101700
|
+
/**
|
|
101701
|
+
* The measured capacity of `deviceKey` for the model it runs NOW, or
|
|
101702
|
+
* undefined. A cell measured for another model says nothing about this one
|
|
101703
|
+
* (a failed load of a heavier build is not this build's capacity), and a cell
|
|
101704
|
+
* that names no model cannot be matched. The ONE predicate behind both the
|
|
101705
|
+
* automatic shares and the automatic benchmark's "has results".
|
|
101706
|
+
*/
|
|
101707
|
+
function capacityForModel(node, deviceKey, modelId) {
|
|
101708
|
+
if (node === void 0 || modelId === null) return void 0;
|
|
101709
|
+
return node.devices.filter((d) => d.deviceKey === deviceKey && d.modelId === modelId).toSorted((a, b) => b.measuredAtMs - a.measuredAtMs)[0];
|
|
101710
|
+
}
|
|
101711
|
+
/**
|
|
101712
|
+
* Every measured (device × model) cell that no device runs now — what
|
|
101713
|
+
* {@link capacityForModel} skips, so the caller can say so once.
|
|
101714
|
+
*/
|
|
101715
|
+
function foreignCapacityCells(recommendations, measured) {
|
|
101716
|
+
const out = [];
|
|
101717
|
+
for (const rec of recommendations) {
|
|
101718
|
+
const node = measured.get(rec.nodeId);
|
|
101719
|
+
if (node === void 0) continue;
|
|
101720
|
+
for (const cell of node.devices) {
|
|
101721
|
+
const runs = rec.devices.find((d) => d.deviceKey === cell.deviceKey)?.chosen?.modelId ?? null;
|
|
101722
|
+
if (cell.modelId === null || cell.modelId === runs) continue;
|
|
101723
|
+
out.push({
|
|
101724
|
+
nodeId: rec.nodeId,
|
|
101725
|
+
deviceKey: cell.deviceKey,
|
|
101726
|
+
measuredModelId: cell.modelId,
|
|
101727
|
+
runsModelId: runs
|
|
101728
|
+
});
|
|
101729
|
+
}
|
|
101730
|
+
}
|
|
101731
|
+
return out;
|
|
101732
|
+
}
|
|
101493
101733
|
/** A source that has no results — the benchmark store before it exists. */
|
|
101494
101734
|
var NO_MEASURED_CAPACITY = { readMeasuredCapacity: async () => /* @__PURE__ */ new Map() };
|
|
101495
101735
|
/** Integer shares summing to 100 (largest remainder); ties broken by key. */
|
|
@@ -101543,7 +101783,11 @@ function sizeNode(rec, input) {
|
|
|
101543
101783
|
if (input.source === "hardware") return fromHardware(null);
|
|
101544
101784
|
if (!rec.reachable) return fromHardware(null);
|
|
101545
101785
|
const results = input.measured.get(rec.nodeId);
|
|
101546
|
-
const byKey = new Map(
|
|
101786
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
101787
|
+
for (const d of rec.devices) {
|
|
101788
|
+
const row = capacityForModel(results, d.deviceKey, d.chosen?.modelId ?? null);
|
|
101789
|
+
if (row !== void 0) byKey.set(d.deviceKey, row);
|
|
101790
|
+
}
|
|
101547
101791
|
const usable = rec.devices.filter((d) => d.enabled && d.available);
|
|
101548
101792
|
const mustCover = rec.devices.filter((d) => d.enabled && d.available && d.chosen !== null);
|
|
101549
101793
|
const covered = usable.filter((d) => byKey.has(d.deviceKey));
|
|
@@ -101797,16 +102041,34 @@ function measuredDetectorCells(rows, nodeId, ctx) {
|
|
|
101797
102041
|
return out;
|
|
101798
102042
|
}
|
|
101799
102043
|
/**
|
|
101800
|
-
*
|
|
101801
|
-
*
|
|
102044
|
+
* Parallel sessions a `device`-phase cell stands for.
|
|
102045
|
+
*
|
|
102046
|
+
* Both numbers are "streams at the camera rate the hardware carried inside
|
|
102047
|
+
* the frame interval" (`kMax` for the detector alone, `maxSessions` for the
|
|
102048
|
+
* detector plus its enrichment steps) and the benchmark page already shows
|
|
102049
|
+
* `kMax` as "streams", so the unit is the same and the conversion is the
|
|
102050
|
+
* identity. It is an UPPER bound for a session that also runs enrichment —
|
|
102051
|
+
* which is why a `pipeline` cell for the same model always wins over it.
|
|
102052
|
+
*/
|
|
102053
|
+
function sessionsOfDeviceCell(kMax) {
|
|
102054
|
+
return Math.max(0, Math.floor(kMax));
|
|
102055
|
+
}
|
|
102056
|
+
/**
|
|
102057
|
+
* Per node, every (device × model) at its best fresh measurement: the newest
|
|
102058
|
+
* `pipeline` cell, else the newest `device` cell read as
|
|
102059
|
+
* {@link sessionsOfDeviceCell}. Several models of one device are kept apart —
|
|
102060
|
+
* the caller picks the one the device runs NOW (a cell for another model says
|
|
102061
|
+
* nothing about it).
|
|
101802
102062
|
*/
|
|
101803
102063
|
function measuredCapacityFromResults(rows, nodeIds, ctx) {
|
|
101804
102064
|
const byNode = /* @__PURE__ */ new Map();
|
|
101805
102065
|
for (const row of freshResults(rows, ctx)) {
|
|
101806
|
-
if (!nodeIds.includes(row.nodeId)
|
|
102066
|
+
if (!nodeIds.includes(row.nodeId)) continue;
|
|
102067
|
+
const candidate = capacityOfRow(row);
|
|
101807
102068
|
const devices = byNode.get(row.nodeId) ?? /* @__PURE__ */ new Map();
|
|
101808
|
-
const
|
|
101809
|
-
|
|
102069
|
+
const key = `${candidate.deviceKey}\u0000${candidate.modelId ?? ""}`;
|
|
102070
|
+
const held = devices.get(key);
|
|
102071
|
+
if (held === void 0 || betterCapacityCell(candidate, held)) devices.set(key, candidate);
|
|
101810
102072
|
byNode.set(row.nodeId, devices);
|
|
101811
102073
|
}
|
|
101812
102074
|
const out = /* @__PURE__ */ new Map();
|
|
@@ -101815,16 +102077,32 @@ function measuredCapacityFromResults(rows, nodeIds, ctx) {
|
|
|
101815
102077
|
if (devices === void 0) continue;
|
|
101816
102078
|
out.set(nodeId, {
|
|
101817
102079
|
nodeId,
|
|
101818
|
-
devices: [...devices.values()].toSorted((a, b) => a.
|
|
101819
|
-
deviceKey: r.cell.deviceKey,
|
|
101820
|
-
maxSessions: r.cell.phase === "pipeline" ? r.cell.maxSessions : 0,
|
|
101821
|
-
modelId: r.cell.modelId,
|
|
101822
|
-
measuredAtMs: r.measuredAtMs
|
|
101823
|
-
}))
|
|
102080
|
+
devices: [...devices.values()].toSorted((a, b) => a.deviceKey.localeCompare(b.deviceKey) || (a.modelId ?? "").localeCompare(b.modelId ?? ""))
|
|
101824
102081
|
});
|
|
101825
102082
|
}
|
|
101826
102083
|
return out;
|
|
101827
102084
|
}
|
|
102085
|
+
function capacityOfRow(row) {
|
|
102086
|
+
const { cell } = row;
|
|
102087
|
+
return cell.phase === "pipeline" ? {
|
|
102088
|
+
deviceKey: cell.deviceKey,
|
|
102089
|
+
maxSessions: cell.maxSessions,
|
|
102090
|
+
modelId: cell.modelId,
|
|
102091
|
+
measuredAtMs: row.measuredAtMs,
|
|
102092
|
+
phase: "pipeline"
|
|
102093
|
+
} : {
|
|
102094
|
+
deviceKey: cell.deviceKey,
|
|
102095
|
+
maxSessions: sessionsOfDeviceCell(cell.kMax),
|
|
102096
|
+
modelId: cell.modelId,
|
|
102097
|
+
measuredAtMs: row.measuredAtMs,
|
|
102098
|
+
phase: "device"
|
|
102099
|
+
};
|
|
102100
|
+
}
|
|
102101
|
+
/** A pipeline cell beats a device cell; within a phase the newer one wins. */
|
|
102102
|
+
function betterCapacityCell(a, b) {
|
|
102103
|
+
if (a.phase !== b.phase) return a.phase === "pipeline";
|
|
102104
|
+
return a.measuredAtMs > b.measuredAtMs;
|
|
102105
|
+
}
|
|
101828
102106
|
//#endregion
|
|
101829
102107
|
//#region src/pipeline/node-benchmark/step-tree.ts
|
|
101830
102108
|
var BENCH_ROOT_STEP_ID = "object-detection";
|
|
@@ -104564,9 +104842,13 @@ exports.ConnectionTestDescriptorSchema = ConnectionTestDescriptorSchema;
|
|
|
104564
104842
|
exports.ConnectionTestInputSchema = ConnectionTestInputSchema;
|
|
104565
104843
|
exports.ConnectionTestOutcomeSchema = ConnectionTestOutcomeSchema;
|
|
104566
104844
|
exports.ConnectivityStatusSchema = ConnectivityStatusSchema;
|
|
104845
|
+
exports.ConsumableFormSchema = ConsumableFormSchema;
|
|
104567
104846
|
exports.ConsumableItemSchema = ConsumableItemSchema;
|
|
104847
|
+
exports.ConsumableKindSchema = ConsumableKindSchema;
|
|
104848
|
+
exports.ConsumableLevelSchema = ConsumableLevelSchema;
|
|
104568
104849
|
exports.ConsumableRemainingSchema = ConsumableRemainingSchema;
|
|
104569
104850
|
exports.ConsumableRemainingUnitSchema = ConsumableRemainingUnitSchema;
|
|
104851
|
+
exports.ConsumableStatusSchema = ConsumableStatusSchema;
|
|
104570
104852
|
exports.ConsumablesStatusSchema = ConsumablesStatusSchema;
|
|
104571
104853
|
exports.ContactStatusSchema = ContactStatusSchema;
|
|
104572
104854
|
exports.ControlKindSchema = ControlKindSchema;
|
|
@@ -104647,6 +104929,8 @@ exports.DEVICE_DEFINITIVE_REFUSALS_BEFORE_DELETE = DEVICE_DEFINITIVE_REFUSALS_BE
|
|
|
104647
104929
|
exports.DEVICE_DO_ACTIONS = DEVICE_DO_ACTIONS;
|
|
104648
104930
|
exports.DEVICE_ENROLLMENT_TTL_MS = DEVICE_ENROLLMENT_TTL_MS;
|
|
104649
104931
|
exports.DEVICE_HISTORY_ENERGY_KEY = DEVICE_HISTORY_ENERGY_KEY;
|
|
104932
|
+
exports.DEVICE_HISTORY_ORPHAN_DELETE_MAX = DEVICE_HISTORY_ORPHAN_DELETE_MAX;
|
|
104933
|
+
exports.DEVICE_HISTORY_ORPHAN_LIST_MAX = DEVICE_HISTORY_ORPHAN_LIST_MAX;
|
|
104650
104934
|
exports.DEVICE_HISTORY_QUERY_MANY_MAX_ITEMS = DEVICE_HISTORY_QUERY_MANY_MAX_ITEMS;
|
|
104651
104935
|
exports.DEVICE_NONCE_TTL_MS = DEVICE_NONCE_TTL_MS;
|
|
104652
104936
|
exports.DEVICE_PROFILES = DEVICE_PROFILES;
|
|
@@ -104706,6 +104990,8 @@ exports.DeviceExportStatusSchema = DeviceExportStatusSchema;
|
|
|
104706
104990
|
exports.DeviceExportUnexposeInputSchema = UnexposeInputSchema;
|
|
104707
104991
|
exports.DeviceFeature = require_err_msg.DeviceFeature;
|
|
104708
104992
|
exports.DeviceHistoryKindSchema = DeviceHistoryKindSchema;
|
|
104993
|
+
exports.DeviceHistoryOrphanDeleteRefusalSchema = DeviceHistoryOrphanDeleteRefusalSchema;
|
|
104994
|
+
exports.DeviceHistoryOrphanReasonSchema = DeviceHistoryOrphanReasonSchema;
|
|
104709
104995
|
exports.DeviceHistoryProducerKindSchema = DeviceHistoryProducerKindSchema;
|
|
104710
104996
|
exports.DeviceHistoryRefusalReasonSchema = DeviceHistoryRefusalReasonSchema;
|
|
104711
104997
|
exports.DeviceHistoryResolutionSchema = DeviceHistoryResolutionSchema;
|
|
@@ -104738,7 +105024,6 @@ exports.DiscoveredDeviceSchema = DiscoveredDeviceSchema;
|
|
|
104738
105024
|
exports.DiscoveredTargetSchema = DiscoveredTargetSchema;
|
|
104739
105025
|
exports.DishwasherAccessSchema = DishwasherAccessSchema;
|
|
104740
105026
|
exports.DishwasherAvailabilitySchema = DishwasherAvailabilitySchema;
|
|
104741
|
-
exports.DishwasherConsumableLevelSchema = DishwasherConsumableLevelSchema;
|
|
104742
105027
|
exports.DishwasherOperationStateSchema = DishwasherOperationStateSchema;
|
|
104743
105028
|
exports.DishwasherOptionDescriptorSchema = DishwasherOptionDescriptorSchema;
|
|
104744
105029
|
exports.DishwasherOptionsSchema = DishwasherOptionsSchema;
|
|
@@ -104899,6 +105184,7 @@ exports.HF_REPO = require_sleep.HF_REPO;
|
|
|
104899
105184
|
exports.HISTORY_BUCKET_MS = HISTORY_BUCKET_MS;
|
|
104900
105185
|
exports.HISTORY_CATALOG = HISTORY_CATALOG;
|
|
104901
105186
|
exports.HISTORY_DEFAULT_MIN_INTERVAL_MS = require_sleep.HISTORY_DEFAULT_MIN_INTERVAL_MS;
|
|
105187
|
+
exports.HISTORY_ITEM_CATALOG = HISTORY_ITEM_CATALOG;
|
|
104902
105188
|
exports.HISTORY_NONE_CAPS = HISTORY_NONE_CAPS;
|
|
104903
105189
|
exports.HISTORY_UNIT_LABELS = require_sleep.HISTORY_UNIT_LABELS;
|
|
104904
105190
|
exports.HOURS_PER_DAY = HOURS_PER_DAY;
|
|
@@ -105787,6 +106073,7 @@ exports.SENSOR_MAP = SENSOR_MAP;
|
|
|
105787
106073
|
exports.SERVER_NAME_MAX_LENGTH = SERVER_NAME_MAX_LENGTH;
|
|
105788
106074
|
exports.SERVER_NAME_SETTING_KEY = SERVER_NAME_SETTING_KEY;
|
|
105789
106075
|
exports.SESSION_PLACEMENT_SETTING_KEY = SESSION_PLACEMENT_SETTING_KEY;
|
|
106076
|
+
exports.SHARE_AFFINITY_TOLERANCE_SESSIONS = SHARE_AFFINITY_TOLERANCE_SESSIONS;
|
|
105790
106077
|
exports.SHARE_SOURCE_SETTING_KEY = SHARE_SOURCE_SETTING_KEY;
|
|
105791
106078
|
exports.SHARE_VIEW_KINDS = require_sleep.SHARE_VIEW_KINDS;
|
|
105792
106079
|
exports.SHARE_VIEW_MAX_DEVICES = SHARE_VIEW_MAX_DEVICES;
|
|
@@ -105951,7 +106238,6 @@ exports.TRAINING_RESULT_SCHEMA = TRAINING_RESULT_SCHEMA;
|
|
|
105951
106238
|
exports.TRANSCODE_DOWN_MAX_BITRATE_KBPS = TRANSCODE_DOWN_MAX_BITRATE_KBPS;
|
|
105952
106239
|
exports.TRANSCODE_DOWN_MAX_HEIGHT = TRANSCODE_DOWN_MAX_HEIGHT;
|
|
105953
106240
|
exports.TamperStatusSchema = TamperStatusSchema;
|
|
105954
|
-
exports.TankStatusSchema = TankStatusSchema;
|
|
105955
106241
|
exports.TargetKindCapsSchema = TargetKindCapsSchema;
|
|
105956
106242
|
exports.TargetKindLevelSchema = TargetKindLevelSchema;
|
|
105957
106243
|
exports.TargetKindSchema = TargetKindSchema;
|
|
@@ -106223,6 +106509,7 @@ exports.canonicalEgressPlan = canonicalEgressPlan;
|
|
|
106223
106509
|
exports.canonicalIconKey = canonicalIconKey;
|
|
106224
106510
|
exports.canonicalizeAppCallback = canonicalizeAppCallback;
|
|
106225
106511
|
exports.capabilityScopesOf = capabilityScopesOf;
|
|
106512
|
+
exports.capacityForModel = capacityForModel;
|
|
106226
106513
|
exports.capacitySessionsOf = capacitySessionsOf;
|
|
106227
106514
|
exports.carbonMonoxideCapability = carbonMonoxideCapability;
|
|
106228
106515
|
exports.cellsToRects = cellsToRects;
|
|
@@ -106281,6 +106568,8 @@ exports.conditionExclusionReason = conditionExclusionReason;
|
|
|
106281
106568
|
exports.conditionVisibleForKind = conditionVisibleForKind;
|
|
106282
106569
|
exports.connectionTestCapability = connectionTestCapability;
|
|
106283
106570
|
exports.connectivityCapability = connectivityCapability;
|
|
106571
|
+
exports.consumableFormOf = consumableFormOf;
|
|
106572
|
+
exports.consumableKindOf = consumableKindOf;
|
|
106284
106573
|
exports.consumableLowPercentOf = consumableLowPercentOf;
|
|
106285
106574
|
exports.consumablesCapability = consumablesCapability;
|
|
106286
106575
|
exports.contactCapability = contactCapability;
|
|
@@ -106387,6 +106676,7 @@ exports.effectiveStepSettings = effectiveStepSettings;
|
|
|
106387
106676
|
exports.egressTranscodeSharingKey = egressTranscodeSharingKey;
|
|
106388
106677
|
exports.egressTransportFromRequest = egressTransportFromRequest;
|
|
106389
106678
|
exports.electByShare = electByShare;
|
|
106679
|
+
exports.electByShareWithAffinity = electByShareWithAffinity;
|
|
106390
106680
|
exports.eligibleUnderBenchmark = eligibleUnderBenchmark;
|
|
106391
106681
|
exports.embeddingEncoderCapability = embeddingEncoderCapability;
|
|
106392
106682
|
exports.embeddingModelFailedError = embeddingModelFailedError;
|
|
@@ -106451,6 +106741,7 @@ exports.findCompositionCycles = findCompositionCycles;
|
|
|
106451
106741
|
exports.findTimezone = findTimezone;
|
|
106452
106742
|
exports.floodCapability = floodCapability;
|
|
106453
106743
|
exports.foldSnapshotByFunction = foldSnapshotByFunction;
|
|
106744
|
+
exports.foreignCapacityCells = foreignCapacityCells;
|
|
106454
106745
|
exports.forgetKnownSecret = require_sleep.forgetKnownSecret;
|
|
106455
106746
|
exports.formatDeviceRevoker = formatDeviceRevoker;
|
|
106456
106747
|
exports.formatForRuntime = formatForRuntime;
|
|
@@ -106479,6 +106770,7 @@ exports.hasUrlScheme = hasUrlScheme;
|
|
|
106479
106770
|
exports.heatingValveCapability = heatingValveCapability;
|
|
106480
106771
|
exports.hfModelUrl = require_sleep.hfModelUrl;
|
|
106481
106772
|
exports.historyFieldsFor = historyFieldsFor;
|
|
106773
|
+
exports.historyItemFieldPath = require_sleep.historyItemFieldPath;
|
|
106482
106774
|
exports.htmlToText = htmlToText;
|
|
106483
106775
|
exports.hubAddressHostname = hubAddressHostname;
|
|
106484
106776
|
exports.hubMotionNativeProvider = hubMotionNativeProvider;
|
|
@@ -106882,6 +107174,7 @@ exports.sensorTransitionNeverFires = sensorTransitionNeverFires;
|
|
|
106882
107174
|
exports.sensorTransitionOffered = sensorTransitionOffered;
|
|
106883
107175
|
exports.servedTemplateVars = servedTemplateVars;
|
|
106884
107176
|
exports.serverManagementCapability = serverManagementCapability;
|
|
107177
|
+
exports.sessionsOfDeviceCell = sessionsOfDeviceCell;
|
|
106885
107178
|
exports.setByPath = setByPath;
|
|
106886
107179
|
exports.settingValuesEqual = settingValuesEqual;
|
|
106887
107180
|
exports.settingsBelow = settingsBelow;
|