Control Node Red with voice from Google Now

This flow shows how to process Google Now commands send from my Android mobile phone using AutoVoice and Tasker running on the phone. The flow can recognize simple commands, mostly related to home automation: turning lights on and off. The logic is implemented in a function node, so if can only understand commands in a specific pattern. But it is highly customizable. This is intended as a template only to be modified to specific requirements.

If you want to know more details on how the code works, watch my video on YouTube: https://youtu.be/8mjTtcdLvQA

[{"id":"f10a1076.cc20b","type":"tab","label":"Google Now"},{"id":"5e61d8f5.683d08","type":"http in","z":"f10a1076.cc20b","name":"Request","url":"/google","method":"get","swaggerDoc":"","x":85,"y":109,"wires":[["fa63c682.86a698","d86d0365.9314"]]},{"id":"bd8d0057.3561f","type":"http response","z":"f10a1076.cc20b","name":"Response","x":948,"y":103,"wires":[]},{"id":"fa63c682.86a698","type":"debug","z":"f10a1076.cc20b","name":"","active":true,"console":"false","complete":"req.query.text","x":340,"y":36,"wires":[]},{"id":"a95df868.6e9e18","type":"inject","z":"f10a1076.cc20b","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":116,"y":238,"wires":[["5e27cf7c.87c67"]]},{"id":"d86d0365.9314","type":"function","z":"f10a1076.cc20b","name":"Analyze voice command","func":"var temp = msg.req.query.text;\nmsg.payload.command = 0;\nmsg.payload.success = false;\n\n// removing rubbish\ntemp = temp.toLowerCase();\ntemp = temp.replace(\"a \",\"\");\ntemp = temp.replace(\"the \",\"\");\ntemp = temp.replace(\"to \",\"\");\ntemp = temp.replace(\"home \",\"\");\ntemp = temp.replace(\"lights\",\"light\");\n\n// check if the command is to turn something on/off\nif (temp.indexOf(\"turn\")>-1) {\n    temp = temp.replace(\"turn \",\"\");\n    msg.payload.command = 1;\n}\nif (temp.indexOf(\"switch\")>-1) {\n    temp = temp.replace(\"switch \",\"\");\n    msg.payload.command = 1;\n}\n\n// check if the command is about the solar panels\nif (temp.indexOf(\"solar\")>-1) {\n    temp = temp.replace(\"solar \",\"\");\n    msg.payload.command = 2;\n}\n\n// let's try finding the thing and state\n// the turn/switch commands are expected as 'turn <state> the <thing>'\nvar lastIndex= temp.indexOf(\" \");\nvar voice_state = temp.substring(0, lastIndex).trim();\nvar voice_thing = temp.substring(lastIndex+1,temp.length).trim();\n\n// evaulate the state\nif (voice_state===\"on\") {\n    msg.payload.command_value = \"1\";\n}\nif (voice_state===\"off\") {\n    msg.payload.command_value = \"0\";\n}\n\n// handle the solar request\nif (msg.payload.command===2) {\n    msg.payload.response=\"The solar system is currently generating \" + global.get(\"growatt_power\") + \" watts. Total generation today is \" + global.get(\"growatt_today\") + \" kilowatt hours.\";\n}\n\n// handle the switch commands\nif (msg.payload.command===1) {\n    switch (voice_thing) {\n        case \"christmas light\":\n            msg.payload.response=\"OK, turning \" + voice_state + \" the \" + voice_thing;\n            msg.payload.success = true;\n            msg.payload.command_thing=\"Sonoff1\";\n            break;\n        case \"test light\":\n            msg.payload.response=\"OK, turning \" + voice_state + \" the \" + voice_thing;\n            msg.payload.success = true;\n            msg.payload.command_thing=\"Test\";\n            break;\n        default:\n            msg.payload.response=\"Sorry, I did not understand turning \" + voice_state + \" the \" + voice_thing;\n            msg.payload.success = false;\n            break;\n    }\n}\n\n\n\nreturn msg;","outputs":1,"noerr":0,"x":366,"y":104,"wires":[["a695aaf0.376488","2138e92c.d64296","973d8cab.37a9"]]},{"id":"a695aaf0.376488","type":"debug","z":"f10a1076.cc20b","name":"","active":true,"console":"false","complete":"false","x":864,"y":211,"wires":[]},{"id":"2138e92c.d64296","type":"switch","z":"f10a1076.cc20b","name":"Check if command was valid","property":"payload.success","propertyType":"msg","rules":[{"t":"true"}],"checkall":"true","outputs":1,"x":423,"y":311,"wires":[["a2cac641.fbd748"]]},{"id":"a2cac641.fbd748","type":"switch","z":"f10a1076.cc20b","name":"Check command","property":"payload.command","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"eq","v":"3","vt":"num"}],"checkall":"true","outputs":3,"x":128,"y":411,"wires":[["a1658db8.a14f8","6c537189.6ac2d"],[],[]]},{"id":"a1658db8.a14f8","type":"switch","z":"f10a1076.cc20b","name":"Christmas light?","property":"payload.command_thing","propertyType":"msg","rules":[{"t":"eq","v":"Sonoff1","vt":"str"}],"checkall":"true","outputs":1,"x":399,"y":398,"wires":[["679a67b2.f0ba68"]]},{"id":"679a67b2.f0ba68","type":"function","z":"f10a1076.cc20b","name":"Put value to payload","func":"msg.payload = msg.payload.command_value;\nreturn msg;","outputs":1,"noerr":0,"x":618,"y":399,"wires":[["1af837e2.52f558"]]},{"id":"973d8cab.37a9","type":"function","z":"f10a1076.cc20b","name":"Put response into payload","func":"msg.payload = msg.payload.response;\nreturn msg;","outputs":1,"noerr":0,"x":697,"y":103,"wires":[["bd8d0057.3561f"]]},{"id":"5e27cf7c.87c67","type":"function","z":"f10a1076.cc20b","name":"Move value","func":"msg.req.query.text = \"home turn on the christmas light\"\nreturn msg;","outputs":1,"noerr":0,"x":239,"y":173,"wires":[["d86d0365.9314"]]},{"id":"1af837e2.52f558","type":"link out","z":"f10a1076.cc20b","name":"","links":["2bd7b670.60308a"],"x":856.4999694824219,"y":397.6666488647461,"wires":[]},{"id":"6c537189.6ac2d","type":"switch","z":"f10a1076.cc20b","name":"Test light?","property":"payload.command_thing","propertyType":"msg","rules":[{"t":"eq","v":"Test","vt":"str"}],"checkall":"true","outputs":1,"x":393.6666564941406,"y":465.6666564941406,"wires":[["146bb513.5434fb"]]},{"id":"146bb513.5434fb","type":"function","z":"f10a1076.cc20b","name":"Put value to payload","func":"//msg.payload = msg.payload.command_value;\nmsg.url = \"http://192.168.1.133/control?cmd=gpio,12,\"+msg.payload.command_value;\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.url});\nreturn msg;","outputs":1,"noerr":0,"x":622.6666564941406,"y":466.6666564941406,"wires":[["8f969c51.fd772"]]},{"id":"8f969c51.fd772","type":"http request","z":"f10a1076.cc20b","name":"","method":"GET","ret":"txt","url":"","x":965.4999694824219,"y":465.6666488647461,"wires":[[]]}]
nygma2004

Flow Info

created 8 months, 1 week ago

Node Types

Core
  • debug (x2)
  • function (x5)
  • http in (x1)
  • http request (x1)
  • http response (x1)
  • inject (x1)
  • switch (x4)
Other
  • link out (x1)
  • tab (x1)

Tags

  • voice
  • google
  • now
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option