Bhavik Bhansali
Published © CC BY-SA

Alexa Where is my car..??!!

how cool it is.., if you ask "Alexa where is my car" to Amazon Alexa and she replied with the latest Address of your car.

AdvancedFull instructions provided10 hours2,864
Alexa Where is my car..??!!

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
×1
SIM800L GSM/GPRS Module
SIM900/SIM908/SIM800 are direct compatible for this project
×1
Seeed Studio GPS Bee - GPS Receiver
Any UART output GPS module are direct compatible for this project
×1
Texas Instruments LM2596 DC-DC Buck regulator module
This module is to convert 5V to 4.2V which is used as power supply by GPRS Module
×1

Software apps and online services

Arduino IDE
Arduino IDE
Used for writing Arduino Mega firmware that handles GPS and GPRS functions
AWS Lambda
Amazon Web Services AWS Lambda
AWS Lambda used for host node.js script that triggered by Alexa
Alexa Skills Kit
Amazon Alexa Alexa Skills Kit
Car tracker custom skill implemented with Alexa Skills Kit
AWS EC2
Amazon Web Services AWS EC2
ubuntu instance on EC2 handles mySQL database and php scripts related to this project
MobaXterm

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Optional .. only useful if you want to build cool enclosure for this project
Soldering iron (generic)
Soldering iron (generic)
Its good to hardwire complete hardware as hardware going to experience vibration due to moving vehicle
Surgical Cutter
Depron Sheet

Story

Read more

Schematics

Alexa Where is my car

Code

alexamap.php

PHP
This file will collect data from the device using URL with HTTP get/post request. from that data, it fetches the address from latitude and longitude value from google map API get data in form of JSON. it will parse formatted address from it and save the latitude, longitude and formatted address into the database.
<?php
   	include("connect.php");
   	
   	$link=Connection();

    $id=$_GET["id"];
	$lat=$_GET["lat"];
    $lng=$_GET["lng"];

	$comma=",";
    	$map="http://maps.googleapis.com/maps/api/geocode/json?latlng=";
	$mapurl = $map.$lat.$comma.$lng;
	//echo $mapurl;
	$result = file_get_contents($mapurl);
	$obj = json_decode($result);
	//echo $obj->access_token;
	//echo $obj->results[0]->formatted_address;
	//echo json_encode($obj->results[0]->formatted_address);
	
	$query = "INSERT INTO `name_of_your_table` (`lat`, `lng`, `address`) 
		VALUES ('".$lat."','".$lng."','".$obj->results[0]->formatted_address."')"; 
   	
	//echo json_encode($obj->results[0]->formatted_address);
	
	
   	mysqli_query($link,$query);
	mysqli_close($link);


?>
			

index.php

PHP
This file captures the last data of latitude and longitude from the database and using google map reverse geocoding API place pinpoint into google map and show it when you open the website.
<?php

	include("connect.php"); 
	$link=Connection();
	$result=mysqli_query($link,"SELECT * FROM `name_of_your_table` ORDER BY `id` DESC LIMIT 1");
	$row = mysqli_fetch_array($result,MYSQLI_ASSOC);
	$lat1 = $row["lat"];
	$lng1 = $row["lng"];
	$latlng= "lat: ".$lat1.","."lng: ".$lng1;
	
?>
<!DOCTYPE html>
<html>
  <head>
    <style>
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #map {
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script type="text/javascript">

      function initMap() {
//        var myLatLng = {lat: -25.363, lng: 131.044};
	var myLatLng = {lat: <?php echo $lat1; ?>, lng: <?php echo $lng1; ?>};
        var map = new google.maps.Map(document.getElementById('map'), {
          zoom: 18,
          center: myLatLng
        });

        var marker = new google.maps.Marker({
          position: myLatLng,
          map: map,
          title: 'Hello World!'
        });
      }
	  </script>
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDKYMiCidmKDPkOkslli7fj-afllBQHtO8&callback=initMap">
    </script>
  </body>
</html>

connect.php

PHP
This code will provide connection of other files to the database on request base.
<?php

	function Connection(){
		$server="localhost";
		$user="root";
		$pass="yourpassword";
		$db="yourdatabasename";
	   	
		$connection = mysqli_connect($server, $user, $pass,$db);

		if (!$connection) {
	    	die('MySQL ERROR: ' . mysqli_connect_error());
		}
		
		mysqli_select_db($connection,$db) or die( 'MySQL ERROR: '. mysqli_connect_error() );

		return $connection;
	}
?>

read.php

PHP
this file fetches the formatted address of cars last location from the database and gives its output on body section in JSON format. This file will call for lambda function to get cars the last location in JSON format on to the Alexa enable device which later will push it and gives us a final result.
<?php

	include("connect.php"); 
	

	$link=Connection();
       

	$result=mysqli_query($link,"SELECT * FROM `name_of_your_table` ORDER BY `id` DESC LIMIT 1");


		  if($result!==FALSE){
		     while($row = mysqli_fetch_array($result,MYSQLI_ASSOC)) {

					echo json_encode($row);
		     }
		     mysqli_free_result($result);
		     mysqli_close($link);
		  }
 ?>	

device_gsm_gps.ino

Arduino
This is the code which you need to upload to Arduino mega2560 device.
// Select your modem:
#define TINY_GSM_MODEM_SIM800
// #define TINY_GSM_MODEM_SIM808
// #define TINY_GSM_MODEM_SIM900
// #define TINY_GSM_MODEM_A6
// #define TINY_GSM_MODEM_A7
// #define TINY_GSM_MODEM_M590
// #define TINY_GSM_MODEM_ESP8266
#include <TinyGsmClient.h>
#include <TinyGPS.h>

TinyGPS gps;
static void smartdelay(unsigned long ms);


// Your GPRS credentials
// Leave empty, if missing user or pass
const char apn[]  = "www"; //please enter apn of your network provider
const char user[] = "";
const char pass[] = "";

// Use Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial1

// or Software Serial on Uno, Nano
//#include <SoftwareSerial.h>
//SoftwareSerial SerialAT(2, 3); // RX, TX

TinyGsm modem(SerialAT);
TinyGsmClient client(modem);

const char server[] = "yourwebsitename.com"; //or you can enter your web server public ip

const int port = 80;
float flat=12.7654321, flon=69.1234567;
unsigned long age, date, time, chars = 0;
void setup() {
  // Set console baud rate
  Serial.begin(115200);
  Serial2.begin(9600);
  delay(10);

  // Set GSM module baud rate
  SerialAT.begin(115200);
  delay(3000);

  // Restart takes quite some time
  // To skip it, call init() instead of restart()
  Serial.println(F("Initializing modem..."));
  modem.restart();

  String modemInfo = modem.getModemInfo();
  Serial.print("Modem: ");
  Serial.println(modemInfo);

  // Unlock your SIM card with a PIN
  //modem.simUnlock("1234");
}

void loop() {
  Serial.print(F("Waiting for network..."));
  if (!modem.waitForNetwork()) {
    Serial.println(" fail");
    delay(10000);
    return;
  }
  Serial.println(" OK");

  
  // Do nothing forevermore
  while (true) {
    char latb[15];
    char lngb[15];
    smartdelay(10000);
    gps.f_get_position(&flat, &flon, &age);
    dtostrf(flat,0,7,latb);
    Serial.println(latb);
    dtostrf(flon,0,7,lngb);
    Serial.println(lngb);
    senddata(latb,lngb);
    
  }
}

void senddata(char* lat, char* lng)
{
  Serial.print(F("Connecting to "));
  Serial.print(apn);
  if (!modem.gprsConnect(apn, user, pass)) {
    Serial.println(" fail");
    delay(10000);
    return;
  }
  Serial.println(" OK");

  Serial.print(F("Connecting to "));
  Serial.print(server);
  if (!client.connect(server, port)) {
    Serial.println(" fail");
    delay(10000);
    return;
  }
  Serial.println(" OK");

  // Make a HTTP GET request:
  client.print(String("GET ") + "/alexamap.php?lat=" + lat + "&lng=" + lng + " HTTP/1.0\r\n");
  client.print(String("Host: ") + server + "\r\n");
  client.print("Connection: close\r\n\r\n");

  unsigned long timeout = millis();
  while (client.connected() && millis() - timeout < 10000L) {
    // Print available data
    while (client.available()) {
      char c = client.read();
      Serial.print(c);
      timeout = millis();
    }
  }
  Serial.println();

  client.stop();
  Serial.println("Server disconnected");

  modem.gprsDisconnect();
  Serial.println("GPRS disconnected");

}

static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    while (Serial2.available())
      gps.encode(Serial2.read());
  } while (millis() - start < ms);
}

index.js

JavaScript
'use strict';

/**
 * This sample demonstrates a simple skill built with the Amazon Alexa Skills Kit.
 * The Intent Schema, Custom Slots, and Sample Utterances for this skill, as well as
 * testing instructions are located at http://amzn.to/1LzFrj6
 *
 * For additional samples, visit the Alexa Skills Kit Getting Started guide at
 * http://amzn.to/1LGWsLG
 */
 //let turl = 'https://api.thingspeak.com/channels/429541/feed/last.json?api_key=7C01SCENVD3OQTA7';
 let turl = 'http://alexavehicletracker.tk/read.php';
        let p_at = 'pat';
        let p_ou = 'pou';
        let p_in = 'pin'; 
        let tempe = 'pin'; 
        let addr = 'Please try again problem in fetching your location';
// --------------- Helpers that build all of the responses -----------------------
var http = require('http');
function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
    return {
        outputSpeech: {
            type: 'PlainText',
            text: output,
        },
        card: {
            type: 'Simple',
            title: `SessionSpeechlet - ${title}`,
            content: `SessionSpeechlet - ${output}`,
        },
        reprompt: {
            outputSpeech: {
                type: 'PlainText',
                text: repromptText,
            },
        },
        shouldEndSession,
    };
}

function buildResponse(sessionAttributes, speechletResponse) {
    return {
        version: '1.0',
        sessionAttributes,
        response: speechletResponse,
    };
}


// --------------- Functions that control the skill's behavior -----------------------

function getWelcomeResponse(callback) {

    
    const sessionAttributes = {};
    const cardTitle = 'Welcome';
    const speechOutput = 'Welcome to the Alexa Vehicle Tracker by Bhavik Bhansali. Please ask location of your vehicle followed by type of vehicle. You can ask like  what is location of my car';
    // If the user either does not reply to the welcome message or says something that is not
    // understood, they will be prompted again with this text.
    const repromptText = 'Please tell me your vehicle type by saying, what is location of my car';
    const shouldEndSession = false;

    callback(sessionAttributes,
        buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}

function handleSessionEndRequest(callback) {
    const cardTitle = 'Session Ended';
    const speechOutput = 'Thank you for using Alexa Vehicle Tracker. Have a nice day!';
    // Setting this to true ends the session and exits the skill.
    const shouldEndSession = true;

    callback({}, buildSpeechletResponse(cardTitle, speechOutput, null, shouldEndSession));
}

function createFavoriteColorAttributes(favoriteColor) {
    return {
        favoriteColor,
    };
}

/**
 * Sets the color in the session and prepares the speech to reply to the user.
 */
function setColorInSession(intent, session, callback) {
                     //Sensor Readings
    // Create URL to retrieve latest temperature reading from my ThingsSpeak channel (JSON format)
    
    const cardTitle = intent.name;
    const favoriteColorSlot = intent.slots.Type;
    let repromptText = '';
    let sessionAttributes = {};
    const shouldEndSession = false;
    let speechOutput = '';

    if (favoriteColorSlot) {
        const favoriteColor = favoriteColorSlot.value;
        sessionAttributes = createFavoriteColorAttributes(favoriteColor);
        speechOutput =`Address is ` + addr;
        repromptText = "You can ask me your cehicle type by saying, what's location of my?";
    } else {
        speechOutput = "I'm not sure what your vechicle type is. Please try again.";
        repromptText = "I'm not sure what your vechicle type is. You can tell me your " +
            'vechicle type by saying, what is location of my car';
    }

    callback(sessionAttributes,
         buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}

function getColorFromSession(intent, session, callback) {
    let favoriteColor;
    const repromptText = null;
    const sessionAttributes = {};
    let shouldEndSession = false;
    let speechOutput = '';

    if (session.attributes) {
        favoriteColor = session.attributes.favoriteColor;
    }

    if (favoriteColor) {
        speechOutput = `Your vehicle type is ${favoriteColor}. Goodbye.`;
        shouldEndSession = true;
    } else {
        speechOutput = "I'm not sure what your vechicle type is, you can say, what is location of my car";
    }

    // Setting repromptText to null signifies that we do not want to reprompt the user.
    // If the user does not respond or says something that is not understood, the session
    // will end.
    callback(sessionAttributes,
         buildSpeechletResponse(intent.name, speechOutput, repromptText, shouldEndSession));
}


// --------------- Events -----------------------

/**
 * Called when the session starts.
 */
function onSessionStarted(sessionStartedRequest, session) {
    console.log(`onSessionStarted requestId=${sessionStartedRequest.requestId}, sessionId=${session.sessionId}`);
}

/**
 * Called when the user launches the skill without specifying what they want.
 */
function onLaunch(launchRequest, session, callback) {
    console.log(`onLaunch requestId=${launchRequest.requestId}, sessionId=${session.sessionId}`);

    // Dispatch to your skill's launch.
    getWelcomeResponse(callback);
}

/**
 * Called when the user specifies an intent for this skill.
 */
function onIntent(intentRequest, session, callback) {
    console.log(`onIntent requestId=${intentRequest.requestId}, sessionId=${session.sessionId}`);

    const intent = intentRequest.intent;
    const intentName = intentRequest.intent.name;

    // Dispatch to your skill's intent handlers
    if (intentName === 'Location') {
        setColorInSession(intent, session, callback);
    } else if (intentName === 'GetLocation') {
        getColorFromSession(intent, session, callback);
    } else if (intentName === 'AMAZON.HelpIntent') {
        getWelcomeResponse(callback);
    } else if (intentName === 'AMAZON.StopIntent' || intentName === 'AMAZON.CancelIntent') {
        handleSessionEndRequest(callback);
    } else {
        throw new Error('Invalid intent');
    }
}

/**
 * Called when the user ends the session.
 * Is not called when the skill returns shouldEndSession=true.
 */
function onSessionEnded(sessionEndedRequest, session) {
    console.log(`onSessionEnded requestId=${sessionEndedRequest.requestId}, sessionId=${session.sessionId}`);
    // Add cleanup logic here
}


// --------------- Main handler -----------------------

// Route the incoming request based on type (LaunchRequest, IntentRequest,
// etc.) The JSON body of the request is provided in the event parameter.
exports.handler = (event, context, callback) => {
    try {
        http.get(turl, function(res) {
        // Get latest sensor data from home IoT SoC
        res.on('data', function(d) {
            addr = JSON.parse(d).address;
        });
        res.on('end', function() {
        });
        res.on('error', function(e) {
             context.fail("Got error: " + e.message);
        });
    });
    
   
        console.log(`event.session.application.applicationId=${event.session.application.applicationId}`);

        /**
         * Uncomment this if statement and populate with your skill's application ID to
         * prevent someone else from configuring a skill that sends requests to this function.
         */
        /*
        if (event.session.application.applicationId !== 'amzn1.echo-sdk-ams.app.[unique-value-here]') {
             callback('Invalid Application ID');
        }
        */

        if (event.session.new) {
            onSessionStarted({ requestId: event.request.requestId }, event.session);
        }

        if (event.request.type === 'LaunchRequest') {
            onLaunch(event.request,
                event.session,
                (sessionAttributes, speechletResponse) => {
                    callback(null, buildResponse(sessionAttributes, speechletResponse));
                });
        } else if (event.request.type === 'IntentRequest') {
            onIntent(event.request,
                event.session,
                (sessionAttributes, speechletResponse) => {
                    callback(null, buildResponse(sessionAttributes, speechletResponse));
                });
        } else if (event.request.type === 'SessionEndedRequest') {
            onSessionEnded(event.request, event.session);
            callback();
        }
    } catch (err) {
        callback(err);
    }
};

Intent Schema

JSON
Type this thing in Intent Schema.
{
  "intents": [
    {
      "intent": "Location",
      "slots": [
        {
          "name": "Type",
          "type": "TYPE_OF_VEHICLE"
        }
      ]
    },
    {
      "intent": "GetLocation"
    },
    {
      "intent": "AMAZON.HelpIntent"
    }
  ]
}

Credits

Bhavik Bhansali

Bhavik Bhansali

1 project • 6 followers

Comments