In this continuation of my blog series (part 1 here), I’m sharing how I Internet of Things (IoT) enabled my gate, garage door and garden irrigation system using Azure IoT Hub, ESP32, IFTTT, .Net Core and much more.
My Garden Irrigation System
So not long after wiring up my gate and garage door to my IoT hardware, I was already thinking about what else I could enable and automate in and around my home. The usual ideas of wiring up some lights came first to mind, but it wouldn’t have been much different to my gate and garage setup, and I was looking to challenge myself with something that would test my know-how of IoT microcontrollers.
While I was jotting down some ideas, I remembered that I had forgotten to water my garden for a couple of days and things were looking very dry. It was then when it hit me! Why not IoT enable my Bluetooth garden irrigation system by making my ESP32, which has Bluetooth itself, talk to the garden irrigation control box?! That way, I could water my garden from anywhere without needing to be in the range of the control box or deal with the proprietary mobile app that is incredibly buggy! I could even trigger watering based off some recorded data like if the last five (5) days were hotter than usual, then water the garden for an extra five (5) minutes per station. With this new excitement, I immediately got to work.
Capturing BLE packets on my Android Phone
So to start, I first needed to capture the BLE calls my phone was sending and receiving to the garden irrigation control box. If I was to have any chance of replacing the mobile app with my ESP32 microcontroller, I first needed to know what the app does.
As I had a Samsung S9 phone, I first turned on developer mode and began capturing the HCI logs. I followed this guide and was able to get the logs into WireShark where I could start seeing the important parts that make up the Bluetooth client to server communication like Service UUID and the Characteristic UUID.
Not long after finding the right write characteristic, I could see the hexadecimal calls being made. Thankfully this write characteristic didn’t look to be based on a read value of something else, so the challenge was simplified a bit. This step, however, took a while, with lots of trial and error, calling to stop and start stations through my phones app so I could pick up the patterns in the captured logs. I could see numbers changing, but I wasn’t 100% sure what each hex was denoting.
At this point, I felt I had a chance of not making a bad write characteristic to the garden irrigation control box which could, though unlikely, scramble its brain. To test locally on my PC first before coding it on the ESP32, I ended up getting an app called Bluetooth LE Lab (GitHub). This app was great. I recommended it to anyone trying to reverse engineer Bluetooth calls that a smartphone app may be making.
I could start my garden watering from my PC. After some trial and error to figure out some of the other values, I concluded that there was a 10-byte hex value that made the garden irrigation control box do something. The breakdown of the value is:
- Turns off all the solenoids.
- 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00
- To run a station (open a solenoid)
- 01 (run)
- 00 (station 1, starting at 0)
- 13 (19 hrs in hex)
- 12 (18 mins in hex)
- 00 00 00 00 00 00 (used for scheduling a station at day/time, instead of immediately running it. Something that I wont use for now.)
To state the obvious because it would have been silly, I did not run a station for 19 hours and 18 minutes! This was just me testing.
Coding it up in the ESP32
When it came to coding this up, I learnt a very tough lesson about the importance of keeping your ESP32 sketch small, efficient and optimised as much as possible. It turns out the BLE library for ESP32 is quite big, and when trying to run it with WiFi, a WebServer and MQTT subscription and publishing to Azure IoT Hub, I was overflowing on the 4mb memory of the controller. To solve this, I had to change the memory partitions, but this meant that over the air (OTA) updates were now no longer possible; something that I would come to regret.
With a few changes to the webserver, I now had the irrigation controlled via this much simpler interface. As this webserver is only on the network, I also created a new subscriber in Azure IoT Hub as well so I could send a JSON payload that, would water each station for the number of minutes I requested.
The below diagram outlines the additions to my ESP32 setup, including the additional IFTTT request to allow Google Assistant to trigger my gardens watering.
In the next blog post for the series, I’ll share why and how I removed the webserver UI from the ESP32 and built a supporting .Net Core WebApp to interact with. Also, I’ll touch on how I further built out the automation of my gardens watering by pulling historical weather data from the Bureau of Meteorology to make decisions on how long to water my garden. Stay tuned!