@camstack/addon-pipeline-orchestrator 1.2.645 → 1.2.646
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 +6 -0
- package/dist/_stub.js +311 -295
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-CwuxFxDA.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-DDVZFPsa.mjs} +2 -2
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CImRTRiM.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CoZ9XX3X.mjs +26 -0
- package/dist/{hostInit-BOzgSP13.mjs → hostInit-D9xAALjA.mjs} +2 -2
- package/dist/index.js +482 -5
- package/dist/index.mjs +482 -5
- package/dist/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-nDsPG0Vk.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DNaztdEQ.mjs +0 -26
package/dist/index.js
CHANGED
|
@@ -5619,7 +5619,7 @@ var ZodIssueCode = {
|
|
|
5619
5619
|
var ZodFirstPartyTypeKind;
|
|
5620
5620
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5621
5621
|
//#endregion
|
|
5622
|
-
//#region ../types/dist/sleep-
|
|
5622
|
+
//#region ../types/dist/sleep-DSVWZfJC.mjs
|
|
5623
5623
|
/**
|
|
5624
5624
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5625
5625
|
* window to float samples (D455).
|
|
@@ -7338,6 +7338,26 @@ var BaseAddon = class {
|
|
|
7338
7338
|
* alternative — skip it — turns a rename into a surface that quietly
|
|
7339
7339
|
* empties, which looks exactly like an addon with nothing to configure.
|
|
7340
7340
|
*/
|
|
7341
|
+
/**
|
|
7342
|
+
* The form schema of ONE integration instance, or `null` to use {@link globalSettingsSchema}.
|
|
7343
|
+
*
|
|
7344
|
+
* Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
|
|
7345
|
+
* needs its connection fields, the default integration the addon's own sections. It is the
|
|
7346
|
+
* SHAPE of the form only — the values live in `integrations.getSettings`, and the write path is
|
|
7347
|
+
* unchanged (`integrations.setSettings` for an account integration).
|
|
7348
|
+
*/
|
|
7349
|
+
async integrationSettingsSchema(_instance) {
|
|
7350
|
+
return null;
|
|
7351
|
+
}
|
|
7352
|
+
/**
|
|
7353
|
+
* What the create wizard and the integration edit page render for one instance: the addon's
|
|
7354
|
+
* per-instance schema when it declares one, else its global schema (what they always showed).
|
|
7355
|
+
*/
|
|
7356
|
+
async getIntegrationFormSchema(instance, nodeId) {
|
|
7357
|
+
const scoped = await this.integrationSettingsSchema(instance);
|
|
7358
|
+
if (scoped === null) return this.getGlobalSettings(void 0, void 0, nodeId);
|
|
7359
|
+
return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
|
|
7360
|
+
}
|
|
7341
7361
|
async getIntegrationSettings(nodeId) {
|
|
7342
7362
|
const declared = this.integrationSettingSections();
|
|
7343
7363
|
if (declared.length === 0) return null;
|
|
@@ -9776,6 +9796,7 @@ var CAP_NAMES = Object.freeze([
|
|
|
9776
9796
|
"remote-layout-components",
|
|
9777
9797
|
"running-state",
|
|
9778
9798
|
"scene-monitor",
|
|
9799
|
+
"schedulers",
|
|
9779
9800
|
"script-runner",
|
|
9780
9801
|
"server-management",
|
|
9781
9802
|
"settings-store",
|
|
@@ -10721,7 +10742,8 @@ Object.freeze({
|
|
|
10721
10742
|
"unlocked",
|
|
10722
10743
|
"locking",
|
|
10723
10744
|
"unlocking",
|
|
10724
|
-
"jammed"
|
|
10745
|
+
"jammed",
|
|
10746
|
+
"door-open"
|
|
10725
10747
|
]
|
|
10726
10748
|
}],
|
|
10727
10749
|
"media-player": [
|
|
@@ -13401,6 +13423,25 @@ var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
|
|
|
13401
13423
|
/** The same list as a Zod enum, for the cap input that carries it. */
|
|
13402
13424
|
var MediaPresenceOwnerKindSchema = _enum([...EVENT_OWNER_TYPES, "track"]);
|
|
13403
13425
|
new Set(EVENT_OWNER_TYPES);
|
|
13426
|
+
/**
|
|
13427
|
+
* Which integration instance a settings form is for. An addon that serves several instances
|
|
13428
|
+
* (`instanceMode: multiple`) can show a different form per instance — an NVR integration
|
|
13429
|
+
* needs its connection, the default integration needs the addon's own sections.
|
|
13430
|
+
*
|
|
13431
|
+
* - `integrationId` is `null` in the create wizard: nothing exists yet, the operator is
|
|
13432
|
+
* setting up a NEW instance.
|
|
13433
|
+
* - `mode` is the wizard mode of the integration type (`getAvailableTypes`).
|
|
13434
|
+
* - `candidateStableId` is the discovery candidate a wizard was seeded from, if any.
|
|
13435
|
+
*/
|
|
13436
|
+
var IntegrationInstanceRefSchema = object({
|
|
13437
|
+
integrationId: string().nullable(),
|
|
13438
|
+
mode: _enum([
|
|
13439
|
+
"standalone",
|
|
13440
|
+
"account",
|
|
13441
|
+
"broker"
|
|
13442
|
+
]),
|
|
13443
|
+
candidateStableId: string().optional()
|
|
13444
|
+
});
|
|
13404
13445
|
var EncodeProfileSchema = object({
|
|
13405
13446
|
video: object({
|
|
13406
13447
|
codec: _enum([
|
|
@@ -17652,6 +17693,11 @@ var ACTUATOR_CAP_VOCABULARY = {
|
|
|
17652
17693
|
value: "jammed",
|
|
17653
17694
|
label: t("Jammed", "Inceppata"),
|
|
17654
17695
|
phrase: t("When {device} jams", "Quando {device} si inceppa")
|
|
17696
|
+
},
|
|
17697
|
+
{
|
|
17698
|
+
value: "door-open",
|
|
17699
|
+
label: t("Door open", "Porta aperta"),
|
|
17700
|
+
phrase: t("When the door of {device} opens", "Quando la porta di {device} si apre")
|
|
17655
17701
|
}
|
|
17656
17702
|
],
|
|
17657
17703
|
icon: "lock"
|
|
@@ -21142,6 +21188,7 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
21142
21188
|
records: system(INTERNAL),
|
|
21143
21189
|
remote: system("the per-device remote setup — authored in the Customize remote editor, sent through the remote UI"),
|
|
21144
21190
|
"remote-layout-components": system("the palette of the remote template editor — read-only data, never actuated"),
|
|
21191
|
+
schedulers: system("time schedulers — authored on their own page, not device actions"),
|
|
21145
21192
|
"server-management": system(CLUSTER),
|
|
21146
21193
|
"settings-store": system(INTERNAL),
|
|
21147
21194
|
"smtp-provider": system(INTERNAL),
|
|
@@ -42005,6 +42052,122 @@ var AutomationWhenSchema = lazy(() => discriminatedUnion("kind", [
|
|
|
42005
42052
|
StationaryPresentLeafSchema,
|
|
42006
42053
|
ExpressionLeafSchema
|
|
42007
42054
|
]));
|
|
42055
|
+
var EVENT_KINDS = new Set([
|
|
42056
|
+
"device-becomes",
|
|
42057
|
+
"device-event",
|
|
42058
|
+
"schedule",
|
|
42059
|
+
"manual",
|
|
42060
|
+
"interval",
|
|
42061
|
+
"detection",
|
|
42062
|
+
"stationary"
|
|
42063
|
+
]);
|
|
42064
|
+
function isEventLeaf(node) {
|
|
42065
|
+
return EVENT_KINDS.has(node.kind);
|
|
42066
|
+
}
|
|
42067
|
+
function isLeaf(node) {
|
|
42068
|
+
return node.kind !== "all" && node.kind !== "any" && node.kind !== "not";
|
|
42069
|
+
}
|
|
42070
|
+
/** Depth of a tree, root container = 1. A bare leaf is depth 1. */
|
|
42071
|
+
function whenDepth(node) {
|
|
42072
|
+
if (isLeaf(node)) return 1;
|
|
42073
|
+
if (node.kind === "not") return 1 + whenDepth(node.child);
|
|
42074
|
+
let deepest = 0;
|
|
42075
|
+
for (const child of node.children) deepest = Math.max(deepest, whenDepth(child));
|
|
42076
|
+
return 1 + deepest;
|
|
42077
|
+
}
|
|
42078
|
+
/** Leaves only — containers do not count toward the leaf budget. */
|
|
42079
|
+
function countWhenLeaves(node) {
|
|
42080
|
+
if (isLeaf(node)) return 1;
|
|
42081
|
+
if (node.kind === "not") return countWhenLeaves(node.child);
|
|
42082
|
+
let total = 0;
|
|
42083
|
+
for (const child of node.children) total += countWhenLeaves(child);
|
|
42084
|
+
return total;
|
|
42085
|
+
}
|
|
42086
|
+
/** Every leaf with its path (`when`, `when.0`, `when.0.1`, `when.0` under a `not`). */
|
|
42087
|
+
function forEachLeaf(node, visit, path = "when") {
|
|
42088
|
+
if (isLeaf(node)) {
|
|
42089
|
+
visit(node, path);
|
|
42090
|
+
return;
|
|
42091
|
+
}
|
|
42092
|
+
if (node.kind === "not") {
|
|
42093
|
+
forEachLeaf(node.child, visit, `${path}.0`);
|
|
42094
|
+
return;
|
|
42095
|
+
}
|
|
42096
|
+
node.children.forEach((child, i) => {
|
|
42097
|
+
forEachLeaf(child, visit, `${path}.${i}`);
|
|
42098
|
+
});
|
|
42099
|
+
}
|
|
42100
|
+
function hasEventLeaves(node) {
|
|
42101
|
+
let found = false;
|
|
42102
|
+
forEachLeaf(node, (leaf) => {
|
|
42103
|
+
if (isEventLeaf(leaf)) found = true;
|
|
42104
|
+
});
|
|
42105
|
+
return found;
|
|
42106
|
+
}
|
|
42107
|
+
function hasEmptyContainer(node) {
|
|
42108
|
+
if (isLeaf(node)) return false;
|
|
42109
|
+
if (node.kind === "not") return hasEmptyContainer(node.child);
|
|
42110
|
+
if (node.children.length === 0) return true;
|
|
42111
|
+
return node.children.some(hasEmptyContainer);
|
|
42112
|
+
}
|
|
42113
|
+
var LEAF_WORDS = {
|
|
42114
|
+
"device-becomes": "a device value that becomes",
|
|
42115
|
+
"device-event": "a device event",
|
|
42116
|
+
schedule: "a schedule",
|
|
42117
|
+
manual: "a manual run",
|
|
42118
|
+
interval: "an interval",
|
|
42119
|
+
detection: "a detection",
|
|
42120
|
+
stationary: "a parked object appearing or leaving"
|
|
42121
|
+
};
|
|
42122
|
+
function say(kind) {
|
|
42123
|
+
return LEAF_WORDS[kind] ?? kind;
|
|
42124
|
+
}
|
|
42125
|
+
/**
|
|
42126
|
+
* The cheapest set of event leaves that makes `node` true, with negation pushed
|
|
42127
|
+
* down to the leaves first (De Morgan), so `not(any(A, B))` and `all(not A,
|
|
42128
|
+
* not B)` are the same shape to the check. A negated event is its own error: an
|
|
42129
|
+
* event is an instant, "the event did not occur" is true at every other moment.
|
|
42130
|
+
*/
|
|
42131
|
+
function eventNeed(node, path, negated) {
|
|
42132
|
+
if (isLeaf(node)) {
|
|
42133
|
+
if (!isEventLeaf(node)) return { paths: [] };
|
|
42134
|
+
if (negated) return { error: `"not" is applied to ${say(node.kind)} (${path}) — an event is an instant, so "it did not happen" is true at every other moment and can never start a run. Negate a state ("is") instead, or remove the "not"` };
|
|
42135
|
+
return { paths: [{
|
|
42136
|
+
path,
|
|
42137
|
+
kind: node.kind
|
|
42138
|
+
}] };
|
|
42139
|
+
}
|
|
42140
|
+
if (node.kind === "not") return eventNeed(node.child, `${path}.0`, !negated);
|
|
42141
|
+
const conjunctive = node.kind === "all" !== negated;
|
|
42142
|
+
const parts = [];
|
|
42143
|
+
for (let i = 0; i < node.children.length; i += 1) {
|
|
42144
|
+
const child = node.children[i];
|
|
42145
|
+
if (child === void 0) continue;
|
|
42146
|
+
const need = eventNeed(child, `${path}.${i}`, negated);
|
|
42147
|
+
if ("error" in need) return need;
|
|
42148
|
+
parts.push(need);
|
|
42149
|
+
}
|
|
42150
|
+
if (conjunctive) return { paths: parts.flatMap((p) => p.paths) };
|
|
42151
|
+
let best;
|
|
42152
|
+
for (const part of parts) if (best === void 0 || part.paths.length < best.paths.length) best = part;
|
|
42153
|
+
return best ?? { paths: [] };
|
|
42154
|
+
}
|
|
42155
|
+
/**
|
|
42156
|
+
* Author-time bounds and sense check of a `when` tree. Returns `null` when it
|
|
42157
|
+
* is legal, else a message the editor shows verbatim.
|
|
42158
|
+
*/
|
|
42159
|
+
function validateWhenTree(when) {
|
|
42160
|
+
if (hasEmptyContainer(when)) return "a group is empty — group existing rows instead of leaving a container to fill";
|
|
42161
|
+
const depth = whenDepth(when);
|
|
42162
|
+
if (depth > 4) return `the rules nest ${depth} levels deep — the limit is 4. "not (any of …)" is the same as "all of (not …)", which is one level shallower`;
|
|
42163
|
+
const leaves = countWhenLeaves(when);
|
|
42164
|
+
if (leaves > 32) return `the rules use ${leaves} rows — the limit is 32`;
|
|
42165
|
+
const need = eventNeed(when, "when", false);
|
|
42166
|
+
if ("error" in need) return need.error;
|
|
42167
|
+
const [first, second] = need.paths;
|
|
42168
|
+
if (first !== void 0 && second !== void 0) return `${say(first.kind)} (${first.path}) and ${say(second.kind)} (${second.path}) would both have to happen at the same instant, and an event happens at one moment — this can never run. Use "any of" to start on either, or turn one of them into a state ("is") that must already hold`;
|
|
42169
|
+
return null;
|
|
42170
|
+
}
|
|
42008
42171
|
/**
|
|
42009
42172
|
* The recipe shape before the single `when` tree: a flat list of triggers
|
|
42010
42173
|
* (OR'd, each an instant) and an optional condition tree. Stored recipes —
|
|
@@ -42360,6 +42523,187 @@ function convertLegacyRecipe(legacy) {
|
|
|
42360
42523
|
var AutomationRecipeSchema = union([CurrentAutomationRecipeSchema, LegacyAutomationRecipeSchema.transform(convertLegacyRecipe)]);
|
|
42361
42524
|
new Set(Object.values(COCO_TO_MACRO.mapping));
|
|
42362
42525
|
/**
|
|
42526
|
+
* Schedulers (D983) — an entity that performs actions over the day.
|
|
42527
|
+
*
|
|
42528
|
+
* A scheduler has profiles; a profile has weekdays and a timeline of POINTS.
|
|
42529
|
+
* A point is an `edge` (run once at its time), a `hold` (from this point until
|
|
42530
|
+
* the next point of the profile, keep the steps' effects true) or a `release`
|
|
42531
|
+
* (end the current hold without acting). The scheduler AND each profile carry
|
|
42532
|
+
* a manual `enabled` flag and an optional `activeWhen`: a `when` STATE tree
|
|
42533
|
+
* (facts only — an event leaf is an instant and cannot be "in force").
|
|
42534
|
+
*
|
|
42535
|
+
* This file is the data half: the schemas, and the author-time rules that
|
|
42536
|
+
* decide whether a scheduler can be saved at all (a hold needs an action that
|
|
42537
|
+
* leads to a state; a sun point needs the site location). It holds no runtime.
|
|
42538
|
+
*/
|
|
42539
|
+
/** A `when` tree that is a STATE: no event leaf, and legal as a tree. */
|
|
42540
|
+
var SchedulerStateTreeSchema = AutomationWhenSchema.superRefine((when, ctx) => {
|
|
42541
|
+
if (hasEventLeaves(when)) {
|
|
42542
|
+
ctx.addIssue({
|
|
42543
|
+
code: "custom",
|
|
42544
|
+
message: "a scheduler condition is a state — an event (\"becomes\", \"detects\", \"at a time\") is an instant and cannot be in force"
|
|
42545
|
+
});
|
|
42546
|
+
return;
|
|
42547
|
+
}
|
|
42548
|
+
const problem = validateWhenTree(when);
|
|
42549
|
+
if (problem !== null) ctx.addIssue({
|
|
42550
|
+
code: "custom",
|
|
42551
|
+
message: problem
|
|
42552
|
+
});
|
|
42553
|
+
});
|
|
42554
|
+
/** A point's moment: a clock time or a sun event. A one-shot date is not a position on a day. */
|
|
42555
|
+
var SchedulerTimeSpecSchema = TimeSpecSchema.refine((spec) => spec.kind !== "date", { message: "a scheduler point is a clock time or a sun event — a one-shot date has no place on a timeline" });
|
|
42556
|
+
var SchedulerPointModeSchema = _enum([
|
|
42557
|
+
"edge",
|
|
42558
|
+
"hold",
|
|
42559
|
+
"release"
|
|
42560
|
+
]);
|
|
42561
|
+
/** What a hold does when someone changes the device by hand. */
|
|
42562
|
+
var HoldOverrideSchema = discriminatedUnion("mode", [object({ mode: literal("respect") }), object({
|
|
42563
|
+
mode: literal("reassert"),
|
|
42564
|
+
/** How long the manual state is left alone before the hold puts its own back. */
|
|
42565
|
+
graceMs: number().int().min(0).max(24 * 36e5)
|
|
42566
|
+
})]);
|
|
42567
|
+
/** A missed edge up to this late still runs. */
|
|
42568
|
+
var DEFAULT_MAX_LATE_MS = 10 * 6e4;
|
|
42569
|
+
var SchedulerPointSchema = object({
|
|
42570
|
+
id: string().min(1).max(64),
|
|
42571
|
+
at: SchedulerTimeSpecSchema,
|
|
42572
|
+
mode: SchedulerPointModeSchema,
|
|
42573
|
+
/** The actions of an `edge` or `hold`; a `release` has none. */
|
|
42574
|
+
steps: array(ActionStepSchema).max(20).default([]),
|
|
42575
|
+
/** Checked when the point runs (an edge) or is applied (a hold). */
|
|
42576
|
+
conditions: SchedulerStateTreeSchema.optional(),
|
|
42577
|
+
/** Hold only; absent means `respect`. */
|
|
42578
|
+
override: HoldOverrideSchema.optional(),
|
|
42579
|
+
/** Hold only: re-applications per window; absent means {@link DEFAULT_MAX_HOLD_ATTEMPTS}. */
|
|
42580
|
+
maxHoldAttempts: number().int().min(1).max(20).optional()
|
|
42581
|
+
});
|
|
42582
|
+
var SchedulerProfileSchema = object({
|
|
42583
|
+
id: string().min(1).max(64),
|
|
42584
|
+
name: string().min(1).max(120),
|
|
42585
|
+
enabled: boolean().default(true),
|
|
42586
|
+
activeWhen: SchedulerStateTreeSchema.optional(),
|
|
42587
|
+
days: array(WeekdayKeySchema).min(1).max(7),
|
|
42588
|
+
points: array(SchedulerPointSchema).max(50)
|
|
42589
|
+
});
|
|
42590
|
+
/** What an operator writes. */
|
|
42591
|
+
var SchedulerInputSchema = object({
|
|
42592
|
+
name: string().min(1).max(120),
|
|
42593
|
+
enabled: boolean().default(true),
|
|
42594
|
+
activeWhen: SchedulerStateTreeSchema.optional(),
|
|
42595
|
+
/** Higher wins when two holds want the same device in different states. */
|
|
42596
|
+
priority: number().int().min(0).max(100).default(0),
|
|
42597
|
+
maxLateMs: number().int().min(1e3).max(24 * 36e5).default(DEFAULT_MAX_LATE_MS),
|
|
42598
|
+
profiles: array(SchedulerProfileSchema).max(20)
|
|
42599
|
+
});
|
|
42600
|
+
var SchedulerSchema = SchedulerInputSchema.extend({
|
|
42601
|
+
id: string().min(1),
|
|
42602
|
+
createdAt: number(),
|
|
42603
|
+
updatedAt: number()
|
|
42604
|
+
});
|
|
42605
|
+
/** Every outcome a scheduler reports to the runs ledger (`AutomationRunTrace.scheduler`). */
|
|
42606
|
+
var SchedulerOutcomeSchema = _enum([
|
|
42607
|
+
"done",
|
|
42608
|
+
"missed",
|
|
42609
|
+
"inactive",
|
|
42610
|
+
"condition-false",
|
|
42611
|
+
"failed",
|
|
42612
|
+
"held",
|
|
42613
|
+
"gave-up",
|
|
42614
|
+
"overridden",
|
|
42615
|
+
"suspended-manual"
|
|
42616
|
+
]);
|
|
42617
|
+
_enum([
|
|
42618
|
+
"not-found",
|
|
42619
|
+
"invalid-scheduler",
|
|
42620
|
+
"invalid-date"
|
|
42621
|
+
]);
|
|
42622
|
+
var LOCAL_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
42623
|
+
/** One point of the day, placed. `at` is `null` when the sun never crosses that day. */
|
|
42624
|
+
var SchedulerPreviewPointSchema = object({
|
|
42625
|
+
pointId: string(),
|
|
42626
|
+
mode: SchedulerPointModeSchema,
|
|
42627
|
+
at: number().nullable(),
|
|
42628
|
+
/** A hold: when its window ends (the next point, else the end of the day). */
|
|
42629
|
+
until: number().nullable(),
|
|
42630
|
+
/** The point's steps are held on a different scheduler's claim at this time — see `conflicts`. */
|
|
42631
|
+
stepCount: number().int()
|
|
42632
|
+
});
|
|
42633
|
+
var SchedulerPreviewSchema = object({
|
|
42634
|
+
schedulerId: string(),
|
|
42635
|
+
/** The site-local day previewed. */
|
|
42636
|
+
date: string().regex(LOCAL_DATE_PATTERN),
|
|
42637
|
+
timeZone: string(),
|
|
42638
|
+
/** Why no profile is in force, or `null` when one is. */
|
|
42639
|
+
idleReason: string().nullable(),
|
|
42640
|
+
/** The profile in force that day: first in list order whose rules hold. */
|
|
42641
|
+
profileId: string().nullable(),
|
|
42642
|
+
points: array(SchedulerPreviewPointSchema)
|
|
42643
|
+
});
|
|
42644
|
+
/** Two holds that want the same device in different states at the same time. */
|
|
42645
|
+
var SchedulerConflictSchema = object({
|
|
42646
|
+
deviceId: number().int(),
|
|
42647
|
+
cap: string(),
|
|
42648
|
+
field: string(),
|
|
42649
|
+
mine: object({
|
|
42650
|
+
profileId: string(),
|
|
42651
|
+
pointId: string(),
|
|
42652
|
+
value: union([
|
|
42653
|
+
string(),
|
|
42654
|
+
number(),
|
|
42655
|
+
boolean()
|
|
42656
|
+
]),
|
|
42657
|
+
priority: number().int()
|
|
42658
|
+
}),
|
|
42659
|
+
other: object({
|
|
42660
|
+
schedulerId: string(),
|
|
42661
|
+
schedulerName: string(),
|
|
42662
|
+
profileId: string(),
|
|
42663
|
+
pointId: string(),
|
|
42664
|
+
value: union([
|
|
42665
|
+
string(),
|
|
42666
|
+
number(),
|
|
42667
|
+
boolean()
|
|
42668
|
+
]),
|
|
42669
|
+
priority: number().int()
|
|
42670
|
+
}),
|
|
42671
|
+
/** The overlapping stretch, as site-local minutes of the day. */
|
|
42672
|
+
fromMinute: number().int(),
|
|
42673
|
+
toMinute: number().int(),
|
|
42674
|
+
/** `mine` | `other` | `tie` — who holds when it happens (a tie: the one that started first). */
|
|
42675
|
+
winner: _enum([
|
|
42676
|
+
"mine",
|
|
42677
|
+
"other",
|
|
42678
|
+
"tie"
|
|
42679
|
+
])
|
|
42680
|
+
});
|
|
42681
|
+
var HoldTargetStatusSchema = _enum([
|
|
42682
|
+
"pending",
|
|
42683
|
+
"held",
|
|
42684
|
+
"suspended-manual",
|
|
42685
|
+
"gave-up",
|
|
42686
|
+
"overridden"
|
|
42687
|
+
]);
|
|
42688
|
+
var SchedulerStatusSchema = object({
|
|
42689
|
+
schedulerId: string(),
|
|
42690
|
+
profileId: string().nullable(),
|
|
42691
|
+
/** The hold in force right now, with where each target stands. */
|
|
42692
|
+
hold: object({
|
|
42693
|
+
pointId: string(),
|
|
42694
|
+
until: number(),
|
|
42695
|
+
/** `true` while the scheduler or profile `activeWhen` is false. */
|
|
42696
|
+
suspendedInactive: boolean(),
|
|
42697
|
+
targets: array(object({
|
|
42698
|
+
deviceId: number().int(),
|
|
42699
|
+
cap: string(),
|
|
42700
|
+
field: string(),
|
|
42701
|
+
status: HoldTargetStatusSchema,
|
|
42702
|
+
attempts: number().int()
|
|
42703
|
+
}))
|
|
42704
|
+
}).nullable()
|
|
42705
|
+
});
|
|
42706
|
+
/**
|
|
42363
42707
|
* Run traces — what an automation (or, later, an Action run) DID, node by node,
|
|
42364
42708
|
* so the editor can paint every block green or red with its reason.
|
|
42365
42709
|
*
|
|
@@ -42495,7 +42839,13 @@ var AutomationRunTraceSchema = object({
|
|
|
42495
42839
|
/** How many identical consecutive skips this trace stands for (>= 1). */
|
|
42496
42840
|
repeat: number().int().min(1),
|
|
42497
42841
|
/** When the latest of those repeats happened. */
|
|
42498
|
-
lastAt: number()
|
|
42842
|
+
lastAt: number(),
|
|
42843
|
+
/**
|
|
42844
|
+
* A scheduler point's own outcome (D983). `outcome` carries the closest
|
|
42845
|
+
* automation outcome so a reader that does not know schedulers still reads
|
|
42846
|
+
* the trace; this field says exactly what happened.
|
|
42847
|
+
*/
|
|
42848
|
+
scheduler: SchedulerOutcomeSchema.optional()
|
|
42499
42849
|
});
|
|
42500
42850
|
/**
|
|
42501
42851
|
* What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
|
|
@@ -43224,6 +43574,10 @@ method(object({
|
|
|
43224
43574
|
}), method(object({
|
|
43225
43575
|
addonId: string(),
|
|
43226
43576
|
nodeId: string().optional()
|
|
43577
|
+
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
43578
|
+
addonId: string(),
|
|
43579
|
+
nodeId: string().optional(),
|
|
43580
|
+
instance: IntegrationInstanceRefSchema
|
|
43227
43581
|
}), SettingsSchemaWithValuesSchema.nullable()), method(object({
|
|
43228
43582
|
addonId: string(),
|
|
43229
43583
|
nodeId: string().optional()
|
|
@@ -45942,6 +46296,7 @@ method(object({
|
|
|
45942
46296
|
kind: "mutation",
|
|
45943
46297
|
auth: "admin"
|
|
45944
46298
|
}), method(object({ blockIds: array(string()) }), object({ states: array(CompositionBlockStateSchema) }), { auth: "admin" });
|
|
46299
|
+
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Gateway, DeviceType.Camera, DeviceType.Lock, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
45945
46300
|
var NUMBER = {
|
|
45946
46301
|
kind: "fixed",
|
|
45947
46302
|
result: ["number"]
|
|
@@ -65589,6 +65944,43 @@ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
|
|
|
65589
65944
|
auth: "admin"
|
|
65590
65945
|
});
|
|
65591
65946
|
/**
|
|
65947
|
+
* schedulers — timelines of edge and hold points that perform actions over the
|
|
65948
|
+
* day (D983). Provided by the core-blocks builtin on the hub, beside `actions`:
|
|
65949
|
+
* the same runs ledger (owner `scheduler:<id>`), the same target resolver, the
|
|
65950
|
+
* same step runner.
|
|
65951
|
+
*
|
|
65952
|
+
* The hub runs ONE timer for the next point across every scheduler. A save is
|
|
65953
|
+
* refused with its reason (`[invalid-scheduler] …`) when a hold has a step that
|
|
65954
|
+
* leads to no state, or a sun point has no site location to read.
|
|
65955
|
+
*/
|
|
65956
|
+
var SchedulerIdInput = object({ schedulerId: string().min(1) });
|
|
65957
|
+
method(object({}), array(SchedulerSchema), { auth: "admin" }), method(SchedulerIdInput, object({ scheduler: SchedulerSchema.nullable() }), { auth: "admin" }), method(object({ scheduler: SchedulerInputSchema }), object({ scheduler: SchedulerSchema }), {
|
|
65958
|
+
kind: "mutation",
|
|
65959
|
+
auth: "admin"
|
|
65960
|
+
}), method(object({
|
|
65961
|
+
schedulerId: string().min(1),
|
|
65962
|
+
scheduler: SchedulerInputSchema
|
|
65963
|
+
}), object({ scheduler: SchedulerSchema }), {
|
|
65964
|
+
kind: "mutation",
|
|
65965
|
+
auth: "admin"
|
|
65966
|
+
}), method(SchedulerIdInput, _void(), {
|
|
65967
|
+
kind: "mutation",
|
|
65968
|
+
auth: "admin"
|
|
65969
|
+
}), method(object({
|
|
65970
|
+
schedulerId: string().min(1),
|
|
65971
|
+
profileId: string().min(1).optional(),
|
|
65972
|
+
enabled: boolean()
|
|
65973
|
+
}), object({ scheduler: SchedulerSchema }), {
|
|
65974
|
+
kind: "mutation",
|
|
65975
|
+
auth: "admin"
|
|
65976
|
+
}), method(object({
|
|
65977
|
+
schedulerId: string().min(1),
|
|
65978
|
+
date: string().regex(LOCAL_DATE_PATTERN).optional()
|
|
65979
|
+
}), SchedulerPreviewSchema, { auth: "admin" }), method(object({
|
|
65980
|
+
scheduler: SchedulerInputSchema,
|
|
65981
|
+
schedulerId: string().min(1).optional()
|
|
65982
|
+
}), object({ conflicts: array(SchedulerConflictSchema) }), { auth: "admin" }), method(object({}), array(SchedulerStatusSchema), { auth: "admin" }), method(SchedulerIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" });
|
|
65983
|
+
/**
|
|
65592
65984
|
* actions — the ONE surface for runnable actions, for the UI and for
|
|
65593
65985
|
* automations. Provided by the core-blocks builtin on the hub.
|
|
65594
65986
|
*
|
|
@@ -68343,6 +68735,8 @@ var IntegrationWithStateSchema = object({
|
|
|
68343
68735
|
name: string(),
|
|
68344
68736
|
enabled: boolean(),
|
|
68345
68737
|
info: record(string(), unknown()).readonly(),
|
|
68738
|
+
/** The discovery candidate this integration was set up from (D984). */
|
|
68739
|
+
originStableId: string().optional(),
|
|
68346
68740
|
createdAt: number(),
|
|
68347
68741
|
updatedAt: number(),
|
|
68348
68742
|
processState: string()
|
|
@@ -68353,6 +68747,8 @@ var IntegrationLiteSchema = object({
|
|
|
68353
68747
|
name: string(),
|
|
68354
68748
|
enabled: boolean(),
|
|
68355
68749
|
info: record(string(), unknown()).readonly(),
|
|
68750
|
+
/** The discovery candidate this integration was set up from (D984). */
|
|
68751
|
+
originStableId: string().optional(),
|
|
68356
68752
|
createdAt: number(),
|
|
68357
68753
|
updatedAt: number()
|
|
68358
68754
|
});
|
|
@@ -68450,6 +68846,8 @@ var CreateIntegrationInputSchema = object({
|
|
|
68450
68846
|
name: string(),
|
|
68451
68847
|
enabled: boolean().optional(),
|
|
68452
68848
|
info: record(string(), unknown()).optional(),
|
|
68849
|
+
/** `stableId` of the discovery candidate the form was seeded from (D984). */
|
|
68850
|
+
originStableId: string().optional(),
|
|
68453
68851
|
settings: record(string(), unknown()).optional(),
|
|
68454
68852
|
/** Keys of `settings` the form's schema declares secret (by type) — kept in
|
|
68455
68853
|
* the keychain, not the table (D787). */
|
|
@@ -69067,11 +69465,13 @@ object({
|
|
|
69067
69465
|
"unlocked",
|
|
69068
69466
|
"locking",
|
|
69069
69467
|
"unlocking",
|
|
69070
|
-
"jammed"
|
|
69468
|
+
"jammed",
|
|
69469
|
+
"door-open"
|
|
69071
69470
|
]),
|
|
69072
69471
|
/** Ms epoch when the slice was last updated. */
|
|
69073
69472
|
lastChangedAt: number()
|
|
69074
69473
|
});
|
|
69474
|
+
DeviceType.Lock;
|
|
69075
69475
|
DeviceType.Lock, method(object({
|
|
69076
69476
|
deviceId: number().int().nonnegative(),
|
|
69077
69477
|
/** Optional PIN code required by some keypad locks. NOT
|
|
@@ -76296,7 +76696,6 @@ discriminatedUnion("kind", [object({
|
|
|
76296
76696
|
})]);
|
|
76297
76697
|
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
76298
76698
|
SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
|
|
76299
|
-
DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.EventEmitter, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.PetFountain, DeviceType.Dishwasher, DeviceType.Washer, DeviceType.Dryer, DeviceType.Gateway, DeviceType.Camera, DeviceType.Camera, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.Switch, DeviceType.Light, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.PetFeeder, DeviceType.MediaPlayer, DeviceType.Washer, DeviceType.Dryer, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
|
|
76300
76699
|
String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
76301
76700
|
DeviceRole.BinarySensor, DeviceRole.MotionSensor;
|
|
76302
76701
|
new Set(CAP_NAMES);
|
|
@@ -76758,6 +77157,13 @@ Object.freeze({
|
|
|
76758
77157
|
access: "view",
|
|
76759
77158
|
role: "admin"
|
|
76760
77159
|
},
|
|
77160
|
+
"addonSettings.getIntegrationFormSchema": {
|
|
77161
|
+
capName: "addon-settings",
|
|
77162
|
+
capScope: "system",
|
|
77163
|
+
addonId: null,
|
|
77164
|
+
access: "view",
|
|
77165
|
+
role: "admin"
|
|
77166
|
+
},
|
|
76761
77167
|
"addonSettings.getIntegrationSettings": {
|
|
76762
77168
|
capName: "addon-settings",
|
|
76763
77169
|
capScope: "system",
|
|
@@ -84290,6 +84696,76 @@ Object.freeze({
|
|
|
84290
84696
|
access: "create",
|
|
84291
84697
|
role: "feature:scenes"
|
|
84292
84698
|
},
|
|
84699
|
+
"schedulers.conflicts": {
|
|
84700
|
+
capName: "schedulers",
|
|
84701
|
+
capScope: "system",
|
|
84702
|
+
addonId: null,
|
|
84703
|
+
access: "view",
|
|
84704
|
+
role: "admin"
|
|
84705
|
+
},
|
|
84706
|
+
"schedulers.create": {
|
|
84707
|
+
capName: "schedulers",
|
|
84708
|
+
capScope: "system",
|
|
84709
|
+
addonId: null,
|
|
84710
|
+
access: "create",
|
|
84711
|
+
role: "admin"
|
|
84712
|
+
},
|
|
84713
|
+
"schedulers.delete": {
|
|
84714
|
+
capName: "schedulers",
|
|
84715
|
+
capScope: "system",
|
|
84716
|
+
addonId: null,
|
|
84717
|
+
access: "delete",
|
|
84718
|
+
role: "admin"
|
|
84719
|
+
},
|
|
84720
|
+
"schedulers.get": {
|
|
84721
|
+
capName: "schedulers",
|
|
84722
|
+
capScope: "system",
|
|
84723
|
+
addonId: null,
|
|
84724
|
+
access: "view",
|
|
84725
|
+
role: "admin"
|
|
84726
|
+
},
|
|
84727
|
+
"schedulers.getStatus": {
|
|
84728
|
+
capName: "schedulers",
|
|
84729
|
+
capScope: "system",
|
|
84730
|
+
addonId: null,
|
|
84731
|
+
access: "view",
|
|
84732
|
+
role: "admin"
|
|
84733
|
+
},
|
|
84734
|
+
"schedulers.getTraces": {
|
|
84735
|
+
capName: "schedulers",
|
|
84736
|
+
capScope: "system",
|
|
84737
|
+
addonId: null,
|
|
84738
|
+
access: "view",
|
|
84739
|
+
role: "admin"
|
|
84740
|
+
},
|
|
84741
|
+
"schedulers.list": {
|
|
84742
|
+
capName: "schedulers",
|
|
84743
|
+
capScope: "system",
|
|
84744
|
+
addonId: null,
|
|
84745
|
+
access: "view",
|
|
84746
|
+
role: "admin"
|
|
84747
|
+
},
|
|
84748
|
+
"schedulers.preview": {
|
|
84749
|
+
capName: "schedulers",
|
|
84750
|
+
capScope: "system",
|
|
84751
|
+
addonId: null,
|
|
84752
|
+
access: "view",
|
|
84753
|
+
role: "admin"
|
|
84754
|
+
},
|
|
84755
|
+
"schedulers.setEnabled": {
|
|
84756
|
+
capName: "schedulers",
|
|
84757
|
+
capScope: "system",
|
|
84758
|
+
addonId: null,
|
|
84759
|
+
access: "create",
|
|
84760
|
+
role: "admin"
|
|
84761
|
+
},
|
|
84762
|
+
"schedulers.update": {
|
|
84763
|
+
capName: "schedulers",
|
|
84764
|
+
capScope: "system",
|
|
84765
|
+
addonId: null,
|
|
84766
|
+
access: "create",
|
|
84767
|
+
role: "admin"
|
|
84768
|
+
},
|
|
84293
84769
|
"scriptRunner.getStatus": {
|
|
84294
84770
|
capName: "script-runner",
|
|
84295
84771
|
capScope: "device",
|
|
@@ -90347,6 +90823,7 @@ new Set([
|
|
|
90347
90823
|
"locking",
|
|
90348
90824
|
"unlocking",
|
|
90349
90825
|
"jammed",
|
|
90826
|
+
"door-open",
|
|
90350
90827
|
"on",
|
|
90351
90828
|
"off",
|
|
90352
90829
|
"home",
|