node-red-contrib-sonospollytts
Advanced tools
Comparing version 1.1.15 to 1.1.16
@@ -9,2 +9,7 @@ ![Sample Node](img/logo.png) | ||
<p> | ||
<b>Version 1.1.16</b> March 2020 - In the middle of Coronavirus emergency in Italy<br/> | ||
- NEW: Automatic discovery added. No more IP addresses to remember.<br/> | ||
- NEW: Grouping function. Now you can add more players to the play group.<br/> | ||
</p> | ||
<p> | ||
<b>Version 1.1.15</b> March 2020<br/> | ||
@@ -11,0 +16,0 @@ - NEW: you can now add your own custom Hailing file.<br/> |
{ | ||
"name": "node-red-contrib-sonospollytts", | ||
"version": "1.1.15", | ||
"version": "1.1.16", | ||
"description": "Node-Red TTS with Sonos and Amazon Polly or with your own local mp3 announcement files. This node is specific for security alarm announcement, zone announcement, doorbell, weather annoucement etc.", | ||
@@ -41,3 +41,3 @@ "main": "index.js", | ||
"path": "^0.12.7", | ||
"sonos": ">=1.12.6", | ||
"sonos": "1.12.7", | ||
"util": ">=0.10.1", | ||
@@ -44,0 +44,0 @@ "formidable": "1.2.2" |
@@ -202,6 +202,8 @@ # Node-Red SonosPollyTTS | ||
* Works with node-red in HTTP and in HTTPS mode. | ||
* TTS queues handling. If you send multiple payloads to the node, it'll handle it in his own queue. | ||
* Automatic grouping is supported. You can group all players you want to play your announcements. | ||
* Automatic discovery of your players. | ||
* TTS caching. Amazon AWS charges you if you use Polly for a very high rate of text to speech request. The node caches the TTS, so if you requests the same TTS the second time, the node will take it from the cache instead of asking to the Amazon Polly service. | ||
* Send a simple payload with the text you want to speech out. For example <code>node.send({payload:"Hello there!"});</code>. | ||
<br/><br/><br/><br/> | ||
@@ -217,5 +219,2 @@ | ||
**Sonos IP** <br/> | ||
Insert your sonos's IP (If your Sonos device doesn't allow you to set a fixed IP, you need to reserve an IP using the DHCP Reservation function of your router/firewall's DHCP Server) | ||
**Sonos Volume** <br/> | ||
@@ -238,2 +237,11 @@ set the preferred TTS volume, from "0" to "100" (can be overridden by passing <code>msg.volume="40";</code> to the node) | ||
**Main Sonos Player** <br/> | ||
Select your Sonos primary player. (It's strongly suggested to set a fixed IP for this player; you can reserve an IP using the DHCP Reservation function of your router/firewall's DHCP Server).<br/> | ||
Starting from Version 1.1.16, 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. | ||
**Additional Players** <br/> | ||
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. | ||
## INPUT MESSAGES TO THE NODE <br/> | ||
@@ -240,0 +248,0 @@ |
@@ -480,2 +480,3 @@ module.exports = function (RED) { | ||
RED.nodes.createNode(this, config); | ||
@@ -496,3 +497,3 @@ if (this.credentials) { | ||
} | ||
//RED.nodes.registerType('sonospollytts-config', PollyConfigNode); | ||
RED.nodes.registerType('sonospollytts-config', PollyConfigNode, { | ||
@@ -508,5 +509,5 @@ credentials: { | ||
}); | ||
// Node Register | ||
@@ -521,3 +522,2 @@ function PollyNode(config) { | ||
node.iVoice; | ||
node.sNoderedURL; // Stores the node.red URL and port | ||
node.oTimer; | ||
@@ -529,2 +529,3 @@ node.oTimerSonosConnectionCheck; | ||
node.sSonosIPAddress = ""; | ||
node.sSonosCoordinatorGroupName = ""; | ||
node.sonoshailing = "0"; // Hailing file | ||
@@ -537,3 +538,36 @@ node.msg = {}; // 08/05/2019 Node message | ||
node.userDir = RED.settings.userDir + "/sonospollyttsstorage"; // 09/03/2020 Storage of sonospollytts (otherwise, at each upgrade to a newer version, the node path is wiped out and recreated, loosing all custom files) | ||
node.oAdditionalSonosPlayers = []; // 20/03/2020 Contains other players to be grouped | ||
node.rules = config.rules || [{}]; | ||
// 11/11/2019 NEW in V 1.1.0, changed webserver behaviour. Redirect pre V. 1.1.0 1880 ports to the nde default 1980 | ||
if (config.noderedport.trim() == "1880") { | ||
RED.log.warn("SonosPollyTTS: The webserver port ist 1880. Please change it to another port, not to conflict with default node-red 1880 port. I've changed this temporarly for you to 1980"); | ||
config.noderedport = "1980"; | ||
} | ||
node.sNoderedURL = "http://" + config.noderedipaddress.trim() + ":" + config.noderedport.trim(); // 11/11/2019 New Endpoint to overcome https problem. | ||
RED.log.info('SonosPollyTTS: Node-Red node.js Endpoint will be created here: ' + node.sNoderedURL + "/tts"); | ||
// 20/03/2020 in the middle of coronavirus, get the sonos groups | ||
RED.httpAdmin.get("/sonosgetAllGroups", RED.auth.needsPermission('PollyNode.read'), function (req, res) { | ||
var jListGroups = []; | ||
try { | ||
const discovery = new sonos.AsyncDeviceDiscovery() | ||
discovery.discover().then((device, model) => { | ||
RED.log.warn('Found one sonos device ' + device.host + ' getting all groups') | ||
return device.getAllGroups().then((groups) => { | ||
//RED.log.warn('Groups ' + JSON.stringify(groups, null, 2)) | ||
for (let index = 0; index < groups.length; index++) { | ||
const element = groups[index]; | ||
jListGroups.push({ name: element.Name, host: element.host }) | ||
} | ||
res.json(jListGroups) | ||
//return groups[0].CoordinatorDevice().togglePlayback() | ||
}) | ||
}).catch(e => { | ||
RED.log.warn(' Error in discovery ' + e) | ||
}) | ||
} catch (error) { } | ||
}); | ||
// 09/03/2020 Get list of filenames in hailing folder | ||
@@ -580,4 +614,2 @@ RED.httpAdmin.get("/getHailingFilesList", RED.auth.needsPermission('PollyNode.read'), function (req, res) { | ||
// 20/11/2019 Used to call the status update | ||
@@ -641,9 +673,9 @@ node.setNodeStatus = ({ fill, shape, text }) => { | ||
// Set ssml | ||
this.ssml = config.ssml; | ||
node.ssml = config.ssml; | ||
this.Pollyconfig = RED.nodes.getNode(config.config); | ||
node.Pollyconfig = RED.nodes.getNode(config.config); | ||
node.sSonosIPAddress = config.sonosipaddress.trim(); | ||
if (!this.Pollyconfig) { | ||
if (!node.Pollyconfig) { | ||
RED.log.error('Missing Polly config'); | ||
@@ -656,9 +688,2 @@ return; | ||
// 11/11/2019 NEW in V 1.1.0, changed webserver behaviour. Redirect pre V. 1.1.0 1880 ports to the nde default 1980 | ||
if (config.noderedport.trim() == "1880") { | ||
RED.log.warn("SonosPollyTTS: The webserver port ist 1880. Please change it to another port, not to conflict with default node-red 1880 port. I've changed this temporarly for you to 1980"); | ||
config.noderedport = "1980"; | ||
} | ||
node.sNoderedURL = "http://" + config.noderedipaddress.trim() + ":" + config.noderedport.trim(); // 11/11/2019 New Endpoint to overcome https problem. | ||
RED.log.info('SonosPollyTTS: Node-Red node.js Endpoint will be created here: ' + node.sNoderedURL + "/tts"); | ||
@@ -668,2 +693,13 @@ // Create sonos client | ||
// 20/03/2020 Set the coorinator's zone name | ||
node.SonosClient.getName().then(info => { | ||
node.sSonosCoordinatorGroupName = info; | ||
RED.log.info("SonosPollyTTS: ZONE COORDINATOR " + info); | ||
}); | ||
// Fill the node.oAdditionalSonosPlayers with all sonos object in the rules | ||
for (let index = 0; index < node.rules.length; index++) { | ||
const element = node.rules[index]; | ||
node.oAdditionalSonosPlayers.push(new sonos.Sonos(element.host)); | ||
RED.log.info("SonosPollyTTS: FOUND ADDITIONAL PLAYER " + element.host); | ||
} | ||
@@ -702,3 +738,33 @@ // Get default sonos volume | ||
this.on('input', function (msg) { | ||
// 20/03=2020 QUEUINPLAYERS | ||
// ###################################################### | ||
// 20/03/2020 Join Coordinator queue | ||
node.groupSpeakers = () => { | ||
// 30/03/2020 in the middle of coronavirus emergency. Group Speakers | ||
// You don't have to worry about who is the coordinator. | ||
for (let index = 0; index < node.oAdditionalSonosPlayers.length; index++) { | ||
const element = node.oAdditionalSonosPlayers[index]; | ||
element.joinGroup(node.sSonosCoordinatorGroupName).then(success => { | ||
//RED.log.warn('SonosPollyTTS: Joining ' + deviceToJoin + " with " + (success ? 'Success' : 'Failure')) | ||
}).catch(err => { | ||
RED.log.warn('SonosPollyTTS: Error joining device ' + err) | ||
}); | ||
} | ||
} | ||
// 20/03/2020 Ungroup Coordinator queue | ||
node.ungroupSpeakers = () => { | ||
for (let index = 0; index < node.oAdditionalSonosPlayers.length; index++) { | ||
const element = node.oAdditionalSonosPlayers[index]; | ||
element.leaveGroup().then(success => { | ||
//RED.log.warn('Leaving the group is a ' + (success ? 'Success' : 'Failure')) | ||
}).catch(err => { | ||
RED.log.warn('SonosPollyTTS: Error joining device ' + err) | ||
}) | ||
} | ||
} | ||
// ###################################################### | ||
node.on('input', function (msg) { | ||
// 12/06/2018 Controllo se il payload è un'impostazione del volume | ||
@@ -732,2 +798,3 @@ if (msg.hasOwnProperty("volume")) { | ||
node.msg.completed = false; | ||
node.groupSpeakers(); // 20/03/2020 Group Speakers toghether | ||
node.send(node.msg); | ||
@@ -746,4 +813,10 @@ } | ||
this.on('close', function () { | ||
node.on('close', function (done) { | ||
clearTimeout(node.oTimer); | ||
node.SonosClient.stop().then(() => { | ||
node.ungroupSpeakers(); | ||
}); | ||
node.msg.completed = true; | ||
node.send(node.msg); | ||
node.setNodeStatus({ fill: "green", shape: "ring", text: "" + node.sSonosPlayState }); | ||
// 11/11/2019 Close the Webserver | ||
@@ -755,2 +828,6 @@ try { | ||
} | ||
setTimeout(function () { | ||
// Wait some time to allow time to do promises. | ||
done(); | ||
}, 3000); | ||
}); | ||
@@ -911,3 +988,2 @@ | ||
function HandleQueue2(node) { | ||
//RED.log.error('SonosPollyTTS: HandleQueue2 - DEBUG ' +node.sSonosIPAddress + " " + node.sSonosPlayState + " Track:" + node.sSonosTrackTitle); | ||
@@ -983,2 +1059,3 @@ // Play next msg | ||
node.msg.completed = true; | ||
node.ungroupSpeakers(); // 20/03/2020 Ungroup Speakers | ||
node.send(node.msg); | ||
@@ -1047,3 +1124,2 @@ node.setNodeStatus({ fill: "green", shape: "ring", text: "" + node.sSonosPlayState }); | ||
synthesizeSpeech([polly, params]).then(data => { return [filename, data.AudioStream]; }).then(cacheSpeech).then(function () { | ||
//RED.log.info("synthesizeSpeech filename " + filename); | ||
// Play | ||
@@ -1133,6 +1209,4 @@ PlaySonos(filename, node); | ||
} | ||
RED.log.info('SonosPollyTTS: PlaySonos - URL: ' + sUrl); | ||
node.SonosClient.setVolume(node.sSonosVolume).then(success => { | ||
node.SonosClient.setAVTransportURI(sUrl).then(playing => { | ||
@@ -1139,0 +1213,0 @@ |
Sorry, the diff of this file is not supported yet
644361
1180
424
+ Addedaxios@0.19.2(transitive)
+ Addedfollow-redirects@1.5.10(transitive)
+ Addedsonos@1.12.7(transitive)
- Removedaxios@0.21.4(transitive)
- Removedfollow-redirects@1.15.9(transitive)
- Removedsonos@1.14.1(transitive)
Updatedsonos@1.12.7