@camstack/addon-google-services 0.2.9 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/google-services.addon.js +385 -12
- package/dist/google-services.addon.mjs +385 -12
- package/package.json +1 -1
|
@@ -5542,7 +5542,7 @@ var ZodIssueCode = {
|
|
|
5542
5542
|
var ZodFirstPartyTypeKind;
|
|
5543
5543
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5544
5544
|
//#endregion
|
|
5545
|
-
//#region ../types/dist/sleep-
|
|
5545
|
+
//#region ../types/dist/sleep-BegKjwUu.mjs
|
|
5546
5546
|
/**
|
|
5547
5547
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5548
5548
|
* window to float samples (D455).
|
|
@@ -8771,7 +8771,7 @@ function userError(code, params, englishFallback) {
|
|
|
8771
8771
|
return new CamstackError(code, params, englishFallback);
|
|
8772
8772
|
}
|
|
8773
8773
|
//#endregion
|
|
8774
|
-
//#region ../types/dist/err-msg
|
|
8774
|
+
//#region ../types/dist/err-msg-BXKzRBwg.mjs
|
|
8775
8775
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
8776
8776
|
DeviceType["Camera"] = "camera";
|
|
8777
8777
|
DeviceType["Hub"] = "hub";
|
|
@@ -8863,6 +8863,10 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
8863
8863
|
* native PetKit (`nodepetkit` `FeederDevice`), reusable by other feeder
|
|
8864
8864
|
* integrations sharing the same food/desiccant/hopper surface. */
|
|
8865
8865
|
DeviceType["PetFeeder"] = "pet-feeder";
|
|
8866
|
+
/** Built-in dishwasher — program lifecycle, door / remote-start gates,
|
|
8867
|
+
* salt and rinse-aid levels. Installed with the `dishwasher` cap.
|
|
8868
|
+
* Sources: native Bosch Home Connect, reusable by similar integrations. */
|
|
8869
|
+
DeviceType["Dishwasher"] = "dishwasher";
|
|
8866
8870
|
return DeviceType;
|
|
8867
8871
|
}({});
|
|
8868
8872
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -9110,7 +9114,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
9110
9114
|
return DeviceRole;
|
|
9111
9115
|
}({});
|
|
9112
9116
|
//#endregion
|
|
9113
|
-
//#region ../types/dist/composition-
|
|
9117
|
+
//#region ../types/dist/composition-CB6PMT9p.mjs
|
|
9114
9118
|
/**
|
|
9115
9119
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
9116
9120
|
*
|
|
@@ -13632,8 +13636,13 @@ var AlertSeveritySchema = _enum([
|
|
|
13632
13636
|
"info",
|
|
13633
13637
|
"success",
|
|
13634
13638
|
"warning",
|
|
13635
|
-
"error"
|
|
13639
|
+
"error",
|
|
13640
|
+
"critical"
|
|
13636
13641
|
]);
|
|
13642
|
+
var AlertActionSchema = object({
|
|
13643
|
+
label: string(),
|
|
13644
|
+
href: string().optional()
|
|
13645
|
+
});
|
|
13637
13646
|
var AlertStatusSchema = _enum([
|
|
13638
13647
|
"active",
|
|
13639
13648
|
"in-progress",
|
|
@@ -13651,6 +13660,7 @@ var AlertSchema = object({
|
|
|
13651
13660
|
severity: AlertSeveritySchema,
|
|
13652
13661
|
title: string(),
|
|
13653
13662
|
message: string(),
|
|
13663
|
+
action: AlertActionSchema.optional(),
|
|
13654
13664
|
status: AlertStatusSchema,
|
|
13655
13665
|
progress: number().optional(),
|
|
13656
13666
|
read: boolean(),
|
|
@@ -17844,7 +17854,11 @@ DeviceType.Hub, DeviceDiscoveryStatusSchema.extend({ lastFetchedAt: number().int
|
|
|
17844
17854
|
});
|
|
17845
17855
|
/**
|
|
17846
17856
|
* `device-adoption` — generic discovery + adoption surface,
|
|
17847
|
-
* system-scoped
|
|
17857
|
+
* system-scoped collection (one provider per integration addon), routed
|
|
17858
|
+
* by explicit `{ addonId }` on direct `deviceAdoption.*` calls — the same
|
|
17859
|
+
* pin model as `connection-test`. The admin UI keeps using
|
|
17860
|
+
* `deviceManager.adoption*` (which already threads `addonId`). The de-HA-ified
|
|
17861
|
+
* successor to `ha-discovery`:
|
|
17848
17862
|
* keyed by `integrationId` (the addon resolves integrationId → broker
|
|
17849
17863
|
* internally) rather than a connection-specific `brokerId`, and it
|
|
17850
17864
|
* REUSES the shared `DiscoveredChildDevice` candidate type from
|
|
@@ -53647,7 +53661,7 @@ var BatteryStatusSchema = object({
|
|
|
53647
53661
|
*/
|
|
53648
53662
|
binary: boolean().optional()
|
|
53649
53663
|
});
|
|
53650
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, method(object({
|
|
53664
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, method(object({
|
|
53651
53665
|
deviceId: number(),
|
|
53652
53666
|
/** Bound on the wait. Sensible range 3000–10000ms. */
|
|
53653
53667
|
timeoutMs: number().int().min(500).max(3e4).default(8e3)
|
|
@@ -54533,6 +54547,130 @@ object({
|
|
|
54533
54547
|
deviceId: number(),
|
|
54534
54548
|
status: DeviceStatusSchema
|
|
54535
54549
|
});
|
|
54550
|
+
/**
|
|
54551
|
+
* Smart-dishwasher cap — program lifecycle, door / remote-start gates,
|
|
54552
|
+
* consumable levels (salt, rinse aid) and common program options.
|
|
54553
|
+
*
|
|
54554
|
+
* Sources: native Bosch Home Connect (`dishwasher` device type). Reusable
|
|
54555
|
+
* by any integration that exposes the same program / option surface.
|
|
54556
|
+
*
|
|
54557
|
+
* `kind: 'poll'` — cloud REST APIs typically have no push channel; the
|
|
54558
|
+
* provider refreshes the slice on an interval and eagerly after commands.
|
|
54559
|
+
*/
|
|
54560
|
+
var DishwasherStateSchema = _enum([
|
|
54561
|
+
"idle",
|
|
54562
|
+
"running",
|
|
54563
|
+
"paused",
|
|
54564
|
+
"finished",
|
|
54565
|
+
"error",
|
|
54566
|
+
"unavailable"
|
|
54567
|
+
]);
|
|
54568
|
+
var DishwasherConsumableLevelSchema = _enum([
|
|
54569
|
+
"ok",
|
|
54570
|
+
"low",
|
|
54571
|
+
"empty"
|
|
54572
|
+
]);
|
|
54573
|
+
object({
|
|
54574
|
+
state: DishwasherStateSchema,
|
|
54575
|
+
/** Active program id/name, or null when none selected / unknown. */
|
|
54576
|
+
program: string().nullable(),
|
|
54577
|
+
/** Program tokens the hardware accepts — drives the UI selector. */
|
|
54578
|
+
availablePrograms: array(string()),
|
|
54579
|
+
/** Minutes remaining on the active cycle, or null when not running. */
|
|
54580
|
+
remainingMinutes: number().int().nonnegative().nullable(),
|
|
54581
|
+
/** Cycle completion 0..100, or null when not applicable. */
|
|
54582
|
+
progressPercent: number().min(0).max(100).nullable(),
|
|
54583
|
+
/** True when the door is reported open. */
|
|
54584
|
+
doorOpen: boolean(),
|
|
54585
|
+
/** True when remote start is allowed (door closed, power on, etc.). */
|
|
54586
|
+
remoteStartAllowed: boolean(),
|
|
54587
|
+
/** Main power / switched-on state. */
|
|
54588
|
+
powerOn: boolean(),
|
|
54589
|
+
saltLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
54590
|
+
rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
54591
|
+
halfLoad: boolean(),
|
|
54592
|
+
hygienePlus: boolean(),
|
|
54593
|
+
/** Extra dry option when the appliance exposes it. */
|
|
54594
|
+
extraDry: boolean(),
|
|
54595
|
+
/** Intensive zone (lower basket) when the appliance exposes it. */
|
|
54596
|
+
intensiveZone: boolean(),
|
|
54597
|
+
/** VarioSpeed / VarioSpeed+ when the appliance exposes it. */
|
|
54598
|
+
varioSpeedPlus: boolean(),
|
|
54599
|
+
/** Child lock (controls disabled on the appliance). */
|
|
54600
|
+
childLock: boolean(),
|
|
54601
|
+
errorCode: number().nullable(),
|
|
54602
|
+
errorLabel: string().nullable(),
|
|
54603
|
+
lastFetchedAt: number()
|
|
54604
|
+
});
|
|
54605
|
+
DeviceType.Dishwasher, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
54606
|
+
kind: "mutation",
|
|
54607
|
+
auth: "protected"
|
|
54608
|
+
}), method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
54609
|
+
kind: "mutation",
|
|
54610
|
+
auth: "protected"
|
|
54611
|
+
}), method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
54612
|
+
kind: "mutation",
|
|
54613
|
+
auth: "protected"
|
|
54614
|
+
}), method(object({
|
|
54615
|
+
deviceId: number().int().nonnegative(),
|
|
54616
|
+
program: string().min(1)
|
|
54617
|
+
}), _void(), {
|
|
54618
|
+
kind: "mutation",
|
|
54619
|
+
auth: "protected"
|
|
54620
|
+
}), method(object({
|
|
54621
|
+
deviceId: number().int().nonnegative(),
|
|
54622
|
+
on: boolean()
|
|
54623
|
+
}), _void(), {
|
|
54624
|
+
kind: "mutation",
|
|
54625
|
+
auth: "protected"
|
|
54626
|
+
}), method(object({
|
|
54627
|
+
deviceId: number().int().nonnegative(),
|
|
54628
|
+
on: boolean()
|
|
54629
|
+
}), _void(), {
|
|
54630
|
+
kind: "mutation",
|
|
54631
|
+
auth: "protected"
|
|
54632
|
+
}), method(object({
|
|
54633
|
+
deviceId: number().int().nonnegative(),
|
|
54634
|
+
on: boolean()
|
|
54635
|
+
}), _void(), {
|
|
54636
|
+
kind: "mutation",
|
|
54637
|
+
auth: "protected"
|
|
54638
|
+
}), method(object({
|
|
54639
|
+
deviceId: number().int().nonnegative(),
|
|
54640
|
+
on: boolean()
|
|
54641
|
+
}), _void(), {
|
|
54642
|
+
kind: "mutation",
|
|
54643
|
+
auth: "protected"
|
|
54644
|
+
}), method(object({
|
|
54645
|
+
deviceId: number().int().nonnegative(),
|
|
54646
|
+
on: boolean()
|
|
54647
|
+
}), _void(), {
|
|
54648
|
+
kind: "mutation",
|
|
54649
|
+
auth: "protected"
|
|
54650
|
+
}), method(object({
|
|
54651
|
+
deviceId: number().int().nonnegative(),
|
|
54652
|
+
on: boolean()
|
|
54653
|
+
}), _void(), {
|
|
54654
|
+
kind: "mutation",
|
|
54655
|
+
auth: "protected"
|
|
54656
|
+
}), method(object({
|
|
54657
|
+
deviceId: number().int().nonnegative(),
|
|
54658
|
+
on: boolean()
|
|
54659
|
+
}), _void(), {
|
|
54660
|
+
kind: "mutation",
|
|
54661
|
+
auth: "protected"
|
|
54662
|
+
}), method(object({
|
|
54663
|
+
deviceId: number().int().nonnegative(),
|
|
54664
|
+
key: string().min(1),
|
|
54665
|
+
value: union([
|
|
54666
|
+
boolean(),
|
|
54667
|
+
string(),
|
|
54668
|
+
number()
|
|
54669
|
+
])
|
|
54670
|
+
}), _void(), {
|
|
54671
|
+
kind: "mutation",
|
|
54672
|
+
auth: "protected"
|
|
54673
|
+
});
|
|
54536
54674
|
object({
|
|
54537
54675
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
54538
54676
|
lastPressedAt: number().nullable(),
|
|
@@ -55098,6 +55236,13 @@ object({
|
|
|
55098
55236
|
lastChangedAt: number()
|
|
55099
55237
|
});
|
|
55100
55238
|
DeviceType.Sensor;
|
|
55239
|
+
object({
|
|
55240
|
+
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
55241
|
+
position: number().min(0).max(100).nullable(),
|
|
55242
|
+
/** Ms epoch when the slice was last updated (push or poll). */
|
|
55243
|
+
lastFetchedAt: number()
|
|
55244
|
+
});
|
|
55245
|
+
DeviceType.Thermostat;
|
|
55101
55246
|
object({
|
|
55102
55247
|
/** Whether the humidifier is currently on. */
|
|
55103
55248
|
on: boolean(),
|
|
@@ -62164,7 +62309,7 @@ var AccessoryKind = {
|
|
|
62164
62309
|
PrivacyMask: DeviceRole.PrivacyMask
|
|
62165
62310
|
};
|
|
62166
62311
|
AccessoryKind.Siren, AccessoryKind.Floodlight, AccessoryKind.Spotlight, AccessoryKind.PirSensor, AccessoryKind.Chime, AccessoryKind.Autotrack, AccessoryKind.Nightvision, AccessoryKind.PrivacyMask;
|
|
62167
|
-
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;
|
|
62312
|
+
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.Dishwasher;
|
|
62168
62313
|
new Set(Object.values(DeviceType));
|
|
62169
62314
|
Object.freeze({
|
|
62170
62315
|
"accessories.getStatus": {
|
|
@@ -64585,6 +64730,84 @@ Object.freeze({
|
|
|
64585
64730
|
addonId: null,
|
|
64586
64731
|
access: "view"
|
|
64587
64732
|
},
|
|
64733
|
+
"dishwasher.getStatus": {
|
|
64734
|
+
capName: "dishwasher",
|
|
64735
|
+
capScope: "device",
|
|
64736
|
+
addonId: null,
|
|
64737
|
+
access: "view"
|
|
64738
|
+
},
|
|
64739
|
+
"dishwasher.pause": {
|
|
64740
|
+
capName: "dishwasher",
|
|
64741
|
+
capScope: "device",
|
|
64742
|
+
addonId: null,
|
|
64743
|
+
access: "create"
|
|
64744
|
+
},
|
|
64745
|
+
"dishwasher.setChildLock": {
|
|
64746
|
+
capName: "dishwasher",
|
|
64747
|
+
capScope: "device",
|
|
64748
|
+
addonId: null,
|
|
64749
|
+
access: "create"
|
|
64750
|
+
},
|
|
64751
|
+
"dishwasher.setExtraDry": {
|
|
64752
|
+
capName: "dishwasher",
|
|
64753
|
+
capScope: "device",
|
|
64754
|
+
addonId: null,
|
|
64755
|
+
access: "create"
|
|
64756
|
+
},
|
|
64757
|
+
"dishwasher.setHalfLoad": {
|
|
64758
|
+
capName: "dishwasher",
|
|
64759
|
+
capScope: "device",
|
|
64760
|
+
addonId: null,
|
|
64761
|
+
access: "create"
|
|
64762
|
+
},
|
|
64763
|
+
"dishwasher.setHygienePlus": {
|
|
64764
|
+
capName: "dishwasher",
|
|
64765
|
+
capScope: "device",
|
|
64766
|
+
addonId: null,
|
|
64767
|
+
access: "create"
|
|
64768
|
+
},
|
|
64769
|
+
"dishwasher.setIntensiveZone": {
|
|
64770
|
+
capName: "dishwasher",
|
|
64771
|
+
capScope: "device",
|
|
64772
|
+
addonId: null,
|
|
64773
|
+
access: "create"
|
|
64774
|
+
},
|
|
64775
|
+
"dishwasher.setOption": {
|
|
64776
|
+
capName: "dishwasher",
|
|
64777
|
+
capScope: "device",
|
|
64778
|
+
addonId: null,
|
|
64779
|
+
access: "create"
|
|
64780
|
+
},
|
|
64781
|
+
"dishwasher.setPower": {
|
|
64782
|
+
capName: "dishwasher",
|
|
64783
|
+
capScope: "device",
|
|
64784
|
+
addonId: null,
|
|
64785
|
+
access: "create"
|
|
64786
|
+
},
|
|
64787
|
+
"dishwasher.setProgram": {
|
|
64788
|
+
capName: "dishwasher",
|
|
64789
|
+
capScope: "device",
|
|
64790
|
+
addonId: null,
|
|
64791
|
+
access: "create"
|
|
64792
|
+
},
|
|
64793
|
+
"dishwasher.setVarioSpeedPlus": {
|
|
64794
|
+
capName: "dishwasher",
|
|
64795
|
+
capScope: "device",
|
|
64796
|
+
addonId: null,
|
|
64797
|
+
access: "create"
|
|
64798
|
+
},
|
|
64799
|
+
"dishwasher.start": {
|
|
64800
|
+
capName: "dishwasher",
|
|
64801
|
+
capScope: "device",
|
|
64802
|
+
addonId: null,
|
|
64803
|
+
access: "create"
|
|
64804
|
+
},
|
|
64805
|
+
"dishwasher.stop": {
|
|
64806
|
+
capName: "dishwasher",
|
|
64807
|
+
capScope: "device",
|
|
64808
|
+
addonId: null,
|
|
64809
|
+
access: "create"
|
|
64810
|
+
},
|
|
64588
64811
|
"doorbell.getStatus": {
|
|
64589
64812
|
capName: "doorbell",
|
|
64590
64813
|
capScope: "device",
|
|
@@ -64795,6 +65018,12 @@ Object.freeze({
|
|
|
64795
65018
|
addonId: null,
|
|
64796
65019
|
access: "view"
|
|
64797
65020
|
},
|
|
65021
|
+
"heatingValve.getStatus": {
|
|
65022
|
+
capName: "heating-valve",
|
|
65023
|
+
capScope: "device",
|
|
65024
|
+
addonId: null,
|
|
65025
|
+
access: "view"
|
|
65026
|
+
},
|
|
64798
65027
|
"humidifier.getStatus": {
|
|
64799
65028
|
capName: "humidifier",
|
|
64800
65029
|
capScope: "device",
|
|
@@ -70382,7 +70611,7 @@ Object.freeze({
|
|
|
70382
70611
|
access: "create"
|
|
70383
70612
|
}
|
|
70384
70613
|
});
|
|
70385
|
-
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;
|
|
70614
|
+
DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher;
|
|
70386
70615
|
DeviceFeature.BatteryOperated;
|
|
70387
70616
|
Object.freeze({
|
|
70388
70617
|
"accessories.getStatus": [{
|
|
@@ -71206,6 +71435,71 @@ Object.freeze({
|
|
|
71206
71435
|
form: "single",
|
|
71207
71436
|
optional: false
|
|
71208
71437
|
}],
|
|
71438
|
+
"dishwasher.getStatus": [{
|
|
71439
|
+
name: "deviceId",
|
|
71440
|
+
form: "single",
|
|
71441
|
+
optional: false
|
|
71442
|
+
}],
|
|
71443
|
+
"dishwasher.pause": [{
|
|
71444
|
+
name: "deviceId",
|
|
71445
|
+
form: "single",
|
|
71446
|
+
optional: false
|
|
71447
|
+
}],
|
|
71448
|
+
"dishwasher.setChildLock": [{
|
|
71449
|
+
name: "deviceId",
|
|
71450
|
+
form: "single",
|
|
71451
|
+
optional: false
|
|
71452
|
+
}],
|
|
71453
|
+
"dishwasher.setExtraDry": [{
|
|
71454
|
+
name: "deviceId",
|
|
71455
|
+
form: "single",
|
|
71456
|
+
optional: false
|
|
71457
|
+
}],
|
|
71458
|
+
"dishwasher.setHalfLoad": [{
|
|
71459
|
+
name: "deviceId",
|
|
71460
|
+
form: "single",
|
|
71461
|
+
optional: false
|
|
71462
|
+
}],
|
|
71463
|
+
"dishwasher.setHygienePlus": [{
|
|
71464
|
+
name: "deviceId",
|
|
71465
|
+
form: "single",
|
|
71466
|
+
optional: false
|
|
71467
|
+
}],
|
|
71468
|
+
"dishwasher.setIntensiveZone": [{
|
|
71469
|
+
name: "deviceId",
|
|
71470
|
+
form: "single",
|
|
71471
|
+
optional: false
|
|
71472
|
+
}],
|
|
71473
|
+
"dishwasher.setOption": [{
|
|
71474
|
+
name: "deviceId",
|
|
71475
|
+
form: "single",
|
|
71476
|
+
optional: false
|
|
71477
|
+
}],
|
|
71478
|
+
"dishwasher.setPower": [{
|
|
71479
|
+
name: "deviceId",
|
|
71480
|
+
form: "single",
|
|
71481
|
+
optional: false
|
|
71482
|
+
}],
|
|
71483
|
+
"dishwasher.setProgram": [{
|
|
71484
|
+
name: "deviceId",
|
|
71485
|
+
form: "single",
|
|
71486
|
+
optional: false
|
|
71487
|
+
}],
|
|
71488
|
+
"dishwasher.setVarioSpeedPlus": [{
|
|
71489
|
+
name: "deviceId",
|
|
71490
|
+
form: "single",
|
|
71491
|
+
optional: false
|
|
71492
|
+
}],
|
|
71493
|
+
"dishwasher.start": [{
|
|
71494
|
+
name: "deviceId",
|
|
71495
|
+
form: "single",
|
|
71496
|
+
optional: false
|
|
71497
|
+
}],
|
|
71498
|
+
"dishwasher.stop": [{
|
|
71499
|
+
name: "deviceId",
|
|
71500
|
+
form: "single",
|
|
71501
|
+
optional: false
|
|
71502
|
+
}],
|
|
71209
71503
|
"doorbell.getStatus": [{
|
|
71210
71504
|
name: "deviceId",
|
|
71211
71505
|
form: "single",
|
|
@@ -71275,6 +71569,11 @@ Object.freeze({
|
|
|
71275
71569
|
form: "single",
|
|
71276
71570
|
optional: false
|
|
71277
71571
|
}],
|
|
71572
|
+
"heatingValve.getStatus": [{
|
|
71573
|
+
name: "deviceId",
|
|
71574
|
+
form: "single",
|
|
71575
|
+
optional: false
|
|
71576
|
+
}],
|
|
71278
71577
|
"humidifier.getStatus": [{
|
|
71279
71578
|
name: "deviceId",
|
|
71280
71579
|
form: "single",
|
|
@@ -74970,6 +75269,40 @@ function createGmailSmtpProvider(deps) {
|
|
|
74970
75269
|
};
|
|
74971
75270
|
}
|
|
74972
75271
|
//#endregion
|
|
75272
|
+
//#region src/google-broker-reconnect-alert.ts
|
|
75273
|
+
function googleBrokerReconnectAlertId(brokerId) {
|
|
75274
|
+
return `google-broker:${brokerId}`;
|
|
75275
|
+
}
|
|
75276
|
+
function isInvalidGrantRefreshError(err) {
|
|
75277
|
+
return (err instanceof Error ? err.message : String(err)).includes("invalid_grant");
|
|
75278
|
+
}
|
|
75279
|
+
function buildGoogleBrokerReconnectAlert(brokerId, brokerName) {
|
|
75280
|
+
const pushLine = `${brokerName}: Google session expired — sign in again`;
|
|
75281
|
+
return {
|
|
75282
|
+
id: googleBrokerReconnectAlertId(brokerId),
|
|
75283
|
+
category: "google.broker-reconnect",
|
|
75284
|
+
severity: "critical",
|
|
75285
|
+
title: "Google needs a new sign-in",
|
|
75286
|
+
message: `${brokerName} needs you to sign in to Google again.`,
|
|
75287
|
+
action: {
|
|
75288
|
+
label: "Sign in again",
|
|
75289
|
+
href: `/addon/google-services/oauth/start?brokerId=${encodeURIComponent(brokerId)}`
|
|
75290
|
+
},
|
|
75291
|
+
status: "active",
|
|
75292
|
+
read: false,
|
|
75293
|
+
createdAt: Date.now(),
|
|
75294
|
+
updatedAt: Date.now(),
|
|
75295
|
+
source: {
|
|
75296
|
+
type: "google-broker",
|
|
75297
|
+
id: brokerId
|
|
75298
|
+
},
|
|
75299
|
+
metadata: {
|
|
75300
|
+
episodeKey: "reconnect",
|
|
75301
|
+
pushLine
|
|
75302
|
+
}
|
|
75303
|
+
};
|
|
75304
|
+
}
|
|
75305
|
+
//#endregion
|
|
74973
75306
|
//#region src/google-oauth.ts
|
|
74974
75307
|
/**
|
|
74975
75308
|
* Google OAuth2 authorization-code + refresh for Calendar API.
|
|
@@ -75585,6 +75918,7 @@ var GoogleServicesAddon = class extends BaseAddon {
|
|
|
75585
75918
|
};
|
|
75586
75919
|
this.registry.setOauth(next);
|
|
75587
75920
|
await this.persistOauthAccounts();
|
|
75921
|
+
if (next.refreshToken.length > 0) this.resolveGoogleBrokerReconnectAlert(brokerId);
|
|
75588
75922
|
if (next.accountEmail && (entry.name === "Google account" || entry.name.startsWith("google_"))) {
|
|
75589
75923
|
const renamed = {
|
|
75590
75924
|
...entry,
|
|
@@ -75717,6 +76051,39 @@ var GoogleServicesAddon = class extends BaseAddon {
|
|
|
75717
76051
|
}
|
|
75718
76052
|
return out.toSorted((a, b) => a.label.localeCompare(b.label));
|
|
75719
76053
|
}
|
|
76054
|
+
async emitGoogleBrokerReconnectAlert(brokerId, brokerName) {
|
|
76055
|
+
const emit = this.ctx.api.alerts?.emit;
|
|
76056
|
+
if (emit === void 0) {
|
|
76057
|
+
this.ctx.logger.warn("google broker reconnect alert skipped — alerts capability missing", { meta: { brokerId } });
|
|
76058
|
+
return;
|
|
76059
|
+
}
|
|
76060
|
+
try {
|
|
76061
|
+
await emit.mutate(buildGoogleBrokerReconnectAlert(brokerId, brokerName));
|
|
76062
|
+
} catch (err) {
|
|
76063
|
+
this.ctx.logger.warn("google broker reconnect alert emit failed", { meta: {
|
|
76064
|
+
brokerId,
|
|
76065
|
+
error: err instanceof Error ? err.message : String(err)
|
|
76066
|
+
} });
|
|
76067
|
+
}
|
|
76068
|
+
}
|
|
76069
|
+
async resolveGoogleBrokerReconnectAlert(brokerId) {
|
|
76070
|
+
const update = this.ctx.api.alerts?.update;
|
|
76071
|
+
if (update === void 0) return;
|
|
76072
|
+
try {
|
|
76073
|
+
await update.mutate({
|
|
76074
|
+
alertId: googleBrokerReconnectAlertId(brokerId),
|
|
76075
|
+
patch: {
|
|
76076
|
+
status: "completed",
|
|
76077
|
+
read: true
|
|
76078
|
+
}
|
|
76079
|
+
});
|
|
76080
|
+
} catch (err) {
|
|
76081
|
+
this.ctx.logger.warn("google broker reconnect alert resolve failed", { meta: {
|
|
76082
|
+
brokerId,
|
|
76083
|
+
error: err instanceof Error ? err.message : String(err)
|
|
76084
|
+
} });
|
|
76085
|
+
}
|
|
76086
|
+
}
|
|
75720
76087
|
async ensureAccessToken(brokerId, opts = {}) {
|
|
75721
76088
|
const entry = this.registry.getEntry(brokerId);
|
|
75722
76089
|
const oauth = this.registry.getOauth(brokerId);
|
|
@@ -75729,10 +76096,16 @@ var GoogleServicesAddon = class extends BaseAddon {
|
|
|
75729
76096
|
accountEmail: oauth.accountEmail
|
|
75730
76097
|
};
|
|
75731
76098
|
if (!opts.forceRefresh && !needsRefresh(state)) return state.accessToken;
|
|
75732
|
-
|
|
75733
|
-
|
|
75734
|
-
|
|
75735
|
-
|
|
76099
|
+
let tokens;
|
|
76100
|
+
try {
|
|
76101
|
+
tokens = await refreshAccessToken({
|
|
76102
|
+
clientId: entry.clientId.trim(),
|
|
76103
|
+
clientSecret: entry.clientSecret.trim()
|
|
76104
|
+
}, state.refreshToken);
|
|
76105
|
+
} catch (err) {
|
|
76106
|
+
if (isInvalidGrantRefreshError(err)) this.emitGoogleBrokerReconnectAlert(brokerId, entry.name);
|
|
76107
|
+
throw err;
|
|
76108
|
+
}
|
|
75736
76109
|
if (typeof tokens.access_token !== "string" || tokens.access_token.trim().length === 0) throw new Error("Google token refresh returned an empty access_token — Sign out and Sign in again");
|
|
75737
76110
|
const nextState = applyTokenResponse(state, tokens);
|
|
75738
76111
|
this.registry.setOauth({
|
|
@@ -5538,7 +5538,7 @@ var ZodIssueCode = {
|
|
|
5538
5538
|
var ZodFirstPartyTypeKind;
|
|
5539
5539
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5540
5540
|
//#endregion
|
|
5541
|
-
//#region ../types/dist/sleep-
|
|
5541
|
+
//#region ../types/dist/sleep-BegKjwUu.mjs
|
|
5542
5542
|
/**
|
|
5543
5543
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5544
5544
|
* window to float samples (D455).
|
|
@@ -8767,7 +8767,7 @@ function userError(code, params, englishFallback) {
|
|
|
8767
8767
|
return new CamstackError(code, params, englishFallback);
|
|
8768
8768
|
}
|
|
8769
8769
|
//#endregion
|
|
8770
|
-
//#region ../types/dist/err-msg
|
|
8770
|
+
//#region ../types/dist/err-msg-BXKzRBwg.mjs
|
|
8771
8771
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
8772
8772
|
DeviceType["Camera"] = "camera";
|
|
8773
8773
|
DeviceType["Hub"] = "hub";
|
|
@@ -8859,6 +8859,10 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
8859
8859
|
* native PetKit (`nodepetkit` `FeederDevice`), reusable by other feeder
|
|
8860
8860
|
* integrations sharing the same food/desiccant/hopper surface. */
|
|
8861
8861
|
DeviceType["PetFeeder"] = "pet-feeder";
|
|
8862
|
+
/** Built-in dishwasher — program lifecycle, door / remote-start gates,
|
|
8863
|
+
* salt and rinse-aid levels. Installed with the `dishwasher` cap.
|
|
8864
|
+
* Sources: native Bosch Home Connect, reusable by similar integrations. */
|
|
8865
|
+
DeviceType["Dishwasher"] = "dishwasher";
|
|
8862
8866
|
return DeviceType;
|
|
8863
8867
|
}({});
|
|
8864
8868
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -9106,7 +9110,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
9106
9110
|
return DeviceRole;
|
|
9107
9111
|
}({});
|
|
9108
9112
|
//#endregion
|
|
9109
|
-
//#region ../types/dist/composition-
|
|
9113
|
+
//#region ../types/dist/composition-CB6PMT9p.mjs
|
|
9110
9114
|
/**
|
|
9111
9115
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
9112
9116
|
*
|
|
@@ -13628,8 +13632,13 @@ var AlertSeveritySchema = _enum([
|
|
|
13628
13632
|
"info",
|
|
13629
13633
|
"success",
|
|
13630
13634
|
"warning",
|
|
13631
|
-
"error"
|
|
13635
|
+
"error",
|
|
13636
|
+
"critical"
|
|
13632
13637
|
]);
|
|
13638
|
+
var AlertActionSchema = object({
|
|
13639
|
+
label: string(),
|
|
13640
|
+
href: string().optional()
|
|
13641
|
+
});
|
|
13633
13642
|
var AlertStatusSchema = _enum([
|
|
13634
13643
|
"active",
|
|
13635
13644
|
"in-progress",
|
|
@@ -13647,6 +13656,7 @@ var AlertSchema = object({
|
|
|
13647
13656
|
severity: AlertSeveritySchema,
|
|
13648
13657
|
title: string(),
|
|
13649
13658
|
message: string(),
|
|
13659
|
+
action: AlertActionSchema.optional(),
|
|
13650
13660
|
status: AlertStatusSchema,
|
|
13651
13661
|
progress: number().optional(),
|
|
13652
13662
|
read: boolean(),
|
|
@@ -17840,7 +17850,11 @@ DeviceType.Hub, DeviceDiscoveryStatusSchema.extend({ lastFetchedAt: number().int
|
|
|
17840
17850
|
});
|
|
17841
17851
|
/**
|
|
17842
17852
|
* `device-adoption` — generic discovery + adoption surface,
|
|
17843
|
-
* system-scoped
|
|
17853
|
+
* system-scoped collection (one provider per integration addon), routed
|
|
17854
|
+
* by explicit `{ addonId }` on direct `deviceAdoption.*` calls — the same
|
|
17855
|
+
* pin model as `connection-test`. The admin UI keeps using
|
|
17856
|
+
* `deviceManager.adoption*` (which already threads `addonId`). The de-HA-ified
|
|
17857
|
+
* successor to `ha-discovery`:
|
|
17844
17858
|
* keyed by `integrationId` (the addon resolves integrationId → broker
|
|
17845
17859
|
* internally) rather than a connection-specific `brokerId`, and it
|
|
17846
17860
|
* REUSES the shared `DiscoveredChildDevice` candidate type from
|
|
@@ -53643,7 +53657,7 @@ var BatteryStatusSchema = object({
|
|
|
53643
53657
|
*/
|
|
53644
53658
|
binary: boolean().optional()
|
|
53645
53659
|
});
|
|
53646
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, method(object({
|
|
53660
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, method(object({
|
|
53647
53661
|
deviceId: number(),
|
|
53648
53662
|
/** Bound on the wait. Sensible range 3000–10000ms. */
|
|
53649
53663
|
timeoutMs: number().int().min(500).max(3e4).default(8e3)
|
|
@@ -54529,6 +54543,130 @@ object({
|
|
|
54529
54543
|
deviceId: number(),
|
|
54530
54544
|
status: DeviceStatusSchema
|
|
54531
54545
|
});
|
|
54546
|
+
/**
|
|
54547
|
+
* Smart-dishwasher cap — program lifecycle, door / remote-start gates,
|
|
54548
|
+
* consumable levels (salt, rinse aid) and common program options.
|
|
54549
|
+
*
|
|
54550
|
+
* Sources: native Bosch Home Connect (`dishwasher` device type). Reusable
|
|
54551
|
+
* by any integration that exposes the same program / option surface.
|
|
54552
|
+
*
|
|
54553
|
+
* `kind: 'poll'` — cloud REST APIs typically have no push channel; the
|
|
54554
|
+
* provider refreshes the slice on an interval and eagerly after commands.
|
|
54555
|
+
*/
|
|
54556
|
+
var DishwasherStateSchema = _enum([
|
|
54557
|
+
"idle",
|
|
54558
|
+
"running",
|
|
54559
|
+
"paused",
|
|
54560
|
+
"finished",
|
|
54561
|
+
"error",
|
|
54562
|
+
"unavailable"
|
|
54563
|
+
]);
|
|
54564
|
+
var DishwasherConsumableLevelSchema = _enum([
|
|
54565
|
+
"ok",
|
|
54566
|
+
"low",
|
|
54567
|
+
"empty"
|
|
54568
|
+
]);
|
|
54569
|
+
object({
|
|
54570
|
+
state: DishwasherStateSchema,
|
|
54571
|
+
/** Active program id/name, or null when none selected / unknown. */
|
|
54572
|
+
program: string().nullable(),
|
|
54573
|
+
/** Program tokens the hardware accepts — drives the UI selector. */
|
|
54574
|
+
availablePrograms: array(string()),
|
|
54575
|
+
/** Minutes remaining on the active cycle, or null when not running. */
|
|
54576
|
+
remainingMinutes: number().int().nonnegative().nullable(),
|
|
54577
|
+
/** Cycle completion 0..100, or null when not applicable. */
|
|
54578
|
+
progressPercent: number().min(0).max(100).nullable(),
|
|
54579
|
+
/** True when the door is reported open. */
|
|
54580
|
+
doorOpen: boolean(),
|
|
54581
|
+
/** True when remote start is allowed (door closed, power on, etc.). */
|
|
54582
|
+
remoteStartAllowed: boolean(),
|
|
54583
|
+
/** Main power / switched-on state. */
|
|
54584
|
+
powerOn: boolean(),
|
|
54585
|
+
saltLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
54586
|
+
rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
54587
|
+
halfLoad: boolean(),
|
|
54588
|
+
hygienePlus: boolean(),
|
|
54589
|
+
/** Extra dry option when the appliance exposes it. */
|
|
54590
|
+
extraDry: boolean(),
|
|
54591
|
+
/** Intensive zone (lower basket) when the appliance exposes it. */
|
|
54592
|
+
intensiveZone: boolean(),
|
|
54593
|
+
/** VarioSpeed / VarioSpeed+ when the appliance exposes it. */
|
|
54594
|
+
varioSpeedPlus: boolean(),
|
|
54595
|
+
/** Child lock (controls disabled on the appliance). */
|
|
54596
|
+
childLock: boolean(),
|
|
54597
|
+
errorCode: number().nullable(),
|
|
54598
|
+
errorLabel: string().nullable(),
|
|
54599
|
+
lastFetchedAt: number()
|
|
54600
|
+
});
|
|
54601
|
+
DeviceType.Dishwasher, method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
54602
|
+
kind: "mutation",
|
|
54603
|
+
auth: "protected"
|
|
54604
|
+
}), method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
54605
|
+
kind: "mutation",
|
|
54606
|
+
auth: "protected"
|
|
54607
|
+
}), method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
54608
|
+
kind: "mutation",
|
|
54609
|
+
auth: "protected"
|
|
54610
|
+
}), method(object({
|
|
54611
|
+
deviceId: number().int().nonnegative(),
|
|
54612
|
+
program: string().min(1)
|
|
54613
|
+
}), _void(), {
|
|
54614
|
+
kind: "mutation",
|
|
54615
|
+
auth: "protected"
|
|
54616
|
+
}), method(object({
|
|
54617
|
+
deviceId: number().int().nonnegative(),
|
|
54618
|
+
on: boolean()
|
|
54619
|
+
}), _void(), {
|
|
54620
|
+
kind: "mutation",
|
|
54621
|
+
auth: "protected"
|
|
54622
|
+
}), method(object({
|
|
54623
|
+
deviceId: number().int().nonnegative(),
|
|
54624
|
+
on: boolean()
|
|
54625
|
+
}), _void(), {
|
|
54626
|
+
kind: "mutation",
|
|
54627
|
+
auth: "protected"
|
|
54628
|
+
}), method(object({
|
|
54629
|
+
deviceId: number().int().nonnegative(),
|
|
54630
|
+
on: boolean()
|
|
54631
|
+
}), _void(), {
|
|
54632
|
+
kind: "mutation",
|
|
54633
|
+
auth: "protected"
|
|
54634
|
+
}), method(object({
|
|
54635
|
+
deviceId: number().int().nonnegative(),
|
|
54636
|
+
on: boolean()
|
|
54637
|
+
}), _void(), {
|
|
54638
|
+
kind: "mutation",
|
|
54639
|
+
auth: "protected"
|
|
54640
|
+
}), method(object({
|
|
54641
|
+
deviceId: number().int().nonnegative(),
|
|
54642
|
+
on: boolean()
|
|
54643
|
+
}), _void(), {
|
|
54644
|
+
kind: "mutation",
|
|
54645
|
+
auth: "protected"
|
|
54646
|
+
}), method(object({
|
|
54647
|
+
deviceId: number().int().nonnegative(),
|
|
54648
|
+
on: boolean()
|
|
54649
|
+
}), _void(), {
|
|
54650
|
+
kind: "mutation",
|
|
54651
|
+
auth: "protected"
|
|
54652
|
+
}), method(object({
|
|
54653
|
+
deviceId: number().int().nonnegative(),
|
|
54654
|
+
on: boolean()
|
|
54655
|
+
}), _void(), {
|
|
54656
|
+
kind: "mutation",
|
|
54657
|
+
auth: "protected"
|
|
54658
|
+
}), method(object({
|
|
54659
|
+
deviceId: number().int().nonnegative(),
|
|
54660
|
+
key: string().min(1),
|
|
54661
|
+
value: union([
|
|
54662
|
+
boolean(),
|
|
54663
|
+
string(),
|
|
54664
|
+
number()
|
|
54665
|
+
])
|
|
54666
|
+
}), _void(), {
|
|
54667
|
+
kind: "mutation",
|
|
54668
|
+
auth: "protected"
|
|
54669
|
+
});
|
|
54532
54670
|
object({
|
|
54533
54671
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
54534
54672
|
lastPressedAt: number().nullable(),
|
|
@@ -55094,6 +55232,13 @@ object({
|
|
|
55094
55232
|
lastChangedAt: number()
|
|
55095
55233
|
});
|
|
55096
55234
|
DeviceType.Sensor;
|
|
55235
|
+
object({
|
|
55236
|
+
/** Radiator valve opening 0 (closed) .. 100 (open). Null = not yet known. */
|
|
55237
|
+
position: number().min(0).max(100).nullable(),
|
|
55238
|
+
/** Ms epoch when the slice was last updated (push or poll). */
|
|
55239
|
+
lastFetchedAt: number()
|
|
55240
|
+
});
|
|
55241
|
+
DeviceType.Thermostat;
|
|
55097
55242
|
object({
|
|
55098
55243
|
/** Whether the humidifier is currently on. */
|
|
55099
55244
|
on: boolean(),
|
|
@@ -62160,7 +62305,7 @@ var AccessoryKind = {
|
|
|
62160
62305
|
PrivacyMask: DeviceRole.PrivacyMask
|
|
62161
62306
|
};
|
|
62162
62307
|
AccessoryKind.Siren, AccessoryKind.Floodlight, AccessoryKind.Spotlight, AccessoryKind.PirSensor, AccessoryKind.Chime, AccessoryKind.Autotrack, AccessoryKind.Nightvision, AccessoryKind.PrivacyMask;
|
|
62163
|
-
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;
|
|
62308
|
+
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.Dishwasher;
|
|
62164
62309
|
new Set(Object.values(DeviceType));
|
|
62165
62310
|
Object.freeze({
|
|
62166
62311
|
"accessories.getStatus": {
|
|
@@ -64581,6 +64726,84 @@ Object.freeze({
|
|
|
64581
64726
|
addonId: null,
|
|
64582
64727
|
access: "view"
|
|
64583
64728
|
},
|
|
64729
|
+
"dishwasher.getStatus": {
|
|
64730
|
+
capName: "dishwasher",
|
|
64731
|
+
capScope: "device",
|
|
64732
|
+
addonId: null,
|
|
64733
|
+
access: "view"
|
|
64734
|
+
},
|
|
64735
|
+
"dishwasher.pause": {
|
|
64736
|
+
capName: "dishwasher",
|
|
64737
|
+
capScope: "device",
|
|
64738
|
+
addonId: null,
|
|
64739
|
+
access: "create"
|
|
64740
|
+
},
|
|
64741
|
+
"dishwasher.setChildLock": {
|
|
64742
|
+
capName: "dishwasher",
|
|
64743
|
+
capScope: "device",
|
|
64744
|
+
addonId: null,
|
|
64745
|
+
access: "create"
|
|
64746
|
+
},
|
|
64747
|
+
"dishwasher.setExtraDry": {
|
|
64748
|
+
capName: "dishwasher",
|
|
64749
|
+
capScope: "device",
|
|
64750
|
+
addonId: null,
|
|
64751
|
+
access: "create"
|
|
64752
|
+
},
|
|
64753
|
+
"dishwasher.setHalfLoad": {
|
|
64754
|
+
capName: "dishwasher",
|
|
64755
|
+
capScope: "device",
|
|
64756
|
+
addonId: null,
|
|
64757
|
+
access: "create"
|
|
64758
|
+
},
|
|
64759
|
+
"dishwasher.setHygienePlus": {
|
|
64760
|
+
capName: "dishwasher",
|
|
64761
|
+
capScope: "device",
|
|
64762
|
+
addonId: null,
|
|
64763
|
+
access: "create"
|
|
64764
|
+
},
|
|
64765
|
+
"dishwasher.setIntensiveZone": {
|
|
64766
|
+
capName: "dishwasher",
|
|
64767
|
+
capScope: "device",
|
|
64768
|
+
addonId: null,
|
|
64769
|
+
access: "create"
|
|
64770
|
+
},
|
|
64771
|
+
"dishwasher.setOption": {
|
|
64772
|
+
capName: "dishwasher",
|
|
64773
|
+
capScope: "device",
|
|
64774
|
+
addonId: null,
|
|
64775
|
+
access: "create"
|
|
64776
|
+
},
|
|
64777
|
+
"dishwasher.setPower": {
|
|
64778
|
+
capName: "dishwasher",
|
|
64779
|
+
capScope: "device",
|
|
64780
|
+
addonId: null,
|
|
64781
|
+
access: "create"
|
|
64782
|
+
},
|
|
64783
|
+
"dishwasher.setProgram": {
|
|
64784
|
+
capName: "dishwasher",
|
|
64785
|
+
capScope: "device",
|
|
64786
|
+
addonId: null,
|
|
64787
|
+
access: "create"
|
|
64788
|
+
},
|
|
64789
|
+
"dishwasher.setVarioSpeedPlus": {
|
|
64790
|
+
capName: "dishwasher",
|
|
64791
|
+
capScope: "device",
|
|
64792
|
+
addonId: null,
|
|
64793
|
+
access: "create"
|
|
64794
|
+
},
|
|
64795
|
+
"dishwasher.start": {
|
|
64796
|
+
capName: "dishwasher",
|
|
64797
|
+
capScope: "device",
|
|
64798
|
+
addonId: null,
|
|
64799
|
+
access: "create"
|
|
64800
|
+
},
|
|
64801
|
+
"dishwasher.stop": {
|
|
64802
|
+
capName: "dishwasher",
|
|
64803
|
+
capScope: "device",
|
|
64804
|
+
addonId: null,
|
|
64805
|
+
access: "create"
|
|
64806
|
+
},
|
|
64584
64807
|
"doorbell.getStatus": {
|
|
64585
64808
|
capName: "doorbell",
|
|
64586
64809
|
capScope: "device",
|
|
@@ -64791,6 +65014,12 @@ Object.freeze({
|
|
|
64791
65014
|
addonId: null,
|
|
64792
65015
|
access: "view"
|
|
64793
65016
|
},
|
|
65017
|
+
"heatingValve.getStatus": {
|
|
65018
|
+
capName: "heating-valve",
|
|
65019
|
+
capScope: "device",
|
|
65020
|
+
addonId: null,
|
|
65021
|
+
access: "view"
|
|
65022
|
+
},
|
|
64794
65023
|
"humidifier.getStatus": {
|
|
64795
65024
|
capName: "humidifier",
|
|
64796
65025
|
capScope: "device",
|
|
@@ -70378,7 +70607,7 @@ Object.freeze({
|
|
|
70378
70607
|
access: "create"
|
|
70379
70608
|
}
|
|
70380
70609
|
});
|
|
70381
|
-
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;
|
|
70610
|
+
DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher;
|
|
70382
70611
|
DeviceFeature.BatteryOperated;
|
|
70383
70612
|
Object.freeze({
|
|
70384
70613
|
"accessories.getStatus": [{
|
|
@@ -71202,6 +71431,71 @@ Object.freeze({
|
|
|
71202
71431
|
form: "single",
|
|
71203
71432
|
optional: false
|
|
71204
71433
|
}],
|
|
71434
|
+
"dishwasher.getStatus": [{
|
|
71435
|
+
name: "deviceId",
|
|
71436
|
+
form: "single",
|
|
71437
|
+
optional: false
|
|
71438
|
+
}],
|
|
71439
|
+
"dishwasher.pause": [{
|
|
71440
|
+
name: "deviceId",
|
|
71441
|
+
form: "single",
|
|
71442
|
+
optional: false
|
|
71443
|
+
}],
|
|
71444
|
+
"dishwasher.setChildLock": [{
|
|
71445
|
+
name: "deviceId",
|
|
71446
|
+
form: "single",
|
|
71447
|
+
optional: false
|
|
71448
|
+
}],
|
|
71449
|
+
"dishwasher.setExtraDry": [{
|
|
71450
|
+
name: "deviceId",
|
|
71451
|
+
form: "single",
|
|
71452
|
+
optional: false
|
|
71453
|
+
}],
|
|
71454
|
+
"dishwasher.setHalfLoad": [{
|
|
71455
|
+
name: "deviceId",
|
|
71456
|
+
form: "single",
|
|
71457
|
+
optional: false
|
|
71458
|
+
}],
|
|
71459
|
+
"dishwasher.setHygienePlus": [{
|
|
71460
|
+
name: "deviceId",
|
|
71461
|
+
form: "single",
|
|
71462
|
+
optional: false
|
|
71463
|
+
}],
|
|
71464
|
+
"dishwasher.setIntensiveZone": [{
|
|
71465
|
+
name: "deviceId",
|
|
71466
|
+
form: "single",
|
|
71467
|
+
optional: false
|
|
71468
|
+
}],
|
|
71469
|
+
"dishwasher.setOption": [{
|
|
71470
|
+
name: "deviceId",
|
|
71471
|
+
form: "single",
|
|
71472
|
+
optional: false
|
|
71473
|
+
}],
|
|
71474
|
+
"dishwasher.setPower": [{
|
|
71475
|
+
name: "deviceId",
|
|
71476
|
+
form: "single",
|
|
71477
|
+
optional: false
|
|
71478
|
+
}],
|
|
71479
|
+
"dishwasher.setProgram": [{
|
|
71480
|
+
name: "deviceId",
|
|
71481
|
+
form: "single",
|
|
71482
|
+
optional: false
|
|
71483
|
+
}],
|
|
71484
|
+
"dishwasher.setVarioSpeedPlus": [{
|
|
71485
|
+
name: "deviceId",
|
|
71486
|
+
form: "single",
|
|
71487
|
+
optional: false
|
|
71488
|
+
}],
|
|
71489
|
+
"dishwasher.start": [{
|
|
71490
|
+
name: "deviceId",
|
|
71491
|
+
form: "single",
|
|
71492
|
+
optional: false
|
|
71493
|
+
}],
|
|
71494
|
+
"dishwasher.stop": [{
|
|
71495
|
+
name: "deviceId",
|
|
71496
|
+
form: "single",
|
|
71497
|
+
optional: false
|
|
71498
|
+
}],
|
|
71205
71499
|
"doorbell.getStatus": [{
|
|
71206
71500
|
name: "deviceId",
|
|
71207
71501
|
form: "single",
|
|
@@ -71271,6 +71565,11 @@ Object.freeze({
|
|
|
71271
71565
|
form: "single",
|
|
71272
71566
|
optional: false
|
|
71273
71567
|
}],
|
|
71568
|
+
"heatingValve.getStatus": [{
|
|
71569
|
+
name: "deviceId",
|
|
71570
|
+
form: "single",
|
|
71571
|
+
optional: false
|
|
71572
|
+
}],
|
|
71274
71573
|
"humidifier.getStatus": [{
|
|
71275
71574
|
name: "deviceId",
|
|
71276
71575
|
form: "single",
|
|
@@ -74966,6 +75265,40 @@ function createGmailSmtpProvider(deps) {
|
|
|
74966
75265
|
};
|
|
74967
75266
|
}
|
|
74968
75267
|
//#endregion
|
|
75268
|
+
//#region src/google-broker-reconnect-alert.ts
|
|
75269
|
+
function googleBrokerReconnectAlertId(brokerId) {
|
|
75270
|
+
return `google-broker:${brokerId}`;
|
|
75271
|
+
}
|
|
75272
|
+
function isInvalidGrantRefreshError(err) {
|
|
75273
|
+
return (err instanceof Error ? err.message : String(err)).includes("invalid_grant");
|
|
75274
|
+
}
|
|
75275
|
+
function buildGoogleBrokerReconnectAlert(brokerId, brokerName) {
|
|
75276
|
+
const pushLine = `${brokerName}: Google session expired — sign in again`;
|
|
75277
|
+
return {
|
|
75278
|
+
id: googleBrokerReconnectAlertId(brokerId),
|
|
75279
|
+
category: "google.broker-reconnect",
|
|
75280
|
+
severity: "critical",
|
|
75281
|
+
title: "Google needs a new sign-in",
|
|
75282
|
+
message: `${brokerName} needs you to sign in to Google again.`,
|
|
75283
|
+
action: {
|
|
75284
|
+
label: "Sign in again",
|
|
75285
|
+
href: `/addon/google-services/oauth/start?brokerId=${encodeURIComponent(brokerId)}`
|
|
75286
|
+
},
|
|
75287
|
+
status: "active",
|
|
75288
|
+
read: false,
|
|
75289
|
+
createdAt: Date.now(),
|
|
75290
|
+
updatedAt: Date.now(),
|
|
75291
|
+
source: {
|
|
75292
|
+
type: "google-broker",
|
|
75293
|
+
id: brokerId
|
|
75294
|
+
},
|
|
75295
|
+
metadata: {
|
|
75296
|
+
episodeKey: "reconnect",
|
|
75297
|
+
pushLine
|
|
75298
|
+
}
|
|
75299
|
+
};
|
|
75300
|
+
}
|
|
75301
|
+
//#endregion
|
|
74969
75302
|
//#region src/google-oauth.ts
|
|
74970
75303
|
/**
|
|
74971
75304
|
* Google OAuth2 authorization-code + refresh for Calendar API.
|
|
@@ -75581,6 +75914,7 @@ var GoogleServicesAddon = class extends BaseAddon {
|
|
|
75581
75914
|
};
|
|
75582
75915
|
this.registry.setOauth(next);
|
|
75583
75916
|
await this.persistOauthAccounts();
|
|
75917
|
+
if (next.refreshToken.length > 0) this.resolveGoogleBrokerReconnectAlert(brokerId);
|
|
75584
75918
|
if (next.accountEmail && (entry.name === "Google account" || entry.name.startsWith("google_"))) {
|
|
75585
75919
|
const renamed = {
|
|
75586
75920
|
...entry,
|
|
@@ -75713,6 +76047,39 @@ var GoogleServicesAddon = class extends BaseAddon {
|
|
|
75713
76047
|
}
|
|
75714
76048
|
return out.toSorted((a, b) => a.label.localeCompare(b.label));
|
|
75715
76049
|
}
|
|
76050
|
+
async emitGoogleBrokerReconnectAlert(brokerId, brokerName) {
|
|
76051
|
+
const emit = this.ctx.api.alerts?.emit;
|
|
76052
|
+
if (emit === void 0) {
|
|
76053
|
+
this.ctx.logger.warn("google broker reconnect alert skipped — alerts capability missing", { meta: { brokerId } });
|
|
76054
|
+
return;
|
|
76055
|
+
}
|
|
76056
|
+
try {
|
|
76057
|
+
await emit.mutate(buildGoogleBrokerReconnectAlert(brokerId, brokerName));
|
|
76058
|
+
} catch (err) {
|
|
76059
|
+
this.ctx.logger.warn("google broker reconnect alert emit failed", { meta: {
|
|
76060
|
+
brokerId,
|
|
76061
|
+
error: err instanceof Error ? err.message : String(err)
|
|
76062
|
+
} });
|
|
76063
|
+
}
|
|
76064
|
+
}
|
|
76065
|
+
async resolveGoogleBrokerReconnectAlert(brokerId) {
|
|
76066
|
+
const update = this.ctx.api.alerts?.update;
|
|
76067
|
+
if (update === void 0) return;
|
|
76068
|
+
try {
|
|
76069
|
+
await update.mutate({
|
|
76070
|
+
alertId: googleBrokerReconnectAlertId(brokerId),
|
|
76071
|
+
patch: {
|
|
76072
|
+
status: "completed",
|
|
76073
|
+
read: true
|
|
76074
|
+
}
|
|
76075
|
+
});
|
|
76076
|
+
} catch (err) {
|
|
76077
|
+
this.ctx.logger.warn("google broker reconnect alert resolve failed", { meta: {
|
|
76078
|
+
brokerId,
|
|
76079
|
+
error: err instanceof Error ? err.message : String(err)
|
|
76080
|
+
} });
|
|
76081
|
+
}
|
|
76082
|
+
}
|
|
75716
76083
|
async ensureAccessToken(brokerId, opts = {}) {
|
|
75717
76084
|
const entry = this.registry.getEntry(brokerId);
|
|
75718
76085
|
const oauth = this.registry.getOauth(brokerId);
|
|
@@ -75725,10 +76092,16 @@ var GoogleServicesAddon = class extends BaseAddon {
|
|
|
75725
76092
|
accountEmail: oauth.accountEmail
|
|
75726
76093
|
};
|
|
75727
76094
|
if (!opts.forceRefresh && !needsRefresh(state)) return state.accessToken;
|
|
75728
|
-
|
|
75729
|
-
|
|
75730
|
-
|
|
75731
|
-
|
|
76095
|
+
let tokens;
|
|
76096
|
+
try {
|
|
76097
|
+
tokens = await refreshAccessToken({
|
|
76098
|
+
clientId: entry.clientId.trim(),
|
|
76099
|
+
clientSecret: entry.clientSecret.trim()
|
|
76100
|
+
}, state.refreshToken);
|
|
76101
|
+
} catch (err) {
|
|
76102
|
+
if (isInvalidGrantRefreshError(err)) this.emitGoogleBrokerReconnectAlert(brokerId, entry.name);
|
|
76103
|
+
throw err;
|
|
76104
|
+
}
|
|
75732
76105
|
if (typeof tokens.access_token !== "string" || tokens.access_token.trim().length === 0) throw new Error("Google token refresh returned an empty access_token — Sign out and Sign in again");
|
|
75733
76106
|
const nextState = applyTokenResponse(state, tokens);
|
|
75734
76107
|
this.registry.setOauth({
|
package/package.json
CHANGED