Peter MaShin Ae Hong
Published © LGPL

Smart Plant IoT

Auto watering the plant and tracking plant's health through Helium and Microsoft Azure IoT.

AdvancedFull instructions provided24 hours7,572

Things used in this project

Story

Read more

Schematics

Helium Architecture

Helium architecture connects IoT Device directly to Azure IoT Hub
Helium arch agqcbqmlep

Code

Azure Function GET Request

C#
Restful call from calling /api/smartplant
#r "System.Configuration"
#r "System.Data"
#r "Newtonsoft.Json"
using System;
using System.Net;
using System.Configuration;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Text;
using Newtonsoft.Json;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
   log.Info("C# HTTP trigger function processed a request.");
var str = ConfigurationManager.ConnectionStrings["sqldb_connection"].ConnectionString;
using (SqlConnection conn = new SqlConnection(str))
   {
       conn.Open();
var text = "SELECT Top 100 Temperature, Moisture, UVLight from dbo.IoTData Order by DateCreated DESC";
       EventData ret = new EventData();
using (SqlCommand cmd = new SqlCommand(text, conn))
       {
           SqlDataReader reader = await cmd.ExecuteReaderAsync();
try
           {
while (reader.Read())
               {
                   ret.Temperature = (int)reader[0];
                   ret.Moisture = (int)reader[1];
                   ret.UVLight = (int)reader[1];
               }
           }
finally
           {
// Always call Close when done reading.
               reader.Close();
           }
var json = JsonConvert.SerializeObject(ret, Formatting.Indented);
return new HttpResponseMessage(HttpStatusCode.OK) 
           {
               Content = new StringContent(json, Encoding.UTF8, "application/json")
           };        
       }
   }
}
public class SmartPlant
{
    public float Temperature { get; set; }
    public float Moisture { get; set; }
    public float UVLight { get; set; }
}

Azure function data insert from IoT Hub

C#
Inserting data via Azure function
using System.Configuration;
using System.Data.SqlClient;
using System.Threading.Tasks;
public static async Task Run(string myIoTHubMessage, TraceWriter log)
{
 var map = myIoTHubMessage.Split('&').Select(x => x.Split('=')).ToDictionary(x => x[0], x => x[1]);
    String Type = map["Type"];
    String Confidence = map["Confidence"];
    log.Info(Type);
    log.Info(Confidence);
 var str = ConfigurationManager.ConnectionStrings["sqldb_connection"].ConnectionString;
 using (SqlConnection conn = new SqlConnection(str))
    {
        conn.Open();
 var text = "INSERT INTO dbo.IoTData (Type, Confidence) VALUES ('" + Type + "', " + Confidence + ");";
 using (SqlCommand cmd = new SqlCommand(text, conn))
        {
 // Execute the command and log the # rows affected.
 var rows = await cmd.ExecuteNonQueryAsync();
            log.Info($"{rows} rows were updated");
        }
    }
    log.Info($"C# IoT Hub trigger function processed a message: {myIoTHubMessage}");
}

Azure function shortcut

C#
directly inserting into AzureSQL
#r "System.Configuration"
#r "System.Data"

using System;
using System.Configuration;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Net;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{


    string Temperature = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "Temperature", true) == 0)
        .Value;

    string Moisture = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "Moisture", true) == 0)
        .Value;

    string UVLight = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "UVLight", true) == 0)
        .Value;

    if (Temperature == null || Moisture == null || UVLight == null)
    {
        // Get request body
        return req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body");
    }

    var str = ConfigurationManager.ConnectionStrings["sqldb_connection"].ConnectionString;
    
    using (SqlConnection conn = new SqlConnection(str))
    {
        conn.Open();
        var text = "INSERT INTO dbo.SmartPlant (Temperature, Moisture, UVLight) VALUES (" + Temperature + ", " + Moisture  + ", " + UVLight + ");";

        using (SqlCommand cmd = new SqlCommand(text, conn))
        {
            // Execute the command and log the # rows affected.
            var rows = await cmd.ExecuteNonQueryAsync();
            log.Info($"{rows} rows were updated");
        }
    }

    return req.CreateResponse(HttpStatusCode.OK, "Success");
}

Arduino code

Arduino
Arduino code for uploading the data as well as automatically watering the plant
#include "Arduino.h"
#include "Board.h"
#include "Helium.h"
#include "HeliumUtil.h"
#include <TH02_dev.h>
#include "Arduino.h"
#include "Wire.h"
#include <SeeedGrayOLED.h>
#include <avr/pgmspace.h>

#define CHANNEL_NAME "Azure IoT App"

Helium  helium(&atom_serial);
Channel channel(&helium);
int relay = 5;

void setDisplayToOriginalState()
{
  SeeedGrayOled.init(SSD1327);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(relay, OUTPUT);
  delay(150);
  /* Reset HP20x_dev */
  TH02.begin();
  delay(100);
  Serial.println("TH02_dev is available.\n");
  DBG_PRINTLN(F("Starting"));

  // Begin communication with the Helium Atom
  // The baud rate differs per supported board
  // and is configured in Board.h
  helium.begin(HELIUM_BAUD_RATE);

  // Connect the Atom to the Helium Network
  helium_connect(&helium);

  // Begin communicating with the channel. This should only need to
  // be done once. The HeliumUtil functions add simple retry logic
  // to re-create a channel if it disconnects.
  channel_create(&channel, CHANNEL_NAME);
  Wire.begin();
}

void loop() {

  //Sound Pollution
  int moisture = 0;
  for (int i = 0; i < 32; i++)
  {
    moisture += analogRead(A0);
  }

  int uvlight = 0;
  for (int i = 0; i < 32; i++)
  {
    uvlight += analogRead(A1);
  }

  float temper = TH02.ReadTemperature();
  float humidity = TH02.ReadHumidity();


  String dataString = "Moisture=" + String(moisture) + "&UVLight=" + String(uvlight) + "&Temperature=" + String(temper) + "&Humidity=" + String(humidity);
  char data[dataString.length()];
  dataString.toCharArray(data, dataString.length());
  channel_send(&channel, CHANNEL_NAME, data, strlen(data));
  Serial.println(data);

  setDisplayToOriginalState();
  SeeedGrayOled.clearDisplay();     //Clear Display.
  SeeedGrayOled.setNormalDisplay(); //Set Normal Display Mode
  SeeedGrayOled.setVerticalMode();  // Set to vertical mode for displaying text
  SeeedGrayOled.setTextXY(0, 0);          //Set the cursor to 0th line, 0th Column
  String moisturestring = "Moisture: " + String(moisture);
  char moibuffer[moisturestring.length()];
  moisturestring.toCharArray(moibuffer, moisturestring.length());
  SeeedGrayOled.putString(moibuffer);

  SeeedGrayOled.setTextXY(2, 0);
  String uvstring = "UVLight: " + String(uvlight);
  char uvbuffer[uvstring.length()];
  uvstring.toCharArray(uvbuffer, uvstring.length());
  SeeedGrayOled.putString(uvbuffer);

  SeeedGrayOled.setTextXY(4, 0);
  String temperaturestring = String(temper) + " C";
  char tempbuffer[temperaturestring.length()];
  temperaturestring.toCharArray(tempbuffer, temperaturestring.length());
  SeeedGrayOled.putString(tempbuffer);

  SeeedGrayOled.setTextXY(6, 0);
  String humidstring = "Humid: " + String(humidity);
  char humidbuffer[temperaturestring.length()];
  humidstring.toCharArray(humidbuffer, humidstring.length());
  SeeedGrayOled.putString(humidbuffer);

  if(moisture < 100)
  {
    digitalWrite(relay, HIGH);
    delay(5000);
    digitalWrite(relay, LOW);
  }
  delay(60000);
}

Project repo

Project repo for netduino smart plant

Credits

Peter Ma

Peter Ma

22 projects • 97 followers
Prototype Hacker, Intel Software Innovator, Hackathon Goer, World Traveler, Ecological balancer, integrationist, technologist, futurist.
Shin Ae Hong

Shin Ae Hong

3 projects • 9 followers
Global Startup Incubation Specialist @Innoway

Comments