Plant control with Slang

See how Slang can be used to monitor a plant with IoT devices to ensure it feels well.

To demonstrate how Slang interacts with IoT (Internet of Things) devices we will build a small demonstration
plant control system which monitors temperature, humidity and
soil moisture.
You will also see how rules can be defined and sensor data processing can be achieved with Slang.
In a future post we will look at how to get notified by email when you should worry about your plant.

What we need

To gather information and send it to our Slang operator, we need a device capable of transmitting data to our Slang
operator via WiFi.
We recommend NodeMCU for that.
It is only a few euros and has everything you need to get you started, especially WiFi capabilities.
Also most Arduino sensors work with it because NodeMCU is Arduino compatible.

We need a moisture sensor and a humidity and temperature sensor.
These are typical sensors to start experimenting with IoT.
To have some direct feedback from our devices we use two RGB LEDs.

All of these items are pretty standard. We bought ours from
AZ-Delivery but you can get them from many other places as
well of course.

IoT accessories we will be using

Our lab rat, err plant

So what do we want to do exactly?
The goal is to monitor temperature, humidity and soil moisture of our plant.
We want to log these values and run some analysis on them later.

Our lucky plant is a coffee plant that decorates our office since we moved in here in July last year.
We do not have a 'green thumb' to put it mildly.
So hopefully it won't have to suffer in the future.
And maybe we can even drink self-cultivated coffee someday?

A coffee plant decorating our Bitspark office

The DHT11 sensor

The DHT11 sensor is a very cheap and unfortunately not very precise sensor.
For our purpose however it is completely sufficient.

We connect the signal pin with D3 of our NodeMCU and the RGB pins of the LED with D5,
D6 and D7, respectively.
Of course, you also need to connect GND and Vin (see picture below).

A NodeMCU (middle) connected with a DHT11 (left) sensor and an RGB LED (right)

Closeup of the DHT11 sensor module

Closeup of the NodeMCU connected with the DHT11 sensor and RGB LED

Closeup of the RGB LED

Of course we need to program the NodeMCU so that they know what to do.
We want them to connect to our office WiFi and an MQTT broker running on a computer.
We will replace it with a Raspberry Pi in a future blog post, but for now it is sufficient to show the basic idea.

We have created a GitHub repository containing the code for both sensors.
You find the repository for the DHT11 sensor here:
Bitspark/example-iot-dht11
We will only explain the crucial parts of it here.

This is a part of the loop function which is being executed over and over again until the device is
shutdown or put into sleep.
As you can see, we measure every 10 seconds with dht.readTemperature and dht.readHumidity
and indicate a measurement with the blue LED.
The LED functions ledOn, ledOn and ledOff are custom functions implemented in
a
different file.
You also find it in the GitHub repository.

After the measurement, we need to check if it was successful.
The DHT sensor uses a serial transmission which can fail sometimes - especially with our cheap DHT11 sensor.
We do that with isnan.
If it was successful, we switch on the green LED, otherwise we switch on the red LED.

The moisture sensor

The moisture sensor can be run in digital and analog mode.
When running in digital mode, you can use the potentiometer to specify a threshold when it should output
1.
We will be using the sensor in analog mode, which allows the NodeMCU to read a value between 0 and
1024.
It uses an analog-digital converter that is connected with the A0 pin (analog pin).

We connect the analog signal pin with A0 of our NodeMCU and the LEDs like we did with the DHT11 sensor
(see picture below).

A NodeMCU (middle) connected with a moisture sensor (left) and an RGB LED (right)

Closeup of the moisture sensor module (without probe)

Closeup of the NodeMCU connected with the moisture sensor and RGB LED

Closeup of the RGB LED

The code for our moisture sensor is very similar.
The only difference is that we use analogRead to read a value between 0 and
1024 from our analog pin.
You find the code on GitHub as well:
Bitspark/example-iot-moisture

Slang and MQTT

Now that we can measure the values we only need some logic which makes our system behave the way we want.
And that's when Slang comes into play!
Just to remind you, we want to log these values and keep them for later analysis.

First, you will need an MQTT broker.
Its task is to keep track of all MQTT devices that have subscribed to it.
Subscribe means that a device has signalled the broker that it is interested in messages of a certain topic.
A topic is hierarchical and looks a bit like an HTTP path.
/bitspark/room1 could be a topic all devices in room 1 of the Bitspark office push their messages to.
/bitspark/room1/window/temperature could be the topic a thermostat at the window pushes its messages
to.
You can even use special character such as # or * as wildcards.
Here is a good explanation on topics if you
want to dive a bit deeper.

For this example, we use Mosquitto.
It has everything you need and runs on most machines.

Slang has MQTT support already built in.
There is an MQTTSubscribe and MQTTPublish operator
which will subscribe or publish to a topic at your MQTT broker.
From the broker's perspective there is no difference between a Slang MQTT operator and a true physical device
connected to it.

Gather sensor data with Slang

We need to collect all data until we have enough to run some analyses on them.
For that, we can use the Insert (file) operator.
It takes arbitrary values and stores them in a file.

Plant control operator created with Slang gathering sensor data

MQTTSubscribe operator form

Split operator form

Before we have a look at what's going on there, let us go through some questions first.

What are operators exactly?

In Slang, operators are small worker units that perform a certain task.
They take data (usually arriving at the top) and emit data (usually at the bottom).
And they all run in parallel!

How many operators are there?

The answer to that question changes every day.
There is a growing number of operators.
We write many of them, but every Slang user can create their own.

How are Slang operators created?

There's two possibilities.
Most of them are built with... operators.
Existing operators can be combined by connecting them to form a new operator.
You can built almost anything just by combining and nesting existing operators.
But of course there has to be something like 'atomic' operators.
These are called elementary operators in Slang and perform very rudimentary tasks.
The Split operator for example takes a string and splits it into multiple strings
at a separator you can specify (see last screenshot above).

How do connections work?

Connections in Slang are channels with a capacity.
That means, if the operator the data is dedicated for has not finished its previous task yet, the value will still
be put into the channel.
That enables us to keep running everything at maximum speed without having operators wait for other operators to
finish.

Now back to our example plant control operator.
So what is happening there?
First, let's follow the left flow.
A gray 'trigger' is connected with MQTTSubscribe.
This causes the operator to start upon starting the surrounding plant control operator.
It will emit one item each time it receives a message from the MQTT broker specified via the form you can see
in the second screenshot.

It subscribes at the topic where our DHT sensor pushed temperature and humidity to.
Unfortunately what arrives is a string of the form "<temperature> <humidity>".
So we somehow need to extract temperature and humidity therefrom.

This can be done with the above-mentioned Split operator.
We need to specify the separator as " " (a space).
It will emit two values per string it receives provided it is of said form.

But we do not want to store these two values as separate values in our database.
We don't want to lose the information that they were measured at the same time.
So what we do is take a Parallelize operator which collects two values and emits
one combined item.

And finally these values can be stored with the file-based database operator Insert.

The right flow is much simpler because the data is already in the right form.
We just need to convert the string into a number.

These conversions might seem a bit confusing right now.
They don't really add much to the logic of an operator you build.
But they are necessary to ensure the usage of correct types.
We don't want to go too deep here and keep that topic for a following post.
We are also working on a solution that deals with conversions automatically to further reduce complexity without
losing the advantages of a typed system.

Setting up the sensors

Our Slang operator is now ready and waiting for data it can gobble up.
So we will set up the sensors now.

We stick the moisture sensor in the soil close to the rim since we don't want to hurt any roots.
The DHT sensor will be fastened to the pot as well so that it doesn't move and provides comparable measurements.
Finally, we connect the batteries.

The sensors are put in place

The DHT sensor does not always produce readable data

The moisture sensor is a bit more robust

The result

After some time, we find several entries in our database files.
We can use a plugin providing graphs directly from Slang Studio.
To see if our moisture sensor works, we have watered the coffee plant at about the middle of our measurement series.

As you can see, the moisture was indeed correctly detected as higher after watering the plant (lower means more
moisture).

So much for part 1, we hope you enjoyed it.
If you have questions don't hesitate to contact us via the contact form.
In the next part we will do some more with Slang operators and add alarm features to our plant control operator.
Maybe our coffee plant has even grown a bit bigger until then :)

Subscribe to our newsletter.

We are building solutions that help bridge the gap between human thinking and computer language.