node-red-contrib-tts-ultimate 1.0.43 → 1.0.44

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
@@ -2,6 +2,11 @@
2
2
 
3
3
  [![Donate via PayPal](https://img.shields.io/badge/Donate-PayPal-blue.svg?style=flat-square)](https://www.paypal.me/techtoday)
4
4
 
5
+ <p>
6
+ <b>Version 1.0.44</b> April 2022<br/>
7
+ - NEW: you can now adjust the additional player's volume, adapting it to the main sonos player volume. This is useful in case you've some recessed speakers, "speaking" too low or some too near speakers, "speaking" too high. You can adapt the volume in the config window or dinamically via msg input.<br/>
8
+ - Updated the README.<br/>
9
+ </p>
5
10
  <p>
6
11
  <b>Version 1.0.43</b> March 2022<br/>
7
12
  - Simplified the configuration by auto discover some IP.<br/>
package/README.md CHANGED
@@ -169,7 +169,8 @@ Select your Sonos primary player. (It's strongly suggested to set a fixed IP for
169
169
  It's possibile to group players, so your announcement can be played on all selected players. For this to happen, you need to select your primary coordinator player. All other players will be then controlled by this coordinator.
170
170
 
171
171
  **Additional Players** <br/>
172
- Here you can add all additional players that will be grouped toghether to the *Main Sonos Player* coordinator group. You can add a player using the "ADD" button, below the list.
172
+ Here you can add all additional players that will be grouped toghether to the *Main Sonos Player* coordinator group. You can add a player using the "ADD" button, below the list.<br/>
173
+ For each additional player, you can adjust their volume, based on the **Main Sonos Player** volume -+100.
173
174
 
174
175
 
175
176
  ## INPUT MESSAGES TO THE NODE <br/>
@@ -287,7 +288,9 @@ The setting is retained until the node receives another msg.setConfig or until n
287
288
 
288
289
  > **property setPlayerGroupArray**<br/>
289
290
  Sets the array of players beloging to the group, if any.<br/>
290
- If you have only one additional player, you need to ever put it into an array. See below.
291
+ You can also specify the volume variation from the main volume player, to adapt the additional player's perceived volume to the main sonos player volume.<br/>
292
+ For example, if you have a speaker mounted in celiling, having less perceived volume, you can "push" the volume up, to match the whole perceived volume. Just add **#** after the IP and a number from -100 to 100 to subtract or add volume ***compared to the main sonos volume***. For example, if the sonos main player volume is 40, you can push this celing speaker's volume to further 10, so it'll have the real volume of 50. See below, the example.<br/>
293
+ Note: Even if you have only one additional player, you need to put it into an array.
291
294
 
292
295
  ```js
293
296
  // Set main player IP
@@ -300,14 +303,15 @@ return msg;
300
303
  ```
301
304
 
302
305
  ```js
303
- // Set player IP and additional players
306
+ // Set player IP and additional players with their optional adapted volume, relative to the main sonos player volume.
307
+ // You can specify the aditional player's volume adaptation
304
308
  // The setting is retained until the node receives another msg.setConfig or until node-red is restarted.
305
309
  var config= {
306
310
  setMainPlayerIP:"192.168.1.109",
307
311
  setPlayerGroupArray:[
308
- "192.168.1.110",
309
- "192.168.1.111",
310
- "192.168.1.112"
312
+ "192.168.1.110", // This additional player will use the same volume as the main sonos player.
313
+ "192.168.1.111#-10", // This additional player will use the main sonos player's volume, minus 10.
314
+ "192.168.1.112#20" // This additional player will use the main sonos player's volume, plus 20.
311
315
  ]
312
316
  };
313
317
  msg.setConfig = config;
@@ -315,7 +319,7 @@ return msg;
315
319
  ```
316
320
 
317
321
  ```js
318
- // If you have only one additional player
322
+ // If you have only one additional player, without setting their adjusted volume.
319
323
  // The setting is retained until the node receives another msg.setConfig or until node-red is restarted.
320
324
  var config= {
321
325
  setMainPlayerIP:"192.168.1.109",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-tts-ultimate",
3
- "version": "1.0.43",
3
+ "version": "1.0.44",
4
4
  "description": "Transforms the text in speech and hear it using Sonos player or generate an audio file to be used with third parties nodes. Works with voices from Amazon, Google (without credentials as well), Microsoft TTS Azure, or your own voice. You can also only create a TTS file to be read by third party nodes. Update of the popular SonosPollyTTS node.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -402,16 +402,32 @@
402
402
  //#region ADDITIONAL PLAYERS
403
403
  // 20/03/2020 ADDITIONAL PLAYERS
404
404
  // ##########################################################
405
- var previousValueType = { value: "prev", label: this._("switch.previous"), hasValue: false };
405
+ //var previousValueType = { value: "prev", label: this._("switch.previous"), hasValue: false };
406
+
407
+ // Add Selectbox with the volume for the additional players
408
+ function addAdditionalPlayerVolumeUI(row, _currentVolume = 0) {
409
+ let oAdjustVolume = $('<select/>', { class: "rowRulePlayerHostAdjustVolume", type: "text", style: "width:200px; margin-left: 5px; text-align: left;" }).appendTo(row);
410
+ for (let index = -100; index < 100; index += 5) {
411
+ let sTesto = "";
412
+ if (index === 0) sTesto = "Same volume as Main Sonos Player";
413
+ if (index < 0) sTesto = "Decrease volume by " + Math.abs(index) ;
414
+ if (index > 0) sTesto = "Increase volume by " + index;
415
+ oAdjustVolume.append($("<option></option>")
416
+ .attr("value", index)
417
+ .text(sTesto)
418
+ )
419
+ }
420
+ oAdjustVolume.val(_currentVolume);
421
+ }
406
422
  function resizeRule(rule) { }
423
+
407
424
  $("#node-input-rule-container").css('min-height', '150px').css('min-width', '450px').editableList({
408
425
  addItem: function (container, i, opt) { // row, index, data
409
- // opt.r is: { topic: rowRuleTopic, devicename: rowRuleDeviceName, dpt:rowRuleDPT, send: rowRuleSend}
410
426
 
411
427
  if (!opt.hasOwnProperty('r')) {
412
428
  opt.r = {};
413
429
  }
414
- var rule = opt.r;
430
+ let rule = opt.r;
415
431
  if (!opt.hasOwnProperty('i')) {
416
432
  opt._i = Math.floor((0x99999 - 0x10000) * Math.random()).toString();
417
433
  }
@@ -422,8 +438,7 @@
422
438
 
423
439
 
424
440
  var row = $('<div class="form-row"/>').appendTo(container);
425
- var oPlayer = $('<label>Discovering.... wait...</label>', { class: "rowRulePlayerHost", type: "text", style: "width:300px; margin-left: 5px; text-align: left;" }).appendTo(row);
426
-
441
+ var oPlayer = $('<label>Discovering.... wait...</label>', { class: "rowRulePlayerHost", type: "text", style: "width:200px; margin-left: 5px; text-align: left;" }).appendTo(row);
427
442
  oPlayer.on("change", function () {
428
443
  resizeRule(container);
429
444
  });
@@ -432,16 +447,18 @@
432
447
  if (typeof data === "string" && data == "ERRORDISCOVERY") { // 10/04/2020 if error in discovery, fallback to manual IP input
433
448
  // Transform the dropdown to a simple input
434
449
  oPlayer.remove();
435
- oPlayer = $('<input/>', { class: "rowRulePlayerHost", type: "text", style: "width:300px; margin-left: 5px; text-align: left;" }).appendTo(row);
450
+ oPlayer = $('<input/>', { class: "rowRulePlayerHost", type: "text", style: "width:200px; margin-left: 5px; text-align: left;" }).appendTo(row);
451
+ addAdditionalPlayerVolumeUI(row, rule.hostVolumeAdjust);
436
452
  } else {
437
453
  oPlayer.remove();
438
- oPlayer = $('<select/>', { class: "rowRulePlayerHost", type: "text", style: "width:300px; margin-left: 5px; text-align: left;" }).appendTo(row);
454
+ oPlayer = $('<select/>', { class: "rowRulePlayerHost", type: "text", style: "width:200px; margin-left: 5px; text-align: left;" }).appendTo(row);
439
455
  data.sort().forEach(oGroup => {
440
456
  oPlayer.append($("<option></option>")
441
457
  .attr("value", oGroup.host)
442
458
  .text(oGroup.name + " (" + oGroup.host + ")")
443
459
  )
444
460
  });
461
+ addAdditionalPlayerVolumeUI(row, rule.hostVolumeAdjust);
445
462
  }
446
463
  oPlayer.val(rule.host);
447
464
  });
@@ -460,7 +477,7 @@
460
477
 
461
478
  // 20/03/2020 For each rule, create a row
462
479
  for (var i = 0; i < this.rules.length; i++) {
463
- var rule = this.rules[i];
480
+ let rule = this.rules[i];
464
481
  $("#node-input-rule-container").editableList('addItem', { r: rule, i: i });
465
482
  }
466
483
  // ##########################################################
@@ -469,14 +486,14 @@
469
486
  node.refreshHailingList();
470
487
 
471
488
  }, oneditsave: function () {
472
- var node = this;
473
-
474
- var rules = $("#node-input-rule-container").editableList('items');
489
+ let node = this;
490
+ let rules = $("#node-input-rule-container").editableList('items');
475
491
  node.rules = [];
476
492
  rules.each(function (i) {
477
- var rule = $(this);
478
- var rowRulePlayerHost = rule.find(".rowRulePlayerHost").val();
479
- node.rules.push({ host: rowRulePlayerHost });
493
+ let rule = $(this);
494
+ let rowRulePlayerHost = rule.find(".rowRulePlayerHost").val();
495
+ let rowRulePlayerHostAdjustVolume = rule.find(".rowRulePlayerHostAdjustVolume").val();
496
+ node.rules.push({ host: rowRulePlayerHost, hostVolumeAdjust: rowRulePlayerHostAdjustVolume });
480
497
  });
481
498
  this.propertyType = $("#node-input-property").typedInput('type');
482
499
  },
@@ -283,7 +283,7 @@ module.exports = function (RED) {
283
283
  }
284
284
  // 30/03/2020 in the middle of coronavirus emergency. Group Speakers
285
285
  for (let index = 0; index < node.oAdditionalSonosPlayers.length; index++) {
286
- const element = node.oAdditionalSonosPlayers[index];
286
+ const element = node.oAdditionalSonosPlayers[index].oPlayer;
287
287
  try {
288
288
  await element.joinGroup(node.sonosCoordinatorGroupName);
289
289
  } catch (error) {
@@ -322,7 +322,7 @@ module.exports = function (RED) {
322
322
  }
323
323
 
324
324
  for (let index = 0; index < node.oAdditionalSonosPlayers.length; index++) {
325
- const element = node.oAdditionalSonosPlayers[index];
325
+ const element = node.oAdditionalSonosPlayers[index].oPlayer;
326
326
  try {
327
327
  await element.leaveGroup();
328
328
  } catch (error) {
@@ -401,9 +401,10 @@ module.exports = function (RED) {
401
401
  });
402
402
  // Fill the node.oAdditionalSonosPlayers with all sonos object in the rules
403
403
  for (let index = 0; index < node.rules.length; index++) {
404
- const element = node.rules[index];
405
- node.oAdditionalSonosPlayers.push(new sonos.Sonos(element.host));
406
- RED.log.info("ttsultimate: FOUND ADDITIONAL PLAYER " + element.host);
404
+ const element = node.rules[index]; // Rule row is {host:"192.168.1.12,hostVolumeAdjust:0}
405
+ // 12/04/2022 Create an object containing the addidtional player and the adapted volume
406
+ node.oAdditionalSonosPlayers.push({ oPlayer: new sonos.Sonos(element.host), hostVolumeAdjust: Number(element.hostVolumeAdjust) });
407
+ RED.log.info("ttsultimate: FOUND ADDITIONAL PLAYER " + element.host + " Adjusted volume: " + element.hostVolumeAdjust);
407
408
  }
408
409
 
409
410
 
@@ -655,21 +656,26 @@ module.exports = function (RED) {
655
656
 
656
657
  // Set Volume
657
658
  try {
658
- let volTemp = 0
659
+ let volTemp = 0;
659
660
  if (node.currentMSGbeingSpoken.hasOwnProperty("volume")) {
660
- volTemp = node.currentMSGbeingSpoken.volume;
661
+ volTemp = Number(node.currentMSGbeingSpoken.volume);
661
662
  } else {
662
- volTemp = node.sSonosVolume;
663
+ volTemp = Number(node.sSonosVolume);
663
664
  }
664
665
  await SETVOLUMESync(volTemp);
665
666
  if (node.unmuteIfMuted) await SETMutedSync(false); // 21/10/2021 Unmute
666
667
 
667
668
  if (node.oAdditionalSonosPlayers.length > 0) {
668
- // 05/07/2021 set the volume of additional coordinatores
669
+ // 05/07/2021 set the volume of additional coordinators
669
670
  for (let index = 0; index < node.oAdditionalSonosPlayers.length; index++) {
670
- const element = node.oAdditionalSonosPlayers[index];
671
+ const element = node.oAdditionalSonosPlayers[index].oPlayer;
672
+ //node.oAdditionalSonosPlayers.push({ oPlayer: new sonos.Sonos(element.host), hostVolumeAdjust: element.hostVolumeAdjust });
671
673
  try {
672
- await element.setVolume(volTemp);
674
+ // 12/04/20222 Set the adjusted volume, based on the main player volume + the adjusted volume in %
675
+ let iAdjustedVol = Number(volTemp) + Number((node.oAdditionalSonosPlayers[index].hostVolumeAdjust || 0));
676
+ if (iAdjustedVol < 0) iAdjustedVol = 0;
677
+ if (iAdjustedVol > 100) iAdjustedVol = 100;
678
+ await element.setVolume(iAdjustedVol);
673
679
  if (node.unmuteIfMuted) await element.setMuted(false); // 21/10/2021 Unmute
674
680
  } catch (error) {
675
681
  RED.log.error("ttsultimate: Handlequeue: Unable to set the volume on additional player " + error.message);
@@ -843,9 +849,18 @@ module.exports = function (RED) {
843
849
  // Fill the node.oAdditionalSonosPlayers with all sonos IPs in the setPlayerGroupArray
844
850
  node.oAdditionalSonosPlayers = [];
845
851
  for (let index = 0; index < msg.setConfig.setPlayerGroupArray.length; index++) {
846
- const element = msg.setConfig.setPlayerGroupArray[index];
847
- node.oAdditionalSonosPlayers.push(new sonos.Sonos(element));
848
- RED.log.info("ttsultimate: new group player set by msg: " + element);
852
+ const sRow = msg.setConfig.setPlayerGroupArray[index];
853
+ let host = "";
854
+ let hostVolumeAdjust = 0;
855
+ if (sRow.includes("#")) {
856
+ host = sRow.split("#")[0];
857
+ hostVolumeAdjust = sRow.split("#")[1];
858
+ } else {
859
+ host = sRow;
860
+ }
861
+ //node.oAdditionalSonosPlayers.push({ oPlayer: new sonos.Sonos(element.host), hostVolumeAdjust: element.hostVolumeAdjust });
862
+ node.oAdditionalSonosPlayers.push({ oPlayer: new sonos.Sonos(host), hostVolumeAdjust: Number(hostVolumeAdjust) });
863
+ RED.log.info("ttsultimate: new group player set by msg: " + host + " adjusted volume: " + Number(hostVolumeAdjust));
849
864
  }
850
865
  };
851
866
  };