As we get busier and busier working and improving ourselves, we end up having less time to take care of, let's say, things that demand less of our attention. This can include our plants, that have need not only for water, but also sunlight (in different intensities). We could create a habit to water the plants at a certain time, but is it really necessary? What if you shouldn't water the plant today, because the soil is already moist or because it will rain within one hour?
What it does
CoolPlant uses 4 sensors - soil moisture, air temperature, air humidity and light - to determine plant's current state, check these values against the optimal values for the plant's species, and if some action is necessary, such as the soil is dry so the user needs to water the plant, the app sends an e-mail to the user or users themselves can check the plant's current status on CoolPlant mobile app, that summarizes how the plant is doing.
When the app sends notification for the user to take an action, it also checks for precipitation, so users can decide whether water or not their gardens.
This app can also be extended to work in groups and cover a bigger area (e.g. a farm or community) making the benefits of saving water much broader.
How I built it
I used the ESP32 board to connect the sensors, since it supports (partially) Arduino, has built-in wifi, can be powered by battery and is cheap. The device sends data in JSON format to Amazon IOT, that receives it and forwards to Amazon Kinesis. I used Kinesis Firehose delivery streams to buffer this incoming data and save it periodically to an S3 bucket. Every time an S3 object is changed, an S3 event is fired and I could attach a AWS Lambda function to respond to it, sending an e-mail. In other words, every time CoolPlant has a good amount of data to process, a custom Java function is called, reflecting the scenario: "the plant is communicating and I should check expected/actual data and maybe take an action".
I also created an Android App to allow users to check up-to-date sensor data and weather conditions. For this kind of "consumer" (mobile app, web apps, third-parties, etc) I created an API using API Gateway by simply using another Java Lambda function I created with the goal of returning plant's current status.
The Core of the CoolPlant also uses a Weather API (wunderground) to give additional advice to the user.
Challenges I ran into
ESP32 and the temperature/humidity sensor did not work as expected, as the sensor very often returned NaN values, even after hours working fine. I added code there to retry reading the sensor's values for n times (and waiting 2 seconds between attempts) and this improved success rate. I also had to try many different wiring setups on the breadboard, from the first prototype when everything was tidy and small to the last prototype, when I became more pragmatic and just used long wires to make my life easier. During this period I also managed to burn the first board :)
In terms of programming, I wish I had more time to improve the solution, but at least I created some "TODO" comments in code to highlight changes I'd like to implement there, such as logging/metrics.
Accomplishments that I'm proud of
- Having the IOT device sending data in a reliable way
- Being able to get started with the AWS ecosystem, including AWS Lambda, API Gateway, S3 (+events), AWS IOT and Kinesis in a short time period
- Deploying my first app to Google Play Store
What I learned
What's next for Cool Plant
Create a serious database featuring plants and optimal values for temperature, soil moisture and sunlight. Refactor code to remove hardcoded values and make them configurable by end-users Improve user experience and mobile apps (including an iOS app) Additional sensors (e.g. pH)