Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

node-red-contrib-sonospollytts

Package Overview
Dependencies
Maintainers
1
Versions
87
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-red-contrib-sonospollytts - npm Package Compare versions

Comparing version 1.1.37 to 1.1.38

7

CHANGELOG.md

@@ -6,6 +6,11 @@ ![Sample Node](img/logo.png)

<p>
<b>Version 1.1.37</b> November 2020<br/>
<b>Version 1.1.38</b> December 2020<br/>
- NEW: resume music queue after TTS speech. Once finished playing the voice speak, the music queue restart at the exact position, at the exact track time.<br/>
- BUGFIX: fixing some issue when inbound msg to the node are very frequent. Should resume the music correctly.<br/>
</p>
<p>
<b>Version 1.1.37</b> December 2020<br/>
- NEW: resume music queue after TTS speech. Once finished playing the voice speak, the music queue restart at the exact position, at the exact track time.<br/>
</p>
<p>
<b>Version 1.1.36</b> November 2020<br/>

@@ -12,0 +17,0 @@ - Whenever node-red is restarted or you make a deploy while Sonos is playing music, the node won't stop Sonos players anymore.<br/>

2

package.json
{
"name": "node-red-contrib-sonospollytts",
"version": "1.1.37",
"version": "1.1.38",
"description": "Node-Red TTS with Sonos and Amazon Polly or with your own local mp3 announcement files. Transforms the text in speech and hear it using Sonos player. Can work OFFLINE as well! This node is specific for security alarm announcement, doorbell, weather annoucement etc.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -0,1 +1,4 @@

const { clear } = require('console');
const { clearInterval } = require('timers');
module.exports = function (RED) {

@@ -78,3 +81,9 @@ 'use strict';

node.sNoderedURL = "";
node.oTimerGetCurrentQueue = null; // 04/12/2020
node.oTimerResumeCurrentQueue = null; // 04/12/2020
node.currMusicTrack = null; // 04/12/2020 Current position of the currently playing music in the queue
node.busyGettingMusicQueue = false; // 04/12/2020 Signal busy getting usic queue
node.busyResumingMusicQueue = false; // 04/12/2020 Signal busy in resuming music queue
node.tempMSGStorage = []; // 04/12/2020 Temporary stores the flow messages
if (typeof node.server !== "undefined" && node.server !== null) {

@@ -670,4 +679,13 @@ node.sNoderedURL = node.server.sNoderedURL || "";

// Start the TTS queue timer
node.oTimer = setTimeout(function () { HandleQueue(); }, 5000);
node.oTimer = setTimeout(function () { HandleQueue(); }, 2000);
// 04/12/2020 Start timer that read the music queue
node.oTimerGetCurrentQueue = setInterval(function () {
getMusicQueue().then(resolve => {
}).catch(err => {
});
}, 5000);
// 27/11/2019 Start the connection healty check

@@ -735,3 +753,2 @@ node.oTimerSonosConnectionCheck = setTimeout(function () { node.CheckSonosConnection(); }, 5000);

node.curTrack;
node.on('input', function (msg) {

@@ -744,43 +761,16 @@

// 04/12/2020 Handle music queue
//#region "HANDLE MUSIC QUEUE"
node.SonosClient.getCurrentState().then(state => {
//console.log("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" + node.msg.completed)
// A music queue is playing and no TTS is speaking?
if (state.toString().toLowerCase() === "playing" && node.msg.completed === true) {
//console.log("AAaaaaAAaaaaAAaaaaAAaaaaAAaaaaAAaaaaAAaaaa")
// Get current track
node.SonosClient.currentTrack().then(track => {
//console.log("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB")
node.currMusicTrack = track;// .queuePosition || 1; // Get the current track in the queue.
node.SonosClient.getVolume().then(volume => {
//console.log("CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC")
node.currMusicTrack.currentVolume = volume; // Get the current volume
console.log("VOLUMA " + volume);
continueProcessingInputMSG();
}).catch(err => {
node.currMusicTrack = null;
console.log('SonospollyTTS: getVolume Error occurred %j', err);
continueProcessingInputMSG();
})
}).catch(err => {
node.currMusicTrack = null;
console.log('SonospollyTTS: Error currentTrackoccurred %j', err);
continueProcessingInputMSG();
})
} else {
node.currMusicTrack = null;
continueProcessingInputMSG();
};
}).catch(err => {
node.currMusicTrack = null;
console.log('SonospollyTTS: getCurrentState: Error occurred %j', err);
continueProcessingInputMSG();
})
//#endregion
// 04/12/2020
// If the queue management is still in process (starting or stopping the queue), store the input messages and send it upon end managing the queue
if (node.busyGettingMusicQueue || node.busyResumingMusicQueue) {
node.tempMSGStorage.push(msg.payload.toString());
if (node.busyGettingMusicQueue) node.setNodeStatus({ fill: 'grey', shape: 'dot', text: 'Busy in reading music queue...retry' });
if (node.busyResumingMusicQueue) node.setNodeStatus({ fill: 'grey', shape: 'dot', text: 'Busy in resuming music queue...retry' });
return;
}
// Clear the read music queue timer
if (node.oTimerGetCurrentQueue !== null) clearTimeout(node.oTimerGetCurrentQueue);
node.busyGettingMusicQueue = false; // Resetting the glaf indicating busy in read music queue
// Continue processing the input command
function continueProcessingInputMSG() {
// 12/06/2018 Controllo se il payload è un'impostazione del volume
// 12/06/2018 Controllo se il payload è un'impostazione del volume
if (msg.hasOwnProperty("volume")) {

@@ -803,16 +793,2 @@ node.sSonosVolume = msg.volume;

node.sonoshailing = config.sonoshailing;
// Backwart compatibiliyy, to remove with the next Version
// ################
if (node.sonoshailing == "0") {
// Remove the hailing.mp3 default file
RED.log.info('SonosPollyTTS: Hailing disabled');
} else if (node.sonoshailing == "1") {
node.sonoshailing = "Hailing_Hailing.mp3";
} else if (node.sonoshailing == "2") {
node.sonoshailing = "Hailing_ComputerCall.mp3";
} else if (node.sonoshailing == "3") {
node.sonoshailing = "Hailing_VintageSpace.mp3";
}
// ################
}

@@ -842,4 +818,2 @@

node.setNodeStatus({ fill: 'yellow', shape: 'dot', text: 'Queued ' + msg.payload });
}

@@ -866,2 +840,117 @@ });

// 04/12/2020
function getMusicQueue() {
return new Promise(function (resolve, reject) {
// 04/12/2020 Get music queue
if (!node.msg.completed) {
resolve(true);
return; // Is playing TTS, exit.
}
node.busyGettingMusicQueue = true; // Avoid enterint here while the promises below are not resolved
node.SonosClient.getCurrentState().then(state => {
// A music queue is playing and no TTS is speaking?
if (state.toString().toLowerCase() === "playing") {
if (!node.msg.completed) {
// Is playing TTS, exit.
node.currMusicTrack = null;
node.busyGettingMusicQueue = false; // Avoid enterint here while the promises below are not resolved
reject(true);
return;
}
// Get current track
node.SonosClient.currentTrack().then(track => {
if (!node.msg.completed) {
// Is playing TTS, exit.
node.currMusicTrack = null;
node.busyGettingMusicQueue = false; // Avoid enterint here while the promises below are not resolved
reject(true);
return;
}
node.currMusicTrack = track;// .queuePosition || 1; // Get the current track in the queue.
node.SonosClient.getVolume().then(volume => {
if (!node.msg.completed) {
// Is playing TTS, exit.
node.currMusicTrack = null;
node.busyGettingMusicQueue = false; // Avoid enterint here while the promises below are not resolved
reject(true);
return;
}
node.currMusicTrack.currentVolume = volume; // Get the current volume
node.busyGettingMusicQueue = false; // finish handling music queue
//console.log("TRACK MUSIC: " + JSON.stringify(node.currMusicTrack));
node.setNodeStatus({ fill: 'grey', shape: 'dot', text: 'Playing music queue pos: ' + node.currMusicTrack.queuePosition });
resolve(true);
}).catch(err => {
node.currMusicTrack = null;
node.busyGettingMusicQueue = false; // finish handling music queue
//console.log('SonospollyTTS: getVolume Error occurred %j', err);
reject(err);
})
}).catch(err => {
node.currMusicTrack = null;
node.busyGettingMusicQueue = false; // finish handling music queue
reject(err);
//console.log('SonospollyTTS: Error currentTrackoccurred %j', err);
})
} else {
node.currMusicTrack = null; // Avoid play last queue at end of the tts speech
node.busyGettingMusicQueue = false; // finish handling music queue
resolve(true);
};
}).catch(err => {
//console.log('SonospollyTTS: getCurrentState: Error occurred %j', err);
node.busyGettingMusicQueue = false; // finish handling music queue
reject(err);
})
});
}
// 04/12/2020
function resumeMusicQueue() {
return new Promise(function (resolve, reject) {
if (node.currMusicTrack !== null) {
node.SonosClient.selectQueue().then(success => {
node.SonosClient.selectTrack(node.currMusicTrack.queuePosition).then(success => {
node.SonosClient.seek(node.currMusicTrack.position).then(success => {
node.SonosClient.setVolume(node.currMusicTrack.currentVolume).then(success => {
node.SonosClient.play().then(success => {
node.busyResumingMusicQueue = false;
resolve(true);
}).catch(err => {
//console.log('Error occurred PLAY %j', err)
node.busyResumingMusicQueue = false;
reject(Err);
})
}).catch(err => {
//console.log('Error occurred setVolume %j', err)
snode.busyResumingMusicQueue = false;
reject(Err);
})
}).catch(err => {
//console.log('Error occurred SEEK %j', err)
node.busyResumingMusicQueue = false;
reject(Err);
})
}).catch(err => {
//console.log('Error occurred SELECTTRACK %j', err);
node.busyResumingMusicQueue = false;
reject(Err);
})
}).catch(err => {
//console.log('Error occurred %j', err);
node.busyResumingMusicQueue = false;
reject(Err);
})
} else {
node.busyResumingMusicQueue = false; // 04/12/2020 Signal end in resuming queue
resolve(true);
}
});
}
// Handle the queue

@@ -877,6 +966,22 @@ function HandleQueue() {

// try {
// node.setNodeStatus({ fill: "yellow", shape: "dot", text: "Queue: " + node.sPollyState });
// } catch (error) { }
// 04/12/220 Busy handling music queue?
if (node.busyGettingMusicQueue || node.busyResumingMusicQueue) {
if (node.busyGettingMusicQueue) node.setNodeStatus({ fill: 'grey', shape: 'dot', text: 'Busy in reading music queue...retry' });
if (node.busyResumingMusicQueue) node.setNodeStatus({ fill: 'grey', shape: 'dot', text: 'Busy in resuming music queue...retry' });
node.oTimer = setTimeout(function () { HandleQueue(); }, 2000);
return;
}
// 04/12/2020 if there are flows messages to be handled, handles it
if (node.tempMSGStorage.length > 0) {
for (let index = 0; index < node.tempMSGStorage.length; index++) {
const element = node.tempMSGStorage[index];
node.aMessageQueue.push(element);
setTimeout(() => {
node.setNodeStatus({ fill: 'green', shape: 'dot', text: 'Queued from flow: ' + element });
}, 1000);
}
node.tempMSGStorage = []; // Flush the array
}
if (node.sPollyState == "transitioning") {

@@ -1028,39 +1133,55 @@ node.iTimeoutPollyState += 1; // Increase Timeout

if (node.msg.completed === false && node.sSonosPlayState == "stopped") {
node.msg.completed = true;
node.ungroupSpeakers(); // 20/03/2020 Ungroup Speakers
node.send(node.msg);
node.setNodeStatus({ fill: "green", shape: "ring", text: "" + node.sSonosPlayState });
if (node.currMusicTrack === null) {
node.ungroupSpeakers(); // 20/03/2020 Ungroup Speakers
node.msg.completed = true;
node.send(node.msg);
node.setNodeStatus({ fill: "green", shape: "ring", text: "Done." });
return;
}
//console.log("PANAMA PANAMA PANAMA PANAMA PANAMA PANAMA " + node.busyGettingMusicQueue + " " + node.busyResumingMusicQueue)
if (node.busyGettingMusicQueue || node.busyResumingMusicQueue) {
if (node.oTimerResumeCurrentQueue !== null) clearTimeout(node.oTimerResumeCurrentQueue);
// Resume the music queue at exact position and seek to exact time
if (node.currMusicTrack !== null) {
node.SonosClient.selectQueue().then(success => {
node.SonosClient.selectTrack(node.currMusicTrack.queuePosition).then(success => {
node.SonosClient.seek(node.currMusicTrack.position).then(success => {
node.SonosClient.setVolume(node.currMusicTrack.currentVolume).then(success => {
node.SonosClient.play().then(success => {
node.currMusicTrack = null;
}).catch(err => {
node.currMusicTrack = null;
console.log('Error occurred PLAY %j', err)
})
}).catch(err => {
node.currMusicTrack = null;
console.log('Error occurred setVolume %j', err)
})
}).catch(err => {
node.currMusicTrack = null;
console.log('Error occurred SEEK %j', err)
})
node.oTimerResumeCurrentQueue = setTimeou(() => {
resumeMusicQueue().then(success => {
if (node.oTimerResumeCurrentQueue !== null) clearInterval(node.oTimerResumeCurrentQueue);
node.msg.completed = true;
node.send(node.msg);
node.setNodeStatus({ fill: "green", shape: "ring", text: "Done." });
}).catch(err => {
node.currMusicTrack = null;
console.log('Error occurred SELECTTRACK %j', err)
})
if (node.oTimerResumeCurrentQueue !== null) clearInterval(node.oTimerResumeCurrentQueue);
node.msg.completed = true;
node.send(node.msg);
node.busyResumingMusicQueue = false;
node.busyGettingMusicQueue = false;
node.setNodeStatus({ fill: "green", shape: "ring", text: "Done." });
}).catch(err => { console.log('Error occurred %j', err) })
});
}, 3000)
} else {
if (node.oTimerResumeCurrentQueue !== null) clearTimeout(node.oTimerResumeCurrentQueue);
resumeMusicQueue().then(success => {
node.msg.completed = true;
node.send(node.msg);
node.setNodeStatus({ fill: "green", shape: "ring", text: "Resuming queue." });
}).catch(err => {
node.msg.completed = true;
node.send(node.msg);
node.busyResumingMusicQueue = false;
node.busyGettingMusicQueue = false;
node.setNodeStatus({ fill: "green", shape: "ring", text: "Error resuming queue." });
});
}
}
} catch (error) { }
} catch (error) {
}
// Resume Queue

@@ -1067,0 +1188,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc