Implementing audible alarms using text-to-speech

Hi everyone. Here’s my challenge…We have 3 groov EPIC units in the plant controlling equipment. We have sirens and horns and such rigged up to sound off whenever there is an alarm condition, but using PAC Control and groov View, we are also displaying the nature of the alarm on the EPIC’s screen (e.g. “Zone 2 temperature on Furnace 3 over allowed limit” or “Motor stopped on conveyor 6”). But each of these alarms sounds the same in the plant. The operator generally has to “follow” his ears to lead him to where the sound is coming from so he can then deal with the situation.

My idea is to use a Text to Speech node from Node-RED (there are many to choose from) and then – on a PC that is hooked up to our overhead PA / loudspeaker system via regular audio cables – read the alarm’s text aloud. This way, the operators can simply listen to the alarm (which could repeat twice if necessary) and then go to the equipment or whatever is in the trouble condition. Kind of like standing in a busy train station and listening for your train number and which platform to go to (rather than running to the large board and reading the data).

I am pretty sure I can work the groov Read node into my flow to read the string variable that describes the alarm (“Zone 2 temperature on Furnace 3 over allowed limit”), but of course the PA system is not hooked up to any of the 3 groov EPIC units in the plant. What I think is needed is Node-RED running on another PC (even a Raspberry Pi that has an audio output) that reads the messages being transmitted by the 3 EPIC units. This post inquired about moving a .txt file to a user’s desktop, but the solutions seemed overly complicated for what I am trying to do. Basically, I am trying to build a Node-RED flow on a separate device (e.g. Windows PC, Raspberry Pi, or whatever) that can listen for any messages being transmitted by the 3 EPIC units, and then read that text over the PA using the TTS node. Am sure this are multiple ways to do this, but I do not know where to begin.

BTW, whatever solution is proposed could easily be applied to the question posed in this posting about audio support on the groov.

EDIT. Ignore this post, see the one below.

@grant1 Get sound working from your Pi or Desktop first…
Then, on your Pi or Windows desktop install Node-RED.
Next install the ‘Dashboard’ nodes. One of those is an Audio out node.
Next install the PAC Nodes from Opto22.

On a new flow, add the PAC nodes to get data from the three EPIC’s. You will need to configure security since they are not on the same Node-RED instance. I have never done this, but follow the help in the info tab and you should get them talking.
Now that you are getting your data from the three EPICs into the one central Node-RED you build a simple dashboard.
Just something with the text from the 3 EPICs that you want spoken. Ensure that you can visit the dashboard in a browser and the text shows up. Don’t worry about making it ‘neat’, you just need a browser tab with the data from the Dashboard node.
Lastly, add the Audio Out node.
Now, when each string comes in, the central Node-RED will speak the text from its browser.
Note the accent and male/female voice will depend on your browser, not all the options will work, so play around till you find one that sounds good in your factory.
You might even strike it lucky and have most of them, that way you can have each EPIC have a different accent (British, USA and computer for example).

Ok, You got me at a good time… We have it working.
Super easy.
The key is that its the browser that does the talking, not the EPIC…

Just install the dashboard nodes on each of the three epics.
In the Node-RED flows for each of the EPICS connect your alarm strings to audio out nodes.

Then on your central computer, the one with the speakers, open three tabs, one to each EPICs Node-RED dashboard. (https://epic-IP-Address/node-red/ui/)
Each tab will then speak as needed.
We have it running here at the office and it works fantastic.

Note that the Node-RED dashboard nodes to not interfere with groov View, the two can run side by side as needed.

Great solution to a really interesting problem.
Thanks for asking.

1 Like

Thanks for your help. You say to install the dashboard nodes on each of the 3 EPICs. I installed node-red-dashboard via the Manage Palette, and I can see the new dashboard nodes on the left. I dragged over the audio out node and connected it to my string variable output and all seems to deploy OK. On a networked PC with speakers, in Chrome, I opened up a tab https://192.168.0.130/node-red/ui/ which corresponds to the EPIC that I put the audio out node into the flow. I know from tinkering around that if I add other dashboard nodes (e.g. text, gauge, etc.), and I get a plain looking dashboard. In my case, I dragged over the text node (from the dashboard set) and it correctly displays the string variable, but no audio is being played. I looked into the settings on the audio out node and below are the options:


I see it says “Expects msg.payload to contain a buffer of a wav or mp3 file” which makes me think I have used the wrong audio out node. Can you tell me the settings on your audio out node?

Looks good… You must be close…
I have Microsoft David as well, I just ticked the box to play the audio when not in focus.

The key is the next line after the one you highlighted, that is if its a STRING, then it will be read aloud.
Test it with this flow;
[{"id":"1c361989.59fc06","type":"ui_audio","z":"f73f253c.88dd6","name":"","group":"fcb8bf11.614a4","voice":"en-US","always":true,"x":740,"y":520,"wires":[]},{"id":"40efb4e5.fe7dcc","type":"inject","z":"f73f253c.88dd6","name":"","topic":"","payload":"hello world 1 plus 1","payloadType":"str","repeat":"5","crontab":"","once":false,"onceDelay":0.1,"x":520,"y":560,"wires":[["1c361989.59fc06"]]},{"id":"fcb8bf11.614a4","type":"ui_group","z":"","name":"Default","tab":"39d04cf4.60bb0c","disp":true,"width":"6","collapse":false},{"id":"39d04cf4.60bb0c","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

I know this speaks once every 5 seconds.

And yes, it will be a very plain looking dashboard, that’s fine, we don’t need anything fancy because it will not be in view anyway.

Thanks. I got your flow running on the EPIC and could hear the browser reading the message on the other PC, so everything definitely works. My error must be in the string message or something. Am sure I will figure it out.

The alarm messages being read are a bit too fast, so I might try to implement this node that allows slowing down the speed, and perhaps use MQTT to connect the EPIC with the Windows PC.

Try putting a debug on both my flow and yours, look and see if you really do have a string.
Node-RED is really good (too good) at doing type conversions and you might not be dealing with a true string.
Also you could play the message twice if its a bit fast.

Glad to hear you are limping along. Hope you crack the last little puzzle and get your messages talking.

So I have the text to speech setup working OK, as far as reading aloud the content of any string variables that are running in my PAC Control programs.

Separate from our EPIC units, we have a SQL database that logs other data in the plant, including a flag to show whenever something is in an alarm condition. For those parameters, I came up with a simple SELECT query that could run every 30 seconds or so and return 3 things: The equipment type (e.g. temper furnace), the equipment number (e.g. 204), and the alarm type (e.g. overtemp). When read over the PA in plain English, it would be something like “Temper furnace 204 overtemp alarm”.

Below is my flow that is working fine in Node-RED (it contains a SQL SELECT query that returns 3 values). What is the best way to take that payload / output text and turn it into plain English that can then be read aloud? I would think a lookup table or something (TMPF = “Temper Furnace”, OTPV = “Overtemp”) and something that can concatenate the text into a sentence.

I think JavaScript in a function node would be your best approach here – but if you prefer to avoid code, a change node would work as well.

The function node could use a JSON object with key:value pairs to define lookup tables, and then use the + operator to concatenate the strings all within a single node.
Another option would be to use a change node to search for “TMPF” on msg.payload[0].EquipmentTypeCode and change that to “Temper Furnace” and so on, and then have another condition to concatenate the strings, likely using JSONATA.

For the code approach here’s a basic example with equipment and parameter objects that you could add your own types and codes to:

equipment = { "TMPF" : "Temper Furnace", "VCMF" : "Vacuum Furnace", "OTHR" : "Other" };
parameter = { "OTPV" : "Overtemp", "UTPV" : "Undertemp", "ALRT" : "Alert" };

type = msg.payload[0].EquipmentTypeCode;
numb = msg.payload[0].EquipmentNumber;
code = msg.payload[0].MeasuredParameterCode;

msg.payload = equipment[type] + " " + numb + " " + parameter[code] + " alarm";

return msg;

This would also work in a loop to grab other msg.payload[i] entries to create multiple alarms based on the values that come in from the database.

Let me know what you think or if you have any followup questions about either method.

Thank you. I was able to modify my SQL query and reference the full name of the equipment and alarm (e.g. Temper Furnace instead of TMPF and Over temp instead of OTPV), so I think all that remains is the concatenation, which seems straightforward. I will give this a try (probably tomorrow) and report back.

1 Like