@camstack/addon-provider-homeassistant 1.2.153 → 1.2.154
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 +125 -1
- package/dist/addon.mjs +125 -1
- package/dist/{dist-evNLjXgk.mjs → dist-CvzpCuzm.mjs} +248 -41
- package/dist/{dist-DMn4t1u_.js → dist-DLQgcqQT.js} +253 -40
- 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-DLQgcqQT.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
|
|
@@ -5130,6 +5130,7 @@ var HaIntegrationManager = class HaIntegrationManager {
|
|
|
5130
5130
|
if (target.deviceId) targetEnvelope["device_id"] = target.deviceId;
|
|
5131
5131
|
if (Object.keys(targetEnvelope).length > 0) message["target"] = targetEnvelope;
|
|
5132
5132
|
if (payload !== void 0 && payload !== null) message["service_data"] = payload;
|
|
5133
|
+
if (target.returnResponse === true) message["return_response"] = true;
|
|
5133
5134
|
const result = await conn.sendMessagePromise(message);
|
|
5134
5135
|
if (result && typeof result === "object") return result;
|
|
5135
5136
|
return null;
|
|
@@ -7071,6 +7072,122 @@ function createHaNotificationOutputProvider(deps) {
|
|
|
7071
7072
|
};
|
|
7072
7073
|
}
|
|
7073
7074
|
//#endregion
|
|
7075
|
+
//#region src/ha-calendar-source.ts
|
|
7076
|
+
function isCalendarEntity(entityId) {
|
|
7077
|
+
return entityId.startsWith("calendar.");
|
|
7078
|
+
}
|
|
7079
|
+
function calendarName(state) {
|
|
7080
|
+
const friendly = state.attributes["friendly_name"];
|
|
7081
|
+
if (typeof friendly === "string" && friendly.trim().length > 0) return friendly.trim();
|
|
7082
|
+
return state.entity_id.replace(/^calendar\./, "").replace(/_/g, " ");
|
|
7083
|
+
}
|
|
7084
|
+
function parseHaDate(value) {
|
|
7085
|
+
if (typeof value !== "string" || value.length === 0) return null;
|
|
7086
|
+
const ms = Date.parse(value.length === 10 ? `${value}T00:00:00` : value);
|
|
7087
|
+
return Number.isFinite(ms) ? ms : null;
|
|
7088
|
+
}
|
|
7089
|
+
function isRecord(x) {
|
|
7090
|
+
return typeof x === "object" && x !== null && !Array.isArray(x);
|
|
7091
|
+
}
|
|
7092
|
+
function asEntityState(raw) {
|
|
7093
|
+
const parsed = HaEntityStateSchema.safeParse(raw);
|
|
7094
|
+
return parsed.success ? parsed.data : null;
|
|
7095
|
+
}
|
|
7096
|
+
/**
|
|
7097
|
+
* HA's `calendar.list_events` response shape (return_response):
|
|
7098
|
+
* `{ response: { [entity_id]: { events: [...] } } }` or a flat
|
|
7099
|
+
* `{ events: [...] }` depending on target width.
|
|
7100
|
+
*/
|
|
7101
|
+
function extractEvents(result, entityId) {
|
|
7102
|
+
if (!isRecord(result)) return [];
|
|
7103
|
+
const response = result["response"];
|
|
7104
|
+
if (isRecord(response)) {
|
|
7105
|
+
const forEntity = response[entityId];
|
|
7106
|
+
if (isRecord(forEntity) && Array.isArray(forEntity["events"])) return forEntity["events"].filter(isRecord);
|
|
7107
|
+
for (const value of Object.values(response)) if (isRecord(value) && Array.isArray(value["events"])) return value["events"].filter(isRecord);
|
|
7108
|
+
}
|
|
7109
|
+
if (Array.isArray(result["events"])) return result["events"].filter(isRecord);
|
|
7110
|
+
return [];
|
|
7111
|
+
}
|
|
7112
|
+
function mapEvent(entityId, raw, index) {
|
|
7113
|
+
const startRaw = raw["start"];
|
|
7114
|
+
const endRaw = raw["end"];
|
|
7115
|
+
const startMs = parseHaDate(isRecord(startRaw) ? startRaw["dateTime"] ?? startRaw["date"] : raw["start"] ?? raw["start_date_time"] ?? raw["dtstart"]);
|
|
7116
|
+
const endMs = parseHaDate(isRecord(endRaw) ? endRaw["dateTime"] ?? endRaw["date"] : raw["end"] ?? raw["end_date_time"] ?? raw["dtend"]) ?? startMs;
|
|
7117
|
+
if (startMs === null || endMs === null) return null;
|
|
7118
|
+
const summary = raw["summary"] ?? raw["title"];
|
|
7119
|
+
const title = typeof summary === "string" ? summary : "(no title)";
|
|
7120
|
+
const uid = raw["uid"] ?? raw["id"];
|
|
7121
|
+
const id = typeof uid === "string" && uid.length > 0 ? `${entityId}:${uid}` : `${entityId}:${String(startMs)}:${String(index)}`;
|
|
7122
|
+
const description = raw["description"];
|
|
7123
|
+
const location = raw["location"];
|
|
7124
|
+
return {
|
|
7125
|
+
id,
|
|
7126
|
+
calendarId: entityId,
|
|
7127
|
+
title,
|
|
7128
|
+
startMs,
|
|
7129
|
+
endMs,
|
|
7130
|
+
...isRecord(startRaw) && typeof startRaw["date"] === "string" || typeof raw["start"] === "string" && raw["start"].length === 10 ? { allDay: true } : {},
|
|
7131
|
+
...typeof description === "string" && description.length > 0 ? { description } : {},
|
|
7132
|
+
...typeof location === "string" && location.length > 0 ? { location } : {}
|
|
7133
|
+
};
|
|
7134
|
+
}
|
|
7135
|
+
function createHaCalendarSource(deps) {
|
|
7136
|
+
return {
|
|
7137
|
+
listCalendars: async () => {
|
|
7138
|
+
const out = [];
|
|
7139
|
+
for (const { manager } of deps.brokers.listManagers()) {
|
|
7140
|
+
const states = manager.snapshotAllStates();
|
|
7141
|
+
for (const [entityId, raw] of Object.entries(states)) {
|
|
7142
|
+
if (!isCalendarEntity(entityId)) continue;
|
|
7143
|
+
const state = asEntityState(raw);
|
|
7144
|
+
if (state === null) continue;
|
|
7145
|
+
out.push({
|
|
7146
|
+
id: entityId,
|
|
7147
|
+
name: calendarName(state),
|
|
7148
|
+
source: "ha",
|
|
7149
|
+
enabled: state.state !== "unavailable"
|
|
7150
|
+
});
|
|
7151
|
+
}
|
|
7152
|
+
}
|
|
7153
|
+
return out;
|
|
7154
|
+
},
|
|
7155
|
+
listEvents: async (input) => {
|
|
7156
|
+
const startIso = new Date(input.startMs).toISOString();
|
|
7157
|
+
const endIso = new Date(input.endMs).toISOString();
|
|
7158
|
+
const wanted = input.calendarIds !== void 0 && input.calendarIds.length > 0 ? new Set(input.calendarIds) : null;
|
|
7159
|
+
const out = [];
|
|
7160
|
+
for (const { brokerId, manager } of deps.brokers.listManagers()) {
|
|
7161
|
+
const states = manager.snapshotAllStates();
|
|
7162
|
+
const entityIds = Object.keys(states).filter((id) => isCalendarEntity(id) && (wanted === null || wanted.has(id)));
|
|
7163
|
+
for (const entityId of entityIds) try {
|
|
7164
|
+
const target = {
|
|
7165
|
+
domain: "calendar",
|
|
7166
|
+
service: "list_events",
|
|
7167
|
+
entityId,
|
|
7168
|
+
returnResponse: true
|
|
7169
|
+
};
|
|
7170
|
+
const rawEvents = extractEvents(await manager.publish(target, {
|
|
7171
|
+
start_date_time: startIso,
|
|
7172
|
+
end_date_time: endIso
|
|
7173
|
+
}), entityId);
|
|
7174
|
+
for (let i = 0; i < rawEvents.length; i += 1) {
|
|
7175
|
+
const mapped = mapEvent(entityId, rawEvents[i], i);
|
|
7176
|
+
if (mapped !== null) out.push(mapped);
|
|
7177
|
+
}
|
|
7178
|
+
} catch (err) {
|
|
7179
|
+
deps.logger.warn("HA calendar.list_events failed", { meta: {
|
|
7180
|
+
entityId,
|
|
7181
|
+
brokerId,
|
|
7182
|
+
error: err instanceof Error ? err.message : String(err)
|
|
7183
|
+
} });
|
|
7184
|
+
}
|
|
7185
|
+
}
|
|
7186
|
+
return out.toSorted((a, b) => a.startMs - b.startMs);
|
|
7187
|
+
}
|
|
7188
|
+
};
|
|
7189
|
+
}
|
|
7190
|
+
//#endregion
|
|
7074
7191
|
//#region src/ha-reconcile-broker.ts
|
|
7075
7192
|
/**
|
|
7076
7193
|
* Run BOTH reconcilers for one broker off a SINGLE shared inventory fetch.
|
|
@@ -7596,6 +7713,13 @@ var HaProviderAddon = class HaProviderAddon extends require_dist.BaseDeviceProvi
|
|
|
7596
7713
|
{
|
|
7597
7714
|
capability: require_dist.addonRoutesCapability,
|
|
7598
7715
|
provider: createHaIconRouteProvider()
|
|
7716
|
+
},
|
|
7717
|
+
{
|
|
7718
|
+
capability: require_dist.calendarSourceCapability,
|
|
7719
|
+
provider: createHaCalendarSource({
|
|
7720
|
+
brokers: this.requireRegistry(),
|
|
7721
|
+
logger: this.ctx.logger.child("calendar-source")
|
|
7722
|
+
})
|
|
7599
7723
|
}
|
|
7600
7724
|
];
|
|
7601
7725
|
}
|
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-CvzpCuzm.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
|
|
@@ -5129,6 +5129,7 @@ var HaIntegrationManager = class HaIntegrationManager {
|
|
|
5129
5129
|
if (target.deviceId) targetEnvelope["device_id"] = target.deviceId;
|
|
5130
5130
|
if (Object.keys(targetEnvelope).length > 0) message["target"] = targetEnvelope;
|
|
5131
5131
|
if (payload !== void 0 && payload !== null) message["service_data"] = payload;
|
|
5132
|
+
if (target.returnResponse === true) message["return_response"] = true;
|
|
5132
5133
|
const result = await conn.sendMessagePromise(message);
|
|
5133
5134
|
if (result && typeof result === "object") return result;
|
|
5134
5135
|
return null;
|
|
@@ -7070,6 +7071,122 @@ function createHaNotificationOutputProvider(deps) {
|
|
|
7070
7071
|
};
|
|
7071
7072
|
}
|
|
7072
7073
|
//#endregion
|
|
7074
|
+
//#region src/ha-calendar-source.ts
|
|
7075
|
+
function isCalendarEntity(entityId) {
|
|
7076
|
+
return entityId.startsWith("calendar.");
|
|
7077
|
+
}
|
|
7078
|
+
function calendarName(state) {
|
|
7079
|
+
const friendly = state.attributes["friendly_name"];
|
|
7080
|
+
if (typeof friendly === "string" && friendly.trim().length > 0) return friendly.trim();
|
|
7081
|
+
return state.entity_id.replace(/^calendar\./, "").replace(/_/g, " ");
|
|
7082
|
+
}
|
|
7083
|
+
function parseHaDate(value) {
|
|
7084
|
+
if (typeof value !== "string" || value.length === 0) return null;
|
|
7085
|
+
const ms = Date.parse(value.length === 10 ? `${value}T00:00:00` : value);
|
|
7086
|
+
return Number.isFinite(ms) ? ms : null;
|
|
7087
|
+
}
|
|
7088
|
+
function isRecord(x) {
|
|
7089
|
+
return typeof x === "object" && x !== null && !Array.isArray(x);
|
|
7090
|
+
}
|
|
7091
|
+
function asEntityState(raw) {
|
|
7092
|
+
const parsed = HaEntityStateSchema.safeParse(raw);
|
|
7093
|
+
return parsed.success ? parsed.data : null;
|
|
7094
|
+
}
|
|
7095
|
+
/**
|
|
7096
|
+
* HA's `calendar.list_events` response shape (return_response):
|
|
7097
|
+
* `{ response: { [entity_id]: { events: [...] } } }` or a flat
|
|
7098
|
+
* `{ events: [...] }` depending on target width.
|
|
7099
|
+
*/
|
|
7100
|
+
function extractEvents(result, entityId) {
|
|
7101
|
+
if (!isRecord(result)) return [];
|
|
7102
|
+
const response = result["response"];
|
|
7103
|
+
if (isRecord(response)) {
|
|
7104
|
+
const forEntity = response[entityId];
|
|
7105
|
+
if (isRecord(forEntity) && Array.isArray(forEntity["events"])) return forEntity["events"].filter(isRecord);
|
|
7106
|
+
for (const value of Object.values(response)) if (isRecord(value) && Array.isArray(value["events"])) return value["events"].filter(isRecord);
|
|
7107
|
+
}
|
|
7108
|
+
if (Array.isArray(result["events"])) return result["events"].filter(isRecord);
|
|
7109
|
+
return [];
|
|
7110
|
+
}
|
|
7111
|
+
function mapEvent(entityId, raw, index) {
|
|
7112
|
+
const startRaw = raw["start"];
|
|
7113
|
+
const endRaw = raw["end"];
|
|
7114
|
+
const startMs = parseHaDate(isRecord(startRaw) ? startRaw["dateTime"] ?? startRaw["date"] : raw["start"] ?? raw["start_date_time"] ?? raw["dtstart"]);
|
|
7115
|
+
const endMs = parseHaDate(isRecord(endRaw) ? endRaw["dateTime"] ?? endRaw["date"] : raw["end"] ?? raw["end_date_time"] ?? raw["dtend"]) ?? startMs;
|
|
7116
|
+
if (startMs === null || endMs === null) return null;
|
|
7117
|
+
const summary = raw["summary"] ?? raw["title"];
|
|
7118
|
+
const title = typeof summary === "string" ? summary : "(no title)";
|
|
7119
|
+
const uid = raw["uid"] ?? raw["id"];
|
|
7120
|
+
const id = typeof uid === "string" && uid.length > 0 ? `${entityId}:${uid}` : `${entityId}:${String(startMs)}:${String(index)}`;
|
|
7121
|
+
const description = raw["description"];
|
|
7122
|
+
const location = raw["location"];
|
|
7123
|
+
return {
|
|
7124
|
+
id,
|
|
7125
|
+
calendarId: entityId,
|
|
7126
|
+
title,
|
|
7127
|
+
startMs,
|
|
7128
|
+
endMs,
|
|
7129
|
+
...isRecord(startRaw) && typeof startRaw["date"] === "string" || typeof raw["start"] === "string" && raw["start"].length === 10 ? { allDay: true } : {},
|
|
7130
|
+
...typeof description === "string" && description.length > 0 ? { description } : {},
|
|
7131
|
+
...typeof location === "string" && location.length > 0 ? { location } : {}
|
|
7132
|
+
};
|
|
7133
|
+
}
|
|
7134
|
+
function createHaCalendarSource(deps) {
|
|
7135
|
+
return {
|
|
7136
|
+
listCalendars: async () => {
|
|
7137
|
+
const out = [];
|
|
7138
|
+
for (const { manager } of deps.brokers.listManagers()) {
|
|
7139
|
+
const states = manager.snapshotAllStates();
|
|
7140
|
+
for (const [entityId, raw] of Object.entries(states)) {
|
|
7141
|
+
if (!isCalendarEntity(entityId)) continue;
|
|
7142
|
+
const state = asEntityState(raw);
|
|
7143
|
+
if (state === null) continue;
|
|
7144
|
+
out.push({
|
|
7145
|
+
id: entityId,
|
|
7146
|
+
name: calendarName(state),
|
|
7147
|
+
source: "ha",
|
|
7148
|
+
enabled: state.state !== "unavailable"
|
|
7149
|
+
});
|
|
7150
|
+
}
|
|
7151
|
+
}
|
|
7152
|
+
return out;
|
|
7153
|
+
},
|
|
7154
|
+
listEvents: async (input) => {
|
|
7155
|
+
const startIso = new Date(input.startMs).toISOString();
|
|
7156
|
+
const endIso = new Date(input.endMs).toISOString();
|
|
7157
|
+
const wanted = input.calendarIds !== void 0 && input.calendarIds.length > 0 ? new Set(input.calendarIds) : null;
|
|
7158
|
+
const out = [];
|
|
7159
|
+
for (const { brokerId, manager } of deps.brokers.listManagers()) {
|
|
7160
|
+
const states = manager.snapshotAllStates();
|
|
7161
|
+
const entityIds = Object.keys(states).filter((id) => isCalendarEntity(id) && (wanted === null || wanted.has(id)));
|
|
7162
|
+
for (const entityId of entityIds) try {
|
|
7163
|
+
const target = {
|
|
7164
|
+
domain: "calendar",
|
|
7165
|
+
service: "list_events",
|
|
7166
|
+
entityId,
|
|
7167
|
+
returnResponse: true
|
|
7168
|
+
};
|
|
7169
|
+
const rawEvents = extractEvents(await manager.publish(target, {
|
|
7170
|
+
start_date_time: startIso,
|
|
7171
|
+
end_date_time: endIso
|
|
7172
|
+
}), entityId);
|
|
7173
|
+
for (let i = 0; i < rawEvents.length; i += 1) {
|
|
7174
|
+
const mapped = mapEvent(entityId, rawEvents[i], i);
|
|
7175
|
+
if (mapped !== null) out.push(mapped);
|
|
7176
|
+
}
|
|
7177
|
+
} catch (err) {
|
|
7178
|
+
deps.logger.warn("HA calendar.list_events failed", { meta: {
|
|
7179
|
+
entityId,
|
|
7180
|
+
brokerId,
|
|
7181
|
+
error: err instanceof Error ? err.message : String(err)
|
|
7182
|
+
} });
|
|
7183
|
+
}
|
|
7184
|
+
}
|
|
7185
|
+
return out.toSorted((a, b) => a.startMs - b.startMs);
|
|
7186
|
+
}
|
|
7187
|
+
};
|
|
7188
|
+
}
|
|
7189
|
+
//#endregion
|
|
7073
7190
|
//#region src/ha-reconcile-broker.ts
|
|
7074
7191
|
/**
|
|
7075
7192
|
* Run BOTH reconcilers for one broker off a SINGLE shared inventory fetch.
|
|
@@ -7595,6 +7712,13 @@ var HaProviderAddon = class HaProviderAddon extends BaseDeviceProvider {
|
|
|
7595
7712
|
{
|
|
7596
7713
|
capability: addonRoutesCapability,
|
|
7597
7714
|
provider: createHaIconRouteProvider()
|
|
7715
|
+
},
|
|
7716
|
+
{
|
|
7717
|
+
capability: calendarSourceCapability,
|
|
7718
|
+
provider: createHaCalendarSource({
|
|
7719
|
+
brokers: this.requireRegistry(),
|
|
7720
|
+
logger: this.ctx.logger.child("calendar-source")
|
|
7721
|
+
})
|
|
7598
7722
|
}
|
|
7599
7723
|
];
|
|
7600
7724
|
}
|
|
@@ -20687,14 +20687,52 @@ var NcAlarmNonBlockingEditSchema = object({
|
|
|
20687
20687
|
nonBlocking: boolean()
|
|
20688
20688
|
});
|
|
20689
20689
|
/**
|
|
20690
|
+
* Controllable openings: opt IN to blocking (default is do not block). Contacts
|
|
20691
|
+
* keep using {@link NcAlarmNonBlockingEditSchema}.
|
|
20692
|
+
*/
|
|
20693
|
+
var NcAlarmBlockingEditSchema = object({
|
|
20694
|
+
mode: AlarmArmModeSchema,
|
|
20695
|
+
deviceId: number().int().positive(),
|
|
20696
|
+
/** true = on the list (blocks when open); false = off the list (default). */
|
|
20697
|
+
blocking: boolean()
|
|
20698
|
+
});
|
|
20699
|
+
/**
|
|
20700
|
+
* Controllable openings: opt OUT of secure-on-arm (default is secure ON —
|
|
20701
|
+
* close / lock / turn off when this mode arms).
|
|
20702
|
+
*/
|
|
20703
|
+
var NcAlarmSecureOnArmEditSchema = object({
|
|
20704
|
+
mode: AlarmArmModeSchema,
|
|
20705
|
+
deviceId: number().int().positive(),
|
|
20706
|
+
/** true = secure on arm (default); false = do not actuate on arm. */
|
|
20707
|
+
secureOnArm: boolean()
|
|
20708
|
+
});
|
|
20709
|
+
/**
|
|
20710
|
+
* One arm mode's device-id list (non-blocking, blocking, or secure-on-arm-off).
|
|
20711
|
+
*/
|
|
20712
|
+
var NcAlarmModeDeviceListSchema = object({
|
|
20713
|
+
mode: AlarmArmModeSchema,
|
|
20714
|
+
deviceIds: array(number().int()).max(200)
|
|
20715
|
+
});
|
|
20716
|
+
/**
|
|
20717
|
+
* One arm mode's non-blocking list: devices that may be open when that mode
|
|
20718
|
+
* arms, without the arm being refused.
|
|
20719
|
+
*/
|
|
20720
|
+
var NcAlarmNonBlockingSchema = NcAlarmModeDeviceListSchema;
|
|
20721
|
+
/** Controllable devices that DO block when open (opt-in; default empty). */
|
|
20722
|
+
var NcAlarmBlockingSchema = NcAlarmModeDeviceListSchema;
|
|
20723
|
+
/**
|
|
20724
|
+
* Controllable devices that do NOT secure on arm (opt-out; default empty =
|
|
20725
|
+
* every controllable secures).
|
|
20726
|
+
*/
|
|
20727
|
+
var NcAlarmSecureOnArmOffSchema = NcAlarmModeDeviceListSchema;
|
|
20728
|
+
/**
|
|
20690
20729
|
* The per-mode lists, at most one per mode. Two lists for one mode have no
|
|
20691
20730
|
* meaning a reader could agree on (union? the last one?), so they are refused
|
|
20692
20731
|
* at the boundary rather than interpreted.
|
|
20693
20732
|
*/
|
|
20694
|
-
var NcAlarmNonBlockingListSchema = array(
|
|
20695
|
-
|
|
20696
|
-
|
|
20697
|
-
})).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
|
|
20733
|
+
var NcAlarmNonBlockingListSchema = array(NcAlarmNonBlockingSchema).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
|
|
20734
|
+
var NcAlarmBlockingListSchema = array(NcAlarmBlockingSchema).max(8).refine(uniqueModes, { message: "blocking: at most one list per arm mode" });
|
|
20735
|
+
var NcAlarmSecureOnArmOffListSchema = array(NcAlarmSecureOnArmOffSchema).max(8).refine(uniqueModes, { message: "secureOnArmOff: at most one list per arm mode" });
|
|
20698
20736
|
/**
|
|
20699
20737
|
* The three durations — global, and per mode since D697 — the panel's state
|
|
20700
20738
|
* machine runs on, who hears about its transitions, and which openings each mode tolerates.
|
|
@@ -20737,9 +20775,23 @@ var NcAlarmSettingsSchema = object({
|
|
|
20737
20775
|
* arm (a window left ajar for the cat under `home`, say). At most one entry
|
|
20738
20776
|
* per mode is meaningful. Defaulted to `[]` so a blob stored before D630
|
|
20739
20777
|
* parses as "every opening blocks" — the behaviour it was written under.
|
|
20778
|
+
* Contacts use this list; controllable openings use {@link blocking} instead
|
|
20779
|
+
* (default: do not block).
|
|
20740
20780
|
*/
|
|
20741
20781
|
nonBlocking: NcAlarmNonBlockingListSchema.default([]),
|
|
20742
20782
|
/**
|
|
20783
|
+
* Per arm mode, controllable openings that DO refuse the arm when open.
|
|
20784
|
+
* Default `[]` = none block (secure-on-arm closes them instead). Absent on a
|
|
20785
|
+
* blob older than this field — read as empty.
|
|
20786
|
+
*/
|
|
20787
|
+
blocking: NcAlarmBlockingListSchema.default([]),
|
|
20788
|
+
/**
|
|
20789
|
+
* Per arm mode, controllable openings that must NOT be actuated on arm.
|
|
20790
|
+
* Default `[]` = every controllable secures (close / lock / off). Absent on
|
|
20791
|
+
* an older blob — read as empty (secure ON).
|
|
20792
|
+
*/
|
|
20793
|
+
secureOnArmOff: NcAlarmSecureOnArmOffListSchema.default([]),
|
|
20794
|
+
/**
|
|
20743
20795
|
* Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
|
|
20744
20796
|
* without a field, uses the global value above — so `[]`, the default, is exactly the
|
|
20745
20797
|
* behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
|
|
@@ -20749,7 +20801,7 @@ var NcAlarmSettingsSchema = object({
|
|
|
20749
20801
|
/**
|
|
20750
20802
|
* Every field optional — a tab edits one control at a time.
|
|
20751
20803
|
*
|
|
20752
|
-
*
|
|
20804
|
+
* List fields and `modeDelays` are re-declared WITHOUT their defaults:
|
|
20753
20805
|
* `.partial()` does not remove an inner `.default()`, so a patch that never
|
|
20754
20806
|
* named the field would parse to `[]` and wipe every mode's list on an
|
|
20755
20807
|
* unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
|
|
@@ -20757,11 +20809,15 @@ var NcAlarmSettingsSchema = object({
|
|
|
20757
20809
|
*/
|
|
20758
20810
|
var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
|
|
20759
20811
|
nonBlocking: NcAlarmNonBlockingListSchema,
|
|
20812
|
+
blocking: NcAlarmBlockingListSchema,
|
|
20813
|
+
secureOnArmOff: NcAlarmSecureOnArmOffListSchema,
|
|
20760
20814
|
/** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
|
|
20761
20815
|
modeDelays: NcAlarmModeDelaysEditListSchema,
|
|
20762
20816
|
/** ONE membership change; the panel applies it to the list it holds at its turn. */
|
|
20763
|
-
nonBlockingEdit: NcAlarmNonBlockingEditSchema
|
|
20764
|
-
|
|
20817
|
+
nonBlockingEdit: NcAlarmNonBlockingEditSchema,
|
|
20818
|
+
blockingEdit: NcAlarmBlockingEditSchema,
|
|
20819
|
+
secureOnArmEdit: NcAlarmSecureOnArmEditSchema
|
|
20820
|
+
}).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" }).refine((p) => p.blocking === void 0 || p.blockingEdit === void 0, { message: "blocking and blockingEdit are exclusive — send the whole lists or one edit" }).refine((p) => p.secureOnArmOff === void 0 || p.secureOnArmEdit === void 0, { message: "secureOnArmOff and secureOnArmEdit are exclusive — send the whole lists or one edit" });
|
|
20765
20821
|
/**
|
|
20766
20822
|
* What one arm mode actually arms, DERIVED from the enabled rules gated on it.
|
|
20767
20823
|
* Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
|
|
@@ -20876,7 +20932,13 @@ var NcAlarmSensorStateSchema = object({
|
|
|
20876
20932
|
/** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
|
|
20877
20933
|
unknownWhy: _enum(["read-failed", "unknown-word"]).nullable(),
|
|
20878
20934
|
/** The device manager's liveness as the centre mirrors it; null = not known. */
|
|
20879
|
-
online: boolean().nullable()
|
|
20935
|
+
online: boolean().nullable(),
|
|
20936
|
+
/**
|
|
20937
|
+
* True when the opening is a cover / lock / switch — the table shows the
|
|
20938
|
+
* Secure-on-arm switch and uses the controllable defaults. False for contacts
|
|
20939
|
+
* and for non-openings. Defaulted so an older hub answer still parses.
|
|
20940
|
+
*/
|
|
20941
|
+
controllable: boolean().default(false)
|
|
20880
20942
|
});
|
|
20881
20943
|
var NcAlarmSensorsInputSchema = object({ deviceIds: array(number().int().positive()).max(500) });
|
|
20882
20944
|
var NcAlarmSensorsSchema = object({
|
|
@@ -29395,6 +29457,74 @@ var buttonCapability = {
|
|
|
29395
29457
|
}) }
|
|
29396
29458
|
};
|
|
29397
29459
|
/**
|
|
29460
|
+
* `calendar-source` — collection cap exposing per-provider calendars and
|
|
29461
|
+
* their events. Every addon that contributes calendars (Home Assistant,
|
|
29462
|
+
* a future Google Calendar addon, …) registers a provider here. The hub
|
|
29463
|
+
* singleton `calendars` walks the collection and merges the answers.
|
|
29464
|
+
*
|
|
29465
|
+
* Mirrors `addon-pages-source`: the public listing is a different shape
|
|
29466
|
+
* (source-stamped ids) and lives on the aggregator.
|
|
29467
|
+
*/
|
|
29468
|
+
var CalendarSourceKindSchema = _enum(["ha", "addon"]);
|
|
29469
|
+
var CalendarInfoSchema = object({
|
|
29470
|
+
/** Provider-local id (e.g. HA `calendar.family`). The aggregator prefixes. */
|
|
29471
|
+
id: string().min(1),
|
|
29472
|
+
name: string().min(1),
|
|
29473
|
+
source: CalendarSourceKindSchema,
|
|
29474
|
+
enabled: boolean()
|
|
29475
|
+
});
|
|
29476
|
+
var CalendarEventSchema = object({
|
|
29477
|
+
id: string().min(1),
|
|
29478
|
+
calendarId: string().min(1),
|
|
29479
|
+
title: string(),
|
|
29480
|
+
startMs: number().int(),
|
|
29481
|
+
endMs: number().int(),
|
|
29482
|
+
allDay: boolean().optional(),
|
|
29483
|
+
description: string().optional(),
|
|
29484
|
+
location: string().optional()
|
|
29485
|
+
});
|
|
29486
|
+
var CalendarListEventsInputSchema = object({
|
|
29487
|
+
calendarIds: array(string().min(1)).max(64).optional(),
|
|
29488
|
+
startMs: number().int(),
|
|
29489
|
+
endMs: number().int()
|
|
29490
|
+
});
|
|
29491
|
+
var calendarSourceCapability = {
|
|
29492
|
+
name: "calendar-source",
|
|
29493
|
+
scope: "system",
|
|
29494
|
+
mode: "collection",
|
|
29495
|
+
internal: true,
|
|
29496
|
+
methods: {
|
|
29497
|
+
listCalendars: method(_void(), array(CalendarInfoSchema).readonly(), { auth: "admin" }),
|
|
29498
|
+
listEvents: method(CalendarListEventsInputSchema, array(CalendarEventSchema).readonly(), { auth: "admin" })
|
|
29499
|
+
}
|
|
29500
|
+
};
|
|
29501
|
+
/**
|
|
29502
|
+
* `calendars` — system-scoped singleton. Public surface admin-ui and the
|
|
29503
|
+
* notification-center calendar-events producer consume.
|
|
29504
|
+
*
|
|
29505
|
+
* Walks every `calendar-source` provider, stamps each calendar with a
|
|
29506
|
+
* cluster-stable id (`<sourceAddonId>:<localId>`) and the providing
|
|
29507
|
+
* addon's id, and fans `listEvents` out the same way. Home Assistant
|
|
29508
|
+
* import is a built-in refresh of the HA source rather than a second
|
|
29509
|
+
* registry — `importFromHomeAssistant` asks that source to re-discover.
|
|
29510
|
+
*/
|
|
29511
|
+
var CalendarEntrySchema = CalendarInfoSchema.extend({
|
|
29512
|
+
/** Cluster-stable id: `<providerAddonId>:<localId>`. */
|
|
29513
|
+
id: string().min(1),
|
|
29514
|
+
/** The addon that registered the calendar-source provider. */
|
|
29515
|
+
providerAddonId: string().min(1).optional()
|
|
29516
|
+
});
|
|
29517
|
+
var CalendarImportResultSchema = object({
|
|
29518
|
+
imported: number().int().nonnegative(),
|
|
29519
|
+
/** Absent when no HA calendar-source provider was reachable. */
|
|
29520
|
+
providerAddonId: string().min(1).optional(),
|
|
29521
|
+
error: string().optional()
|
|
29522
|
+
});
|
|
29523
|
+
method(_void(), array(CalendarEntrySchema).readonly(), { auth: "admin" }), method(CalendarListEventsInputSchema, array(CalendarEventSchema).readonly(), { auth: "admin" }), method(_void(), CalendarImportResultSchema, {
|
|
29524
|
+
auth: "admin",
|
|
29525
|
+
kind: "mutation"
|
|
29526
|
+
});
|
|
29527
|
+
/**
|
|
29398
29528
|
* camera-credentials — device-scoped cap exposing the camera's network
|
|
29399
29529
|
* + auth surface in a vendor-neutral shape.
|
|
29400
29530
|
*
|
|
@@ -33943,38 +34073,52 @@ DeviceType.Camera, method(object({
|
|
|
33943
34073
|
deviceId: number(),
|
|
33944
34074
|
status: OsdStatusSchema
|
|
33945
34075
|
});
|
|
34076
|
+
_enum([
|
|
34077
|
+
"value",
|
|
34078
|
+
"unit",
|
|
34079
|
+
"full"
|
|
34080
|
+
]);
|
|
34081
|
+
_enum([
|
|
34082
|
+
"value+unit",
|
|
34083
|
+
"value",
|
|
34084
|
+
"unit"
|
|
34085
|
+
]);
|
|
34086
|
+
/**
|
|
34087
|
+
* How the operator reached the leaf device. `deviceId` is ALWAYS the
|
|
34088
|
+
* OSD-supported leaf that is read; `containerId` is set when the pick
|
|
34089
|
+
* went through a container (gateway) first.
|
|
34090
|
+
*/
|
|
34091
|
+
var OsdTemplatePickSchema = object({
|
|
34092
|
+
containerId: number().int().optional(),
|
|
34093
|
+
deviceId: number().int()
|
|
34094
|
+
});
|
|
33946
34095
|
/**
|
|
33947
|
-
*
|
|
33948
|
-
*
|
|
33949
|
-
*
|
|
33950
|
-
*
|
|
33951
|
-
* comes from, and it must not — a driver that grew a "show the temperature
|
|
33952
|
-
* here" feature would grow it once per vendor.
|
|
33953
|
-
*
|
|
33954
|
-
* This cap owns the other half: a per-(camera, slot) BINDING that says
|
|
33955
|
-
* which value feeds the slot, how it is formatted, and under which
|
|
33956
|
-
* conditions it is shown at all. One addon renders every binding on every
|
|
33957
|
-
* camera, so a new source costs zero driver code.
|
|
33958
|
-
*
|
|
33959
|
-
* Three deliberate choices, each with a rejected alternative:
|
|
33960
|
-
*
|
|
33961
|
-
* 1. A source is `(capName, valuePath)` over the kernel's device
|
|
33962
|
-
* runtime-state mirror — NOT a closed enum of source kinds. Every
|
|
33963
|
-
* cap-keyed slice a device publishes is bindable the day the cap
|
|
33964
|
-
* ships. The rejected alternative (one enum member per source, with
|
|
33965
|
-
* a resolver branch each) is what makes "add the humidity too" a
|
|
33966
|
-
* code change.
|
|
33967
|
-
* 2. The display gate reuses `NcConditionsSchema` verbatim — the
|
|
33968
|
-
* notification centre's condition vocabulary — rather than a parallel
|
|
33969
|
-
* model. An operator who has learned one condition editor has learned
|
|
33970
|
-
* both.
|
|
33971
|
-
* 3. Because the renderer's facts are device STATE and not a detection
|
|
33972
|
-
* record, only a SUBSET of that vocabulary can be answered here.
|
|
33973
|
-
* `setSlotBinding` REJECTS the rest at write time (see
|
|
33974
|
-
* `getConditionSupport`). It does not accept-then-fail-closed: a
|
|
33975
|
-
* condition that can never be true renders a permanently blank
|
|
33976
|
-
* overlay, and a blank overlay looks exactly like a broken camera.
|
|
34096
|
+
* One named binding inside a multi-device template: device path + unit
|
|
34097
|
+
* selection + precision. The parser expands `{alias}`, `{alias.value}`,
|
|
34098
|
+
* `{alias.unit}`, or `{alias.full}` from the same binding — there is no
|
|
34099
|
+
* per-binding format lock.
|
|
33977
34100
|
*/
|
|
34101
|
+
var OsdTemplateBindingSchema = object({
|
|
34102
|
+
/** Token stem in the parser, e.g. `t` → `{t}` / `{t.value}`. Unique within the template. */
|
|
34103
|
+
alias: string().min(1).max(32).regex(/^[A-Za-z][A-Za-z0-9_-]*$/, "alias must start with a letter"),
|
|
34104
|
+
pick: OsdTemplatePickSchema,
|
|
34105
|
+
capName: string().min(1).max(64),
|
|
34106
|
+
valuePath: string().min(1).max(64),
|
|
34107
|
+
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
34108
|
+
displayUnit: string().max(16).optional(),
|
|
34109
|
+
maxDecimals: number().int().min(0).max(4).default(1)
|
|
34110
|
+
});
|
|
34111
|
+
/**
|
|
34112
|
+
* A named template: bindings (alias → leaf field) + a parser that
|
|
34113
|
+
* references `{alias}` / `{alias.value}` / `{alias.unit}` / `{alias.full}`.
|
|
34114
|
+
*/
|
|
34115
|
+
var OsdNamedTemplateSchema = object({
|
|
34116
|
+
id: string().min(1).max(64),
|
|
34117
|
+
name: string().min(1).max(64),
|
|
34118
|
+
bindings: array(OsdTemplateBindingSchema).max(32).default([]),
|
|
34119
|
+
/** Parser with alias placeholders, e.g. `{t.value} {t.unit} / {h}`. */
|
|
34120
|
+
parser: string().max(256).default("")
|
|
34121
|
+
});
|
|
33978
34122
|
/** Where a slot's value comes from. */
|
|
33979
34123
|
var OsdSourceSchema = discriminatedUnion("kind", [
|
|
33980
34124
|
object({
|
|
@@ -33993,11 +34137,17 @@ var OsdSourceSchema = discriminatedUnion("kind", [
|
|
|
33993
34137
|
deviceId: number().int().optional(),
|
|
33994
34138
|
capName: string().min(1).max(64),
|
|
33995
34139
|
/** Dot path inside the slice, e.g. `detected`, `value`, `mode`. */
|
|
33996
|
-
valuePath: string().min(1).max(64)
|
|
34140
|
+
valuePath: string().min(1).max(64),
|
|
34141
|
+
/** Convert TO this unit at render. Absent = no conversion. */
|
|
34142
|
+
displayUnit: string().max(16).optional()
|
|
33997
34143
|
}),
|
|
33998
34144
|
object({
|
|
33999
34145
|
kind: literal("latest-recognition"),
|
|
34000
34146
|
recognition: _enum(["person", "plate"])
|
|
34147
|
+
}),
|
|
34148
|
+
object({
|
|
34149
|
+
kind: literal("template"),
|
|
34150
|
+
templateId: string().min(1).max(64)
|
|
34001
34151
|
})
|
|
34002
34152
|
]);
|
|
34003
34153
|
var OsdSlotBindingSchema = object({
|
|
@@ -34013,7 +34163,10 @@ var OsdSlotBindingSchema = object({
|
|
|
34013
34163
|
* documented workaround for firmwares that reject `.` in overlay text.
|
|
34014
34164
|
*/
|
|
34015
34165
|
maxDecimals: number().int().min(0).max(4).default(1),
|
|
34016
|
-
/**
|
|
34166
|
+
/**
|
|
34167
|
+
* Appended via `${unit}` when no unit conversion produces a label.
|
|
34168
|
+
* Prefer `source.displayUnit` for converted device-state values.
|
|
34169
|
+
*/
|
|
34017
34170
|
unitLabel: string().max(8).optional(),
|
|
34018
34171
|
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
34019
34172
|
valueMap: record(string(), string()).optional(),
|
|
@@ -34122,6 +34275,12 @@ method(object({ deviceId: number().int() }), object({
|
|
|
34122
34275
|
}), method(object({ deviceId: number().int() }), object({ results: array(OsdRenderResultSchema) }), {
|
|
34123
34276
|
kind: "mutation",
|
|
34124
34277
|
auth: "admin"
|
|
34278
|
+
}), method(object({}), object({ templates: array(OsdNamedTemplateSchema) }), { auth: "admin" }), method(object({ template: OsdNamedTemplateSchema }), object({ template: OsdNamedTemplateSchema }), {
|
|
34279
|
+
kind: "mutation",
|
|
34280
|
+
auth: "admin"
|
|
34281
|
+
}), method(object({ templateId: string().min(1).max(64) }), object({ success: literal(true) }), {
|
|
34282
|
+
kind: "mutation",
|
|
34283
|
+
auth: "admin"
|
|
34125
34284
|
});
|
|
34126
34285
|
/**
|
|
34127
34286
|
* Feeder connectivity / power status — mirrors the HA petkit device-status
|
|
@@ -42916,6 +43075,36 @@ Object.freeze({
|
|
|
42916
43075
|
addonId: null,
|
|
42917
43076
|
access: "create"
|
|
42918
43077
|
},
|
|
43078
|
+
"calendars.importFromHomeAssistant": {
|
|
43079
|
+
capName: "calendars",
|
|
43080
|
+
capScope: "system",
|
|
43081
|
+
addonId: null,
|
|
43082
|
+
access: "create"
|
|
43083
|
+
},
|
|
43084
|
+
"calendars.listCalendars": {
|
|
43085
|
+
capName: "calendars",
|
|
43086
|
+
capScope: "system",
|
|
43087
|
+
addonId: null,
|
|
43088
|
+
access: "view"
|
|
43089
|
+
},
|
|
43090
|
+
"calendars.listEvents": {
|
|
43091
|
+
capName: "calendars",
|
|
43092
|
+
capScope: "system",
|
|
43093
|
+
addonId: null,
|
|
43094
|
+
access: "view"
|
|
43095
|
+
},
|
|
43096
|
+
"calendarSource.listCalendars": {
|
|
43097
|
+
capName: "calendar-source",
|
|
43098
|
+
capScope: "system",
|
|
43099
|
+
addonId: null,
|
|
43100
|
+
access: "view"
|
|
43101
|
+
},
|
|
43102
|
+
"calendarSource.listEvents": {
|
|
43103
|
+
capName: "calendar-source",
|
|
43104
|
+
capScope: "system",
|
|
43105
|
+
addonId: null,
|
|
43106
|
+
access: "view"
|
|
43107
|
+
},
|
|
42919
43108
|
"cameraCredentials.getCredentials": {
|
|
42920
43109
|
capName: "camera-credentials",
|
|
42921
43110
|
capScope: "device",
|
|
@@ -45910,6 +46099,12 @@ Object.freeze({
|
|
|
45910
46099
|
addonId: null,
|
|
45911
46100
|
access: "create"
|
|
45912
46101
|
},
|
|
46102
|
+
"osdManager.deleteTemplate": {
|
|
46103
|
+
capName: "osd-manager",
|
|
46104
|
+
capScope: "system",
|
|
46105
|
+
addonId: null,
|
|
46106
|
+
access: "delete"
|
|
46107
|
+
},
|
|
45913
46108
|
"osdManager.getConditionSupport": {
|
|
45914
46109
|
capName: "osd-manager",
|
|
45915
46110
|
capScope: "system",
|
|
@@ -45928,6 +46123,12 @@ Object.freeze({
|
|
|
45928
46123
|
addonId: null,
|
|
45929
46124
|
access: "view"
|
|
45930
46125
|
},
|
|
46126
|
+
"osdManager.listTemplates": {
|
|
46127
|
+
capName: "osd-manager",
|
|
46128
|
+
capScope: "system",
|
|
46129
|
+
addonId: null,
|
|
46130
|
+
access: "view"
|
|
46131
|
+
},
|
|
45931
46132
|
"osdManager.previewSlot": {
|
|
45932
46133
|
capName: "osd-manager",
|
|
45933
46134
|
capScope: "system",
|
|
@@ -45946,6 +46147,12 @@ Object.freeze({
|
|
|
45946
46147
|
addonId: null,
|
|
45947
46148
|
access: "create"
|
|
45948
46149
|
},
|
|
46150
|
+
"osdManager.upsertTemplate": {
|
|
46151
|
+
capName: "osd-manager",
|
|
46152
|
+
capScope: "system",
|
|
46153
|
+
addonId: null,
|
|
46154
|
+
access: "create"
|
|
46155
|
+
},
|
|
45949
46156
|
"petFeeder.callPet": {
|
|
45950
46157
|
capName: "pet-feeder",
|
|
45951
46158
|
capScope: "device",
|
|
@@ -53120,4 +53327,4 @@ function bestLocationMatch(externalName, existing, threshold = .8) {
|
|
|
53120
53327
|
var MB = 1024 * 1024;
|
|
53121
53328
|
1024 * MB, 3072 * MB;
|
|
53122
53329
|
//#endregion
|
|
53123
|
-
export {
|
|
53330
|
+
export { oauthIntegrationCapability as $, connectivityCapability as A, string as At, floodCapability as B, buildAddonRouteProvider as C, _enum as Ct, carbonMonoxideCapability as D, number as Dt, calendarSourceCapability as E, literal as Et, deviceAdoptionCapability as F, lawnMowerControlCapability as G, humidifierCapability as H, deviceExportCapability as I, motionCapability as J, lockControlCapability as K, enumSensorCapability as L, controlCapability as M, unknown as Mt, coverCapability as N, url as Nt, climateControlCapability as O, object as Ot, deviceAdminLinkCapability as P, EventCategory as Pt, numericSensorCapability as Q, eventEmitterCapability as R, brokerCapability as S, nodePin as St, buttonCapability as T, discriminatedUnion as Tt, humiditySensorCapability as U, gasCapability as V, imageCapability as W, notificationOutputCapability as X, normalizeUnit as Y, notifierCapability as Z, automationControlCapability as _, DeviceRole as _t, COCO_TO_MACRO as a, scriptRunnerCapability as at, binaryCapability as b, BaseAddon as bt, FanDirectionSchema as c, tamperCapability as ct, TargetSchema as d, vacuumControlCapability as dt, parseAdminBase as et, accessoriesCapability as f, valveCapability as ft, ambientLightSensorCapability as g, DeviceFeature as gt, alarmPanelCapability as h, weatherCapability as ht, CAMERA_SWITCH_ORDER as i, pressureSensorCapability as it, contactCapability as j, union as jt, colorCapability as k, record as kt, HvacModeSchema as l, temperatureSensorCapability as lt, airQualitySensorCapability as m, waterHeaterCapability as mt, BaseDevice as n, prepareNotification as nt, CameraSwitchIdSchema as o, smokeCapability as ot, addonRoutesCapability as p, vibrationCapability as pt, mediaPlayerCapability as q, BaseDeviceProvider as r, presenceCapability as rt, EnumSensorDateTimeFormatSchema as s, switchCapability as st, AlarmArmModeSchema as t, powerMeterCapability as tt, MediaPlayerRepeatSchema as u, updateCapability as ut, batteryCapability as v, DeviceType as vt, buildDeviceAdminUrl as w, array as wt, brightnessCapability as x, createEvent as xt, bestLocationMatch as y, errMsg as yt, fanControlCapability as z };
|
|
@@ -20688,14 +20688,52 @@ var NcAlarmNonBlockingEditSchema = object({
|
|
|
20688
20688
|
nonBlocking: boolean()
|
|
20689
20689
|
});
|
|
20690
20690
|
/**
|
|
20691
|
+
* Controllable openings: opt IN to blocking (default is do not block). Contacts
|
|
20692
|
+
* keep using {@link NcAlarmNonBlockingEditSchema}.
|
|
20693
|
+
*/
|
|
20694
|
+
var NcAlarmBlockingEditSchema = object({
|
|
20695
|
+
mode: AlarmArmModeSchema,
|
|
20696
|
+
deviceId: number().int().positive(),
|
|
20697
|
+
/** true = on the list (blocks when open); false = off the list (default). */
|
|
20698
|
+
blocking: boolean()
|
|
20699
|
+
});
|
|
20700
|
+
/**
|
|
20701
|
+
* Controllable openings: opt OUT of secure-on-arm (default is secure ON —
|
|
20702
|
+
* close / lock / turn off when this mode arms).
|
|
20703
|
+
*/
|
|
20704
|
+
var NcAlarmSecureOnArmEditSchema = object({
|
|
20705
|
+
mode: AlarmArmModeSchema,
|
|
20706
|
+
deviceId: number().int().positive(),
|
|
20707
|
+
/** true = secure on arm (default); false = do not actuate on arm. */
|
|
20708
|
+
secureOnArm: boolean()
|
|
20709
|
+
});
|
|
20710
|
+
/**
|
|
20711
|
+
* One arm mode's device-id list (non-blocking, blocking, or secure-on-arm-off).
|
|
20712
|
+
*/
|
|
20713
|
+
var NcAlarmModeDeviceListSchema = object({
|
|
20714
|
+
mode: AlarmArmModeSchema,
|
|
20715
|
+
deviceIds: array(number().int()).max(200)
|
|
20716
|
+
});
|
|
20717
|
+
/**
|
|
20718
|
+
* One arm mode's non-blocking list: devices that may be open when that mode
|
|
20719
|
+
* arms, without the arm being refused.
|
|
20720
|
+
*/
|
|
20721
|
+
var NcAlarmNonBlockingSchema = NcAlarmModeDeviceListSchema;
|
|
20722
|
+
/** Controllable devices that DO block when open (opt-in; default empty). */
|
|
20723
|
+
var NcAlarmBlockingSchema = NcAlarmModeDeviceListSchema;
|
|
20724
|
+
/**
|
|
20725
|
+
* Controllable devices that do NOT secure on arm (opt-out; default empty =
|
|
20726
|
+
* every controllable secures).
|
|
20727
|
+
*/
|
|
20728
|
+
var NcAlarmSecureOnArmOffSchema = NcAlarmModeDeviceListSchema;
|
|
20729
|
+
/**
|
|
20691
20730
|
* The per-mode lists, at most one per mode. Two lists for one mode have no
|
|
20692
20731
|
* meaning a reader could agree on (union? the last one?), so they are refused
|
|
20693
20732
|
* at the boundary rather than interpreted.
|
|
20694
20733
|
*/
|
|
20695
|
-
var NcAlarmNonBlockingListSchema = array(
|
|
20696
|
-
|
|
20697
|
-
|
|
20698
|
-
})).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
|
|
20734
|
+
var NcAlarmNonBlockingListSchema = array(NcAlarmNonBlockingSchema).max(8).refine(uniqueModes, { message: "nonBlocking: at most one list per arm mode" });
|
|
20735
|
+
var NcAlarmBlockingListSchema = array(NcAlarmBlockingSchema).max(8).refine(uniqueModes, { message: "blocking: at most one list per arm mode" });
|
|
20736
|
+
var NcAlarmSecureOnArmOffListSchema = array(NcAlarmSecureOnArmOffSchema).max(8).refine(uniqueModes, { message: "secureOnArmOff: at most one list per arm mode" });
|
|
20699
20737
|
/**
|
|
20700
20738
|
* The three durations — global, and per mode since D697 — the panel's state
|
|
20701
20739
|
* machine runs on, who hears about its transitions, and which openings each mode tolerates.
|
|
@@ -20738,9 +20776,23 @@ var NcAlarmSettingsSchema = object({
|
|
|
20738
20776
|
* arm (a window left ajar for the cat under `home`, say). At most one entry
|
|
20739
20777
|
* per mode is meaningful. Defaulted to `[]` so a blob stored before D630
|
|
20740
20778
|
* parses as "every opening blocks" — the behaviour it was written under.
|
|
20779
|
+
* Contacts use this list; controllable openings use {@link blocking} instead
|
|
20780
|
+
* (default: do not block).
|
|
20741
20781
|
*/
|
|
20742
20782
|
nonBlocking: NcAlarmNonBlockingListSchema.default([]),
|
|
20743
20783
|
/**
|
|
20784
|
+
* Per arm mode, controllable openings that DO refuse the arm when open.
|
|
20785
|
+
* Default `[]` = none block (secure-on-arm closes them instead). Absent on a
|
|
20786
|
+
* blob older than this field — read as empty.
|
|
20787
|
+
*/
|
|
20788
|
+
blocking: NcAlarmBlockingListSchema.default([]),
|
|
20789
|
+
/**
|
|
20790
|
+
* Per arm mode, controllable openings that must NOT be actuated on arm.
|
|
20791
|
+
* Default `[]` = every controllable secures (close / lock / off). Absent on
|
|
20792
|
+
* an older blob — read as empty (secure ON).
|
|
20793
|
+
*/
|
|
20794
|
+
secureOnArmOff: NcAlarmSecureOnArmOffListSchema.default([]),
|
|
20795
|
+
/**
|
|
20744
20796
|
* Per arm mode, the delays that mode OVERRIDES (D697). A mode with no entry, or an entry
|
|
20745
20797
|
* without a field, uses the global value above — so `[]`, the default, is exactly the
|
|
20746
20798
|
* behaviour of a blob stored before this field existed. Read through `resolveModeDelays`.
|
|
@@ -20750,7 +20802,7 @@ var NcAlarmSettingsSchema = object({
|
|
|
20750
20802
|
/**
|
|
20751
20803
|
* Every field optional — a tab edits one control at a time.
|
|
20752
20804
|
*
|
|
20753
|
-
*
|
|
20805
|
+
* List fields and `modeDelays` are re-declared WITHOUT their defaults:
|
|
20754
20806
|
* `.partial()` does not remove an inner `.default()`, so a patch that never
|
|
20755
20807
|
* named the field would parse to `[]` and wipe every mode's list on an
|
|
20756
20808
|
* unrelated edit (the same trap {@link NcRulePatchSchema} documents). Here
|
|
@@ -20758,11 +20810,15 @@ var NcAlarmSettingsSchema = object({
|
|
|
20758
20810
|
*/
|
|
20759
20811
|
var NcAlarmSettingsPatchSchema = NcAlarmSettingsSchema.extend({
|
|
20760
20812
|
nonBlocking: NcAlarmNonBlockingListSchema,
|
|
20813
|
+
blocking: NcAlarmBlockingListSchema,
|
|
20814
|
+
secureOnArmOff: NcAlarmSecureOnArmOffListSchema,
|
|
20761
20815
|
/** Per-mode, per-field edits — NOT the whole list (see NcAlarmModeDelaysEditSchema). */
|
|
20762
20816
|
modeDelays: NcAlarmModeDelaysEditListSchema,
|
|
20763
20817
|
/** ONE membership change; the panel applies it to the list it holds at its turn. */
|
|
20764
|
-
nonBlockingEdit: NcAlarmNonBlockingEditSchema
|
|
20765
|
-
|
|
20818
|
+
nonBlockingEdit: NcAlarmNonBlockingEditSchema,
|
|
20819
|
+
blockingEdit: NcAlarmBlockingEditSchema,
|
|
20820
|
+
secureOnArmEdit: NcAlarmSecureOnArmEditSchema
|
|
20821
|
+
}).partial().refine((p) => p.nonBlocking === void 0 || p.nonBlockingEdit === void 0, { message: "nonBlocking and nonBlockingEdit are exclusive — send the whole lists or one edit" }).refine((p) => p.blocking === void 0 || p.blockingEdit === void 0, { message: "blocking and blockingEdit are exclusive — send the whole lists or one edit" }).refine((p) => p.secureOnArmOff === void 0 || p.secureOnArmEdit === void 0, { message: "secureOnArmOff and secureOnArmEdit are exclusive — send the whole lists or one edit" });
|
|
20766
20822
|
/**
|
|
20767
20823
|
* What one arm mode actually arms, DERIVED from the enabled rules gated on it.
|
|
20768
20824
|
* Never authored, never stored — see `alarm-mode-coverage.ts` for why a stored
|
|
@@ -20877,7 +20933,13 @@ var NcAlarmSensorStateSchema = object({
|
|
|
20877
20933
|
/** Why `unknown`: the read failed, or the slice holds no word its cap defines (a placeholder included). */
|
|
20878
20934
|
unknownWhy: _enum(["read-failed", "unknown-word"]).nullable(),
|
|
20879
20935
|
/** The device manager's liveness as the centre mirrors it; null = not known. */
|
|
20880
|
-
online: boolean().nullable()
|
|
20936
|
+
online: boolean().nullable(),
|
|
20937
|
+
/**
|
|
20938
|
+
* True when the opening is a cover / lock / switch — the table shows the
|
|
20939
|
+
* Secure-on-arm switch and uses the controllable defaults. False for contacts
|
|
20940
|
+
* and for non-openings. Defaulted so an older hub answer still parses.
|
|
20941
|
+
*/
|
|
20942
|
+
controllable: boolean().default(false)
|
|
20881
20943
|
});
|
|
20882
20944
|
var NcAlarmSensorsInputSchema = object({ deviceIds: array(number().int().positive()).max(500) });
|
|
20883
20945
|
var NcAlarmSensorsSchema = object({
|
|
@@ -29396,6 +29458,74 @@ var buttonCapability = {
|
|
|
29396
29458
|
}) }
|
|
29397
29459
|
};
|
|
29398
29460
|
/**
|
|
29461
|
+
* `calendar-source` — collection cap exposing per-provider calendars and
|
|
29462
|
+
* their events. Every addon that contributes calendars (Home Assistant,
|
|
29463
|
+
* a future Google Calendar addon, …) registers a provider here. The hub
|
|
29464
|
+
* singleton `calendars` walks the collection and merges the answers.
|
|
29465
|
+
*
|
|
29466
|
+
* Mirrors `addon-pages-source`: the public listing is a different shape
|
|
29467
|
+
* (source-stamped ids) and lives on the aggregator.
|
|
29468
|
+
*/
|
|
29469
|
+
var CalendarSourceKindSchema = _enum(["ha", "addon"]);
|
|
29470
|
+
var CalendarInfoSchema = object({
|
|
29471
|
+
/** Provider-local id (e.g. HA `calendar.family`). The aggregator prefixes. */
|
|
29472
|
+
id: string().min(1),
|
|
29473
|
+
name: string().min(1),
|
|
29474
|
+
source: CalendarSourceKindSchema,
|
|
29475
|
+
enabled: boolean()
|
|
29476
|
+
});
|
|
29477
|
+
var CalendarEventSchema = object({
|
|
29478
|
+
id: string().min(1),
|
|
29479
|
+
calendarId: string().min(1),
|
|
29480
|
+
title: string(),
|
|
29481
|
+
startMs: number().int(),
|
|
29482
|
+
endMs: number().int(),
|
|
29483
|
+
allDay: boolean().optional(),
|
|
29484
|
+
description: string().optional(),
|
|
29485
|
+
location: string().optional()
|
|
29486
|
+
});
|
|
29487
|
+
var CalendarListEventsInputSchema = object({
|
|
29488
|
+
calendarIds: array(string().min(1)).max(64).optional(),
|
|
29489
|
+
startMs: number().int(),
|
|
29490
|
+
endMs: number().int()
|
|
29491
|
+
});
|
|
29492
|
+
var calendarSourceCapability = {
|
|
29493
|
+
name: "calendar-source",
|
|
29494
|
+
scope: "system",
|
|
29495
|
+
mode: "collection",
|
|
29496
|
+
internal: true,
|
|
29497
|
+
methods: {
|
|
29498
|
+
listCalendars: method(_void(), array(CalendarInfoSchema).readonly(), { auth: "admin" }),
|
|
29499
|
+
listEvents: method(CalendarListEventsInputSchema, array(CalendarEventSchema).readonly(), { auth: "admin" })
|
|
29500
|
+
}
|
|
29501
|
+
};
|
|
29502
|
+
/**
|
|
29503
|
+
* `calendars` — system-scoped singleton. Public surface admin-ui and the
|
|
29504
|
+
* notification-center calendar-events producer consume.
|
|
29505
|
+
*
|
|
29506
|
+
* Walks every `calendar-source` provider, stamps each calendar with a
|
|
29507
|
+
* cluster-stable id (`<sourceAddonId>:<localId>`) and the providing
|
|
29508
|
+
* addon's id, and fans `listEvents` out the same way. Home Assistant
|
|
29509
|
+
* import is a built-in refresh of the HA source rather than a second
|
|
29510
|
+
* registry — `importFromHomeAssistant` asks that source to re-discover.
|
|
29511
|
+
*/
|
|
29512
|
+
var CalendarEntrySchema = CalendarInfoSchema.extend({
|
|
29513
|
+
/** Cluster-stable id: `<providerAddonId>:<localId>`. */
|
|
29514
|
+
id: string().min(1),
|
|
29515
|
+
/** The addon that registered the calendar-source provider. */
|
|
29516
|
+
providerAddonId: string().min(1).optional()
|
|
29517
|
+
});
|
|
29518
|
+
var CalendarImportResultSchema = object({
|
|
29519
|
+
imported: number().int().nonnegative(),
|
|
29520
|
+
/** Absent when no HA calendar-source provider was reachable. */
|
|
29521
|
+
providerAddonId: string().min(1).optional(),
|
|
29522
|
+
error: string().optional()
|
|
29523
|
+
});
|
|
29524
|
+
method(_void(), array(CalendarEntrySchema).readonly(), { auth: "admin" }), method(CalendarListEventsInputSchema, array(CalendarEventSchema).readonly(), { auth: "admin" }), method(_void(), CalendarImportResultSchema, {
|
|
29525
|
+
auth: "admin",
|
|
29526
|
+
kind: "mutation"
|
|
29527
|
+
});
|
|
29528
|
+
/**
|
|
29399
29529
|
* camera-credentials — device-scoped cap exposing the camera's network
|
|
29400
29530
|
* + auth surface in a vendor-neutral shape.
|
|
29401
29531
|
*
|
|
@@ -33944,38 +34074,52 @@ DeviceType.Camera, method(object({
|
|
|
33944
34074
|
deviceId: number(),
|
|
33945
34075
|
status: OsdStatusSchema
|
|
33946
34076
|
});
|
|
34077
|
+
_enum([
|
|
34078
|
+
"value",
|
|
34079
|
+
"unit",
|
|
34080
|
+
"full"
|
|
34081
|
+
]);
|
|
34082
|
+
_enum([
|
|
34083
|
+
"value+unit",
|
|
34084
|
+
"value",
|
|
34085
|
+
"unit"
|
|
34086
|
+
]);
|
|
34087
|
+
/**
|
|
34088
|
+
* How the operator reached the leaf device. `deviceId` is ALWAYS the
|
|
34089
|
+
* OSD-supported leaf that is read; `containerId` is set when the pick
|
|
34090
|
+
* went through a container (gateway) first.
|
|
34091
|
+
*/
|
|
34092
|
+
var OsdTemplatePickSchema = object({
|
|
34093
|
+
containerId: number().int().optional(),
|
|
34094
|
+
deviceId: number().int()
|
|
34095
|
+
});
|
|
34096
|
+
/**
|
|
34097
|
+
* One named binding inside a multi-device template: device path + unit
|
|
34098
|
+
* selection + precision. The parser expands `{alias}`, `{alias.value}`,
|
|
34099
|
+
* `{alias.unit}`, or `{alias.full}` from the same binding — there is no
|
|
34100
|
+
* per-binding format lock.
|
|
34101
|
+
*/
|
|
34102
|
+
var OsdTemplateBindingSchema = object({
|
|
34103
|
+
/** Token stem in the parser, e.g. `t` → `{t}` / `{t.value}`. Unique within the template. */
|
|
34104
|
+
alias: string().min(1).max(32).regex(/^[A-Za-z][A-Za-z0-9_-]*$/, "alias must start with a letter"),
|
|
34105
|
+
pick: OsdTemplatePickSchema,
|
|
34106
|
+
capName: string().min(1).max(64),
|
|
34107
|
+
valuePath: string().min(1).max(64),
|
|
34108
|
+
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
34109
|
+
displayUnit: string().max(16).optional(),
|
|
34110
|
+
maxDecimals: number().int().min(0).max(4).default(1)
|
|
34111
|
+
});
|
|
33947
34112
|
/**
|
|
33948
|
-
*
|
|
33949
|
-
*
|
|
33950
|
-
* The `osd` cap is the firmware contract: it probes a camera's overlay
|
|
33951
|
-
* SLOTS and writes literal text into one. It has no idea WHERE that text
|
|
33952
|
-
* comes from, and it must not — a driver that grew a "show the temperature
|
|
33953
|
-
* here" feature would grow it once per vendor.
|
|
33954
|
-
*
|
|
33955
|
-
* This cap owns the other half: a per-(camera, slot) BINDING that says
|
|
33956
|
-
* which value feeds the slot, how it is formatted, and under which
|
|
33957
|
-
* conditions it is shown at all. One addon renders every binding on every
|
|
33958
|
-
* camera, so a new source costs zero driver code.
|
|
33959
|
-
*
|
|
33960
|
-
* Three deliberate choices, each with a rejected alternative:
|
|
33961
|
-
*
|
|
33962
|
-
* 1. A source is `(capName, valuePath)` over the kernel's device
|
|
33963
|
-
* runtime-state mirror — NOT a closed enum of source kinds. Every
|
|
33964
|
-
* cap-keyed slice a device publishes is bindable the day the cap
|
|
33965
|
-
* ships. The rejected alternative (one enum member per source, with
|
|
33966
|
-
* a resolver branch each) is what makes "add the humidity too" a
|
|
33967
|
-
* code change.
|
|
33968
|
-
* 2. The display gate reuses `NcConditionsSchema` verbatim — the
|
|
33969
|
-
* notification centre's condition vocabulary — rather than a parallel
|
|
33970
|
-
* model. An operator who has learned one condition editor has learned
|
|
33971
|
-
* both.
|
|
33972
|
-
* 3. Because the renderer's facts are device STATE and not a detection
|
|
33973
|
-
* record, only a SUBSET of that vocabulary can be answered here.
|
|
33974
|
-
* `setSlotBinding` REJECTS the rest at write time (see
|
|
33975
|
-
* `getConditionSupport`). It does not accept-then-fail-closed: a
|
|
33976
|
-
* condition that can never be true renders a permanently blank
|
|
33977
|
-
* overlay, and a blank overlay looks exactly like a broken camera.
|
|
34113
|
+
* A named template: bindings (alias → leaf field) + a parser that
|
|
34114
|
+
* references `{alias}` / `{alias.value}` / `{alias.unit}` / `{alias.full}`.
|
|
33978
34115
|
*/
|
|
34116
|
+
var OsdNamedTemplateSchema = object({
|
|
34117
|
+
id: string().min(1).max(64),
|
|
34118
|
+
name: string().min(1).max(64),
|
|
34119
|
+
bindings: array(OsdTemplateBindingSchema).max(32).default([]),
|
|
34120
|
+
/** Parser with alias placeholders, e.g. `{t.value} {t.unit} / {h}`. */
|
|
34121
|
+
parser: string().max(256).default("")
|
|
34122
|
+
});
|
|
33979
34123
|
/** Where a slot's value comes from. */
|
|
33980
34124
|
var OsdSourceSchema = discriminatedUnion("kind", [
|
|
33981
34125
|
object({
|
|
@@ -33994,11 +34138,17 @@ var OsdSourceSchema = discriminatedUnion("kind", [
|
|
|
33994
34138
|
deviceId: number().int().optional(),
|
|
33995
34139
|
capName: string().min(1).max(64),
|
|
33996
34140
|
/** Dot path inside the slice, e.g. `detected`, `value`, `mode`. */
|
|
33997
|
-
valuePath: string().min(1).max(64)
|
|
34141
|
+
valuePath: string().min(1).max(64),
|
|
34142
|
+
/** Convert TO this unit at render. Absent = no conversion. */
|
|
34143
|
+
displayUnit: string().max(16).optional()
|
|
33998
34144
|
}),
|
|
33999
34145
|
object({
|
|
34000
34146
|
kind: literal("latest-recognition"),
|
|
34001
34147
|
recognition: _enum(["person", "plate"])
|
|
34148
|
+
}),
|
|
34149
|
+
object({
|
|
34150
|
+
kind: literal("template"),
|
|
34151
|
+
templateId: string().min(1).max(64)
|
|
34002
34152
|
})
|
|
34003
34153
|
]);
|
|
34004
34154
|
var OsdSlotBindingSchema = object({
|
|
@@ -34014,7 +34164,10 @@ var OsdSlotBindingSchema = object({
|
|
|
34014
34164
|
* documented workaround for firmwares that reject `.` in overlay text.
|
|
34015
34165
|
*/
|
|
34016
34166
|
maxDecimals: number().int().min(0).max(4).default(1),
|
|
34017
|
-
/**
|
|
34167
|
+
/**
|
|
34168
|
+
* Appended via `${unit}` when no unit conversion produces a label.
|
|
34169
|
+
* Prefer `source.displayUnit` for converted device-state values.
|
|
34170
|
+
*/
|
|
34018
34171
|
unitLabel: string().max(8).optional(),
|
|
34019
34172
|
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
34020
34173
|
valueMap: record(string(), string()).optional(),
|
|
@@ -34123,6 +34276,12 @@ method(object({ deviceId: number().int() }), object({
|
|
|
34123
34276
|
}), method(object({ deviceId: number().int() }), object({ results: array(OsdRenderResultSchema) }), {
|
|
34124
34277
|
kind: "mutation",
|
|
34125
34278
|
auth: "admin"
|
|
34279
|
+
}), method(object({}), object({ templates: array(OsdNamedTemplateSchema) }), { auth: "admin" }), method(object({ template: OsdNamedTemplateSchema }), object({ template: OsdNamedTemplateSchema }), {
|
|
34280
|
+
kind: "mutation",
|
|
34281
|
+
auth: "admin"
|
|
34282
|
+
}), method(object({ templateId: string().min(1).max(64) }), object({ success: literal(true) }), {
|
|
34283
|
+
kind: "mutation",
|
|
34284
|
+
auth: "admin"
|
|
34126
34285
|
});
|
|
34127
34286
|
/**
|
|
34128
34287
|
* Feeder connectivity / power status — mirrors the HA petkit device-status
|
|
@@ -42917,6 +43076,36 @@ Object.freeze({
|
|
|
42917
43076
|
addonId: null,
|
|
42918
43077
|
access: "create"
|
|
42919
43078
|
},
|
|
43079
|
+
"calendars.importFromHomeAssistant": {
|
|
43080
|
+
capName: "calendars",
|
|
43081
|
+
capScope: "system",
|
|
43082
|
+
addonId: null,
|
|
43083
|
+
access: "create"
|
|
43084
|
+
},
|
|
43085
|
+
"calendars.listCalendars": {
|
|
43086
|
+
capName: "calendars",
|
|
43087
|
+
capScope: "system",
|
|
43088
|
+
addonId: null,
|
|
43089
|
+
access: "view"
|
|
43090
|
+
},
|
|
43091
|
+
"calendars.listEvents": {
|
|
43092
|
+
capName: "calendars",
|
|
43093
|
+
capScope: "system",
|
|
43094
|
+
addonId: null,
|
|
43095
|
+
access: "view"
|
|
43096
|
+
},
|
|
43097
|
+
"calendarSource.listCalendars": {
|
|
43098
|
+
capName: "calendar-source",
|
|
43099
|
+
capScope: "system",
|
|
43100
|
+
addonId: null,
|
|
43101
|
+
access: "view"
|
|
43102
|
+
},
|
|
43103
|
+
"calendarSource.listEvents": {
|
|
43104
|
+
capName: "calendar-source",
|
|
43105
|
+
capScope: "system",
|
|
43106
|
+
addonId: null,
|
|
43107
|
+
access: "view"
|
|
43108
|
+
},
|
|
42920
43109
|
"cameraCredentials.getCredentials": {
|
|
42921
43110
|
capName: "camera-credentials",
|
|
42922
43111
|
capScope: "device",
|
|
@@ -45911,6 +46100,12 @@ Object.freeze({
|
|
|
45911
46100
|
addonId: null,
|
|
45912
46101
|
access: "create"
|
|
45913
46102
|
},
|
|
46103
|
+
"osdManager.deleteTemplate": {
|
|
46104
|
+
capName: "osd-manager",
|
|
46105
|
+
capScope: "system",
|
|
46106
|
+
addonId: null,
|
|
46107
|
+
access: "delete"
|
|
46108
|
+
},
|
|
45914
46109
|
"osdManager.getConditionSupport": {
|
|
45915
46110
|
capName: "osd-manager",
|
|
45916
46111
|
capScope: "system",
|
|
@@ -45929,6 +46124,12 @@ Object.freeze({
|
|
|
45929
46124
|
addonId: null,
|
|
45930
46125
|
access: "view"
|
|
45931
46126
|
},
|
|
46127
|
+
"osdManager.listTemplates": {
|
|
46128
|
+
capName: "osd-manager",
|
|
46129
|
+
capScope: "system",
|
|
46130
|
+
addonId: null,
|
|
46131
|
+
access: "view"
|
|
46132
|
+
},
|
|
45932
46133
|
"osdManager.previewSlot": {
|
|
45933
46134
|
capName: "osd-manager",
|
|
45934
46135
|
capScope: "system",
|
|
@@ -45947,6 +46148,12 @@ Object.freeze({
|
|
|
45947
46148
|
addonId: null,
|
|
45948
46149
|
access: "create"
|
|
45949
46150
|
},
|
|
46151
|
+
"osdManager.upsertTemplate": {
|
|
46152
|
+
capName: "osd-manager",
|
|
46153
|
+
capScope: "system",
|
|
46154
|
+
addonId: null,
|
|
46155
|
+
access: "create"
|
|
46156
|
+
},
|
|
45950
46157
|
"petFeeder.callPet": {
|
|
45951
46158
|
capName: "pet-feeder",
|
|
45952
46159
|
capScope: "device",
|
|
@@ -53313,6 +53520,12 @@ Object.defineProperty(exports, "buttonCapability", {
|
|
|
53313
53520
|
return buttonCapability;
|
|
53314
53521
|
}
|
|
53315
53522
|
});
|
|
53523
|
+
Object.defineProperty(exports, "calendarSourceCapability", {
|
|
53524
|
+
enumerable: true,
|
|
53525
|
+
get: function() {
|
|
53526
|
+
return calendarSourceCapability;
|
|
53527
|
+
}
|
|
53528
|
+
});
|
|
53316
53529
|
Object.defineProperty(exports, "carbonMonoxideCapability", {
|
|
53317
53530
|
enumerable: true,
|
|
53318
53531
|
get: function() {
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
//#endregion
|
|
6
|
-
const require_dist = require("../dist-
|
|
6
|
+
const require_dist = require("../dist-DLQgcqQT.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
//#region src/ha-export/topics.ts
|
|
9
9
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as buildAddonRouteProvider,
|
|
1
|
+
import { $ as oauthIntegrationCapability, At as string, C as buildAddonRouteProvider, I as deviceExportCapability, Pt as EventCategory, St as nodePin, a as COCO_TO_MACRO, bt as BaseAddon, c as FanDirectionSchema, i as CAMERA_SWITCH_ORDER, l as HvacModeSchema, o as CameraSwitchIdSchema, p as addonRoutesCapability, t as AlarmArmModeSchema, u as MediaPlayerRepeatSchema } from "../dist-CvzpCuzm.mjs";
|
|
2
2
|
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
3
3
|
//#region src/ha-export/topics.ts
|
|
4
4
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-homeassistant",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.154",
|
|
4
4
|
"description": "Home Assistant device provider addon for CamStack",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|
|
@@ -82,6 +82,9 @@
|
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
84
|
"name": "addon-routes"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"name": "calendar-source"
|
|
85
88
|
}
|
|
86
89
|
]
|
|
87
90
|
},
|