@camstack/addon-provider-bosch 0.1.44 → 0.1.46
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/CHANGELOG.md +12 -0
- package/dist/{account-integration-offline-IHodWmhD.mjs → account-integration-offline-BGH1q3tj.mjs} +1 -1
- package/dist/{account-integration-offline-CFyuKmsG.js → account-integration-offline-BfsMnlJo.js} +1 -1
- package/dist/{bosch-instances-CXMUquuA.js → bosch-instances-BD-Valeo.js} +1355 -187
- package/dist/{bosch-instances-C8FRjQzC.mjs → bosch-instances-DkUo6BfT.mjs} +1344 -188
- package/dist/home-connect/addon.js +2 -2
- package/dist/home-connect/addon.mjs +2 -2
- package/dist/homecom/addon.js +771 -52
- package/dist/homecom/addon.mjs +771 -52
- package/dist/shc/addon.js +1 -1
- package/dist/shc/addon.mjs +1 -1
- package/package.json +8 -2
|
@@ -802,7 +802,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
802
802
|
return EventCategory;
|
|
803
803
|
}({});
|
|
804
804
|
//#endregion
|
|
805
|
-
//#region ../types/dist/device-type-
|
|
805
|
+
//#region ../types/dist/device-type-DTTZKB2I.mjs
|
|
806
806
|
/**
|
|
807
807
|
import { errMsg } from '@camstack/types'
|
|
808
808
|
* Extract a human-readable message from an unknown error value.
|
|
@@ -928,6 +928,10 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
928
928
|
* (`reboot`, `device-admin-link`). Products are NOT its children — they are
|
|
929
929
|
* adopted beside it — and its connection settings stay on the integration. */
|
|
930
930
|
DeviceType["Gateway"] = "gateway";
|
|
931
|
+
/** A heat pump (any vendor): the compressor unit with its circuits (heating, hot
|
|
932
|
+
* water, cooling, solar), its system modes and its power. One main read-only
|
|
933
|
+
* `heat-pump-status` cap carries all of it; `heat-pump-control` sets it (D1026). */
|
|
934
|
+
DeviceType["HeatPump"] = "heat-pump";
|
|
931
935
|
return DeviceType;
|
|
932
936
|
}({});
|
|
933
937
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -6012,7 +6016,7 @@ var ZodIssueCode = {
|
|
|
6012
6016
|
var ZodFirstPartyTypeKind;
|
|
6013
6017
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6014
6018
|
//#endregion
|
|
6015
|
-
//#region ../types/dist/sleep-
|
|
6019
|
+
//#region ../types/dist/sleep-DnVqHJc4.mjs
|
|
6016
6020
|
/**
|
|
6017
6021
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6018
6022
|
* window to float samples (D455).
|
|
@@ -8759,16 +8763,6 @@ var BaseAddon = class {
|
|
|
8759
8763
|
return null;
|
|
8760
8764
|
}
|
|
8761
8765
|
/**
|
|
8762
|
-
* The form schema of ONE integration instance, or `null` to use the scoped form.
|
|
8763
|
-
*
|
|
8764
|
-
* Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
|
|
8765
|
-
* needs its connection fields, the default integration the addon's own sections. It is the
|
|
8766
|
-
* SHAPE of the form only — the values live on the instance record.
|
|
8767
|
-
*/
|
|
8768
|
-
async integrationFormSchema(_instance) {
|
|
8769
|
-
return null;
|
|
8770
|
-
}
|
|
8771
|
-
/**
|
|
8772
8766
|
* D986 scoped settings: the form shape of the CLUSTER-wide settings one capability this addon
|
|
8773
8767
|
* provides owns, or `null` when it has none. `cap` is a capability name the addon's manifest
|
|
8774
8768
|
* declares. Stored as `addon-settings` rows `<addonId>.<field>`. The keys of this schema, of
|
|
@@ -8796,8 +8790,7 @@ var BaseAddon = class {
|
|
|
8796
8790
|
}
|
|
8797
8791
|
/**
|
|
8798
8792
|
* The host's read of the scoped declarations: the schema one capability declares for `scope`,
|
|
8799
|
-
* or `null`.
|
|
8800
|
-
* host asks this method.
|
|
8793
|
+
* or `null`. The hook is protected, the host asks this method.
|
|
8801
8794
|
*/
|
|
8802
8795
|
async getScopedSettingsSchema(scope, cap) {
|
|
8803
8796
|
switch (scope) {
|
|
@@ -8965,22 +8958,6 @@ var BaseAddon = class {
|
|
|
8965
8958
|
return Object.fromEntries([...collectHydratedFieldValues(form)].filter(([, value]) => value !== void 0));
|
|
8966
8959
|
}
|
|
8967
8960
|
/**
|
|
8968
|
-
* What the create wizard and the integration edit page render for one instance: the addon's
|
|
8969
|
-
* per-instance schema when it declares one, else its global schema (what they always showed).
|
|
8970
|
-
*/
|
|
8971
|
-
async getIntegrationFormSchema(instance, nodeId) {
|
|
8972
|
-
const scoped = await this.integrationFormSchema(instance);
|
|
8973
|
-
if (scoped === null) return this.scopedForm(nodeId);
|
|
8974
|
-
return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
|
|
8975
|
-
}
|
|
8976
|
-
/** The form of the scoped schemas this addon declared, hydrated from its store. */
|
|
8977
|
-
async scopedForm(nodeId) {
|
|
8978
|
-
await this.loadScopedSchemas();
|
|
8979
|
-
const schema = this.scopedFormSchema();
|
|
8980
|
-
if (!schema) return { sections: [] };
|
|
8981
|
-
return hydrateSchema(schema, await this.readRawProjectedStore(nodeId), { inlineSecretsAsViews: true });
|
|
8982
|
-
}
|
|
8983
|
-
/**
|
|
8984
8961
|
* The raw addon store PROJECTED onto the target node's bare per-node keys:
|
|
8985
8962
|
* every `perNode: true` field carries THAT node's scoped value on its bare
|
|
8986
8963
|
* key (absent scoped key ⇒ key absent, so the schema `default` wins — no
|
|
@@ -9167,12 +9144,6 @@ var BaseAddon = class {
|
|
|
9167
9144
|
this._nodeKeysByCap = /* @__PURE__ */ new Map();
|
|
9168
9145
|
this._addonSecretTree = null;
|
|
9169
9146
|
}
|
|
9170
|
-
/** The form of an addon's scoped schemas: their sections, each shown once. */
|
|
9171
|
-
scopedFormSchema(cap) {
|
|
9172
|
-
const byId = /* @__PURE__ */ new Map();
|
|
9173
|
-
for (const entry of this.loadedScopedSchemas(cap)) for (const section of entry.schema.sections) if (!byId.has(section.id)) byId.set(section.id, section);
|
|
9174
|
-
return byId.size === 0 ? null : { sections: [...byId.values()] };
|
|
9175
|
-
}
|
|
9176
9147
|
/** Every loaded scoped schema of `cap`, or of every loaded capability. */
|
|
9177
9148
|
loadedScopedSchemas(cap) {
|
|
9178
9149
|
if (cap !== void 0) return this._scopedByCap.get(cap) ?? [];
|
|
@@ -9762,6 +9733,10 @@ function normalizeAddonInitResult(result) {
|
|
|
9762
9733
|
if (Array.isArray(result)) return { providers: result };
|
|
9763
9734
|
return result;
|
|
9764
9735
|
}
|
|
9736
|
+
object({
|
|
9737
|
+
code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
|
|
9738
|
+
params: record(string(), union([string(), number$1()])).optional()
|
|
9739
|
+
});
|
|
9765
9740
|
object({
|
|
9766
9741
|
field: string().min(1),
|
|
9767
9742
|
on: literal("advance")
|
|
@@ -9838,12 +9813,6 @@ function systemMethod(input, output, options) {
|
|
|
9838
9813
|
systemOnly: true
|
|
9839
9814
|
};
|
|
9840
9815
|
}
|
|
9841
|
-
/**
|
|
9842
|
-
* A method a SOURCE of a collection cap may legitimately not serve — OPTIONAL
|
|
9843
|
-
* on `InferProvider`. The `providerOptional: true` literal is what
|
|
9844
|
-
* `InferProvider` keys on; see {@link CapabilityMethodSchema.providerOptional}
|
|
9845
|
-
* for when this is the honest answer and when it is a soft stub.
|
|
9846
|
-
*/
|
|
9847
9816
|
function optionalMethod(input, output, options) {
|
|
9848
9817
|
return {
|
|
9849
9818
|
...method(input, output, options),
|
|
@@ -10653,7 +10622,7 @@ function t(en, it) {
|
|
|
10653
10622
|
* Things an operator switches, opens, sets or arms: lights, plugs, sirens,
|
|
10654
10623
|
* covers, valves, locks, climate, fans, alarm panels.
|
|
10655
10624
|
*/
|
|
10656
|
-
var ON = t("On", "Acceso");
|
|
10625
|
+
var ON$1 = t("On", "Acceso");
|
|
10657
10626
|
var PERCENT = t("Percentage", "Percentuale");
|
|
10658
10627
|
var OPEN_CLOSE_STATES = [
|
|
10659
10628
|
{
|
|
@@ -10713,7 +10682,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
10713
10682
|
state: [{
|
|
10714
10683
|
kind: "boolean",
|
|
10715
10684
|
field: "on",
|
|
10716
|
-
label: ON,
|
|
10685
|
+
label: ON$1,
|
|
10717
10686
|
whenTrue: t("When {device} turns on", "Quando {device} si accende"),
|
|
10718
10687
|
whenFalse: t("When {device} turns off", "Quando {device} si spegne"),
|
|
10719
10688
|
icon: "power"
|
|
@@ -11879,7 +11848,7 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
11879
11848
|
state: [{
|
|
11880
11849
|
kind: "boolean",
|
|
11881
11850
|
field: "on",
|
|
11882
|
-
label: ON,
|
|
11851
|
+
label: ON$1,
|
|
11883
11852
|
whenTrue: t("When {device} turns on", "Quando {device} si accende"),
|
|
11884
11853
|
whenFalse: t("When {device} turns off", "Quando {device} si spegne"),
|
|
11885
11854
|
icon: "power"
|
|
@@ -14291,6 +14260,133 @@ var CAMERA_CAP_VOCABULARY = {
|
|
|
14291
14260
|
}
|
|
14292
14261
|
};
|
|
14293
14262
|
/**
|
|
14263
|
+
* The heat pump (D1026): its system modes are phrased for automations, each with the
|
|
14264
|
+
* values the gateway really accepts; the per-circuit parameters need a circuit and are
|
|
14265
|
+
* set from the device page.
|
|
14266
|
+
*/
|
|
14267
|
+
var OFF = {
|
|
14268
|
+
value: "off",
|
|
14269
|
+
label: t("Off", "Off")
|
|
14270
|
+
};
|
|
14271
|
+
var AUTO = {
|
|
14272
|
+
value: "auto",
|
|
14273
|
+
label: t("Auto", "Auto")
|
|
14274
|
+
};
|
|
14275
|
+
var ON = {
|
|
14276
|
+
value: "on",
|
|
14277
|
+
label: t("On", "On")
|
|
14278
|
+
};
|
|
14279
|
+
var MANUAL = {
|
|
14280
|
+
value: "manual",
|
|
14281
|
+
label: t("Manual", "Manuale")
|
|
14282
|
+
};
|
|
14283
|
+
var HOLIDAY_PROGRAMMES = [OFF, ...[
|
|
14284
|
+
1,
|
|
14285
|
+
2,
|
|
14286
|
+
3,
|
|
14287
|
+
4,
|
|
14288
|
+
5,
|
|
14289
|
+
6,
|
|
14290
|
+
7,
|
|
14291
|
+
8
|
|
14292
|
+
].map((n) => ({
|
|
14293
|
+
value: `hm${n}`,
|
|
14294
|
+
label: t(`Programme ${n}`, `Programma ${n}`)
|
|
14295
|
+
}))];
|
|
14296
|
+
var PER_CIRCUIT = "Needs a circuit: set from the device page, not offered to automations";
|
|
14297
|
+
var HEAT_PUMP_CAP_VOCABULARY = {
|
|
14298
|
+
"heat-pump-status": {
|
|
14299
|
+
scope: "device",
|
|
14300
|
+
noun: t("Heat pump", "Pompa di calore")
|
|
14301
|
+
},
|
|
14302
|
+
"heat-pump-control": {
|
|
14303
|
+
scope: "device",
|
|
14304
|
+
noun: t("Heat pump settings", "Impostazioni pompa di calore"),
|
|
14305
|
+
actions: [
|
|
14306
|
+
{
|
|
14307
|
+
id: "heatPump.silent",
|
|
14308
|
+
method: "setSilentMode",
|
|
14309
|
+
label: t("Set silent mode", "Imposta la modalità silenziosa"),
|
|
14310
|
+
phrase: t("Set silent mode of {device} to {mode}", "Imposta la modalità silenziosa di {device} su {mode}"),
|
|
14311
|
+
icon: "volume-x",
|
|
14312
|
+
openArgs: [{
|
|
14313
|
+
key: "mode",
|
|
14314
|
+
label: t("Silent mode", "Modalità silenziosa"),
|
|
14315
|
+
offer: {
|
|
14316
|
+
kind: "enum",
|
|
14317
|
+
values: [
|
|
14318
|
+
OFF,
|
|
14319
|
+
AUTO,
|
|
14320
|
+
ON
|
|
14321
|
+
]
|
|
14322
|
+
}
|
|
14323
|
+
}]
|
|
14324
|
+
},
|
|
14325
|
+
{
|
|
14326
|
+
id: "heatPump.away",
|
|
14327
|
+
method: "setAwayMode",
|
|
14328
|
+
label: t("Set away mode", "Imposta la modalità assente"),
|
|
14329
|
+
phrase: t("Set away mode of {device} to {mode}", "Imposta la modalità assente di {device} su {mode}"),
|
|
14330
|
+
icon: "plane",
|
|
14331
|
+
openArgs: [{
|
|
14332
|
+
key: "mode",
|
|
14333
|
+
label: t("Away mode", "Modalità assente"),
|
|
14334
|
+
offer: {
|
|
14335
|
+
kind: "enum",
|
|
14336
|
+
values: [OFF, ON]
|
|
14337
|
+
}
|
|
14338
|
+
}]
|
|
14339
|
+
},
|
|
14340
|
+
{
|
|
14341
|
+
id: "heatPump.additionalHeater",
|
|
14342
|
+
method: "setAdditionalHeaterMode",
|
|
14343
|
+
label: t("Set additional heater", "Imposta il riscaldatore aggiuntivo"),
|
|
14344
|
+
phrase: t("Set the additional heater of {device} to {mode}", "Imposta il riscaldatore aggiuntivo di {device} su {mode}"),
|
|
14345
|
+
icon: "flame",
|
|
14346
|
+
openArgs: [{
|
|
14347
|
+
key: "mode",
|
|
14348
|
+
label: t("Additional heater", "Riscaldatore aggiuntivo"),
|
|
14349
|
+
offer: {
|
|
14350
|
+
kind: "enum",
|
|
14351
|
+
values: [
|
|
14352
|
+
OFF,
|
|
14353
|
+
MANUAL,
|
|
14354
|
+
AUTO
|
|
14355
|
+
]
|
|
14356
|
+
}
|
|
14357
|
+
}]
|
|
14358
|
+
},
|
|
14359
|
+
{
|
|
14360
|
+
id: "heatPump.holiday",
|
|
14361
|
+
method: "setHolidayMode",
|
|
14362
|
+
label: t("Set holiday mode", "Imposta la modalità vacanza"),
|
|
14363
|
+
phrase: t("Set holiday mode of {device} to {mode}", "Imposta la modalità vacanza di {device} su {mode}"),
|
|
14364
|
+
icon: "tree-palm",
|
|
14365
|
+
openArgs: [{
|
|
14366
|
+
key: "mode",
|
|
14367
|
+
label: t("Holiday programme", "Programma vacanza"),
|
|
14368
|
+
offer: {
|
|
14369
|
+
kind: "enum",
|
|
14370
|
+
values: HOLIDAY_PROGRAMMES
|
|
14371
|
+
}
|
|
14372
|
+
}]
|
|
14373
|
+
}
|
|
14374
|
+
],
|
|
14375
|
+
notOperatorFacing: {
|
|
14376
|
+
setCircuitOperationMode: PER_CIRCUIT,
|
|
14377
|
+
setCircuitHeatCoolMode: PER_CIRCUIT,
|
|
14378
|
+
setCircuitSummerWinter: PER_CIRCUIT,
|
|
14379
|
+
setCircuitComfortSetpoint: PER_CIRCUIT,
|
|
14380
|
+
setCircuitEcoSetpoint: PER_CIRCUIT,
|
|
14381
|
+
setCircuitMaxFlowTemp: PER_CIRCUIT,
|
|
14382
|
+
setDhwOperationMode: PER_CIRCUIT,
|
|
14383
|
+
setDhwTemperatureLevel: PER_CIRCUIT,
|
|
14384
|
+
setDhwChargeDuration: PER_CIRCUIT,
|
|
14385
|
+
startExtraHotWater: PER_CIRCUIT
|
|
14386
|
+
}
|
|
14387
|
+
}
|
|
14388
|
+
};
|
|
14389
|
+
/**
|
|
14294
14390
|
* Things an operator WATCHES: contacts, motion, leaks, smoke, measurements,
|
|
14295
14391
|
* presence, reachability, batteries, doorbells and event sources.
|
|
14296
14392
|
*/
|
|
@@ -15012,6 +15108,7 @@ var CAP_VOCABULARY_BY_NAME = {
|
|
|
15012
15108
|
...ACTUATOR_CAP_VOCABULARY,
|
|
15013
15109
|
...APPLIANCE_CAP_VOCABULARY,
|
|
15014
15110
|
...CAMERA_CAP_VOCABULARY,
|
|
15111
|
+
...HEAT_PUMP_CAP_VOCABULARY,
|
|
15015
15112
|
...SENSOR_CAP_VOCABULARY,
|
|
15016
15113
|
...SYSTEM_CAP_VOCABULARY
|
|
15017
15114
|
};
|
|
@@ -15259,6 +15356,8 @@ var CAP_NAMES = Object.freeze([
|
|
|
15259
15356
|
"group-active",
|
|
15260
15357
|
"group-commands",
|
|
15261
15358
|
"group-status",
|
|
15359
|
+
"heat-pump-control",
|
|
15360
|
+
"heat-pump-status",
|
|
15262
15361
|
"heating-valve",
|
|
15263
15362
|
"hero-layout",
|
|
15264
15363
|
"humidifier",
|
|
@@ -16124,6 +16223,48 @@ Object.freeze({
|
|
|
16124
16223
|
"valueType": "number"
|
|
16125
16224
|
}
|
|
16126
16225
|
],
|
|
16226
|
+
"heat-pump-status": [
|
|
16227
|
+
{
|
|
16228
|
+
"path": "power.thermalW",
|
|
16229
|
+
"valueType": "number"
|
|
16230
|
+
},
|
|
16231
|
+
{
|
|
16232
|
+
"path": "power.electricalW",
|
|
16233
|
+
"valueType": "number"
|
|
16234
|
+
},
|
|
16235
|
+
{
|
|
16236
|
+
"path": "power.compressorPct",
|
|
16237
|
+
"valueType": "number"
|
|
16238
|
+
},
|
|
16239
|
+
{
|
|
16240
|
+
"path": "temperatures.supply",
|
|
16241
|
+
"valueType": "number"
|
|
16242
|
+
},
|
|
16243
|
+
{
|
|
16244
|
+
"path": "temperatures.return",
|
|
16245
|
+
"valueType": "number"
|
|
16246
|
+
},
|
|
16247
|
+
{
|
|
16248
|
+
"path": "temperatures.outdoor",
|
|
16249
|
+
"valueType": "number"
|
|
16250
|
+
},
|
|
16251
|
+
{
|
|
16252
|
+
"path": "energy.thermalKwh",
|
|
16253
|
+
"valueType": "number"
|
|
16254
|
+
},
|
|
16255
|
+
{
|
|
16256
|
+
"path": "energy.electricalKwh",
|
|
16257
|
+
"valueType": "number"
|
|
16258
|
+
},
|
|
16259
|
+
{
|
|
16260
|
+
"path": "waterPressureBar",
|
|
16261
|
+
"valueType": "number"
|
|
16262
|
+
},
|
|
16263
|
+
{
|
|
16264
|
+
"path": "starts",
|
|
16265
|
+
"valueType": "number"
|
|
16266
|
+
}
|
|
16267
|
+
],
|
|
16127
16268
|
"heating-valve": [{
|
|
16128
16269
|
"path": "position",
|
|
16129
16270
|
"valueType": "number"
|
|
@@ -17264,12 +17405,8 @@ Object.freeze({
|
|
|
17264
17405
|
"uploadDataset": 72e5
|
|
17265
17406
|
}
|
|
17266
17407
|
});
|
|
17267
|
-
object({
|
|
17268
|
-
code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
|
|
17269
|
-
params: record(string(), union([string(), number$1()])).optional()
|
|
17270
|
-
});
|
|
17271
17408
|
//#endregion
|
|
17272
|
-
//#region ../types/dist/composition-
|
|
17409
|
+
//#region ../types/dist/composition-C6TZGqUb.mjs
|
|
17273
17410
|
/**
|
|
17274
17411
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
17275
17412
|
*
|
|
@@ -18983,25 +19120,6 @@ var RequiredAddonUpdateSchema = object({
|
|
|
18983
19120
|
installed: string().nullable()
|
|
18984
19121
|
});
|
|
18985
19122
|
/**
|
|
18986
|
-
* Which integration instance a settings form is for. An addon that serves several instances
|
|
18987
|
-
* (`instanceMode: multiple`) can show a different form per instance — an NVR integration
|
|
18988
|
-
* needs its connection, the default integration needs the addon's own sections.
|
|
18989
|
-
*
|
|
18990
|
-
* - `integrationId` is `null` in the create wizard: nothing exists yet, the operator is
|
|
18991
|
-
* setting up a NEW instance.
|
|
18992
|
-
* - `mode` is the wizard mode of the integration type (`getAvailableTypes`).
|
|
18993
|
-
* - `candidateStableId` is the discovery candidate a wizard was seeded from, if any.
|
|
18994
|
-
*/
|
|
18995
|
-
var IntegrationInstanceRefSchema = object({
|
|
18996
|
-
integrationId: string().nullable(),
|
|
18997
|
-
mode: _enum([
|
|
18998
|
-
"standalone",
|
|
18999
|
-
"account",
|
|
19000
|
-
"broker"
|
|
19001
|
-
]),
|
|
19002
|
-
candidateStableId: string().optional()
|
|
19003
|
-
});
|
|
19004
|
-
/**
|
|
19005
19123
|
* notification-output — canonical, capability-gated notification delivery.
|
|
19006
19124
|
*
|
|
19007
19125
|
* Apprise-derived model (see
|
|
@@ -44435,21 +44553,44 @@ var AutomationCapStepBaseSchema = object({
|
|
|
44435
44553
|
*/
|
|
44436
44554
|
argUnits: record(string(), string().min(1)).optional()
|
|
44437
44555
|
});
|
|
44438
|
-
|
|
44556
|
+
/**
|
|
44557
|
+
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
44558
|
+
* call back into an Action — so an Action can never reach itself (no cycles).
|
|
44559
|
+
* This is the LEAF shape: no condition of its own.
|
|
44560
|
+
*/
|
|
44561
|
+
var LeafActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepBaseSchema.refine((step) => step.target !== void 0 || step.deviceId !== void 0, {
|
|
44439
44562
|
message: "a cap step needs a target",
|
|
44440
44563
|
path: ["target"]
|
|
44441
44564
|
}).refine((step) => step.target?.kind !== "domain" || step.actionId !== void 0, {
|
|
44442
44565
|
message: "a domain target needs the vocabulary action it applies to (actionId)",
|
|
44443
44566
|
path: ["actionId"]
|
|
44444
|
-
});
|
|
44567
|
+
})]);
|
|
44445
44568
|
/**
|
|
44446
|
-
* The
|
|
44447
|
-
*
|
|
44569
|
+
* The optional guard of a step (#472): `if` is the ONE `when` tree (D980), read
|
|
44570
|
+
* on the state mirror when the step is reached; `else` runs when it is false.
|
|
44571
|
+
* An `else` holds leaf steps only — the nesting is bounded at ONE level, so a
|
|
44572
|
+
* branch can never grow a tree the trace has to draw.
|
|
44448
44573
|
*/
|
|
44449
|
-
var
|
|
44574
|
+
var stepGuardShape = {
|
|
44575
|
+
if: AutomationWhenSchema.optional(),
|
|
44576
|
+
else: array(LeafActionStepSchema).max(10).optional()
|
|
44577
|
+
};
|
|
44578
|
+
var elseNeedsIf = {
|
|
44579
|
+
message: "an else list needs the condition it is the other side of (if)",
|
|
44580
|
+
path: ["else"]
|
|
44581
|
+
};
|
|
44582
|
+
var GuardedWaitStepSchema = AutomationWaitStepSchema.extend(stepGuardShape).refine((step) => step.else === void 0 || step.if !== void 0, elseNeedsIf);
|
|
44583
|
+
var GuardedCapStepSchema = AutomationCapStepBaseSchema.extend(stepGuardShape).refine((step) => step.target !== void 0 || step.deviceId !== void 0, {
|
|
44584
|
+
message: "a cap step needs a target",
|
|
44585
|
+
path: ["target"]
|
|
44586
|
+
}).refine((step) => step.target?.kind !== "domain" || step.actionId !== void 0, {
|
|
44587
|
+
message: "a domain target needs the vocabulary action it applies to (actionId)",
|
|
44588
|
+
path: ["actionId"]
|
|
44589
|
+
}).refine((step) => step.else === void 0 || step.if !== void 0, elseNeedsIf);
|
|
44590
|
+
var ActionStepSchema = discriminatedUnion("kind", [GuardedWaitStepSchema, GuardedCapStepSchema]);
|
|
44450
44591
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
44451
|
-
|
|
44452
|
-
|
|
44592
|
+
GuardedWaitStepSchema,
|
|
44593
|
+
GuardedCapStepSchema,
|
|
44453
44594
|
object({
|
|
44454
44595
|
kind: literal("action"),
|
|
44455
44596
|
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
@@ -44829,7 +44970,7 @@ var StepDeviceTraceSchema = object({
|
|
|
44829
44970
|
outcome: _enum(["ok", "error"]),
|
|
44830
44971
|
message: string().optional()
|
|
44831
44972
|
});
|
|
44832
|
-
var
|
|
44973
|
+
var StepTraceBaseSchema = object({
|
|
44833
44974
|
/** `actions.<i>` */
|
|
44834
44975
|
path: string().min(1),
|
|
44835
44976
|
kind: string().min(1),
|
|
@@ -44848,15 +44989,35 @@ var AutomationStepTraceSchema = object({
|
|
|
44848
44989
|
* is shown as {@link REDACTED_ARG}. Absent on traces written before it existed.
|
|
44849
44990
|
*/
|
|
44850
44991
|
args: record(string(), TraceValueSchema).optional(),
|
|
44851
|
-
/**
|
|
44992
|
+
/**
|
|
44993
|
+
* The device values a templated arg printed as `—`, one `ref: reason` each
|
|
44994
|
+
* (D1021): why a sentence says "—" where a number was expected. Bounded.
|
|
44995
|
+
*/
|
|
44996
|
+
templates: array(string()).max(20).optional(),
|
|
44997
|
+
/**
|
|
44998
|
+
* What the step's own `if` read when the step was reached (#472): `true` the
|
|
44999
|
+
* step ran, `false` its `else` ran (or nothing did), `unknown` a state leaf
|
|
45000
|
+
* could not be read, so NEITHER side ran. Absent on an unguarded step.
|
|
45001
|
+
*/
|
|
45002
|
+
condition: _enum([
|
|
45003
|
+
"true",
|
|
45004
|
+
"false",
|
|
45005
|
+
"unknown"
|
|
45006
|
+
]).optional(),
|
|
45007
|
+
/** Why the condition read what it read, in the evaluator's own words. */
|
|
45008
|
+
conditionReason: string().optional(),
|
|
45009
|
+
/** `empty`: the target resolved to no device, so nothing was done — never silently `ok`. `skipped`: its `if` was false (or unknown) and nothing ran in its place. */
|
|
44852
45010
|
outcome: _enum([
|
|
44853
45011
|
"ok",
|
|
44854
45012
|
"error",
|
|
44855
45013
|
"not-run",
|
|
44856
|
-
"empty"
|
|
45014
|
+
"empty",
|
|
45015
|
+
"skipped"
|
|
44857
45016
|
]),
|
|
44858
45017
|
message: string().optional()
|
|
44859
45018
|
});
|
|
45019
|
+
/** A step trace; the `else` steps that ran are one level of the same shape (the nesting is bounded at one). */
|
|
45020
|
+
var AutomationStepTraceSchema = StepTraceBaseSchema.extend({ else: array(StepTraceBaseSchema).optional() });
|
|
44860
45021
|
var AutomationRunTraceSchema = object({
|
|
44861
45022
|
runId: string().min(1),
|
|
44862
45023
|
startedAt: number$1(),
|
|
@@ -45032,6 +45193,7 @@ _enum([
|
|
|
45032
45193
|
"invalid-variables",
|
|
45033
45194
|
"invalid-steps",
|
|
45034
45195
|
"not-linked",
|
|
45196
|
+
"template-scope",
|
|
45035
45197
|
"busy"
|
|
45036
45198
|
]);
|
|
45037
45199
|
object({
|
|
@@ -45356,10 +45518,6 @@ method(object({
|
|
|
45356
45518
|
scope: ScopedSettingsScopeSchema,
|
|
45357
45519
|
nodeId: string().optional()
|
|
45358
45520
|
}), record(string(), unknown()).nullable()), method(object({
|
|
45359
|
-
addonId: string(),
|
|
45360
|
-
nodeId: string().optional(),
|
|
45361
|
-
instance: IntegrationInstanceRefSchema
|
|
45362
|
-
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
45363
45521
|
addonId: string(),
|
|
45364
45522
|
nodeId: string().optional()
|
|
45365
45523
|
}), object({ keys: array(string()) }).nullable(), { auth: "admin" }), method(object({
|
|
@@ -50599,7 +50757,7 @@ var mediaPlayerCapability = {
|
|
|
50599
50757
|
isMuted: { kind: "boolean" }
|
|
50600
50758
|
} }
|
|
50601
50759
|
};
|
|
50602
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, 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.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway, DeviceType.Camera, DeviceType.Fan, DeviceType.Lock, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Gateway, DeviceType.Hub, DeviceType.Camera, DeviceType.Sensor, DeviceType.MediaPlayer, DeviceType.Vacuum, DeviceType.Generic, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.PetFountain, DeviceType.Fan, DeviceType.Humidifier, DeviceType.Climate, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.MediaPlayer;
|
|
50760
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, 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.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway, DeviceType.HeatPump, DeviceType.Camera, DeviceType.Fan, DeviceType.Lock, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.Gateway, DeviceType.Hub, DeviceType.Camera, DeviceType.Sensor, DeviceType.MediaPlayer, DeviceType.Vacuum, DeviceType.Generic, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.PetFountain, DeviceType.Fan, DeviceType.Humidifier, DeviceType.Climate, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder, DeviceType.Heater, DeviceType.MediaPlayer;
|
|
50603
50761
|
var NUMBER = {
|
|
50604
50762
|
kind: "fixed",
|
|
50605
50763
|
result: ["number"]
|
|
@@ -52618,6 +52776,43 @@ method(InstancePinSchema, DeviceExportStatusSchema), method(_void(), array(Expor
|
|
|
52618
52776
|
auth: "admin"
|
|
52619
52777
|
});
|
|
52620
52778
|
var DeviceAliasSchema = string().max(64).regex(/^[a-z][a-z0-9_]*$/);
|
|
52779
|
+
var DeviceTemplateSchema = string().min(1).max(4096);
|
|
52780
|
+
var DeviceTemplateRefusalSchema = object({
|
|
52781
|
+
reason: _enum([
|
|
52782
|
+
"too-long",
|
|
52783
|
+
"syntax",
|
|
52784
|
+
"forbidden-syntax",
|
|
52785
|
+
"forbidden-member",
|
|
52786
|
+
"unknown-filter",
|
|
52787
|
+
"ambiguous-field",
|
|
52788
|
+
"busy",
|
|
52789
|
+
"budget-exceeded",
|
|
52790
|
+
"timeout",
|
|
52791
|
+
"output-too-large",
|
|
52792
|
+
"render-failed",
|
|
52793
|
+
"out-of-scope",
|
|
52794
|
+
"unavailable"
|
|
52795
|
+
]),
|
|
52796
|
+
message: string()
|
|
52797
|
+
});
|
|
52798
|
+
var DeviceTemplateTraceEntrySchema = object({
|
|
52799
|
+
ref: string(),
|
|
52800
|
+
reason: _enum([
|
|
52801
|
+
"unknown-alias",
|
|
52802
|
+
"unknown-field",
|
|
52803
|
+
"no-field",
|
|
52804
|
+
"unavailable"
|
|
52805
|
+
])
|
|
52806
|
+
});
|
|
52807
|
+
var DeviceTemplateRenderSchema = discriminatedUnion("ok", [object({
|
|
52808
|
+
ok: literal(true),
|
|
52809
|
+
text: string(),
|
|
52810
|
+
trace: array(DeviceTemplateTraceEntrySchema)
|
|
52811
|
+
}), object({
|
|
52812
|
+
ok: literal(false),
|
|
52813
|
+
refusal: DeviceTemplateRefusalSchema,
|
|
52814
|
+
trace: array(DeviceTemplateTraceEntrySchema)
|
|
52815
|
+
})]);
|
|
52621
52816
|
/**
|
|
52622
52817
|
* A SITE ZONE — a named part of the property that several locations belong to.
|
|
52623
52818
|
*
|
|
@@ -53449,6 +53644,22 @@ method(object({
|
|
|
53449
53644
|
kind: "mutation",
|
|
53450
53645
|
auth: "admin"
|
|
53451
53646
|
}), method(object({
|
|
53647
|
+
templates: array(DeviceTemplateSchema).max(64),
|
|
53648
|
+
allowedDeviceIds: array(number$1().int()).optional()
|
|
53649
|
+
}), object({ results: array(DeviceTemplateRenderSchema) }), { auth: "admin" }), method(object({
|
|
53650
|
+
templates: array(string()).max(64),
|
|
53651
|
+
allowedDeviceIds: array(number$1().int()).optional()
|
|
53652
|
+
}), object({ results: array(discriminatedUnion("ok", [object({
|
|
53653
|
+
ok: literal(true),
|
|
53654
|
+
aliases: array(object({
|
|
53655
|
+
alias: string(),
|
|
53656
|
+
deviceId: number$1().int().nullable(),
|
|
53657
|
+
allowed: boolean()
|
|
53658
|
+
}))
|
|
53659
|
+
}), object({
|
|
53660
|
+
ok: literal(false),
|
|
53661
|
+
refusal: DeviceTemplateRefusalSchema
|
|
53662
|
+
})])) }), { auth: "admin" }), method(object({
|
|
53452
53663
|
deviceId: number$1(),
|
|
53453
53664
|
location: string().nullable()
|
|
53454
53665
|
}), _void(), {
|
|
@@ -56639,6 +56850,332 @@ var groupStatusCapability = {
|
|
|
56639
56850
|
durability: "session",
|
|
56640
56851
|
history: "none"
|
|
56641
56852
|
};
|
|
56853
|
+
/**
|
|
56854
|
+
* Heat pump settable surface (D1026): one typed method per parameter, never a
|
|
56855
|
+
* generic `set(key, value)`. The values a mode takes and the limits of a number
|
|
56856
|
+
* are the ones `heat-pump-status` carries (`allowed`, `min`, `max`, `step`),
|
|
56857
|
+
* read from the gateway; a provider refuses a value outside them. The state is
|
|
56858
|
+
* `heat-pump-status` — this cap has none.
|
|
56859
|
+
*/
|
|
56860
|
+
var deviceId = number$1().int().nonnegative();
|
|
56861
|
+
var circuitId = string().min(1);
|
|
56862
|
+
var mode = string().min(1);
|
|
56863
|
+
var temp = number$1().finite();
|
|
56864
|
+
var heatPumpControlCapability = {
|
|
56865
|
+
name: "heat-pump-control",
|
|
56866
|
+
scope: "device",
|
|
56867
|
+
deviceNative: true,
|
|
56868
|
+
mode: "singleton",
|
|
56869
|
+
deviceTypes: [DeviceType.HeatPump],
|
|
56870
|
+
methods: {
|
|
56871
|
+
/** off / auto / on. */
|
|
56872
|
+
setSilentMode: method(object({
|
|
56873
|
+
deviceId,
|
|
56874
|
+
mode
|
|
56875
|
+
}), _void(), {
|
|
56876
|
+
kind: "mutation",
|
|
56877
|
+
auth: "protected"
|
|
56878
|
+
}),
|
|
56879
|
+
/** off / on. */
|
|
56880
|
+
setAwayMode: method(object({
|
|
56881
|
+
deviceId,
|
|
56882
|
+
mode
|
|
56883
|
+
}), _void(), {
|
|
56884
|
+
kind: "mutation",
|
|
56885
|
+
auth: "protected"
|
|
56886
|
+
}),
|
|
56887
|
+
/** off / manual / auto. */
|
|
56888
|
+
setAdditionalHeaterMode: method(object({
|
|
56889
|
+
deviceId,
|
|
56890
|
+
mode
|
|
56891
|
+
}), _void(), {
|
|
56892
|
+
kind: "mutation",
|
|
56893
|
+
auth: "protected"
|
|
56894
|
+
}),
|
|
56895
|
+
/** off / hm1 .. hm8 (the programmes the gateway lists). */
|
|
56896
|
+
setHolidayMode: method(object({
|
|
56897
|
+
deviceId,
|
|
56898
|
+
mode
|
|
56899
|
+
}), _void(), {
|
|
56900
|
+
kind: "mutation",
|
|
56901
|
+
auth: "protected"
|
|
56902
|
+
}),
|
|
56903
|
+
setCircuitOperationMode: method(object({
|
|
56904
|
+
deviceId,
|
|
56905
|
+
circuitId,
|
|
56906
|
+
mode
|
|
56907
|
+
}), _void(), {
|
|
56908
|
+
kind: "mutation",
|
|
56909
|
+
auth: "protected"
|
|
56910
|
+
}),
|
|
56911
|
+
setCircuitHeatCoolMode: method(object({
|
|
56912
|
+
deviceId,
|
|
56913
|
+
circuitId,
|
|
56914
|
+
mode
|
|
56915
|
+
}), _void(), {
|
|
56916
|
+
kind: "mutation",
|
|
56917
|
+
auth: "protected"
|
|
56918
|
+
}),
|
|
56919
|
+
setCircuitSummerWinter: method(object({
|
|
56920
|
+
deviceId,
|
|
56921
|
+
circuitId,
|
|
56922
|
+
mode
|
|
56923
|
+
}), _void(), {
|
|
56924
|
+
kind: "mutation",
|
|
56925
|
+
auth: "protected"
|
|
56926
|
+
}),
|
|
56927
|
+
setCircuitComfortSetpoint: method(object({
|
|
56928
|
+
deviceId,
|
|
56929
|
+
circuitId,
|
|
56930
|
+
temp
|
|
56931
|
+
}), _void(), {
|
|
56932
|
+
kind: "mutation",
|
|
56933
|
+
auth: "protected"
|
|
56934
|
+
}),
|
|
56935
|
+
setCircuitEcoSetpoint: method(object({
|
|
56936
|
+
deviceId,
|
|
56937
|
+
circuitId,
|
|
56938
|
+
temp
|
|
56939
|
+
}), _void(), {
|
|
56940
|
+
kind: "mutation",
|
|
56941
|
+
auth: "protected"
|
|
56942
|
+
}),
|
|
56943
|
+
setCircuitMaxFlowTemp: method(object({
|
|
56944
|
+
deviceId,
|
|
56945
|
+
circuitId,
|
|
56946
|
+
temp
|
|
56947
|
+
}), _void(), {
|
|
56948
|
+
kind: "mutation",
|
|
56949
|
+
auth: "protected"
|
|
56950
|
+
}),
|
|
56951
|
+
setDhwOperationMode: method(object({
|
|
56952
|
+
deviceId,
|
|
56953
|
+
circuitId,
|
|
56954
|
+
mode
|
|
56955
|
+
}), _void(), {
|
|
56956
|
+
kind: "mutation",
|
|
56957
|
+
auth: "protected"
|
|
56958
|
+
}),
|
|
56959
|
+
setDhwTemperatureLevel: method(object({
|
|
56960
|
+
deviceId,
|
|
56961
|
+
circuitId,
|
|
56962
|
+
level: mode
|
|
56963
|
+
}), _void(), {
|
|
56964
|
+
kind: "mutation",
|
|
56965
|
+
auth: "protected"
|
|
56966
|
+
}),
|
|
56967
|
+
setDhwChargeDuration: method(object({
|
|
56968
|
+
deviceId,
|
|
56969
|
+
circuitId,
|
|
56970
|
+
minutes: number$1().int().positive()
|
|
56971
|
+
}), _void(), {
|
|
56972
|
+
kind: "mutation",
|
|
56973
|
+
auth: "protected"
|
|
56974
|
+
}),
|
|
56975
|
+
/** Start an extra-hot-water charge now: an action, not a stored mode. */
|
|
56976
|
+
startExtraHotWater: method(object({
|
|
56977
|
+
deviceId,
|
|
56978
|
+
circuitId
|
|
56979
|
+
}), _void(), {
|
|
56980
|
+
kind: "mutation",
|
|
56981
|
+
auth: "protected"
|
|
56982
|
+
})
|
|
56983
|
+
}
|
|
56984
|
+
};
|
|
56985
|
+
var HeatPumpCircuitKindSchema = _enum([
|
|
56986
|
+
"heating",
|
|
56987
|
+
"dhw",
|
|
56988
|
+
"cooling",
|
|
56989
|
+
"solar"
|
|
56990
|
+
]);
|
|
56991
|
+
/** A setting that takes one of a list of values the gateway named. */
|
|
56992
|
+
var HeatPumpOptionSettingSchema = object({
|
|
56993
|
+
/** The active value. Null when the gateway did not answer. */
|
|
56994
|
+
value: string().nullable(),
|
|
56995
|
+
/** Values the gateway accepts, in its order. Empty = read-only here. */
|
|
56996
|
+
allowed: array(string())
|
|
56997
|
+
});
|
|
56998
|
+
/** A numeric setting with the limits the gateway named. */
|
|
56999
|
+
var HeatPumpRangeSettingSchema = object({
|
|
57000
|
+
value: number$1().nullable(),
|
|
57001
|
+
min: number$1().nullable(),
|
|
57002
|
+
max: number$1().nullable(),
|
|
57003
|
+
step: number$1().nullable()
|
|
57004
|
+
});
|
|
57005
|
+
var HeatPumpCircuitSchema = object({
|
|
57006
|
+
/** Gateway id of the circuit (`hc1`, `dhw1`): the key of the series. */
|
|
57007
|
+
id: string().min(1),
|
|
57008
|
+
kind: HeatPumpCircuitKindSchema,
|
|
57009
|
+
label: string(),
|
|
57010
|
+
icon: IconKeySchema,
|
|
57011
|
+
/** Measured temperature of the circuit (room, tank, collector). */
|
|
57012
|
+
currentTemp: number$1().nullable().meta(readingMeta("temperature")),
|
|
57013
|
+
/** The setpoint in force now. */
|
|
57014
|
+
targetTemp: number$1().nullable().meta(readingMeta("temperature")),
|
|
57015
|
+
/** The operation mode in force (mirror of `operationMode.value`, for the series). */
|
|
57016
|
+
mode: string().nullable(),
|
|
57017
|
+
/** Whether the circuit is calling for heat right now. Null = unknown. */
|
|
57018
|
+
active: boolean().nullable(),
|
|
57019
|
+
operationMode: HeatPumpOptionSettingSchema.nullable(),
|
|
57020
|
+
/** Heating circuits: heat / cool / heatCool. */
|
|
57021
|
+
heatCoolMode: HeatPumpOptionSettingSchema.nullable(),
|
|
57022
|
+
/** Heating circuits: summer / winter changeover. */
|
|
57023
|
+
summerWinter: HeatPumpOptionSettingSchema.nullable(),
|
|
57024
|
+
comfortSetpoint: HeatPumpRangeSettingSchema.nullable(),
|
|
57025
|
+
ecoSetpoint: HeatPumpRangeSettingSchema.nullable(),
|
|
57026
|
+
maxFlowTemp: HeatPumpRangeSettingSchema.nullable(),
|
|
57027
|
+
/** Hot water: the temperature level (off / low / high / eco). */
|
|
57028
|
+
temperatureLevel: HeatPumpOptionSettingSchema.nullable(),
|
|
57029
|
+
/** Hot water: how long a charge lasts, minutes. */
|
|
57030
|
+
chargeDuration: HeatPumpRangeSettingSchema.nullable(),
|
|
57031
|
+
/** Hot water: whether an extra-hot-water charge is running. Null = no such surface. */
|
|
57032
|
+
extraHotWater: boolean().nullable()
|
|
57033
|
+
});
|
|
57034
|
+
/** The independent system modes, each with its real values. A null mode = the gateway has none. */
|
|
57035
|
+
var HeatPumpSystemSchema = object({
|
|
57036
|
+
silent: HeatPumpOptionSettingSchema.nullable(),
|
|
57037
|
+
away: HeatPumpOptionSettingSchema.nullable(),
|
|
57038
|
+
additionalHeater: HeatPumpOptionSettingSchema.nullable(),
|
|
57039
|
+
holiday: HeatPumpOptionSettingSchema.nullable()
|
|
57040
|
+
});
|
|
57041
|
+
var HeatPumpPowerSchema = object({
|
|
57042
|
+
thermalW: number$1().nullable().meta(readingMeta("power")),
|
|
57043
|
+
electricalW: number$1().nullable().meta(readingMeta("power")),
|
|
57044
|
+
/** Compressor modulation, percent. */
|
|
57045
|
+
compressorPct: number$1().nullable().meta(readingMeta("percentage"))
|
|
57046
|
+
});
|
|
57047
|
+
var HeatPumpTemperaturesSchema = object({
|
|
57048
|
+
supply: number$1().nullable().meta(readingMeta("temperature")),
|
|
57049
|
+
return: number$1().nullable().meta(readingMeta("temperature")),
|
|
57050
|
+
outdoor: number$1().nullable().meta(readingMeta("temperature"))
|
|
57051
|
+
});
|
|
57052
|
+
/** Lifetime meters, kWh: the energy of a period is computed at read time from their difference (D944). */
|
|
57053
|
+
var HeatPumpEnergySchema = object({
|
|
57054
|
+
thermalKwh: number$1().nullable().meta(readingMeta("energy")),
|
|
57055
|
+
electricalKwh: number$1().nullable().meta(readingMeta("energy"))
|
|
57056
|
+
});
|
|
57057
|
+
var HeatPumpStatusSchema = object({
|
|
57058
|
+
circuits: array(HeatPumpCircuitSchema),
|
|
57059
|
+
system: HeatPumpSystemSchema,
|
|
57060
|
+
power: HeatPumpPowerSchema,
|
|
57061
|
+
temperatures: HeatPumpTemperaturesSchema,
|
|
57062
|
+
energy: HeatPumpEnergySchema,
|
|
57063
|
+
/** Water pressure of the heating loop, bar. */
|
|
57064
|
+
waterPressureBar: number$1().nullable(),
|
|
57065
|
+
/** Compressor starts since commissioning. */
|
|
57066
|
+
starts: number$1().nullable(),
|
|
57067
|
+
/** Ms epoch when the slice was last read from the gateway. */
|
|
57068
|
+
lastFetchedAt: number$1()
|
|
57069
|
+
});
|
|
57070
|
+
/**
|
|
57071
|
+
* The instantaneous COP: thermal over electrical power. Null unless BOTH powers
|
|
57072
|
+
* are known and the unit draws power — a missing reading is never a 0 or a
|
|
57073
|
+
* division by it (D393). Computed on every read; there is no stored value.
|
|
57074
|
+
*/
|
|
57075
|
+
function heatPumpInstantCop(power) {
|
|
57076
|
+
const { thermalW, electricalW } = power;
|
|
57077
|
+
if (thermalW === null || electricalW === null || electricalW <= 0) return null;
|
|
57078
|
+
return thermalW / electricalW;
|
|
57079
|
+
}
|
|
57080
|
+
var heatPumpStatusCapability = {
|
|
57081
|
+
name: "heat-pump-status",
|
|
57082
|
+
scope: "device",
|
|
57083
|
+
deviceNative: true,
|
|
57084
|
+
mode: "singleton",
|
|
57085
|
+
deviceTypes: [DeviceType.HeatPump],
|
|
57086
|
+
methods: {},
|
|
57087
|
+
status: {
|
|
57088
|
+
schema: HeatPumpStatusSchema,
|
|
57089
|
+
kind: "push"
|
|
57090
|
+
},
|
|
57091
|
+
runtimeState: HeatPumpStatusSchema,
|
|
57092
|
+
/**
|
|
57093
|
+
* Runtime-state durability: **session** — a heat pump's gateway answers on the
|
|
57094
|
+
* next poll, so a restart that clears the slice loses nothing a reader needs
|
|
57095
|
+
* (the series are recorded). See `RuntimeStateDurability`.
|
|
57096
|
+
*/
|
|
57097
|
+
durability: "session",
|
|
57098
|
+
/**
|
|
57099
|
+
* History (D850, D917): `circuits[]` is a keyed array — one series per circuit and
|
|
57100
|
+
* field, named by the circuit's label. The mode is a state (D896); the energy
|
|
57101
|
+
* totals are lifetime counters, the kWh of a period is computed at read time (D944).
|
|
57102
|
+
* The COP is never recorded: it derives from the two powers.
|
|
57103
|
+
*/
|
|
57104
|
+
history: {
|
|
57105
|
+
fields: {
|
|
57106
|
+
"power.thermalW": {
|
|
57107
|
+
kind: "gauge",
|
|
57108
|
+
unit: "W",
|
|
57109
|
+
deadband: 50,
|
|
57110
|
+
displayName: "Thermal power"
|
|
57111
|
+
},
|
|
57112
|
+
"power.electricalW": {
|
|
57113
|
+
kind: "gauge",
|
|
57114
|
+
unit: "W",
|
|
57115
|
+
deadband: 50,
|
|
57116
|
+
displayName: "Electrical power"
|
|
57117
|
+
},
|
|
57118
|
+
"power.compressorPct": {
|
|
57119
|
+
kind: "gauge",
|
|
57120
|
+
unit: "%",
|
|
57121
|
+
deadband: 2,
|
|
57122
|
+
displayName: "Compressor"
|
|
57123
|
+
},
|
|
57124
|
+
"temperatures.supply": {
|
|
57125
|
+
kind: "gauge",
|
|
57126
|
+
unit: "°C",
|
|
57127
|
+
deadband: .5,
|
|
57128
|
+
displayName: "Supply"
|
|
57129
|
+
},
|
|
57130
|
+
"temperatures.return": {
|
|
57131
|
+
kind: "gauge",
|
|
57132
|
+
unit: "°C",
|
|
57133
|
+
deadband: .5,
|
|
57134
|
+
displayName: "Return"
|
|
57135
|
+
},
|
|
57136
|
+
"temperatures.outdoor": {
|
|
57137
|
+
kind: "gauge",
|
|
57138
|
+
unit: "°C",
|
|
57139
|
+
deadband: .5,
|
|
57140
|
+
displayName: "Outdoor"
|
|
57141
|
+
},
|
|
57142
|
+
"energy.thermalKwh": {
|
|
57143
|
+
kind: "counter",
|
|
57144
|
+
unit: "kWh",
|
|
57145
|
+
displayName: "Thermal energy"
|
|
57146
|
+
},
|
|
57147
|
+
"energy.electricalKwh": {
|
|
57148
|
+
kind: "counter",
|
|
57149
|
+
unit: "kWh",
|
|
57150
|
+
displayName: "Electrical energy"
|
|
57151
|
+
}
|
|
57152
|
+
},
|
|
57153
|
+
items: {
|
|
57154
|
+
path: "circuits",
|
|
57155
|
+
key: "id",
|
|
57156
|
+
label: "label",
|
|
57157
|
+
fields: {
|
|
57158
|
+
currentTemp: {
|
|
57159
|
+
kind: "gauge",
|
|
57160
|
+
unit: "°C",
|
|
57161
|
+
deadband: .5,
|
|
57162
|
+
displayName: "Temperature"
|
|
57163
|
+
},
|
|
57164
|
+
targetTemp: {
|
|
57165
|
+
kind: "gauge",
|
|
57166
|
+
unit: "°C",
|
|
57167
|
+
minIntervalMs: 0,
|
|
57168
|
+
displayName: "Setpoint"
|
|
57169
|
+
},
|
|
57170
|
+
mode: {
|
|
57171
|
+
kind: "enum",
|
|
57172
|
+
displayName: "Mode"
|
|
57173
|
+
}
|
|
57174
|
+
}
|
|
57175
|
+
}
|
|
57176
|
+
},
|
|
57177
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
57178
|
+
};
|
|
56642
57179
|
var HeatingValveStatusSchema = object({
|
|
56643
57180
|
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
56644
57181
|
position: number$1().min(0).max(100).nullable().meta(readingMeta("percentage")),
|
|
@@ -56853,6 +57390,7 @@ var HeroSceneSchema = object({
|
|
|
56853
57390
|
"ac",
|
|
56854
57391
|
"thermostat",
|
|
56855
57392
|
"heater",
|
|
57393
|
+
"heat-pump",
|
|
56856
57394
|
"fan",
|
|
56857
57395
|
"washer",
|
|
56858
57396
|
"dryer",
|
|
@@ -56895,7 +57433,7 @@ var HeroSceneSchema = object({
|
|
|
56895
57433
|
/** 0..1: volume, cover position, cycle progress. */
|
|
56896
57434
|
level: number$1().min(0).max(1).nullable()
|
|
56897
57435
|
});
|
|
56898
|
-
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.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway;
|
|
57436
|
+
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.HeatPump, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway;
|
|
56899
57437
|
DeviceRole.Siren, DeviceRole.Floodlight, DeviceRole.Spotlight, DeviceRole.PirSensor, DeviceRole.Chime, DeviceRole.Autotrack, DeviceRole.Nightvision, DeviceRole.PrivacyMask, DeviceRole.Doorbell, DeviceRole.CoverBlind, DeviceRole.CoverShutter, DeviceRole.CoverAwning, DeviceRole.CoverCurtain, DeviceRole.CoverGarage, DeviceRole.CoverGate, DeviceRole.CoverDoor, DeviceRole.CoverWindow, DeviceRole.BinaryHelper, DeviceRole.Outlet, DeviceRole.MotionSensor, DeviceRole.ContactSensor, DeviceRole.LeakSensor, DeviceRole.SmokeSensor, DeviceRole.COSensor, DeviceRole.GasSensor, DeviceRole.TamperSensor, DeviceRole.VibrationSensor, DeviceRole.ConnectivitySensor, DeviceRole.SoundSensor, DeviceRole.BinarySensor, DeviceRole.TemperatureSensor, DeviceRole.HumiditySensor, DeviceRole.AmbientLightSensor, DeviceRole.PressureSensor, DeviceRole.WindSensor, DeviceRole.RainSensor, DeviceRole.UvSensor, DeviceRole.SolarRadiationSensor, DeviceRole.SoilMoistureSensor, DeviceRole.PowerSensor, DeviceRole.EnergySensor, DeviceRole.VoltageSensor, DeviceRole.CurrentSensor, DeviceRole.AirQualitySensor, DeviceRole.BatterySensor, DeviceRole.NumericSensor, DeviceRole.EnumSensor, DeviceRole.DateTimeSensor, DeviceRole.GenericSensor, DeviceRole.NumericControl, DeviceRole.SelectControl, DeviceRole.TextControl, DeviceRole.DateTimeControl, DeviceRole.MobilePushNotifier, DeviceRole.MessagingNotifier, DeviceRole.EmailNotifier, DeviceRole.GenericNotifier, DeviceRole.IrTransmitter;
|
|
56900
57438
|
/** A string in both languages, as the cap vocabulary writes it (D920): no `t()` in the model. */
|
|
56901
57439
|
var HeroTextSchema = object({
|
|
@@ -56903,6 +57441,7 @@ var HeroTextSchema = object({
|
|
|
56903
57441
|
it: string()
|
|
56904
57442
|
});
|
|
56905
57443
|
var HeroRowIdSchema = _enum([
|
|
57444
|
+
"progress",
|
|
56906
57445
|
"run-for",
|
|
56907
57446
|
"cycle",
|
|
56908
57447
|
"program",
|
|
@@ -56917,6 +57456,7 @@ var HeroRowIdSchema = _enum([
|
|
|
56917
57456
|
"alarm",
|
|
56918
57457
|
"fan",
|
|
56919
57458
|
"vacuum",
|
|
57459
|
+
"vacuum-suction",
|
|
56920
57460
|
"mower",
|
|
56921
57461
|
"feeder",
|
|
56922
57462
|
"fountain",
|
|
@@ -56935,7 +57475,10 @@ var HeroRowIdSchema = _enum([
|
|
|
56935
57475
|
"climate-fan",
|
|
56936
57476
|
"setpoint",
|
|
56937
57477
|
"channel",
|
|
56938
|
-
"control"
|
|
57478
|
+
"control",
|
|
57479
|
+
"circuit",
|
|
57480
|
+
"heat-pump-power",
|
|
57481
|
+
"system-mode"
|
|
56939
57482
|
]);
|
|
56940
57483
|
var HeroArgValueSchema = lazy(() => union([
|
|
56941
57484
|
string(),
|
|
@@ -57000,16 +57543,32 @@ var HeroControlSchema = discriminatedUnion("kind", [
|
|
|
57000
57543
|
label: HeroTextSchema,
|
|
57001
57544
|
current: string().nullable(),
|
|
57002
57545
|
options: array(string()),
|
|
57546
|
+
/** A readable label per option value; an option without one is drawn as its raw value. */
|
|
57547
|
+
optionLabels: record(string(), HeroTextSchema).optional(),
|
|
57003
57548
|
call: HeroCallSchema,
|
|
57004
57549
|
valueArg: string()
|
|
57005
57550
|
})
|
|
57006
57551
|
]);
|
|
57552
|
+
/** Declared by its interface: a `z.infer` of one more icon union pushes the cap's inferred type past what the compiler can print. */
|
|
57553
|
+
var HeroPillSchema = object({
|
|
57554
|
+
icon: IconKeySchema.nullable(),
|
|
57555
|
+
text: HeroTextSchema,
|
|
57556
|
+
tone: HeroToneSchema
|
|
57557
|
+
});
|
|
57007
57558
|
var HeroRowSchema = object({
|
|
57008
57559
|
id: HeroRowIdSchema,
|
|
57560
|
+
/** The row's own name when the kind's label would not tell rows of one kind apart (a circuit's label). */
|
|
57561
|
+
label: HeroTextSchema.optional(),
|
|
57562
|
+
/** A group header drawn above the row when it differs from the previous row's ("System"). */
|
|
57563
|
+
group: HeroTextSchema.optional(),
|
|
57564
|
+
/** Values drawn as pills across the row (a heat pump's powers). */
|
|
57565
|
+
pills: array(HeroPillSchema).optional(),
|
|
57009
57566
|
icon: IconKeySchema,
|
|
57010
57567
|
/** The row's status, in words. `null` = nothing to say. */
|
|
57011
57568
|
status: HeroTextSchema.nullable(),
|
|
57012
|
-
controls: array(HeroControlSchema)
|
|
57569
|
+
controls: array(HeroControlSchema),
|
|
57570
|
+
/** A bar under the row's label, 0..1; `null` / absent = no bar. */
|
|
57571
|
+
progress: number$1().min(0).max(1).nullable().optional()
|
|
57013
57572
|
});
|
|
57014
57573
|
var HeroDetailSchema = object({
|
|
57015
57574
|
label: HeroTextSchema,
|
|
@@ -57017,7 +57576,11 @@ var HeroDetailSchema = object({
|
|
|
57017
57576
|
unit: string().nullable()
|
|
57018
57577
|
});
|
|
57019
57578
|
var HeroBadgeSchema = object({
|
|
57020
|
-
id: _enum([
|
|
57579
|
+
id: _enum([
|
|
57580
|
+
"battery",
|
|
57581
|
+
"network-link",
|
|
57582
|
+
"integration"
|
|
57583
|
+
]),
|
|
57021
57584
|
icon: IconKeySchema,
|
|
57022
57585
|
tone: HeroToneSchema,
|
|
57023
57586
|
/** Percent for a battery, link quality for a link; `null` = not known. */
|
|
@@ -57065,7 +57628,13 @@ var HeroTimedRunSlotSchema = object({
|
|
|
57065
57628
|
activeUntil: number$1().nullable(),
|
|
57066
57629
|
quickRun: TimedRunQuickRunSchema,
|
|
57067
57630
|
run: HeroActionSchema,
|
|
57068
|
-
cancel: HeroActionSchema
|
|
57631
|
+
cancel: HeroActionSchema,
|
|
57632
|
+
/**
|
|
57633
|
+
* Whole units left (the limit's unit, ceil). `null` while nothing is armed.
|
|
57634
|
+
* A number, not words: the row formats it, and a text here would not fit the
|
|
57635
|
+
* hero-layout declaration.
|
|
57636
|
+
*/
|
|
57637
|
+
remaining: number$1().nullable()
|
|
57069
57638
|
});
|
|
57070
57639
|
var HeroPowerSupplySlotSchema = object({
|
|
57071
57640
|
/** The plug's state; `null` = unknown, never off. */
|
|
@@ -57117,7 +57686,12 @@ var HeroFactSchema = object({
|
|
|
57117
57686
|
var HeroSideTileSchema = object({
|
|
57118
57687
|
label: HeroTextSchema,
|
|
57119
57688
|
value: HeroTextSchema,
|
|
57120
|
-
tone: HeroToneSchema.optional()
|
|
57689
|
+
tone: HeroToneSchema.optional(),
|
|
57690
|
+
/**
|
|
57691
|
+
* Epoch ms when the tile reads a clock time (an appliance's end): a client prints it in
|
|
57692
|
+
* the viewer's own time zone; `value` is the fallback for one that cannot.
|
|
57693
|
+
*/
|
|
57694
|
+
at: number$1().optional()
|
|
57121
57695
|
});
|
|
57122
57696
|
var HeroSideTilesSchema = object({
|
|
57123
57697
|
left: array(HeroSideTileSchema).max(2),
|
|
@@ -57153,8 +57727,12 @@ var HeroModelSchema = object({
|
|
|
57153
57727
|
sideTiles: HeroSideTilesSchema,
|
|
57154
57728
|
/** The status line under the main icon. */
|
|
57155
57729
|
title: HeroTextSchema,
|
|
57730
|
+
/** The scene's top line when it says more than `title`; absent = draw the title. */
|
|
57731
|
+
caption: HeroTextSchema.optional(),
|
|
57156
57732
|
badges: array(HeroBadgeSchema),
|
|
57157
57733
|
remote: HeroRemoteSlotSchema.nullable(),
|
|
57734
|
+
/** The foot button that opens the device's history: "History", "Cycles", "Meals", "Access". */
|
|
57735
|
+
historyLabel: HeroTextSchema,
|
|
57158
57736
|
consumables: HeroConsumablesSlotSchema.nullable(),
|
|
57159
57737
|
consumption: HeroConsumptionSlotSchema.nullable(),
|
|
57160
57738
|
ownPower: HeroOwnPowerSlotSchema.nullable(),
|
|
@@ -57175,18 +57753,31 @@ var HeroModelSchema = object({
|
|
|
57175
57753
|
* 4. a trailing fact (power, else battery, else consumables).
|
|
57176
57754
|
*
|
|
57177
57755
|
* Selection rules, all taken from the model:
|
|
57178
|
-
* -
|
|
57756
|
+
* - the primary control is the device's own power; else the FIRST control of
|
|
57179
57757
|
* the FIRST row that has any (a later row's control is never promoted). When
|
|
57180
57758
|
* the model lists that part in `gated`, the row has no inline control: the
|
|
57181
57759
|
* projection never falls through to another control the caller could use.
|
|
57760
|
+
* - a timed run, when the model carries the slot, sits beside that primary:
|
|
57761
|
+
* Run while idle, Stop while armed. Gating the slot hides the control.
|
|
57182
57762
|
* - the status line is the head (what plays, else the state) plus at most
|
|
57183
|
-
* {@link ROW_STATUS_FACTS_MAX} facts, the trailing fact excluded
|
|
57763
|
+
* {@link ROW_STATUS_FACTS_MAX} facts, the trailing fact excluded, then the
|
|
57764
|
+
* time left on an armed timed run;
|
|
57184
57765
|
* - the trailing fact is the first of power, battery, consumables.
|
|
57185
57766
|
*
|
|
57186
57767
|
* `projectDeviceRow` is pure and computes nothing: it selects from a
|
|
57187
57768
|
* {@link HeroModel}. A row that needed a value the hero lacks would mean the
|
|
57188
57769
|
* model is missing it, so the fix goes in the model.
|
|
57189
57770
|
*/
|
|
57771
|
+
/**
|
|
57772
|
+
* The row's timed-run control. `id` is `timed-run.run` while idle and
|
|
57773
|
+
* `timed-run.cancel` while armed; `duration` and `unit` are the one-tap run
|
|
57774
|
+
* a Run press starts.
|
|
57775
|
+
*/
|
|
57776
|
+
var HeroRowTimedRunSchema = object({
|
|
57777
|
+
id: _enum(["timed-run.run", "timed-run.cancel"]),
|
|
57778
|
+
duration: number$1(),
|
|
57779
|
+
unit: _enum(["min", "s"])
|
|
57780
|
+
});
|
|
57190
57781
|
var HeroRowModelSchema = object({
|
|
57191
57782
|
deviceId: number$1().int(),
|
|
57192
57783
|
name: string(),
|
|
@@ -57199,6 +57790,11 @@ var HeroRowModelSchema = object({
|
|
|
57199
57790
|
statusLine: array(HeroTextSchema),
|
|
57200
57791
|
/** `null` = the type has no inline control, or the caller may not act on it. */
|
|
57201
57792
|
primary: HeroControlSchema.nullable(),
|
|
57793
|
+
/**
|
|
57794
|
+
* Beside `primary` when the device offers a timed run: Run while idle, Stop
|
|
57795
|
+
* while armed. `null` when there is no slot, or the caller may not act.
|
|
57796
|
+
*/
|
|
57797
|
+
timedRun: HeroRowTimedRunSchema.nullable(),
|
|
57202
57798
|
trailing: HeroFactSchema.nullable()
|
|
57203
57799
|
});
|
|
57204
57800
|
/**
|
|
@@ -57612,6 +58208,12 @@ var IntegrationWithStateSchema = object({
|
|
|
57612
58208
|
name: string(),
|
|
57613
58209
|
/** A projection of the instance body's switch (`setInstanceEnabled` is the only writer). */
|
|
57614
58210
|
enabled: boolean(),
|
|
58211
|
+
/**
|
|
58212
|
+
* True when the addon that holds the switch did not answer (down, failed, or keeps no record for
|
|
58213
|
+
* this row): `enabled` is then the stored registry flag, a stale value, not the state. A reader
|
|
58214
|
+
* must not draw it as on or off (D315).
|
|
58215
|
+
*/
|
|
58216
|
+
switchUnknown: literal(true).optional(),
|
|
57615
58217
|
info: record(string(), unknown()).readonly(),
|
|
57616
58218
|
/** The discovery candidate this integration was set up from (D984). */
|
|
57617
58219
|
originStableId: string().optional(),
|
|
@@ -57625,6 +58227,12 @@ var IntegrationLiteSchema = object({
|
|
|
57625
58227
|
name: string(),
|
|
57626
58228
|
/** A projection of the instance body's switch (`setInstanceEnabled` is the only writer). */
|
|
57627
58229
|
enabled: boolean(),
|
|
58230
|
+
/**
|
|
58231
|
+
* True when the addon that holds the switch did not answer (down, failed, or keeps no record for
|
|
58232
|
+
* this row): `enabled` is then the stored registry flag, a stale value, not the state. A reader
|
|
58233
|
+
* must not draw it as on or off (D315).
|
|
58234
|
+
*/
|
|
58235
|
+
switchUnknown: literal(true).optional(),
|
|
57628
58236
|
info: record(string(), unknown()).readonly(),
|
|
57629
58237
|
/** The discovery candidate this integration was set up from (D984). */
|
|
57630
58238
|
originStableId: string().optional(),
|
|
@@ -57723,9 +58331,9 @@ var UpdateIntegrationInputSchema = object({
|
|
|
57723
58331
|
id: string(),
|
|
57724
58332
|
name: string().optional(),
|
|
57725
58333
|
/**
|
|
57726
|
-
*
|
|
57727
|
-
*
|
|
57728
|
-
*
|
|
58334
|
+
* Honoured ONLY for a fixed builtin (`info.fixed`), whose switch is the hub's own registry flag
|
|
58335
|
+
* and works while its addon is down. Any other row is refused (a typed `BAD_REQUEST`): its
|
|
58336
|
+
* switch is `integration-instances.setInstanceEnabled`.
|
|
57729
58337
|
*/
|
|
57730
58338
|
enabled: boolean().optional(),
|
|
57731
58339
|
info: record(string(), unknown()).optional()
|
|
@@ -57759,6 +58367,12 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
57759
58367
|
* the form as a `SecretFieldView`, never text (D789). A patch value omitted, `''`
|
|
57760
58368
|
* or the redaction token KEEPS the stored secret; `{ $secretClear: true }`
|
|
57761
58369
|
* clears it.
|
|
58370
|
+
*
|
|
58371
|
+
* Who may call (epic #440): every method but `describe` and `instanceFormSchema` is open to any
|
|
58372
|
+
* session (`caller: 'scoped'`) and default-denies. An admin passes everywhere. A non-admin passes
|
|
58373
|
+
* only on a call pinned to one addon whose `describe().userScoped` is true, and that provider
|
|
58374
|
+
* filters every row on the `caller` the router injected (a notification target is somebody's
|
|
58375
|
+
* phone: a user sees and changes only their own). An addon that says nothing keeps the admin door.
|
|
57762
58376
|
*/
|
|
57763
58377
|
var ConfigSchemaPassthrough$2 = custom();
|
|
57764
58378
|
var IntegrationInstanceIdSchema = string().min(1);
|
|
@@ -57872,7 +58486,15 @@ var IntegrationInstanceDescriptionSchema = object({
|
|
|
57872
58486
|
*/
|
|
57873
58487
|
mintsId: boolean().optional(),
|
|
57874
58488
|
/** The links to other instances the provider's kinds declare; absent means none. */
|
|
57875
|
-
links: array(IntegrationInstanceLinkSchema).optional()
|
|
58489
|
+
links: array(IntegrationInstanceLinkSchema).optional(),
|
|
58490
|
+
/**
|
|
58491
|
+
* The rows belong to individual users (a notification target is somebody's phone). The router
|
|
58492
|
+
* then opens `listInstances`, `getInstance`, `createInstance`, `updateInstance`,
|
|
58493
|
+
* `setInstanceEnabled`, `deleteInstance` and `testInstance` to a NON-admin session on a call
|
|
58494
|
+
* pinned to this addon, and hands the provider the `caller` so it keeps a user to their own rows.
|
|
58495
|
+
* Absent means admin only, as it always was.
|
|
58496
|
+
*/
|
|
58497
|
+
userScoped: boolean().optional()
|
|
57876
58498
|
});
|
|
57877
58499
|
var IntegrationInstanceStatusSchema = object({
|
|
57878
58500
|
state: _enum([
|
|
@@ -57930,8 +58552,14 @@ var integrationInstancesCapability = {
|
|
|
57930
58552
|
/** The discovery candidate the wizard was seeded from (`stableId`), if any. */
|
|
57931
58553
|
candidateStableId: string().min(1).optional()
|
|
57932
58554
|
}), ConfigSchemaPassthrough$2, { auth: "admin" }),
|
|
57933
|
-
listInstances: method(
|
|
57934
|
-
|
|
58555
|
+
listInstances: method(looseObject({}), array(IntegrationInstanceSchema).readonly(), {
|
|
58556
|
+
auth: "protected",
|
|
58557
|
+
caller: "scoped"
|
|
58558
|
+
}),
|
|
58559
|
+
getInstance: method(object({ id: IntegrationInstanceIdSchema }), IntegrationInstanceSchema.nullable(), {
|
|
58560
|
+
auth: "protected",
|
|
58561
|
+
caller: "scoped"
|
|
58562
|
+
}),
|
|
57935
58563
|
/**
|
|
57936
58564
|
* Insert the typed record. With `id` it is stored under that id (a duplicate id is refused);
|
|
57937
58565
|
* without one the PROVIDER mints it and answers it. `kind` picks one of `describe().kinds`.
|
|
@@ -57964,11 +58592,13 @@ var integrationInstancesCapability = {
|
|
|
57964
58592
|
seed: object({ info: record(string(), unknown()) }).optional()
|
|
57965
58593
|
}), object({ id: string() }), {
|
|
57966
58594
|
kind: "mutation",
|
|
57967
|
-
auth: "
|
|
58595
|
+
auth: "protected",
|
|
58596
|
+
caller: "scoped"
|
|
57968
58597
|
}),
|
|
57969
58598
|
updateInstance: method(IntegrationInstancePatchSchema, object({ ok: literal(true) }), {
|
|
57970
58599
|
kind: "mutation",
|
|
57971
|
-
auth: "
|
|
58600
|
+
auth: "protected",
|
|
58601
|
+
caller: "scoped"
|
|
57972
58602
|
}),
|
|
57973
58603
|
/**
|
|
57974
58604
|
* Switch ONE instance on or off, for every role; a missing record is created from the addon's
|
|
@@ -57980,7 +58610,8 @@ var integrationInstancesCapability = {
|
|
|
57980
58610
|
enabled: boolean()
|
|
57981
58611
|
}), object({ ok: literal(true) }), {
|
|
57982
58612
|
kind: "mutation",
|
|
57983
|
-
auth: "
|
|
58613
|
+
auth: "protected",
|
|
58614
|
+
caller: "scoped"
|
|
57984
58615
|
}),
|
|
57985
58616
|
/**
|
|
57986
58617
|
* Delete the record and its keychain refs together. For an instance that brings devices the hub
|
|
@@ -57989,7 +58620,8 @@ var integrationInstancesCapability = {
|
|
|
57989
58620
|
*/
|
|
57990
58621
|
deleteInstance: method(object({ id: IntegrationInstanceIdSchema }), object({ ok: literal(true) }), {
|
|
57991
58622
|
kind: "mutation",
|
|
57992
|
-
auth: "
|
|
58623
|
+
auth: "protected",
|
|
58624
|
+
caller: "scoped"
|
|
57993
58625
|
}),
|
|
57994
58626
|
testInstance: optionalMethod(object({
|
|
57995
58627
|
id: IntegrationInstanceIdSchema.nullable(),
|
|
@@ -57998,7 +58630,8 @@ var integrationInstancesCapability = {
|
|
|
57998
58630
|
kind: string().min(1).optional()
|
|
57999
58631
|
}), TestConnectionResultSchema, {
|
|
58000
58632
|
kind: "mutation",
|
|
58001
|
-
auth: "
|
|
58633
|
+
auth: "protected",
|
|
58634
|
+
caller: "scoped"
|
|
58002
58635
|
})
|
|
58003
58636
|
}
|
|
58004
58637
|
};
|
|
@@ -77465,6 +78098,11 @@ var SendEmailResultSchema = object({
|
|
|
77465
78098
|
var SmtpStatusSchema = object({
|
|
77466
78099
|
/** True iff the addon has successfully verified the relay. */
|
|
77467
78100
|
ready: boolean(),
|
|
78101
|
+
/**
|
|
78102
|
+
* The tri-state behind `ready` (D315): true when the last send worked, false when it failed,
|
|
78103
|
+
* ABSENT when the relay has not sent yet (unknown, never "not verified").
|
|
78104
|
+
*/
|
|
78105
|
+
verified: boolean().optional(),
|
|
77468
78106
|
/** Operator-visible host string (no credentials). */
|
|
77469
78107
|
host: string(),
|
|
77470
78108
|
/** Last error message reported by the relay, when not ready. */
|
|
@@ -77476,10 +78114,6 @@ method(SendEmailInputSchema, SendEmailResultSchema, {
|
|
|
77476
78114
|
kind: "mutation",
|
|
77477
78115
|
auth: "admin",
|
|
77478
78116
|
access: "create"
|
|
77479
|
-
}), method(RelayPinSchema, SmtpStatusSchema, {
|
|
77480
|
-
kind: "mutation",
|
|
77481
|
-
auth: "admin",
|
|
77482
|
-
access: "view"
|
|
77483
78117
|
}), method(RelayPinSchema, SmtpStatusSchema, { auth: "admin" });
|
|
77484
78118
|
/**
|
|
77485
78119
|
* A single device snapshot returned as base64 JPEG/PNG.
|
|
@@ -82417,6 +83051,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
82417
83051
|
groupCommands: groupCommandsCapability,
|
|
82418
83052
|
groupStatus: groupStatusCapability,
|
|
82419
83053
|
heatingValve: heatingValveCapability,
|
|
83054
|
+
heatPumpStatus: heatPumpStatusCapability,
|
|
82420
83055
|
humidifier: humidifierCapability,
|
|
82421
83056
|
humiditySensor: humiditySensorCapability,
|
|
82422
83057
|
image: imageCapability,
|
|
@@ -83700,7 +84335,7 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
83700
84335
|
return toDeviceSummary(device, this.addonId);
|
|
83701
84336
|
}
|
|
83702
84337
|
};
|
|
83703
|
-
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Heater, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Gateway;
|
|
84338
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.HeatPump, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Heater, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Gateway;
|
|
83704
84339
|
new Set(Object.values(DeviceType));
|
|
83705
84340
|
/** Parses the raw slice with the cap's own schema; `undefined` when it does not parse. */
|
|
83706
84341
|
function contribution(cap, schema, build) {
|
|
@@ -83836,6 +84471,13 @@ var lockContribution = contribution("lock-control", LockControlStatusSchema, (sl
|
|
|
83836
84471
|
reading: reading("lock-control", words?.state ?? "unknown", false, words?.title),
|
|
83837
84472
|
rows: [row$1("lock", state === "locked" || state === "locking" ? "lock" : "lock-open", joinText([title, since]), lockControls(state, ctx.features.includes(DeviceFeature.LockOpen)))],
|
|
83838
84473
|
...since === null || words === null ? {} : { facts: [fact("since", "clock", since, "muted")] },
|
|
84474
|
+
...words === null ? {} : { tiles: { left: [{
|
|
84475
|
+
label: t("Door", "Porta"),
|
|
84476
|
+
value: title
|
|
84477
|
+
}, ...since === null ? [] : [{
|
|
84478
|
+
label: t("Since", "Da"),
|
|
84479
|
+
value: since
|
|
84480
|
+
}]] } },
|
|
83839
84481
|
...words?.door == null ? {} : { scene: { mode: words.door } }
|
|
83840
84482
|
};
|
|
83841
84483
|
});
|
|
@@ -83917,7 +84559,17 @@ var ACCESS_FAMILY_CONTRIBUTIONS = {
|
|
|
83917
84559
|
return {
|
|
83918
84560
|
reading: reading("alarm-panel", words?.state ?? "unknown", false, words?.title),
|
|
83919
84561
|
rows: [row$1("alarm", state === "triggered" ? "shield-alert" : state === "disarmed" ? "shield-off" : "shield-check", joinText([words?.title ?? t("Unknown", "Sconosciuto"), since]), alarmControls(state, modes, slice?.requiresCode ?? false))],
|
|
83920
|
-
...since === null || words === null ? {} : { facts: [fact("since", "clock", since, state === "triggered" ? "danger" : "muted")] }
|
|
84562
|
+
...since === null || words === null ? {} : { facts: [fact("since", "clock", since, state === "triggered" ? "danger" : "muted")] },
|
|
84563
|
+
...words === null ? {} : { tiles: {
|
|
84564
|
+
left: [{
|
|
84565
|
+
label: t("Mode", "Modalità"),
|
|
84566
|
+
value: words.title
|
|
84567
|
+
}],
|
|
84568
|
+
...since === null ? {} : { right: [{
|
|
84569
|
+
label: t("Since", "Da"),
|
|
84570
|
+
value: since
|
|
84571
|
+
}] }
|
|
84572
|
+
} }
|
|
83921
84573
|
};
|
|
83922
84574
|
}),
|
|
83923
84575
|
"automation-control": contribution("automation-control", AutomationControlStatusSchema, (slice, ctx) => {
|
|
@@ -83981,7 +84633,7 @@ var ACCESS_FAMILY_CONTRIBUTIONS = {
|
|
|
83981
84633
|
*/
|
|
83982
84634
|
var has$3 = (ctx, f) => ctx.features.includes(f);
|
|
83983
84635
|
var unknownText = t("Unknown", "Sconosciuto");
|
|
83984
|
-
var pct$
|
|
84636
|
+
var pct$2 = (n) => t(`${Math.round(n)}%`, `${Math.round(n)}%`);
|
|
83985
84637
|
var unit = (n) => Math.min(1, Math.max(0, n / 100));
|
|
83986
84638
|
/** Battery as a fact, unless the device is also bound to the `battery` cap (it already says so). */
|
|
83987
84639
|
function ownBattery(level, ctx) {
|
|
@@ -84043,7 +84695,7 @@ var fanContribution = contribution("fan-control", FanControlStatusSchema, (slice
|
|
|
84043
84695
|
},
|
|
84044
84696
|
valueArg: "direction"
|
|
84045
84697
|
});
|
|
84046
|
-
const speedText = speed === null ? null : pct$
|
|
84698
|
+
const speedText = speed === null ? null : pct$2(speed);
|
|
84047
84699
|
const preset = slice?.preset ?? "";
|
|
84048
84700
|
const status = speed === null ? unknownText : joinText([speed === 0 ? t("Off", "Spento") : t(`Speed ${speed}%`, `Velocità ${speed}%`), preset === "" ? null : t(preset, preset)]);
|
|
84049
84701
|
return {
|
|
@@ -84056,10 +84708,16 @@ var fanContribution = contribution("fan-control", FanControlStatusSchema, (slice
|
|
|
84056
84708
|
}],
|
|
84057
84709
|
...speedText === null ? {} : {
|
|
84058
84710
|
facts: [fact("speed", "fan", speedText, speed === 0 ? "muted" : "primary")],
|
|
84059
|
-
tiles: {
|
|
84060
|
-
|
|
84061
|
-
|
|
84062
|
-
|
|
84711
|
+
tiles: {
|
|
84712
|
+
...slice?.oscillating == null ? {} : { left: [{
|
|
84713
|
+
label: t("Oscillation", "Oscilla"),
|
|
84714
|
+
value: slice.oscillating ? t("Yes", "Sì") : t("No", "No")
|
|
84715
|
+
}] },
|
|
84716
|
+
...preset === "" ? {} : { right: [{
|
|
84717
|
+
label: t("Mode", "Modalità"),
|
|
84718
|
+
value: t(preset, preset)
|
|
84719
|
+
}] }
|
|
84720
|
+
},
|
|
84063
84721
|
scene: { level: unit(speed ?? 0) }
|
|
84064
84722
|
}
|
|
84065
84723
|
};
|
|
@@ -84123,7 +84781,8 @@ var vacuumContribution = contribution("vacuum-control", VacuumControlStatusSchem
|
|
|
84123
84781
|
const words = state === null ? null : VACUUM_WORDS[state];
|
|
84124
84782
|
const title = state === "error" && slice?.errorLabel ? t(slice.errorLabel, slice.errorLabel) : words?.title;
|
|
84125
84783
|
const controls = vacuumControls(state);
|
|
84126
|
-
|
|
84784
|
+
const suctionControls = [];
|
|
84785
|
+
if (slice !== void 0 && slice.availableFanSpeeds.length > 0) suctionControls.push({
|
|
84127
84786
|
kind: "picker",
|
|
84128
84787
|
id: "vacuum.suction",
|
|
84129
84788
|
label: t("Suction", "Aspirazione"),
|
|
@@ -84138,22 +84797,31 @@ var vacuumContribution = contribution("vacuum-control", VacuumControlStatusSchem
|
|
|
84138
84797
|
});
|
|
84139
84798
|
if (state !== null) controls.push(vac("locate", "Locate", "Trova", "map-pin", "locate"));
|
|
84140
84799
|
const progress = state === "cleaning" ? slice?.progress ?? null : null;
|
|
84800
|
+
const suction = slice?.fanSpeed == null || slice.fanSpeed === "" ? [] : [{
|
|
84801
|
+
label: t("Suction", "Aspirazione"),
|
|
84802
|
+
value: t(slice.fanSpeed, slice.fanSpeed)
|
|
84803
|
+
}];
|
|
84804
|
+
const suctionRows = suctionControls.length === 0 ? [] : [{
|
|
84805
|
+
id: "vacuum-suction",
|
|
84806
|
+
icon: "bot",
|
|
84807
|
+
status: null,
|
|
84808
|
+
controls: suctionControls
|
|
84809
|
+
}];
|
|
84810
|
+
const vacuumRows = [{
|
|
84811
|
+
id: "vacuum",
|
|
84812
|
+
icon: "bot",
|
|
84813
|
+
status: title ?? unknownText,
|
|
84814
|
+
controls
|
|
84815
|
+
}, ...suctionRows];
|
|
84141
84816
|
return {
|
|
84142
84817
|
reading: reading("vacuum-control", words?.state ?? "unknown", false, title),
|
|
84143
|
-
rows:
|
|
84144
|
-
|
|
84145
|
-
|
|
84146
|
-
|
|
84147
|
-
|
|
84148
|
-
}],
|
|
84149
|
-
|
|
84150
|
-
...progress === null ? {} : {
|
|
84151
|
-
tiles: { right: [{
|
|
84152
|
-
label: t("Progress", "Avanzamento"),
|
|
84153
|
-
value: pct$1(progress)
|
|
84154
|
-
}] },
|
|
84155
|
-
scene: { level: unit(progress) }
|
|
84156
|
-
}
|
|
84818
|
+
rows: vacuumRows,
|
|
84819
|
+
facts: [...ownBattery(slice?.batteryLevel ?? null, ctx), ...progress === null ? [] : [fact("progress", "activity", pct$2(progress), "primary")]],
|
|
84820
|
+
...suction.length === 0 && progress === null ? {} : { tiles: { right: [...suction, ...progress === null ? [] : [{
|
|
84821
|
+
label: t("Progress", "Avanzamento"),
|
|
84822
|
+
value: pct$2(progress)
|
|
84823
|
+
}]] } },
|
|
84824
|
+
...progress === null ? {} : { scene: { level: unit(progress) } }
|
|
84157
84825
|
};
|
|
84158
84826
|
});
|
|
84159
84827
|
var MOWER_WORDS = {
|
|
@@ -84209,11 +84877,11 @@ var mowerContribution = contribution("lawn-mower-control", LawnMowerControlStatu
|
|
|
84209
84877
|
status: title ?? unknownText,
|
|
84210
84878
|
controls: mowerControls(activity)
|
|
84211
84879
|
}],
|
|
84212
|
-
facts: [...ownBattery(slice?.batteryLevel ?? null, ctx), ...progress === null ? [] : [fact("progress", "activity", pct$
|
|
84880
|
+
facts: [...ownBattery(slice?.batteryLevel ?? null, ctx), ...progress === null ? [] : [fact("progress", "activity", pct$2(progress), "primary")]],
|
|
84213
84881
|
...progress === null ? {} : {
|
|
84214
84882
|
tiles: { right: [{
|
|
84215
84883
|
label: t("Progress", "Avanzamento"),
|
|
84216
|
-
value: pct$
|
|
84884
|
+
value: pct$2(progress)
|
|
84217
84885
|
}] },
|
|
84218
84886
|
scene: { level: unit(progress) }
|
|
84219
84887
|
}
|
|
@@ -84284,10 +84952,13 @@ var feederContribution = contribution("pet-feeder", PetFeederStatusSchema, (slic
|
|
|
84284
84952
|
...last === null ? [] : [fact("last-run", "clock", t(`Last ${last} g`, `Ultimo ${last} g`))],
|
|
84285
84953
|
...ownBattery(slice?.powerSource === "battery" ? slice.batteryPower : null, ctx)
|
|
84286
84954
|
],
|
|
84287
|
-
...
|
|
84955
|
+
tiles: { left: [...slice?.foodLevel == null ? [] : [{
|
|
84956
|
+
label: t("Tank", "Serbatoio"),
|
|
84957
|
+
value: pct$2(slice.foodLevel)
|
|
84958
|
+
}], ...last === null ? [] : [{
|
|
84288
84959
|
label: t("Last portion", "Ultima porzione"),
|
|
84289
84960
|
value: t(`${last} g`, `${last} g`)
|
|
84290
|
-
}] }
|
|
84961
|
+
}]] }
|
|
84291
84962
|
};
|
|
84292
84963
|
});
|
|
84293
84964
|
var fountainContribution = contribution("pet-fountain", PetFountainStatusSchema, (slice) => {
|
|
@@ -84315,10 +84986,13 @@ var fountainContribution = contribution("pet-fountain", PetFountainStatusSchema,
|
|
|
84315
84986
|
}],
|
|
84316
84987
|
...level === null ? {} : {
|
|
84317
84988
|
facts: [fact("level", "droplets", t(`Water ${Math.round(level)}%`, `Acqua ${Math.round(level)}%`), level <= 20 ? "warning" : "primary")],
|
|
84318
|
-
tiles: {
|
|
84989
|
+
tiles: { left: [{
|
|
84319
84990
|
label: t("Water", "Acqua"),
|
|
84320
|
-
value: pct$
|
|
84321
|
-
}]
|
|
84991
|
+
value: pct$2(level)
|
|
84992
|
+
}, ...slice?.waterVolume == null ? [] : [{
|
|
84993
|
+
label: t("Volume", "Volume"),
|
|
84994
|
+
value: t(`${Math.round(slice.waterVolume)} ml`, `${Math.round(slice.waterVolume)} ml`)
|
|
84995
|
+
}]] },
|
|
84322
84996
|
scene: { level: unit(level) }
|
|
84323
84997
|
}
|
|
84324
84998
|
};
|
|
@@ -84350,14 +85024,18 @@ var DEVICES_FAMILY_CONTRIBUTIONS = {
|
|
|
84350
85024
|
* that does not parse reads `unknown`, never closed or off (D315/D393).
|
|
84351
85025
|
*/
|
|
84352
85026
|
var has$2 = (ctx, f) => ctx.features.includes(f);
|
|
84353
|
-
var pct = (n) => t(`${Math.round(n)}%`, `${Math.round(n)}%`);
|
|
85027
|
+
var pct$1 = (n) => t(`${Math.round(n)}%`, `${Math.round(n)}%`);
|
|
84354
85028
|
var brightnessContribution = contribution("brightness", BrightnessStatusSchema, (slice) => {
|
|
84355
85029
|
const level = slice?.level ?? null;
|
|
84356
85030
|
return {
|
|
84357
85031
|
...level === null ? {} : { reading: reading("brightness", level > 0 ? "on" : "off") },
|
|
84358
85032
|
...level === null ? {} : {
|
|
84359
|
-
facts: [fact("level", "sun-dim", pct(level), level > 0 ? "primary" : "muted")],
|
|
84360
|
-
scene: { level: level / 100 }
|
|
85033
|
+
facts: [fact("level", "sun-dim", pct$1(level), level > 0 ? "primary" : "muted")],
|
|
85034
|
+
scene: { level: level / 100 },
|
|
85035
|
+
tiles: { left: [{
|
|
85036
|
+
label: t("Brightness", "Luminosità"),
|
|
85037
|
+
value: pct$1(level)
|
|
85038
|
+
}] }
|
|
84361
85039
|
},
|
|
84362
85040
|
rows: [row$1("brightness", "sun-dim", level === null ? null : t(`Brightness ${Math.round(level)}%`, `Luminosità ${Math.round(level)}%`), [{
|
|
84363
85041
|
kind: "slider",
|
|
@@ -84566,12 +85244,16 @@ function travelFragment(s, state, position, tilt, ctx) {
|
|
|
84566
85244
|
});
|
|
84567
85245
|
return {
|
|
84568
85246
|
reading: reading(s.source, words.state, false, words.title),
|
|
84569
|
-
...position === null ? {} : { facts: [fact("level", "arrow-up-down", pct(position))] },
|
|
85247
|
+
...position === null ? {} : { facts: [fact("level", "arrow-up-down", pct$1(position))] },
|
|
85248
|
+
...position === null ? {} : { tiles: { left: [{
|
|
85249
|
+
label: t("Opening", "Apertura"),
|
|
85250
|
+
value: pct$1(position)
|
|
85251
|
+
}] } },
|
|
84570
85252
|
scene: {
|
|
84571
85253
|
...words.mode === null ? {} : { mode: words.mode },
|
|
84572
85254
|
...position === null ? {} : { level: position / 100 }
|
|
84573
85255
|
},
|
|
84574
|
-
rows: [row$1(s.rowId, "arrow-up-down", joinText([words.title, position !== null && state !== "open" ? pct(position) : null]), controls)]
|
|
85256
|
+
rows: [row$1(s.rowId, "arrow-up-down", joinText([words.title, position !== null && state !== "open" ? pct$1(position) : null]), controls)]
|
|
84575
85257
|
};
|
|
84576
85258
|
}
|
|
84577
85259
|
var ACTUATORS_FAMILY_CONTRIBUTIONS = {
|
|
@@ -84649,10 +85331,10 @@ var ACTUATORS_FAMILY_CONTRIBUTIONS = {
|
|
|
84649
85331
|
const now = slice.currentHumidity;
|
|
84650
85332
|
return {
|
|
84651
85333
|
reading: reading("humidifier", state, false, title),
|
|
84652
|
-
...now === null ? {} : { facts: [fact("level", "droplets", pct(now), "info")] },
|
|
85334
|
+
...now === null ? {} : { facts: [fact("level", "droplets", pct$1(now), "info")] },
|
|
84653
85335
|
...slice.targetHumidity === null ? {} : { tiles: { right: [{
|
|
84654
85336
|
label: t("Target", "Obiettivo"),
|
|
84655
|
-
value: pct(slice.targetHumidity)
|
|
85337
|
+
value: pct$1(slice.targetHumidity)
|
|
84656
85338
|
}] } },
|
|
84657
85339
|
...now === null ? {} : { scene: { level: now / 100 } },
|
|
84658
85340
|
rows: [row$1("humidifier", "droplets", joinText([title, slice.mode === null ? null : t(slice.mode, slice.mode)]), controls)]
|
|
@@ -84900,17 +85582,16 @@ var weatherContribution = contribution("weather", WeatherStatusSchema, (slice, c
|
|
|
84900
85582
|
});
|
|
84901
85583
|
var updateContribution = contribution("update", UpdateStatusSchema, (slice) => {
|
|
84902
85584
|
if (slice === void 0) return { reading: reading("update", "unknown") };
|
|
84903
|
-
const { currentVersion, availableVersion, inProgress
|
|
85585
|
+
const { currentVersion, availableVersion, inProgress } = slice;
|
|
84904
85586
|
const pending = availableVersion !== null && availableVersion !== "" && availableVersion !== currentVersion;
|
|
84905
85587
|
if (!pending && currentVersion === null && !inProgress) return { reading: reading("update", "unknown") };
|
|
84906
85588
|
const state = inProgress ? "running" : pending ? "standby" : "idle";
|
|
84907
85589
|
const title = inProgress ? t("Updating", "Aggiornamento in corso") : pending ? t("Update available", "Aggiornamento disponibile") : t("Up to date", "Aggiornato");
|
|
84908
85590
|
const versions = currentVersion === null ? pending ? t(`${availableVersion}`, `${availableVersion}`) : null : pending ? t(`${currentVersion} → ${availableVersion}`, `${currentVersion} → ${availableVersion}`) : t(`Version ${currentVersion}`, `Versione ${currentVersion}`);
|
|
84909
|
-
const install = pending && updatable && !inProgress ? [asAction(action("update.install", t("Install", "Installa"), "download", "update", "installUpdate", {}, "primary", "install"))] : [];
|
|
84910
85591
|
return {
|
|
84911
85592
|
reading: reading("update", state, false, title),
|
|
84912
85593
|
facts: versions === null ? [] : [fact("reading", "download", versions, pending ? "warning" : "muted")],
|
|
84913
|
-
rows: [row$1("update", "download", versions,
|
|
85594
|
+
rows: [row$1("update", "download", versions, [])]
|
|
84914
85595
|
};
|
|
84915
85596
|
});
|
|
84916
85597
|
var imageContribution = contribution("image", ImageStatusSchema, (slice, ctx) => {
|
|
@@ -85018,6 +85699,33 @@ var ON_MODE_PREFERENCE = [
|
|
|
85018
85699
|
"heat",
|
|
85019
85700
|
"cool"
|
|
85020
85701
|
];
|
|
85702
|
+
var FAN_LABEL = {
|
|
85703
|
+
auto: t("Auto", "Auto"),
|
|
85704
|
+
quiet: t("Quiet", "Silenziosa"),
|
|
85705
|
+
low: t("Low", "Bassa"),
|
|
85706
|
+
medium: t("Medium", "Media"),
|
|
85707
|
+
high: t("High", "Alta"),
|
|
85708
|
+
turbo: t("Turbo", "Turbo"),
|
|
85709
|
+
off: t("Off", "Spenta")
|
|
85710
|
+
};
|
|
85711
|
+
/** A readable label for a fan speed name; an unknown one is shown as the device reported it. */
|
|
85712
|
+
function fanLabelOf(fan) {
|
|
85713
|
+
return FAN_LABEL[fan] ?? t(fan, fan);
|
|
85714
|
+
}
|
|
85715
|
+
/** Short labels for a segmented control: one word each, so the segments stay on a line. */
|
|
85716
|
+
var MODE_SEGMENT_LABEL = {
|
|
85717
|
+
off: t("Off", "Spento"),
|
|
85718
|
+
heat: t("Heat", "Caldo"),
|
|
85719
|
+
cool: t("Cool", "Freddo"),
|
|
85720
|
+
auto: t("Auto", "Auto"),
|
|
85721
|
+
heat_cool: t("Heat/Cool", "Caldo/Freddo"),
|
|
85722
|
+
fan_only: t("Fan", "Vent."),
|
|
85723
|
+
dry: t("Dry", "Deum.")
|
|
85724
|
+
};
|
|
85725
|
+
/** The segment label of every available HVAC mode, keyed by the mode value. */
|
|
85726
|
+
function modeLabelsOf(modes) {
|
|
85727
|
+
return Object.fromEntries(modes.map((m) => [m, MODE_SEGMENT_LABEL[m]]));
|
|
85728
|
+
}
|
|
85021
85729
|
/** 22 -> "22", 22.3 -> "22.3": a trailing zero is noise on a thermostat. */
|
|
85022
85730
|
function formatDegrees(value) {
|
|
85023
85731
|
return `${Number(value.toFixed(1))}°`;
|
|
@@ -85082,11 +85790,11 @@ function rangeFrom(min, max, step) {
|
|
|
85082
85790
|
* contribute, types never do (D14). A slice that is absent or does not parse is
|
|
85083
85791
|
* "not answered": the state reads unknown, no row is drawn (D315, D393).
|
|
85084
85792
|
*/
|
|
85085
|
-
var same = (text) => t(text, text);
|
|
85086
|
-
function tile(en, it, value) {
|
|
85793
|
+
var same$1 = (text) => t(text, text);
|
|
85794
|
+
function tile$1(en, it, value) {
|
|
85087
85795
|
return {
|
|
85088
85796
|
label: t(en, it),
|
|
85089
|
-
value: same(value)
|
|
85797
|
+
value: same$1(value)
|
|
85090
85798
|
};
|
|
85091
85799
|
}
|
|
85092
85800
|
function setpointSlider(id, cap, method, valueArg, value, range) {
|
|
@@ -85121,18 +85829,19 @@ var climateContribution = contribution("climate-control", ClimateControlStatusSc
|
|
|
85121
85829
|
const status = climateStatusText(view);
|
|
85122
85830
|
const facts = [];
|
|
85123
85831
|
if (status !== null) facts.push(fact("climate", "thermometer", status));
|
|
85124
|
-
if (view.humidity !== null) facts.push(fact("humidity", "droplets", same(`${Math.round(view.humidity)}%`)));
|
|
85125
|
-
if (view.targetHumidity !== null) facts.push(fact("humidity", "droplets", same(`→ ${Math.round(view.targetHumidity)}%`)));
|
|
85832
|
+
if (view.humidity !== null) facts.push(fact("humidity", "droplets", same$1(`${Math.round(view.humidity)}%`)));
|
|
85833
|
+
if (view.targetHumidity !== null) facts.push(fact("humidity", "droplets", same$1(`→ ${Math.round(view.targetHumidity)}%`)));
|
|
85126
85834
|
const left = [];
|
|
85127
85835
|
const right = [];
|
|
85128
|
-
if (view.measured !== null) left.push(tile("Indoor", "In casa", formatDegrees(view.measured)));
|
|
85129
|
-
if (view.humidity !== null) left.push(tile("Humidity", "Umidità", `${Math.round(view.humidity)}%`));
|
|
85836
|
+
if (view.measured !== null) left.push(tile$1("Indoor", "In casa", formatDegrees(view.measured)));
|
|
85837
|
+
if (view.humidity !== null) left.push(tile$1("Humidity", "Umidità", `${Math.round(view.humidity)}%`));
|
|
85130
85838
|
const modeControls = [{
|
|
85131
85839
|
kind: "picker",
|
|
85132
85840
|
id: "climate.mode",
|
|
85133
85841
|
label: t("Mode", "Modalità"),
|
|
85134
85842
|
current: view.mode,
|
|
85135
|
-
options: [...view.availableModes],
|
|
85843
|
+
options: [...view.availableModes.filter((m) => m !== "off"), ...view.availableModes.filter((m) => m === "off")],
|
|
85844
|
+
optionLabels: modeLabelsOf(view.availableModes),
|
|
85136
85845
|
call: {
|
|
85137
85846
|
cap: "climate-control",
|
|
85138
85847
|
method: "setMode",
|
|
@@ -85160,6 +85869,7 @@ var climateContribution = contribution("climate-control", ClimateControlStatusSc
|
|
|
85160
85869
|
label: t("Fan", "Ventola"),
|
|
85161
85870
|
current: slice.fanMode === "" ? null : slice.fanMode,
|
|
85162
85871
|
options: [...slice.availableFanModes],
|
|
85872
|
+
optionLabels: Object.fromEntries(slice.availableFanModes.map((m) => [m, fanLabelOf(m)])),
|
|
85163
85873
|
call: {
|
|
85164
85874
|
cap: "climate-control",
|
|
85165
85875
|
method: "setFanMode",
|
|
@@ -85185,14 +85895,15 @@ var climateContribution = contribution("climate-control", ClimateControlStatusSc
|
|
|
85185
85895
|
if (fanControls.length > 0) rows.push({
|
|
85186
85896
|
id: "climate-fan",
|
|
85187
85897
|
icon: "fan",
|
|
85188
|
-
status: slice.fanMode === "" ? null : same(slice.fanMode),
|
|
85898
|
+
status: slice.fanMode === "" ? null : same$1(slice.fanMode),
|
|
85189
85899
|
controls: fanControls
|
|
85190
85900
|
});
|
|
85191
|
-
rows.push(...setpointRow(view.target === null ? null : same(formatDegrees(view.target)), view.range === null || view.target === null ? null : setpointSlider("climate.target", "climate-control", "setTarget", "target", view.target, view.range)));
|
|
85901
|
+
rows.push(...setpointRow(view.target === null ? null : same$1(formatDegrees(view.target)), view.range === null || view.target === null ? null : setpointSlider("climate.target", "climate-control", "setTarget", "target", view.target, view.range)));
|
|
85192
85902
|
const sceneMode = view.sceneMode;
|
|
85193
85903
|
return {
|
|
85194
85904
|
reading: reading("climate-control", view.isOff ? "off" : "on"),
|
|
85195
85905
|
title: view.modeLabel,
|
|
85906
|
+
...view.isOff || slice.fanMode === "" ? {} : { caption: t(`${view.modeLabel.en} · fan ${fanLabelOf(slice.fanMode).en}`, `${view.modeLabel.it} · ventola ${fanLabelOf(slice.fanMode).it}`) },
|
|
85196
85907
|
facts,
|
|
85197
85908
|
...left.length === 0 && right.length === 0 ? {} : { tiles: {
|
|
85198
85909
|
left,
|
|
@@ -85219,7 +85930,7 @@ var WATER_ON_PREFERENCE = [
|
|
|
85219
85930
|
"performance"
|
|
85220
85931
|
];
|
|
85221
85932
|
function capitalised(word) {
|
|
85222
|
-
return same(word.charAt(0).toUpperCase() + word.slice(1).replace(/_/g, " "));
|
|
85933
|
+
return same$1(word.charAt(0).toUpperCase() + word.slice(1).replace(/_/g, " "));
|
|
85223
85934
|
}
|
|
85224
85935
|
var waterHeaterContribution = contribution("water-heater", WaterHeaterStatusSchema, (slice) => {
|
|
85225
85936
|
if (slice === void 0 || slice.operationMode === null) return { reading: reading("climate-control", "unknown") };
|
|
@@ -85256,13 +85967,13 @@ var waterHeaterContribution = contribution("water-heater", WaterHeaterStatusSche
|
|
|
85256
85967
|
icon: "flame",
|
|
85257
85968
|
status: label,
|
|
85258
85969
|
controls: modeControls
|
|
85259
|
-
}, ...setpointRow(slice.targetTemp === null ? null : same(formatDegrees(slice.targetTemp)), range === null || slice.targetTemp === null ? null : setpointSlider("water-heater.target", "water-heater", "setTargetTemp", "temp", slice.targetTemp, range))];
|
|
85970
|
+
}, ...setpointRow(slice.targetTemp === null ? null : same$1(formatDegrees(slice.targetTemp)), range === null || slice.targetTemp === null ? null : setpointSlider("water-heater.target", "water-heater", "setTargetTemp", "temp", slice.targetTemp, range))];
|
|
85260
85971
|
const level = levelWithin(slice.targetTemp, range);
|
|
85261
85972
|
return {
|
|
85262
85973
|
reading: reading("climate-control", isOff ? "off" : "on"),
|
|
85263
85974
|
title: label,
|
|
85264
85975
|
facts: status === null ? [] : [fact("climate", "flame", status)],
|
|
85265
|
-
...slice.currentTemp === null ? {} : { tiles: { left: [tile("Water", "Acqua", formatDegrees(slice.currentTemp))] } },
|
|
85976
|
+
...slice.currentTemp === null ? {} : { tiles: { left: [tile$1("Water", "Acqua", formatDegrees(slice.currentTemp))] } },
|
|
85266
85977
|
scene: {
|
|
85267
85978
|
...isOff ? {} : { mode: "heat" },
|
|
85268
85979
|
...level === null ? {} : { level }
|
|
@@ -85280,11 +85991,12 @@ var waterHeaterContribution = contribution("water-heater", WaterHeaterStatusSche
|
|
|
85280
85991
|
var heatingValveContribution = contribution("heating-valve", HeatingValveStatusSchema, (slice) => {
|
|
85281
85992
|
const position = slice?.position ?? null;
|
|
85282
85993
|
if (position === null) return { reading: reading("sensor", "unknown") };
|
|
85283
|
-
const text = same(`${Math.round(position)}%`);
|
|
85994
|
+
const text = same$1(`${Math.round(position)}%`);
|
|
85284
85995
|
return {
|
|
85285
85996
|
reading: reading("sensor", position > 0 ? "running" : "idle"),
|
|
85286
85997
|
facts: [fact("valve", "gauge", t(`Valve ${text.en}`, `Valvola ${text.it}`))],
|
|
85287
|
-
tiles: { right: [tile("Valve", "Valvola", text.en)] },
|
|
85998
|
+
tiles: { right: [tile$1("Valve", "Valvola", text.en)] },
|
|
85999
|
+
...position > 0 ? { caption: t(`Heating · valve ${text.en}`, `Riscalda · valvola ${text.it}`) } : {},
|
|
85288
86000
|
scene: { level: position / 100 }
|
|
85289
86001
|
};
|
|
85290
86002
|
});
|
|
@@ -85293,9 +86005,9 @@ function sensorFragment(value, id, icon, en, it, text) {
|
|
|
85293
86005
|
if (value === null) return { reading: reading("sensor", "unknown") };
|
|
85294
86006
|
return {
|
|
85295
86007
|
reading: reading("sensor", "on"),
|
|
85296
|
-
title: same(text),
|
|
85297
|
-
facts: [fact(id, icon, same(text))],
|
|
85298
|
-
tiles: { right: [tile(en, it, text)] }
|
|
86008
|
+
title: same$1(text),
|
|
86009
|
+
facts: [fact(id, icon, same$1(text))],
|
|
86010
|
+
tiles: { right: [tile$1(en, it, text)] }
|
|
85299
86011
|
};
|
|
85300
86012
|
}
|
|
85301
86013
|
var temperatureContribution = contribution("temperature-sensor", TemperatureSensorStatusSchema, (slice) => sensorFragment(slice?.temperature ?? null, "temperature", "thermometer", "Temperature", "Temperatura", formatDegrees(slice?.temperature ?? 0)));
|
|
@@ -85350,8 +86062,8 @@ var CLIMATE_FAMILY_CONTRIBUTIONS = {
|
|
|
85350
86062
|
return {
|
|
85351
86063
|
reading: reading("sensor", "on"),
|
|
85352
86064
|
...slice.aqi === void 0 ? {} : { title: airQualityWord(slice.aqi) },
|
|
85353
|
-
facts: parts.map((p) => fact("air-quality", "wind", same(`${p.label} ${p.value}`))),
|
|
85354
|
-
tiles: { right: parts.slice(0, 2).map((p) => tile(p.label, p.label, p.value)) }
|
|
86065
|
+
facts: parts.map((p) => fact("air-quality", "wind", same$1(`${p.label} ${p.value}`))),
|
|
86066
|
+
tiles: { right: parts.slice(0, 2).map((p) => tile$1(p.label, p.label, p.value)) }
|
|
85355
86067
|
};
|
|
85356
86068
|
}),
|
|
85357
86069
|
"carbon-monoxide": contribution("carbon-monoxide", CarbonMonoxideStatusSchema, (slice) => {
|
|
@@ -85366,15 +86078,264 @@ var CLIMATE_FAMILY_CONTRIBUTIONS = {
|
|
|
85366
86078
|
"numeric-sensor": numericContribution,
|
|
85367
86079
|
"enum-sensor": enumContribution
|
|
85368
86080
|
};
|
|
86081
|
+
/**
|
|
86082
|
+
* The heat pump's contribution to a hero (D1026): the compressor scene, every
|
|
86083
|
+
* circuit as a row with its own label and icon, the powers as pills (the
|
|
86084
|
+
* instantaneous COP only when both powers are known) and a "System" group with
|
|
86085
|
+
* one selector per mode. Values and their limits come from the slice, which the
|
|
86086
|
+
* gateway filled: a selector with no allowed value is not drawn, a missing
|
|
86087
|
+
* reading is never a 0 (D393).
|
|
86088
|
+
*/
|
|
86089
|
+
var CAP = "heat-pump-control";
|
|
86090
|
+
var same = (text) => t(text, text);
|
|
86091
|
+
/** The words of the values the gateway names; a value not listed is drawn as the gateway wrote it. */
|
|
86092
|
+
var VALUE_LABELS = {
|
|
86093
|
+
off: t("Off", "Off"),
|
|
86094
|
+
on: t("On", "On"),
|
|
86095
|
+
auto: t("Auto", "Auto"),
|
|
86096
|
+
manual: t("Manual", "Manuale"),
|
|
86097
|
+
low: t("Low", "Bassa"),
|
|
86098
|
+
high: t("High", "Alta"),
|
|
86099
|
+
eco: t("Eco", "Eco"),
|
|
86100
|
+
heat: t("Heat", "Caldo"),
|
|
86101
|
+
cool: t("Cool", "Freddo"),
|
|
86102
|
+
heatCool: t("Heat/cool", "Caldo/freddo"),
|
|
86103
|
+
ownprogram: t("Programme", "Programma")
|
|
86104
|
+
};
|
|
86105
|
+
function valueLabel(value) {
|
|
86106
|
+
const known = VALUE_LABELS[value];
|
|
86107
|
+
if (known !== void 0) return known;
|
|
86108
|
+
const holiday = /^hm(\d+)$/.exec(value);
|
|
86109
|
+
if (holiday?.[1] !== void 0) return t(`Programme ${holiday[1]}`, `Programma ${holiday[1]}`);
|
|
86110
|
+
return same(value);
|
|
86111
|
+
}
|
|
86112
|
+
function optionLabels(allowed) {
|
|
86113
|
+
return Object.fromEntries(allowed.map((value) => [value, valueLabel(value)]));
|
|
86114
|
+
}
|
|
86115
|
+
function picker(id, label, setting, method, args, valueArg = "mode") {
|
|
86116
|
+
return {
|
|
86117
|
+
kind: "picker",
|
|
86118
|
+
id,
|
|
86119
|
+
label,
|
|
86120
|
+
current: setting.value,
|
|
86121
|
+
options: [...setting.allowed],
|
|
86122
|
+
optionLabels: optionLabels(setting.allowed),
|
|
86123
|
+
call: {
|
|
86124
|
+
cap: CAP,
|
|
86125
|
+
method,
|
|
86126
|
+
args: { ...args }
|
|
86127
|
+
},
|
|
86128
|
+
valueArg
|
|
86129
|
+
};
|
|
86130
|
+
}
|
|
86131
|
+
/** A selector exists only where the gateway named values to choose from. */
|
|
86132
|
+
function choosable(setting) {
|
|
86133
|
+
return setting !== null && setting.allowed.length > 0;
|
|
86134
|
+
}
|
|
86135
|
+
function circuitControl(circuit) {
|
|
86136
|
+
const args = { circuitId: circuit.id };
|
|
86137
|
+
if (circuit.kind === "dhw" && choosable(circuit.temperatureLevel)) return picker(`heat-pump.${circuit.id}.level`, t("Level", "Livello"), circuit.temperatureLevel, "setDhwTemperatureLevel", args, "level");
|
|
86138
|
+
if (!choosable(circuit.operationMode)) return null;
|
|
86139
|
+
const method = circuit.kind === "dhw" ? "setDhwOperationMode" : "setCircuitOperationMode";
|
|
86140
|
+
return picker(`heat-pump.${circuit.id}.mode`, t("Mode", "Modalità"), circuit.operationMode, method, args);
|
|
86141
|
+
}
|
|
86142
|
+
/** A circuit with no reading is still a row: it shows that nothing is known, not nothing. */
|
|
86143
|
+
var UNKNOWN_STATUS = same("—");
|
|
86144
|
+
function circuitRow(circuit) {
|
|
86145
|
+
const control = circuitControl(circuit);
|
|
86146
|
+
const status = thermalStatusText(circuit.targetTemp, circuit.currentTemp) ?? UNKNOWN_STATUS;
|
|
86147
|
+
return {
|
|
86148
|
+
id: "circuit",
|
|
86149
|
+
label: same(circuit.label),
|
|
86150
|
+
icon: circuit.icon,
|
|
86151
|
+
status,
|
|
86152
|
+
controls: control === null ? [] : [control]
|
|
86153
|
+
};
|
|
86154
|
+
}
|
|
86155
|
+
var kilowatts = (watts) => `${Number((watts / 1e3).toFixed(2))} kW`;
|
|
86156
|
+
function powerPills(status) {
|
|
86157
|
+
const { thermalW, electricalW } = status.power;
|
|
86158
|
+
const cop = heatPumpInstantCop(status.power);
|
|
86159
|
+
const pills = [];
|
|
86160
|
+
if (thermalW !== null) pills.push({
|
|
86161
|
+
icon: "flame",
|
|
86162
|
+
text: t(`Thermal ${kilowatts(thermalW)}`, `Termica ${kilowatts(thermalW)}`),
|
|
86163
|
+
tone: "muted"
|
|
86164
|
+
});
|
|
86165
|
+
if (electricalW !== null) pills.push({
|
|
86166
|
+
icon: "zap",
|
|
86167
|
+
text: t(`Electrical ${kilowatts(electricalW)}`, `Elettrica ${kilowatts(electricalW)}`),
|
|
86168
|
+
tone: "muted"
|
|
86169
|
+
});
|
|
86170
|
+
if (cop !== null) {
|
|
86171
|
+
const text = String(Number(cop.toFixed(1)));
|
|
86172
|
+
pills.push({
|
|
86173
|
+
icon: "gauge",
|
|
86174
|
+
text: t(`Instantaneous COP ${text}`, `COP istantaneo ${text}`),
|
|
86175
|
+
tone: "success"
|
|
86176
|
+
});
|
|
86177
|
+
}
|
|
86178
|
+
return pills;
|
|
86179
|
+
}
|
|
86180
|
+
/** The independent system modes, in the order the card draws them. */
|
|
86181
|
+
var SYSTEM_MODES = [
|
|
86182
|
+
{
|
|
86183
|
+
key: "silent",
|
|
86184
|
+
label: t("Silent", "Silenzioso"),
|
|
86185
|
+
icon: "volume-x",
|
|
86186
|
+
method: "setSilentMode"
|
|
86187
|
+
},
|
|
86188
|
+
{
|
|
86189
|
+
key: "away",
|
|
86190
|
+
label: t("Away", "Assente"),
|
|
86191
|
+
icon: "plane",
|
|
86192
|
+
method: "setAwayMode"
|
|
86193
|
+
},
|
|
86194
|
+
{
|
|
86195
|
+
key: "additionalHeater",
|
|
86196
|
+
label: t("Additional heater", "Riscaldatore aggiuntivo"),
|
|
86197
|
+
icon: "flame",
|
|
86198
|
+
method: "setAdditionalHeaterMode"
|
|
86199
|
+
},
|
|
86200
|
+
{
|
|
86201
|
+
key: "holiday",
|
|
86202
|
+
label: t("Holiday", "Vacanza"),
|
|
86203
|
+
icon: "tree-palm",
|
|
86204
|
+
method: "setHolidayMode"
|
|
86205
|
+
}
|
|
86206
|
+
];
|
|
86207
|
+
var SYSTEM_GROUP = t("System", "Sistema");
|
|
86208
|
+
var PROGRAMME = /^hm\d+$/;
|
|
86209
|
+
/**
|
|
86210
|
+
* Holiday is two segments, off / programme. Choosing "programme" keeps the programme
|
|
86211
|
+
* that is set, else the first one the gateway allowed, so a write never leaves
|
|
86212
|
+
* `allowed`. The full hm1..hm8 pick is not in the hero (D1026). A holiday whose values
|
|
86213
|
+
* are not programmes keeps the plain selector.
|
|
86214
|
+
*/
|
|
86215
|
+
function holidayRow(def, setting) {
|
|
86216
|
+
if (!setting.allowed.includes("off")) return null;
|
|
86217
|
+
const current = setting.value !== null && PROGRAMME.test(setting.value) ? setting.value : null;
|
|
86218
|
+
const programme = current ?? setting.allowed.find((v) => PROGRAMME.test(v));
|
|
86219
|
+
if (programme === void 0) return null;
|
|
86220
|
+
const control = picker("heat-pump.system.holiday", def.label, {
|
|
86221
|
+
value: setting.value,
|
|
86222
|
+
allowed: ["off", programme]
|
|
86223
|
+
}, def.method, {});
|
|
86224
|
+
const number = programme.slice(2);
|
|
86225
|
+
return {
|
|
86226
|
+
id: "system-mode",
|
|
86227
|
+
label: def.label,
|
|
86228
|
+
group: SYSTEM_GROUP,
|
|
86229
|
+
icon: def.icon,
|
|
86230
|
+
status: current === null ? null : t(`Programme ${number}`, `Programma ${number}`),
|
|
86231
|
+
controls: [control.kind === "picker" ? {
|
|
86232
|
+
...control,
|
|
86233
|
+
optionLabels: {
|
|
86234
|
+
off: t("Off", "Off"),
|
|
86235
|
+
[programme]: t("Programme", "Programma")
|
|
86236
|
+
}
|
|
86237
|
+
} : control]
|
|
86238
|
+
};
|
|
86239
|
+
}
|
|
86240
|
+
function systemRows(status) {
|
|
86241
|
+
const rows = [];
|
|
86242
|
+
for (const def of SYSTEM_MODES) {
|
|
86243
|
+
const setting = status.system[def.key];
|
|
86244
|
+
if (!choosable(setting)) continue;
|
|
86245
|
+
if (def.key === "holiday") {
|
|
86246
|
+
const holiday = holidayRow(def, setting);
|
|
86247
|
+
if (holiday !== null) {
|
|
86248
|
+
rows.push(holiday);
|
|
86249
|
+
continue;
|
|
86250
|
+
}
|
|
86251
|
+
}
|
|
86252
|
+
rows.push({
|
|
86253
|
+
id: "system-mode",
|
|
86254
|
+
label: def.label,
|
|
86255
|
+
group: SYSTEM_GROUP,
|
|
86256
|
+
icon: def.icon,
|
|
86257
|
+
status: null,
|
|
86258
|
+
controls: [picker(`heat-pump.system.${def.key}`, def.label, setting, def.method, {})]
|
|
86259
|
+
});
|
|
86260
|
+
}
|
|
86261
|
+
return rows;
|
|
86262
|
+
}
|
|
86263
|
+
function tile(en, it, value) {
|
|
86264
|
+
return {
|
|
86265
|
+
label: t(en, it),
|
|
86266
|
+
value: same(value)
|
|
86267
|
+
};
|
|
86268
|
+
}
|
|
86269
|
+
function tilesOf$1(status) {
|
|
86270
|
+
const { supply, return: back, outdoor } = status.temperatures;
|
|
86271
|
+
const left = [];
|
|
86272
|
+
const right = [];
|
|
86273
|
+
if (supply !== null) left.push(tile("Supply", "Mandata", formatDegrees(supply)));
|
|
86274
|
+
if (back !== null) left.push(tile("Return", "Ritorno", formatDegrees(back)));
|
|
86275
|
+
if (outdoor !== null) right.push(tile("Outdoor", "Esterna", formatDegrees(outdoor)));
|
|
86276
|
+
if (status.waterPressureBar !== null) right.push(tile("Pressure", "Pressione", `${Number(status.waterPressureBar.toFixed(1))} bar`));
|
|
86277
|
+
return {
|
|
86278
|
+
left,
|
|
86279
|
+
right
|
|
86280
|
+
};
|
|
86281
|
+
}
|
|
86282
|
+
function isRunning(status) {
|
|
86283
|
+
const { compressorPct, electricalW } = status.power;
|
|
86284
|
+
if (compressorPct !== null) return compressorPct > 0;
|
|
86285
|
+
if (electricalW !== null) return electricalW > 0;
|
|
86286
|
+
return null;
|
|
86287
|
+
}
|
|
86288
|
+
var HEAT_PUMP_FAMILY_CONTRIBUTIONS = { "heat-pump-status": contribution("heat-pump-status", HeatPumpStatusSchema, (slice) => {
|
|
86289
|
+
if (slice === void 0) return { reading: reading("climate-control", "unknown") };
|
|
86290
|
+
const running = isRunning(slice);
|
|
86291
|
+
const facts = [];
|
|
86292
|
+
if (slice.power.electricalW !== null) facts.push(fact("power", "zap", same(`${Math.round(slice.power.electricalW)} W`)));
|
|
86293
|
+
if (slice.power.compressorPct !== null) facts.push(fact("level", "gauge", t(`Compressor ${Math.round(slice.power.compressorPct)} %`, `Compressore ${Math.round(slice.power.compressorPct)} %`)));
|
|
86294
|
+
const charging = slice.circuits.find((c) => c.active === true);
|
|
86295
|
+
const tiles = tilesOf$1(slice);
|
|
86296
|
+
const pills = powerPills(slice);
|
|
86297
|
+
const rows = [
|
|
86298
|
+
...slice.circuits.map(circuitRow),
|
|
86299
|
+
...pills.length === 0 ? [] : [{
|
|
86300
|
+
id: "heat-pump-power",
|
|
86301
|
+
icon: "zap",
|
|
86302
|
+
status: null,
|
|
86303
|
+
controls: [],
|
|
86304
|
+
pills: [...pills]
|
|
86305
|
+
}],
|
|
86306
|
+
...systemRows(slice)
|
|
86307
|
+
];
|
|
86308
|
+
return {
|
|
86309
|
+
reading: reading("climate-control", running === true ? "running" : running === false ? "idle" : "on"),
|
|
86310
|
+
title: t("Heat pump", "Pompa di calore"),
|
|
86311
|
+
...charging === void 0 ? {} : { caption: t(`${charging.label} · heating`.toUpperCase(), `${charging.label} · in riscaldamento`.toUpperCase()) },
|
|
86312
|
+
facts,
|
|
86313
|
+
...tiles.left.length === 0 && tiles.right.length === 0 ? {} : { tiles },
|
|
86314
|
+
...slice.power.electricalW === null ? {} : { consumption: {
|
|
86315
|
+
priority: 1,
|
|
86316
|
+
slot: {
|
|
86317
|
+
kind: "power",
|
|
86318
|
+
watts: slice.power.electricalW,
|
|
86319
|
+
detail: slice.power.thermalW === null ? [] : [{
|
|
86320
|
+
label: t("Thermal", "Termica"),
|
|
86321
|
+
value: Math.round(slice.power.thermalW),
|
|
86322
|
+
unit: "W"
|
|
86323
|
+
}]
|
|
86324
|
+
}
|
|
86325
|
+
} },
|
|
86326
|
+
rows
|
|
86327
|
+
};
|
|
86328
|
+
}) };
|
|
85369
86329
|
[
|
|
85370
86330
|
...Object.values(ACCESS_FAMILY_CONTRIBUTIONS),
|
|
85371
86331
|
...Object.values(DEVICES_FAMILY_CONTRIBUTIONS),
|
|
85372
86332
|
...Object.values(GROUPS_FAMILY_CONTRIBUTIONS),
|
|
85373
86333
|
...Object.values(ACTUATORS_FAMILY_CONTRIBUTIONS),
|
|
85374
86334
|
...Object.values(SENSORS_FAMILY_CONTRIBUTIONS),
|
|
85375
|
-
...Object.values(CLIMATE_FAMILY_CONTRIBUTIONS)
|
|
86335
|
+
...Object.values(CLIMATE_FAMILY_CONTRIBUTIONS),
|
|
86336
|
+
...Object.values(HEAT_PUMP_FAMILY_CONTRIBUTIONS)
|
|
85376
86337
|
];
|
|
85377
|
-
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.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway;
|
|
86338
|
+
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.HeatPump, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway;
|
|
85378
86339
|
/**
|
|
85379
86340
|
* Who looks like what (D1023). One look per {@link DeviceType}, refined by a
|
|
85380
86341
|
* {@link DeviceRole} where the role changes how the device reads (a leak
|
|
@@ -85764,7 +86725,7 @@ lookOf({
|
|
|
85764
86725
|
({ ...lookOf({
|
|
85765
86726
|
icon: "shield-check",
|
|
85766
86727
|
on: [
|
|
85767
|
-
"
|
|
86728
|
+
"danger",
|
|
85768
86729
|
"glow",
|
|
85769
86730
|
"halo"
|
|
85770
86731
|
],
|
|
@@ -86002,8 +86963,24 @@ lookOf({
|
|
|
86002
86963
|
idle: INFO,
|
|
86003
86964
|
standby: MUTED
|
|
86004
86965
|
});
|
|
86966
|
+
lookOf({
|
|
86967
|
+
icon: "thermometer-sun",
|
|
86968
|
+
on: [
|
|
86969
|
+
"warning",
|
|
86970
|
+
"heat-rise",
|
|
86971
|
+
"rise"
|
|
86972
|
+
],
|
|
86973
|
+
off: MUTED,
|
|
86974
|
+
running: [
|
|
86975
|
+
"warning",
|
|
86976
|
+
"heat-rise",
|
|
86977
|
+
"rise"
|
|
86978
|
+
],
|
|
86979
|
+
idle: INFO,
|
|
86980
|
+
standby: MUTED
|
|
86981
|
+
});
|
|
86005
86982
|
DeviceType.Climate, DeviceType.Thermostat;
|
|
86006
|
-
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.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway;
|
|
86983
|
+
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.HeatPump, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Heater, DeviceType.Dryer, DeviceType.Gateway;
|
|
86007
86984
|
DeviceRole.Siren, DeviceRole.Floodlight, DeviceRole.Spotlight, DeviceRole.PirSensor, DeviceRole.Chime, DeviceRole.Autotrack, DeviceRole.Nightvision, DeviceRole.PrivacyMask, DeviceRole.Doorbell, DeviceRole.CoverBlind, DeviceRole.CoverShutter, DeviceRole.CoverAwning, DeviceRole.CoverCurtain, DeviceRole.CoverGarage, DeviceRole.CoverGate, DeviceRole.CoverDoor, DeviceRole.CoverWindow, DeviceRole.BinaryHelper, DeviceRole.Outlet, DeviceRole.MotionSensor, DeviceRole.ContactSensor, DeviceRole.LeakSensor, DeviceRole.SmokeSensor, DeviceRole.COSensor, DeviceRole.GasSensor, DeviceRole.TamperSensor, DeviceRole.VibrationSensor, DeviceRole.ConnectivitySensor, DeviceRole.SoundSensor, DeviceRole.BinarySensor, DeviceRole.TemperatureSensor, DeviceRole.HumiditySensor, DeviceRole.AmbientLightSensor, DeviceRole.PressureSensor, DeviceRole.WindSensor, DeviceRole.RainSensor, DeviceRole.UvSensor, DeviceRole.SolarRadiationSensor, DeviceRole.SoilMoistureSensor, DeviceRole.PowerSensor, DeviceRole.EnergySensor, DeviceRole.VoltageSensor, DeviceRole.CurrentSensor, DeviceRole.AirQualitySensor, DeviceRole.BatterySensor, DeviceRole.NumericSensor, DeviceRole.EnumSensor, DeviceRole.DateTimeSensor, DeviceRole.GenericSensor, DeviceRole.NumericControl, DeviceRole.SelectControl, DeviceRole.TextControl, DeviceRole.DateTimeControl, DeviceRole.MobilePushNotifier, DeviceRole.MessagingNotifier, DeviceRole.EmailNotifier, DeviceRole.GenericNotifier, DeviceRole.IrTransmitter;
|
|
86008
86985
|
Object.freeze({
|
|
86009
86986
|
"accessories.getStatus": {
|
|
@@ -86384,13 +87361,6 @@ Object.freeze({
|
|
|
86384
87361
|
access: "view",
|
|
86385
87362
|
role: "admin"
|
|
86386
87363
|
},
|
|
86387
|
-
"addonSettings.getIntegrationFormSchema": {
|
|
86388
|
-
capName: "addon-settings",
|
|
86389
|
-
capScope: "system",
|
|
86390
|
-
addonId: null,
|
|
86391
|
-
access: "view",
|
|
86392
|
-
role: "admin"
|
|
86393
|
-
},
|
|
86394
87364
|
"addonSettings.getScopedSettings": {
|
|
86395
87365
|
capName: "addon-settings",
|
|
86396
87366
|
capScope: "system",
|
|
@@ -88176,6 +89146,13 @@ Object.freeze({
|
|
|
88176
89146
|
access: "create",
|
|
88177
89147
|
role: "admin"
|
|
88178
89148
|
},
|
|
89149
|
+
"deviceManager.checkDeviceTemplates": {
|
|
89150
|
+
capName: "device-manager",
|
|
89151
|
+
capScope: "system",
|
|
89152
|
+
addonId: null,
|
|
89153
|
+
access: "view",
|
|
89154
|
+
role: "admin"
|
|
89155
|
+
},
|
|
88179
89156
|
"deviceManager.cleanupDeletedDevicesData": {
|
|
88180
89157
|
capName: "device-manager",
|
|
88181
89158
|
capScope: "system",
|
|
@@ -88575,6 +89552,13 @@ Object.freeze({
|
|
|
88575
89552
|
access: "create",
|
|
88576
89553
|
role: "admin"
|
|
88577
89554
|
},
|
|
89555
|
+
"deviceManager.renderDeviceTemplates": {
|
|
89556
|
+
capName: "device-manager",
|
|
89557
|
+
capScope: "system",
|
|
89558
|
+
addonId: null,
|
|
89559
|
+
access: "view",
|
|
89560
|
+
role: "admin"
|
|
89561
|
+
},
|
|
88578
89562
|
"deviceManager.reportDiscoveryObservations": {
|
|
88579
89563
|
capName: "device-manager",
|
|
88580
89564
|
capScope: "system",
|
|
@@ -89506,6 +90490,111 @@ Object.freeze({
|
|
|
89506
90490
|
access: "view",
|
|
89507
90491
|
role: "viewer"
|
|
89508
90492
|
},
|
|
90493
|
+
"heatPumpControl.setAdditionalHeaterMode": {
|
|
90494
|
+
capName: "heat-pump-control",
|
|
90495
|
+
capScope: "device",
|
|
90496
|
+
addonId: null,
|
|
90497
|
+
access: "create",
|
|
90498
|
+
role: "viewer"
|
|
90499
|
+
},
|
|
90500
|
+
"heatPumpControl.setAwayMode": {
|
|
90501
|
+
capName: "heat-pump-control",
|
|
90502
|
+
capScope: "device",
|
|
90503
|
+
addonId: null,
|
|
90504
|
+
access: "create",
|
|
90505
|
+
role: "viewer"
|
|
90506
|
+
},
|
|
90507
|
+
"heatPumpControl.setCircuitComfortSetpoint": {
|
|
90508
|
+
capName: "heat-pump-control",
|
|
90509
|
+
capScope: "device",
|
|
90510
|
+
addonId: null,
|
|
90511
|
+
access: "create",
|
|
90512
|
+
role: "viewer"
|
|
90513
|
+
},
|
|
90514
|
+
"heatPumpControl.setCircuitEcoSetpoint": {
|
|
90515
|
+
capName: "heat-pump-control",
|
|
90516
|
+
capScope: "device",
|
|
90517
|
+
addonId: null,
|
|
90518
|
+
access: "create",
|
|
90519
|
+
role: "viewer"
|
|
90520
|
+
},
|
|
90521
|
+
"heatPumpControl.setCircuitHeatCoolMode": {
|
|
90522
|
+
capName: "heat-pump-control",
|
|
90523
|
+
capScope: "device",
|
|
90524
|
+
addonId: null,
|
|
90525
|
+
access: "create",
|
|
90526
|
+
role: "viewer"
|
|
90527
|
+
},
|
|
90528
|
+
"heatPumpControl.setCircuitMaxFlowTemp": {
|
|
90529
|
+
capName: "heat-pump-control",
|
|
90530
|
+
capScope: "device",
|
|
90531
|
+
addonId: null,
|
|
90532
|
+
access: "create",
|
|
90533
|
+
role: "viewer"
|
|
90534
|
+
},
|
|
90535
|
+
"heatPumpControl.setCircuitOperationMode": {
|
|
90536
|
+
capName: "heat-pump-control",
|
|
90537
|
+
capScope: "device",
|
|
90538
|
+
addonId: null,
|
|
90539
|
+
access: "create",
|
|
90540
|
+
role: "viewer"
|
|
90541
|
+
},
|
|
90542
|
+
"heatPumpControl.setCircuitSummerWinter": {
|
|
90543
|
+
capName: "heat-pump-control",
|
|
90544
|
+
capScope: "device",
|
|
90545
|
+
addonId: null,
|
|
90546
|
+
access: "create",
|
|
90547
|
+
role: "viewer"
|
|
90548
|
+
},
|
|
90549
|
+
"heatPumpControl.setDhwChargeDuration": {
|
|
90550
|
+
capName: "heat-pump-control",
|
|
90551
|
+
capScope: "device",
|
|
90552
|
+
addonId: null,
|
|
90553
|
+
access: "create",
|
|
90554
|
+
role: "viewer"
|
|
90555
|
+
},
|
|
90556
|
+
"heatPumpControl.setDhwOperationMode": {
|
|
90557
|
+
capName: "heat-pump-control",
|
|
90558
|
+
capScope: "device",
|
|
90559
|
+
addonId: null,
|
|
90560
|
+
access: "create",
|
|
90561
|
+
role: "viewer"
|
|
90562
|
+
},
|
|
90563
|
+
"heatPumpControl.setDhwTemperatureLevel": {
|
|
90564
|
+
capName: "heat-pump-control",
|
|
90565
|
+
capScope: "device",
|
|
90566
|
+
addonId: null,
|
|
90567
|
+
access: "create",
|
|
90568
|
+
role: "viewer"
|
|
90569
|
+
},
|
|
90570
|
+
"heatPumpControl.setHolidayMode": {
|
|
90571
|
+
capName: "heat-pump-control",
|
|
90572
|
+
capScope: "device",
|
|
90573
|
+
addonId: null,
|
|
90574
|
+
access: "create",
|
|
90575
|
+
role: "viewer"
|
|
90576
|
+
},
|
|
90577
|
+
"heatPumpControl.setSilentMode": {
|
|
90578
|
+
capName: "heat-pump-control",
|
|
90579
|
+
capScope: "device",
|
|
90580
|
+
addonId: null,
|
|
90581
|
+
access: "create",
|
|
90582
|
+
role: "viewer"
|
|
90583
|
+
},
|
|
90584
|
+
"heatPumpControl.startExtraHotWater": {
|
|
90585
|
+
capName: "heat-pump-control",
|
|
90586
|
+
capScope: "device",
|
|
90587
|
+
addonId: null,
|
|
90588
|
+
access: "create",
|
|
90589
|
+
role: "viewer"
|
|
90590
|
+
},
|
|
90591
|
+
"heatPumpStatus.getStatus": {
|
|
90592
|
+
capName: "heat-pump-status",
|
|
90593
|
+
capScope: "device",
|
|
90594
|
+
addonId: null,
|
|
90595
|
+
access: "view",
|
|
90596
|
+
role: "viewer"
|
|
90597
|
+
},
|
|
89509
90598
|
"heroLayout.getHeroModel": {
|
|
89510
90599
|
capName: "hero-layout",
|
|
89511
90600
|
capScope: "system",
|
|
@@ -94413,13 +95502,6 @@ Object.freeze({
|
|
|
94413
95502
|
access: "create",
|
|
94414
95503
|
role: "admin"
|
|
94415
95504
|
},
|
|
94416
|
-
"smtpProvider.verify": {
|
|
94417
|
-
capName: "smtp-provider",
|
|
94418
|
-
capScope: "system",
|
|
94419
|
-
addonId: null,
|
|
94420
|
-
access: "view",
|
|
94421
|
-
role: "admin"
|
|
94422
|
-
},
|
|
94423
95505
|
"snapshot.applyDeviceSettingsPatch": {
|
|
94424
95506
|
capName: "snapshot",
|
|
94425
95507
|
capScope: "device",
|
|
@@ -96352,7 +97434,7 @@ function projectAction(cap, action) {
|
|
|
96352
97434
|
};
|
|
96353
97435
|
}
|
|
96354
97436
|
Object.entries(CAP_VOCABULARY_BY_NAME).flatMap(([cap, entry]) => entry.scope === "device" ? (entry.actions ?? []).map((a) => projectAction(cap, a)) : []);
|
|
96355
|
-
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.PetFountain, DeviceType.Heater, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Gateway;
|
|
97437
|
+
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.HeatPump, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Heater, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Gateway;
|
|
96356
97438
|
DeviceFeature.BatteryOperated;
|
|
96357
97439
|
DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher;
|
|
96358
97440
|
var HA_AS = "a power sensor (device_class power). Home Assistant has no laundry domain. running-state stays unexported until a null reading can be published as unavailable.";
|
|
@@ -96393,7 +97475,6 @@ function offered(received) {
|
|
|
96393
97475
|
};
|
|
96394
97476
|
}
|
|
96395
97477
|
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
96396
|
-
string().min(1).max(4096);
|
|
96397
97478
|
Object.freeze({
|
|
96398
97479
|
"accessories.getStatus": [{
|
|
96399
97480
|
name: "deviceId",
|
|
@@ -97476,6 +98557,81 @@ Object.freeze({
|
|
|
97476
98557
|
form: "single",
|
|
97477
98558
|
optional: false
|
|
97478
98559
|
}],
|
|
98560
|
+
"heatPumpControl.setAdditionalHeaterMode": [{
|
|
98561
|
+
name: "deviceId",
|
|
98562
|
+
form: "single",
|
|
98563
|
+
optional: false
|
|
98564
|
+
}],
|
|
98565
|
+
"heatPumpControl.setAwayMode": [{
|
|
98566
|
+
name: "deviceId",
|
|
98567
|
+
form: "single",
|
|
98568
|
+
optional: false
|
|
98569
|
+
}],
|
|
98570
|
+
"heatPumpControl.setCircuitComfortSetpoint": [{
|
|
98571
|
+
name: "deviceId",
|
|
98572
|
+
form: "single",
|
|
98573
|
+
optional: false
|
|
98574
|
+
}],
|
|
98575
|
+
"heatPumpControl.setCircuitEcoSetpoint": [{
|
|
98576
|
+
name: "deviceId",
|
|
98577
|
+
form: "single",
|
|
98578
|
+
optional: false
|
|
98579
|
+
}],
|
|
98580
|
+
"heatPumpControl.setCircuitHeatCoolMode": [{
|
|
98581
|
+
name: "deviceId",
|
|
98582
|
+
form: "single",
|
|
98583
|
+
optional: false
|
|
98584
|
+
}],
|
|
98585
|
+
"heatPumpControl.setCircuitMaxFlowTemp": [{
|
|
98586
|
+
name: "deviceId",
|
|
98587
|
+
form: "single",
|
|
98588
|
+
optional: false
|
|
98589
|
+
}],
|
|
98590
|
+
"heatPumpControl.setCircuitOperationMode": [{
|
|
98591
|
+
name: "deviceId",
|
|
98592
|
+
form: "single",
|
|
98593
|
+
optional: false
|
|
98594
|
+
}],
|
|
98595
|
+
"heatPumpControl.setCircuitSummerWinter": [{
|
|
98596
|
+
name: "deviceId",
|
|
98597
|
+
form: "single",
|
|
98598
|
+
optional: false
|
|
98599
|
+
}],
|
|
98600
|
+
"heatPumpControl.setDhwChargeDuration": [{
|
|
98601
|
+
name: "deviceId",
|
|
98602
|
+
form: "single",
|
|
98603
|
+
optional: false
|
|
98604
|
+
}],
|
|
98605
|
+
"heatPumpControl.setDhwOperationMode": [{
|
|
98606
|
+
name: "deviceId",
|
|
98607
|
+
form: "single",
|
|
98608
|
+
optional: false
|
|
98609
|
+
}],
|
|
98610
|
+
"heatPumpControl.setDhwTemperatureLevel": [{
|
|
98611
|
+
name: "deviceId",
|
|
98612
|
+
form: "single",
|
|
98613
|
+
optional: false
|
|
98614
|
+
}],
|
|
98615
|
+
"heatPumpControl.setHolidayMode": [{
|
|
98616
|
+
name: "deviceId",
|
|
98617
|
+
form: "single",
|
|
98618
|
+
optional: false
|
|
98619
|
+
}],
|
|
98620
|
+
"heatPumpControl.setSilentMode": [{
|
|
98621
|
+
name: "deviceId",
|
|
98622
|
+
form: "single",
|
|
98623
|
+
optional: false
|
|
98624
|
+
}],
|
|
98625
|
+
"heatPumpControl.startExtraHotWater": [{
|
|
98626
|
+
name: "deviceId",
|
|
98627
|
+
form: "single",
|
|
98628
|
+
optional: false
|
|
98629
|
+
}],
|
|
98630
|
+
"heatPumpStatus.getStatus": [{
|
|
98631
|
+
name: "deviceId",
|
|
98632
|
+
form: "single",
|
|
98633
|
+
optional: false
|
|
98634
|
+
}],
|
|
97479
98635
|
"heroLayout.getHeroModel": [{
|
|
97480
98636
|
name: "deviceId",
|
|
97481
98637
|
form: "single",
|
|
@@ -101117,6 +102273,18 @@ Object.defineProperty(exports, "eventEmitterCapability", {
|
|
|
101117
102273
|
return eventEmitterCapability;
|
|
101118
102274
|
}
|
|
101119
102275
|
});
|
|
102276
|
+
Object.defineProperty(exports, "heatPumpControlCapability", {
|
|
102277
|
+
enumerable: true,
|
|
102278
|
+
get: function() {
|
|
102279
|
+
return heatPumpControlCapability;
|
|
102280
|
+
}
|
|
102281
|
+
});
|
|
102282
|
+
Object.defineProperty(exports, "heatPumpStatusCapability", {
|
|
102283
|
+
enumerable: true,
|
|
102284
|
+
get: function() {
|
|
102285
|
+
return heatPumpStatusCapability;
|
|
102286
|
+
}
|
|
102287
|
+
});
|
|
101120
102288
|
Object.defineProperty(exports, "heatingValveCapability", {
|
|
101121
102289
|
enumerable: true,
|
|
101122
102290
|
get: function() {
|