@camstack/addon-provider-homeassistant 1.2.654 → 1.2.655
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 +8 -0
- package/dist/addon.js +312 -88
- package/dist/addon.mjs +309 -88
- package/dist/ha-export/ha-export.addon.js +71 -31
- package/dist/ha-export/ha-export.addon.mjs +71 -31
- package/dist/{ha-instance-settings-Bn_Trz6p.js → ha-instance-settings-5Ms7yRju.js} +940 -309
- package/dist/{ha-instance-settings-g5pwb3Fi.mjs → ha-instance-settings-DLDNOmgL.mjs} +899 -310
- package/package.json +6 -2
|
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
enumerable: true
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
//#endregion
|
|
27
|
-
const require_ha_instance_settings = require("../ha-instance-settings-
|
|
27
|
+
const require_ha_instance_settings = require("../ha-instance-settings-5Ms7yRju.js");
|
|
28
28
|
let node_crypto = require("node:crypto");
|
|
29
29
|
require("node:zlib");
|
|
30
30
|
let node_fs = require("node:fs");
|
|
@@ -7672,31 +7672,46 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
|
|
|
7672
7672
|
{
|
|
7673
7673
|
capability: require_ha_instance_settings.deviceExportCapability,
|
|
7674
7674
|
provider: {
|
|
7675
|
-
getStatus: async () => this.buildStatus(),
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7675
|
+
getStatus: async (input) => this.buildStatus(this.brokerScope(require_ha_instance_settings.statusInstanceOf(input))),
|
|
7676
|
+
listInstances: async () => this.config.knownBrokers.map((broker) => ({
|
|
7677
|
+
instanceId: broker.id,
|
|
7678
|
+
name: broker.name,
|
|
7679
|
+
enabled: this.enabledBrokerIds().includes(broker.id),
|
|
7680
|
+
kind: "home-assistant"
|
|
7680
7681
|
})),
|
|
7681
|
-
|
|
7682
|
-
|
|
7682
|
+
listSupportedDeviceKinds: async ({ instanceId }) => {
|
|
7683
|
+
this.brokerScope(instanceId);
|
|
7684
|
+
return [...SUPPORTED_DEVICE_KINDS];
|
|
7685
|
+
},
|
|
7686
|
+
listExposedDevices: async ({ instanceId }) => this.exposedDeviceRows(this.brokerScope(instanceId)),
|
|
7687
|
+
exposeDevice: async ({ instanceId, deviceId }) => this.setBrokerMembership(instanceId, deviceId, true),
|
|
7688
|
+
unexposeDevice: async ({ instanceId, deviceId }) => this.setBrokerMembership(instanceId, deviceId, false),
|
|
7683
7689
|
listSupportedEntityKinds: async () => [
|
|
7684
7690
|
"device",
|
|
7685
7691
|
"action",
|
|
7686
7692
|
"notifier"
|
|
7687
7693
|
],
|
|
7688
|
-
listExposedEntities: async () => {
|
|
7694
|
+
listExposedEntities: async ({ instanceId }) => {
|
|
7695
|
+
const scope = this.brokerScope(instanceId);
|
|
7689
7696
|
await exportedEntities.pruneDeleted();
|
|
7690
|
-
return [...
|
|
7697
|
+
return [...this.exposedDeviceRows(scope).map((row) => ({
|
|
7691
7698
|
entity: {
|
|
7692
7699
|
kind: "device",
|
|
7693
|
-
deviceId
|
|
7700
|
+
deviceId: row.deviceId
|
|
7694
7701
|
},
|
|
7695
|
-
exposedAs:
|
|
7702
|
+
exposedAs: row.exposedAs
|
|
7696
7703
|
})), ...exportedEntities.list()];
|
|
7697
7704
|
},
|
|
7698
|
-
exposeEntity: async ({ entity }) =>
|
|
7699
|
-
|
|
7705
|
+
exposeEntity: async ({ instanceId, entity }) => {
|
|
7706
|
+
if (entity.kind === "device") return this.setBrokerMembership(instanceId, entity.deviceId, true);
|
|
7707
|
+
this.brokerScope(instanceId);
|
|
7708
|
+
return exportedEntities.expose(entity);
|
|
7709
|
+
},
|
|
7710
|
+
unexposeEntity: async ({ instanceId, entity }) => {
|
|
7711
|
+
if (entity.kind === "device") return this.setBrokerMembership(instanceId, entity.deviceId, false);
|
|
7712
|
+
this.brokerScope(instanceId);
|
|
7713
|
+
return exportedEntities.unexpose(entity);
|
|
7714
|
+
},
|
|
7700
7715
|
getDeviceSettingsContribution: async ({ deviceId }) => this.buildContribution(deviceId),
|
|
7701
7716
|
getDeviceLiveContribution: async () => null,
|
|
7702
7717
|
applyDeviceSettingsPatch: async ({ deviceId, patch }) => this.applyDeviceSettingsPatch(deviceId, patch)
|
|
@@ -9820,20 +9835,44 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
|
|
|
9820
9835
|
return bases;
|
|
9821
9836
|
}
|
|
9822
9837
|
/**
|
|
9823
|
-
*
|
|
9824
|
-
*
|
|
9825
|
-
*
|
|
9826
|
-
* and has no notion of a broker; per-broker granularity lives in the
|
|
9827
|
-
* derived Export panel, over the same store. There is exactly one
|
|
9828
|
-
* authority either way.
|
|
9838
|
+
* Every broker this addon knows, enabled or not: a membership write may
|
|
9839
|
+
* target a broker that is switched off (its devices resume when it is turned
|
|
9840
|
+
* back on). A cold `knownBrokers` still counts the enabled ids.
|
|
9829
9841
|
*/
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9842
|
+
knownBrokerIds() {
|
|
9843
|
+
return new Set([...this.config.knownBrokers.map((b) => b.id), ...this.enabledBrokerIds()]);
|
|
9844
|
+
}
|
|
9845
|
+
/**
|
|
9846
|
+
* The brokers a `device-export` read answers over: the named instance, or
|
|
9847
|
+
* (absent) every enabled broker. A broker this addon does not know is
|
|
9848
|
+
* refused, never answered empty.
|
|
9849
|
+
*/
|
|
9850
|
+
brokerScope(instanceId) {
|
|
9851
|
+
if (instanceId === void 0) return this.enabledBrokerIds();
|
|
9852
|
+
if (!this.knownBrokerIds().has(instanceId)) throw new require_ha_instance_settings.ExportInstanceUnknownError("provider-homeassistant", instanceId);
|
|
9853
|
+
return [instanceId];
|
|
9854
|
+
}
|
|
9855
|
+
exposedDeviceRows(scope) {
|
|
9856
|
+
return exposedDeviceIds(this.config.membership, scope).map((deviceId) => ({
|
|
9857
|
+
deviceId,
|
|
9858
|
+
exposedAs: brokersExposing(this.config.membership, deviceId).map((brokerId) => this.brokerName(brokerId)).join(", ")
|
|
9859
|
+
}));
|
|
9860
|
+
}
|
|
9861
|
+
/**
|
|
9862
|
+
* A cap-level expose/unexpose changes ONE broker's membership — the named
|
|
9863
|
+
* instance. There is no write without a target and no "everywhere": the
|
|
9864
|
+
* other brokers' membership is not touched.
|
|
9865
|
+
*/
|
|
9866
|
+
async setBrokerMembership(instanceId, deviceId, exposed) {
|
|
9867
|
+
this.brokerScope(instanceId);
|
|
9868
|
+
const next = setExposed(this.config.membership, instanceId, deviceId, exposed);
|
|
9833
9869
|
if (next === this.config.membership) {
|
|
9834
9870
|
this.ctx.logger.debug("ha-export: membership already in that state, nothing to do", {
|
|
9835
9871
|
tags: { deviceId: Number(deviceId) },
|
|
9836
|
-
meta: {
|
|
9872
|
+
meta: {
|
|
9873
|
+
exposed,
|
|
9874
|
+
brokerId: instanceId
|
|
9875
|
+
}
|
|
9837
9876
|
});
|
|
9838
9877
|
return;
|
|
9839
9878
|
}
|
|
@@ -9842,7 +9881,7 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
|
|
|
9842
9881
|
tags: { deviceId: Number(deviceId) },
|
|
9843
9882
|
meta: {
|
|
9844
9883
|
exposed,
|
|
9845
|
-
|
|
9884
|
+
brokerId: instanceId
|
|
9846
9885
|
}
|
|
9847
9886
|
});
|
|
9848
9887
|
await this.reconcile(exposed ? "expose" : "unexpose");
|
|
@@ -9996,19 +10035,20 @@ var HaExportAddon = class extends require_ha_instance_settings.BaseAddon {
|
|
|
9996
10035
|
await this.reconcile("device-panel");
|
|
9997
10036
|
return { success: true };
|
|
9998
10037
|
}
|
|
9999
|
-
buildStatus() {
|
|
10000
|
-
const enabled =
|
|
10001
|
-
const
|
|
10002
|
-
const
|
|
10038
|
+
buildStatus(scope) {
|
|
10039
|
+
const enabled = scope;
|
|
10040
|
+
const links = [...this.links.entries()].filter(([brokerId]) => scope.includes(brokerId)).map(([, link]) => link);
|
|
10041
|
+
const healthy = links.filter((link) => link.client.healthy).length;
|
|
10042
|
+
const linkFailure = links.map((link) => link.client.failure).filter((failure) => failure !== null)[0]?.text;
|
|
10003
10043
|
return {
|
|
10004
|
-
linkState: enabled.length === 0 ? "unlinked" : healthy ===
|
|
10044
|
+
linkState: enabled.length === 0 ? "unlinked" : healthy === links.length ? "linked" : "error",
|
|
10005
10045
|
exposedDeviceCount: exposedDeviceIds(this.config.membership, enabled).length,
|
|
10006
10046
|
...linkFailure !== void 0 ? { error: linkFailure } : this.lastError !== void 0 ? { error: this.lastError } : {},
|
|
10007
10047
|
setup: {
|
|
10008
10048
|
fields: [
|
|
10009
10049
|
{
|
|
10010
10050
|
label: "Home Assistant instances",
|
|
10011
|
-
value: `${healthy} / ${
|
|
10051
|
+
value: `${healthy} / ${links.length} reachable`
|
|
10012
10052
|
},
|
|
10013
10053
|
{
|
|
10014
10054
|
label: "Last push failure",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $t as
|
|
1
|
+
import { $t as baseUnitOf, At as runExportedAction, Cn as EventCategory, E as addonRoutesCapability, Et as pruneDeletedEntities, G as consumableFormOf, It as sendToExportedTarget, K as consumableKindOf, L as buildAddonRouteProvider, Q as deviceExportCapability, Rt as statusInstanceOf, St as preconditionOf, Xt as BaseAddon, _ as ExportInstanceUnknownError, _n as unknown, an as isReadingQuantity, b as MediaPlayerRepeatSchema, cn as array, d as COCO_TO_MACRO, f as CameraSwitchIdSchema, h as ConsumableStatusSchema, hn as string, m as ConsumableItemSchema, n as listInstancesOrNothing, o as listHomeAssistantBrokers, on as nodePin, p as ConsumableFormSchema, pn as object, r as settingsByBroker, s as AlarmArmModeSchema, t as haInstanceSettingsPortsOver, tn as defineAddonMigrations, u as CAMERA_SWITCH_ORDER, v as FanDirectionSchema, x as PLUG_APPLIANCE_TYPES, y as HvacModeSchema, yt as oauthIntegrationCapability } from "../ha-instance-settings-DLDNOmgL.mjs";
|
|
2
2
|
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
3
3
|
import "node:zlib";
|
|
4
4
|
import "node:fs";
|
|
@@ -7637,31 +7637,46 @@ var HaExportAddon = class extends BaseAddon {
|
|
|
7637
7637
|
{
|
|
7638
7638
|
capability: deviceExportCapability,
|
|
7639
7639
|
provider: {
|
|
7640
|
-
getStatus: async () => this.buildStatus(),
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7640
|
+
getStatus: async (input) => this.buildStatus(this.brokerScope(statusInstanceOf(input))),
|
|
7641
|
+
listInstances: async () => this.config.knownBrokers.map((broker) => ({
|
|
7642
|
+
instanceId: broker.id,
|
|
7643
|
+
name: broker.name,
|
|
7644
|
+
enabled: this.enabledBrokerIds().includes(broker.id),
|
|
7645
|
+
kind: "home-assistant"
|
|
7645
7646
|
})),
|
|
7646
|
-
|
|
7647
|
-
|
|
7647
|
+
listSupportedDeviceKinds: async ({ instanceId }) => {
|
|
7648
|
+
this.brokerScope(instanceId);
|
|
7649
|
+
return [...SUPPORTED_DEVICE_KINDS];
|
|
7650
|
+
},
|
|
7651
|
+
listExposedDevices: async ({ instanceId }) => this.exposedDeviceRows(this.brokerScope(instanceId)),
|
|
7652
|
+
exposeDevice: async ({ instanceId, deviceId }) => this.setBrokerMembership(instanceId, deviceId, true),
|
|
7653
|
+
unexposeDevice: async ({ instanceId, deviceId }) => this.setBrokerMembership(instanceId, deviceId, false),
|
|
7648
7654
|
listSupportedEntityKinds: async () => [
|
|
7649
7655
|
"device",
|
|
7650
7656
|
"action",
|
|
7651
7657
|
"notifier"
|
|
7652
7658
|
],
|
|
7653
|
-
listExposedEntities: async () => {
|
|
7659
|
+
listExposedEntities: async ({ instanceId }) => {
|
|
7660
|
+
const scope = this.brokerScope(instanceId);
|
|
7654
7661
|
await exportedEntities.pruneDeleted();
|
|
7655
|
-
return [...
|
|
7662
|
+
return [...this.exposedDeviceRows(scope).map((row) => ({
|
|
7656
7663
|
entity: {
|
|
7657
7664
|
kind: "device",
|
|
7658
|
-
deviceId
|
|
7665
|
+
deviceId: row.deviceId
|
|
7659
7666
|
},
|
|
7660
|
-
exposedAs:
|
|
7667
|
+
exposedAs: row.exposedAs
|
|
7661
7668
|
})), ...exportedEntities.list()];
|
|
7662
7669
|
},
|
|
7663
|
-
exposeEntity: async ({ entity }) =>
|
|
7664
|
-
|
|
7670
|
+
exposeEntity: async ({ instanceId, entity }) => {
|
|
7671
|
+
if (entity.kind === "device") return this.setBrokerMembership(instanceId, entity.deviceId, true);
|
|
7672
|
+
this.brokerScope(instanceId);
|
|
7673
|
+
return exportedEntities.expose(entity);
|
|
7674
|
+
},
|
|
7675
|
+
unexposeEntity: async ({ instanceId, entity }) => {
|
|
7676
|
+
if (entity.kind === "device") return this.setBrokerMembership(instanceId, entity.deviceId, false);
|
|
7677
|
+
this.brokerScope(instanceId);
|
|
7678
|
+
return exportedEntities.unexpose(entity);
|
|
7679
|
+
},
|
|
7665
7680
|
getDeviceSettingsContribution: async ({ deviceId }) => this.buildContribution(deviceId),
|
|
7666
7681
|
getDeviceLiveContribution: async () => null,
|
|
7667
7682
|
applyDeviceSettingsPatch: async ({ deviceId, patch }) => this.applyDeviceSettingsPatch(deviceId, patch)
|
|
@@ -9785,20 +9800,44 @@ var HaExportAddon = class extends BaseAddon {
|
|
|
9785
9800
|
return bases;
|
|
9786
9801
|
}
|
|
9787
9802
|
/**
|
|
9788
|
-
*
|
|
9789
|
-
*
|
|
9790
|
-
*
|
|
9791
|
-
* and has no notion of a broker; per-broker granularity lives in the
|
|
9792
|
-
* derived Export panel, over the same store. There is exactly one
|
|
9793
|
-
* authority either way.
|
|
9803
|
+
* Every broker this addon knows, enabled or not: a membership write may
|
|
9804
|
+
* target a broker that is switched off (its devices resume when it is turned
|
|
9805
|
+
* back on). A cold `knownBrokers` still counts the enabled ids.
|
|
9794
9806
|
*/
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9807
|
+
knownBrokerIds() {
|
|
9808
|
+
return new Set([...this.config.knownBrokers.map((b) => b.id), ...this.enabledBrokerIds()]);
|
|
9809
|
+
}
|
|
9810
|
+
/**
|
|
9811
|
+
* The brokers a `device-export` read answers over: the named instance, or
|
|
9812
|
+
* (absent) every enabled broker. A broker this addon does not know is
|
|
9813
|
+
* refused, never answered empty.
|
|
9814
|
+
*/
|
|
9815
|
+
brokerScope(instanceId) {
|
|
9816
|
+
if (instanceId === void 0) return this.enabledBrokerIds();
|
|
9817
|
+
if (!this.knownBrokerIds().has(instanceId)) throw new ExportInstanceUnknownError("provider-homeassistant", instanceId);
|
|
9818
|
+
return [instanceId];
|
|
9819
|
+
}
|
|
9820
|
+
exposedDeviceRows(scope) {
|
|
9821
|
+
return exposedDeviceIds(this.config.membership, scope).map((deviceId) => ({
|
|
9822
|
+
deviceId,
|
|
9823
|
+
exposedAs: brokersExposing(this.config.membership, deviceId).map((brokerId) => this.brokerName(brokerId)).join(", ")
|
|
9824
|
+
}));
|
|
9825
|
+
}
|
|
9826
|
+
/**
|
|
9827
|
+
* A cap-level expose/unexpose changes ONE broker's membership — the named
|
|
9828
|
+
* instance. There is no write without a target and no "everywhere": the
|
|
9829
|
+
* other brokers' membership is not touched.
|
|
9830
|
+
*/
|
|
9831
|
+
async setBrokerMembership(instanceId, deviceId, exposed) {
|
|
9832
|
+
this.brokerScope(instanceId);
|
|
9833
|
+
const next = setExposed(this.config.membership, instanceId, deviceId, exposed);
|
|
9798
9834
|
if (next === this.config.membership) {
|
|
9799
9835
|
this.ctx.logger.debug("ha-export: membership already in that state, nothing to do", {
|
|
9800
9836
|
tags: { deviceId: Number(deviceId) },
|
|
9801
|
-
meta: {
|
|
9837
|
+
meta: {
|
|
9838
|
+
exposed,
|
|
9839
|
+
brokerId: instanceId
|
|
9840
|
+
}
|
|
9802
9841
|
});
|
|
9803
9842
|
return;
|
|
9804
9843
|
}
|
|
@@ -9807,7 +9846,7 @@ var HaExportAddon = class extends BaseAddon {
|
|
|
9807
9846
|
tags: { deviceId: Number(deviceId) },
|
|
9808
9847
|
meta: {
|
|
9809
9848
|
exposed,
|
|
9810
|
-
|
|
9849
|
+
brokerId: instanceId
|
|
9811
9850
|
}
|
|
9812
9851
|
});
|
|
9813
9852
|
await this.reconcile(exposed ? "expose" : "unexpose");
|
|
@@ -9961,19 +10000,20 @@ var HaExportAddon = class extends BaseAddon {
|
|
|
9961
10000
|
await this.reconcile("device-panel");
|
|
9962
10001
|
return { success: true };
|
|
9963
10002
|
}
|
|
9964
|
-
buildStatus() {
|
|
9965
|
-
const enabled =
|
|
9966
|
-
const
|
|
9967
|
-
const
|
|
10003
|
+
buildStatus(scope) {
|
|
10004
|
+
const enabled = scope;
|
|
10005
|
+
const links = [...this.links.entries()].filter(([brokerId]) => scope.includes(brokerId)).map(([, link]) => link);
|
|
10006
|
+
const healthy = links.filter((link) => link.client.healthy).length;
|
|
10007
|
+
const linkFailure = links.map((link) => link.client.failure).filter((failure) => failure !== null)[0]?.text;
|
|
9968
10008
|
return {
|
|
9969
|
-
linkState: enabled.length === 0 ? "unlinked" : healthy ===
|
|
10009
|
+
linkState: enabled.length === 0 ? "unlinked" : healthy === links.length ? "linked" : "error",
|
|
9970
10010
|
exposedDeviceCount: exposedDeviceIds(this.config.membership, enabled).length,
|
|
9971
10011
|
...linkFailure !== void 0 ? { error: linkFailure } : this.lastError !== void 0 ? { error: this.lastError } : {},
|
|
9972
10012
|
setup: {
|
|
9973
10013
|
fields: [
|
|
9974
10014
|
{
|
|
9975
10015
|
label: "Home Assistant instances",
|
|
9976
|
-
value: `${healthy} / ${
|
|
10016
|
+
value: `${healthy} / ${links.length} reachable`
|
|
9977
10017
|
},
|
|
9978
10018
|
{
|
|
9979
10019
|
label: "Last push failure",
|