Building a #Growlab using Raspberry Pi & Waylay
Tags: iot, raspberrypi, showdev, python
Published: 2021-05-25 15:20:23

# Intro

Last month [Alex Ellis](https://twitter.com/alexellisuk) was the [lone nut](https://twitter.com/alexellisuk/status/1392920685308268548) who started the [#Growlab](https://growlab.dev/) project. His idea was simple: grow your own vegetables while learning something new technology-wise.

When he showed me the project I really wanted to participate, so I bought some sensors, dusted of my old Raspberry Pi and got to creating my setup.

# Hardware

My final setup looks like this:

{% twitter 1391665619616026624 %}

I'm using a:

* Raspberry Pi 3b+, but you could definitely run everything on a less powerful device like a Raspberry Zero.
* Raspberry Camera v2
* Grove Moisture sensor
* Grove Temperature/Humidity sensor
* Grove Light sensor
* Grove 16x2 Display
* Grove Base Hat to connect all the Grove components

Everything is build into an IKEA rack I had standing around. I had to find a home for the stuff it was housing, but it's a nice frame. Then I just cut some wood to the right dimensions and zip-tied everything together.

It may not be the most beautiful setup, but like Alex said in [his talk about Growlab](https://youtu.be/GE7kyi6kFJY?t=701): "This is about making due".

No matter what hardware or sensors you are using, the growlab project is about creating and learning something and not so much about exactly copying what others are doing.

# Software

I'm only going to cover the link to Waylay here, else this article would get way to long. But you are invited to check out my complete code solution on [this Github repository](https://github.com/SanderVanhove/plant-monitor).

### Measurements

Getting measurements from the sensors is very manufacturer specific. The Grove system has its own [grove.py](https://github.com/Seeed-Studio/grove.py) python library that I am using in my [sensors.py](https://github.com/SanderVanhove/plant-monitor/blob/main/sensors.py) code to return an object with this signature:

```python
@dataclass
class SensorReading:
    light: float
    temperature: float
    humidity: float
    moisture: float
```

### Posting to Waylay

Getting these measurement values into Waylay is not that hard from here on. The steps we want to take are:

1. Create a Resource
2. Create a Webscript
3. Send data to the Webscript

#### 1. Create a Resource

Resources are the base of the Waylay system, they represent physical devices or groups of them. Check out [this video tutorial](https://www.youtube.com/watch?v=54E5gKpLCKc) to get a better grasp on what they are. Let's create a new one and name it `plant-monitor`:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lp3dzf8b33i04bbvrich.png)

Copy that `Identifier`, we'll need it in the next step.

#### 2. Create a Webscripts

Webscripts are lambda functions within the Waylay system. We first send the data to one of these because it is able to process the data before storing it to a resource. Now when I want to change some processing of the data (for example dividing the humidity by 100 so it is a value from 0 to 1 instead of 0 to 100), I can change the webscript in a nice UI environment instead of having to ssh into my Raspberry Pi.

I will be sending to a Webscript directly because that is easiest way to get started. If you want to build out a bigger use case or to run something in production, MQTT is probably the better option. A Webscript can still be used after data is ingested by MQTT.

Create a new Webscript in Waylay and paste this code, or something similar:

```javascript
async function handleRequest (req, res) {
  if (!req.body) {
    // No body found
    return
  }

  // Parse body if needed
  let payload = req.body
  if (typeof payload === 'string' || payload instanceof String)
    payload = JSON.parse(payload)

  /*
    You can do some processing of the payload over here.
  */

  // Post values to our resource
  waylay.data.baseUrl = 'https://data-io.waylay.io'
  await waylay.data.postSeries('resource-id', payload, { store: true, forward: true })
    .catch(e => console.error(e.message))

  res.sendStatus(200)
}
```

Don't forget to replace `'resource-id'` with the `Identifier` of your resource.

**Bonus points:** Send the id of your resource along in the payload. This way you can have multiple plant monitors running.

#### 3. Send data to the Webscript

Now all we have to do is send the metric values from our Raspberry Pi to that Webscript. First copy the Webscript's link by clicking on the URL underneath its name:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1f6vz27r42vwsrwryxcg.png)

If your Webscript is private (which it is by default), this copied URL also includes the secret token to authenticate, so we don't have to do any more auth in the code.

We can use this URL to `POST` values to on our Raspberry like this:

```python
from requests import post
from dataclasses import asdict

json_data = asdict(data)
request = post("webscript-url", json=json_data)
```

Again change the `"webscript-url"` with your URL. Check out the [webscript.py](https://github.com/SanderVanhove/plant-monitor/blob/main/webscript.py) file in my repo to see my full implementation that also does some error handling.

I glossed over a bunch of things about taking pictures and storing them to Github, so please check out [the Github repo](https://github.com/SanderVanhove/plant-monitor) if you want a more indepth view of my code. But these are the basic steps to get values into the Waylay system.

## Viewing the data

Now that everything is set up we can start pushing data from the Raspberry Pi. We should be able to see this data coming in under the `data` tab of our resource:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rhhjfnj3z0tosqyyl6sa.png)

If you press `Explore` next to one of the metrics, you are taken to the explorer view. You can learn more about the explorer view in [this video tutorial](https://www.youtube.com/watch?v=_HtPEZeuZOM). If you add the other metrics too, you have an overview of everything at once:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cz2588hfihje6e9gujhk.png)

Huray, we did it! 🥳

## Dashboard

Lastly I also created a [little dashboard](https://dashboard-io.waylay.io/public?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmdhbmlzYXRpb24iOiI2MDliYTE2MjRlMmEwNzQ4Mzk5YTIzZjkiLCJkYXNoYm9hcmRJZCI6IjYwOWJhYzA4NWEwOTc0NzExODdkODUxMiIsInJlc291cmNlSWQiOiIwMTg0ZDY3ZS01OGExLTQ3NjktYWFjZC03OWRlZjI5YzhjOGEiLCJyb2xlIjoicHVibGljIiwidXNlciI6IjYwOWJhOGQ0NGUyYTA3NWJmZDlhMjNmYyIsImRvbWFpbiI6ImlvLXRlc3Rpbmcud2F5bGF5LmlvIiwidGVuYW50IjoiNjY0MTc4NTctOWY0OS00YTgzLTkzMDctZTEyYWQ1ZmJkYTQ1IiwiaWF0IjoxNjIxNTg5ODI5LCJpc3MiOiJ3YXlsYXlEYXNoYm9hcmQifQ.QsGCf1r-1RZycpIIeJ3WIIpsjWkzMlmG3o8BzwEqF8k) that quickly gives me the stats of my plants. As this article is already getting quite long I'll leave explaining this for another time.

{% twitter 1394224807013666816 %}

# Further improvements

There are so many ways to keep improving this project! I'll list a few here:

#### Automations

There are no automations being done for the moment. I just have the monitoring and dashboard set up. I could have some automated alarms firing when conditions are not ideal for the little plants.

#### Closing the loop

At the moment I'm only monitor the plant, but it would be so much more interesting if I could close the loop and also water the plant using a little pump. Then I need a sensor that measures the water level in the reservoir too 🤔

#### MQTT

Using a Webscript directly is easy to get started with, but using MQTT is the way to go in production environments.

#### ML

You can do a lot of cool things with Machine Learning, some cool ideas that could be incorporated here:

* [Germination detection](https://pubmed.ncbi.nlm.nih.gov/33353559/): detect whether the seeds have germinated so I can get a notification when they do.
* Bad leaf detection: determine if there are leafs going bad. [This dataset](https://github.com/spMohanty/PlantVillage-Dataset/) could be used.
* Droop detection: see if the leafs are drooping, which is generally a bad sign.

More cool ML applications in agriculture can be found in [this awesome paper](https://www.sciencedirect.com/science/article/pii/S2589004220310877#sectitle0030).

# Conclusion

I certainly had a lot of fun putting this together and I hope my plants will be able to survive this time 😅

Again, this project is not about exactly copying what others are doing, but making due with what you have and just starting to experiment!

Hopefully this article got you on board with the [#Growlab](https://growlab.dev/) project. You now certainly have a jumping off point for growing your own vegetables and learning some tech-skills on the way.