@camstack/addon-provider-bosch 0.1.45 → 0.1.47
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-DAEciV_Q.mjs → account-integration-offline-Bie4aS5e.mjs} +1 -1
- package/dist/{account-integration-offline-BiXbzZsg.js → account-integration-offline-C6tzFB-H.js} +1 -1
- package/dist/{bosch-instances-DdklwoKS.js → bosch-instances-D0eF-Jjy.js} +181 -30
- package/dist/{bosch-instances-DXID-jMD.mjs → bosch-instances-DAqkAsRO.mjs} +181 -30
- package/dist/home-connect/addon.js +2 -2
- package/dist/home-connect/addon.mjs +2 -2
- package/dist/homecom/addon.js +439 -113
- package/dist/homecom/addon.mjs +439 -113
- package/dist/shc/addon.js +1 -1
- package/dist/shc/addon.mjs +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.47] - 2026-11-09
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- A HomeCom gateway with a heat pump is adopted as one heat pump, with a climate child per circuit and a Hot water child; a circuit already adopted on its own stays there
|
|
15
|
+
|
|
16
|
+
## [0.1.46] - 2026-11-09
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- A HomeCom heat pump whose gateway reports only its system modes is now offered for adoption.
|
|
21
|
+
|
|
10
22
|
## [0.1.45] - 2026-11-09
|
|
11
23
|
|
|
12
24
|
### Changed
|
package/dist/{account-integration-offline-DAEciV_Q.mjs → account-integration-offline-Bie4aS5e.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { X as errMsg } from "./bosch-instances-
|
|
1
|
+
import { X as errMsg } from "./bosch-instances-DAqkAsRO.mjs";
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
3
|
//#region src/shared/sign-in-redirects.ts
|
|
4
4
|
/** The addresses each vendor sends the browser to after a sign-in; no browser can open them. Kept free of imports so the form schema can name them. */
|
package/dist/{account-integration-offline-BiXbzZsg.js → account-integration-offline-C6tzFB-H.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_bosch_instances = require("./bosch-instances-
|
|
1
|
+
const require_bosch_instances = require("./bosch-instances-D0eF-Jjy.js");
|
|
2
2
|
let node_crypto = require("node:crypto");
|
|
3
3
|
//#region src/shared/sign-in-redirects.ts
|
|
4
4
|
/** The addresses each vendor sends the browser to after a sign-in; no browser can open them. Kept free of imports so the form schema can name them. */
|
|
@@ -802,7 +802,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
802
802
|
return EventCategory;
|
|
803
803
|
}({});
|
|
804
804
|
//#endregion
|
|
805
|
-
//#region ../types/dist/
|
|
805
|
+
//#region ../types/dist/composed-stable-id-DLcPInGv.mjs
|
|
806
806
|
/**
|
|
807
807
|
import { errMsg } from '@camstack/types'
|
|
808
808
|
* Extract a human-readable message from an unknown error value.
|
|
@@ -1204,6 +1204,12 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
1204
1204
|
DeviceRole["IrTransmitter"] = "ir-transmitter";
|
|
1205
1205
|
return DeviceRole;
|
|
1206
1206
|
}({});
|
|
1207
|
+
/**
|
|
1208
|
+
* A composed device's stableId is this prefix plus the block id. Its own module,
|
|
1209
|
+
* free of zod, so the addon runner can read it through `@camstack/types/addon`
|
|
1210
|
+
* without loading the schema barrel (D28).
|
|
1211
|
+
*/
|
|
1212
|
+
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
1207
1213
|
//#endregion
|
|
1208
1214
|
//#region ../../node_modules/zod/v4/core/core.js
|
|
1209
1215
|
var _a$1;
|
|
@@ -6016,7 +6022,7 @@ var ZodIssueCode = {
|
|
|
6016
6022
|
var ZodFirstPartyTypeKind;
|
|
6017
6023
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6018
6024
|
//#endregion
|
|
6019
|
-
//#region ../types/dist/sleep-
|
|
6025
|
+
//#region ../types/dist/sleep-B36hHDDz.mjs
|
|
6020
6026
|
/**
|
|
6021
6027
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6022
6028
|
* window to float samples (D455).
|
|
@@ -17406,7 +17412,7 @@ Object.freeze({
|
|
|
17406
17412
|
}
|
|
17407
17413
|
});
|
|
17408
17414
|
//#endregion
|
|
17409
|
-
//#region ../types/dist/composition-
|
|
17415
|
+
//#region ../types/dist/composition-BFJq1Y88.mjs
|
|
17410
17416
|
/**
|
|
17411
17417
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
17412
17418
|
*
|
|
@@ -18361,8 +18367,6 @@ var HelperSpecSchema = discriminatedUnion("kind", [
|
|
|
18361
18367
|
source: HelperMemberSchema
|
|
18362
18368
|
})
|
|
18363
18369
|
]);
|
|
18364
|
-
/** A composed device's stableId is this prefix plus the block id. */
|
|
18365
|
-
var COMPOSED_DEVICE_STABLE_ID_PREFIX = "composed-";
|
|
18366
18370
|
/** Longest snippet a `code` source may carry (slice 4). */
|
|
18367
18371
|
var MAX_COMPOSITION_CODE_LENGTH = 2e4;
|
|
18368
18372
|
/** One field of one capability of one source device. */
|
|
@@ -44553,21 +44557,44 @@ var AutomationCapStepBaseSchema = object({
|
|
|
44553
44557
|
*/
|
|
44554
44558
|
argUnits: record(string(), string().min(1)).optional()
|
|
44555
44559
|
});
|
|
44556
|
-
|
|
44560
|
+
/**
|
|
44561
|
+
* The steps an internal Action may contain: cap and wait, and nothing that can
|
|
44562
|
+
* call back into an Action — so an Action can never reach itself (no cycles).
|
|
44563
|
+
* This is the LEAF shape: no condition of its own.
|
|
44564
|
+
*/
|
|
44565
|
+
var LeafActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepBaseSchema.refine((step) => step.target !== void 0 || step.deviceId !== void 0, {
|
|
44557
44566
|
message: "a cap step needs a target",
|
|
44558
44567
|
path: ["target"]
|
|
44559
44568
|
}).refine((step) => step.target?.kind !== "domain" || step.actionId !== void 0, {
|
|
44560
44569
|
message: "a domain target needs the vocabulary action it applies to (actionId)",
|
|
44561
44570
|
path: ["actionId"]
|
|
44562
|
-
});
|
|
44571
|
+
})]);
|
|
44563
44572
|
/**
|
|
44564
|
-
* The
|
|
44565
|
-
*
|
|
44573
|
+
* The optional guard of a step (#472): `if` is the ONE `when` tree (D980), read
|
|
44574
|
+
* on the state mirror when the step is reached; `else` runs when it is false.
|
|
44575
|
+
* An `else` holds leaf steps only — the nesting is bounded at ONE level, so a
|
|
44576
|
+
* branch can never grow a tree the trace has to draw.
|
|
44566
44577
|
*/
|
|
44567
|
-
var
|
|
44578
|
+
var stepGuardShape = {
|
|
44579
|
+
if: AutomationWhenSchema.optional(),
|
|
44580
|
+
else: array(LeafActionStepSchema).max(10).optional()
|
|
44581
|
+
};
|
|
44582
|
+
var elseNeedsIf = {
|
|
44583
|
+
message: "an else list needs the condition it is the other side of (if)",
|
|
44584
|
+
path: ["else"]
|
|
44585
|
+
};
|
|
44586
|
+
var GuardedWaitStepSchema = AutomationWaitStepSchema.extend(stepGuardShape).refine((step) => step.else === void 0 || step.if !== void 0, elseNeedsIf);
|
|
44587
|
+
var GuardedCapStepSchema = AutomationCapStepBaseSchema.extend(stepGuardShape).refine((step) => step.target !== void 0 || step.deviceId !== void 0, {
|
|
44588
|
+
message: "a cap step needs a target",
|
|
44589
|
+
path: ["target"]
|
|
44590
|
+
}).refine((step) => step.target?.kind !== "domain" || step.actionId !== void 0, {
|
|
44591
|
+
message: "a domain target needs the vocabulary action it applies to (actionId)",
|
|
44592
|
+
path: ["actionId"]
|
|
44593
|
+
}).refine((step) => step.else === void 0 || step.if !== void 0, elseNeedsIf);
|
|
44594
|
+
var ActionStepSchema = discriminatedUnion("kind", [GuardedWaitStepSchema, GuardedCapStepSchema]);
|
|
44568
44595
|
var AutomationActionSchema = discriminatedUnion("kind", [
|
|
44569
|
-
|
|
44570
|
-
|
|
44596
|
+
GuardedWaitStepSchema,
|
|
44597
|
+
GuardedCapStepSchema,
|
|
44571
44598
|
object({
|
|
44572
44599
|
kind: literal("action"),
|
|
44573
44600
|
/** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
|
|
@@ -44947,7 +44974,7 @@ var StepDeviceTraceSchema = object({
|
|
|
44947
44974
|
outcome: _enum(["ok", "error"]),
|
|
44948
44975
|
message: string().optional()
|
|
44949
44976
|
});
|
|
44950
|
-
var
|
|
44977
|
+
var StepTraceBaseSchema = object({
|
|
44951
44978
|
/** `actions.<i>` */
|
|
44952
44979
|
path: string().min(1),
|
|
44953
44980
|
kind: string().min(1),
|
|
@@ -44966,15 +44993,35 @@ var AutomationStepTraceSchema = object({
|
|
|
44966
44993
|
* is shown as {@link REDACTED_ARG}. Absent on traces written before it existed.
|
|
44967
44994
|
*/
|
|
44968
44995
|
args: record(string(), TraceValueSchema).optional(),
|
|
44969
|
-
/**
|
|
44996
|
+
/**
|
|
44997
|
+
* The device values a templated arg printed as `—`, one `ref: reason` each
|
|
44998
|
+
* (D1021): why a sentence says "—" where a number was expected. Bounded.
|
|
44999
|
+
*/
|
|
45000
|
+
templates: array(string()).max(20).optional(),
|
|
45001
|
+
/**
|
|
45002
|
+
* What the step's own `if` read when the step was reached (#472): `true` the
|
|
45003
|
+
* step ran, `false` its `else` ran (or nothing did), `unknown` a state leaf
|
|
45004
|
+
* could not be read, so NEITHER side ran. Absent on an unguarded step.
|
|
45005
|
+
*/
|
|
45006
|
+
condition: _enum([
|
|
45007
|
+
"true",
|
|
45008
|
+
"false",
|
|
45009
|
+
"unknown"
|
|
45010
|
+
]).optional(),
|
|
45011
|
+
/** Why the condition read what it read, in the evaluator's own words. */
|
|
45012
|
+
conditionReason: string().optional(),
|
|
45013
|
+
/** `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. */
|
|
44970
45014
|
outcome: _enum([
|
|
44971
45015
|
"ok",
|
|
44972
45016
|
"error",
|
|
44973
45017
|
"not-run",
|
|
44974
|
-
"empty"
|
|
45018
|
+
"empty",
|
|
45019
|
+
"skipped"
|
|
44975
45020
|
]),
|
|
44976
45021
|
message: string().optional()
|
|
44977
45022
|
});
|
|
45023
|
+
/** A step trace; the `else` steps that ran are one level of the same shape (the nesting is bounded at one). */
|
|
45024
|
+
var AutomationStepTraceSchema = StepTraceBaseSchema.extend({ else: array(StepTraceBaseSchema).optional() });
|
|
44978
45025
|
var AutomationRunTraceSchema = object({
|
|
44979
45026
|
runId: string().min(1),
|
|
44980
45027
|
startedAt: number$1(),
|
|
@@ -45150,6 +45197,7 @@ _enum([
|
|
|
45150
45197
|
"invalid-variables",
|
|
45151
45198
|
"invalid-steps",
|
|
45152
45199
|
"not-linked",
|
|
45200
|
+
"template-scope",
|
|
45153
45201
|
"busy"
|
|
45154
45202
|
]);
|
|
45155
45203
|
object({
|
|
@@ -52732,6 +52780,43 @@ method(InstancePinSchema, DeviceExportStatusSchema), method(_void(), array(Expor
|
|
|
52732
52780
|
auth: "admin"
|
|
52733
52781
|
});
|
|
52734
52782
|
var DeviceAliasSchema = string().max(64).regex(/^[a-z][a-z0-9_]*$/);
|
|
52783
|
+
var DeviceTemplateSchema = string().min(1).max(4096);
|
|
52784
|
+
var DeviceTemplateRefusalSchema = object({
|
|
52785
|
+
reason: _enum([
|
|
52786
|
+
"too-long",
|
|
52787
|
+
"syntax",
|
|
52788
|
+
"forbidden-syntax",
|
|
52789
|
+
"forbidden-member",
|
|
52790
|
+
"unknown-filter",
|
|
52791
|
+
"ambiguous-field",
|
|
52792
|
+
"busy",
|
|
52793
|
+
"budget-exceeded",
|
|
52794
|
+
"timeout",
|
|
52795
|
+
"output-too-large",
|
|
52796
|
+
"render-failed",
|
|
52797
|
+
"out-of-scope",
|
|
52798
|
+
"unavailable"
|
|
52799
|
+
]),
|
|
52800
|
+
message: string()
|
|
52801
|
+
});
|
|
52802
|
+
var DeviceTemplateTraceEntrySchema = object({
|
|
52803
|
+
ref: string(),
|
|
52804
|
+
reason: _enum([
|
|
52805
|
+
"unknown-alias",
|
|
52806
|
+
"unknown-field",
|
|
52807
|
+
"no-field",
|
|
52808
|
+
"unavailable"
|
|
52809
|
+
])
|
|
52810
|
+
});
|
|
52811
|
+
var DeviceTemplateRenderSchema = discriminatedUnion("ok", [object({
|
|
52812
|
+
ok: literal(true),
|
|
52813
|
+
text: string(),
|
|
52814
|
+
trace: array(DeviceTemplateTraceEntrySchema)
|
|
52815
|
+
}), object({
|
|
52816
|
+
ok: literal(false),
|
|
52817
|
+
refusal: DeviceTemplateRefusalSchema,
|
|
52818
|
+
trace: array(DeviceTemplateTraceEntrySchema)
|
|
52819
|
+
})]);
|
|
52735
52820
|
/**
|
|
52736
52821
|
* A SITE ZONE — a named part of the property that several locations belong to.
|
|
52737
52822
|
*
|
|
@@ -53539,7 +53624,13 @@ method(object({
|
|
|
53539
53624
|
auth: "admin"
|
|
53540
53625
|
}), method(object({ deviceId: number$1() }), record(string(), unknown()), { auth: "admin" }), method(object({ deviceId: number$1() }), record(string(), unknown()), { auth: "admin" }), method(object({ deviceId: number$1() }), DeviceMetaSchema.nullable()), method(object({
|
|
53541
53626
|
deviceId: number$1(),
|
|
53542
|
-
name: string()
|
|
53627
|
+
name: string(),
|
|
53628
|
+
/**
|
|
53629
|
+
* Absent or true: an operator rename, which stamps `userNamed`.
|
|
53630
|
+
* False: the system copying a block name onto the device. That write
|
|
53631
|
+
* must not look like the operator's, or the next reconcile freezes it.
|
|
53632
|
+
*/
|
|
53633
|
+
stampUserNamed: boolean().optional()
|
|
53543
53634
|
}), _void(), {
|
|
53544
53635
|
kind: "mutation",
|
|
53545
53636
|
auth: "admin"
|
|
@@ -53563,6 +53654,22 @@ method(object({
|
|
|
53563
53654
|
kind: "mutation",
|
|
53564
53655
|
auth: "admin"
|
|
53565
53656
|
}), method(object({
|
|
53657
|
+
templates: array(DeviceTemplateSchema).max(64),
|
|
53658
|
+
allowedDeviceIds: array(number$1().int()).optional()
|
|
53659
|
+
}), object({ results: array(DeviceTemplateRenderSchema) }), { auth: "admin" }), method(object({
|
|
53660
|
+
templates: array(string()).max(64),
|
|
53661
|
+
allowedDeviceIds: array(number$1().int()).optional()
|
|
53662
|
+
}), object({ results: array(discriminatedUnion("ok", [object({
|
|
53663
|
+
ok: literal(true),
|
|
53664
|
+
aliases: array(object({
|
|
53665
|
+
alias: string(),
|
|
53666
|
+
deviceId: number$1().int().nullable(),
|
|
53667
|
+
allowed: boolean()
|
|
53668
|
+
}))
|
|
53669
|
+
}), object({
|
|
53670
|
+
ok: literal(false),
|
|
53671
|
+
refusal: DeviceTemplateRefusalSchema
|
|
53672
|
+
})])) }), { auth: "admin" }), method(object({
|
|
53566
53673
|
deviceId: number$1(),
|
|
53567
53674
|
location: string().nullable()
|
|
53568
53675
|
}), _void(), {
|
|
@@ -57531,7 +57638,13 @@ var HeroTimedRunSlotSchema = object({
|
|
|
57531
57638
|
activeUntil: number$1().nullable(),
|
|
57532
57639
|
quickRun: TimedRunQuickRunSchema,
|
|
57533
57640
|
run: HeroActionSchema,
|
|
57534
|
-
cancel: HeroActionSchema
|
|
57641
|
+
cancel: HeroActionSchema,
|
|
57642
|
+
/**
|
|
57643
|
+
* Whole units left (the limit's unit, ceil). `null` while nothing is armed.
|
|
57644
|
+
* A number, not words: the row formats it, and a text here would not fit the
|
|
57645
|
+
* hero-layout declaration.
|
|
57646
|
+
*/
|
|
57647
|
+
remaining: number$1().nullable()
|
|
57535
57648
|
});
|
|
57536
57649
|
var HeroPowerSupplySlotSchema = object({
|
|
57537
57650
|
/** The plug's state; `null` = unknown, never off. */
|
|
@@ -57650,18 +57763,31 @@ var HeroModelSchema = object({
|
|
|
57650
57763
|
* 4. a trailing fact (power, else battery, else consumables).
|
|
57651
57764
|
*
|
|
57652
57765
|
* Selection rules, all taken from the model:
|
|
57653
|
-
* -
|
|
57766
|
+
* - the primary control is the device's own power; else the FIRST control of
|
|
57654
57767
|
* the FIRST row that has any (a later row's control is never promoted). When
|
|
57655
57768
|
* the model lists that part in `gated`, the row has no inline control: the
|
|
57656
57769
|
* projection never falls through to another control the caller could use.
|
|
57770
|
+
* - a timed run, when the model carries the slot, sits beside that primary:
|
|
57771
|
+
* Run while idle, Stop while armed. Gating the slot hides the control.
|
|
57657
57772
|
* - the status line is the head (what plays, else the state) plus at most
|
|
57658
|
-
* {@link ROW_STATUS_FACTS_MAX} facts, the trailing fact excluded
|
|
57773
|
+
* {@link ROW_STATUS_FACTS_MAX} facts, the trailing fact excluded, then the
|
|
57774
|
+
* time left on an armed timed run;
|
|
57659
57775
|
* - the trailing fact is the first of power, battery, consumables.
|
|
57660
57776
|
*
|
|
57661
57777
|
* `projectDeviceRow` is pure and computes nothing: it selects from a
|
|
57662
57778
|
* {@link HeroModel}. A row that needed a value the hero lacks would mean the
|
|
57663
57779
|
* model is missing it, so the fix goes in the model.
|
|
57664
57780
|
*/
|
|
57781
|
+
/**
|
|
57782
|
+
* The row's timed-run control. `id` is `timed-run.run` while idle and
|
|
57783
|
+
* `timed-run.cancel` while armed; `duration` and `unit` are the one-tap run
|
|
57784
|
+
* a Run press starts.
|
|
57785
|
+
*/
|
|
57786
|
+
var HeroRowTimedRunSchema = object({
|
|
57787
|
+
id: _enum(["timed-run.run", "timed-run.cancel"]),
|
|
57788
|
+
duration: number$1(),
|
|
57789
|
+
unit: _enum(["min", "s"])
|
|
57790
|
+
});
|
|
57665
57791
|
var HeroRowModelSchema = object({
|
|
57666
57792
|
deviceId: number$1().int(),
|
|
57667
57793
|
name: string(),
|
|
@@ -57674,6 +57800,11 @@ var HeroRowModelSchema = object({
|
|
|
57674
57800
|
statusLine: array(HeroTextSchema),
|
|
57675
57801
|
/** `null` = the type has no inline control, or the caller may not act on it. */
|
|
57676
57802
|
primary: HeroControlSchema.nullable(),
|
|
57803
|
+
/**
|
|
57804
|
+
* Beside `primary` when the device offers a timed run: Run while idle, Stop
|
|
57805
|
+
* while armed. `null` when there is no slot, or the caller may not act.
|
|
57806
|
+
*/
|
|
57807
|
+
timedRun: HeroRowTimedRunSchema.nullable(),
|
|
57677
57808
|
trailing: HeroFactSchema.nullable()
|
|
57678
57809
|
});
|
|
57679
57810
|
/**
|
|
@@ -84214,6 +84345,7 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
84214
84345
|
return toDeviceSummary(device, this.addonId);
|
|
84215
84346
|
}
|
|
84216
84347
|
};
|
|
84348
|
+
DeviceType.HeatPump;
|
|
84217
84349
|
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;
|
|
84218
84350
|
new Set(Object.values(DeviceType));
|
|
84219
84351
|
/** Parses the raw slice with the cap's own schema; `undefined` when it does not parse. */
|
|
@@ -85960,7 +86092,7 @@ var CLIMATE_FAMILY_CONTRIBUTIONS = {
|
|
|
85960
86092
|
/**
|
|
85961
86093
|
* The heat pump's contribution to a hero (D1026): the compressor scene, every
|
|
85962
86094
|
* circuit as a row with its own label and icon, the powers as pills (the
|
|
85963
|
-
* instantaneous COP
|
|
86095
|
+
* instantaneous COP is "—" when it cannot be computed) and a "System" group with
|
|
85964
86096
|
* one selector per mode. Values and their limits come from the slice, which the
|
|
85965
86097
|
* gateway filled: a selector with no allowed value is not drawn, a missing
|
|
85966
86098
|
* reading is never a 0 (D393).
|
|
@@ -86032,9 +86164,22 @@ function circuitRow(circuit) {
|
|
|
86032
86164
|
};
|
|
86033
86165
|
}
|
|
86034
86166
|
var kilowatts = (watts) => `${Number((watts / 1e3).toFixed(2))} kW`;
|
|
86167
|
+
/** A COP that cannot be computed is still the pill: "—", never an absent reading (D393). */
|
|
86168
|
+
function copPill(cop) {
|
|
86169
|
+
if (cop === null) return {
|
|
86170
|
+
icon: "gauge",
|
|
86171
|
+
text: t("Instantaneous COP —", "COP istantaneo —"),
|
|
86172
|
+
tone: "muted"
|
|
86173
|
+
};
|
|
86174
|
+
const text = String(Number(cop.toFixed(1)));
|
|
86175
|
+
return {
|
|
86176
|
+
icon: "gauge",
|
|
86177
|
+
text: t(`Instantaneous COP ${text}`, `COP istantaneo ${text}`),
|
|
86178
|
+
tone: "success"
|
|
86179
|
+
};
|
|
86180
|
+
}
|
|
86035
86181
|
function powerPills(status) {
|
|
86036
86182
|
const { thermalW, electricalW } = status.power;
|
|
86037
|
-
const cop = heatPumpInstantCop(status.power);
|
|
86038
86183
|
const pills = [];
|
|
86039
86184
|
if (thermalW !== null) pills.push({
|
|
86040
86185
|
icon: "flame",
|
|
@@ -86046,14 +86191,7 @@ function powerPills(status) {
|
|
|
86046
86191
|
text: t(`Electrical ${kilowatts(electricalW)}`, `Elettrica ${kilowatts(electricalW)}`),
|
|
86047
86192
|
tone: "muted"
|
|
86048
86193
|
});
|
|
86049
|
-
|
|
86050
|
-
const text = String(Number(cop.toFixed(1)));
|
|
86051
|
-
pills.push({
|
|
86052
|
-
icon: "gauge",
|
|
86053
|
-
text: t(`Instantaneous COP ${text}`, `COP istantaneo ${text}`),
|
|
86054
|
-
tone: "success"
|
|
86055
|
-
});
|
|
86056
|
-
}
|
|
86194
|
+
pills.push(copPill(heatPumpInstantCop(status.power)));
|
|
86057
86195
|
return pills;
|
|
86058
86196
|
}
|
|
86059
86197
|
/** The independent system modes, in the order the card draws them. */
|
|
@@ -89025,6 +89163,13 @@ Object.freeze({
|
|
|
89025
89163
|
access: "create",
|
|
89026
89164
|
role: "admin"
|
|
89027
89165
|
},
|
|
89166
|
+
"deviceManager.checkDeviceTemplates": {
|
|
89167
|
+
capName: "device-manager",
|
|
89168
|
+
capScope: "system",
|
|
89169
|
+
addonId: null,
|
|
89170
|
+
access: "view",
|
|
89171
|
+
role: "admin"
|
|
89172
|
+
},
|
|
89028
89173
|
"deviceManager.cleanupDeletedDevicesData": {
|
|
89029
89174
|
capName: "device-manager",
|
|
89030
89175
|
capScope: "system",
|
|
@@ -89424,6 +89569,13 @@ Object.freeze({
|
|
|
89424
89569
|
access: "create",
|
|
89425
89570
|
role: "admin"
|
|
89426
89571
|
},
|
|
89572
|
+
"deviceManager.renderDeviceTemplates": {
|
|
89573
|
+
capName: "device-manager",
|
|
89574
|
+
capScope: "system",
|
|
89575
|
+
addonId: null,
|
|
89576
|
+
access: "view",
|
|
89577
|
+
role: "admin"
|
|
89578
|
+
},
|
|
89427
89579
|
"deviceManager.reportDiscoveryObservations": {
|
|
89428
89580
|
capName: "device-manager",
|
|
89429
89581
|
capScope: "system",
|
|
@@ -97340,7 +97492,6 @@ function offered(received) {
|
|
|
97340
97492
|
};
|
|
97341
97493
|
}
|
|
97342
97494
|
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
97343
|
-
string().min(1).max(4096);
|
|
97344
97495
|
Object.freeze({
|
|
97345
97496
|
"accessories.getStatus": [{
|
|
97346
97497
|
name: "deviceId",
|