@camstack/addon-import-alexa 0.2.185 → 0.2.186
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/addon.js +78 -54
- package/dist/addon.mjs +78 -54
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.186] - 2026-11-05
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- An Alexa integration links to its account through the account record
|
|
15
|
+
|
|
10
16
|
## [0.2.185] - 2026-11-04
|
|
11
17
|
|
|
12
18
|
### Changed
|
package/dist/addon.js
CHANGED
|
@@ -6044,7 +6044,7 @@ function number(params) {
|
|
|
6044
6044
|
return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
|
|
6045
6045
|
}
|
|
6046
6046
|
//#endregion
|
|
6047
|
-
//#region ../types/dist/sleep-
|
|
6047
|
+
//#region ../types/dist/sleep-9TIHFj1w.mjs
|
|
6048
6048
|
/**
|
|
6049
6049
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6050
6050
|
* window to float samples (D455).
|
|
@@ -7988,10 +7988,9 @@ var BaseAddon = class {
|
|
|
7988
7988
|
*
|
|
7989
7989
|
* Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
|
|
7990
7990
|
* needs its connection fields, the default integration the addon's own sections. It is the
|
|
7991
|
-
* SHAPE of the form only — the values live
|
|
7992
|
-
* unchanged (`integrations.setSettings` for an account integration).
|
|
7991
|
+
* SHAPE of the form only — the values live on the instance record.
|
|
7993
7992
|
*/
|
|
7994
|
-
async
|
|
7993
|
+
async integrationFormSchema(_instance) {
|
|
7995
7994
|
return null;
|
|
7996
7995
|
}
|
|
7997
7996
|
/**
|
|
@@ -8037,7 +8036,7 @@ var BaseAddon = class {
|
|
|
8037
8036
|
* per-instance schema when it declares one, else its global schema (what they always showed).
|
|
8038
8037
|
*/
|
|
8039
8038
|
async getIntegrationFormSchema(instance, nodeId) {
|
|
8040
|
-
const scoped = await this.
|
|
8039
|
+
const scoped = await this.integrationFormSchema(instance);
|
|
8041
8040
|
if (scoped === null) return this.getGlobalSettings(void 0, void 0, nodeId);
|
|
8042
8041
|
return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
|
|
8043
8042
|
}
|
|
@@ -9311,6 +9310,7 @@ function defineEntryKind(name, spec) {
|
|
|
9311
9310
|
class: "config",
|
|
9312
9311
|
writeTrigger: spec.writeTrigger ?? "an operator adds or edits an entry in the entries UI",
|
|
9313
9312
|
retention: { none: "an entry goes only when the operator deletes it" },
|
|
9313
|
+
...spec.maxDataBytes === void 0 ? {} : { maxDataBytes: spec.maxDataBytes },
|
|
9314
9314
|
...spec.database === void 0 ? {} : { database: spec.database },
|
|
9315
9315
|
...spec.indexes === void 0 ? {} : { indexes: spec.indexes },
|
|
9316
9316
|
...spec.secretArrayKeys === void 0 ? {} : { secretArrayKeys: spec.secretArrayKeys },
|
|
@@ -11980,7 +11980,7 @@ object({
|
|
|
11980
11980
|
params: record(string(), union([string(), number$1()])).optional()
|
|
11981
11981
|
});
|
|
11982
11982
|
//#endregion
|
|
11983
|
-
//#region ../types/dist/composition-
|
|
11983
|
+
//#region ../types/dist/composition-pOHbTzRB.mjs
|
|
11984
11984
|
/**
|
|
11985
11985
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11986
11986
|
*
|
|
@@ -50460,6 +50460,9 @@ var RunningProposalEvidenceSchema = object({
|
|
|
50460
50460
|
runsFound: number$1().int().nonnegative(),
|
|
50461
50461
|
pausesFound: number$1().int().nonnegative(),
|
|
50462
50462
|
longestPauseMs: number$1().nonnegative(),
|
|
50463
|
+
/** Episodes shorter than ~90 s (an anti-crease pulse, a display waking): never a run, never a pause. */
|
|
50464
|
+
pulsesFound: number$1().int().nonnegative(),
|
|
50465
|
+
longestPulseMs: number$1().nonnegative(),
|
|
50463
50466
|
idleFloorW: number$1(),
|
|
50464
50467
|
noiseCeilingW: number$1(),
|
|
50465
50468
|
plateauW: number$1(),
|
|
@@ -56305,11 +56308,7 @@ var CreateIntegrationInputSchema = object({
|
|
|
56305
56308
|
info: record(string(), unknown()).optional(),
|
|
56306
56309
|
/** `stableId` of the discovery candidate the form was seeded from (D984). */
|
|
56307
56310
|
originStableId: string().optional(),
|
|
56308
|
-
settings: record(string(), unknown()).optional()
|
|
56309
|
-
/** Keys of `settings` the form's schema declares secret (by type) — kept in
|
|
56310
|
-
* the keychain, not the table (D787). */
|
|
56311
|
-
secretKeys: array(string()).optional(),
|
|
56312
|
-
skipRestart: boolean().optional()
|
|
56311
|
+
settings: record(string(), unknown()).optional()
|
|
56313
56312
|
});
|
|
56314
56313
|
var UpdateIntegrationInputSchema = object({
|
|
56315
56314
|
id: string(),
|
|
@@ -56330,16 +56329,6 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
56330
56329
|
}), method(object({ id: string() }), DeleteIntegrationResultSchema, {
|
|
56331
56330
|
kind: "mutation",
|
|
56332
56331
|
auth: "admin"
|
|
56333
|
-
}), method(object({ id: string() }), record(string(), unknown()), { auth: "admin" }), method(object({
|
|
56334
|
-
id: string(),
|
|
56335
|
-
settings: record(string(), unknown()),
|
|
56336
|
-
/** Keys the form's schema declares secret (by type) — keychain-stored (D787). */
|
|
56337
|
-
secretKeys: array(string()).optional(),
|
|
56338
|
-
/** The integration's own addon applies the change in-process and asks the hub not to respawn it. */
|
|
56339
|
-
skipRestart: boolean().optional()
|
|
56340
|
-
}), object({ success: boolean() }), {
|
|
56341
|
-
kind: "mutation",
|
|
56342
|
-
auth: "admin"
|
|
56343
56332
|
}), method(_void(), array(AvailableIntegrationTypeSchema), { auth: "admin" }), method(object({
|
|
56344
56333
|
addonId: string(),
|
|
56345
56334
|
settings: record(string(), unknown())
|
|
@@ -59316,6 +59305,27 @@ method(object({}), object({ entries: array(MigrationLedgerEntrySchema) }), { aut
|
|
|
59316
59305
|
}), {
|
|
59317
59306
|
kind: "mutation",
|
|
59318
59307
|
auth: "admin"
|
|
59308
|
+
}), method(object({ integrationId: string().min(1) }), record(string(), unknown()), { auth: "admin" }), method(object({ integrationId: string().min(1) }), object({
|
|
59309
|
+
rows: number$1().int().nonnegative(),
|
|
59310
|
+
secrets: number$1().int().nonnegative()
|
|
59311
|
+
}), {
|
|
59312
|
+
kind: "mutation",
|
|
59313
|
+
auth: "admin"
|
|
59314
|
+
}), method(object({
|
|
59315
|
+
integrationId: string().min(1),
|
|
59316
|
+
patch: record(string(), unknown())
|
|
59317
|
+
}), object({ written: boolean() }), {
|
|
59318
|
+
kind: "mutation",
|
|
59319
|
+
auth: "admin"
|
|
59320
|
+
}), method(object({
|
|
59321
|
+
integrationId: string().min(1),
|
|
59322
|
+
keys: array(string().min(1))
|
|
59323
|
+
}), object({
|
|
59324
|
+
present: boolean(),
|
|
59325
|
+
removed: record(string(), unknown())
|
|
59326
|
+
}), {
|
|
59327
|
+
kind: "mutation",
|
|
59328
|
+
auth: "admin"
|
|
59319
59329
|
});
|
|
59320
59330
|
method(object({
|
|
59321
59331
|
sourceUrl: string(),
|
|
@@ -80642,11 +80652,15 @@ discriminatedUnion("kind", [object({
|
|
|
80642
80652
|
* 1. idle floor F = time-weighted median; noise ceiling N = highest value seen
|
|
80643
80653
|
* near F. A device that is not near one level most of the time has no floor.
|
|
80644
80654
|
* 2. coarse activity = above max(2N, N + 5 W); consecutive stretches are episodes.
|
|
80645
|
-
* 3.
|
|
80646
|
-
*
|
|
80655
|
+
* 3. an episode shorter than `PULSE_MAX_MS` is a PULSE (an anti-crease tumble, a
|
|
80656
|
+
* display waking): it is neither a run nor a pause. Among the remaining
|
|
80657
|
+
* episodes, gaps over `PAUSE_MAX_MS` always separate runs; the rest split in
|
|
80658
|
+
* two by the largest log-scale jump (>= 3x): the short ones are pauses INSIDE
|
|
80659
|
+
* a run (a soak), the long ones separate runs. A stretch under `MIN_RUN_MS`
|
|
80660
|
+
* is no run.
|
|
80647
80661
|
* 4. T = geometric mean of N and the plateau's 10th percentile, snapped to a
|
|
80648
|
-
* grid a person would type; stop dwell covers the longest pause
|
|
80649
|
-
* covers the longest standby blip above T.
|
|
80662
|
+
* grid a person would type; stop dwell covers the longest pause and the
|
|
80663
|
+
* kind's floor; start dwell covers the longest pulse and standby blip above T.
|
|
80650
80664
|
* 5. the numbers are proved by REPLAY through the real `dwell` evaluation: each
|
|
80651
80665
|
* run must hold exactly one true interval and nothing may flap outside.
|
|
80652
80666
|
*/
|
|
@@ -80657,6 +80671,10 @@ var MINUTE_MS$1 = 60 * SECOND_MS;
|
|
|
80657
80671
|
30 * SECOND_MS;
|
|
80658
80672
|
60 * SECOND_MS;
|
|
80659
80673
|
20 * MINUTE_MS$1;
|
|
80674
|
+
90 * SECOND_MS;
|
|
80675
|
+
30 * MINUTE_MS$1;
|
|
80676
|
+
10 * MINUTE_MS$1;
|
|
80677
|
+
DeviceType.Dryer, 3 * MINUTE_MS$1, DeviceType.Dishwasher, 3 * MINUTE_MS$1, DeviceType.Washer, 10 * MINUTE_MS$1;
|
|
80660
80678
|
10 * SECOND_MS;
|
|
80661
80679
|
10 * SECOND_MS;
|
|
80662
80680
|
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverStoppable, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
@@ -85976,13 +85994,6 @@ Object.freeze({
|
|
|
85976
85994
|
access: "view",
|
|
85977
85995
|
role: "admin"
|
|
85978
85996
|
},
|
|
85979
|
-
"integrations.getSettings": {
|
|
85980
|
-
capName: "integrations",
|
|
85981
|
-
capScope: "system",
|
|
85982
|
-
addonId: null,
|
|
85983
|
-
access: "view",
|
|
85984
|
-
role: "admin"
|
|
85985
|
-
},
|
|
85986
85997
|
"integrations.list": {
|
|
85987
85998
|
capName: "integrations",
|
|
85988
85999
|
capScope: "system",
|
|
@@ -85990,13 +86001,6 @@ Object.freeze({
|
|
|
85990
86001
|
access: "view",
|
|
85991
86002
|
role: "admin"
|
|
85992
86003
|
},
|
|
85993
|
-
"integrations.setSettings": {
|
|
85994
|
-
capName: "integrations",
|
|
85995
|
-
capScope: "system",
|
|
85996
|
-
addonId: null,
|
|
85997
|
-
access: "create",
|
|
85998
|
-
role: "admin"
|
|
85999
|
-
},
|
|
86000
86004
|
"integrations.testConnection": {
|
|
86001
86005
|
capName: "integrations",
|
|
86002
86006
|
capScope: "system",
|
|
@@ -86991,6 +86995,13 @@ Object.freeze({
|
|
|
86991
86995
|
access: "view",
|
|
86992
86996
|
role: "admin"
|
|
86993
86997
|
},
|
|
86998
|
+
"migrations.clearLegacyIntegrationRows": {
|
|
86999
|
+
capName: "migrations",
|
|
87000
|
+
capScope: "system",
|
|
87001
|
+
addonId: null,
|
|
87002
|
+
access: "delete",
|
|
87003
|
+
role: "admin"
|
|
87004
|
+
},
|
|
86994
87005
|
"migrations.declareOwner": {
|
|
86995
87006
|
capName: "migrations",
|
|
86996
87007
|
capScope: "system",
|
|
@@ -86998,6 +87009,13 @@ Object.freeze({
|
|
|
86998
87009
|
access: "create",
|
|
86999
87010
|
role: "admin"
|
|
87000
87011
|
},
|
|
87012
|
+
"migrations.deleteLegacyIntegrationRowKeys": {
|
|
87013
|
+
capName: "migrations",
|
|
87014
|
+
capScope: "system",
|
|
87015
|
+
addonId: null,
|
|
87016
|
+
access: "delete",
|
|
87017
|
+
role: "admin"
|
|
87018
|
+
},
|
|
87001
87019
|
"migrations.dryRun": {
|
|
87002
87020
|
capName: "migrations",
|
|
87003
87021
|
capScope: "system",
|
|
@@ -87033,6 +87051,20 @@ Object.freeze({
|
|
|
87033
87051
|
access: "create",
|
|
87034
87052
|
role: "admin"
|
|
87035
87053
|
},
|
|
87054
|
+
"migrations.patchLegacyIntegrationRows": {
|
|
87055
|
+
capName: "migrations",
|
|
87056
|
+
capScope: "system",
|
|
87057
|
+
addonId: null,
|
|
87058
|
+
access: "create",
|
|
87059
|
+
role: "admin"
|
|
87060
|
+
},
|
|
87061
|
+
"migrations.readLegacyIntegrationRows": {
|
|
87062
|
+
capName: "migrations",
|
|
87063
|
+
capScope: "system",
|
|
87064
|
+
addonId: null,
|
|
87065
|
+
access: "view",
|
|
87066
|
+
role: "admin"
|
|
87067
|
+
},
|
|
87036
87068
|
"migrations.restorePreMigration": {
|
|
87037
87069
|
capName: "migrations",
|
|
87038
87070
|
capScope: "system",
|
|
@@ -145507,18 +145539,10 @@ var AlexaImportAddon = class extends BaseDeviceProvider {
|
|
|
145507
145539
|
try {
|
|
145508
145540
|
const mine = (await this.ctx.api.integrations.list.query()).filter((i) => i.addonId === this.ctx.id);
|
|
145509
145541
|
const surviving = new Set(mine.map((i) => i.id));
|
|
145510
|
-
for (const
|
|
145511
|
-
const
|
|
145512
|
-
|
|
145513
|
-
|
|
145514
|
-
if (!this.activeBrokers.some((b) => b.id === brokerId)) {
|
|
145515
|
-
this.ctx.logger.warn("Alexa integration→broker: linked broker not found", { meta: {
|
|
145516
|
-
integrationId: integration.id,
|
|
145517
|
-
brokerId
|
|
145518
|
-
} });
|
|
145519
|
-
continue;
|
|
145520
|
-
}
|
|
145521
|
-
this.requireRegistry().linkIntegration(integration.id, brokerId);
|
|
145542
|
+
for (const broker of this.activeBrokers) {
|
|
145543
|
+
const integrationId = broker.integrationId;
|
|
145544
|
+
if (integrationId === void 0 || !surviving.has(integrationId)) continue;
|
|
145545
|
+
this.requireRegistry().linkIntegration(integrationId, broker.id);
|
|
145522
145546
|
}
|
|
145523
145547
|
const toRemove = this.activeBrokers.filter((b) => b.integrationId !== void 0 && !surviving.has(b.integrationId)).map((b) => b.id);
|
|
145524
145548
|
if (toRemove.length === 0) return;
|
|
@@ -145560,9 +145584,9 @@ var AlexaImportAddon = class extends BaseDeviceProvider {
|
|
|
145560
145584
|
},
|
|
145561
145585
|
logger: this.ctx.logger,
|
|
145562
145586
|
getBrokerIdForIntegration: async (id) => {
|
|
145563
|
-
const
|
|
145564
|
-
if (
|
|
145565
|
-
return
|
|
145587
|
+
const broker = this.activeBrokers.find((entry) => entry.integrationId === id);
|
|
145588
|
+
if (broker === void 0) throw new Error(`integration ${id} has no linked brokerId`);
|
|
145589
|
+
return broker.id;
|
|
145566
145590
|
},
|
|
145567
145591
|
listAdoptedAlexa: async () => {
|
|
145568
145592
|
const reg = this.ctx.kernel.deviceRegistry;
|
package/dist/addon.mjs
CHANGED
|
@@ -6042,7 +6042,7 @@ function number(params) {
|
|
|
6042
6042
|
return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
|
|
6043
6043
|
}
|
|
6044
6044
|
//#endregion
|
|
6045
|
-
//#region ../types/dist/sleep-
|
|
6045
|
+
//#region ../types/dist/sleep-9TIHFj1w.mjs
|
|
6046
6046
|
/**
|
|
6047
6047
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6048
6048
|
* window to float samples (D455).
|
|
@@ -7986,10 +7986,9 @@ var BaseAddon = class {
|
|
|
7986
7986
|
*
|
|
7987
7987
|
* Override it only when an `instanceMode: multiple` addon's instances differ: an NVR integration
|
|
7988
7988
|
* needs its connection fields, the default integration the addon's own sections. It is the
|
|
7989
|
-
* SHAPE of the form only — the values live
|
|
7990
|
-
* unchanged (`integrations.setSettings` for an account integration).
|
|
7989
|
+
* SHAPE of the form only — the values live on the instance record.
|
|
7991
7990
|
*/
|
|
7992
|
-
async
|
|
7991
|
+
async integrationFormSchema(_instance) {
|
|
7993
7992
|
return null;
|
|
7994
7993
|
}
|
|
7995
7994
|
/**
|
|
@@ -8035,7 +8034,7 @@ var BaseAddon = class {
|
|
|
8035
8034
|
* per-instance schema when it declares one, else its global schema (what they always showed).
|
|
8036
8035
|
*/
|
|
8037
8036
|
async getIntegrationFormSchema(instance, nodeId) {
|
|
8038
|
-
const scoped = await this.
|
|
8037
|
+
const scoped = await this.integrationFormSchema(instance);
|
|
8039
8038
|
if (scoped === null) return this.getGlobalSettings(void 0, void 0, nodeId);
|
|
8040
8039
|
return hydrateSchema(scoped, {}, { inlineSecretsAsViews: true });
|
|
8041
8040
|
}
|
|
@@ -9309,6 +9308,7 @@ function defineEntryKind(name, spec) {
|
|
|
9309
9308
|
class: "config",
|
|
9310
9309
|
writeTrigger: spec.writeTrigger ?? "an operator adds or edits an entry in the entries UI",
|
|
9311
9310
|
retention: { none: "an entry goes only when the operator deletes it" },
|
|
9311
|
+
...spec.maxDataBytes === void 0 ? {} : { maxDataBytes: spec.maxDataBytes },
|
|
9312
9312
|
...spec.database === void 0 ? {} : { database: spec.database },
|
|
9313
9313
|
...spec.indexes === void 0 ? {} : { indexes: spec.indexes },
|
|
9314
9314
|
...spec.secretArrayKeys === void 0 ? {} : { secretArrayKeys: spec.secretArrayKeys },
|
|
@@ -11978,7 +11978,7 @@ object({
|
|
|
11978
11978
|
params: record(string(), union([string(), number$1()])).optional()
|
|
11979
11979
|
});
|
|
11980
11980
|
//#endregion
|
|
11981
|
-
//#region ../types/dist/composition-
|
|
11981
|
+
//#region ../types/dist/composition-pOHbTzRB.mjs
|
|
11982
11982
|
/**
|
|
11983
11983
|
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
11984
11984
|
*
|
|
@@ -50458,6 +50458,9 @@ var RunningProposalEvidenceSchema = object({
|
|
|
50458
50458
|
runsFound: number$1().int().nonnegative(),
|
|
50459
50459
|
pausesFound: number$1().int().nonnegative(),
|
|
50460
50460
|
longestPauseMs: number$1().nonnegative(),
|
|
50461
|
+
/** Episodes shorter than ~90 s (an anti-crease pulse, a display waking): never a run, never a pause. */
|
|
50462
|
+
pulsesFound: number$1().int().nonnegative(),
|
|
50463
|
+
longestPulseMs: number$1().nonnegative(),
|
|
50461
50464
|
idleFloorW: number$1(),
|
|
50462
50465
|
noiseCeilingW: number$1(),
|
|
50463
50466
|
plateauW: number$1(),
|
|
@@ -56303,11 +56306,7 @@ var CreateIntegrationInputSchema = object({
|
|
|
56303
56306
|
info: record(string(), unknown()).optional(),
|
|
56304
56307
|
/** `stableId` of the discovery candidate the form was seeded from (D984). */
|
|
56305
56308
|
originStableId: string().optional(),
|
|
56306
|
-
settings: record(string(), unknown()).optional()
|
|
56307
|
-
/** Keys of `settings` the form's schema declares secret (by type) — kept in
|
|
56308
|
-
* the keychain, not the table (D787). */
|
|
56309
|
-
secretKeys: array(string()).optional(),
|
|
56310
|
-
skipRestart: boolean().optional()
|
|
56309
|
+
settings: record(string(), unknown()).optional()
|
|
56311
56310
|
});
|
|
56312
56311
|
var UpdateIntegrationInputSchema = object({
|
|
56313
56312
|
id: string(),
|
|
@@ -56328,16 +56327,6 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
56328
56327
|
}), method(object({ id: string() }), DeleteIntegrationResultSchema, {
|
|
56329
56328
|
kind: "mutation",
|
|
56330
56329
|
auth: "admin"
|
|
56331
|
-
}), method(object({ id: string() }), record(string(), unknown()), { auth: "admin" }), method(object({
|
|
56332
|
-
id: string(),
|
|
56333
|
-
settings: record(string(), unknown()),
|
|
56334
|
-
/** Keys the form's schema declares secret (by type) — keychain-stored (D787). */
|
|
56335
|
-
secretKeys: array(string()).optional(),
|
|
56336
|
-
/** The integration's own addon applies the change in-process and asks the hub not to respawn it. */
|
|
56337
|
-
skipRestart: boolean().optional()
|
|
56338
|
-
}), object({ success: boolean() }), {
|
|
56339
|
-
kind: "mutation",
|
|
56340
|
-
auth: "admin"
|
|
56341
56330
|
}), method(_void(), array(AvailableIntegrationTypeSchema), { auth: "admin" }), method(object({
|
|
56342
56331
|
addonId: string(),
|
|
56343
56332
|
settings: record(string(), unknown())
|
|
@@ -59314,6 +59303,27 @@ method(object({}), object({ entries: array(MigrationLedgerEntrySchema) }), { aut
|
|
|
59314
59303
|
}), {
|
|
59315
59304
|
kind: "mutation",
|
|
59316
59305
|
auth: "admin"
|
|
59306
|
+
}), method(object({ integrationId: string().min(1) }), record(string(), unknown()), { auth: "admin" }), method(object({ integrationId: string().min(1) }), object({
|
|
59307
|
+
rows: number$1().int().nonnegative(),
|
|
59308
|
+
secrets: number$1().int().nonnegative()
|
|
59309
|
+
}), {
|
|
59310
|
+
kind: "mutation",
|
|
59311
|
+
auth: "admin"
|
|
59312
|
+
}), method(object({
|
|
59313
|
+
integrationId: string().min(1),
|
|
59314
|
+
patch: record(string(), unknown())
|
|
59315
|
+
}), object({ written: boolean() }), {
|
|
59316
|
+
kind: "mutation",
|
|
59317
|
+
auth: "admin"
|
|
59318
|
+
}), method(object({
|
|
59319
|
+
integrationId: string().min(1),
|
|
59320
|
+
keys: array(string().min(1))
|
|
59321
|
+
}), object({
|
|
59322
|
+
present: boolean(),
|
|
59323
|
+
removed: record(string(), unknown())
|
|
59324
|
+
}), {
|
|
59325
|
+
kind: "mutation",
|
|
59326
|
+
auth: "admin"
|
|
59317
59327
|
});
|
|
59318
59328
|
method(object({
|
|
59319
59329
|
sourceUrl: string(),
|
|
@@ -80640,11 +80650,15 @@ discriminatedUnion("kind", [object({
|
|
|
80640
80650
|
* 1. idle floor F = time-weighted median; noise ceiling N = highest value seen
|
|
80641
80651
|
* near F. A device that is not near one level most of the time has no floor.
|
|
80642
80652
|
* 2. coarse activity = above max(2N, N + 5 W); consecutive stretches are episodes.
|
|
80643
|
-
* 3.
|
|
80644
|
-
*
|
|
80653
|
+
* 3. an episode shorter than `PULSE_MAX_MS` is a PULSE (an anti-crease tumble, a
|
|
80654
|
+
* display waking): it is neither a run nor a pause. Among the remaining
|
|
80655
|
+
* episodes, gaps over `PAUSE_MAX_MS` always separate runs; the rest split in
|
|
80656
|
+
* two by the largest log-scale jump (>= 3x): the short ones are pauses INSIDE
|
|
80657
|
+
* a run (a soak), the long ones separate runs. A stretch under `MIN_RUN_MS`
|
|
80658
|
+
* is no run.
|
|
80645
80659
|
* 4. T = geometric mean of N and the plateau's 10th percentile, snapped to a
|
|
80646
|
-
* grid a person would type; stop dwell covers the longest pause
|
|
80647
|
-
* covers the longest standby blip above T.
|
|
80660
|
+
* grid a person would type; stop dwell covers the longest pause and the
|
|
80661
|
+
* kind's floor; start dwell covers the longest pulse and standby blip above T.
|
|
80648
80662
|
* 5. the numbers are proved by REPLAY through the real `dwell` evaluation: each
|
|
80649
80663
|
* run must hold exactly one true interval and nothing may flap outside.
|
|
80650
80664
|
*/
|
|
@@ -80655,6 +80669,10 @@ var MINUTE_MS$1 = 60 * SECOND_MS;
|
|
|
80655
80669
|
30 * SECOND_MS;
|
|
80656
80670
|
60 * SECOND_MS;
|
|
80657
80671
|
20 * MINUTE_MS$1;
|
|
80672
|
+
90 * SECOND_MS;
|
|
80673
|
+
30 * MINUTE_MS$1;
|
|
80674
|
+
10 * MINUTE_MS$1;
|
|
80675
|
+
DeviceType.Dryer, 3 * MINUTE_MS$1, DeviceType.Dishwasher, 3 * MINUTE_MS$1, DeviceType.Washer, 10 * MINUTE_MS$1;
|
|
80658
80676
|
10 * SECOND_MS;
|
|
80659
80677
|
10 * SECOND_MS;
|
|
80660
80678
|
DeviceFeature.FanSpeed, DeviceFeature.FanPreset, DeviceFeature.FanDirection, DeviceFeature.FanOscillating, DeviceFeature.CoverStoppable, DeviceFeature.CoverPositionable, DeviceFeature.CoverTilt, DeviceFeature.ValvePositionable, DeviceFeature.MediaPlayerVolume, DeviceFeature.ClimateFanMode;
|
|
@@ -85974,13 +85992,6 @@ Object.freeze({
|
|
|
85974
85992
|
access: "view",
|
|
85975
85993
|
role: "admin"
|
|
85976
85994
|
},
|
|
85977
|
-
"integrations.getSettings": {
|
|
85978
|
-
capName: "integrations",
|
|
85979
|
-
capScope: "system",
|
|
85980
|
-
addonId: null,
|
|
85981
|
-
access: "view",
|
|
85982
|
-
role: "admin"
|
|
85983
|
-
},
|
|
85984
85995
|
"integrations.list": {
|
|
85985
85996
|
capName: "integrations",
|
|
85986
85997
|
capScope: "system",
|
|
@@ -85988,13 +85999,6 @@ Object.freeze({
|
|
|
85988
85999
|
access: "view",
|
|
85989
86000
|
role: "admin"
|
|
85990
86001
|
},
|
|
85991
|
-
"integrations.setSettings": {
|
|
85992
|
-
capName: "integrations",
|
|
85993
|
-
capScope: "system",
|
|
85994
|
-
addonId: null,
|
|
85995
|
-
access: "create",
|
|
85996
|
-
role: "admin"
|
|
85997
|
-
},
|
|
85998
86002
|
"integrations.testConnection": {
|
|
85999
86003
|
capName: "integrations",
|
|
86000
86004
|
capScope: "system",
|
|
@@ -86989,6 +86993,13 @@ Object.freeze({
|
|
|
86989
86993
|
access: "view",
|
|
86990
86994
|
role: "admin"
|
|
86991
86995
|
},
|
|
86996
|
+
"migrations.clearLegacyIntegrationRows": {
|
|
86997
|
+
capName: "migrations",
|
|
86998
|
+
capScope: "system",
|
|
86999
|
+
addonId: null,
|
|
87000
|
+
access: "delete",
|
|
87001
|
+
role: "admin"
|
|
87002
|
+
},
|
|
86992
87003
|
"migrations.declareOwner": {
|
|
86993
87004
|
capName: "migrations",
|
|
86994
87005
|
capScope: "system",
|
|
@@ -86996,6 +87007,13 @@ Object.freeze({
|
|
|
86996
87007
|
access: "create",
|
|
86997
87008
|
role: "admin"
|
|
86998
87009
|
},
|
|
87010
|
+
"migrations.deleteLegacyIntegrationRowKeys": {
|
|
87011
|
+
capName: "migrations",
|
|
87012
|
+
capScope: "system",
|
|
87013
|
+
addonId: null,
|
|
87014
|
+
access: "delete",
|
|
87015
|
+
role: "admin"
|
|
87016
|
+
},
|
|
86999
87017
|
"migrations.dryRun": {
|
|
87000
87018
|
capName: "migrations",
|
|
87001
87019
|
capScope: "system",
|
|
@@ -87031,6 +87049,20 @@ Object.freeze({
|
|
|
87031
87049
|
access: "create",
|
|
87032
87050
|
role: "admin"
|
|
87033
87051
|
},
|
|
87052
|
+
"migrations.patchLegacyIntegrationRows": {
|
|
87053
|
+
capName: "migrations",
|
|
87054
|
+
capScope: "system",
|
|
87055
|
+
addonId: null,
|
|
87056
|
+
access: "create",
|
|
87057
|
+
role: "admin"
|
|
87058
|
+
},
|
|
87059
|
+
"migrations.readLegacyIntegrationRows": {
|
|
87060
|
+
capName: "migrations",
|
|
87061
|
+
capScope: "system",
|
|
87062
|
+
addonId: null,
|
|
87063
|
+
access: "view",
|
|
87064
|
+
role: "admin"
|
|
87065
|
+
},
|
|
87034
87066
|
"migrations.restorePreMigration": {
|
|
87035
87067
|
capName: "migrations",
|
|
87036
87068
|
capScope: "system",
|
|
@@ -145505,18 +145537,10 @@ var AlexaImportAddon = class extends BaseDeviceProvider {
|
|
|
145505
145537
|
try {
|
|
145506
145538
|
const mine = (await this.ctx.api.integrations.list.query()).filter((i) => i.addonId === this.ctx.id);
|
|
145507
145539
|
const surviving = new Set(mine.map((i) => i.id));
|
|
145508
|
-
for (const
|
|
145509
|
-
const
|
|
145510
|
-
|
|
145511
|
-
|
|
145512
|
-
if (!this.activeBrokers.some((b) => b.id === brokerId)) {
|
|
145513
|
-
this.ctx.logger.warn("Alexa integration→broker: linked broker not found", { meta: {
|
|
145514
|
-
integrationId: integration.id,
|
|
145515
|
-
brokerId
|
|
145516
|
-
} });
|
|
145517
|
-
continue;
|
|
145518
|
-
}
|
|
145519
|
-
this.requireRegistry().linkIntegration(integration.id, brokerId);
|
|
145540
|
+
for (const broker of this.activeBrokers) {
|
|
145541
|
+
const integrationId = broker.integrationId;
|
|
145542
|
+
if (integrationId === void 0 || !surviving.has(integrationId)) continue;
|
|
145543
|
+
this.requireRegistry().linkIntegration(integrationId, broker.id);
|
|
145520
145544
|
}
|
|
145521
145545
|
const toRemove = this.activeBrokers.filter((b) => b.integrationId !== void 0 && !surviving.has(b.integrationId)).map((b) => b.id);
|
|
145522
145546
|
if (toRemove.length === 0) return;
|
|
@@ -145558,9 +145582,9 @@ var AlexaImportAddon = class extends BaseDeviceProvider {
|
|
|
145558
145582
|
},
|
|
145559
145583
|
logger: this.ctx.logger,
|
|
145560
145584
|
getBrokerIdForIntegration: async (id) => {
|
|
145561
|
-
const
|
|
145562
|
-
if (
|
|
145563
|
-
return
|
|
145585
|
+
const broker = this.activeBrokers.find((entry) => entry.integrationId === id);
|
|
145586
|
+
if (broker === void 0) throw new Error(`integration ${id} has no linked brokerId`);
|
|
145587
|
+
return broker.id;
|
|
145564
145588
|
},
|
|
145565
145589
|
listAdoptedAlexa: async () => {
|
|
145566
145590
|
const reg = this.ctx.kernel.deviceRegistry;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-import-alexa",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.186",
|
|
4
4
|
"description": "Alexa device-import provider for CamStack — imports the smart-home devices in a user's Alexa account via the unofficial alexa-remote2 cookie/token client (the inverse of the Alexa exporter)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
}
|
|
73
73
|
],
|
|
74
74
|
"requires": {
|
|
75
|
-
"server": ">=1.2.
|
|
75
|
+
"server": ">=1.2.770"
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
78
|
"files": [
|