@camstack/addon-provider-enpal 0.1.20 → 0.1.22
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 +14 -0
- package/assets/icon.png +0 -0
- package/dist/addon.js +355 -99
- package/dist/addon.mjs +355 -99
- package/i18n/en.json +3 -1
- package/i18n/it.json +3 -1
- package/package.json +3 -3
- package/assets/icon.svg +0 -8
package/dist/addon.js
CHANGED
|
@@ -815,7 +815,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
815
815
|
return EventCategory;
|
|
816
816
|
}({});
|
|
817
817
|
//#endregion
|
|
818
|
-
//#region ../types/dist/composed-stable-id-
|
|
818
|
+
//#region ../types/dist/composed-stable-id-COP6zOXx.mjs
|
|
819
819
|
/**
|
|
820
820
|
import { errMsg } from '@camstack/types'
|
|
821
821
|
* Extract a human-readable message from an unknown error value.
|
|
@@ -828,8 +828,6 @@ function errMsg(err) {
|
|
|
828
828
|
}
|
|
829
829
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
830
830
|
DeviceType["Camera"] = "camera";
|
|
831
|
-
/** Legacy stored value, read only by the hub-to-integration migrations; no live device carries it. */
|
|
832
|
-
DeviceType["Hub"] = "hub";
|
|
833
831
|
DeviceType["Light"] = "light";
|
|
834
832
|
DeviceType["Siren"] = "siren";
|
|
835
833
|
DeviceType["Switch"] = "switch";
|
|
@@ -6066,7 +6064,7 @@ var ZodIssueCode = {
|
|
|
6066
6064
|
var ZodFirstPartyTypeKind;
|
|
6067
6065
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6068
6066
|
//#endregion
|
|
6069
|
-
//#region ../types/dist/sleep-
|
|
6067
|
+
//#region ../types/dist/sleep-B5XPl2YP.mjs
|
|
6070
6068
|
/**
|
|
6071
6069
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6072
6070
|
* window to float samples (D455).
|
|
@@ -6729,7 +6727,8 @@ async function runAddonMigrations(host, migrations, logger, options = {}) {
|
|
|
6729
6727
|
try {
|
|
6730
6728
|
declaration = await host.declareOwner({
|
|
6731
6729
|
owner,
|
|
6732
|
-
metas: migrations.map((m) => m.meta)
|
|
6730
|
+
metas: migrations.map((m) => m.meta),
|
|
6731
|
+
...options.retired === void 0 ? {} : { retired: [...options.retired] }
|
|
6733
6732
|
});
|
|
6734
6733
|
} catch (err) {
|
|
6735
6734
|
log.error("the migration engine refused or could not take this addon catalogue — none ran", { meta: { error: errMsg(err) } });
|
|
@@ -8722,6 +8721,14 @@ var BaseAddon = class {
|
|
|
8722
8721
|
declareRegistrySwitch(spec) {
|
|
8723
8722
|
this.registrySwitchSpec = spec;
|
|
8724
8723
|
}
|
|
8724
|
+
/**
|
|
8725
|
+
* Ids this addon removed from its catalogue on purpose (`declareRetiredMigrations`): sent with
|
|
8726
|
+
* every declaration so the engine does not read their applied rows as a newer database.
|
|
8727
|
+
*/
|
|
8728
|
+
retiredMigrationIds = [];
|
|
8729
|
+
declareRetiredMigrations(ids) {
|
|
8730
|
+
this.retiredMigrationIds = ids;
|
|
8731
|
+
}
|
|
8725
8732
|
registrySwitchSpec = null;
|
|
8726
8733
|
registrySwitchBound() {
|
|
8727
8734
|
const spec = this.registrySwitchSpec;
|
|
@@ -8745,10 +8752,14 @@ var BaseAddon = class {
|
|
|
8745
8752
|
async runBound(declared, options) {
|
|
8746
8753
|
const added = this.registrySwitchBound();
|
|
8747
8754
|
const migrations = [...declared, ...added];
|
|
8748
|
-
const
|
|
8755
|
+
const widened = options?.only === void 0 || added.length === 0 ? options : {
|
|
8749
8756
|
...options,
|
|
8750
8757
|
only: [...options.only, ...added.map((m) => m.meta.id)]
|
|
8751
8758
|
};
|
|
8759
|
+
const phased = this.retiredMigrationIds.length === 0 ? widened ?? {} : {
|
|
8760
|
+
...widened,
|
|
8761
|
+
retired: this.retiredMigrationIds
|
|
8762
|
+
};
|
|
8752
8763
|
const api = this.ctx.api.migrations;
|
|
8753
8764
|
const report = await runAddonMigrations({
|
|
8754
8765
|
declareOwner: (input) => api.declareOwner.mutate(input),
|
|
@@ -10377,6 +10388,8 @@ var READING_QUANTITIES = [
|
|
|
10377
10388
|
"information",
|
|
10378
10389
|
"sound-level",
|
|
10379
10390
|
"signal-level",
|
|
10391
|
+
"signal-ratio",
|
|
10392
|
+
"frequency",
|
|
10380
10393
|
"colour-temperature",
|
|
10381
10394
|
"angle",
|
|
10382
10395
|
"bitrate",
|
|
@@ -10420,6 +10433,8 @@ var QUANTITY_BASE = {
|
|
|
10420
10433
|
information: "B",
|
|
10421
10434
|
"sound-level": "dBFS",
|
|
10422
10435
|
"signal-level": "dBm",
|
|
10436
|
+
"signal-ratio": "dB",
|
|
10437
|
+
frequency: "Hz",
|
|
10423
10438
|
"colour-temperature": "mired",
|
|
10424
10439
|
angle: "°",
|
|
10425
10440
|
bitrate: "kbps",
|
|
@@ -10772,41 +10787,57 @@ var CAP_VOCABULARY_BY_NAME = {
|
|
|
10772
10787
|
en: "Switch",
|
|
10773
10788
|
it: "Interruttore"
|
|
10774
10789
|
},
|
|
10775
|
-
actions: [
|
|
10776
|
-
|
|
10777
|
-
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
10782
|
-
|
|
10783
|
-
|
|
10784
|
-
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
|
|
10789
|
-
|
|
10790
|
-
|
|
10791
|
-
|
|
10792
|
-
|
|
10793
|
-
id: "switch.off",
|
|
10794
|
-
method: "setState",
|
|
10795
|
-
label: {
|
|
10796
|
-
en: "Turn off",
|
|
10797
|
-
it: "Spegni"
|
|
10790
|
+
actions: [
|
|
10791
|
+
{
|
|
10792
|
+
id: "switch.on",
|
|
10793
|
+
method: "setState",
|
|
10794
|
+
label: {
|
|
10795
|
+
en: "Turn on",
|
|
10796
|
+
it: "Accendi"
|
|
10797
|
+
},
|
|
10798
|
+
phrase: {
|
|
10799
|
+
en: "Turn on {device}",
|
|
10800
|
+
it: "Accendi {device}"
|
|
10801
|
+
},
|
|
10802
|
+
icon: "power",
|
|
10803
|
+
args: { on: true },
|
|
10804
|
+
effect: {
|
|
10805
|
+
field: "on",
|
|
10806
|
+
value: true
|
|
10807
|
+
}
|
|
10798
10808
|
},
|
|
10799
|
-
|
|
10800
|
-
|
|
10801
|
-
|
|
10809
|
+
{
|
|
10810
|
+
id: "switch.off",
|
|
10811
|
+
method: "setState",
|
|
10812
|
+
label: {
|
|
10813
|
+
en: "Turn off",
|
|
10814
|
+
it: "Spegni"
|
|
10815
|
+
},
|
|
10816
|
+
phrase: {
|
|
10817
|
+
en: "Turn off {device}",
|
|
10818
|
+
it: "Spegni {device}"
|
|
10819
|
+
},
|
|
10820
|
+
icon: "power-off",
|
|
10821
|
+
args: { on: false },
|
|
10822
|
+
effect: {
|
|
10823
|
+
field: "on",
|
|
10824
|
+
value: false
|
|
10825
|
+
}
|
|
10802
10826
|
},
|
|
10803
|
-
|
|
10804
|
-
|
|
10805
|
-
|
|
10806
|
-
|
|
10807
|
-
|
|
10827
|
+
{
|
|
10828
|
+
id: "switch.toggle",
|
|
10829
|
+
method: "toggle",
|
|
10830
|
+
label: {
|
|
10831
|
+
en: "Toggle",
|
|
10832
|
+
it: "Commuta"
|
|
10833
|
+
},
|
|
10834
|
+
phrase: {
|
|
10835
|
+
en: "Toggle {device}",
|
|
10836
|
+
it: "Commuta {device}"
|
|
10837
|
+
},
|
|
10838
|
+
icon: "toggle-right"
|
|
10808
10839
|
}
|
|
10809
|
-
|
|
10840
|
+
],
|
|
10810
10841
|
state: [{
|
|
10811
10842
|
kind: "boolean",
|
|
10812
10843
|
field: "on",
|
|
@@ -20339,6 +20370,10 @@ Object.freeze({
|
|
|
20339
20370
|
{
|
|
20340
20371
|
"path": "storage.dischargedTodayKwh",
|
|
20341
20372
|
"valueType": "number"
|
|
20373
|
+
},
|
|
20374
|
+
{
|
|
20375
|
+
"path": "storage.healthPct",
|
|
20376
|
+
"valueType": "number"
|
|
20342
20377
|
}
|
|
20343
20378
|
],
|
|
20344
20379
|
"enum-sensor": [{
|
|
@@ -20719,6 +20754,10 @@ Object.freeze({
|
|
|
20719
20754
|
"path": "isMuted",
|
|
20720
20755
|
"valueType": "boolean"
|
|
20721
20756
|
},
|
|
20757
|
+
{
|
|
20758
|
+
"path": "muteReadback",
|
|
20759
|
+
"valueType": "boolean"
|
|
20760
|
+
},
|
|
20722
20761
|
{
|
|
20723
20762
|
"path": "source",
|
|
20724
20763
|
"valueType": "string"
|
|
@@ -21655,7 +21694,7 @@ Object.freeze({
|
|
|
21655
21694
|
}
|
|
21656
21695
|
});
|
|
21657
21696
|
//#endregion
|
|
21658
|
-
//#region ../types/dist/implemented-methods-
|
|
21697
|
+
//#region ../types/dist/implemented-methods-0xxMOekw.mjs
|
|
21659
21698
|
/**
|
|
21660
21699
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
21661
21700
|
*
|
|
@@ -22839,7 +22878,7 @@ var NodeColorIdSchema = _enum([
|
|
|
22839
22878
|
"node-h"
|
|
22840
22879
|
]);
|
|
22841
22880
|
//#endregion
|
|
22842
|
-
//#region ../types/dist/convert-
|
|
22881
|
+
//#region ../types/dist/convert-BwMfbk5b.mjs
|
|
22843
22882
|
/**
|
|
22844
22883
|
* Frozen unit → spec table. `•` in the doc marks each dimension's canonical
|
|
22845
22884
|
* unit (`factor: 1, offset: 0`). °F derives from `°C = (°F − 32) × 5/9` ⇒
|
|
@@ -23172,6 +23211,21 @@ var UNIT_TABLE = {
|
|
|
23172
23211
|
factor: 1,
|
|
23173
23212
|
offset: 0
|
|
23174
23213
|
},
|
|
23214
|
+
dB: {
|
|
23215
|
+
dimension: "signal-ratio",
|
|
23216
|
+
factor: 1,
|
|
23217
|
+
offset: 0
|
|
23218
|
+
},
|
|
23219
|
+
Hz: {
|
|
23220
|
+
dimension: "frequency",
|
|
23221
|
+
factor: 1,
|
|
23222
|
+
offset: 0
|
|
23223
|
+
},
|
|
23224
|
+
kHz: {
|
|
23225
|
+
dimension: "frequency",
|
|
23226
|
+
factor: 1e3,
|
|
23227
|
+
offset: 0
|
|
23228
|
+
},
|
|
23175
23229
|
mired: {
|
|
23176
23230
|
dimension: "colour-temperature",
|
|
23177
23231
|
factor: 1,
|
|
@@ -55494,7 +55548,9 @@ var ClusterUpdateFailureReasonSchema = _enum([
|
|
|
55494
55548
|
"status-unreadable",
|
|
55495
55549
|
"addon-update-failed",
|
|
55496
55550
|
"addons-not-converged",
|
|
55497
|
-
"interrupted"
|
|
55551
|
+
"interrupted",
|
|
55552
|
+
"timeout-stall",
|
|
55553
|
+
"timeout-ceiling"
|
|
55498
55554
|
]);
|
|
55499
55555
|
var ClusterUpdateStepSchema = object({
|
|
55500
55556
|
kind: ClusterUpdateStepKindSchema,
|
|
@@ -57061,6 +57117,12 @@ var MediaPlayerStatusSchema = object({
|
|
|
57061
57117
|
/** Mute toggle distinct from volume=0. Null when no mute surface.
|
|
57062
57118
|
* Pair with `DeviceFeature.MediaPlayerMute`. */
|
|
57063
57119
|
isMuted: boolean().nullable(),
|
|
57120
|
+
/**
|
|
57121
|
+
* True only when the provider READS the mute state back from the device.
|
|
57122
|
+
* Absent or false: mute is a momentary key. A non-null `isMuted` is not a
|
|
57123
|
+
* reading on its own — an infrared send can leave a value without this flag.
|
|
57124
|
+
*/
|
|
57125
|
+
muteReadback: boolean().optional(),
|
|
57064
57126
|
/** Active source / input. Empty when no source surface. */
|
|
57065
57127
|
source: string(),
|
|
57066
57128
|
/** Selectable sources. Empty when no source surface.
|
|
@@ -57502,7 +57564,7 @@ var mediaPlayerCapability = {
|
|
|
57502
57564
|
]
|
|
57503
57565
|
}
|
|
57504
57566
|
};
|
|
57505
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Climate, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.
|
|
57567
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Climate, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, 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.Dryer, DeviceType.Gateway, DeviceType.HeatPump, DeviceType.EnergySystem, DeviceType.Camera, DeviceType.Fan, DeviceType.Fan, DeviceType.Fan, DeviceType.Fan, DeviceType.Fan, DeviceType.Fan, DeviceType.Fan, DeviceType.Fan, DeviceType.Fan, DeviceType.Fan, DeviceType.Lock, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Gateway, 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.PetFeeder, DeviceType.MediaPlayer;
|
|
57506
57568
|
var NUMBER$1 = {
|
|
57507
57569
|
kind: "fixed",
|
|
57508
57570
|
result: ["number"]
|
|
@@ -59764,9 +59826,15 @@ var SiteZoneSchema = object({
|
|
|
59764
59826
|
locationKeys: array(string())
|
|
59765
59827
|
});
|
|
59766
59828
|
var DeviceSearchRequiresSchema = object({
|
|
59767
|
-
/** Capability names the field wants a value of. */
|
|
59768
|
-
caps: array(string()).readonly(),
|
|
59769
|
-
/**
|
|
59829
|
+
/** Capability names the field wants a value of. Absent when the field wants actions only. */
|
|
59830
|
+
caps: array(string()).readonly().optional(),
|
|
59831
|
+
/**
|
|
59832
|
+
* Vocabulary action ids (`cover.open`) the device must offer. Compatible means
|
|
59833
|
+
* the device's bindings resolve those actions; `values` stays empty when no
|
|
59834
|
+
* cap was required. `mode` applies the same way as for `caps`.
|
|
59835
|
+
*/
|
|
59836
|
+
actions: array(string()).readonly().optional(),
|
|
59837
|
+
/** `any` (default): one of the named caps, and one of the named actions, is enough. `all`: every one. */
|
|
59770
59838
|
mode: _enum(["any", "all"]).optional()
|
|
59771
59839
|
});
|
|
59772
59840
|
var DeviceSearchFiltersSchema = object({
|
|
@@ -61823,7 +61891,7 @@ var TransitionsStatusSchema = object({
|
|
|
61823
61891
|
/** Refused rows since start, by reason. */
|
|
61824
61892
|
refused: record(string(), number$1())
|
|
61825
61893
|
});
|
|
61826
|
-
Object.values(DeviceType).filter((type) => type !== DeviceType.
|
|
61894
|
+
Object.values(DeviceType).filter((type) => type !== DeviceType.Container), method(object({
|
|
61827
61895
|
deviceId: number$1().int(),
|
|
61828
61896
|
capName: string().optional(),
|
|
61829
61897
|
actorKind: TransitionActorKindSchema.optional(),
|
|
@@ -63117,7 +63185,9 @@ var EnergyStorageSchema = object({
|
|
|
63117
63185
|
/** Lifetime discharged, kWh. */
|
|
63118
63186
|
dischargedKwh: number$1().nullable().meta(readingMeta("energy")),
|
|
63119
63187
|
chargedTodayKwh: number$1().nullable().meta(readingMeta("energy")),
|
|
63120
|
-
dischargedTodayKwh: number$1().nullable().meta(readingMeta("energy"))
|
|
63188
|
+
dischargedTodayKwh: number$1().nullable().meta(readingMeta("energy")),
|
|
63189
|
+
/** State of health, 0..100. Null when the system did not report it. */
|
|
63190
|
+
healthPct: number$1().nullable().meta(readingMeta("percentage"))
|
|
63121
63191
|
});
|
|
63122
63192
|
var EnergySystemStatusSchema = object({
|
|
63123
63193
|
solar: EnergySolarSchema.nullable(),
|
|
@@ -63229,6 +63299,12 @@ var energySystemCapability = {
|
|
|
63229
63299
|
kind: "counter",
|
|
63230
63300
|
unit: "kWh",
|
|
63231
63301
|
displayName: "Storage discharged"
|
|
63302
|
+
},
|
|
63303
|
+
"storage.healthPct": {
|
|
63304
|
+
kind: "gauge",
|
|
63305
|
+
unit: "%",
|
|
63306
|
+
deadband: 1,
|
|
63307
|
+
displayName: "Storage health"
|
|
63232
63308
|
}
|
|
63233
63309
|
} },
|
|
63234
63310
|
volatileStateFields: ["lastFetchedAt"],
|
|
@@ -65762,7 +65838,7 @@ var HeroSceneSchema = object({
|
|
|
65762
65838
|
/** 0..1: volume, cover position, cycle progress. */
|
|
65763
65839
|
level: number$1().min(0).max(1).nullable()
|
|
65764
65840
|
});
|
|
65765
|
-
DeviceType.Camera, DeviceType.
|
|
65841
|
+
DeviceType.Camera, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, 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.EnergySystem, 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.Dryer, DeviceType.Gateway;
|
|
65766
65842
|
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.SwitchHeater, DeviceRole.SwitchFan, DeviceRole.SwitchLight, DeviceRole.ClimateAc, DeviceRole.ClimateThermostat, DeviceRole.ClimateFloor, DeviceRole.ClimateRadiator, DeviceRole.ClimateHeater, DeviceRole.ClimateHeatPumpCircuit, 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;
|
|
65767
65843
|
var HeroRowIdSchema = _enum([
|
|
65768
65844
|
"progress",
|
|
@@ -66123,7 +66199,7 @@ var HeroModelSchema = object({
|
|
|
66123
66199
|
*
|
|
66124
66200
|
* - `extras` are the further inline controls of the types that carry more than one
|
|
66125
66201
|
* ({@link ROW_EXTRAS_BY_TYPE}): climate setpoint, a robot's return to base,
|
|
66126
|
-
* a player's volume and remote. Each is a control the model already has, named by id,
|
|
66202
|
+
* a player's volume and remote, an automation's enabled switch. Each is a control the model already has, named by id,
|
|
66127
66203
|
* in that order and at most {@link ROW_EXTRAS_MAX}; one the model lacks, or lists in
|
|
66128
66204
|
* `gated`, is absent, and the one `primary` already is never repeats. Empty = the
|
|
66129
66205
|
* row of an older server: `primary` alone.
|
|
@@ -66183,7 +66259,7 @@ new Set([
|
|
|
66183
66259
|
"valve"
|
|
66184
66260
|
]);
|
|
66185
66261
|
DeviceType.Climate;
|
|
66186
|
-
DeviceType.Climate, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer;
|
|
66262
|
+
DeviceType.Climate, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.Automation;
|
|
66187
66263
|
/**
|
|
66188
66264
|
* hero-layout — what a device's hero says (D1023). Read-only: the FIXED
|
|
66189
66265
|
* layouts live in `@camstack/types` and nothing here stores or edits one.
|
|
@@ -70518,7 +70594,9 @@ method(object({}), object({ entries: array(MigrationLedgerEntrySchema) }), { aut
|
|
|
70518
70594
|
auth: "admin"
|
|
70519
70595
|
}), method(object({
|
|
70520
70596
|
owner: string().min(1),
|
|
70521
|
-
metas: array(MigrationMetaSchema)
|
|
70597
|
+
metas: array(MigrationMetaSchema),
|
|
70598
|
+
/** Ids the owner deliberately removed: an applied row of one is fine, never "newer". */
|
|
70599
|
+
retired: array(string().min(1)).optional()
|
|
70522
70600
|
}), object({
|
|
70523
70601
|
bootId: string(),
|
|
70524
70602
|
snapshot: _enum([
|
|
@@ -79306,6 +79384,13 @@ var NcHistoryEntrySchema = object({
|
|
|
79306
79384
|
error: string().optional(),
|
|
79307
79385
|
subject: NcHistorySubjectSchema,
|
|
79308
79386
|
/**
|
|
79387
|
+
* The title and body actually sent, frozen at delivery. Absent on a row
|
|
79388
|
+
* still pending, a row suppressed before a notification was built, and a
|
|
79389
|
+
* row delivered before this field shipped.
|
|
79390
|
+
*/
|
|
79391
|
+
title: string().optional(),
|
|
79392
|
+
body: string().optional(),
|
|
79393
|
+
/**
|
|
79309
79394
|
* Ids of the artefacts (still, then gif, then clip) this row's successful
|
|
79310
79395
|
* delivery indexed in the artefact library — a REFERENCE, never the bytes
|
|
79311
79396
|
* (an artefact is often megabytes; this row is durable JSON rewritten on
|
|
@@ -87616,7 +87701,8 @@ var ServerUpdateActionResultSchema = object({
|
|
|
87616
87701
|
outcome: ServerUpdateOutcomeSchema.optional(),
|
|
87617
87702
|
/**
|
|
87618
87703
|
* Stable, greppable cause for `refused` / `failed` (the engine's
|
|
87619
|
-
* `UpdateRefusalReason`, `staging-failed`,
|
|
87704
|
+
* `UpdateRefusalReason`, `staging-failed`, `timeout-stall`,
|
|
87705
|
+
* `timeout-ceiling`). `null` on success.
|
|
87620
87706
|
*/
|
|
87621
87707
|
reason: string().nullable().optional(),
|
|
87622
87708
|
/**
|
|
@@ -87738,6 +87824,14 @@ var smokeCapability = {
|
|
|
87738
87824
|
}]
|
|
87739
87825
|
}
|
|
87740
87826
|
};
|
|
87827
|
+
var EmailImagePartSchema = object({
|
|
87828
|
+
ticket: PeerBytesTicketSchema,
|
|
87829
|
+
mime: string().min(1),
|
|
87830
|
+
name: string().min(1),
|
|
87831
|
+
contentId: string().min(1),
|
|
87832
|
+
placement: _enum(["inline", "attachment"]),
|
|
87833
|
+
deviceId: number$1().int().nonnegative().optional()
|
|
87834
|
+
});
|
|
87741
87835
|
/**
|
|
87742
87836
|
* `smtp-provider` — pluggable email delivery surface.
|
|
87743
87837
|
*
|
|
@@ -87747,8 +87841,8 @@ var smokeCapability = {
|
|
|
87747
87841
|
* ready provider OR target a specific addonId.
|
|
87748
87842
|
*
|
|
87749
87843
|
* The shape stays small on purpose — `sendEmail` is enough for the
|
|
87750
|
-
* 90% case.
|
|
87751
|
-
*
|
|
87844
|
+
* 90% case. An image is not a byte field on this method (D613): `images`
|
|
87845
|
+
* names `peerBytes` tickets the sender opens and folds into one MIME body.
|
|
87752
87846
|
*/
|
|
87753
87847
|
var EmailAddressSchema = email();
|
|
87754
87848
|
/**
|
|
@@ -87775,7 +87869,12 @@ var SendEmailInputSchema = object({
|
|
|
87775
87869
|
* for clients that strip HTML — including most spam filters). */
|
|
87776
87870
|
text: string(),
|
|
87777
87871
|
/** Optional HTML body. Renders alongside `text` as multi-part. */
|
|
87778
|
-
html: string().optional()
|
|
87872
|
+
html: string().optional(),
|
|
87873
|
+
/**
|
|
87874
|
+
* Images the caller already offered over `peerBytes`. Absent = a mail with
|
|
87875
|
+
* no image. The sender opens each ticket; one it cannot read is left out.
|
|
87876
|
+
*/
|
|
87877
|
+
images: array(EmailImagePartSchema).max(3).optional()
|
|
87779
87878
|
});
|
|
87780
87879
|
var SendEmailResultSchema = object({
|
|
87781
87880
|
messageId: string(),
|
|
@@ -88805,34 +88904,46 @@ var switchCapability = {
|
|
|
88805
88904
|
DeviceType.Light,
|
|
88806
88905
|
DeviceType.Fan
|
|
88807
88906
|
],
|
|
88808
|
-
methods: {
|
|
88809
|
-
|
|
88810
|
-
|
|
88811
|
-
|
|
88812
|
-
|
|
88813
|
-
|
|
88814
|
-
|
|
88815
|
-
|
|
88816
|
-
|
|
88817
|
-
|
|
88818
|
-
|
|
88819
|
-
|
|
88820
|
-
|
|
88821
|
-
|
|
88822
|
-
|
|
88823
|
-
|
|
88824
|
-
|
|
88825
|
-
|
|
88826
|
-
|
|
88827
|
-
|
|
88828
|
-
|
|
88829
|
-
|
|
88830
|
-
|
|
88831
|
-
|
|
88832
|
-
|
|
88833
|
-
|
|
88834
|
-
|
|
88835
|
-
|
|
88907
|
+
methods: {
|
|
88908
|
+
setState: method(object({
|
|
88909
|
+
deviceId: number$1(),
|
|
88910
|
+
on: boolean()
|
|
88911
|
+
}), _void(), {
|
|
88912
|
+
kind: "mutation",
|
|
88913
|
+
auth: "protected",
|
|
88914
|
+
actions: [{
|
|
88915
|
+
id: "switch.on",
|
|
88916
|
+
label: t("Turn on", "Accendi"),
|
|
88917
|
+
phrase: t("Turn on {device}", "Accendi {device}"),
|
|
88918
|
+
icon: "power",
|
|
88919
|
+
effect: {
|
|
88920
|
+
field: "on",
|
|
88921
|
+
value: true
|
|
88922
|
+
},
|
|
88923
|
+
args: { on: true }
|
|
88924
|
+
}, {
|
|
88925
|
+
id: "switch.off",
|
|
88926
|
+
label: t("Turn off", "Spegni"),
|
|
88927
|
+
phrase: t("Turn off {device}", "Spegni {device}"),
|
|
88928
|
+
icon: "power-off",
|
|
88929
|
+
effect: {
|
|
88930
|
+
field: "on",
|
|
88931
|
+
value: false
|
|
88932
|
+
},
|
|
88933
|
+
args: { on: false }
|
|
88934
|
+
}]
|
|
88935
|
+
}),
|
|
88936
|
+
toggle: optionalMethod(object({ deviceId: number$1() }), _void(), {
|
|
88937
|
+
kind: "mutation",
|
|
88938
|
+
auth: "protected",
|
|
88939
|
+
actions: [{
|
|
88940
|
+
id: "switch.toggle",
|
|
88941
|
+
label: t("Toggle", "Commuta"),
|
|
88942
|
+
phrase: t("Toggle {device}", "Commuta {device}"),
|
|
88943
|
+
icon: "toggle-right"
|
|
88944
|
+
}]
|
|
88945
|
+
})
|
|
88946
|
+
},
|
|
88836
88947
|
events: { onStateChanged: {
|
|
88837
88948
|
data: object({
|
|
88838
88949
|
deviceId: number$1(),
|
|
@@ -94932,7 +95043,7 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
94932
95043
|
}
|
|
94933
95044
|
};
|
|
94934
95045
|
DeviceType.HeatPump;
|
|
94935
|
-
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.HeatPump, DeviceType.EnergySystem, DeviceType.Camera, DeviceType.
|
|
95046
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.HeatPump, DeviceType.EnergySystem, DeviceType.Camera, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, 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.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Gateway;
|
|
94936
95047
|
new Set(Object.values(DeviceType));
|
|
94937
95048
|
/** Parses the raw slice with the cap's own schema; `undefined` when it does not parse. */
|
|
94938
95049
|
function contribution(cap, schema, build) {
|
|
@@ -96646,7 +96757,11 @@ var temperatureContribution = contribution("temperature-sensor", TemperatureSens
|
|
|
96646
96757
|
var humidityContribution = contribution("humidity-sensor", HumiditySensorStatusSchema, (slice) => measured(sensorFragment(slice?.humidity ?? null, "humidity", "droplets", "Humidity", "Umidità", `${Math.round(slice?.humidity ?? 0)}%`), slice?.humidity == null ? emptyMeasurement("humidity") : humidityMeasurement(slice.humidity, slice.lastFetchedAt)));
|
|
96647
96758
|
var pressureContribution = contribution("pressure-sensor", PressureSensorStatusSchema, (slice) => sensorFragment(slice?.pressure ?? null, "pressure", "gauge", "Pressure", "Pressione", `${Math.round(slice?.pressure ?? 0)} hPa`));
|
|
96648
96759
|
var illuminanceContribution = contribution("ambient-light-sensor", AmbientLightSensorStatusSchema, (slice) => sensorFragment(slice?.illuminance ?? null, "illuminance", "sun", "Light", "Luce", `${Math.round(slice?.illuminance ?? 0)} lx`));
|
|
96649
|
-
var numericContribution = contribution("numeric-sensor", NumericSensorStatusSchema, (slice) =>
|
|
96760
|
+
var numericContribution = contribution("numeric-sensor", NumericSensorStatusSchema, (slice, ctx) => {
|
|
96761
|
+
const unit = ctx.quantity == null ? void 0 : baseUnitOf(ctx.quantity);
|
|
96762
|
+
const text = String(Number((slice?.value ?? 0).toFixed(2)));
|
|
96763
|
+
return sensorFragment(slice?.value ?? null, "reading", "gauge", "Value", "Valore", unit === void 0 ? text : `${text} ${unit}`);
|
|
96764
|
+
});
|
|
96650
96765
|
var enumContribution = contribution("enum-sensor", EnumSensorStatusSchema, (slice) => {
|
|
96651
96766
|
if (slice === void 0 || slice.value === "") return measured({ reading: reading("sensor", "unknown") }, emptyMeasurement("text"));
|
|
96652
96767
|
if (slice.timestamp === true) return { reading: reading("sensor", "on") };
|
|
@@ -96973,7 +97088,7 @@ var HEAT_PUMP_FAMILY_CONTRIBUTIONS = { "heat-pump-status": contribution("heat-pu
|
|
|
96973
97088
|
...Object.values(CLIMATE_FAMILY_CONTRIBUTIONS),
|
|
96974
97089
|
...Object.values(HEAT_PUMP_FAMILY_CONTRIBUTIONS)
|
|
96975
97090
|
];
|
|
96976
|
-
DeviceType.Camera, DeviceType.
|
|
97091
|
+
DeviceType.Camera, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, 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.EnergySystem, 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.Dryer, DeviceType.Gateway;
|
|
96977
97092
|
/**
|
|
96978
97093
|
* Who looks like what (D1023). One look per {@link DeviceType}, refined by a
|
|
96979
97094
|
* {@link DeviceRole} where the role changes how the device reads (a leak
|
|
@@ -97617,7 +97732,7 @@ lookOf({
|
|
|
97617
97732
|
standby: MUTED
|
|
97618
97733
|
});
|
|
97619
97734
|
DeviceType.Climate;
|
|
97620
|
-
DeviceType.Camera, DeviceType.
|
|
97735
|
+
DeviceType.Camera, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, 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.EnergySystem, 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.Dryer, DeviceType.Gateway;
|
|
97621
97736
|
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.SwitchHeater, DeviceRole.SwitchFan, DeviceRole.SwitchLight, DeviceRole.ClimateAc, DeviceRole.ClimateThermostat, DeviceRole.ClimateFloor, DeviceRole.ClimateRadiator, DeviceRole.ClimateHeater, DeviceRole.ClimateHeatPumpCircuit, 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;
|
|
97622
97737
|
Object.freeze({
|
|
97623
97738
|
"accessories.getStatus": {
|
|
@@ -106916,6 +107031,13 @@ Object.freeze({
|
|
|
106916
107031
|
access: "create",
|
|
106917
107032
|
role: "viewer"
|
|
106918
107033
|
},
|
|
107034
|
+
"switch.toggle": {
|
|
107035
|
+
capName: "switch",
|
|
107036
|
+
capScope: "device",
|
|
107037
|
+
addonId: null,
|
|
107038
|
+
access: "create",
|
|
107039
|
+
role: "viewer"
|
|
107040
|
+
},
|
|
106919
107041
|
"system.debugWatch": {
|
|
106920
107042
|
capName: "system",
|
|
106921
107043
|
capScope: "system",
|
|
@@ -108081,7 +108203,7 @@ function offered(received) {
|
|
|
108081
108203
|
};
|
|
108082
108204
|
}
|
|
108083
108205
|
offered(HA_AS), withheld(HOMEKIT_REASON), withheld(ALEXA_REASON), withheld(GOOGLE_REASON), withheld(MATTER_REASON);
|
|
108084
|
-
DeviceType.Camera, DeviceType.
|
|
108206
|
+
DeviceType.Camera, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Climate, DeviceType.HeatPump, DeviceType.EnergySystem, 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.Dryer, DeviceType.Gateway;
|
|
108085
108207
|
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.SwitchHeater, DeviceRole.SwitchFan, DeviceRole.SwitchLight, DeviceRole.ClimateAc, DeviceRole.ClimateThermostat, DeviceRole.ClimateFloor, DeviceRole.ClimateRadiator, DeviceRole.ClimateHeater, DeviceRole.ClimateHeatPumpCircuit, 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;
|
|
108086
108208
|
new Set(Object.values(DeviceType));
|
|
108087
108209
|
new Set(Object.values(DeviceRole));
|
|
@@ -110743,6 +110865,12 @@ Object.freeze({
|
|
|
110743
110865
|
form: "single",
|
|
110744
110866
|
optional: false
|
|
110745
110867
|
}],
|
|
110868
|
+
"smtpProvider.sendEmail": [{
|
|
110869
|
+
name: "images",
|
|
110870
|
+
form: "object-array",
|
|
110871
|
+
optional: true,
|
|
110872
|
+
itemField: "deviceId"
|
|
110873
|
+
}],
|
|
110746
110874
|
"snapshot.applyDeviceSettingsPatch": [{
|
|
110747
110875
|
name: "deviceId",
|
|
110748
110876
|
form: "single",
|
|
@@ -110909,6 +111037,11 @@ Object.freeze({
|
|
|
110909
111037
|
form: "single",
|
|
110910
111038
|
optional: false
|
|
110911
111039
|
}],
|
|
111040
|
+
"switch.toggle": [{
|
|
111041
|
+
name: "deviceId",
|
|
111042
|
+
form: "single",
|
|
111043
|
+
optional: false
|
|
111044
|
+
}],
|
|
110912
111045
|
"system.debugWatch": [{
|
|
110913
111046
|
name: "deviceIds",
|
|
110914
111047
|
form: "array",
|
|
@@ -111772,6 +111905,28 @@ var STATE_SUMMARY_VARS = [
|
|
|
111772
111905
|
systemEventKinds: [...SUMMARISABLE],
|
|
111773
111906
|
systemEventDeliveries: ["summary"]
|
|
111774
111907
|
},
|
|
111908
|
+
{
|
|
111909
|
+
name: "offlineCount",
|
|
111910
|
+
label: "Summary: how many went offline",
|
|
111911
|
+
example: "2",
|
|
111912
|
+
group: "system",
|
|
111913
|
+
families: ["rule"],
|
|
111914
|
+
fields: [...RULE_TEXT],
|
|
111915
|
+
kinds: ["system"],
|
|
111916
|
+
systemEventKinds: [...SUMMARISABLE],
|
|
111917
|
+
systemEventDeliveries: ["summary"]
|
|
111918
|
+
},
|
|
111919
|
+
{
|
|
111920
|
+
name: "onlineCount",
|
|
111921
|
+
label: "Summary: how many came back",
|
|
111922
|
+
example: "5",
|
|
111923
|
+
group: "system",
|
|
111924
|
+
families: ["rule"],
|
|
111925
|
+
fields: [...RULE_TEXT],
|
|
111926
|
+
kinds: ["system"],
|
|
111927
|
+
systemEventKinds: [...SUMMARISABLE],
|
|
111928
|
+
systemEventDeliveries: ["summary"]
|
|
111929
|
+
},
|
|
111775
111930
|
{
|
|
111776
111931
|
name: "summaryCount",
|
|
111777
111932
|
label: "Summary: items reported",
|
|
@@ -111813,6 +111968,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
111813
111968
|
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
111814
111969
|
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
111815
111970
|
[...RULE_TEXT],
|
|
111971
|
+
[...RULE_TEXT],
|
|
111816
111972
|
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
111817
111973
|
([...RULE_TEXT], [...PACKAGE_UPDATES]),
|
|
111818
111974
|
[...RULE_TEXT],
|
|
@@ -112930,6 +113086,21 @@ function toBase(value, unit, quantity) {
|
|
|
112930
113086
|
}
|
|
112931
113087
|
//#endregion
|
|
112932
113088
|
//#region src/enpal-catalog.ts
|
|
113089
|
+
/**
|
|
113090
|
+
* The two meters the box both called "Consumption". English is the device
|
|
113091
|
+
* name (one string, like every other catalog entry); Italian is the addon
|
|
113092
|
+
* catalogue key `catalog.<id>.name`.
|
|
113093
|
+
*/
|
|
113094
|
+
var ENPAL_CONSUMPTION_NAMES = {
|
|
113095
|
+
house: {
|
|
113096
|
+
en: "House consumption",
|
|
113097
|
+
it: "Consumo casa"
|
|
113098
|
+
},
|
|
113099
|
+
heatpump: {
|
|
113100
|
+
en: "Heat pump consumption",
|
|
113101
|
+
it: "Consumo pompa di calore"
|
|
113102
|
+
}
|
|
113103
|
+
};
|
|
112933
113104
|
var point = (quantity, ...sources) => ({
|
|
112934
113105
|
quantity,
|
|
112935
113106
|
sources: sources.map((s) => typeof s === "string" ? { key: s } : s)
|
|
@@ -113030,7 +113201,7 @@ var ENPAL_SPECS = [
|
|
|
113030
113201
|
{
|
|
113031
113202
|
kind: "power-meter",
|
|
113032
113203
|
id: "house",
|
|
113033
|
-
name:
|
|
113204
|
+
name: ENPAL_CONSUMPTION_NAMES.house.en,
|
|
113034
113205
|
role: DeviceRole.PowerSensor,
|
|
113035
113206
|
power: point("power", "Power.Consumption.Total"),
|
|
113036
113207
|
kwh: point("energy", "Energy.Consumption.Total.Lifetime")
|
|
@@ -113038,7 +113209,7 @@ var ENPAL_SPECS = [
|
|
|
113038
113209
|
{
|
|
113039
113210
|
kind: "power-meter",
|
|
113040
113211
|
id: "heatpump",
|
|
113041
|
-
name:
|
|
113212
|
+
name: ENPAL_CONSUMPTION_NAMES.heatpump.en,
|
|
113042
113213
|
role: DeviceRole.PowerSensor,
|
|
113043
113214
|
power: point("power", "Heatpump.Power.Consumption.Total"),
|
|
113044
113215
|
kwh: point("energy", "Heatpump.Energy.Consumption.Total.Lifetime")
|
|
@@ -113115,11 +113286,8 @@ var ENPAL_SPECS = [
|
|
|
113115
113286
|
id: "grid-frequency",
|
|
113116
113287
|
name: "Frequency",
|
|
113117
113288
|
role: DeviceRole.NumericSensor,
|
|
113118
|
-
quantity: "
|
|
113119
|
-
value:
|
|
113120
|
-
...point("index", "Frequency.Grid"),
|
|
113121
|
-
ignoreUnit: true
|
|
113122
|
-
}
|
|
113289
|
+
quantity: "frequency",
|
|
113290
|
+
value: point("frequency", "Frequency.Grid")
|
|
113123
113291
|
},
|
|
113124
113292
|
numeric("grid-feed-max", "Maximum feed-in power", "power", "Power.Grid.Maximum.Feed", DeviceRole.PowerSensor),
|
|
113125
113293
|
numeric("house-energy-day", "Consumption today", "energy", "Energy.Consumption.Total.Day", DeviceRole.EnergySensor),
|
|
@@ -113153,9 +113321,9 @@ var ENPAL_SPECS = [
|
|
|
113153
113321
|
text("lte-connection-type", "Connection type", "LTE.Connection.Type"),
|
|
113154
113322
|
numeric("lte-quality", "LTE quality", "percentage", "LTE.Quality"),
|
|
113155
113323
|
numeric("lte-rsrp", "RSRP", "signal-level", "LTE.RSRP"),
|
|
113156
|
-
numeric("lte-rsrq", "RSRQ", "
|
|
113324
|
+
numeric("lte-rsrq", "RSRQ", "signal-ratio", "LTE.RSRQ"),
|
|
113157
113325
|
numeric("lte-rssi", "RSSI", "signal-level", "LTE.RSSI"),
|
|
113158
|
-
numeric("lte-snr", "SNR", "
|
|
113326
|
+
numeric("lte-snr", "SNR", "signal-ratio", "LTE.SNR"),
|
|
113159
113327
|
text("lte-failover", "Failover result", "LTE.Failover.Result"),
|
|
113160
113328
|
text("lte-signal-check", "Signal check", "LTE.Cronny.Result"),
|
|
113161
113329
|
text("wifi-state", "Wi-Fi state", "WiFi.State"),
|
|
@@ -113196,7 +113364,7 @@ function resolve(target, snapshot) {
|
|
|
113196
113364
|
for (const source of target.sources) {
|
|
113197
113365
|
const reading = snapshot.readings.get(source.key);
|
|
113198
113366
|
if (reading === void 0) continue;
|
|
113199
|
-
const converted = toBase(reading.value,
|
|
113367
|
+
const converted = toBase(reading.value, reading.unit, target.quantity);
|
|
113200
113368
|
if (!converted.ok) {
|
|
113201
113369
|
refusal = `${source.key}: ${converted.reason} (unit ${reading.unit ?? "none"})`;
|
|
113202
113370
|
continue;
|
|
@@ -113669,7 +113837,8 @@ function computeEnergySystemStatus(snapshot, options, now) {
|
|
|
113669
113837
|
chargedKwh: read.meter("battery-charged"),
|
|
113670
113838
|
dischargedKwh: read.meter("battery-discharged"),
|
|
113671
113839
|
chargedTodayKwh: read.numeric("battery-charge-day"),
|
|
113672
|
-
dischargedTodayKwh: read.numeric("battery-discharge-day")
|
|
113840
|
+
dischargedTodayKwh: read.numeric("battery-discharge-day"),
|
|
113841
|
+
healthPct: read.numeric("battery-health")
|
|
113673
113842
|
};
|
|
113674
113843
|
return {
|
|
113675
113844
|
status: {
|
|
@@ -114062,6 +114231,53 @@ function accessoryChildSpecs(config) {
|
|
|
114062
114231
|
return out;
|
|
114063
114232
|
}
|
|
114064
114233
|
//#endregion
|
|
114234
|
+
//#region src/devices/enpal-catalog-rename.ts
|
|
114235
|
+
/**
|
|
114236
|
+
* House and heat-pump meters used to be created as "Consumption". A restore
|
|
114237
|
+
* may replace that default; a name the operator chose stays.
|
|
114238
|
+
*/
|
|
114239
|
+
/** Keep unless the stored name is still the old catalogue default for this meter. */
|
|
114240
|
+
function catalogNameWrite(input) {
|
|
114241
|
+
const spec = findSpec(input.specId);
|
|
114242
|
+
if (spec === void 0) return { kind: "keep" };
|
|
114243
|
+
if (input.specId !== "house" && input.specId !== "heatpump") return { kind: "keep" };
|
|
114244
|
+
if (input.name === spec.name) return { kind: "keep" };
|
|
114245
|
+
if (input.name !== "Consumption") return { kind: "keep" };
|
|
114246
|
+
return {
|
|
114247
|
+
kind: "rename",
|
|
114248
|
+
name: spec.name,
|
|
114249
|
+
stampUserNamed: input.userNamed === true
|
|
114250
|
+
};
|
|
114251
|
+
}
|
|
114252
|
+
/** Rename each child that still carries the old default. Logs every rename. */
|
|
114253
|
+
async function renameLegacyCatalogDevices(input) {
|
|
114254
|
+
for (const child of input.children) {
|
|
114255
|
+
const decision = catalogNameWrite(child);
|
|
114256
|
+
if (decision.kind === "keep") continue;
|
|
114257
|
+
try {
|
|
114258
|
+
await input.rename(child.deviceId, decision.name, decision.stampUserNamed);
|
|
114259
|
+
} catch (err) {
|
|
114260
|
+
input.logger.warn("enpal: could not rename a device still carrying the old catalogue name", {
|
|
114261
|
+
tags: { deviceId: child.deviceId },
|
|
114262
|
+
meta: {
|
|
114263
|
+
from: child.name,
|
|
114264
|
+
to: decision.name,
|
|
114265
|
+
error: errMsg(err)
|
|
114266
|
+
}
|
|
114267
|
+
});
|
|
114268
|
+
continue;
|
|
114269
|
+
}
|
|
114270
|
+
input.logger.info("enpal: renamed a device that still had the old catalogue name", {
|
|
114271
|
+
tags: { deviceId: child.deviceId },
|
|
114272
|
+
meta: {
|
|
114273
|
+
specId: child.specId,
|
|
114274
|
+
from: child.name,
|
|
114275
|
+
to: decision.name
|
|
114276
|
+
}
|
|
114277
|
+
});
|
|
114278
|
+
}
|
|
114279
|
+
}
|
|
114280
|
+
//#endregion
|
|
114065
114281
|
//#region src/devices/enpal-metadata-sync.ts
|
|
114066
114282
|
/**
|
|
114067
114283
|
* Writes the identity facts a piece reported (model, serial, firmware) as device attributes.
|
|
@@ -114177,6 +114393,7 @@ var EnpalEquipmentDevice = class extends BaseDevice {
|
|
|
114177
114393
|
},
|
|
114178
114394
|
logger: this.ctx.logger
|
|
114179
114395
|
});
|
|
114396
|
+
await this.renameLegacyNames();
|
|
114180
114397
|
const metadata = new EnpalMetadataSync({
|
|
114181
114398
|
equipment: this.equipment,
|
|
114182
114399
|
deviceId: this.id,
|
|
@@ -114194,6 +114411,45 @@ var EnpalEquipmentDevice = class extends BaseDevice {
|
|
|
114194
114411
|
});
|
|
114195
114412
|
await metadata.apply();
|
|
114196
114413
|
}
|
|
114414
|
+
/**
|
|
114415
|
+
* A meter created as "Consumption" takes the current catalogue name. A name
|
|
114416
|
+
* the operator changed is left as it is.
|
|
114417
|
+
*/
|
|
114418
|
+
async renameLegacyNames() {
|
|
114419
|
+
const manager = this.ctx.api.deviceManager;
|
|
114420
|
+
try {
|
|
114421
|
+
const legacy = (await manager.getChildren.query({ parentDeviceId: this.id })).flatMap((child) => {
|
|
114422
|
+
const specId = child.config["specId"];
|
|
114423
|
+
if (typeof specId !== "string" || child.name !== "Consumption") return [];
|
|
114424
|
+
return [{
|
|
114425
|
+
deviceId: child.id,
|
|
114426
|
+
specId,
|
|
114427
|
+
name: child.name
|
|
114428
|
+
}];
|
|
114429
|
+
});
|
|
114430
|
+
await renameLegacyCatalogDevices({
|
|
114431
|
+
children: await Promise.all(legacy.map(async (child) => {
|
|
114432
|
+
const meta = await manager.loadMeta.query({ deviceId: child.deviceId });
|
|
114433
|
+
return {
|
|
114434
|
+
...child,
|
|
114435
|
+
name: meta?.name ?? child.name,
|
|
114436
|
+
userNamed: meta?.userNamed
|
|
114437
|
+
};
|
|
114438
|
+
})),
|
|
114439
|
+
rename: (deviceId, name, stampUserNamed) => manager.setName.mutate({
|
|
114440
|
+
deviceId,
|
|
114441
|
+
name,
|
|
114442
|
+
...stampUserNamed ? {} : { stampUserNamed: false }
|
|
114443
|
+
}),
|
|
114444
|
+
logger: this.ctx.logger
|
|
114445
|
+
});
|
|
114446
|
+
} catch (err) {
|
|
114447
|
+
this.ctx.logger.warn("enpal: could not rename devices still carrying the old catalogue name", {
|
|
114448
|
+
tags: { deviceId: this.id },
|
|
114449
|
+
meta: { error: errMsg(err) }
|
|
114450
|
+
});
|
|
114451
|
+
}
|
|
114452
|
+
}
|
|
114197
114453
|
async removeDevice() {
|
|
114198
114454
|
this.snapshotUnsub?.();
|
|
114199
114455
|
this.snapshotUnsub = null;
|