Archived | Build a PHP app that uses GPS data from an IoT device

Archived content

Archive date: 2019-11-26

This content is no longer being updated or maintained. The content is provided “as is.” Given the rapid evolution of technology, some content, steps, or illustrations may have changed.

There’s plenty of buzz around the Internet of Things (IoT) these days. Everyone’s talking about how your house, car, boat, or solar-powered thingamajig will be sending out real-time data streams about how it’s currently operating, which opens up a new range of technology applications and business opportunities.

If you’re a PHP developer who is interested in building IoT applications, though, it’s often hard to cut through the hype and understand how IoT devices and applications will operate on a technical or implementation level. At least that’s the way it was for me. And, until I gained a fundamental understanding, I found it hard to begin imagining and building applications to take advantage of the IoT-enabled universe.

It took me some time, and quite a few experiments, to begin understanding the world of IoT (and I’m still learning). In this beginner article, I hope to save you that time and effort, by walking you through the process of building an IoT application that uses my favorite programming language, PHP.

I’ll show you how to use the IoT Starter Application for Android to turn your Android phone into a GPS sensor that constantly publishes its location to the IBM Cloud. I’ll then show you how to connect a PHP application with this data stream and use it to track the location of the Android phone in real time in your web browser.

Sounds interesting, right? Keep reading.

What You Will Need

Any application that uses the Google Maps API must comply with the Google Maps APIs Terms of Service, Google APIs Terms of Service, and the Google Privacy Policies. Before you begin, spend a few minutes reading these requirements and ensuring that your application complies with them.


Build an IBM Cloud app with the Internet of Things Platform Starter boilerplate

One of the quickest ways to get started with IoT is with the IBM Watson IoT Platform. Watson IoT Platform is a cloud-hosted platform that serves as a central point of contact for all your IoT-enabled devices and applications. In simple terms, devices publish their data to the IBM Watson IoT Platform in the cloud, and mobile or web applications consume that data.

Since the IBM Watson IoT Platform is a critical component of the application we’re building, we’ll set it up first. The easiest way to get started with the IBM Watson IoT Platform is to create a new IBM Cloud application with the Internet of Things Platform Starter boilerplate, which binds an Internet of Things Platform service instance to it.

  1. Log in to your IBM Cloud account.
  2. From your IBM Cloud account dashboard, click Create App. Screen capture of Dashboard including the create app button
  3. From the list of boilerplates, select the Internet of Things Platform Starter boilerplate. Screen capture of the Internet of Things Platform Starter boilerplate icon
  4. In the Create a Cloud Foundry App area, specify a name and host name for your IBM Cloud application, and click Create. Ensure that you select the “Lite” plan for the Internet of Things Platform service. Screen capture of the Create an app dialog with the input fields highlighted
  5. After some time, your application is staged and launched. Click the application name in the IBM Cloud dashboard to view the status of your app and see the bound Internet of Things Platform service to your application in the list of available services. Screen capture of the Overview screen for your IBM Cloud app

Register Devices with the IBM Watson IoT Platform

After you’ve successfully configured the Internet of Things Platform service, the next step is to tell it about the devices that will be connecting to it.

For security, the IBM Watson IoT Platform isolates your devices and their data in a separate account, also called an organization. Each organization has a unique 6-character identifier that is automatically created within the IBM Watson IoT Platform. Devices and applications in one IBM Watson IoT Platform organization are invisible to any other IBM Watson IoT Platform organization.

  1. On your application detail page, select the Internet of Things Platform service. The service detail page opens.
  2. Click the Launch button. The IBM Watson IoT Platform dashboard for your organization opens with the identifier at the top.alt
  3. When you first start the platform within an organization, no devices are registered. Your first step must be to create a device type, which serves as a template to register devices of a specific type. Then, your second step is to use that template to register devices with the IBM Watson IoT Platform.

    a. From the Devices menu, find the Device Types section and click Create Type. On the Create Device Type page, specify the device type and a brief description. You can choose any string for the device type, but your devices need to use the same string when they authenticate with the Internet of Things Platform service. For this tutorial, specify Android for the device type because the IoT Starter Application that you use in the next step is hard-wired to use this device type. alt Although you can select additional attributes that your users must specify when they register a new device, such as its serial number or a hardware version, our simple application does not require any additional attributes. Save the device type.


    b. From the Devices menu, find the Browse section, click Add Device, and select Android as the device type.


    Enter a unique identifier for the device. It can be a random or descriptive string; for example, in this tutorial, use A111. Remember this device identifier because it will form part of the client identifier that your device will use when authenticating with the IBM Watson IoT Platform. alt

  4. You will now be asked to provide or generate an authentication token for the device. Let the system generate it for you; the summary screen lists the details of your newly registered device, including the auto-generated token. Copy the token to your clipboard to use later in the tutorial, as it will not be displayed again. alt

Now, the device “A111” is registered with the IBM Watson IoT Platform and the Internet of Things Platform service can begin accepting data from it, subject to a valid authentication token.


Compile and Install the IoT Starter for Android Application

The IoT Starter for Android is a sample Android application that lives on your Android smartphone or tablet and publishes a stream of data and events from the device accelerometer and other sensors to the IBM Watson IoT Platform. It can also receive commands from the IBM Watson IoT Platform. As such, it’s a great way to start experimenting with the IBM Watson IoT Platform and building applications to interact with real-time data streams.

If you are experienced in Android development, you can download the code from GitHub, import it into your Android development environment, and then build the apk file. Otherwise, to get the app installed and running quickly, follow these steps.

  1. Clone the project’s source code repository.

    a. Launch Android Studio.

    b. Click Quick Start > Check out project from Version Control > Git.

    c. In the Clone Repository dialog, specify the following GitHub repository: alt

    d. Click Clone.

  2. Compile the application by clicking the Build > Build APK menu. An Android application package (an .apk file) will be produced in the project’s output directory, for example in app/build/outputs/apk. alt

    Copy this .apk file to your Android device, and install it by using a file manager.


Publish Data from the Android Starter Application to the IBM Watson IoT Platform

  1. On your Android device, launch the app that you just installed.
  2. On the Welcome screen, enter the organization identifier, device identifier, and authentication token from Step 2.
  3. Click the Activate Sensor button.Screen capture of Android Starter app on Android device

The data that is sent by an IoT device is published to topics, which are the rough equivalent of channels on the radio. Different types of events can be published to different topics. For example, for this device, accelerometer events are published to the topic iot-2/evt/accel/fmt/jsoniot-2/evt/accel/fmt/json, and touch events are published to the topic iot-2/evt/touchmove/fmt/jsoniot-2/evt/touchmove/fmt/json.

Return to the IBM Watson IoT Platform dashboard, and you should see the incoming data stream from the device as JSON documents. Here’s an example:


In particular, note the ‘latitude’ and ‘longitude’ keys in each JSON message, which contain the current GPS coordinates of the device. In case you don’t see these keys, ensure that your Android device is set to report its location and then relaunch the IOT Starter for Android application.


Generate an API Key for Application Access

Now, you’ve got a stream of data that is arriving in your IBM Watson IoT Platform organization from a registered device. To complete the picture, you need an application that can retrieve this data from the IBM Watson IoT Platform organization and do something useful with it.

First, you must make sure that your application can access your IBM Watson IoT Platform organization. Just as you generated an authentication token for your device in Step 2, you now need to generate an API key for your application.

  1. Open the IBM Watson IoT Platform dashboard for your organization.
  2. Select Apps > API Keys.
  3. Click the Generate API Key button.
  4. Make a note of the API key and authentication token that are generated for you. You’ll use both of these values in the next step.alt
  5. Click Generate to save the API key.

Consume Data from the IBM Watson IoT Platform in a PHP Application

Now for the fun part. Devices and applications can send and receive data from the IBM Watson IoT Platform by using a lightweight messaging protocol called Message Queue Telemetry Transport or MQTT. The Android Starter Application publishes its accelerometer data to the IBM Watson IoT Platform by using MQTT, and any application that you build will usually need to “speak MQTT” so that it can receive data from the IBM Watson IoT Platform.

Just as a device publishes data to specific topics, an application can subscribe to and consume data in those topics. The device type and name should be specified as part of the topic name. For example, to subscribe to ‘accel’ events from device ‘A111’, the topic name is iot-2/type/Android/id/A111/evt/accel/fmt/jsoniot-2/type/Android/id/A111/evt/accel/fmt/json. The + symbol can be used as a wildcard character to refer to all device types or all devices.

If you’re using PHP for your application, one of the easiest ways to add MQTT support is with the phpMQTT library, a PHP class that lets you work with MQTT messages and brokers. To use it, clone or download it to your PHP development environment. The PHP scripts for this tutorial call the phpMQTT library.

Three PHP apps are created with three PHP scripts:

  1. cli-app.php and db-app.php – These scripts are run at the server console or at the command line.
  2. web-app.php – This script is accessed through a web browser.

Download these three .php files, and open them in a text editor.

The script cli-app.php begins by initializing a new phpMQTT object, which will serve as the control point for all communication with the IBM Watson IoT Platform. This object needs several parameters, all of which are stored in the $config array at the top.

Update the placeholders that are shown in the following code listing with the actual values from previous steps in this tutorial:

// set configuration values
$config = array(
  'org_id' => 'IOTF‑ORG‑ID',
  'port' => '1883',
  'app_id' => 'phpmqtt',
  'iotf_api_key' => 'IOTF‑API‑KEY',
  'iotf_api_secret' => 'IOTF‑API‑TOKEN',
  'device_id' => 'DEVICE‑ID'

$config['server'] = $config['org_id'] . '';
$config['client_id'] = 'a:' . $config['org_id'] . ':' . $config['app_id'];
$location = array();

The parameters that phpMQTT needs are:

  • The server name, which is usually named after your organization identifier under the ‘’ domain.
  • The server port, which is 1883 for unencrypted connections and 8883 for encrypted connections.
  • The client identifier. The application must authenticate itself by using a client identifier in the format a:ORG_ID:APP_IDa:ORG_ID:APP_ID, where the APP_ID is a user-supplied value.
  • The client API key and secret, which are needed to access the service.

After the object has been initialized, its connect() method can be used to connect to the IBM Watson IoT Platform by using the API key and authentication token from Step 5. The subscribe() method is used to subscribe to the accel topic; it also specifies a user-defined function to run for each incoming message.

In this script, the user-defined function is the getLocation() function, and its job is to use the PHP json_decode() function to extract the GPS data from each message and display it on the screen. The proc() method inspects and processes the stream of messages that arrive in that topic in a continuous loop.

Here’s an example of the output from the script:


Instead of merely displaying the GPS data, you can also save it to a database so that you can “track” the movement of the device (and also its owner) over time. The db-app.php script is a variant of the cli-app.php script that, instead of displaying the GPS stream from the device, continuously saves the data to a MySQL database with PHP. This data can then be analyzed and used for various applications; one example might be to build a graph of the user’s movements over time.

You can build this graph by creating a connection to the MySQL database at the top of the script and then using that connection to execute an INSERT query for each data packet that is received over MQTT. The changes are localized in the getLocation() function shown earlier and can be seen in full in the source code repository, but here’s a quick sample:

// connect to database
$mysqli = new mysqli($config['db_host'], $config['db_user'], $config['db_pass'], $config['db_name']);
if ($mysqli‑>connect_errno) {
  echo 'ERROR: Could not connect to MySQL (' . $mysqli‑>connect_errno . ') ' . $mysqli‑>connect_error;

// ...

function getLocation($topic, $msg) {
  $mysqli = $GLOBALS['mysqli'];
  $json = json_decode($msg);
  $latitude = $json‑>d‑>latitude;
  $longitude = $json‑>d‑>longitude;
  if (!$mysqli‑>query("INSERT INTO data(ts, latitude, longitude) VALUES (NOW(), '$latitude', '$longitude')")) {
    echo 'ERROR: Data insertion failed';

Here’s an example of the data that was saved to the database:


Instead of displaying or saving the GPS data, a more sophisticated application is a PHP web app that displays the device’s location on a map.

As you can imagine, it’s quite easy to use this GPS data stream to do something more useful, such as producing a map of the device’s location that is updated in real time. The Google Static Maps API has everything you need.

Before you can use the Google Static Maps API, you need to register your web application with Google. Log in to Google using your Google Account credentials, and go to the Google Developers Console. Create a new project, assign it a name, and then turn on access to the Google Static Maps API.


Familiarize yourself with the usage limits for this API.

Next, in the credentials screen, make a note of the API key for browser access. You’ll use this API key to authorize all API requests made by your application.


After you’re done, you can create or update the web-app.php script, which displays the GPS data in a map.

Unlike the previous script, which was designed to process every message that was received in the topic and display it on the screen, the requirements for this script are slightly different and various workarounds are needed to use it in a web browser context:

  • First, you need to process the incoming data stream and extract the GPS coordinates from it to display the map in a browser, not merely output the values to the console. Thus, the values that are extracted during the execution of the getLocation() method need to be exposed to the rest of the script, which means you need to make it a global variable.
  • Second, to display the map, the app must interpolate the GPS coordinates into the Google Maps API endpoint and then request the map image by using the endpoint URL. However, it typically takes the client browser some time to perform this request and render the image. To avoid a situation where every new message results in a new request to the Google Maps API without the previous request completing, the proc() loop automatically terminates when the first message is received. The problem with the previous implementation, of course, is that only the first message that is received from the device will be processed and all subsequent messages will be ignored. In this scenario, the map will reflect the first location of the device only. This issue is remedied by using a <meta http-equiv="refresh"> tag, which forces a page reload every 10 seconds. This tag effectively causes the script to reload and produce an updated map every 10 seconds.
  • Third, should the device be turned off or disconnected from the IBM Watson IoT Platform, the proc() loop will wait endlessly (until the script times out) for a message, which leaves the user staring at an empty browser page followed by a timeout error message. This implementation is not particularly user-friendly, so to avoid this situation, the sleep() method is used to break out of the proc() processing loop after five seconds without it receiving a message in the subscribed topic, and the page displays an appropriate error message.

Here’s an example of what the script displays when you access it through your web browser:

Output of the PHP application


For developers who are used to traditional web applications, the real-time data streams and publish/subscribe mechanisms of the IoT universe take some getting used to. IBM Cloud and the IBM Watson IoT Platform help reduce the learning curve by providing all the necessary infrastructure to receive, manage, and transmit data to and from IoT sensors. If you add in some PHP glue, you’ll be on your way to building IoT applications with IBM Cloud in no time.

The concepts that were discussed in this article are only the tip of the iceberg. For example, this tutorial discussed only receiving and processing event data from IoT sensors – one-way communication, if you will. However, it’s just as easy (and even more interesting) to implement two-way communication loops to make IoT sensors react to requests and perform tasks or calculations.


Steps 1-5 in this article are based on the m2m @ IBM IoT Starter application tutorial by Mark Halliday and Bryan Boyd.