Every good product needs an
Insight
I’m teaching at the Miami Ad School in Hamburg a class called „Tech Garage“, some IoT stuff. The lovely ladies at the office have a pot plant. They call him Arthur. Arthur does not always look really well cared. They focus on the students. Which in contrary look well cared, so right priorities. As I mentioned „I could build something for you that reminds you.“, they were amused.
What it does
The action our plant Arthur does is very simple. As you can see in the setup, we have an attached speaker. So as soon as the level of humidity of the soil will drop under a certain level it will execute several actions. First it will play a small audio sample, which says „I’m hungry.“ via the speaker. So within the office the ladies will be called to action.
But Arthur does also have an Twitter account. Of course. Otherwise, it would not be an tweeting pot plant. You could follow him under https://twitter.com/arthurtheplant. So Arthur will also send a Tweet, each time he is hungry. But no more often than once each 8 hours. We don’t want to spam the people. There we has a „wide“ range of sentences in his vocabulary, he could choose randomly from.
How it is done
What we need for our Arthur pot plant is:
- Raspberry PI, the „old“ Raspberry I is powerfull enough
- WiFi dongle, like this one
- Speaker, like those
- Moisture sensor, I used this one
Currently I do most of my Raspberry PI projects based on Node-RED. It is a Node.js based „If this than that“- plattform for the Internet of Thing (IoT). And it has a nice interface, so when you are ready technically you could give it to non-technicians as well. So it is worth a look.
Here you find a good installation guide for Node-RED on a Raspberry PI: http://nodered.org/docs/hardware/raspberrypi
Once you have Node-RED running on your Rapsberry PI ( http://nodered.org/docs/getting-started/running ) you should be able to open the webinterface of Node-RED via port 1880. So sth like this: http://192.168.1.2:1880, where 192.168.1.2 is the IP address of your Raspberry PI.
Before we are going to wire together the logic within Node-RED, we have to connect our moisture sensor. The moisture sensor I use has four connectors. We need three. So please connect:
- VCC to PIN 1, 3.3V, Raspberry PI Model 1 Layout
- GND to PIN 9, Ground, Raspberry PI Model 1 Layout
- D0 to PIN 11, GPIO17, Raspberry PI Model 1 Layout
If you have connected the sensor and have your Rapsberry PI running a red LED should be shining on the sensor which indicates that the sensor is under power. There is a second LED on the sensor lighting in green. If this is lighting it shows humidity is detected. If this is lighting without the sensor toughing water, the threshold isn’t correct yet. The best idea is you grab yourself a pot plant which is well watered, like it should be. Than put the sensor in the soil. Now rotate the little screw hole on the sensor until the green light isn’t lighing any more. Than a littel back until it is lighting again.
Now we could switch into the Node-RED interface. Over the main menu top right you could select „Import > Clipboard“. Please find my Node-RED flow at the bottom of the page and copy this there. So you get the flow ready. Once you copied the flow into your Node-RED. IT should sth. like that
There are three nodes we have to adapt for your case. First you see a twitter node on the right end of the top flow. This is not connected yet and you have to enter your twitter name and have to authorise this twitter node running as app on your twitter account. Second, please go to the big red „Play Im hungry“ node. This is an Exec node, which plays an mp3 file, located in the Desktop folder on the Raspberry PI. So first you have to copy an mp3 file of your choice onto the Raspberry PI. Than you have to update the filename there. And third you have to enter some texts, which should be twittered. Therefor there is an Injection node „Add text“. Double click the node and enter some text into the string field. Now deploy everthing ( red button top right ). And click on the small button infront of „Add Text“. You could repeat this ( enter new text into Injection node, Deploy, click ) to add more texts.
Have fun with your twittering plant.
cheers.
Sebastian
Node-RED Flow:
[{"id":"760a0fbe.8437c","type":"rpi-gpio in","z":"1e352319.d22d3d","name":"","pin":"11","intype":"up","read":true,"x":111,"y":108,"wires":[["33900545.48300a"]]},{"id":"c42db9fc.0d05d8","type":"inject","z":"1e352319.d22d3d","name":"","topic":"","payload":"","payloadType":"date","repeat":"3600","crontab":"","once":true,"x":148,"y":742,"wires":[["6e04586f.8a7cb8"]]},{"id":"30b8f25b.f5407e","type":"debug","z":"1e352319.d22d3d","name":"","active":true,"console":"false","complete":"true","x":598,"y":742,"wires":[]},{"id":"6e04586f.8a7cb8","type":"exec","z":"1e352319.d22d3d","command":"/home/pi/Desktop/sendip.sh","addpay":true,"append":"","useSpawn":"","name":"","x":361,"y":754,"wires":[["30b8f25b.f5407e"],[],["30b8f25b.f5407e"]]},{"id":"48476f8b.bdbf1","type":"comment","z":"1e352319.d22d3d","name":"Send own IP","info":"","x":128,"y":694,"wires":[]},{"id":"b2d42c76.493e4","type":"twitter out","z":"1e352319.d22d3d","twitter":"","name":"Tweet @arthurtheplant","x":1259,"y":531,"wires":[]},{"id":"33900545.48300a","type":"function","z":"1e352319.d22d3d","name":"Store","func":"// store current status\ncontext.global.water_status = msg.payload;\n\nreturn msg;","outputs":1,"noerr":0,"x":242,"y":107,"wires":[["e7198d5c.b0c27"]]},{"id":"bf0066d4.928ab8","type":"switch","z":"1e352319.d22d3d","name":"","property":"payload","rules":[{"t":"eq","v":"1"},{"t":"eq","v":"0"}],"checkall":"true","outputs":2,"x":507,"y":103,"wires":[["ef445002.7e282"],[]]},{"id":"ef445002.7e282","type":"delay","z":"1e352319.d22d3d","name":"","pauseType":"delay","timeout":"7","timeoutUnits":"seconds","rate":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":366,"y":188,"wires":[["46339188.f9e76"]]},{"id":"46339188.f9e76","type":"function","z":"1e352319.d22d3d","name":"Read","func":"return {payload:context.global.water_status};","outputs":1,"noerr":0,"x":506,"y":188,"wires":[["5c3ef08d.14c02"]]},{"id":"5c3ef08d.14c02","type":"switch","z":"1e352319.d22d3d","name":"","property":"payload","rules":[{"t":"eq","v":"1"},{"t":"eq","v":"0"}],"checkall":"true","outputs":2,"x":631,"y":189,"wires":[["df138f31.6c0c8"],[]]},{"id":"df138f31.6c0c8","type":"function","z":"1e352319.d22d3d","name":"","func":"\nreturn msg;","outputs":1,"noerr":0,"x":525,"y":301,"wires":[["16eac047.b6b99","5243554d.93ccec","8ad468cf.2999f8"]]},{"id":"ab42994f.c75fb8","type":"comment","z":"1e352319.d22d3d","name":"Still dry, call to action","info":"","x":570,"y":250,"wires":[]},{"id":"554e5e50.b2bd3","type":"comment","z":"1e352319.d22d3d","name":"Check PIN for state change","info":"","x":174,"y":58,"wires":[]},{"id":"5243554d.93ccec","type":"exec","z":"1e352319.d22d3d","command":"omxplayer -l 00:00:00 -o local /home/pi/Desktop/imhungry.mp3","addpay":true,"append":"","useSpawn":"","name":"Play Im Hungry","x":899,"y":305,"wires":[[],[],[]]},{"id":"c7cc8f1a.4d16d","type":"exec","z":"1e352319.d22d3d","command":"kill -9 $(ps aux | grep omxplayer | awk '{print $2}')","addpay":true,"append":"","useSpawn":"","name":"Stop All Music","x":898,"y":360,"wires":[[],[],[]]},{"id":"16eac047.b6b99","type":"delay","z":"1e352319.d22d3d","name":"","pauseType":"delay","timeout":"11800","timeoutUnits":"milliseconds","rate":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":720,"y":361,"wires":[["c7cc8f1a.4d16d"]]},{"id":"e3273442.8d7658","type":"inject","z":"1e352319.d22d3d","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":538,"y":359,"wires":[["c7cc8f1a.4d16d"]]},{"id":"e7198d5c.b0c27","type":"function","z":"1e352319.d22d3d","name":"Read","func":"return {payload:context.global.water_status};","outputs":1,"noerr":0,"x":380,"y":106,"wires":[["bf0066d4.928ab8"]]},{"id":"201ec204.554d3e","type":"inject","z":"1e352319.d22d3d","name":"","topic":"","payload":"","payloadType":"date","repeat":"1800","crontab":"","once":false,"x":125,"y":168,"wires":[["e7198d5c.b0c27"]]},{"id":"d51b9c3a.411e5","type":"inject","z":"1e352319.d22d3d","name":"Add Text","topic":"","payload":"It got no water for a long time. This is no fun !","payloadType":"string","repeat":"","crontab":"","once":false,"x":130,"y":639,"wires":[["b54b7def.aa6b6"]]},{"id":"b54b7def.aa6b6","type":"file","z":"1e352319.d22d3d","name":"Write to file","filename":"/home/pi/arthur-complains.txt","appendNewline":true,"createDir":false,"overwriteFile":"false","x":290,"y":639,"wires":[]},{"id":"391a6668.fba9aa","type":"comment","z":"1e352319.d22d3d","name":"Add new complains","info":"","x":145,"y":588,"wires":[]},{"id":"8cf41589.c09418","type":"file in","z":"1e352319.d22d3d","name":"","filename":"/home/pi/arthur-complains.txt","format":"utf8","x":868,"y":531,"wires":[["7f2a92a5.b775ac"]]},{"id":"b120f8a9.60c0f8","type":"inject","z":"1e352319.d22d3d","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":639,"y":530,"wires":[["8cf41589.c09418"]]},{"id":"7f2a92a5.b775ac","type":"function","z":"1e352319.d22d3d","name":"","func":"// get each possible answer as array\nvar data = msg.payload.split(\"\\n\");\n// stop is no text data available\nif( !data.length ) return null;\n// get random value;\nvar rand = Math.floor(Math.random() * (data.length-1));\nvar timeNow = new Date();\n\n// \nvar outstr = \"It is \" + \n timeNow.getDate() + \".\" +\n timeNow.getMonth() + \".\" +\n timeNow.getFullYear() + \" \" +\n timeNow.getHours() + \":\" +\n timeNow.getMinutes() + \"h \" +\n data[rand] + \" /Arthur\";\n \nreturn {payload: outstr};","outputs":1,"noerr":0,"x":1072,"y":531,"wires":[["b2d42c76.493e4","b9705232.cfe7e"]]},{"id":"7322fa98.fdd244","type":"comment","z":"1e352319.d22d3d","name":"Get random text","info":"","x":553,"y":435,"wires":[]},{"id":"8ad468cf.2999f8","type":"function","z":"1e352319.d22d3d","name":"","func":"if( !context.global.lasttweet ){\n context.global.lasttweet = (new Date()).getTime()-(1001*60*60*8);\n}\n\nvar tweettime = context.global.lasttweet;\n\nif( (((new Date()).getTime() - tweettime)/1000/60/60)>8 ){\n context.global.lasttweet = (new Date()).getTime();\n return msg;\n}\n\nreturn null; ","outputs":1,"noerr":0,"x":637,"y":480,"wires":[["8cf41589.c09418"]]},{"id":"62083a66.6c8b24","type":"comment","z":"1e352319.d22d3d","name":"Get last tweet time ","info":"","x":146,"y":803,"wires":[]},{"id":"80dd0c0b.8e097","type":"inject","z":"1e352319.d22d3d","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":146,"y":862,"wires":[["edf35134.c9635"]]},{"id":"edf35134.c9635","type":"function","z":"1e352319.d22d3d","name":"","func":"\nreturn {payload:context.global.lasttweet};","outputs":1,"noerr":0,"x":315,"y":863,"wires":[["6899bea9.fc639"]]},{"id":"6899bea9.fc639","type":"debug","z":"1e352319.d22d3d","name":"","active":true,"console":"false","complete":"false","x":499,"y":862,"wires":[]},{"id":"b9705232.cfe7e","type":"debug","z":"1e352319.d22d3d","name":"","active":true,"console":"false","complete":"false","x":1231,"y":478,"wires":[]},{"id":"3e83a0bf.3c90c","type":"inject","z":"1e352319.d22d3d","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":143,"y":970,"wires":[["dec6ae99.f1a6c"]]},{"id":"be0c939c.83beb","type":"comment","z":"1e352319.d22d3d","name":"Reset Tweet Time","info":"","x":145,"y":920,"wires":[]},{"id":"dec6ae99.f1a6c","type":"function","z":"1e352319.d22d3d","name":"","func":"\ncontext.global.lasttweet = null;\n\nreturn {payload:context.global.lasttweet};","outputs":1,"noerr":0,"x":320,"y":970,"wires":[[]]}]