ArduinoYun_Angular_TemperatureTembooGmailBig

HTML5, Arduino YUN and Temboo API:
get temperature in JSON format and send it to GMail

GOALS:

1) configure an Arduino YUN to accept REST calls from HTML5 apps.

2) get the current temperature from Arduino using an LM35 sensor and return the value to the HTML5 app in JSON format through a PHP proxy.

3) Send the temperature to your GMail address using the Temboo API

SUMMARY

We’ll create a simple HTML5 application (in AngularJS) that contains two buttons:

1) the first one makes a REST call to get and print the currrent temperature from the board in JSON format

2) the second button will be used to send the temperature by mail from your GMAIL account. Furthermore a LED on the board will be set to ON when the email is completely sent

The application works in a local network from desktop and mobile devices.

Watch the video to see it in action:

ARDUINO CIRCUIT LM35 SENSOR WITH GMAIL LED!

TemperatureTM35_Circuit

ARDUINO SKETCH

1. First we need to enable our Arduino YUN to accept REST calls using the following YUN libraries: Bridge, YunServer and YunClient
Read my previous article for more info.

#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>

void setup() {
  Bridge.begin();
  server.listenOnLocalhost();
  server.begin();
...
}

void loop()
{
  YunClient client = server.accept();
	...
}

2. Then we parse the url in order to accept two different calls:
a) http://YOUR_ARDUINO_IP/arduino/getTemp:
returns a JSON with the current temperature in Celsius {temperature: 26}

b) http://YOUR_IP/arduino/sendTemp: send an email with the temperature to a GMAIL account using the Temboo Api:


void process(YunClient client) {

  String command = client.readStringUntil('\r');

  // Check if url is http://YOUR_IP/arduino/getTemp
  if (command == "getTemp") {

      getTemperature();

      // Return a JSON with the temperature  {temperature: 26}
      client.println("Status: 200");
      client.println("Content-type: application/json; charset=utf-8");
      client.println(); //mandatory blank line
      client.print("{\"temperature\": " + String(tempC) + "}");

  }

  // Check if url is http://YOUR_IP/arduino/sendTemp
  if (command == "sendTemp") {
      digitalWrite(LED_PIN, LOW);   // Set lef off
      sending = true;
      getTemperature();
      sendMail();
  }

}

3) Following the script I have used to get the temperature from a LM35 sensor and to create the body message for the email.
Source: http://playground.arduino.cc/Main/LM35HigherResolution

void getTemperature() {
   int tempValue = analogRead(0);
   tempC = tempValue / 9.31;
   bodyMsg = String("Temperature is ") + tempC;
}

4) The sendMail() function uses the Temboo GMail->SendEmail API to send an email to your account. You can see the whole script below.

WHAT’S TEMBOO?
A set of cool API that work with Arduino making it simple to connect a vast array of web-based resources and services such as Gmail, Twitter, Facebook and so on. https://www.temboo.com/arduino

5) We turn ON a led on Arduino board and we display an alert on the HTML5 app when the email is successfully sent.

Here the complete sketch for the Arduino YUN:

#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
#include <Temboo.h>
#include "TembooAccount.h" // contains Temboo account information

YunServer server;

// led pin notification email sent
int LED_PIN = 5;

// Temperature values
long tempC = 0;

// Email body msg
String bodyMsg = "";

// sending = true, while sending emails :) 
boolean sending = false; // a flag to indicate whether we've sent the email yet or not

// your Gmail username, formatted as a complete email address, eg "bob.smith@gmail.com"
const String GMAIL_USER_NAME = "YOUR_ADDRESS@gmail.com";

// your Gmail password
const String GMAIL_PASSWORD = "GMAIL_PASS";

// the email address you want to send the email to, eg "jane.doe@temboo.com"
const String TO_EMAIL_ADDRESS = "DESTINATION_ADDRESS";

  void setup() {
  Serial.begin(9600);
  pinMode(0, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);

  // Use Bridge to access pins on the board through REST calls
  // more info: http://arduino.cc/en/Guide/ArduinoYun
  Bridge.begin();
  server.listenOnLocalhost();
  server.begin();
}

void loop()
{

  YunClient client = server.accept();

  //Process Client Requests
  if (client) {
    process(client);
    client.stop();
  }

  delay(15);

}

void process(YunClient client) {

  String command = client.readStringUntil('\r');

  // Check if url is http://YOUR_IP/arduino/getTemp
  if (command == "getTemp") {

      getTemperature(); // Get temperature

      // Return a JSON with the temperature  {temperature: 26}
      client.println("Status: 200");
      client.println("Content-type: application/json; charset=utf-8");
      client.println(); //mandatory blank line
      client.print("{\"temperature\": " + String(tempC) + "}");

  }

  // Check if url is http://YOUR_IP/arduino/sendTemp
  if (command == "sendTemp") {
      digitalWrite(LED_PIN, LOW);   // Set lef off
      sending = true;
      getTemperature();
      sendMail();
  }

}

/**
 * Get temperature and convert in Celsius (LM35 SENSOR
 * NOTE: Probably the following way to get the temperature is not so accurate
 * Source: http://playground.arduino.cc/Main/LM35HigherResolution
 */
void getTemperature() {
   int tempValue = analogRead(0);
   tempC = tempValue / 9.31;
   bodyMsg = String("Temperature is ") + tempC;
}

/**
 * Send email to your GMAIL account using a  Temboo API
 * NOTE: this script is completely copied from https://www.temboo.com/arduino/send-an-email
 */
void sendMail() {

    Serial.println("Sending Email...");

    TembooChoreo SendEmailChoreo;

    // invoke the Temboo client
    // NOTE that the client must be reinvoked, and repopulated with
    // appropriate arguments, each time its run() method is called.
    SendEmailChoreo.begin();

    // set Temboo account credentials
    SendEmailChoreo.setAccountName(TEMBOO_ACCOUNT);
    SendEmailChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME);
    SendEmailChoreo.setAppKey(TEMBOO_APP_KEY);

    // identify the Temboo Library choreo to run (Google > Gmail > SendEmail)
    SendEmailChoreo.setChoreo("/Library/Google/Gmail/SendEmail");

    // set the required choreo inputs
    // see https://www.temboo.com/library/Library/Google/Gmail/SendEmail/
    // for complete details about the inputs for this Choreo

    // the first input is your Gmail email address
    SendEmailChoreo.addInput("Username", GMAIL_USER_NAME);
    // next is your Gmail password.
    SendEmailChoreo.addInput("Password", GMAIL_PASSWORD);
    // who to send the email to
    SendEmailChoreo.addInput("ToAddress", TO_EMAIL_ADDRESS);
    // then a subject line
    SendEmailChoreo.addInput("Subject", "ALERT: CURRENT OFFICE TEMPERATURE");

     // next comes the message body, the main content of the email
    SendEmailChoreo.addInput("MessageBody", bodyMsg);

    // tell the Choreo to run and wait for the results. The
    // return code (returnCode) will tell us whether the Temboo client
    // was able to send our request to the Temboo servers
    unsigned int returnCode = SendEmailChoreo.run();

    // a return code of zero (0) means everything worked
    if (returnCode == 0) {
        Serial.println("Success! Email sent!");
        digitalWrite(LED_PIN, HIGH); // Set led ON
    } else {
      // a non-zero return code means there was an error
      // read and print the error message
      while (SendEmailChoreo.available()) {
        char c = SendEmailChoreo.read();
        Serial.print(c);
      }

    }
     sending = false;
    SendEmailChoreo.close();

}

TembooAccount.h

#define TEMBOO_ACCOUNT "YOUR_TEMBOO_ACCOUNT"  // your Temboo account name
#define TEMBOO_APP_KEY_NAME "APP_KEY_NAME"  // your Temboo app key name
#define TEMBOO_APP_KEY  "APP_KEY"  // your Temboo app key

HTML / ANGULARJS code(or JQuery, Zepto,… )

Our HTML app only needs to call the REST API we just created.
You can use any technology but since I love AngularJS I often choose it : )

<!doctype html>
<html lang="en" ng-app="arduApp">
<head>
    <meta charset="utf-8">

    <title>AngularJS / Arduino</title>
    <meta name="viewport" content="width=device-width">

    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
    <script src="http://code.angularjs.org/1.2.6/angular.min.js"></script>

</head>

<script>

var app = angular.module('arduApp', [])

    function ArduinoCtrl($scope, $http)
    {

        // get the temperature in JSON format
        $scope.getJSONTemp = function() {

            $scope.temperature = null;

            $http.get("proxy.php?url=http://192.168.1.165/arduino/getTemp")
                 .success(function(data) {
  
                $scope.temperature = data.temperature;
            });

             
        }

        // Send mail to your GMAIL account with the temperature
        $scope.sendTemp = function() {

            $scope.temperature = null;
            $scope.sending = true;

             $http.get("proxy.php?url=http://192.168.1.165/arduino/sendTemp")
                  .success(function(data) {

               $scope.sending = false;
               alert("email sent")
            });

        }

    }

</script>

<body>
    <div ng-controller="ArduinoCtrl" class="container">

        <h2>Arduino YUN and AngularJS</h2>
        <h3>Temperature, Temboo and GMAIL</h3>

        <hr>
        <button ng-click="getJSONTemp()" class="btn btn-primary">Get Temperature</button>
        <hr>
        <button ng-click="sendTemp()" class="btn btn-primary">Send MAIL with Temperature</button>
        
        <h1 ng-show="temperature">{{temperature}}C°</h1>
        <h2 ng-show="sending">Sending email. Please wait few seconds...</h2>

    </div>
</body>
</html>

PHP PROXY:
Anyway to avoid cross domain ajax issues (since your Arduino and your HTML page are on different IPs) we use a simple PHP proxy:

<?php
$file = @file_get_contents($_GET['url']);
echo $file;
?>

Comments (4)

  1. Flavio (reply)

    April 15, 2014 at 9:23 am

    Puoi farmi un esempio ? Se il mio arduino è raggiungibile all’ indirizzo 79.14.89.12:90 come si modifica il suddetto proxy ?

    Grazie

    Flavio

    1. Fabio Biondi (reply)

      June 18, 2014 at 11:38 pm

      Ciao Flavio… ho notato poco fa che il codice visualizzato da WordPress era corrotto (quindi alcune parti non erano visibili)… ahime!!!
      Hai risolto poi? Ad ogni modo era sufficiente cambiare l’Ip dell’url utilizzato nell’HTML.
      Scusa per il ritardo nella risposta

  2. Abdoul (reply)

    June 18, 2014 at 11:47 am

    hey, thanks for the great tutorial, just wanted to ask, how do you run the HTML file on your phone and connect it to the Arduino and where exactly do you keep the html file…thanks

    1. Fabio Biondi (reply)

      June 18, 2014 at 11:39 pm

      Hi Abdoul, first of all I have noticed now that some parts of the sketch, the PHP and the HTML code were missing : ((((
      Wordpress didn’t show them correctly. Now I have fixed all of them.. sorry.

      Anyway my code run in a local webserver of my desktop (Apache or IIS) and I simply use its IP to run the app from my phone:
      http://YOUR_DESKTOP_IP/path/index.html

Leave a Reply

Your email address will not be published. Required fields are marked *

Published on: 16 February
Posted by:
Discussion: 4 Comments