Amazon Polly and Node-Red. This was far easier to get going than any Alexa skill I tried to do. I just came across this the other day on Scargill’s Tech blog.
“Amazon Polly is a service that turns text into lifelike speech. … With Amazon Polly, you only pay for the number of characters you convert to speech, and you can save and replay Amazon Polly’s generated speech.”
Basically you feed Polly SSML text and it returns it in spoken form as an MP3 (or other format). Sweet, I can give my server/Node-Red a voice! Not sure my wife will like this but it will actually server a valid purpose. I was admitted to the hospital (again) for a short three-day stay recently and while I was admitted (and loaded up on drugs) my server closet reached my maximum set temperature… and issued the text alert 187 times. Now I can have the server annunciate that the closet needs to be opened. I could add my wife’s number to the SMS list but that will fail, lol. Simply saving the MP3 on the server and having it be played back works just great.
I am sure you can tap into the API many other ways, and use Polly many other ways, but the simplest way was my path. I just logged into the Amazon Polly Developer console and slapped some text in the input box. It spit out an MP3 and I saved it. The catch here is that the free tier of the Polly program only lasts 12 months, then you get charged. Its super cheap though, $4 per 1 million characters. The free tier is 4 million per month (for 12 months). From what I have read Polly will search the cloud to see if the file already exists. If it does it pulls it down, if it doesn’t it creates it (and counts agains the character limit) and pulls it down. Is this for “the cloud” or your account? Dunno. Still pretty cheap.
I have circumvented the whole thing (for now). I don’t really plan on (or have the need to) generating Polly files on the fly. What works for me is as I said, just slapping a ton of phrases I think I’ll need into Polly and saving the files for later. I’m cool with that.
But, there is a node for NR that will generate Polly files for you on the fly, and/or pull down the ones already generated. I mentioned I found Polly on Scargill’s blog, he also used NR to play with Polly. He had to do it the hard way. Three days ago the node was made. Definitely check out his blog even if you just use the node. Its all good info.
The node looks pretty simply to use (I have not used it). You need to add your Amazon Polly API credentials to the node. The input gets TTS’d and the file saved. If the text has already been converted no Polly call is made and just the file served. So it looks like it stores all the Polly MP3s for you locally. Sweet.
I use Node-Red for a lot of things and I have recently wanted to send notifications via SMS instead of an email, and I wanted to be able to receive SMS messages as well. I have had issues with the email node. It doesn’t always send for me (I’m using Google’s SMTP) and I don’t have a loud email notification on my phone. Because tons of emails thats why. But text messages on my phone have a very loud notification. I also wanted to be able to send messages to my Node-Red server, doing that via email is cumbersome. So texting it is. Plus sending/receiving an SMS is way cooler than a boring email. I know I can send texts to my phone via email (on most carriers) but that still requires using email and the email node. Don’t want to.
Enter Twilio. I have used Twilio before in the past with their free service tier and never got around to actually using it. The free service lets you do all the same stuff (I think) as the paid service but all the texts have a “This message was sent by Twilio – ” tag attached before every message. So I think thats why I never used it. Well I looked into it again and this time I just upgraded my account right away. Not fucking around. I just threw down $20 bucks. You buy a phone number for $1 per month and then you pay for all the messages you send. The cost per message (at this time) is somewhere around $0.0075 cents! Sweet! I figure I should be able to get a years worth of my number rental and a few messages off that $20 bucks.
So lets use Node-Red to send and receive an SMS with Twilio, it’s why you’re here right? Not for my ramblings.
To send an SMS from Node-Red is dead simple. Just install the Twilio node. It gives you a new output node. Just send you data to the node and off the SMS goes.
To be able to receive a message from Twilio your Node-Red needs to be accessible from the outside world. Twilio needs to be able to see the XML we are going to generate. In my searches for doing this I got a fucking headache. I found a few blogs out there with info on this but nothing concrete. It was actually pretty simple, at least for me. I have also already done this before in a previous post. I happen to run Apache for my web server, which is already setup and open to the world, DNS already setup. All I had to do was create a subdomain (not required) and point a the new vhost to my Node-Red server/install (via ProxyPass). Once this was done Twilio could access my Node-Red served pages. I also have (but I don’t think is required?) SSL already setup. I used Let’s Encrypt on my Apache server. However you do it is fine, you just need to be able to see at least 1-2 Node-Red generated pages from the web. I honestly found this to be one of the more pain in the ass tasks to deal with. Good luck.
The switch node checks
msg.Body with
msg.req.query.Body for an incoming command. If the switch matches a command it routes it to a function node. If it matches a command it also checks that command for an ON or OFF and outputs the results as a 1 or 0 for you to do with what you like. So you would text your Twilio number “mySwitch on” or “mySwitch off” and bam! Otherwise it passes it off to a different function node to process the message further. That node checks the incoming message for a global. By this I mean you text your Twilio number “read mySensor” and this function node sees the “read” command and then checks for a sensor name (mySensor). It matches this name against a global you have saved and spits back the results after being XML’d. So when you text “read mySensor” it checks the mySensor global and texts you back with “mySensor: yourvalue”. Awesome.
Tip: the switch node is case sensitive, so be careful. The function nodes change everything to caps I assume to simplify stuff I dunno. I didn’t write it. Also when you change the sensor name make sure to edit the substr to match the character limit of your sensor name. Example: WEMO would be 4, MYSWITCH is 8 characters. Same thing if you change the READ query.
Here’s the flow, I included a testing global for you as well:
1
[{"id":"2ae927d8.5bde18","type":"http in","z":"c0516cfd.4f261","name":"","url":"/twiliosms","method":"get","swaggerDoc":"","x":220,"y":740,"wires":[["4893a45a.60540c","f3d48024.a344"]]},{"id":"ef0e3c3c.3f3ea","type":"function","z":"c0516cfd.4f261","name":"Process SMS","func":"// Process SMS request and create a response\n// If SMS starts with READ (match is not case sensitive) then use REST to access\n// a global context to read a previously stored value from a sensor\n// If READ is not found then just it returns what you sent\n\nvar responseMsg = \"\";\nvar smsMsg = msg.req.query.Body;\n\nif( smsMsg.substr(0,4).toUpperCase() == \"READ\" ) {\n\tvar name = smsMsg.substr(4).trim();\n\tvar reading = context.global[name]; // This is where it grabs your global\n\tresponseMsg = name + \": \" + reading; // This is the message you will get\n} else {\n // This is the message you get if it cant find your global\n\tresponseMsg = \"You sent: \" + msg.req.query.Body;\n}\n\n// Create JSON object for payload response, and format it for Twilio\nvar messageObj = { \"Response\": { \"Sms\": responseMsg } };\n\n// Need to return received msg object, but with new payload\nmsg.payload = messageObj;\n\nreturn msg;\n","outputs":"1","noerr":0,"x":660,"y":760,"wires":[["13584066.d156","3379a357.0094dc"]]},{"id":"36410242.7bcd9e","type":"http response","z":"c0516cfd.4f261","name":"Send TwiML","x":1070,"y":760,"wires":[]},{"id":"f3d48024.a344","type":"switch","z":"c0516cfd.4f261","name":"Switch","property":"req.query.Body","propertyType":"msg","rules":[{"t":"cont","v":"mySwitch","vt":"str"},{"t":"nnull"}],"outputs":2,"x":450,"y":740,"wires":[["c5a4681b.783a88"],["ef0e3c3c.3f3ea"]]},{"id":"c5a4681b.783a88","type":"function","z":"c0516cfd.4f261","name":"Process mySwitch","func":"// Setup mySwitch message based on on/off received for mySwitch command\n\nvar smsMsg = msg.req.query.Body;\n\nif( smsMsg.substr(0,8).toUpperCase() == \"MYSWITCH\" ) {\n\tvar status = smsMsg.substr(8).trim();\n\tif( status.toUpperCase() == \"ON\" )\n\t\tmsg.payload = \"1\";\n\telse if( status.toUpperCase() == \"OFF\" )\n\t\tmsg.payload = \"0\";\n}\n\nreturn msg;\n","outputs":1,"noerr":0,"x":670,"y":720,"wires":[["adb95e4a.d3065"]]},{"id":"adb95e4a.d3065","type":"debug","z":"c0516cfd.4f261","name":"","active":true,"console":"false","complete":"false","x":890,"y":720,"wires":[]},{"id":"13584066.d156","type":"xml","z":"c0516cfd.4f261","name":"","attr":"","chr":"","x":870,"y":760,"wires":[["36410242.7bcd9e"]]},{"id":"3379a357.0094dc","type":"debug","z":"c0516cfd.4f261","name":"","active":true,"console":"false","complete":"false","x":890,"y":800,"wires":[]},{"id":"4893a45a.60540c","type":"debug","z":"c0516cfd.4f261","name":"","active":true,"console":"false","complete":"false","x":470,"y":780,"wires":[]},{"id":"59868f57.52fd","type":"debug","z":"c0516cfd.4f261","name":"","active":true,"console":"false","complete":"false","x":890,"y":660,"wires":[]},{"id":"61bf58e6.a8c5c8","type":"globalGetSet","z":"c0516cfd.4f261","name":"mySensor","topic":"","context":"msg","variable":"payload","outContext":"global","outVar":"mySensor","x":640,"y":660,"wires":[["59868f57.52fd"]]},{"id":"51cda2d4.21bffc","type":"inject","z":"c0516cfd.4f261","name":"","topic":"","payload":"70.45","payloadType":"str","repeat":"","crontab":"","once":true,"x":450,"y":660,"wires":[["61bf58e6.a8c5c8"]]}]
This is where I got the information on the Twilio node (from the creator it seems) and how to receive messages. But I found it about as clear as mud. (Note: the json2xml node doesn’t exist anymore. Just use the XML node now.) http://blog.thiseldo.co.uk/?p=1090
I love Star Trek (any good SciFi really) and who doesn’t? I also have an Amazon echo and I have been making my home smarter and adding automation where I can, very SciFi’ish yeah? The other day I thought to myself how cool would it be if I could activate a red alert”? Well I do have the Dot and I do have Philips Hue bulbs. I do have a home server and I do have Raspberry Pies. So I decided I wanted to have this feature and set out to get it done. As it turns out I am not the only one that wanted to be able to do this. After Googling I found a few other people that went through a similar process. Although I have not seen anyone do it the way I did. The ones I found mostly accomplished it with a Google Home Assistant and some used Node-Red. Hey, I have Node-Red. I guess the Home Assistant can play audio files. I have found a few pages on Alexa doing this recently but I have not gotten into making skills, yet. All the pages I saw also seemed to rely on an outside service of some kind (minus the voice assistant). They pulled the audio from the web or used IFTTT (which I hate) to do something. I don’t want that. I like to be as self contained as possible. Here’s what I did.
I have my home server setup with NR and it takes it all the MQTT in the house and does all the NR handling for the house. Then I have a Raspberry Pi (that also sits on top of the server), this has a temperature sensor on it and it handles the audio portion of the red alert. Since it is sitting there I also have it monitor the server, and the server monitor the Pi.
Yes I have a server and a Pi, yes they both also run NR. Why do I not use just the server instead of the Pi? The server doesn’t have a sound card and I don’t have an extra one. So yeah.
This flow is where I make the color changes. I use the Wemo Emulator node to create a device Alexa can discover, that also allows me to choose my own trigger word. That node gives a 1 or a 0 (on or off). I pass that to a function that contains the hue bulb color and activates the alert pulsing, this all flows to the hue bulb and out via MQTT. In the flow I only have one hue bulb connected. I have since connected the red alert to all the bulbs I have (currently 4 colored ones).
Here is where I activate the audio. I initially tried omxplayer. I found a shell script that looped the audio but it gave me issues when trying to kill the process. It only worked the first time. The processes didn’t die completely. I want to be able to stop the red alert also. So I continued searching. I came across a post in the NR Google groups and they had created a flow for playing a sound off of motion detection. I was able to take the kill (killall, duh) command he used to stop my flow. I also used the player (mpg123) he used because it has looping options builtin. Sweetness.
I am now able to tell Alexa to turn on a red alert and have her stop it as well. This doesn’t used IFTTT or rely on any other outside source (besides Alexa). It does not require an Alexa skill either. I have future plans to make a custom skill for this so I can change the phrase from “turn on red alert” to something more comfortable like “activate red alert”.
Onward to the flows!
I am using Node-Red 0.16.2 with Node 6.10.2 with NPM 3.10.10. The server is Ubuntu 16.04.2 LTS and the RPi is Raspbian 8 (Jessie)
I am running these flows split on two different Node-Red installs (one on the server one on the Pi) but this is not necessary. You could do it all on a Pi or all on a server/computer (with a sound card).
Don’t forget to turn up the volume on the 3.5mm audio jack
amixer set PCM---21.00 worked for me.
(You may notice that the flows are different from the images, I cleaned up the flow before exporting and pasting the code.)
UPDATE 8/29/2017: I added updated code/flows so that you can disable the Red Alert lights. Previously a “stop node red” command would silence the sounds but not cancel the flashing lights. With the new update the sounds stop and the lights stop flashing and turn white. Still working on getting the lights to default to white after the Red Alert times out.
I had programmed a page of goodness in Node-Red for being the middle-man between the internet and my security system. Here’s the schpeal…
I used to work for an alarm company for a number of years. It’s a job that has kind of stuck with me, specially all the shit and skills that I learned while doing it. So I still have friends in the industry and I still have equipment from when I worked there. Naturally I install my own security system. Not wanting to pay for monitoring but still wanting to be notified with issues gave me a problem. I happen to know Pies so I decided to use a Raspberry Pi with Node-Red to solve that problem.
There are many ways to get notifications from your security system these days but they all require some kind of monitoring or to be activated by an alarm company (someone with a license). Using the Raspberry Pi I could do everything I wanted to. Node-Red just made it that much easier.
I programmed all of this via NR on one of my Raspberry Pies. I believe at the time I was programming in Node-Red v0.12 (around May 2016 I think). Here’s the flow:
I cannot be held responsible for anything bad that may happen. This has been coded to the best of my ability but there may be bugs and some of it may be unfinished. USE AT YOUR OWN RISK!
Huge thanks out to Martin Harizanov (https://harizanov.com) I don’t know the man but sifting through his very informative blog has allowed me to get this code (and many others) up and running. You can find his original post on the subject here https://harizanov.com/2014/03/presence-detection-using-phones-wifi-and-node-red/
This is basically his work with a few tweaks. I decided to send all my sensor logs to my home servers MySQL db. The RPi uses an SDCard that has limited write life, and I think there are some performance issues there too (I don’t know, never bothered to look it up, I’m talking out my ass). I have a home server that runs MySQL and Apache so I was going to just offload that work away from the RPi anyway.
To get the presence detecting done I ping for my phone every 30 seconds or so then that result goes to a function to get analyzed (by Mr. Harizanov’s code), then that result is given to another function that UPDATES a MySQL database then finally on to a MySQL node to make the connection.
Ping->Analyze Ping Function->Update MySQL Function->Connect toMySQL Server
I noticed that it took about 2-4 ping results before it would change status, and that it didn’t matter if it was a 30 second or 5 minute delay. So I went with 30 seconds, it doesn’t hammer the Pi too bad and I don’t have to wait too long to test it, hah. I did not thoroughly test this theory, I just noticed it once or twice so I could be way off.
Hopefully this helps someone else in their time of need. One is glad to be of service.
Presence Detection
If you DO NOT have or use a cellphone (or a device that uses WiFi that goes with you everywhere) then this WILL NOT WORK for you.
It works by utilizing the fact that almost everyone has a cellphone and that they usually always have it with them. The idea is simple, Node-RED looks for your cellphone. If it can see your phone it assumes you are home along with it. How do we see your phone? Ping it. Basically ping the IP address of your phone every so often and it the ping comes back you are home, if it times out you are assumed away.
You will need
node-red-node-ping installed for this to work.
(http://flows.nodered.org/node/node-red-node-ping)
MySQL Node to make the connection http://flows.nodered.org/node/node-red-node-mysql
You may want to add a debug node after the Update DB function and two inject nodes before the Update DB function, set as 1 and 0 to simulate your phone home/away.
Ping Node
This one is simple, just add the IP of your cellphone and set the timer. I used 30 seconds, although I will probably change this to 5 minutes. It helps to have control over your router so you can set static IPs.
Function Node (Analyze Ping Result)
Don’t forget the global variable, this is needed in the next step.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// anything stored in context is kept available for next time we get called
context.gotping=context.gotping||1;
context.pingfails=context.pingfails||0;
if(msg.payload){
context.gotping=1;
context.pingfails=0;
}else{
context.pingfails+=1;
if(context.pingfails>3)context.gotping=0;
}
msg.payload=context.gotping;
// set global variable
context.global.variable1=msg.payload;
returnmsg;
Function (Update MySQL db)
You will need to change the db settings to match yours of course
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data=(msg.payload);
time=newDate().toString();
if(data==1){
varmsg={
// topic : "INSERT INTO `mydb`.`mytable` (`one`, `two`) VALUES (NULL, '" + data + "');"
topic:"UPDATE presence SET home = '"+data+"', lastin = '"+time+"' WHERE presenceid = '28';"
};
}else{
varmsg={
// topic : "INSERT INTO `mydb`.`mytable` (`one`, `two`) VALUES (NULL, '" + data + "');"
topic:"UPDATE presence SET home = '"+data+"', lastout = '"+time+"' WHERE presenceid = '28';"
};
}
msg.payload=data;
returnmsg;
Connect to MySQL node
This is pretty straight forward, setup with your servers credentials
That should get your Node-RED to detect if you are home or not based off your cellphones Wifi. Pretty cool, yeah but what do you do with that info? Log it? Display? Yes! Take the info from my last post and apply it here and we can check the status any time we want! http://itsalllost.com/node-red-requesting-sensor-data-via-http/
Here’s the code to check the status of the global variables (make sure they all match!)
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here:
Cookie Policy