Solution #3: Automation
Estimated time: 20–30 minutes
You will want to complete the prior sections of this workshop before starting with this one.
You can use the nio Platform to completely automate the watering of your plant based on the soil moisture in the ground. In other words, you can enable your plant to ask nio directly for water when it is in need, and then allow nio to respond.
In the previous section, you were introduced to the concept of thresholds. Using that same 50% threshold, you can apply logic to your data stream of soil conditions.
A Filter block will split the signal depending if the soil moisture is above or below the threshold. These contextualized signals can then be used to create a command to turn irrigation systems on or off automatically.
After contextualizing the data and formatting a message, the Automation_1 service can then publish its on/off message back to the Plant_Simulator service to control the pump.
Configure the publisher:
- Double-click the ToIrrigationCommands Publisher block.
- Set the value of the Topic to
- Accept the block config to close the window.
The Automation_1 service subscribes to the soil moisture measurement coming from the Plant_Simulator service then publishes a signal with an irrigation command back to the Plant_Simulator service. This command mirrors the commands that you previously sent by toggling the button on the UI. In effect, you have connected the soil moisture readings to the irrigation system, and the moisture should not fall below 50%.
Test your service
- Water your plant to above 55% soil moisture and then turn off irrigation.
- Start the Automation_1 service.
- Watch the UI.
Notice how the irrigation automatically turns on when the soil moisture drops below 50%. Job done!
Not so fast…
Take a closer look at the system's behavior.
As you can see from this chart, off signals will repeatedly be sent to the irrigation pump for every soil moisture signal that is sent (every second) until the soil moisture drops below 50%. Once the soil moisture dips below that 50% threshold, an on signal will be sent to the pump until it reaches a soil moisture percent above 50%, and then an off command will be sent. Once the soil moisture dips below 50%, an on command will be sent to the irrigation pump. This pattern will repeat itself over and over, which is why the graph shows the soil moisture oscillating around the 50% threshold.
There are two main problems with this setup: your system is sending many extra repeated commands to the pump, then, when it nears the threshold, it cycles quickly between off and on, abusing the irrigation equipment and not irrigating the crops effectively. With nio, you can do better…
[warning] You're blowin' up!
If you successfully completed the Twilio extra credit, you may notice that you're receiving a lot of text messages right as the soil moisture percentage oscillates around your threshold. Feel free to stop the Threshold_Notification service if you'd like those text messages to stop.
Automation 2.0—avoid repetition, use stage change
A fundamental concept of building nio services is determining and using states of a stream to your advantage. You don't need to send an off command for every measurement received above 50%, or an on command for every signal below that limit. You only need to send a command when the measurement crosses a threshold; that is to say, the state of the moisture data has changed from being above the limit to below or vice versa.
Go back to your instance view and open the Automation_2 service.
This service is pretty straightforward. The Filter and dual Modifier blocks used in the previous service have been replaced with a StateChange block and a single Modifier block.
The StateChange block is configured with a state expression that will only pass a signal to the following Modifier block when the incoming signal's soil value crosses 50%. The signal output from the Modifier block contains the result of this state evaluation (i.e., is the soil moisture below 50%?) as a value of
False. That value also reflects the desired state of the irrigation pump. To apply that desired state to the pump, use a Modifier block to create a signal attribute
irrigate with a value equal to the current state. Therefore, nio will irrigate when the state is less than 50%.
Test the service:
- Turn off () the Automation_1 service.
- Water your plant to around 55% soil moisture and then turn off irrigation.
- Now start the Automation_2 service and watch the behavior on the UI.
This service eliminated many of the unnecessary signals, but the pump is still turning off and on excessively as the value oscillates around the 50% threshold.
Next, a smoother graph to lower the wear and tear on the valves, pumps, and everything else.
Automation 3.0—avoid oscillation, add a high threshold
More robust logic employs two thresholds—a high and low—to account for a lag, a concept known as hysteresis. The behavior you want here is to turn the irrigation on when the soil moisture drops below 50%, and leave it on until that moisture surpasses 90%. This more closely mimics how one would water the plant by hand, and will give you better results.
Go back to your instance view and open the Automation_3 service.
You'll see a StateChange block for each threshold, but with opposite filter evaluations on their outputs. By joining these filters at a third StateChange block, the resulting "compound" state will be
True when the soil measurement crosses below 50%, and will remain
True until it surpasses 90% when the state evaluation false changes to
Start the service:
- Stop the Automation_2 service.
- Start the Automation_3 service and take a look at the UI to see the irrigation behavior.
Each soil moisture measurement is evaluated against two thresholds, but the trick is that "compound" state where
True states are only set when the soil moisture is below 50%, and
False states are only set by measurements above 90%. The resulting logic can be applied not only to this irrigation problem, but to many other streams where stability is required in a noisy or otherwise dynamic data stream.
You did it! You went from manually watering your virtual plant to keep it alive, to a completely autonomous plant that relies on nio to water it when it's thirsty. Now you have a healthy plant, and much more free time on your hands to continue exploring nio!
Next, add weather to the mix using an external weather service.
Or, if you're ready to start building your own nio services: