In this guide, you’ll learn how to program your Arduino to query the FedEx API every time someone comes to your door in order to determine whether that person was delivering a package. Then, you’ll program the board to use the Zendesk API to alert you if a package was delivered. To connect the APIs to the hardware, we’ll use Temboo, a service that facilitates programming devices to interact with web services. The framework we’ll use in this example is flexible, however, so there’s plenty of room to create—the hardware and APIs we’ve chosen to use are by no means prescriptive.
Parts
To build this example project, you'll be using an Arduino Uno, an Arduino WiFi Shield, and an IR proximity sensor. You’ll need:
An Arduino Uno
An Arduino Wifi Shield
An IR proximity sensor
A USB A - B cable
Some wires
Credentials
You'll also need a Temboo account, a Zendesk account, and a set of FedEx developer keys. You can create a Temboo account for free here, and a Zendesk account here.
To obtain your FedEx keys, begin by creating a FedEx account here. Next, find the Develop and Test tab on the FedEx developers page and click the Get your test key button in the middle of the page. Once you’ve agreed to the terms of service, filled in the registration fields, and accepted the Access Authorization License, you’ll see a confirmation screen with your FedEx web services credentials. We’ll use these later. You’ll also receive a FedEx test password by email after you’ve completed your registration; keep that handy as well.
Generate Your Sketch
Now that you're all set up, log in to Temboo and go to the FedEx > TrackingAndVisibility > TrackByNumber Choreo in the Temboo Library. Turn on IoT Mode and select Arduino and Arduino WiFi from the dropdown menus. In the pop-up that appears, give a name to your board (so that you can find it again for future projects), and also fill in your wireless network information (this will enable Temboo to generate code that is preconfigured to work with your network).
Fill out the Input fields using your FedEx keys; your inputs should look similar to those shown in the screenshot below. Make sure to enter the value “test” for the Endpoint input (we’ll change this once we’re finished testing). For the tracking number, put in 123456789012. This is a test tracking number provided by FedEx, which we’ll use for now.
Once you've filled out all of the Input fields, test the Choreo from your browser by clicking Run at the bottom of the window. Now, if you scroll down to the box labeled Response under Output, you’ll see an XML response from FedEx indicating that you were successful.
Parse Your Output
Now that you've tested the Choreo successfully, scroll down to find the Code section of the page. When you're in IoT Mode and you run a Choreo, Temboo automatically generates code that can be used to make the same API call from an Arduino sketch. Copy the code, and paste it into a new sketch in the Arduino IDE.
In order to run this sketch on your Arduino, it needs to be configured with an appropriate TembooAccount.h header file that contains your Temboo account information and WiFi shield setup information. To create the header file, make a new tab in the Arduino IDE, and name it TembooAccount.h.
On the AppendRow Choreo page beneath the sketch code that you previously copied and pasted into the Arduino IDE, you’ll find another block of generated code containing a set of #define statements. This is your header file. Copy the contents of the header into the TembooAccount.h tab in your Arduino IDE.
Next, we’ll set up an Output Filter to parse the response from FedEx. The Output Filter will filter out the parts of the Choreo response that we aren’t interested in so that only the element that we care about—whether or not the package has been delivered—will be returned to the board. This will make the response more manageable. In your Arduino sketch, right before
// Run the Choreo; when results are available, print them to serial TrackByNumberChoreo.run();
add the following line of code:
TrackByNumberChoreo.addOutputFilter(“delivered”, “/SOAP-ENV:Body/CompletedTrackDetails/TrackDetails/StatusDetail/Location/Residential”, “Response”)
That will filter your output so that the only response returned to your Arduino will be True if the package has been delivered or False if it has not. If you want to adjust your Output Filter to look for something else, you can read more about how to do that here.
Add an Alert
Next, let’s set up your Zendesk alert. Go to the Zendesk > Tickets > CreateTicket Choreo page and, as you did for FedEx, put in your Zendesk credentials and whatever subject and body text you’d like for your alert. Once again, you’ll find that the code for running the Choreo has been generated further down the page. Since you’ve already set up most of your Arduino sketch with your FedEx code, you’ll only need to add a few more lines to bring in the Zendesk functionality. From void loop() in the generated Zendesk code, copy the following lines (note that the inputs in the code below have been replaced with placeholders):
TembooChoreo CreateTicketChoreo(client); // Invoke the Temboo client CreateTicketChoreo.begin(); // Set Temboo account credentials CreateTicketChoreo.setAccountName(TEMBOO_ACCOUNT); CreateTicketChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME); CreateTicketChoreo.setAppKey(TEMBOO_APP_KEY); // Set Choreo inputs String EmailValue = "PLACEHOLDER"; CreateTicketChoreo.addInput("Email", EmailValue); String SubjectValue = "Delivery Alert"; CreateTicketChoreo.addInput("Subject", SubjectValue); String PasswordValue = "PLACEHOLDER"; CreateTicketChoreo.addInput("Password", PasswordValue); String CommentValue = "Your package was just delivered!"; CreateTicketChoreo.addInput("Comment", CommentValue); String ServerValue = "PLACEHOLDER"; CreateTicketChoreo.addInput("Server", ServerValue); // Identify the Choreo to run CreateTicketChoreo.setChoreo("/Library/Zendesk/Tickets/CreateTicket"); // Run the Choreo; when results are available, print them to serial CreateTicketChoreo.run(); while(CreateTicketChoreo.available()) { char c = CreateTicketChoreo.read(); Serial.print(c); } CreateTicketChoreo.close();
and paste them into your sketch in the Arduino IDE after
TrackByNumberChoreo.close();
from the FedEx Choreo.
To make sure that the Zendesk ticket is created only if the package is delivered, we want to make the running of the Zendesk Choreo dependent on the FedEx Choreo’s returning True. To do this, we need to do two things. First, we'll store the FedEx response in a variable called “delivered” by declaring
boolean delivered;
before
while(TrackByNumberChoreo.available()) {
and then replacing the lines
char c = TrackByNumberChoreo.read(); Serial.print(c);
with
boolean delivered = TrackByNumber.readStringUntil('\x1E'); delivered.trim();
Second, let’s enclose the CreateTicket lines that we just added in a conditional:
if(delivered == true){
Now, the FedEx TrackByNumber Choreo will run whenever someone trips your sensor, it will return whether or not the package has been delivered and save the response as a variable, and that variable will be checked to determine whether or not a Zendesk ticket should be filed. Your code should look like this (the individual inputs that you provided will be different, of course):
/* Setup shield-specific #include statements */ #include <SPI.h> #include <WiFi.h> #include <WiFiClient.h> #include <Temboo.h> #include "TembooAccount.h" // Contains Temboo account information WiFiClient client; int numRuns = 1; // Execution count, so this doesn't run forever int maxRuns = 10; // Maximum number of times the Choreo should be executed void setup() { Serial.begin(9600); // For debugging, wait until the serial console is connected. delay(4000); while(!Serial); int wifiStatus = WL_IDLE_STATUS; // Determine if the WiFi Shield is present. Serial.print("\n\nShield:"); if (WiFi.status() == WL_NO_SHIELD) { Serial.println("FAIL"); // If there's no WiFi shield, stop here. while(true); } Serial.println("OK"); // Try to connect to the local WiFi network. while(wifiStatus != WL_CONNECTED) { Serial.print("WiFi:"); wifiStatus = WiFi.begin(WIFI_SSID, WPA_PASSWORD); if (wifiStatus == WL_CONNECTED) { Serial.println("OK"); } else { Serial.println("FAIL"); } delay(5000); } Serial.println("Setup complete.\n"); } void loop() { if (numRuns <= maxRuns) { Serial.println("Running TrackByNumber - Run #" + String(numRuns++)); TembooChoreo TrackByNumberChoreo(client); // Invoke the Temboo client TrackByNumberChoreo.begin(); // Set Temboo account credentials TrackByNumberChoreo.setAccountName(TEMBOO_ACCOUNT); TrackByNumberChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME); TrackByNumberChoreo.setAppKey(TEMBOO_APP_KEY); // Set Choreo inputs String AccountNumberValue = "PLACEHOLDER"; TrackByNumberChoreo.addInput("AccountNumber", AccountNumberValue); String PasswordValue = "PLACEHOLDER"; TrackByNumberChoreo.addInput("Password", PasswordValue); String TrackingNumberValue = "123456789012"; TrackByNumberChoreo.addInput("TrackingNumber", TrackingNumberValue); String MeterNumberValue = "PLACEHOLDER"; TrackByNumberChoreo.addInput("MeterNumber", MeterNumberValue); String EndpointValue = "test"; TrackByNumberChoreo.addInput("Endpoint", EndpointValue); String AuthenticationKeyValue = "PLACEHOLDER"; TrackByNumberChoreo.addInput("AuthenticationKey", AuthenticationKeyValue); // Identify the Choreo to run TrackByNumberChoreo.setChoreo("/Library/FedEx/TrackingAndVisibility/TrackByNumber"); TrackByNumberChoreo.addOutputFilter(“delivered”, “/SOAP-ENV:Body/CompletedTrackDetails/TrackDetails/StatusDetail/Location/Residential”, “Response”) // Run the Choreo; when results are available, print them to serial TrackByNumberChoreo.run(); boolean delivered; while(TrackByNumberChoreo.available()) { boolean delivered = TrackByNumber.readStringUntil('\x1E'); delivered.trim(); } TrackByNumberChoreo.close(); if(delivered == true){ TembooChoreo CreateTicketChoreo(client); // Invoke the Temboo client CreateTicketChoreo.begin(); // Set Temboo account credentials CreateTicketChoreo.setAccountName(TEMBOO_ACCOUNT); CreateTicketChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME); CreateTicketChoreo.setAppKey(TEMBOO_APP_KEY); // Set Choreo inputs String EmailValue = "PLACEHOLDER"; CreateTicketChoreo.addInput("Email", EmailValue); String SubjectValue = "Delivery Alert"; CreateTicketChoreo.addInput("Subject", SubjectValue); String PasswordValue = "PLACEHOLDER"; CreateTicketChoreo.addInput("Password", PasswordValue); String CommentValue = "Your package was just delivered!"; CreateTicketChoreo.addInput("Comment", CommentValue); String ServerValue = "PLACEHOLDER"; CreateTicketChoreo.addInput("Server", ServerValue); // Identify the Choreo to run CreateTicketChoreo.setChoreo("/Library/Zendesk/Tickets/CreateTicket"); // Run the Choreo; when results are available, print them to serial CreateTicketChoreo.run(); while(CreateTicketChoreo.available()) { char c = CreateTicketChoreo.read(); Serial.print(c); } CreateTicketChoreo.close(); } } Serial.println("\nWaiting...\n"); delay(30000); // wait 30 seconds between TrackByNumber calls }
Add the Sensor
Now that your sketch has been written, let’s wire the IR proximity sensor to the Arduino and WiFi shield. The circuit will be relatively simple, and won’t require a breadboard (although you are welcome to use one if you prefer). The sensor will have three wires; connect the black or brown one to ground, the red one to the 5V power supply on the Arduino, and the white one to the analog pin you’ve specified (recall that we chose to use pin A5).
With that, you are ready for a test run. Save your sketch, upload it to your Arduino, open the serial monitor, and trigger it using the proximity sensor. Once you’re satisfied that everything is working as it should be, two small final changes will make the whole setup production-ready.
First, recall that we have been using test credentials from FedEx to build the example. To move out of testing, follow the instructions here, and replace the test credentials in your code with the production keys that you obtain (and, of course, put in the tracking number for a real package as well). Second, add a small delay to the code so that the delivery person has time to mark your package as “delivered” after depositing it on your doorstep.
Add the line
delay(120000);
to pause for two minutes after the proximity sensor first identifies motion in the vicinity.
And that’s it! You can continue to make changes if you’d like—for example, you may want to change the delay period or add a different sort of motion sensor—but no further alterations are required. Save the sketch, upload it to your Arduino, and open the serial monitor to begin looking for deliveries!
This guide was first published on Feb 24, 2016. It was last updated on Feb 24, 2016.