@camstack/addon-provider-homeassistant 1.2.153 → 1.2.155
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/addon.js +138 -1
- package/dist/addon.mjs +138 -1
- package/dist/{dist-DMn4t1u_.js → dist-CERTsNmo.js} +3405 -2846
- package/dist/{dist-evNLjXgk.mjs → dist-DqKiElqb.mjs} +3405 -2852
- package/dist/ha-export/ha-export.addon.js +1 -1
- package/dist/ha-export/ha-export.addon.mjs +1 -1
- package/package.json +4 -1
package/dist/addon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_dist = require("./dist-
|
|
2
|
+
const require_dist = require("./dist-CERTsNmo.js");
|
|
3
3
|
let node_crypto = require("node:crypto");
|
|
4
4
|
let node_zlib = require("node:zlib");
|
|
5
5
|
//#region src/ha-admin-link.ts
|
|
@@ -2290,6 +2290,7 @@ function readBooleanAttr(attrs, key) {
|
|
|
2290
2290
|
//#region src/devices/ha-alarm-panel-device.ts
|
|
2291
2291
|
var COLD_START$9 = {
|
|
2292
2292
|
state: "disarmed",
|
|
2293
|
+
targetMode: null,
|
|
2293
2294
|
availableModes: [],
|
|
2294
2295
|
requiresCode: false,
|
|
2295
2296
|
lastChangedAt: 0
|
|
@@ -2316,6 +2317,7 @@ var HaAlarmPanelDevice = class extends HaBaseChildDevice {
|
|
|
2316
2317
|
const attrs = state.attributes;
|
|
2317
2318
|
this.runtimeState.setCapState("alarm-panel", {
|
|
2318
2319
|
state: lifecycle,
|
|
2320
|
+
targetMode: targetModeFromState(lifecycle),
|
|
2319
2321
|
availableModes: deriveAvailableModes(attrs),
|
|
2320
2322
|
requiresCode: attrs["code_format"] !== void 0 && attrs["code_format"] !== null,
|
|
2321
2323
|
lastChangedAt
|
|
@@ -2354,6 +2356,17 @@ function mapHaState(s) {
|
|
|
2354
2356
|
default: return null;
|
|
2355
2357
|
}
|
|
2356
2358
|
}
|
|
2359
|
+
/** Settled `armed_*` → mode; transitional HA words carry no mode. */
|
|
2360
|
+
function targetModeFromState(state) {
|
|
2361
|
+
switch (state) {
|
|
2362
|
+
case "armed_home": return "home";
|
|
2363
|
+
case "armed_away": return "away";
|
|
2364
|
+
case "armed_night": return "night";
|
|
2365
|
+
case "armed_vacation": return "vacation";
|
|
2366
|
+
case "armed_custom_bypass": return "custom_bypass";
|
|
2367
|
+
default: return null;
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2357
2370
|
function deriveAvailableModes(attrs) {
|
|
2358
2371
|
const sf = attrs["supported_features"];
|
|
2359
2372
|
if (typeof sf !== "number") return [];
|
|
@@ -5130,6 +5143,7 @@ var HaIntegrationManager = class HaIntegrationManager {
|
|
|
5130
5143
|
if (target.deviceId) targetEnvelope["device_id"] = target.deviceId;
|
|
5131
5144
|
if (Object.keys(targetEnvelope).length > 0) message["target"] = targetEnvelope;
|
|
5132
5145
|
if (payload !== void 0 && payload !== null) message["service_data"] = payload;
|
|
5146
|
+
if (target.returnResponse === true) message["return_response"] = true;
|
|
5133
5147
|
const result = await conn.sendMessagePromise(message);
|
|
5134
5148
|
if (result && typeof result === "object") return result;
|
|
5135
5149
|
return null;
|
|
@@ -7071,6 +7085,122 @@ function createHaNotificationOutputProvider(deps) {
|
|
|
7071
7085
|
};
|
|
7072
7086
|
}
|
|
7073
7087
|
//#endregion
|
|
7088
|
+
//#region src/ha-calendar-source.ts
|
|
7089
|
+
function isCalendarEntity(entityId) {
|
|
7090
|
+
return entityId.startsWith("calendar.");
|
|
7091
|
+
}
|
|
7092
|
+
function calendarName(state) {
|
|
7093
|
+
const friendly = state.attributes["friendly_name"];
|
|
7094
|
+
if (typeof friendly === "string" && friendly.trim().length > 0) return friendly.trim();
|
|
7095
|
+
return state.entity_id.replace(/^calendar\./, "").replace(/_/g, " ");
|
|
7096
|
+
}
|
|
7097
|
+
function parseHaDate(value) {
|
|
7098
|
+
if (typeof value !== "string" || value.length === 0) return null;
|
|
7099
|
+
const ms = Date.parse(value.length === 10 ? `${value}T00:00:00` : value);
|
|
7100
|
+
return Number.isFinite(ms) ? ms : null;
|
|
7101
|
+
}
|
|
7102
|
+
function isRecord(x) {
|
|
7103
|
+
return typeof x === "object" && x !== null && !Array.isArray(x);
|
|
7104
|
+
}
|
|
7105
|
+
function asEntityState(raw) {
|
|
7106
|
+
const parsed = HaEntityStateSchema.safeParse(raw);
|
|
7107
|
+
return parsed.success ? parsed.data : null;
|
|
7108
|
+
}
|
|
7109
|
+
/**
|
|
7110
|
+
* HA's `calendar.list_events` response shape (return_response):
|
|
7111
|
+
* `{ response: { [entity_id]: { events: [...] } } }` or a flat
|
|
7112
|
+
* `{ events: [...] }` depending on target width.
|
|
7113
|
+
*/
|
|
7114
|
+
function extractEvents(result, entityId) {
|
|
7115
|
+
if (!isRecord(result)) return [];
|
|
7116
|
+
const response = result["response"];
|
|
7117
|
+
if (isRecord(response)) {
|
|
7118
|
+
const forEntity = response[entityId];
|
|
7119
|
+
if (isRecord(forEntity) && Array.isArray(forEntity["events"])) return forEntity["events"].filter(isRecord);
|
|
7120
|
+
for (const value of Object.values(response)) if (isRecord(value) && Array.isArray(value["events"])) return value["events"].filter(isRecord);
|
|
7121
|
+
}
|
|
7122
|
+
if (Array.isArray(result["events"])) return result["events"].filter(isRecord);
|
|
7123
|
+
return [];
|
|
7124
|
+
}
|
|
7125
|
+
function mapEvent(entityId, raw, index) {
|
|
7126
|
+
const startRaw = raw["start"];
|
|
7127
|
+
const endRaw = raw["end"];
|
|
7128
|
+
const startMs = parseHaDate(isRecord(startRaw) ? startRaw["dateTime"] ?? startRaw["date"] : raw["start"] ?? raw["start_date_time"] ?? raw["dtstart"]);
|
|
7129
|
+
const endMs = parseHaDate(isRecord(endRaw) ? endRaw["dateTime"] ?? endRaw["date"] : raw["end"] ?? raw["end_date_time"] ?? raw["dtend"]) ?? startMs;
|
|
7130
|
+
if (startMs === null || endMs === null) return null;
|
|
7131
|
+
const summary = raw["summary"] ?? raw["title"];
|
|
7132
|
+
const title = typeof summary === "string" ? summary : "(no title)";
|
|
7133
|
+
const uid = raw["uid"] ?? raw["id"];
|
|
7134
|
+
const id = typeof uid === "string" && uid.length > 0 ? `${entityId}:${uid}` : `${entityId}:${String(startMs)}:${String(index)}`;
|
|
7135
|
+
const description = raw["description"];
|
|
7136
|
+
const location = raw["location"];
|
|
7137
|
+
return {
|
|
7138
|
+
id,
|
|
7139
|
+
calendarId: entityId,
|
|
7140
|
+
title,
|
|
7141
|
+
startMs,
|
|
7142
|
+
endMs,
|
|
7143
|
+
...isRecord(startRaw) && typeof startRaw["date"] === "string" || typeof raw["start"] === "string" && raw["start"].length === 10 ? { allDay: true } : {},
|
|
7144
|
+
...typeof description === "string" && description.length > 0 ? { description } : {},
|
|
7145
|
+
...typeof location === "string" && location.length > 0 ? { location } : {}
|
|
7146
|
+
};
|
|
7147
|
+
}
|
|
7148
|
+
function createHaCalendarSource(deps) {
|
|
7149
|
+
return {
|
|
7150
|
+
listCalendars: async () => {
|
|
7151
|
+
const out = [];
|
|
7152
|
+
for (const { manager } of deps.brokers.listManagers()) {
|
|
7153
|
+
const states = manager.snapshotAllStates();
|
|
7154
|
+
for (const [entityId, raw] of Object.entries(states)) {
|
|
7155
|
+
if (!isCalendarEntity(entityId)) continue;
|
|
7156
|
+
const state = asEntityState(raw);
|
|
7157
|
+
if (state === null) continue;
|
|
7158
|
+
out.push({
|
|
7159
|
+
id: entityId,
|
|
7160
|
+
name: calendarName(state),
|
|
7161
|
+
source: "ha",
|
|
7162
|
+
enabled: state.state !== "unavailable"
|
|
7163
|
+
});
|
|
7164
|
+
}
|
|
7165
|
+
}
|
|
7166
|
+
return out;
|
|
7167
|
+
},
|
|
7168
|
+
listEvents: async (input) => {
|
|
7169
|
+
const startIso = new Date(input.startMs).toISOString();
|
|
7170
|
+
const endIso = new Date(input.endMs).toISOString();
|
|
7171
|
+
const wanted = input.calendarIds !== void 0 && input.calendarIds.length > 0 ? new Set(input.calendarIds) : null;
|
|
7172
|
+
const out = [];
|
|
7173
|
+
for (const { brokerId, manager } of deps.brokers.listManagers()) {
|
|
7174
|
+
const states = manager.snapshotAllStates();
|
|
7175
|
+
const entityIds = Object.keys(states).filter((id) => isCalendarEntity(id) && (wanted === null || wanted.has(id)));
|
|
7176
|
+
for (const entityId of entityIds) try {
|
|
7177
|
+
const target = {
|
|
7178
|
+
domain: "calendar",
|
|
7179
|
+
service: "list_events",
|
|
7180
|
+
entityId,
|
|
7181
|
+
returnResponse: true
|
|
7182
|
+
};
|
|
7183
|
+
const rawEvents = extractEvents(await manager.publish(target, {
|
|
7184
|
+
start_date_time: startIso,
|
|
7185
|
+
end_date_time: endIso
|
|
7186
|
+
}), entityId);
|
|
7187
|
+
for (let i = 0; i < rawEvents.length; i += 1) {
|
|
7188
|
+
const mapped = mapEvent(entityId, rawEvents[i], i);
|
|
7189
|
+
if (mapped !== null) out.push(mapped);
|
|
7190
|
+
}
|
|
7191
|
+
} catch (err) {
|
|
7192
|
+
deps.logger.warn("HA calendar.list_events failed", { meta: {
|
|
7193
|
+
entityId,
|
|
7194
|
+
brokerId,
|
|
7195
|
+
error: err instanceof Error ? err.message : String(err)
|
|
7196
|
+
} });
|
|
7197
|
+
}
|
|
7198
|
+
}
|
|
7199
|
+
return out.toSorted((a, b) => a.startMs - b.startMs);
|
|
7200
|
+
}
|
|
7201
|
+
};
|
|
7202
|
+
}
|
|
7203
|
+
//#endregion
|
|
7074
7204
|
//#region src/ha-reconcile-broker.ts
|
|
7075
7205
|
/**
|
|
7076
7206
|
* Run BOTH reconcilers for one broker off a SINGLE shared inventory fetch.
|
|
@@ -7596,6 +7726,13 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
7596
7726
|
{
|
|
7597
7727
|
capability: require_dist.addonRoutesCapability,
|
|
7598
7728
|
provider: createHaIconRouteProvider()
|
|
7729
|
+
},
|
|
7730
|
+
{
|
|
7731
|
+
capability: require_dist.calendarSourceCapability,
|
|
7732
|
+
provider: createHaCalendarSource({
|
|
7733
|
+
brokers: this.requireRegistry(),
|
|
7734
|
+
logger: this.ctx.logger.child("calendar-source")
|
|
7735
|
+
})
|
|
7599
7736
|
}
|
|
7600
7737
|
];
|
|
7601
7738
|
}
|
package/dist/addon.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as connectivityCapability, At as string, B as floodCapability, C as buildAddonRouteProvider, Ct as _enum, D as carbonMonoxideCapability, Dt as number, E as calendarSourceCapability, Et as literal, F as deviceAdoptionCapability, G as lawnMowerControlCapability, H as humidifierCapability, J as motionCapability, K as lockControlCapability, L as enumSensorCapability, M as controlCapability, Mt as unknown, N as coverCapability, Nt as url, O as climateControlCapability, Ot as object, P as deviceAdminLinkCapability, Pt as EventCategory, Q as numericSensorCapability, R as eventEmitterCapability, S as brokerCapability, T as buttonCapability, Tt as discriminatedUnion, U as humiditySensorCapability, V as gasCapability, W as imageCapability, X as notificationOutputCapability, Y as normalizeUnit, Z as notifierCapability, _ as automationControlCapability, _t as DeviceRole, at as scriptRunnerCapability, b as binaryCapability, ct as tamperCapability, d as TargetSchema, dt as vacuumControlCapability, et as parseAdminBase, f as accessoriesCapability, ft as valveCapability, g as ambientLightSensorCapability, gt as DeviceFeature, h as alarmPanelCapability, ht as weatherCapability, it as pressureSensorCapability, j as contactCapability, jt as union, k as colorCapability, kt as record, lt as temperatureSensorCapability, m as airQualitySensorCapability, mt as waterHeaterCapability, n as BaseDevice, nt as prepareNotification, ot as smokeCapability, p as addonRoutesCapability, pt as vibrationCapability, q as mediaPlayerCapability, r as BaseDeviceProvider, rt as presenceCapability, s as EnumSensorDateTimeFormatSchema, st as switchCapability, tt as powerMeterCapability, ut as updateCapability, v as batteryCapability, vt as DeviceType, w as buildDeviceAdminUrl, wt as array, x as brightnessCapability, xt as createEvent, y as bestLocationMatch, yt as errMsg, z as fanControlCapability } from "./dist-DqKiElqb.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
|
|
@@ -2289,6 +2289,7 @@ function readBooleanAttr(attrs, key) {
|
|
|
2289
2289
|
//#region src/devices/ha-alarm-panel-device.ts
|
|
2290
2290
|
var COLD_START$9 = {
|
|
2291
2291
|
state: "disarmed",
|
|
2292
|
+
targetMode: null,
|
|
2292
2293
|
availableModes: [],
|
|
2293
2294
|
requiresCode: false,
|
|
2294
2295
|
lastChangedAt: 0
|
|
@@ -2315,6 +2316,7 @@ var HaAlarmPanelDevice = class extends HaBaseChildDevice {
|
|
|
2315
2316
|
const attrs = state.attributes;
|
|
2316
2317
|
this.runtimeState.setCapState("alarm-panel", {
|
|
2317
2318
|
state: lifecycle,
|
|
2319
|
+
targetMode: targetModeFromState(lifecycle),
|
|
2318
2320
|
availableModes: deriveAvailableModes(attrs),
|
|
2319
2321
|
requiresCode: attrs["code_format"] !== void 0 && attrs["code_format"] !== null,
|
|
2320
2322
|
lastChangedAt
|
|
@@ -2353,6 +2355,17 @@ function mapHaState(s) {
|
|
|
2353
2355
|
default: return null;
|
|
2354
2356
|
}
|
|
2355
2357
|
}
|
|
2358
|
+
/** Settled `armed_*` → mode; transitional HA words carry no mode. */
|
|
2359
|
+
function targetModeFromState(state) {
|
|
2360
|
+
switch (state) {
|
|
2361
|
+
case "armed_home": return "home";
|
|
2362
|
+
case "armed_away": return "away";
|
|
2363
|
+
case "armed_night": return "night";
|
|
2364
|
+
case "armed_vacation": return "vacation";
|
|
2365
|
+
case "armed_custom_bypass": return "custom_bypass";
|
|
2366
|
+
default: return null;
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2356
2369
|
function deriveAvailableModes(attrs) {
|
|
2357
2370
|
const sf = attrs["supported_features"];
|
|
2358
2371
|
if (typeof sf !== "number") return [];
|
|
@@ -5129,6 +5142,7 @@ var HaIntegrationManager = class HaIntegrationManager {
|
|
|
5129
5142
|
if (target.deviceId) targetEnvelope["device_id"] = target.deviceId;
|
|
5130
5143
|
if (Object.keys(targetEnvelope).length > 0) message["target"] = targetEnvelope;
|
|
5131
5144
|
if (payload !== void 0 && payload !== null) message["service_data"] = payload;
|
|
5145
|
+
if (target.returnResponse === true) message["return_response"] = true;
|
|
5132
5146
|
const result = await conn.sendMessagePromise(message);
|
|
5133
5147
|
if (result && typeof result === "object") return result;
|
|
5134
5148
|
return null;
|
|
@@ -7070,6 +7084,122 @@ function createHaNotificationOutputProvider(deps) {
|
|
|
7070
7084
|
};
|
|
7071
7085
|
}
|
|
7072
7086
|
//#endregion
|
|
7087
|
+
//#region src/ha-calendar-source.ts
|
|
7088
|
+
function isCalendarEntity(entityId) {
|
|
7089
|
+
return entityId.startsWith("calendar.");
|
|
7090
|
+
}
|
|
7091
|
+
function calendarName(state) {
|
|
7092
|
+
const friendly = state.attributes["friendly_name"];
|
|
7093
|
+
if (typeof friendly === "string" && friendly.trim().length > 0) return friendly.trim();
|
|
7094
|
+
return state.entity_id.replace(/^calendar\./, "").replace(/_/g, " ");
|
|
7095
|
+
}
|
|
7096
|
+
function parseHaDate(value) {
|
|
7097
|
+
if (typeof value !== "string" || value.length === 0) return null;
|
|
7098
|
+
const ms = Date.parse(value.length === 10 ? `${value}T00:00:00` : value);
|
|
7099
|
+
return Number.isFinite(ms) ? ms : null;
|
|
7100
|
+
}
|
|
7101
|
+
function isRecord(x) {
|
|
7102
|
+
return typeof x === "object" && x !== null && !Array.isArray(x);
|
|
7103
|
+
}
|
|
7104
|
+
function asEntityState(raw) {
|
|
7105
|
+
const parsed = HaEntityStateSchema.safeParse(raw);
|
|
7106
|
+
return parsed.success ? parsed.data : null;
|
|
7107
|
+
}
|
|
7108
|
+
/**
|
|
7109
|
+
* HA's `calendar.list_events` response shape (return_response):
|
|
7110
|
+
* `{ response: { [entity_id]: { events: [...] } } }` or a flat
|
|
7111
|
+
* `{ events: [...] }` depending on target width.
|
|
7112
|
+
*/
|
|
7113
|
+
function extractEvents(result, entityId) {
|
|
7114
|
+
if (!isRecord(result)) return [];
|
|
7115
|
+
const response = result["response"];
|
|
7116
|
+
if (isRecord(response)) {
|
|
7117
|
+
const forEntity = response[entityId];
|
|
7118
|
+
if (isRecord(forEntity) && Array.isArray(forEntity["events"])) return forEntity["events"].filter(isRecord);
|
|
7119
|
+
for (const value of Object.values(response)) if (isRecord(value) && Array.isArray(value["events"])) return value["events"].filter(isRecord);
|
|
7120
|
+
}
|
|
7121
|
+
if (Array.isArray(result["events"])) return result["events"].filter(isRecord);
|
|
7122
|
+
return [];
|
|
7123
|
+
}
|
|
7124
|
+
function mapEvent(entityId, raw, index) {
|
|
7125
|
+
const startRaw = raw["start"];
|
|
7126
|
+
const endRaw = raw["end"];
|
|
7127
|
+
const startMs = parseHaDate(isRecord(startRaw) ? startRaw["dateTime"] ?? startRaw["date"] : raw["start"] ?? raw["start_date_time"] ?? raw["dtstart"]);
|
|
7128
|
+
const endMs = parseHaDate(isRecord(endRaw) ? endRaw["dateTime"] ?? endRaw["date"] : raw["end"] ?? raw["end_date_time"] ?? raw["dtend"]) ?? startMs;
|
|
7129
|
+
if (startMs === null || endMs === null) return null;
|
|
7130
|
+
const summary = raw["summary"] ?? raw["title"];
|
|
7131
|
+
const title = typeof summary === "string" ? summary : "(no title)";
|
|
7132
|
+
const uid = raw["uid"] ?? raw["id"];
|
|
7133
|
+
const id = typeof uid === "string" && uid.length > 0 ? `${entityId}:${uid}` : `${entityId}:${String(startMs)}:${String(index)}`;
|
|
7134
|
+
const description = raw["description"];
|
|
7135
|
+
const location = raw["location"];
|
|
7136
|
+
return {
|
|
7137
|
+
id,
|
|
7138
|
+
calendarId: entityId,
|
|
7139
|
+
title,
|
|
7140
|
+
startMs,
|
|
7141
|
+
endMs,
|
|
7142
|
+
...isRecord(startRaw) && typeof startRaw["date"] === "string" || typeof raw["start"] === "string" && raw["start"].length === 10 ? { allDay: true } : {},
|
|
7143
|
+
...typeof description === "string" && description.length > 0 ? { description } : {},
|
|
7144
|
+
...typeof location === "string" && location.length > 0 ? { location } : {}
|
|
7145
|
+
};
|
|
7146
|
+
}
|
|
7147
|
+
function createHaCalendarSource(deps) {
|
|
7148
|
+
return {
|
|
7149
|
+
listCalendars: async () => {
|
|
7150
|
+
const out = [];
|
|
7151
|
+
for (const { manager } of deps.brokers.listManagers()) {
|
|
7152
|
+
const states = manager.snapshotAllStates();
|
|
7153
|
+
for (const [entityId, raw] of Object.entries(states)) {
|
|
7154
|
+
if (!isCalendarEntity(entityId)) continue;
|
|
7155
|
+
const state = asEntityState(raw);
|
|
7156
|
+
if (state === null) continue;
|
|
7157
|
+
out.push({
|
|
7158
|
+
id: entityId,
|
|
7159
|
+
name: calendarName(state),
|
|
7160
|
+
source: "ha",
|
|
7161
|
+
enabled: state.state !== "unavailable"
|
|
7162
|
+
});
|
|
7163
|
+
}
|
|
7164
|
+
}
|
|
7165
|
+
return out;
|
|
7166
|
+
},
|
|
7167
|
+
listEvents: async (input) => {
|
|
7168
|
+
const startIso = new Date(input.startMs).toISOString();
|
|
7169
|
+
const endIso = new Date(input.endMs).toISOString();
|
|
7170
|
+
const wanted = input.calendarIds !== void 0 && input.calendarIds.length > 0 ? new Set(input.calendarIds) : null;
|
|
7171
|
+
const out = [];
|
|
7172
|
+
for (const { brokerId, manager } of deps.brokers.listManagers()) {
|
|
7173
|
+
const states = manager.snapshotAllStates();
|
|
7174
|
+
const entityIds = Object.keys(states).filter((id) => isCalendarEntity(id) && (wanted === null || wanted.has(id)));
|
|
7175
|
+
for (const entityId of entityIds) try {
|
|
7176
|
+
const target = {
|
|
7177
|
+
domain: "calendar",
|
|
7178
|
+
service: "list_events",
|
|
7179
|
+
entityId,
|
|
7180
|
+
returnResponse: true
|
|
7181
|
+
};
|
|
7182
|
+
const rawEvents = extractEvents(await manager.publish(target, {
|
|
7183
|
+
start_date_time: startIso,
|
|
7184
|
+
end_date_time: endIso
|
|
7185
|
+
}), entityId);
|
|
7186
|
+
for (let i = 0; i < rawEvents.length; i += 1) {
|
|
7187
|
+
const mapped = mapEvent(entityId, rawEvents[i], i);
|
|
7188
|
+
if (mapped !== null) out.push(mapped);
|
|
7189
|
+
}
|
|
7190
|
+
} catch (err) {
|
|
7191
|
+
deps.logger.warn("HA calendar.list_events failed", { meta: {
|
|
7192
|
+
entityId,
|
|
7193
|
+
brokerId,
|
|
7194
|
+
error: err instanceof Error ? err.message : String(err)
|
|
7195
|
+
} });
|
|
7196
|
+
}
|
|
7197
|
+
}
|
|
7198
|
+
return out.toSorted((a, b) => a.startMs - b.startMs);
|
|
7199
|
+
}
|
|
7200
|
+
};
|
|
7201
|
+
}
|
|
7202
|
+
//#endregion
|
|
7073
7203
|
//#region src/ha-reconcile-broker.ts
|
|
7074
7204
|
/**
|
|
7075
7205
|
* Run BOTH reconcilers for one broker off a SINGLE shared inventory fetch.
|
|
@@ -7595,6 +7725,13 @@ var HaProviderAddon = class HaProviderAddon extends BaseDeviceProvider {
|
|
|
7595
7725
|
{
|
|
7596
7726
|
capability: addonRoutesCapability,
|
|
7597
7727
|
provider: createHaIconRouteProvider()
|
|
7728
|
+
},
|
|
7729
|
+
{
|
|
7730
|
+
capability: calendarSourceCapability,
|
|
7731
|
+
provider: createHaCalendarSource({
|
|
7732
|
+
brokers: this.requireRegistry(),
|
|
7733
|
+
logger: this.ctx.logger.child("calendar-source")
|
|
7734
|
+
})
|
|
7598
7735
|
}
|
|
7599
7736
|
];
|
|
7600
7737
|
}
|