Project in progress
Smart Garden - Alexa consults & automates your garden

Smart Garden - Alexa consults & automates your garden © GPL3+

How might we utilise smart water management systems to enhance our human experience for the people of today, and also tomorrow.

  • 1,040 views
  • 2 comments
  • 4 respects

Components and supplies

Apps and online services

About this project

Goal:

How might we utilise smart water management systems to enhance our human experience. This mission encapsulates not only the people of today, but also strives to benefit the lives of people of tomorrow - worldwide.

The Vision

This is not just a project. This is the start of a journey that aims to empower individuals to play their part in not only environmental sustainability in developed nations, but in developing smart water management systems to provide sustainable clean water to individuals in developing nations - working towards UN Sustainable Development Goals 6 & 13:

  • Goal 6: Clean Water & Sanitation.
  • Goal 13: Climate Action

This project aims to start the journey with a Smart Garden Management Tool which integrates data points such as real time Soil Moisture, the optimal soil moisture for different plants, and weather forecasts to consult home owners on when to turn on sprinklers and irrigation systems. However, it doesn't end their. After being consulted by our Smart Garden System, we are are able to activate the irrigation/sprinkler system through our voice to achieve optimal results. This solution allows for the ideal quantity of water being used to keep the garden at optimal health - reducing water wastage and environmental degradation. This is only the start.

Demo Video

Project Overview:

For the purpose of creating a smooth flow and ease of replication we will go through the project in a series of stages, in saying this, the guide will be written with the expectation that readers have a reasonable understanding of how the Internet of Things works including Sigfox, Arduino and Alexa.

Stage 1: Set up Accounts, Software & Hardware

Stage 2: Sigfox Integration

Stage 3: Develop a Garden Monitoring Device

Stage 4: Integrate Garden Data to AWS Cloud

Stage 5: Develop the Smart Solenoid Valve

Stage 6: Build Alexa Skill for Water Activation and Garden Consultation

Stage 1: Sigfox Integration

Here we will go through the set up of the project - with a focus on setting up accounts and software to ease the flow of our journey.

1.1 Sigfox & Device Registration

Throughout this project we use the Sigfox Network to take advantage of their ability to transmit low energy signals from the Arduino board to the cloud.

To set up an account follow the link: https://backend.sigfox.com/activate/thinxtra which should take you to a screen where you will need to choose the country - Australia (as seen in image below).

Next enter the Device Information which can be found in/on the package of your Thinxtra Kit.

Enter account details and hit *Subscribe* to complete the Sigfox account set up & device registration.

This will take you to the developer portal where you will be able to see your newly registered Device under the [Device] tab.

Run the demo app on your device and check that the messages are coming up on your Sigfox network.

Now you need to set up the Thinxtra development kit. Follow these guides to set up your Thinxtra device with your sigfox console https://www.thinxtra.com/xkit/#step-1

Stage 2: Setting up the Soil Moisture Reader

Now connect the soil moisture reader AO pins of the sensor expansion shield, then connect together the Arduino board and Thinxtra shield to the expansion shield like this. Upload this code to the Arduino board and check you are receiving messages on your sigfox console.

#include <dht.h>
#include <WISOL.h>
#include <Tsensors.h>
#include <Wire.h>
#include <math.h>
int temp;
int mositure;
Isigfox *Isigfox = new WISOL();
Tsensors *tSensors = new Tsensors();
typedef union{
   float number;
   uint8_t bytes[4];
} FLOATUNION_t;
typedef union{
   uint16_t number;
   uint8_t bytes[2];
} UINT16_t;
typedef union{
   int16_t number;
   uint8_t bytes[2];
} INT16_t;
int val = 0; //value for storing moisture value 
int soilPin = A0;//Declare a variable for the soil moisture sensor 
int soilPower = 7;//Variable for Soil moisture Power
void setup(){
 Serial.begin(9600);
 pinMode(soilPower, OUTPUT);//Set D7 as an OUTPUT
 digitalWrite(soilPower, LOW);//Set to LOW so no power is flowing through the sensor
 Isigfox->initSigfox();
 Isigfox->testComms();
// Init sensors on Thinxtra Module
 tSensors->initSensors();
 // Init an interruption on the button of the Xkit
 tSensors->setButton(buttonIR);
}
void loop()
{
static unsigned long dataTime=millis();
if(millis() >= dataTime)   //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
 {
 dataTime=millis()+600000;
 Send_Data();
 }
}
int readSoil()
{
   digitalWrite(soilPower, HIGH);//turn D7 "On"
   delay(10);//wait 10 milliseconds 
   val = analogRead(soilPin);//Read the SIG value form sensor 
   digitalWrite(soilPower, LOW);//turn D7 "Off"
   return val;//send current moisture value
}
int readTemp(){
 int temp = (tSensors->getTemp() * 100);
 return temp;
 }  
void Send_Pload(uint8_t *sendData, const uint8_t len) {
 recvMsg *RecvMsg;
 RecvMsg = (recvMsg *)malloc(sizeof(recvMsg));
 Isigfox->sendPayload(sendData, len, 0, RecvMsg);
 for (int i = 0; i < RecvMsg->len; i++) {
   Serial.print(RecvMsg->inData[i]);
 }
 Serial.println("");
 free(RecvMsg);
}
void Send_Data(){
 UINT16_t mositure, temp;
 mositure.number = (uint16_t)readSoil();
 Serial.println(mositure.number);
 temp.number = (uint16_t)readTemp();
 Serial.println(temp.number);
const uint8_t payloadSize = 4; //in bytes
//  byte* buf_str = (byte*) malloc (payloadSize);
 uint8_t buf_str[payloadSize];
 buf_str[0] = mositure.bytes[0];
 buf_str[1] = mositure.bytes[1];
 buf_str[2] = temp.bytes[0];
 buf_str[3] = temp.bytes[1];
Send_Pload(buf_str, payloadSize);
 }
void buttonIR(){
Send_Data();
Serial.print("Button Works");
}

Stage 3: Passing data from Sigfox to Dynamo Table

Re-upload the demo sketch to your Arduino Board and follow the Xkit with Amazon Web Services guide on https://www.thinxtra.com/xkit/#step-3

After following and completing this guide, re-upload the Soil Moisture Reader sketch and change the variables in the callback function of the Sigfox message to pass the soil moisture data, as well as changing the variables the Lambda function passes to the Dynamo Table. Make sure the Lambda function feeds the Dynamo Table the time as '100' in order to constantly overwrite the data, as well as tabling the Soil Moisture reading under the name 'moisture'.

Stage 4: Develop the Smart Solenoid Valve

You can create the Smart Solenoid valve by connecting the Arduino board, ESP8266 Wifi Module, Solenoid Valve and 1 Channel relay board like this.

Now follow this guide on how to set up your ESP8266 to connect to your wifi

https://learn.adafruit.com/adafruit-huzzah-esp8266-breakout/using-arduino-ide

Also you have to download and install MQTT libraries from https://learn.adafruit.com/mqtt-adafruit-io-and-you/arduino-plus-library-setup

Once you have set all this up, we have to create a IFTTT Applet to trigger the solenoid to turn on.

Stage 6: Build Alexa Skill for Water Activation and Garden Consultation

Create an Alexa Skill by following this simple guide https://developer.amazon.com/alexa-skills-kit/alexa-skill-quick-start-tutorial

When creating the Alexa Skill, add in this code to your Intent editor

{
 "languageModel": {
   "intents": [
     {
       "name": "activateSprinkler",
       "samples": [
         "water my grass",
         "activate sprinkler",
         "water my garden",
         "turn on sprinkler",
         "do what you need to do"
       ],
       "slots": []
     },
     {
       "name": "AMAZON.CancelIntent",
       "samples": []
     },
     {
       "name": "AMAZON.HelpIntent",
       "samples": []
     },
     {
       "name": "AMAZON.StopIntent",
       "samples": []
     },
     {
       "name": "gardenCheck",
       "samples": [
         "give me a garden briefing",
         "How is my grass",
         "check the grass",
         "check the garden",
         "does my grass need watering",
         "how is my garden",
         "give me a garden update"
       ],
       "slots": []
     }
   ],
   "invocationName": "my gardener"
 }
} 

Also, when creating the Lambda function, add this to your code

var callback;
var myRequest = 'Skill';
const AWSregion = 'us-east-1';  // us-east-1
const params = {
   TableName: '3E5ACD',
   Key:{ "deviceId": '3E5ACD', "time":	'100'}
};
// 2. Skill Code =======================================================================================================
const Alexa = require('alexa-sdk');
const AWS = require('aws-sdk');
AWS.config.update({
   region: AWSregion
});
exports.handler = function(event, context, callback) {
   var alexa = Alexa.handler(event, context);
   alexa.appId = '{Skill ID}';
   alexa.registerHandlers(handlers);
   alexa.execute();
};
const handlers = {
   'LaunchRequest': function () {
       this.response.speak('Welcome Alex, I am your personal garden assistant, what would you like to know?').listen('try again');
       this.emit(':responseReady');
   },
   'gardenCheck': function () {
       readDynamoItem(params, myResult=>{
           var speach = '';
           var moisture = myResult;
           if (moisture < 250){
               speach = "Your grass is currently very dry, it is advised to activate the sprinkler to ensure it stays healthy, would you like me to do something?"
               this.response.speak(speach).listen('try again');
           } else if (moisture > 450){
               speach = "Your grass is very wet and potentially flooded, it is advised to stay clear and consider checking on it's drainage"
               this.response.speak(speach);
           } else {
               speach = "Your grass is looking very well and healthy, no need to water it today"
               this.response.speak(speach);
           }
           this.emit(':responseReady');
       });
   },
    'activateSprinkler': function () {
   httpsGet(myRequest,  (myResult) => {
               this.response.speak('Turning on the sprinkler system for you now');
               this.emit(':responseReady');
           }
       );
   },
   'AMAZON.HelpIntent': function () {
       this.response.speak('Ask me how your pool is going').listen('try again');
       this.emit(':responseReady');
   },
   'AMAZON.CancelIntent': function () {
       this.response.speak('Goodbye!');
       this.emit(':responseReady');
   },
   'AMAZON.StopIntent': function () {
       this.response.speak('Goodbye!');
       this.emit(':responseReady');
   }
};
//    END of Intent Handlers {} ========================================================================================
// 3. Helper Function  =================================================================================================
function readDynamoItem(params, callback) {
   var AWS = require('aws-sdk');
   AWS.config.update({region: AWSregion});
   var docClient = new AWS.DynamoDB.DocumentClient();
   console.log('reading item from DynamoDB table');
   docClient.get(params, (err, data) => {
       if (err) {
           console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
       } else {
           console.log("GetItem succeeded:", JSON.stringify(data, null, 2));
var moisture = data.Item.moisture
           callback(moisture);  // this particular row has an attribute called message
       }
   });
}
var https = require('https');
function httpsGet(myData, callback) {
   var options = {
       host: 'maker.ifttt.com',
       port: 443,
       path: '/trigger/{Webhook Trigger Word}/with/key/{Webhook Key}',
       method: 'GET',
   };
   var req = https.request(options, res => {
       res.setEncoding('utf8');
       var returnData = "";
       res.on('data', chunk => {
           returnData = returnData + chunk;
       });
callback();
   });
   req.end();
}

Now you should have a working Alexa enabled sprinkler model, enjoy!

Code

Soil MoistureArduino
#include <dht.h>
#include <WISOL.h>
#include <Tsensors.h>
#include <Wire.h>
#include <math.h>

int temp;
int mositure;

Isigfox *Isigfox = new WISOL();
Tsensors *tSensors = new Tsensors();

typedef union{
    float number;
    uint8_t bytes[4];
} FLOATUNION_t;

typedef union{
    uint16_t number;
    uint8_t bytes[2];
} UINT16_t;

typedef union{
    int16_t number;
    uint8_t bytes[2];
} INT16_t;



int val = 0; //value for storing moisture value 
int soilPin = A0;//Declare a variable for the soil moisture sensor 
int soilPower = 7;//Variable for Soil moisture Power


void setup(){
  Serial.begin(9600);
  pinMode(soilPower, OUTPUT);//Set D7 as an OUTPUT
  digitalWrite(soilPower, LOW);//Set to LOW so no power is flowing through the sensor

  Isigfox->initSigfox();
  Isigfox->testComms();

// Init sensors on Thinxtra Module
  tSensors->initSensors();

  // Init an interruption on the button of the Xkit
  tSensors->setButton(buttonIR);

}

void loop()
{
static unsigned long dataTime=millis();
if(millis() >= dataTime)   //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
  {
  dataTime=millis()+600000;
  Send_Data();
  }
}

int readSoil()
{
    digitalWrite(soilPower, HIGH);//turn D7 "On"
    delay(10);//wait 10 milliseconds 
    val = analogRead(soilPin);//Read the SIG value form sensor 
    digitalWrite(soilPower, LOW);//turn D7 "Off"
    return val;//send current moisture value
}




int readTemp(){
  int temp = (tSensors->getTemp() * 100);
  return temp;
  }  
  



void Send_Pload(uint8_t *sendData, const uint8_t len) {
  recvMsg *RecvMsg;

  RecvMsg = (recvMsg *)malloc(sizeof(recvMsg));
  Isigfox->sendPayload(sendData, len, 0, RecvMsg);
  for (int i = 0; i < RecvMsg->len; i++) {
    Serial.print(RecvMsg->inData[i]);
  }
  Serial.println("");
  free(RecvMsg);
}

void Send_Data(){
  UINT16_t mositure, temp;

  mositure.number = (uint16_t)readSoil();
  Serial.println(mositure.number);
  temp.number = (uint16_t)readTemp();
  Serial.println(temp.number);

 

const uint8_t payloadSize = 4; //in bytes
//  byte* buf_str = (byte*) malloc (payloadSize);
  uint8_t buf_str[payloadSize];

  buf_str[0] = mositure.bytes[0];
  buf_str[1] = mositure.bytes[1];
  buf_str[2] = temp.bytes[0];
  buf_str[3] = temp.bytes[1];


  
  
Send_Pload(buf_str, payloadSize);
  
  }




void buttonIR(){
    
Send_Data();
Serial.print("Button Works");

}

Schematics

Thinxtra Kit
Devkit1 explosive  57621 1491599355 380 500 wi6gozpvu0

Comments

Similar projects you might like

Smart Pool: Alexa Controlled Pool Manager

Project tutorial by Benjamin Winiarski

  • 1,366 views
  • 2 comments
  • 7 respects

Animated Smart Light with Alexa and Arduino

Project tutorial by Bruno Portaluri

  • 4,514 views
  • 10 comments
  • 26 respects

Alexa Smart Power Strip with Temperature

Project tutorial by Muhammad Afzal

  • 1,203 views
  • 0 comments
  • 7 respects

Amazon Alexa / Arduino YÚN Smart Home Light Sample

Project showcase by Noctuvigilus

  • 3,448 views
  • 0 comments
  • 10 respects

Alexa BBQ/Kitchen Thermometer with IoT Arduino and e-Paper

Project tutorial by Roger Theriault

  • 2,387 views
  • 0 comments
  • 9 respects

Alexa Based Smart Home Monitoring

Project tutorial by Adithya TG

  • 22,237 views
  • 21 comments
  • 59 respects
Add projectSign up / Login