@camstack/addon-provider-homeassistant 1.2.639 → 1.2.640
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 +7 -0
- package/dist/addon.js +529 -460
- package/dist/addon.mjs +85 -16
- package/dist/{dist-C_XoeULr.js → ha-broker-source-0HGmZj7D.js} +2225 -853
- package/dist/{dist-Cvz76AD1.mjs → ha-broker-source-FHFpUlgq.mjs} +2208 -854
- package/dist/ha-export/ha-export.addon.js +209 -86
- package/dist/ha-export/ha-export.addon.mjs +164 -41
- package/i18n/en.json +2 -2
- package/i18n/it.json +2 -2
- package/package.json +1 -1
package/dist/addon.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as humiditySensorCapability, $t as discriminatedUnion, A as brokerCapability, At as tryConvertUnit, Bt as errMsg, C as alarmPanelCapability, Ct as scriptRunnerCapability, D as bestLocationMatch, Dt as tamperCapability, E as batteryCapability, Et as switchCapability, F as carbonMonoxideCapability, Ft as waterHeaterCapability, G as deviceAdoptionCapability, Gt as defineEntryKind, H as controlCapability, Ht as RecordSecretUnavailableError, I as climateControlCapability, It as weatherCapability, J as eventEmitterCapability, Kt as defineRecordKinds, L as colorCapability, Lt as DeviceFeature, M as buildDeviceAdminUrl, Mt as vacuumControlCapability, N as buttonCapability, Nt as valveCapability, O as binaryCapability, Ot as temperatureSensorCapability, P as calendarSourceCapability, Pt as vibrationCapability, Q as humidifierCapability, Qt as boolean, R as connectivityCapability, Rt as DeviceRole, S as airQualitySensorCapability, St as runningStateCapability, T as automationControlCapability, Tt as smokeCapability, U as coverCapability, Ut as baseUnitOf, V as contactCapability, W as deviceAdminLinkCapability, Wt as createEvent, X as floodCapability, Xt as _enum, Y as fanControlCapability, Z as gasCapability, Zt as array, _t as quantityFromUnit, a as BaseDevice, an as union, at as motionCapability, b as accessoriesCapability, bt as runningFromMediaPlayer, cn as EventCategory, ct as notifierCapability, dt as parseAdminBase, en as literal, et as imageCapability, ft as powerMeterCapability, ht as pressureSensorCapability, in as string, it as mediaPlayerCapability, j as buildAddonRouteProvider, jt as updateCapability, k as brightnessCapability, kt as tryConvertDelta, lt as numericSensorCapability, mt as presenceCapability, nn as object, nt as lawnMowerControlCapability, o as BaseDeviceProvider, on as unknown, ot as normalizeUnit, p as EnumSensorDateTimeFormatSchema, pt as prepareNotification, q as enumSensorCapability, qt as entryBody, rn as record, rt as lockControlCapability, sn as url, st as notificationOutputCapability, t as HA_BROKER_KIND, tn as number, tt as ingestReading, v as RUNNING_STATE_COLD, w as ambientLightSensorCapability, x as addonRoutesCapability, xt as runningFromVacuumState, y as TargetSchema, yt as runningFromLawnMower, zt as DeviceType } from "./ha-broker-source-FHFpUlgq.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
|
|
4
4
|
//#region src/ha-admin-link.ts
|
|
@@ -7230,21 +7230,27 @@ function haConfigSchema() {
|
|
|
7230
7230
|
title: "Home Assistant notify",
|
|
7231
7231
|
titleKey: "provider-homeassistant:haConfig.s_connection.title",
|
|
7232
7232
|
fields: [{
|
|
7233
|
-
type: "
|
|
7233
|
+
type: "broker-select",
|
|
7234
|
+
key: "brokerId",
|
|
7235
|
+
label: "Broker",
|
|
7236
|
+
labelKey: "provider-homeassistant:haConfig.s_connection.brokerId.label",
|
|
7237
|
+
description: "The Home Assistant connection the notification goes through.",
|
|
7238
|
+
descriptionKey: "provider-homeassistant:haConfig.s_connection.brokerId.description",
|
|
7239
|
+
brokerKind: HA_BROKER_KIND
|
|
7240
|
+
}, {
|
|
7241
|
+
type: "select",
|
|
7234
7242
|
key: "service",
|
|
7235
7243
|
label: "Notify service",
|
|
7236
7244
|
labelKey: "provider-homeassistant:haConfig.s_connection.service.label",
|
|
7237
7245
|
required: true,
|
|
7246
|
+
options: [],
|
|
7238
7247
|
placeholder: "mobile_app_pixel_7",
|
|
7239
|
-
description: "
|
|
7240
|
-
descriptionKey: "provider-homeassistant:haConfig.s_connection.service.description"
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
labelKey: "provider-homeassistant:haConfig.s_connection.brokerId.label",
|
|
7246
|
-
description: "Optional; blank uses the only configured broker.",
|
|
7247
|
-
descriptionKey: "provider-homeassistant:haConfig.s_connection.brokerId.description"
|
|
7248
|
+
description: "Loaded from the broker once it is picked. If the list does not load, type the part after `notify.`.",
|
|
7249
|
+
descriptionKey: "provider-homeassistant:haConfig.s_connection.service.description",
|
|
7250
|
+
discoverOptions: {
|
|
7251
|
+
kind: HA_NOTIFICATION_KIND,
|
|
7252
|
+
dependsOn: ["brokerId"]
|
|
7253
|
+
}
|
|
7248
7254
|
}]
|
|
7249
7255
|
}] };
|
|
7250
7256
|
}
|
|
@@ -7385,24 +7391,70 @@ function buildNotifyServiceData(prepared) {
|
|
|
7385
7391
|
* `get_services` returns `{ [domain]: { [service]: {...} } }`; we read the
|
|
7386
7392
|
* `notify` domain. mobile_app_* services (rich push features) sort first.
|
|
7387
7393
|
*/
|
|
7388
|
-
function parseNotifyServices(result, brokerId) {
|
|
7394
|
+
function parseNotifyServices(result, brokerId, deviceNames) {
|
|
7389
7395
|
if (typeof result !== "object" || result === null) return [];
|
|
7390
7396
|
const notify = result["notify"];
|
|
7391
7397
|
if (typeof notify !== "object" || notify === null) return [];
|
|
7392
|
-
return [...Object.
|
|
7398
|
+
return [...Object.entries(notify)].sort(([a], [b]) => {
|
|
7393
7399
|
const am = a.startsWith("mobile_app_") ? 0 : 1;
|
|
7394
7400
|
const bm = b.startsWith("mobile_app_") ? 0 : 1;
|
|
7395
7401
|
if (am !== bm) return am - bm;
|
|
7396
7402
|
return a.localeCompare(b);
|
|
7397
|
-
}).map((service) => ({
|
|
7403
|
+
}).map(([service, definition]) => ({
|
|
7398
7404
|
kind: HA_NOTIFICATION_KIND,
|
|
7399
|
-
suggestedName:
|
|
7405
|
+
suggestedName: friendlyServiceName(service, definition, deviceNames),
|
|
7400
7406
|
config: {
|
|
7401
7407
|
service,
|
|
7402
7408
|
...brokerId !== void 0 ? { brokerId } : {}
|
|
7403
7409
|
}
|
|
7404
7410
|
}));
|
|
7405
7411
|
}
|
|
7412
|
+
function nonEmptyText(value) {
|
|
7413
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
7414
|
+
}
|
|
7415
|
+
/** `alexa_media_echo` -> `Alexa Media Echo`. */
|
|
7416
|
+
function prettifyServiceId(service) {
|
|
7417
|
+
return service.split("_").filter((word) => word.length > 0).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
7418
|
+
}
|
|
7419
|
+
/**
|
|
7420
|
+
* The name an operator recognises: the device name for a mobile app, else the
|
|
7421
|
+
* service's own `name`, else its `description`, else the prettified id.
|
|
7422
|
+
*/
|
|
7423
|
+
function friendlyServiceName(service, definition, deviceNames) {
|
|
7424
|
+
const device = deviceNames?.get(service);
|
|
7425
|
+
if (device !== void 0) return device;
|
|
7426
|
+
if (typeof definition === "object" && definition !== null) {
|
|
7427
|
+
const fields = { ...definition };
|
|
7428
|
+
const name = nonEmptyText(fields["name"]);
|
|
7429
|
+
if (name !== void 0) return name;
|
|
7430
|
+
const description = nonEmptyText(fields["description"]);
|
|
7431
|
+
if (description !== void 0) return description;
|
|
7432
|
+
}
|
|
7433
|
+
return prettifyServiceId(service);
|
|
7434
|
+
}
|
|
7435
|
+
/** HA's slug of a device name, as it appears in `mobile_app_<slug>`. */
|
|
7436
|
+
function slugifyDeviceName(name) {
|
|
7437
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
7438
|
+
}
|
|
7439
|
+
/**
|
|
7440
|
+
* `mobile_app_<slug>` -> device name, read from a `config/device_registry/list`
|
|
7441
|
+
* reply. Only devices of the mobile_app integration count; the name the user
|
|
7442
|
+
* gave wins over the one the app reported.
|
|
7443
|
+
*/
|
|
7444
|
+
function mobileAppDeviceNames(registry) {
|
|
7445
|
+
const names = /* @__PURE__ */ new Map();
|
|
7446
|
+
if (!Array.isArray(registry)) return names;
|
|
7447
|
+
for (const entry of registry) {
|
|
7448
|
+
if (typeof entry !== "object" || entry === null) continue;
|
|
7449
|
+
const device = { ...entry };
|
|
7450
|
+
const identifiers = device["identifiers"];
|
|
7451
|
+
if (!(Array.isArray(identifiers) && identifiers.some((pair) => Array.isArray(pair) && pair[0] === "mobile_app"))) continue;
|
|
7452
|
+
const name = nonEmptyText(device["name_by_user"]) ?? nonEmptyText(device["name"]);
|
|
7453
|
+
if (name === void 0) continue;
|
|
7454
|
+
names.set(`mobile_app_${slugifyDeviceName(name)}`, name);
|
|
7455
|
+
}
|
|
7456
|
+
return names;
|
|
7457
|
+
}
|
|
7406
7458
|
/**
|
|
7407
7459
|
* CRUD over the `ha-notification-targets` record kind.
|
|
7408
7460
|
*
|
|
@@ -7556,12 +7608,24 @@ function createHaNotificationOutputProvider(deps) {
|
|
|
7556
7608
|
},
|
|
7557
7609
|
discoverTargets: async ({ kind, config }) => {
|
|
7558
7610
|
if (kind !== "homeassistant") return [];
|
|
7611
|
+
const deviceNamesOf = async (brokerId) => {
|
|
7612
|
+
if (deps.listDevices === void 0) return /* @__PURE__ */ new Map();
|
|
7613
|
+
try {
|
|
7614
|
+
return mobileAppDeviceNames(await deps.listDevices(brokerId));
|
|
7615
|
+
} catch (err) {
|
|
7616
|
+
logger?.warn("ha device registry read failed; naming services from their ids", { meta: {
|
|
7617
|
+
brokerId,
|
|
7618
|
+
error: errMsg(err)
|
|
7619
|
+
} });
|
|
7620
|
+
return /* @__PURE__ */ new Map();
|
|
7621
|
+
}
|
|
7622
|
+
};
|
|
7559
7623
|
const explicit = config ? readBrokerId(config) : void 0;
|
|
7560
7624
|
const brokerIds = explicit ? [explicit] : [...deps.listBrokerIds()];
|
|
7561
7625
|
const out = [];
|
|
7562
7626
|
for (const brokerId of brokerIds) try {
|
|
7563
7627
|
const result = await deps.getServices(brokerId);
|
|
7564
|
-
out.push(...parseNotifyServices(result, brokerId));
|
|
7628
|
+
out.push(...parseNotifyServices(result, brokerId, await deviceNamesOf(brokerId)));
|
|
7565
7629
|
} catch (err) {
|
|
7566
7630
|
logger?.warn("ha get_services discovery failed", { meta: {
|
|
7567
7631
|
brokerId,
|
|
@@ -8430,6 +8494,11 @@ var HaProviderAddon = class HaProviderAddon extends BaseDeviceProvider {
|
|
|
8430
8494
|
if (!manager) throw new Error(`ha-broker '${brokerId}' not found`);
|
|
8431
8495
|
return manager.sendMessage({ type: "get_services" });
|
|
8432
8496
|
},
|
|
8497
|
+
listDevices: async (brokerId) => {
|
|
8498
|
+
const manager = this.requireRegistry().getManager(brokerId);
|
|
8499
|
+
if (!manager) throw new Error(`ha-broker '${brokerId}' not found`);
|
|
8500
|
+
return manager.sendMessage({ type: "config/device_registry/list" });
|
|
8501
|
+
},
|
|
8433
8502
|
listBrokerIds: () => this.activeBrokers.map((b) => b.id),
|
|
8434
8503
|
logger: this.ctx.logger.child("notification-output")
|
|
8435
8504
|
});
|