@camstack/addon-import-alexa 0.2.170 → 0.2.171
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 +58 -49
- package/dist/addon.mjs +58 -49
- package/i18n/en.json +0 -1
- package/i18n/it.json +0 -1
- package/package.json +1 -1
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.171] - 2026-10-30
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Notification targets pick a broker and list their options inside the add/edit form; the page-wide Find devices dialog is gone
|
|
15
|
+
|
|
10
16
|
## [0.2.170] - 2026-10-30
|
|
11
17
|
|
|
12
18
|
### Changed
|
package/dist/addon.js
CHANGED
|
@@ -57379,6 +57379,12 @@ var TerminalInstanceInfoSchema = object({
|
|
|
57379
57379
|
instanceId: string(),
|
|
57380
57380
|
cameraStableId: string(),
|
|
57381
57381
|
nodeId: string(),
|
|
57382
|
+
/**
|
|
57383
|
+
* False while the node the instance is bound to is not in the cluster
|
|
57384
|
+
* topology (forgotten, renamed, re-paired). The instance is kept; the
|
|
57385
|
+
* operator re-points it with `updateInstance({ targetNodeId })`.
|
|
57386
|
+
*/
|
|
57387
|
+
nodeInCluster: boolean(),
|
|
57382
57388
|
profileId: string(),
|
|
57383
57389
|
profileLabel: string(),
|
|
57384
57390
|
name: string(),
|
|
@@ -57428,6 +57434,8 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
|
|
|
57428
57434
|
auth: "admin"
|
|
57429
57435
|
}), method(object({
|
|
57430
57436
|
instanceId: string().min(1),
|
|
57437
|
+
/** Re-point the instance to another node; the profile must exist there. */
|
|
57438
|
+
targetNodeId: string().min(1).max(256).optional(),
|
|
57431
57439
|
name: string().trim().min(1).max(160).optional(),
|
|
57432
57440
|
executable: string().max(1024).optional(),
|
|
57433
57441
|
args: array(string().max(2048)).max(64).optional(),
|
|
@@ -137868,8 +137876,17 @@ var AlexaBrokerRegistry = class {
|
|
|
137868
137876
|
}
|
|
137869
137877
|
};
|
|
137870
137878
|
//#endregion
|
|
137879
|
+
//#region src/speak/constants.ts
|
|
137880
|
+
/** Echo speech limits and the worker restart bound (same window as CrashSupervisor). */
|
|
137881
|
+
var ALEXA_SPEAK_ADDON_ID = "import-alexa";
|
|
137882
|
+
var ALEXA_SPEAK_KIND = "alexa-echo";
|
|
137883
|
+
/** The kind of the Amazon-account broker the Echoes are read from. */
|
|
137884
|
+
var ALEXA_BROKER_KIND = "alexa";
|
|
137885
|
+
var DEVICE_REFRESH_MS = 5 * 6e4;
|
|
137886
|
+
/** Where the addon serves the Alexa mark; `listTargetKinds` stamps it as `iconUrl`. */
|
|
137887
|
+
var ALEXA_SPEAK_ICON_URL = `/addon/${ALEXA_SPEAK_ADDON_ID}/icons/${ALEXA_SPEAK_KIND}`;
|
|
137888
|
+
//#endregion
|
|
137871
137889
|
//#region src/alexa-broker-provider.ts
|
|
137872
|
-
var ALEXA_KIND = "alexa";
|
|
137873
137890
|
/**
|
|
137874
137891
|
* Construct the `broker` cap provider for the Alexa import addon. Pure builder.
|
|
137875
137892
|
* Mirrors `buildEcowittBrokerProvider`. The cookie + refresh token are secrets:
|
|
@@ -137887,7 +137904,7 @@ function buildAlexaBrokerProvider(deps) {
|
|
|
137887
137904
|
});
|
|
137888
137905
|
return {
|
|
137889
137906
|
list: async ({ kind }) => {
|
|
137890
|
-
if (kind && kind !==
|
|
137907
|
+
if (kind && kind !== "alexa") return [];
|
|
137891
137908
|
return registry.list().map((info) => ({
|
|
137892
137909
|
...info,
|
|
137893
137910
|
addonId: ownerAddonId
|
|
@@ -137903,7 +137920,7 @@ function buildAlexaBrokerProvider(deps) {
|
|
|
137903
137920
|
listProviders: async () => [{
|
|
137904
137921
|
addonId: ownerAddonId,
|
|
137905
137922
|
kinds: [{
|
|
137906
|
-
kind:
|
|
137923
|
+
kind: ALEXA_BROKER_KIND,
|
|
137907
137924
|
label: "Alexa",
|
|
137908
137925
|
signIn: {
|
|
137909
137926
|
basePath: "/addon/import-alexa/login",
|
|
@@ -137912,7 +137929,7 @@ function buildAlexaBrokerProvider(deps) {
|
|
|
137912
137929
|
}]
|
|
137913
137930
|
}],
|
|
137914
137931
|
add: async ({ kind, name, settings }) => {
|
|
137915
|
-
if (kind !==
|
|
137932
|
+
if (kind !== "alexa") throw new Error(`import-alexa: only kind '${ALEXA_BROKER_KIND}' is handled here (got '${kind}')`);
|
|
137916
137933
|
const entry = await registry.createEntry(name, settingsToAlexaConnection(settings));
|
|
137917
137934
|
await persistBrokers([...getBrokers(), entry]);
|
|
137918
137935
|
return { id: entry.id };
|
|
@@ -137970,11 +137987,11 @@ function buildAlexaBrokerProvider(deps) {
|
|
|
137970
137987
|
return entry ? redact(entry) : null;
|
|
137971
137988
|
},
|
|
137972
137989
|
getSettingsSchema: async ({ kind }) => {
|
|
137973
|
-
if (kind !==
|
|
137990
|
+
if (kind !== "alexa") return null;
|
|
137974
137991
|
return buildConnectionFormSchema();
|
|
137975
137992
|
},
|
|
137976
137993
|
testSettings: async ({ kind, settings }) => {
|
|
137977
|
-
if (kind !==
|
|
137994
|
+
if (kind !== "alexa") return {
|
|
137978
137995
|
ok: false,
|
|
137979
137996
|
error: `unsupported kind: ${kind}`
|
|
137980
137997
|
};
|
|
@@ -139193,14 +139210,6 @@ var BrokerEcho = class {
|
|
|
139193
139210
|
}
|
|
139194
139211
|
};
|
|
139195
139212
|
//#endregion
|
|
139196
|
-
//#region src/speak/constants.ts
|
|
139197
|
-
/** Echo speech limits and the worker restart bound (same window as CrashSupervisor). */
|
|
139198
|
-
var ALEXA_SPEAK_ADDON_ID = "import-alexa";
|
|
139199
|
-
var ALEXA_SPEAK_KIND = "alexa-echo";
|
|
139200
|
-
var DEVICE_REFRESH_MS = 5 * 6e4;
|
|
139201
|
-
/** Where the addon serves the Alexa mark; `listTargetKinds` stamps it as `iconUrl`. */
|
|
139202
|
-
var ALEXA_SPEAK_ICON_URL = `/addon/${ALEXA_SPEAK_ADDON_ID}/icons/${ALEXA_SPEAK_KIND}`;
|
|
139203
|
-
//#endregion
|
|
139204
139213
|
//#region src/speak/rate-limit.ts
|
|
139205
139214
|
/**
|
|
139206
139215
|
* Per-Echo admission. A burst is dropped here, not queued: a queue would be
|
|
@@ -139351,50 +139360,37 @@ function echoOptionLabel(device) {
|
|
|
139351
139360
|
if (kind.length > 0) parts.push(kind);
|
|
139352
139361
|
return parts.join(" · ");
|
|
139353
139362
|
}
|
|
139354
|
-
function echoField(devices, showWhen) {
|
|
139355
|
-
return {
|
|
139356
|
-
type: "select",
|
|
139357
|
-
key: "echoId",
|
|
139358
|
-
label: "Echo",
|
|
139359
|
-
labelKey: "import-alexa:echoTarget.s_echo.echoId.label",
|
|
139360
|
-
description: devices.length === 0 ? "No Echo found yet. Sign the Amazon account in on Integrations, Alexa." : void 0,
|
|
139361
|
-
descriptionKey: devices.length === 0 ? "import-alexa:echoTarget.s_echo.echoId.empty" : void 0,
|
|
139362
|
-
options: devices.map((device) => ({
|
|
139363
|
-
value: device.id,
|
|
139364
|
-
label: echoOptionLabel(device)
|
|
139365
|
-
})),
|
|
139366
|
-
...showWhen === void 0 ? {} : { showWhen }
|
|
139367
|
-
};
|
|
139368
|
-
}
|
|
139369
139363
|
/**
|
|
139370
139364
|
* The two pickers are not `required`: a required select shows its first option
|
|
139371
139365
|
* while the form still holds no value, so a save would drop the choice. Left
|
|
139372
139366
|
* optional they open on "Select", and `upsertTarget` refuses an empty pick.
|
|
139373
139367
|
*
|
|
139374
|
-
* The
|
|
139375
|
-
* so a new Echo shows up without a deploy.
|
|
139376
|
-
* field; with several, each account's Echoes appear when that account is chosen.
|
|
139368
|
+
* The account is a broker pick (existing, or created in place); the Echo list
|
|
139369
|
+
* is fetched from that account, so a new Echo shows up without a deploy.
|
|
139377
139370
|
*/
|
|
139378
|
-
function configSchema(
|
|
139379
|
-
const first = brokers[0];
|
|
139371
|
+
function configSchema() {
|
|
139380
139372
|
return { sections: [{
|
|
139381
139373
|
id: "echo",
|
|
139382
139374
|
title: "Echo",
|
|
139383
139375
|
titleKey: "import-alexa:echoTarget.s_echo.title",
|
|
139384
139376
|
fields: [
|
|
139385
|
-
...
|
|
139386
|
-
type: "select",
|
|
139377
|
+
...[{
|
|
139378
|
+
type: "broker-select",
|
|
139387
139379
|
key: "brokerId",
|
|
139388
139380
|
label: "Amazon account",
|
|
139389
139381
|
labelKey: "import-alexa:echoTarget.s_echo.brokerId.label",
|
|
139390
|
-
|
|
139391
|
-
|
|
139392
|
-
|
|
139393
|
-
|
|
139394
|
-
|
|
139395
|
-
|
|
139396
|
-
|
|
139397
|
-
|
|
139382
|
+
brokerKind: ALEXA_BROKER_KIND
|
|
139383
|
+
}, {
|
|
139384
|
+
type: "select",
|
|
139385
|
+
key: "echoId",
|
|
139386
|
+
label: "Echo",
|
|
139387
|
+
labelKey: "import-alexa:echoTarget.s_echo.echoId.label",
|
|
139388
|
+
options: [],
|
|
139389
|
+
discoverOptions: {
|
|
139390
|
+
kind: ALEXA_SPEAK_KIND,
|
|
139391
|
+
dependsOn: ["brokerId"]
|
|
139392
|
+
}
|
|
139393
|
+
}],
|
|
139398
139394
|
{
|
|
139399
139395
|
type: "select",
|
|
139400
139396
|
key: "mode",
|
|
@@ -139428,8 +139424,8 @@ function configSchema(brokers) {
|
|
|
139428
139424
|
]
|
|
139429
139425
|
}] };
|
|
139430
139426
|
}
|
|
139431
|
-
/** The Alexa target kind as the Add target form sees it
|
|
139432
|
-
function alexaTargetKind(
|
|
139427
|
+
/** The Alexa target kind as the Add target form sees it. */
|
|
139428
|
+
function alexaTargetKind() {
|
|
139433
139429
|
return {
|
|
139434
139430
|
kind: ALEXA_SPEAK_KIND,
|
|
139435
139431
|
label: "Alexa",
|
|
@@ -139439,7 +139435,7 @@ function alexaTargetKind(brokers) {
|
|
|
139439
139435
|
addonId: ALEXA_SPEAK_ADDON_ID,
|
|
139440
139436
|
supportsDiscovery: true,
|
|
139441
139437
|
destinationKeys: ["brokerId", "echoId"],
|
|
139442
|
-
configSchema: configSchema(
|
|
139438
|
+
configSchema: configSchema(),
|
|
139443
139439
|
deliveryParams: DELIVERY_PARAMS,
|
|
139444
139440
|
caps: {
|
|
139445
139441
|
attachments: {
|
|
@@ -139701,7 +139697,7 @@ function createAlexaNotificationProvider(ports) {
|
|
|
139701
139697
|
return deliveries;
|
|
139702
139698
|
},
|
|
139703
139699
|
async listTargetKinds() {
|
|
139704
|
-
return [alexaTargetKind(
|
|
139700
|
+
return [alexaTargetKind()];
|
|
139705
139701
|
},
|
|
139706
139702
|
async listTargets() {
|
|
139707
139703
|
return [...targets];
|
|
@@ -139711,7 +139707,20 @@ function createAlexaNotificationProvider(ports) {
|
|
|
139711
139707
|
if (found === void 0) throw new Error(`target not found: ${input.targetId}`);
|
|
139712
139708
|
return found;
|
|
139713
139709
|
},
|
|
139714
|
-
async discoverTargets() {
|
|
139710
|
+
async discoverTargets(input) {
|
|
139711
|
+
const named = readString(input.config ?? {}, "brokerId");
|
|
139712
|
+
if (named.length > 0) {
|
|
139713
|
+
const owner = ports.brokers().find((broker) => broker.id === named);
|
|
139714
|
+
return (owner?.devices ?? []).map((device) => ({
|
|
139715
|
+
...discoveredFrom(owner ?? {
|
|
139716
|
+
id: named,
|
|
139717
|
+
name: named,
|
|
139718
|
+
ready: false,
|
|
139719
|
+
devices: []
|
|
139720
|
+
}, device),
|
|
139721
|
+
suggestedName: echoOptionLabel(device)
|
|
139722
|
+
}));
|
|
139723
|
+
}
|
|
139715
139724
|
const taken = new Set(targets.flatMap((row) => {
|
|
139716
139725
|
const owner = brokerFor(row.config);
|
|
139717
139726
|
return owner === void 0 ? [] : [`${owner.id}/${readString(row.config, "echoId")}`];
|
package/dist/addon.mjs
CHANGED
|
@@ -57377,6 +57377,12 @@ var TerminalInstanceInfoSchema = object({
|
|
|
57377
57377
|
instanceId: string(),
|
|
57378
57378
|
cameraStableId: string(),
|
|
57379
57379
|
nodeId: string(),
|
|
57380
|
+
/**
|
|
57381
|
+
* False while the node the instance is bound to is not in the cluster
|
|
57382
|
+
* topology (forgotten, renamed, re-paired). The instance is kept; the
|
|
57383
|
+
* operator re-points it with `updateInstance({ targetNodeId })`.
|
|
57384
|
+
*/
|
|
57385
|
+
nodeInCluster: boolean(),
|
|
57380
57386
|
profileId: string(),
|
|
57381
57387
|
profileLabel: string(),
|
|
57382
57388
|
name: string(),
|
|
@@ -57426,6 +57432,8 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
|
|
|
57426
57432
|
auth: "admin"
|
|
57427
57433
|
}), method(object({
|
|
57428
57434
|
instanceId: string().min(1),
|
|
57435
|
+
/** Re-point the instance to another node; the profile must exist there. */
|
|
57436
|
+
targetNodeId: string().min(1).max(256).optional(),
|
|
57429
57437
|
name: string().trim().min(1).max(160).optional(),
|
|
57430
57438
|
executable: string().max(1024).optional(),
|
|
57431
57439
|
args: array(string().max(2048)).max(64).optional(),
|
|
@@ -137866,8 +137874,17 @@ var AlexaBrokerRegistry = class {
|
|
|
137866
137874
|
}
|
|
137867
137875
|
};
|
|
137868
137876
|
//#endregion
|
|
137877
|
+
//#region src/speak/constants.ts
|
|
137878
|
+
/** Echo speech limits and the worker restart bound (same window as CrashSupervisor). */
|
|
137879
|
+
var ALEXA_SPEAK_ADDON_ID = "import-alexa";
|
|
137880
|
+
var ALEXA_SPEAK_KIND = "alexa-echo";
|
|
137881
|
+
/** The kind of the Amazon-account broker the Echoes are read from. */
|
|
137882
|
+
var ALEXA_BROKER_KIND = "alexa";
|
|
137883
|
+
var DEVICE_REFRESH_MS = 5 * 6e4;
|
|
137884
|
+
/** Where the addon serves the Alexa mark; `listTargetKinds` stamps it as `iconUrl`. */
|
|
137885
|
+
var ALEXA_SPEAK_ICON_URL = `/addon/${ALEXA_SPEAK_ADDON_ID}/icons/${ALEXA_SPEAK_KIND}`;
|
|
137886
|
+
//#endregion
|
|
137869
137887
|
//#region src/alexa-broker-provider.ts
|
|
137870
|
-
var ALEXA_KIND = "alexa";
|
|
137871
137888
|
/**
|
|
137872
137889
|
* Construct the `broker` cap provider for the Alexa import addon. Pure builder.
|
|
137873
137890
|
* Mirrors `buildEcowittBrokerProvider`. The cookie + refresh token are secrets:
|
|
@@ -137885,7 +137902,7 @@ function buildAlexaBrokerProvider(deps) {
|
|
|
137885
137902
|
});
|
|
137886
137903
|
return {
|
|
137887
137904
|
list: async ({ kind }) => {
|
|
137888
|
-
if (kind && kind !==
|
|
137905
|
+
if (kind && kind !== "alexa") return [];
|
|
137889
137906
|
return registry.list().map((info) => ({
|
|
137890
137907
|
...info,
|
|
137891
137908
|
addonId: ownerAddonId
|
|
@@ -137901,7 +137918,7 @@ function buildAlexaBrokerProvider(deps) {
|
|
|
137901
137918
|
listProviders: async () => [{
|
|
137902
137919
|
addonId: ownerAddonId,
|
|
137903
137920
|
kinds: [{
|
|
137904
|
-
kind:
|
|
137921
|
+
kind: ALEXA_BROKER_KIND,
|
|
137905
137922
|
label: "Alexa",
|
|
137906
137923
|
signIn: {
|
|
137907
137924
|
basePath: "/addon/import-alexa/login",
|
|
@@ -137910,7 +137927,7 @@ function buildAlexaBrokerProvider(deps) {
|
|
|
137910
137927
|
}]
|
|
137911
137928
|
}],
|
|
137912
137929
|
add: async ({ kind, name, settings }) => {
|
|
137913
|
-
if (kind !==
|
|
137930
|
+
if (kind !== "alexa") throw new Error(`import-alexa: only kind '${ALEXA_BROKER_KIND}' is handled here (got '${kind}')`);
|
|
137914
137931
|
const entry = await registry.createEntry(name, settingsToAlexaConnection(settings));
|
|
137915
137932
|
await persistBrokers([...getBrokers(), entry]);
|
|
137916
137933
|
return { id: entry.id };
|
|
@@ -137968,11 +137985,11 @@ function buildAlexaBrokerProvider(deps) {
|
|
|
137968
137985
|
return entry ? redact(entry) : null;
|
|
137969
137986
|
},
|
|
137970
137987
|
getSettingsSchema: async ({ kind }) => {
|
|
137971
|
-
if (kind !==
|
|
137988
|
+
if (kind !== "alexa") return null;
|
|
137972
137989
|
return buildConnectionFormSchema();
|
|
137973
137990
|
},
|
|
137974
137991
|
testSettings: async ({ kind, settings }) => {
|
|
137975
|
-
if (kind !==
|
|
137992
|
+
if (kind !== "alexa") return {
|
|
137976
137993
|
ok: false,
|
|
137977
137994
|
error: `unsupported kind: ${kind}`
|
|
137978
137995
|
};
|
|
@@ -139191,14 +139208,6 @@ var BrokerEcho = class {
|
|
|
139191
139208
|
}
|
|
139192
139209
|
};
|
|
139193
139210
|
//#endregion
|
|
139194
|
-
//#region src/speak/constants.ts
|
|
139195
|
-
/** Echo speech limits and the worker restart bound (same window as CrashSupervisor). */
|
|
139196
|
-
var ALEXA_SPEAK_ADDON_ID = "import-alexa";
|
|
139197
|
-
var ALEXA_SPEAK_KIND = "alexa-echo";
|
|
139198
|
-
var DEVICE_REFRESH_MS = 5 * 6e4;
|
|
139199
|
-
/** Where the addon serves the Alexa mark; `listTargetKinds` stamps it as `iconUrl`. */
|
|
139200
|
-
var ALEXA_SPEAK_ICON_URL = `/addon/${ALEXA_SPEAK_ADDON_ID}/icons/${ALEXA_SPEAK_KIND}`;
|
|
139201
|
-
//#endregion
|
|
139202
139211
|
//#region src/speak/rate-limit.ts
|
|
139203
139212
|
/**
|
|
139204
139213
|
* Per-Echo admission. A burst is dropped here, not queued: a queue would be
|
|
@@ -139349,50 +139358,37 @@ function echoOptionLabel(device) {
|
|
|
139349
139358
|
if (kind.length > 0) parts.push(kind);
|
|
139350
139359
|
return parts.join(" · ");
|
|
139351
139360
|
}
|
|
139352
|
-
function echoField(devices, showWhen) {
|
|
139353
|
-
return {
|
|
139354
|
-
type: "select",
|
|
139355
|
-
key: "echoId",
|
|
139356
|
-
label: "Echo",
|
|
139357
|
-
labelKey: "import-alexa:echoTarget.s_echo.echoId.label",
|
|
139358
|
-
description: devices.length === 0 ? "No Echo found yet. Sign the Amazon account in on Integrations, Alexa." : void 0,
|
|
139359
|
-
descriptionKey: devices.length === 0 ? "import-alexa:echoTarget.s_echo.echoId.empty" : void 0,
|
|
139360
|
-
options: devices.map((device) => ({
|
|
139361
|
-
value: device.id,
|
|
139362
|
-
label: echoOptionLabel(device)
|
|
139363
|
-
})),
|
|
139364
|
-
...showWhen === void 0 ? {} : { showWhen }
|
|
139365
|
-
};
|
|
139366
|
-
}
|
|
139367
139361
|
/**
|
|
139368
139362
|
* The two pickers are not `required`: a required select shows its first option
|
|
139369
139363
|
* while the form still holds no value, so a save would drop the choice. Left
|
|
139370
139364
|
* optional they open on "Select", and `upsertTarget` refuses an empty pick.
|
|
139371
139365
|
*
|
|
139372
|
-
* The
|
|
139373
|
-
* so a new Echo shows up without a deploy.
|
|
139374
|
-
* field; with several, each account's Echoes appear when that account is chosen.
|
|
139366
|
+
* The account is a broker pick (existing, or created in place); the Echo list
|
|
139367
|
+
* is fetched from that account, so a new Echo shows up without a deploy.
|
|
139375
139368
|
*/
|
|
139376
|
-
function configSchema(
|
|
139377
|
-
const first = brokers[0];
|
|
139369
|
+
function configSchema() {
|
|
139378
139370
|
return { sections: [{
|
|
139379
139371
|
id: "echo",
|
|
139380
139372
|
title: "Echo",
|
|
139381
139373
|
titleKey: "import-alexa:echoTarget.s_echo.title",
|
|
139382
139374
|
fields: [
|
|
139383
|
-
...
|
|
139384
|
-
type: "select",
|
|
139375
|
+
...[{
|
|
139376
|
+
type: "broker-select",
|
|
139385
139377
|
key: "brokerId",
|
|
139386
139378
|
label: "Amazon account",
|
|
139387
139379
|
labelKey: "import-alexa:echoTarget.s_echo.brokerId.label",
|
|
139388
|
-
|
|
139389
|
-
|
|
139390
|
-
|
|
139391
|
-
|
|
139392
|
-
|
|
139393
|
-
|
|
139394
|
-
|
|
139395
|
-
|
|
139380
|
+
brokerKind: ALEXA_BROKER_KIND
|
|
139381
|
+
}, {
|
|
139382
|
+
type: "select",
|
|
139383
|
+
key: "echoId",
|
|
139384
|
+
label: "Echo",
|
|
139385
|
+
labelKey: "import-alexa:echoTarget.s_echo.echoId.label",
|
|
139386
|
+
options: [],
|
|
139387
|
+
discoverOptions: {
|
|
139388
|
+
kind: ALEXA_SPEAK_KIND,
|
|
139389
|
+
dependsOn: ["brokerId"]
|
|
139390
|
+
}
|
|
139391
|
+
}],
|
|
139396
139392
|
{
|
|
139397
139393
|
type: "select",
|
|
139398
139394
|
key: "mode",
|
|
@@ -139426,8 +139422,8 @@ function configSchema(brokers) {
|
|
|
139426
139422
|
]
|
|
139427
139423
|
}] };
|
|
139428
139424
|
}
|
|
139429
|
-
/** The Alexa target kind as the Add target form sees it
|
|
139430
|
-
function alexaTargetKind(
|
|
139425
|
+
/** The Alexa target kind as the Add target form sees it. */
|
|
139426
|
+
function alexaTargetKind() {
|
|
139431
139427
|
return {
|
|
139432
139428
|
kind: ALEXA_SPEAK_KIND,
|
|
139433
139429
|
label: "Alexa",
|
|
@@ -139437,7 +139433,7 @@ function alexaTargetKind(brokers) {
|
|
|
139437
139433
|
addonId: ALEXA_SPEAK_ADDON_ID,
|
|
139438
139434
|
supportsDiscovery: true,
|
|
139439
139435
|
destinationKeys: ["brokerId", "echoId"],
|
|
139440
|
-
configSchema: configSchema(
|
|
139436
|
+
configSchema: configSchema(),
|
|
139441
139437
|
deliveryParams: DELIVERY_PARAMS,
|
|
139442
139438
|
caps: {
|
|
139443
139439
|
attachments: {
|
|
@@ -139699,7 +139695,7 @@ function createAlexaNotificationProvider(ports) {
|
|
|
139699
139695
|
return deliveries;
|
|
139700
139696
|
},
|
|
139701
139697
|
async listTargetKinds() {
|
|
139702
|
-
return [alexaTargetKind(
|
|
139698
|
+
return [alexaTargetKind()];
|
|
139703
139699
|
},
|
|
139704
139700
|
async listTargets() {
|
|
139705
139701
|
return [...targets];
|
|
@@ -139709,7 +139705,20 @@ function createAlexaNotificationProvider(ports) {
|
|
|
139709
139705
|
if (found === void 0) throw new Error(`target not found: ${input.targetId}`);
|
|
139710
139706
|
return found;
|
|
139711
139707
|
},
|
|
139712
|
-
async discoverTargets() {
|
|
139708
|
+
async discoverTargets(input) {
|
|
139709
|
+
const named = readString(input.config ?? {}, "brokerId");
|
|
139710
|
+
if (named.length > 0) {
|
|
139711
|
+
const owner = ports.brokers().find((broker) => broker.id === named);
|
|
139712
|
+
return (owner?.devices ?? []).map((device) => ({
|
|
139713
|
+
...discoveredFrom(owner ?? {
|
|
139714
|
+
id: named,
|
|
139715
|
+
name: named,
|
|
139716
|
+
ready: false,
|
|
139717
|
+
devices: []
|
|
139718
|
+
}, device),
|
|
139719
|
+
suggestedName: echoOptionLabel(device)
|
|
139720
|
+
}));
|
|
139721
|
+
}
|
|
139713
139722
|
const taken = new Set(targets.flatMap((row) => {
|
|
139714
139723
|
const owner = brokerFor(row.config);
|
|
139715
139724
|
return owner === void 0 ? [] : [`${owner.id}/${readString(row.config, "echoId")}`];
|
package/i18n/en.json
CHANGED
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
"echoTarget.s_echo.title": "Echo",
|
|
15
15
|
"echoTarget.s_echo.brokerId.label": "Amazon account",
|
|
16
16
|
"echoTarget.s_echo.echoId.label": "Echo",
|
|
17
|
-
"echoTarget.s_echo.echoId.empty": "No Echo found yet. Sign the Amazon account in on Integrations, Alexa.",
|
|
18
17
|
"echoTarget.s_echo.mode.label": "Mode",
|
|
19
18
|
"echoTarget.s_echo.volume.label": "Volume",
|
|
20
19
|
"echoTarget.s_echo.respectDnd.label": "Respect Do Not Disturb",
|
package/i18n/it.json
CHANGED
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
"echoTarget.s_echo.title": "Echo",
|
|
15
15
|
"echoTarget.s_echo.brokerId.label": "Account Amazon",
|
|
16
16
|
"echoTarget.s_echo.echoId.label": "Echo",
|
|
17
|
-
"echoTarget.s_echo.echoId.empty": "Nessun Echo trovato. Accedi con l'account Amazon da Integrazioni, Alexa.",
|
|
18
17
|
"echoTarget.s_echo.mode.label": "Modalità",
|
|
19
18
|
"echoTarget.s_echo.volume.label": "Volume",
|
|
20
19
|
"echoTarget.s_echo.respectDnd.label": "Rispetta Non disturbare",
|
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.171",
|
|
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",
|