Introduction & Use Case:
Today, Weโll build some automation (playbooks ๐) to swiftly address incidents when logged data values breach predefined thresholds. In this case, Iโd like automated alerts โ for when my plants are too hot ๐ฅ, too cold โ, or too thirsty ๐ง.
๐ Note: This follows up on a previous post where we built a Raspberry Pi based soil sensor and onboarded it to Azure IoT Hub, then sent that data to a Log Analytics Workspace, bypassing the endpoint bottleneck.
In this Post We Will:
- ๐ Build a Logic App to automate email alerting based on sensor readings ๐
- ๐ Get alerts for when our plants are too hot ๐ฅ, too cold โ, or too thirsty ๐ง
- ๐ Make the most of the free IoT Hub tier ๐ช
Hardware Setup:
See previous post for hardward setupโฆ
Get alerts for when our plants are too hot ๐ฅ, too cold โ, or too thirsty ๐ง
Youโll want to follow this setup for a quick win:
1. Recurrence
The first Action in our Logic App dictates how often it should run. Here we can see itโs configured to trigger every 4 hours.
2. Run
Retrieves a list of unique PepperName (hostname) values from a dataset named peppers that meet certain moisture and temperature conditions. Hereโs a high-level breakdown of what it does:
-
It starts by looking at the peppers dataset.
-
It then applies a filter to only include records where the Moisture or Temperature values (converted to decimal) fall outside of certain ranges.
-
These ranges are defined by the MoistureGreaterThan, MoistureLessThan, TempGreaterThan, and TempLessThan parameters.
-
Finally, it selects the distinct PepperName from the remaining data.
3. Parse
Hereโs a high-level summary:
-
The top-level element is an object.
-
This object has a property named value.
-
The value property is an array (indicated by โtypeโ: โarrayโ).
-
Each item in the value array is an object (indicated by โtypeโ: โobjectโ under items).
-
These objects have a property named PepperName, which is a string (indicated by โtypeโ: โstringโ).
-
The PepperName property is required for each object in the value array (indicated by the required array).
In simpler terms, this schema describes an object that contains an array of objects (value), each with a required string property (PepperName).
4. Initialize
high-level summary of what this step does:
-
It initializes a variable as part of a workflow.
-
The variable is named PeppersOutOfCondition and its type is array. Itโs intended to hold a list of peppers that meet certain conditions (too hot/cold etc.).
-
This step in the workflow is set to run after the prior step has succeeded.
-
The PeppersOutOfCondition variable is used to store the results from the previous step.
In simpler terms, this step is preparing an empty list (or array) named PeppersOutOfCondition to store data that will be used later in the workflow (peppers that are too hot/cold etc.)
5. For Each Loop 1 - Extract
High-level summary of what this next step does:
-
Itโs a Foreach loop, which is used to iterate over a collection of items. In this case, itโs iterating over the value array from the results of a previous step (Peppers that match or fail to match predefined conditions).
-
This Foreach loop is set to run after the previous Initialize step has succeeded.
This step is iterating over the results of a parsed JSON, extracting the PepperName from each item, and appending these names to an array named PeppersOutOfCondition. This happens after the PeppersOutOfCondition variable has been initialized.
6. Append Results to an Array
The action here is of type AppendToArrayVariable, which means it appends a value to an existing array variable that was initialized in a previous step in the workflow (step 4).
-
The array variable is named PeppersOutOfCondition.
-
The value being appended to the PeppersOutOfCondition array is the PepperName from each item in the Foreach loop in the previous step.
This action adds the name of each pepper that meets certain conditions (extracted in a previous step) to the PeppersOutOfCondition array. Thus, this array will contain a list of all peppers that are outside of the specified moisture and temperature conditions.
๐ This is how we can get more than one sensor transmitting across the same service bus and endpoint, and then โpeelโ them back out by hostname and throw them into an array to continue working with.
7. Foreach Loop 2 - Filter
This Foreach loop applies to or iterates over the value array from the results of the previous step:
8. Run Query
This Action starts by looking at the peppers dataset. It then filters the data to only include records where the PepperName matches a specific value using a KQL query.
Next, it applies another filter to only include records where the Moisture or Temperature values (converted to decimal) fall outside of certain ranges. These ranges are defined by the MoistureGreaterThan, MoistureLessThan, TempGreaterThan, and TempLessThan parameters.
Finally, it selects the top 1 record from the remaining data, ordered by PepperName.
๐ if youโre looking for a specific pepper that has moisture and temperature values outside of certain ranges, this is the query that will find it.
9. Foreach Loop 3 - Check Conditions with KQL
This third Foreach loop iterates over the value array from the result of the previous Run step.
10. Parse KQL Results
-
The action is of type ParseJson, which means itโs parsing a JSON string into a JSON object.
-
The JSON string to be parsed is provided by the items(โFor_each_-_KQL_Results_Check_Moisture_Conditionsโ) expression from the prior Foreach loop.
-
The schema defines the expected structure of the JSON object. Here itโs configured with the following properties: IngestionTime, Moisture, MoisturePercentageEstimate, PepperName, Temperature, and TimeGenerated.
-
The types of these properties are also defined (string for most properties and number for MoisturePercentageEstimate).
In simpler terms, this action is taking a JSON string from a previous step in the workflow, parsing it into a JSON object, and validating its structure against the defined schema.
11. Check Moisture Condition
The If action checks a condition based on the Moisture value from the parsed JSON result of each pepper.
If the Moisture is greater than a threshold (MoistureGreaterThan), or True as illustrated in the Logic App Designer view, it triggers the next Action in the workflow that corresponds with the True condition.
If the Moisture is less than the threshold (False) then trigger the next Action in the workflow corresponding with the False condition.
12. Send Email Action
This action checks the moisture condition for each pepper, and sendg an email alert if the moisture is too high or too low:
-
The Send_an_email_(V2)_-_High_Moisture action sends an email indicating high moisture. The email is sent to the address provided by the email parameter, and the email body includes the PepperName and Moisture values from the parsed JSON result.
-
If the Moisture is not greater than the MoistureGreaterThan threshold, it checks another condition where the Moisture is less than the MoistureLessThan threshold.
-
If this condition is met, it triggers the Send_an_email_(V2)_-_Low_Moisture action.
-
Similar to the high moisture email, it includes the PepperName and Moisture values in the email body.
๐ Make sure to connect your Send from email account when configuring the Send an email V2 action.
13. Re-iteratate for Temperature
Repeat steps 9 through 12, but for Temperature instead of Moisture
Sensor Thresholds:
Iโm growing a variety of peppers (jalapeno, sichuan, goat horn, etc.) so my thresholds are as follows for this sensor setup (you may want to adjust these based on the moisture requirements for what youโre trying to grow. Tomatoes usually need more water than peppers in my experience):
Humidity/Moisture Alerts:
<300 --> too dry
>800 --> too wet
Temperature Alerts:
<45 Degrees F --> too low
>90 Degress F --> too high
Conclusion:
Thanks for reading! With this configuration illustrated across the past few blog posts, you can now securely leverage the free Azure IoTHub to setup automated email alerting for multiple sensors simultaneously (bypassing the single service endpoint bottleneck) so your crop never goes cold โ, too hot ๐ฅ, or thirsty ๐ง, without breaking the bank! ๐ฐ
๐ฑ ๐ฟ What will you grow next? ๐ผ๐ป
In this Post We:
- ๐ Built a Logic App to automate email alerting based on sensor readings ๐
- ๐ Got alerts for when our plants are too hot ๐ฅ, too cold โ, or too thirsty ๐ง
- ๐ Made the most of the free IoT Hub tier ๐ช