@camstack/addon-import-alexa 0.2.171 → 0.2.172

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 CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.172] - 2026-10-31
11
+
12
+ ### Changed
13
+
14
+ - Alexa shows an error instead of 'connected' when polling Amazon keeps failing, with the HTTP status in the log.
15
+ - Alexa: quiet vs announce is now decided per notification (a silent notification is spoken quietly, any other announces); the per-target Mode setting is gone and a stored one is ignored.
16
+
10
17
  ## [0.2.171] - 2026-10-30
11
18
 
12
19
  ### Changed
package/dist/addon.js CHANGED
@@ -137148,7 +137148,21 @@ function isRateLimitError(message) {
137148
137148
  const m = message.toLowerCase();
137149
137149
  return m.includes("rate exceeded") || m.includes("throttl") || m.includes("too many requests") || m.includes("429");
137150
137150
  }
137151
+ /** HTTP statuses that mean Amazon rejected the session (a re-link is needed). */
137152
+ var SESSION_DEAD_STATUSES = new Set([401, 403]);
137153
+ /** The library logs `No body (code=NNN)` on a body-less non-2xx; it is the only place the status shows. */
137154
+ var NO_BODY_CODE = /No body \(code=(\d{3})\)/;
137155
+ /** A failed Amazon call whose HTTP status is known (null when the library did not say). */
137156
+ var AlexaHttpError = class extends Error {
137157
+ statusCode;
137158
+ constructor(message, statusCode) {
137159
+ super(message);
137160
+ this.name = "AlexaHttpError";
137161
+ this.statusCode = statusCode;
137162
+ }
137163
+ };
137151
137164
  var AlexaRemoteClient = class {
137165
+ #lastHttpStatus = null;
137152
137166
  #options;
137153
137167
  #logger;
137154
137168
  #dataDir;
@@ -137168,7 +137182,10 @@ var AlexaRemoteClient = class {
137168
137182
  async connect() {
137169
137183
  const remote = new import_alexa_remote.default();
137170
137184
  this.#remote = remote;
137171
- const initOptions = await this.#buildInitOptions();
137185
+ const initOptions = {
137186
+ ...await this.#buildInitOptions(),
137187
+ logger: (...args) => this.#captureLibraryLine(args)
137188
+ };
137172
137189
  remote.on("cookie", () => {
137173
137190
  this.#persistSession(remote);
137174
137191
  });
@@ -137262,11 +137279,17 @@ var AlexaRemoteClient = class {
137262
137279
  async #withBackoff(op, run) {
137263
137280
  let lastError = null;
137264
137281
  for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) try {
137282
+ this.#lastHttpStatus = null;
137265
137283
  return await run();
137266
137284
  } catch (err) {
137267
137285
  lastError = err;
137268
137286
  const message = errMsg(err);
137269
137287
  if (isAuthError(message)) throw new AlexaAuthError(message);
137288
+ if (message.toLowerCase().includes("no body")) {
137289
+ const status = this.#lastHttpStatus;
137290
+ if (status !== null && SESSION_DEAD_STATUSES.has(status)) throw new AlexaAuthError(`${message} (HTTP ${status})`);
137291
+ throw new AlexaHttpError(message, status);
137292
+ }
137270
137293
  if (!isRateLimitError(message) || attempt === MAX_ATTEMPTS - 1) throw err;
137271
137294
  const delay = this.#backoffDelay(attempt);
137272
137295
  this.#logger?.warn("AlexaRemoteClient: rate-limited — backing off", { meta: {
@@ -137279,6 +137302,10 @@ var AlexaRemoteClient = class {
137279
137302
  }
137280
137303
  throw lastError instanceof Error ? lastError : /* @__PURE__ */ new Error(`AlexaRemoteClient: ${op} failed`);
137281
137304
  }
137305
+ #captureLibraryLine(args) {
137306
+ const match = NO_BODY_CODE.exec(args.map(String).join(" "));
137307
+ if (match?.[1] !== void 0) this.#lastHttpStatus = Number(match[1]);
137308
+ }
137282
137309
  #backoffDelay(attempt) {
137283
137310
  return Math.min(BACKOFF_BASE_MS * 2 ** attempt, BACKOFF_MAX_MS) + Math.floor(Math.random() * BACKOFF_BASE_MS);
137284
137311
  }
@@ -137517,8 +137544,6 @@ var AlexaCommandSink = class {
137517
137544
  };
137518
137545
  /** The single in-process command sink shared across the addon. */
137519
137546
  var alexaCommands = new AlexaCommandSink();
137520
- //#endregion
137521
- //#region src/alexa-integration-manager.ts
137522
137547
  /**
137523
137548
  * Wraps exactly one {@link AlexaClient} (= one Amazon account). Authenticates on
137524
137549
  * `start()`, lists the appliance inventory, then runs a POLL loop (Alexa has no
@@ -137546,6 +137571,7 @@ var AlexaIntegrationManager = class {
137546
137571
  #client = null;
137547
137572
  #pollTimer = null;
137548
137573
  #status = "disconnected";
137574
+ #pollFailures = 0;
137549
137575
  #applianceCount = 0;
137550
137576
  #lastCheckedAt = null;
137551
137577
  #error = null;
@@ -137650,14 +137676,37 @@ var AlexaIntegrationManager = class {
137650
137676
  alexaAccounts.recordStates(this.#id, values);
137651
137677
  this.#lastCheckedAt = Date.now();
137652
137678
  this.#onStatesPolled(this.#id, values);
137679
+ this.#pollFailures = 0;
137680
+ this.#error = null;
137681
+ if (this.#status === "error" || this.#status === "auth-failed") this.#transition("connected");
137653
137682
  } catch (err) {
137654
137683
  this.#error = errMsg(err);
137684
+ this.#pollFailures += 1;
137685
+ const httpStatus = err instanceof AlexaHttpError ? err.statusCode : null;
137655
137686
  this.#logger.warn("AlexaIntegrationManager: poll failed", {
137656
137687
  tags: { brokerId: this.#id },
137657
- meta: { error: errMsg(err) }
137688
+ meta: {
137689
+ error: errMsg(err),
137690
+ consecutiveFailures: this.#pollFailures,
137691
+ httpStatus
137692
+ }
137658
137693
  });
137694
+ if (this.#pollFailures >= 3 && this.#status !== "disconnected") this.#transition(err instanceof AlexaAuthError ? "auth-failed" : "error");
137659
137695
  }
137660
137696
  }
137697
+ #transition(next) {
137698
+ if (this.#status === next) return;
137699
+ const previous = this.#status;
137700
+ this.#status = next;
137701
+ this.#logger.info("AlexaIntegrationManager: status changed", {
137702
+ tags: { brokerId: this.#id },
137703
+ meta: {
137704
+ from: previous,
137705
+ to: next,
137706
+ error: this.#error
137707
+ }
137708
+ });
137709
+ }
137661
137710
  /** Stop the poll loop, disconnect the client (FIRST), null it. */
137662
137711
  async stop() {
137663
137712
  if (this.#pollTimer !== null) {
@@ -139313,9 +139362,16 @@ function readString(config, key) {
139313
139362
  const value = config[key];
139314
139363
  return typeof value === "string" ? value : "";
139315
139364
  }
139316
- /** The rule's value for this send wins; the target's saved config is the fallback. */
139317
- function readMode(config, delivery) {
139318
- return (delivery?.["mode"] ?? config["mode"]) === "announce" ? "announce" : "speak";
139365
+ /** The level id an Echo notification uses for "quiet: no chime, no announcement". */
139366
+ var SILENT_LEVEL_ID = "silent";
139367
+ var SILENT_PRIORITY = 1;
139368
+ /**
139369
+ * Quiet or announce is decided PER NOTIFICATION, never per target: a silent
139370
+ * notification (the kind's silent level, or the lowest priority when no level
139371
+ * is named) is spoken quietly, hours-aware; every other one announces.
139372
+ */
139373
+ function modeFor(notification) {
139374
+ return (notification.level !== void 0 ? notification.level === SILENT_LEVEL_ID : notification.priority <= SILENT_PRIORITY) ? "speak" : "announce";
139319
139375
  }
139320
139376
  function readVolume(config, delivery) {
139321
139377
  const ruled = delivery?.["volume"];
@@ -139326,21 +139382,9 @@ function readVolume(config, delivery) {
139326
139382
  /**
139327
139383
  * The delivery parameters a rule may set for an Echo target (D938). The
139328
139384
  * target's own config holds the default; these override it per notification.
139385
+ * Quiet vs announce is not one of them: it follows the notification's level.
139329
139386
  */
139330
139387
  var DELIVERY_PARAMS = [{
139331
- key: "mode",
139332
- label: "Mode",
139333
- labelKey: "import-alexa:echoTarget.s_echo.mode.label",
139334
- type: "enum",
139335
- options: [{
139336
- value: "speak",
139337
- label: "Speak (quiet hours apply)"
139338
- }, {
139339
- value: "announce",
139340
- label: "Announce (chime, then speech)"
139341
- }],
139342
- default: "speak"
139343
- }, {
139344
139388
  key: "volume",
139345
139389
  label: "Volume",
139346
139390
  labelKey: "import-alexa:echoTarget.s_echo.volume.label",
@@ -139391,20 +139435,6 @@ function configSchema() {
139391
139435
  dependsOn: ["brokerId"]
139392
139436
  }
139393
139437
  }],
139394
- {
139395
- type: "select",
139396
- key: "mode",
139397
- label: "Mode",
139398
- labelKey: "import-alexa:echoTarget.s_echo.mode.label",
139399
- default: "speak",
139400
- options: [{
139401
- value: "speak",
139402
- label: "Speak (quiet hours apply)"
139403
- }, {
139404
- value: "announce",
139405
- label: "Announce (chime, then speech)"
139406
- }]
139407
- },
139408
139438
  {
139409
139439
  type: "number",
139410
139440
  key: "volume",
@@ -139446,9 +139476,16 @@ function alexaTargetKind() {
139446
139476
  actions: 0,
139447
139477
  actionIcons: false,
139448
139478
  levels: [{
139479
+ id: SILENT_LEVEL_ID,
139480
+ label: "Silent",
139481
+ ordinal: SILENT_PRIORITY,
139482
+ flags: { silent: true },
139483
+ description: "Spoken quietly: no chime, quiet hours apply."
139484
+ }, {
139449
139485
  id: "default",
139450
- label: "Default",
139451
- ordinal: 3
139486
+ label: "Announce",
139487
+ ordinal: 3,
139488
+ description: "Announced: chime, then speech."
139452
139489
  }],
139453
139490
  format: ["text"],
139454
139491
  clickUrl: false,
@@ -139465,7 +139502,6 @@ function discoveredFrom(broker, device) {
139465
139502
  config: {
139466
139503
  brokerId: broker.id,
139467
139504
  echoId: device.id,
139468
- mode: "speak",
139469
139505
  volume: 40,
139470
139506
  respectDnd: true,
139471
139507
  family: device.family,
@@ -139478,6 +139514,7 @@ function createAlexaNotificationProvider(ports) {
139478
139514
  let targets = ports.loadTargets();
139479
139515
  let ledger = emptySpeechLedger();
139480
139516
  let deliveries = [];
139517
+ const warnedLegacyMode = /* @__PURE__ */ new Set();
139481
139518
  function record(row) {
139482
139519
  deliveries = [...deliveries, row];
139483
139520
  }
@@ -139619,7 +139656,14 @@ function createAlexaNotificationProvider(ports) {
139619
139656
  renderedAs: speech.renderedAs
139620
139657
  };
139621
139658
  }
139622
- const mode = readMode(target.config, notification.delivery);
139659
+ const mode = modeFor(notification);
139660
+ if (target.config["mode"] !== void 0 && !warnedLegacyMode.has(target.id)) {
139661
+ warnedLegacyMode.add(target.id);
139662
+ logger.warn("alexa target mode is ignored: quiet vs announce follows each notification", {
139663
+ ...tags,
139664
+ meta: { targetId: target.id }
139665
+ });
139666
+ }
139623
139667
  try {
139624
139668
  const outcomes = await ports.speak({
139625
139669
  brokerId: broker.id,
@@ -140049,7 +140093,6 @@ function targetsFrom(rows) {
140049
140093
  config: {
140050
140094
  ...row.brokerId.length > 0 ? { brokerId: row.brokerId } : {},
140051
140095
  echoId: row.echoId,
140052
- mode: row.mode,
140053
140096
  volume: row.volume,
140054
140097
  respectDnd: row.respectDnd
140055
140098
  }
@@ -140062,7 +140105,7 @@ function rowsFrom(targets) {
140062
140105
  enabled: target.enabled,
140063
140106
  brokerId: typeof target.config["brokerId"] === "string" ? target.config["brokerId"] : "",
140064
140107
  echoId: typeof target.config["echoId"] === "string" ? target.config["echoId"] : "",
140065
- mode: target.config["mode"] === "announce" ? "announce" : "speak",
140108
+ mode: "speak",
140066
140109
  volume: typeof target.config["volume"] === "number" ? target.config["volume"] : 40,
140067
140110
  respectDnd: target.config["respectDnd"] !== false
140068
140111
  }));
package/dist/addon.mjs CHANGED
@@ -137146,7 +137146,21 @@ function isRateLimitError(message) {
137146
137146
  const m = message.toLowerCase();
137147
137147
  return m.includes("rate exceeded") || m.includes("throttl") || m.includes("too many requests") || m.includes("429");
137148
137148
  }
137149
+ /** HTTP statuses that mean Amazon rejected the session (a re-link is needed). */
137150
+ var SESSION_DEAD_STATUSES = new Set([401, 403]);
137151
+ /** The library logs `No body (code=NNN)` on a body-less non-2xx; it is the only place the status shows. */
137152
+ var NO_BODY_CODE = /No body \(code=(\d{3})\)/;
137153
+ /** A failed Amazon call whose HTTP status is known (null when the library did not say). */
137154
+ var AlexaHttpError = class extends Error {
137155
+ statusCode;
137156
+ constructor(message, statusCode) {
137157
+ super(message);
137158
+ this.name = "AlexaHttpError";
137159
+ this.statusCode = statusCode;
137160
+ }
137161
+ };
137149
137162
  var AlexaRemoteClient = class {
137163
+ #lastHttpStatus = null;
137150
137164
  #options;
137151
137165
  #logger;
137152
137166
  #dataDir;
@@ -137166,7 +137180,10 @@ var AlexaRemoteClient = class {
137166
137180
  async connect() {
137167
137181
  const remote = new import_alexa_remote.default();
137168
137182
  this.#remote = remote;
137169
- const initOptions = await this.#buildInitOptions();
137183
+ const initOptions = {
137184
+ ...await this.#buildInitOptions(),
137185
+ logger: (...args) => this.#captureLibraryLine(args)
137186
+ };
137170
137187
  remote.on("cookie", () => {
137171
137188
  this.#persistSession(remote);
137172
137189
  });
@@ -137260,11 +137277,17 @@ var AlexaRemoteClient = class {
137260
137277
  async #withBackoff(op, run) {
137261
137278
  let lastError = null;
137262
137279
  for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) try {
137280
+ this.#lastHttpStatus = null;
137263
137281
  return await run();
137264
137282
  } catch (err) {
137265
137283
  lastError = err;
137266
137284
  const message = errMsg(err);
137267
137285
  if (isAuthError(message)) throw new AlexaAuthError(message);
137286
+ if (message.toLowerCase().includes("no body")) {
137287
+ const status = this.#lastHttpStatus;
137288
+ if (status !== null && SESSION_DEAD_STATUSES.has(status)) throw new AlexaAuthError(`${message} (HTTP ${status})`);
137289
+ throw new AlexaHttpError(message, status);
137290
+ }
137268
137291
  if (!isRateLimitError(message) || attempt === MAX_ATTEMPTS - 1) throw err;
137269
137292
  const delay = this.#backoffDelay(attempt);
137270
137293
  this.#logger?.warn("AlexaRemoteClient: rate-limited — backing off", { meta: {
@@ -137277,6 +137300,10 @@ var AlexaRemoteClient = class {
137277
137300
  }
137278
137301
  throw lastError instanceof Error ? lastError : /* @__PURE__ */ new Error(`AlexaRemoteClient: ${op} failed`);
137279
137302
  }
137303
+ #captureLibraryLine(args) {
137304
+ const match = NO_BODY_CODE.exec(args.map(String).join(" "));
137305
+ if (match?.[1] !== void 0) this.#lastHttpStatus = Number(match[1]);
137306
+ }
137280
137307
  #backoffDelay(attempt) {
137281
137308
  return Math.min(BACKOFF_BASE_MS * 2 ** attempt, BACKOFF_MAX_MS) + Math.floor(Math.random() * BACKOFF_BASE_MS);
137282
137309
  }
@@ -137515,8 +137542,6 @@ var AlexaCommandSink = class {
137515
137542
  };
137516
137543
  /** The single in-process command sink shared across the addon. */
137517
137544
  var alexaCommands = new AlexaCommandSink();
137518
- //#endregion
137519
- //#region src/alexa-integration-manager.ts
137520
137545
  /**
137521
137546
  * Wraps exactly one {@link AlexaClient} (= one Amazon account). Authenticates on
137522
137547
  * `start()`, lists the appliance inventory, then runs a POLL loop (Alexa has no
@@ -137544,6 +137569,7 @@ var AlexaIntegrationManager = class {
137544
137569
  #client = null;
137545
137570
  #pollTimer = null;
137546
137571
  #status = "disconnected";
137572
+ #pollFailures = 0;
137547
137573
  #applianceCount = 0;
137548
137574
  #lastCheckedAt = null;
137549
137575
  #error = null;
@@ -137648,14 +137674,37 @@ var AlexaIntegrationManager = class {
137648
137674
  alexaAccounts.recordStates(this.#id, values);
137649
137675
  this.#lastCheckedAt = Date.now();
137650
137676
  this.#onStatesPolled(this.#id, values);
137677
+ this.#pollFailures = 0;
137678
+ this.#error = null;
137679
+ if (this.#status === "error" || this.#status === "auth-failed") this.#transition("connected");
137651
137680
  } catch (err) {
137652
137681
  this.#error = errMsg(err);
137682
+ this.#pollFailures += 1;
137683
+ const httpStatus = err instanceof AlexaHttpError ? err.statusCode : null;
137653
137684
  this.#logger.warn("AlexaIntegrationManager: poll failed", {
137654
137685
  tags: { brokerId: this.#id },
137655
- meta: { error: errMsg(err) }
137686
+ meta: {
137687
+ error: errMsg(err),
137688
+ consecutiveFailures: this.#pollFailures,
137689
+ httpStatus
137690
+ }
137656
137691
  });
137692
+ if (this.#pollFailures >= 3 && this.#status !== "disconnected") this.#transition(err instanceof AlexaAuthError ? "auth-failed" : "error");
137657
137693
  }
137658
137694
  }
137695
+ #transition(next) {
137696
+ if (this.#status === next) return;
137697
+ const previous = this.#status;
137698
+ this.#status = next;
137699
+ this.#logger.info("AlexaIntegrationManager: status changed", {
137700
+ tags: { brokerId: this.#id },
137701
+ meta: {
137702
+ from: previous,
137703
+ to: next,
137704
+ error: this.#error
137705
+ }
137706
+ });
137707
+ }
137659
137708
  /** Stop the poll loop, disconnect the client (FIRST), null it. */
137660
137709
  async stop() {
137661
137710
  if (this.#pollTimer !== null) {
@@ -139311,9 +139360,16 @@ function readString(config, key) {
139311
139360
  const value = config[key];
139312
139361
  return typeof value === "string" ? value : "";
139313
139362
  }
139314
- /** The rule's value for this send wins; the target's saved config is the fallback. */
139315
- function readMode(config, delivery) {
139316
- return (delivery?.["mode"] ?? config["mode"]) === "announce" ? "announce" : "speak";
139363
+ /** The level id an Echo notification uses for "quiet: no chime, no announcement". */
139364
+ var SILENT_LEVEL_ID = "silent";
139365
+ var SILENT_PRIORITY = 1;
139366
+ /**
139367
+ * Quiet or announce is decided PER NOTIFICATION, never per target: a silent
139368
+ * notification (the kind's silent level, or the lowest priority when no level
139369
+ * is named) is spoken quietly, hours-aware; every other one announces.
139370
+ */
139371
+ function modeFor(notification) {
139372
+ return (notification.level !== void 0 ? notification.level === SILENT_LEVEL_ID : notification.priority <= SILENT_PRIORITY) ? "speak" : "announce";
139317
139373
  }
139318
139374
  function readVolume(config, delivery) {
139319
139375
  const ruled = delivery?.["volume"];
@@ -139324,21 +139380,9 @@ function readVolume(config, delivery) {
139324
139380
  /**
139325
139381
  * The delivery parameters a rule may set for an Echo target (D938). The
139326
139382
  * target's own config holds the default; these override it per notification.
139383
+ * Quiet vs announce is not one of them: it follows the notification's level.
139327
139384
  */
139328
139385
  var DELIVERY_PARAMS = [{
139329
- key: "mode",
139330
- label: "Mode",
139331
- labelKey: "import-alexa:echoTarget.s_echo.mode.label",
139332
- type: "enum",
139333
- options: [{
139334
- value: "speak",
139335
- label: "Speak (quiet hours apply)"
139336
- }, {
139337
- value: "announce",
139338
- label: "Announce (chime, then speech)"
139339
- }],
139340
- default: "speak"
139341
- }, {
139342
139386
  key: "volume",
139343
139387
  label: "Volume",
139344
139388
  labelKey: "import-alexa:echoTarget.s_echo.volume.label",
@@ -139389,20 +139433,6 @@ function configSchema() {
139389
139433
  dependsOn: ["brokerId"]
139390
139434
  }
139391
139435
  }],
139392
- {
139393
- type: "select",
139394
- key: "mode",
139395
- label: "Mode",
139396
- labelKey: "import-alexa:echoTarget.s_echo.mode.label",
139397
- default: "speak",
139398
- options: [{
139399
- value: "speak",
139400
- label: "Speak (quiet hours apply)"
139401
- }, {
139402
- value: "announce",
139403
- label: "Announce (chime, then speech)"
139404
- }]
139405
- },
139406
139436
  {
139407
139437
  type: "number",
139408
139438
  key: "volume",
@@ -139444,9 +139474,16 @@ function alexaTargetKind() {
139444
139474
  actions: 0,
139445
139475
  actionIcons: false,
139446
139476
  levels: [{
139477
+ id: SILENT_LEVEL_ID,
139478
+ label: "Silent",
139479
+ ordinal: SILENT_PRIORITY,
139480
+ flags: { silent: true },
139481
+ description: "Spoken quietly: no chime, quiet hours apply."
139482
+ }, {
139447
139483
  id: "default",
139448
- label: "Default",
139449
- ordinal: 3
139484
+ label: "Announce",
139485
+ ordinal: 3,
139486
+ description: "Announced: chime, then speech."
139450
139487
  }],
139451
139488
  format: ["text"],
139452
139489
  clickUrl: false,
@@ -139463,7 +139500,6 @@ function discoveredFrom(broker, device) {
139463
139500
  config: {
139464
139501
  brokerId: broker.id,
139465
139502
  echoId: device.id,
139466
- mode: "speak",
139467
139503
  volume: 40,
139468
139504
  respectDnd: true,
139469
139505
  family: device.family,
@@ -139476,6 +139512,7 @@ function createAlexaNotificationProvider(ports) {
139476
139512
  let targets = ports.loadTargets();
139477
139513
  let ledger = emptySpeechLedger();
139478
139514
  let deliveries = [];
139515
+ const warnedLegacyMode = /* @__PURE__ */ new Set();
139479
139516
  function record(row) {
139480
139517
  deliveries = [...deliveries, row];
139481
139518
  }
@@ -139617,7 +139654,14 @@ function createAlexaNotificationProvider(ports) {
139617
139654
  renderedAs: speech.renderedAs
139618
139655
  };
139619
139656
  }
139620
- const mode = readMode(target.config, notification.delivery);
139657
+ const mode = modeFor(notification);
139658
+ if (target.config["mode"] !== void 0 && !warnedLegacyMode.has(target.id)) {
139659
+ warnedLegacyMode.add(target.id);
139660
+ logger.warn("alexa target mode is ignored: quiet vs announce follows each notification", {
139661
+ ...tags,
139662
+ meta: { targetId: target.id }
139663
+ });
139664
+ }
139621
139665
  try {
139622
139666
  const outcomes = await ports.speak({
139623
139667
  brokerId: broker.id,
@@ -140047,7 +140091,6 @@ function targetsFrom(rows) {
140047
140091
  config: {
140048
140092
  ...row.brokerId.length > 0 ? { brokerId: row.brokerId } : {},
140049
140093
  echoId: row.echoId,
140050
- mode: row.mode,
140051
140094
  volume: row.volume,
140052
140095
  respectDnd: row.respectDnd
140053
140096
  }
@@ -140060,7 +140103,7 @@ function rowsFrom(targets) {
140060
140103
  enabled: target.enabled,
140061
140104
  brokerId: typeof target.config["brokerId"] === "string" ? target.config["brokerId"] : "",
140062
140105
  echoId: typeof target.config["echoId"] === "string" ? target.config["echoId"] : "",
140063
- mode: target.config["mode"] === "announce" ? "announce" : "speak",
140106
+ mode: "speak",
140064
140107
  volume: typeof target.config["volume"] === "number" ? target.config["volume"] : 40,
140065
140108
  respectDnd: target.config["respectDnd"] !== false
140066
140109
  }));
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.mode.label": "Mode",
18
17
  "echoTarget.s_echo.volume.label": "Volume",
19
18
  "echoTarget.s_echo.respectDnd.label": "Respect Do Not Disturb",
20
19
  "globalSettings": {
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.mode.label": "Modalità",
18
17
  "echoTarget.s_echo.volume.label": "Volume",
19
18
  "echoTarget.s_echo.respectDnd.label": "Rispetta Non disturbare",
20
19
  "globalSettings": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-import-alexa",
3
- "version": "0.2.171",
3
+ "version": "0.2.172",
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",