Hans Scharler
Published © MIT

Use Uber with AWS IoT + Lambda + Arduino Starter Kit

Use Uber without a phone! This AWS IoT connected device allows anyone without a smart phone or different capabilities to request Uber.

IntermediateFull instructions provided5,741
Use Uber with AWS IoT + Lambda + Arduino Starter Kit

Things used in this project

Hardware components

Arduino Yun
Arduino Yun
×1
Seeed Studio Grove Starter Kit for Arduino
×1

Software apps and online services

AWS IoT
Amazon Web Services AWS IoT
AWS Lambda
Amazon Web Services AWS Lambda
Uber API

Story

Read more

Schematics

Arduino Yun and Grove Starter Kit assembly

Code

Arduino Yun Pub/Sub to AWS IoT

Arduino
Publishes button presses (D3) to the "uber" topic and subscribes to "uber_respone" topic to activate the buzzer board (D2).
/*
 * Uber + AWS IoT + Lambda + Arduino
 * 
 * Use an AWS IoT connected Arduino Yun to indicate how far your Uber car
 * is away from you. This project started with the BasicPubSub example by
 * Amazon to interface with AWS IoT.
 * 
 * https://github.com/nothans/Uber-AWS-IoT
 * 
 * Created: January 31, 2016 by Hans Scharler - http://www.nothans.com
 */

// Include AWS IoT
#include <aws_iot_mqtt.h>
#include <aws_iot_version.h>
#include "aws_iot_config.h"

// Setup AWS IoT Client
aws_iot_mqtt_client myClient; // init iot_mqtt_client

// Setup global variables for AWS IoT
char msg[32]; // read-write buffer
int cnt = 0; // loop counts
int rc = -100; // return value placeholder
bool success_connect = false; // whether it is connected

// Create a callback for AWS IoT messages
void msg_callback(char* src, int len) {
  
  Serial.println("CALLBACK:");  
  int i;
  for(i = 0; i < len; i++) {
    Serial.print(src[i]);
  }
  Serial.println("");

  // Get number of beeps
  int n = atoi(src);
  
  // Signal Uber's ETA by beeping the buzzer
  soundBeeps(n, 500, 300);  
  
}

// Define pins for button and buzzer
const int pinButton = 3;
const int pinBuzzer = 2;

void setup() {
  // Configure button pin as a digital input
  pinMode(pinButton, INPUT);

  // Configure buzzer pin as a digital output
  pinMode(pinBuzzer, OUTPUT);
    
  // Start serial for debug / monitoring
  Serial.begin(115200);

  // Wait for serial before AWS IoT setup starts
  while(!Serial);
  //
  char curr_version[80];
  sprintf(curr_version, "AWS IoT SDK Version(dev) %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);
  Serial.println(curr_version);
  // Set up the client
  if((rc = myClient.setup(AWS_IOT_CLIENT_ID)) == 0) {
    // Load user configuration
    if((rc = myClient.config(AWS_IOT_MQTT_HOST, AWS_IOT_MQTT_PORT, AWS_IOT_ROOT_CA_PATH, AWS_IOT_PRIVATE_KEY_PATH, AWS_IOT_CERTIFICATE_PATH)) == 0) {
      // Use default connect: 60 sec for keepalive
      if((rc = myClient.connect()) == 0) {
        success_connect = true;
        // Subscribe to "topic1"
        if((rc = myClient.subscribe("uber_response", 1, msg_callback)) != 0) {
          Serial.println("Subscribe failed!");
          Serial.println(rc);
        }
      }
      else {
        Serial.println("Connect failed!");
        Serial.println(rc);
      }
    }
    else {
      Serial.println("Config failed!");
      Serial.println(rc);
    }
  }
  else {
    Serial.println("Setup failed!");
    Serial.println(rc);
  }
  // Delay to make sure SUBACK is received, delay time could vary according to the server
  delay(2000);  
}

void loop() {

  // Check if button is pressed
  if (digitalRead(pinButton)) {
    publishToAWSIoT();
  }

  if (success_connect) {
 
    // Get a chance to run a callback
    if ((rc = myClient.yield()) != 0) {
      Serial.println("Yield failed!");
      Serial.println(rc);
    }
        
  }
    
  delay(1000);
  
}

int publishToAWSIoT() {
  
  if (success_connect) {
    
    // Send the message "estimate" to the "uber_request" topic
    sprintf(msg, "{\"command\":\"estimate\"}", cnt);
    
    if ((rc = myClient.publish("uber", msg, strlen(msg), 1, false)) != 0) {
      Serial.println("Publish failed!");
      Serial.println(rc);
    }
    
    delay(1000);
    
  }
  
}

void soundBeeps(int beeps, int duration, int wait) {
  
    for (int i = 0; i < beeps; i++) {
      
        digitalWrite(pinBuzzer, HIGH);
        delay(duration);
        digitalWrite(pinBuzzer, LOW);
        delay(wait);
        
    }
    
}

AWS Lambda Function

JavaScript
This Lambda function is triggered when a message on the "uber" topic matches. The function requests data from the Uber API and replies back to the AWS IoT connected Arduino.
var AWS = require('aws-sdk');
var https = require('https');

// Set options for AWS IoT
//   - make sure credentials have AWSIoTDataAccess permissions policy
var CONFIG_AWSIOT = {
  endpoint: 'XXX.iot.us-east-1.amazonaws.com',
  region: 'us-east-1',
  accessKeyId: 'XXX',
  secretAccessKey: 'XXX'
};

// Set options for Uber API  
var CONFIG_UBER = {
  uber_token: "XXX",
  product_id: "XXX",
  start_latitude: 42.300080,
  start_longitude: -71.350349
};

function callUber(event, context) {
    
  var data =  {
    product_id:      CONFIG_UBER.product_id,
    start_latitude:  CONFIG_UBER.start_latitude,
    start_longitude: CONFIG_UBER.start_longitude
  };
  
  data = JSON.stringify(data);
  
  var headers = {
    'Authorization': 'Bearer ' + CONFIG_UBER.uber_token,
    'Content-Type': 'application/json',
    'Content-Length': Buffer.byteLength(data)
  };

  var options = {
    host:    'api.uber.com',
    path:    '/v1/requests/estimate',
    method:  'POST',
    headers: headers
  };

  var req = https.request(options, function(res) {
      
    res.on('data', function (chunk) {
        
      uberData = JSON.parse(chunk);
      
      iotdata = new AWS.IotData(CONFIG_AWSIOT);
  
      params = {
        topic: 'uber_response',
        payload: uberData.pickup_estimate.toString(),
        qos: 0
      };
      
      iotdata.publish(params, function(err, data) {
        if (err) {
          console.log(err, err.stack);
          context.fail(event); 
        }
        else {
          console.log(data);
          context.succeed(event);
        }
      });
  
      console.log(chunk.toString());
    });

  });

  req.write(data);
  req.end();
  
  req.on('error', function(e) {
    context.fail(event); 
  });
  
}

exports.handler = callUber;

Arduino Yun Pub/Sub to AWS IoT

Credits

Hans Scharler

Hans Scharler

15 projects • 86 followers
IoT Engineer, Maker - I have a toaster that has been tweeting since 2008.

Comments