# Water reminder for plants using adafruit and webhook Linus Ingvarsson #Author li222fv The purpose of this project is to remind me when my plants need water, since I usually forget to and dont want to spend money on any prebuilt stuff that already exists. In this project I used Pycom fipy microcontroller with expansion board 3.0 as well as a capacitive soil moisture sensor. The sensor detects the amount of moisture in the soil and this data gets sent to adafruit. I connected the pycom with adafruit with Wifi and from adafruit i created a webhook, which created a bot that notifys and sends a message in discord when the plants needs water. The data collected can be seen in the adafruit dashbord. ## Time estimation Since this is quite a simple setup with only using one sensor which collects data it should not require that much time. * Get up and running with the pycom device should be quite quick, so around 1h-2h and that includes getting the device attached to expansionboard aswell as flash the device with micropython. * Getting connected to adafruit using Wifi from the fipy device 1h ## Objective This is my first project in IoT so my goal was to create a simple yet valuable project which can later on be scaled up with more sensors and data collected if so desired. It was not supposed to be a project that when completted would be thrown away since it actually solves one of my biggest problems at home, keeping my plants alive. Insights given by the project is how often my plants need water. By following this guide you will hopefully learn to setup a simple water reminder for your plants using IoT and adafruit with webhook. ## Material | Hardware | Price and link | | ----------------- |:----------------------- | | Pycom fipy | Neat microcontroller device which is the main device [640kr](https://pycom.io/product/fipy/) | | Expansion board 3.1 | Makes you able to connect to the computer as well as other features like being able to connect sensors [190kr](https://pycom.io/product/expansion-board-3-0/)| | Capacitive moisture sensor| Reads the amount of moisture in the soil [34kr](https://sizable.se/P.8AS66/Capacitive-Soil-Moisture-Sensor) | | Wires for connecting sensor to bredboard| You can never get enough of these [24kr](https://sizable.se/P.K2HUW/Dupont-kopplingskablar-Hane-Hane-40-pin)| | Bredboard | Makes connecting electrical components easier for development [34kr](https://sizable.se/P.SFGYT/Kopplingsdack-med-400-punkter) | | USB charger with a micro usb cable | Be aware that you need a data cable, if you get a charge only cable, you wont be able to transfer data. [[1]](https://www.dignited.com/50330/usb-data-cable-vs-usb-charging-cable/) [219kr](https://www.kjell.com/se/produkter/el-verktyg/laddare/usb-laddare/linocell-usb-laddare-med-micro-usb-kabel-24-a-svart-p95719) | ## Computer setup ### Hardware Connect the fipy device to the expansion board as shown in the figure below. When the fipy device is connected to expansion board, plug in a usb data cable which is located below the reset button and RBG LED. ![](https://i.imgur.com/3V2OAPB.png) [Fig 1](https://docs.pycom.io/gettingstarted/#step-1-setting-up-the-hardware) --- ### Flashing hardware To ensure your device is up to date it is recommended to get the latest firmware update. Pycom has detailed documentation provided how to do it, with all different operating systems included [firmware](https://docs.pycom.io/updatefirmware/device/) --- ### Chosen IDE enviroment You are free to choose the ide to your preferences, however in this tutorial i have choosen to work with Atom because it supports NodeJs and is a light weight texteditor which fits the scope of this project as well as supports all operating systems. Atom is from their official website avaliable [here](https://atom.io/) ![](https://i.imgur.com/U9N4qqk.png) --- Next you have to download pymakr, which is a package that connects your pycom device to atom so you can run code on the device. From the settings locate package and from there search for "pymakr" and install it. ![](https://i.imgur.com/qW8cWky.jpg) --- Open Atom and your device should automatically be detected, and if not use Connect device to get access to REPL.![](https://i.imgur.com/do2KA95.jpg) Create a new project and name the file main.py and test the code provided below. After running the code you should be able to see your device blink in red, green and blue. ``` import pycom import time pycom.heartbeat(False) #stops the on-board LED blinking blue while True: #colors in hexadecimal (0xRRGGBB) pycom.rgbled(0xFF0000) # Red time.sleep(1) pycom.rgbled(0x00FF00) # Green time.sleep(1) pycom.rgbled(0x0000FF) # Blue time.sleep(1) ``` :::info :bulb: **Hint:** Since its a forever loop you have to press *Ctrl-c* on your keyboard to break the loop. ::: ## Putting everything together When it comes to conneting the device and sensor, its a good rule of thumb to be consistent with the colors on the cables. So in this case, **black** cable is connected to ground (GND) and **red** cables for VCC. This will save you save from lots of headaches. Remember this is only for a development setup. **black** cable should be connected to the - on the breadboard and **red** cable to plus. the hardware has been connected on the breadboard like the figure shows below. ![](https://i.imgur.com/4GEy5AT.png) ## Platform My first choice was to try [pybytes](https://sso.pycom.io/login/?client_id=pycom&redirect_uri=https%3A%2F%2Fpyauth.pybytes.pycom.io%2Fauth_code%2Fcallback&scope=profile&response_type=code&state=pybytes-browser) which is a device management platform that makes you able to visualise data from the sensor with dashboards which is customisable. Other features include notifications about the devices status like battery level. However i stumbled across lots of issues while connecting to pybytes, I could not get the wifi connection working to the platform. This eventually after serverals tries ended with me switching platform to [adafruit](https://accounts.adafruit.com/users/sign_up). Adafruit is a plattform on the cloud and is primary used for retrieving data but also includes other features like: * Display data in real time, online * Make project internet connected: Control motors, read sensor data. * Connect projects to web services like twitter, RSS, feeds weather services etc. * Connect proejct to other internet-enbaled devices * Everything stated above is free. [[2]](https://learn.adafruit.com/welcome-to-adafruit-io/what-is-adafruit-io) ## Code There is three files contained in the project boot.py which contains code to conncet to the wifi, main.py with the main code and mqtt.py. **1. Connect to wifi** Code for connecting to wifi for fipy. Code below makes it possible to connect to your wifi. All you need to do is change the row with 'yourssid' and 'yourpassword' to your own creditals. I had issues connecting to my router since i connected to the network which consisted of 5ghz. When trying my other network the device was stuck on the old network and took a while to "kick out" the device. Make sure you connect to the right network (if you have two different SSIDs). :::info :bulb: **Hint:** Fipy only supports 2.4ghz, so makes sure that your router supports it. This means 5 ghz wont work when connecting. However most routers nowdays consists of both 5ghz and 2.4ghz. ::: ``` #boot.py from machine import WDT watchdog = WDT(timeout=600000) def do_connect(): from network import WLAN import time import pycom import machine pycom.wifi_mode_on_boot(WLAN.STA) # choose station mode on boot wlan = WLAN() # get current object, without changing the mode # Set STA on soft rest if machine.reset_cause() != machine.SOFT_RESET: wlan.init(mode=WLAN.STA) # Put modem on Station mode if not wlan.isconnected(): # Check if already connected print("Connecting to WiFi...") # Connect with your WiFi Credential wlan.connect('YourSSID', auth=(WLAN.WPA2, 'YourPassword')) # Check if it is connected otherwise wait while not wlan.isconnected(): pass print("Connected to Wifi") time.sleep_ms(500) # Print the IP assigned by router print('network config:', wlan.ifconfig(id=0)) def http_get(url = 'http://detectportal.firefox.com/'): import socket # Used by HTML get request import time # Used for delay _, _, host, path = url.split('/', 3) # Separate URL request addr = socket.getaddrinfo(host, 80)[0][-1] # Get IP address of host s = socket.socket() # Initialise the socket s.connect(addr) # Try connecting to host address # Send HTTP request to the host with specific path s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8')) time.sleep(1) # Sleep for a second rec_bytes = s.recv(10000) # Receve response print(rec_bytes) # Print the response s.close() # Close connection # WiFi Connection do_connect() # HTTP request http_get() ``` **2. Sensor connecting and reading** We start of by declaring which pin we are connecting to and afterwards we create an ADC object which will convert analog to digital and makes us able to read from the sensor. ``` #Capacitive soil moisture sensor SoilSensorPin = 'P13' # sensor connected to p13 SoilSensor = machine.Pin(SoilSensorPin, mode=Pin.IN) # pin mode to input adc = ADC(bits=10) #adc object bits 10 means 0-1024 apin = adc.channel(attn=ADC.ATTN_11DB, pin=SoilSensorPin) # create an analog pin on P13; attn=ADC.ATTN_11DB measures voltage from 0.1 to 3.3v ``` and to test and read the sensor value we can use the following code. ``` val = apin() # read an analog value ``` --- main.py consists of the following code, which connects us to adafruit. To connect to adafruit we use the protocool MQTT. The following imports are required. In mqtt.py we create a class MQTTClient, and we import this to main.py. ``` #main.py from machine import ADC, Pin import time # Allows use of time.sleep() for delays import pycom # Base library for Pycom devices from mqtt import MQTTClient # For use of MQTT protocol to talk to Adafruit IO import ubinascii # Needed to run any MicroPython code import machine # Interfaces with hardware components import micropython # Needed to run any MicroPython code ``` --- ## Transmitting the data / connectivity the data is sent every min to the website, however the webhook with a trigger only activates if the sensor exceds a certain value and the bot can only message every 15min. The wireless protocool used is wifi and transport protocool is MQTT and webhook. 1. Start with signing up on [adafruit](https://accounts.adafruit.com/users/sign_up) 3. Go to this [link](https://io.adafruit.com/) and sign in to get access to your control panel by clicking on IO in the navbar. You have to be signed in to get access. 3. navigate from your control panel to feeds and view all + new feed, to create a new feed. We will create two different feeds moisture: which will show the amount of moisture detected in the plant soil. waterplant: we will create a webhook, which will notify through discord when the plant needs water. ![](https://i.imgur.com/sBQM02F.jpg) Next we go to dashboard and create a new dashboard. In my case I named it IoT project. ![](https://i.imgur.com/FCioFza.jpg) in the dashboard pannel we create a new block. ![](https://i.imgur.com/x6MO89G.jpg) from there we can choice however we wanna present the data, i will choice linechart to see how the value changes. From there we connect this linechart to a feeds, which in this case is moisture. Go to next step. ![](https://i.imgur.com/lEfCpHZ.jpg) From there we get some settings to choose how we wanna present the data, if we wanna see history and so on. I will keep it on 24 hours. Now we have created a linechart connected to moisture feed. Next part we need to get our key, you do it from the yellow key icon in the right corner. ![](https://i.imgur.com/RMVZ1sb.jpg) The key under your username should be posted in the following row "Yourkey". aswell as username and feeds info. ``` # Adafruit IO (AIO) configuration AIO_SERVER = "io.adafruit.com" AIO_PORT = 1883 AIO_USER = "YourUserName" AIO_KEY = "YourKey" AIO_CLIENT_ID = ubinascii.hexlify(machine.unique_id()) # Can be anything AIO_CONTROL_FEED = "YourUserName/feeds/moisture" AIO_RANDOMS_FEED = "YourUserName/feeds/plant-iot-project" ``` The feeds info you get in the following way. Click on the feed moisture and in the top right corner feed info. ![](https://i.imgur.com/AZZnb2q.jpg) and from there, go to MQTT by key and copy and post in this variable. ``` AIO_CONTROL_FEED = "YourUserName/feeds/moisture" ``` the following row of code is how you subscribe to a feed in the code. ``` client.publish(topic=AIO_CONTROL_FEED, msg=str(val)) ``` --- Last part consists of making discord bot notify using webhook. 1. if you are not admin on a discord server already. Create a server in the following way. Click on the + to add a server. 2. Click on "create my own server" for me and my friends. 3. Name it like IoT project. 4. click on the settings tab as shown below ![](https://i.imgur.com/rcVG5aA.jpg) 5. go to integrations ![](https://i.imgur.com/PbpnlXE.jpg) 6. create a webhook ![](https://i.imgur.com/fdeejMd.jpg) 7. copy webhook-url and name the bot to captain plant or anything you feel like fits. ### Adafruit trigger Before we create a trigger we have to create a new feed for the bot. Create a feed named waterplant. And follow the steps before. --- 1. Next we go back to the website and click actions ![](https://i.imgur.com/8JI1oD3.jpg) 2. Create a new action and click on reactive action. 3. **If** waterplant 4. **Is** **comparsion value or feed** 50 5. **Then send a webhook message** 6. **To url** "post the url copied from discord from before" 7. **Waterplant** **value and time** 8. **Custom/saved template** 9. "Username": "Captain plant" This is name of the bot 10. "Content": "the plant needs water" Or whatever message you wanna send. 11. Limit every fifteen minutes. 12. And click create at the bottom ![](https://i.imgur.com/Voumq3H.jpg) ## Presenting the data The dashboard could look something like this. Data is saved every minute in the database website. You can decide if you wanna save history or not. "Turning history off for your feed will mean only the last value received is stored. History is on for all new feeds by default. While history is turned ON, feed data is limited to 1KB (1024 bytes) in size. While history is turned OFF, feed data is limited to 100KB (102400 bytes) in size." ![](https://i.imgur.com/plhp9AT.jpg) --- And the bot in my case look like this but can be customised depeneding on your preferences. ![](https://i.imgur.com/Xs8mamf.jpg) ## Finalizing the design Even tho there have been some problems on the row it worked out fine in the end. I would like to continue on connecting sensors and making more advanced actions with these in the future. Lots of my time was wasted on getting pybytes to work, which costs lots of valuable time. In the future, its better to switch platform quicker to have more time for more important parts. **Hopefully now my plants will survive.** ![](https://i.imgur.com/QUnPWRd.jpg)