<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sander Vanhove</title>
    <description>The latest articles on DEV Community by Sander Vanhove (@sandervanhove).</description>
    <link>https://dev.to/sandervanhove</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F615018%2Fb76e17dd-60da-45ec-b806-e9a84beb502b.jpeg</url>
      <title>DEV Community: Sander Vanhove</title>
      <link>https://dev.to/sandervanhove</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sandervanhove"/>
    <language>en</language>
    <item>
      <title>Building a #Growlab using Raspberry Pi &amp; Waylay</title>
      <dc:creator>Sander Vanhove</dc:creator>
      <pubDate>Tue, 25 May 2021 15:20:23 +0000</pubDate>
      <link>https://dev.to/sandervanhove/building-a-growlab-using-raspberry-pi-waylay-4dl9</link>
      <guid>https://dev.to/sandervanhove/building-a-growlab-using-raspberry-pi-waylay-4dl9</guid>
      <description>&lt;h1&gt;
  
  
  Intro
&lt;/h1&gt;

&lt;p&gt;Last month &lt;a href="https://twitter.com/alexellisuk" rel="noopener noreferrer"&gt;Alex Ellis&lt;/a&gt; was the &lt;a href="https://twitter.com/alexellisuk/status/1392920685308268548" rel="noopener noreferrer"&gt;lone nut&lt;/a&gt; who started the &lt;a href="https://growlab.dev/" rel="noopener noreferrer"&gt;#Growlab&lt;/a&gt; project. His idea was simple: grow your own vegetables while learning something new technology-wise.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h1&gt;
  
  
  Hardware
&lt;/h1&gt;

&lt;p&gt;My final setup looks like this:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1391665619616026624-923" src="https://platform.twitter.com/embed/Tweet.html?id=1391665619616026624"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1391665619616026624-923');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1391665619616026624&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;I'm using a:&lt;/p&gt;

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

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;It may not be the most beautiful setup, but like Alex said in &lt;a href="https://youtu.be/GE7kyi6kFJY?t=701" rel="noopener noreferrer"&gt;his talk about Growlab&lt;/a&gt;: "This is about making due".&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h1&gt;
  
  
  Software
&lt;/h1&gt;

&lt;p&gt;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 &lt;a href="https://github.com/SanderVanhove/plant-monitor" rel="noopener noreferrer"&gt;this Github repository&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Measurements
&lt;/h3&gt;

&lt;p&gt;Getting measurements from the sensors is very manufacturer specific. The Grove system has its own &lt;a href="https://github.com/Seeed-Studio/grove.py" rel="noopener noreferrer"&gt;grove.py&lt;/a&gt; python library that I am using in my &lt;a href="https://github.com/SanderVanhove/plant-monitor/blob/main/sensors.py" rel="noopener noreferrer"&gt;sensors.py&lt;/a&gt; code to return an object with this signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SensorReading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;humidity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;moisture&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Posting to Waylay
&lt;/h3&gt;

&lt;p&gt;Getting these measurement values into Waylay is not that hard from here on. The steps we want to take are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Resource&lt;/li&gt;
&lt;li&gt;Create a Webscript&lt;/li&gt;
&lt;li&gt;Send data to the Webscript&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  1. Create a Resource
&lt;/h4&gt;

&lt;p&gt;Resources are the base of the Waylay system, they represent physical devices or groups of them. Check out &lt;a href="https://www.youtube.com/watch?v=54E5gKpLCKc" rel="noopener noreferrer"&gt;this video tutorial&lt;/a&gt; to get a better grasp on what they are. Let's create a new one and name it &lt;code&gt;plant-monitor&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flp3dzf8b33i04bbvrich.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flp3dzf8b33i04bbvrich.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy that &lt;code&gt;Identifier&lt;/code&gt;, we'll need it in the next step.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Create a Webscripts
&lt;/h4&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Create a new Webscript in Waylay and paste this code, or something similar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// No body found&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Parse body if needed&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="cm"&gt;/*
    You can do some processing of the payload over here.
  */&lt;/span&gt;

  &lt;span class="c1"&gt;// Post values to our resource&lt;/span&gt;
  &lt;span class="nx"&gt;waylay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://data-io.waylay.io&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waylay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postSeries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resource-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to replace &lt;code&gt;'resource-id'&lt;/code&gt; with the &lt;code&gt;Identifier&lt;/code&gt; of your resource.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus points:&lt;/strong&gt; Send the id of your resource along in the payload. This way you can have multiple plant monitors running.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Send data to the Webscript
&lt;/h4&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1f6vz27r42vwsrwryxcg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1f6vz27r42vwsrwryxcg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;We can use this URL to &lt;code&gt;POST&lt;/code&gt; values to on our Raspberry like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asdict&lt;/span&gt;

&lt;span class="n"&gt;json_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;asdict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;webscript-url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again change the &lt;code&gt;"webscript-url"&lt;/code&gt; with your URL. Check out the &lt;a href="https://github.com/SanderVanhove/plant-monitor/blob/main/webscript.py" rel="noopener noreferrer"&gt;webscript.py&lt;/a&gt; file in my repo to see my full implementation that also does some error handling.&lt;/p&gt;

&lt;p&gt;I glossed over a bunch of things about taking pictures and storing them to Github, so please check out &lt;a href="https://github.com/SanderVanhove/plant-monitor" rel="noopener noreferrer"&gt;the Github repo&lt;/a&gt; if you want a more indepth view of my code. But these are the basic steps to get values into the Waylay system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing the data
&lt;/h2&gt;

&lt;p&gt;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 &lt;code&gt;data&lt;/code&gt; tab of our resource:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhhjfnj3z0tosqyyl6sa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhhjfnj3z0tosqyyl6sa.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you press &lt;code&gt;Explore&lt;/code&gt; next to one of the metrics, you are taken to the explorer view. You can learn more about the explorer view in &lt;a href="https://www.youtube.com/watch?v=_HtPEZeuZOM" rel="noopener noreferrer"&gt;this video tutorial&lt;/a&gt;. If you add the other metrics too, you have an overview of everything at once:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcz2588hfihje6e9gujhk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcz2588hfihje6e9gujhk.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Huray, we did it! 🥳&lt;/p&gt;

&lt;h2&gt;
  
  
  Dashboard
&lt;/h2&gt;

&lt;p&gt;Lastly I also created a &lt;a href="https://dashboard-io.waylay.io/public?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmdhbmlzYXRpb24iOiI2MDliYTE2MjRlMmEwNzQ4Mzk5YTIzZjkiLCJkYXNoYm9hcmRJZCI6IjYwOWJhYzA4NWEwOTc0NzExODdkODUxMiIsInJlc291cmNlSWQiOiIwMTg0ZDY3ZS01OGExLTQ3NjktYWFjZC03OWRlZjI5YzhjOGEiLCJyb2xlIjoicHVibGljIiwidXNlciI6IjYwOWJhOGQ0NGUyYTA3NWJmZDlhMjNmYyIsImRvbWFpbiI6ImlvLXRlc3Rpbmcud2F5bGF5LmlvIiwidGVuYW50IjoiNjY0MTc4NTctOWY0OS00YTgzLTkzMDctZTEyYWQ1ZmJkYTQ1IiwiaWF0IjoxNjIxNTg5ODI5LCJpc3MiOiJ3YXlsYXlEYXNoYm9hcmQifQ.QsGCf1r-1RZycpIIeJ3WIIpsjWkzMlmG3o8BzwEqF8k" rel="noopener noreferrer"&gt;little dashboard&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1394224807013666816-164" src="https://platform.twitter.com/embed/Tweet.html?id=1394224807013666816"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1394224807013666816-164');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1394224807013666816&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h1&gt;
  
  
  Further improvements
&lt;/h1&gt;

&lt;p&gt;There are so many ways to keep improving this project! I'll list a few here:&lt;/p&gt;

&lt;h4&gt;
  
  
  Automations
&lt;/h4&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h4&gt;
  
  
  Closing the loop
&lt;/h4&gt;

&lt;p&gt;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 🤔&lt;/p&gt;

&lt;h4&gt;
  
  
  MQTT
&lt;/h4&gt;

&lt;p&gt;Using a Webscript directly is easy to get started with, but using MQTT is the way to go in production environments.&lt;/p&gt;

&lt;h4&gt;
  
  
  ML
&lt;/h4&gt;

&lt;p&gt;You can do a lot of cool things with Machine Learning, some cool ideas that could be incorporated here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pubmed.ncbi.nlm.nih.gov/33353559/" rel="noopener noreferrer"&gt;Germination detection&lt;/a&gt;: detect whether the seeds have germinated so I can get a notification when they do.&lt;/li&gt;
&lt;li&gt;Bad leaf detection: determine if there are leafs going bad. &lt;a href="https://github.com/spMohanty/PlantVillage-Dataset/" rel="noopener noreferrer"&gt;This dataset&lt;/a&gt; could be used.&lt;/li&gt;
&lt;li&gt;Droop detection: see if the leafs are drooping, which is generally a bad sign.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More cool ML applications in agriculture can be found in &lt;a href="https://www.sciencedirect.com/science/article/pii/S2589004220310877#sectitle0030" rel="noopener noreferrer"&gt;this awesome paper&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I certainly had a lot of fun putting this together and I hope my plants will be able to survive this time 😅&lt;/p&gt;

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

&lt;p&gt;Hopefully this article got you on board with the &lt;a href="https://growlab.dev/" rel="noopener noreferrer"&gt;#Growlab&lt;/a&gt; project. You now certainly have a jumping off point for growing your own vegetables and learning some tech-skills on the way.&lt;/p&gt;

</description>
      <category>iot</category>
      <category>raspberrypi</category>
      <category>showdev</category>
      <category>python</category>
    </item>
    <item>
      <title>What does a Data Orchestration platform do?</title>
      <dc:creator>Sander Vanhove</dc:creator>
      <pubDate>Tue, 20 Apr 2021 10:11:53 +0000</pubDate>
      <link>https://dev.to/sandervanhove/what-does-a-data-orchestration-platform-do-1i40</link>
      <guid>https://dev.to/sandervanhove/what-does-a-data-orchestration-platform-do-1i40</guid>
      <description>&lt;p&gt;&lt;em&gt;Data Orchestration&lt;/em&gt; is becoming one of those buzzwords sales people like to throw around in pitch meetings. &lt;/p&gt;

&lt;p&gt;It is very important to understand that data orchestration is not just one &lt;em&gt;"thing"&lt;/em&gt;, but describes a whole process of how to handle data within a system.&lt;/p&gt;

&lt;p&gt;I identified 4 steps each data orchestration platform should support:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Data Ingestion
&lt;/h3&gt;

&lt;p&gt;Data has to get into the system one way or another. We all know how it goes: part of the data we need is on an SQL database somewhere, other data comes in via MQTT and the last part is only available in .txt logs. &lt;strong&gt;Data ingestion can be a mess.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first thing a Data Orchestration platform should be able to do is integrate with all these different sources so it is able to combine the data we need.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Data Processing
&lt;/h3&gt;

&lt;p&gt;Data is rarely in the right format when entering a system. Therefore we need a way for data to be &lt;strong&gt;combined, unpacked or decoded&lt;/strong&gt;. This step could also entail aggregation if we don't want to use all the data but just a higher order abstraction.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Making Decisions
&lt;/h3&gt;

&lt;p&gt;Now that the data is ready, it is time to make some decisions based on what we ingested. For this, the platform needs some way to &lt;strong&gt;create rules and automated workflows&lt;/strong&gt;. The cool platforms even have the ability to utilize AI or ML models and let those call the shots.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgeyhe9z163ya11mxehj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgeyhe9z163ya11mxehj.png" alt="A rule on top of data that is coming in."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Taking Actions
&lt;/h3&gt;

&lt;p&gt;Lastly it is time to take action! Based on the data and earlier decisions, the platform should be able to &lt;strong&gt;take actions in and outside of its own ecosystem&lt;/strong&gt;. This could go from throwing alarms to turning some physical device on/off or sending quarterly figures to a certain list of employees.&lt;/p&gt;

&lt;p&gt;The best of the best data orchestration platforms are flexible in each of these steps, making it a generally applicable solution. They let the developer integrate the system easily with other platforms and provides a way to quickly define new logic. But that is a topic for a whole other article.&lt;/p&gt;

&lt;p&gt;Want an example of a data orchestration platform that does these things right? Check out &lt;a href="https://www.waylay.io/products/waylay-io/product" rel="noopener noreferrer"&gt;Waylay IO&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>lowcode</category>
      <category>iot</category>
      <category>pipelines</category>
      <category>dataprocessing</category>
    </item>
  </channel>
</rss>
