Browser Connection to REST API

This article is part of a series with the name IoT Remote Power Switch – Project Part 7.

It describes how to connect a browser to a server’s REST API and how it can be tested.

Goal

What do I mean by browser connection to REST API? Generally speaking, I want to turn my static web page into a dynamic one.
Some weeks ago I’ve programmed the static page. This was the result. It lacks 2 major features: it should send the OFF and ON button clicks to the server, and it should display the state of the selected Remote Power Switch and update it periodically.

Changes to the Existing Code

I’ve written about the REST API of the web server in the last post. The browser code I’m implementing now is programmed against this API.
15 years ago, I’d have had to reload the whole HTML/CSS page when I had wanted to update the status field. This would have generated a lot of network traffic overhead, and it was visible to the user since the browser had to re-generate the whole page from scratch. All in all a bad user experience.
In order to improve this, AJAX calls were invented. AJAX stands for Asynchronous JavaScript and XML. AJAX calls allow updating just one field or element (or many) of a web page. It is supported by several JavaScript libraries, one of them (probably currently the most wide spread) being jQuery. Initially, AJAX calls required the involvement of XML, but nowadays the libraries allow JSON or text encoded data transfers as well.

In brief, I’ve added a JavaScript function called buttonClicked() to the index.html file. It executes an AJAX call when a button is clicked. This call sends the requested new state of the Remote Power Switch with the specified device identifier to the web server. It issues HTTP POST messages for this purpose.
Furthermore, I’ve added an updateStatus() function. It updates the status of the selected Remote Power Switch by sending periodic HTTP GET messages to the server.

For those interested I’ve listed the changes compared to the pre-release v0.1 (shown here) in the release notes on GitHub (follow this link)

Testing

I describe here how I tested the functionality of my code. I’ve put down some steps in detail without the intention to store ALL possible test combinations. This isn’t a fully fledged test procedure, rather a collection of ideas how the functionality can be tested.
Open a Linux shell window and start the web server locally:

$> cd to/top-level/project/directory
$> node server/app.js

Note that the web server outputs some log information inside this window. Occasionally it can be helpful reading it.

Open a second Linux shell window for manipulating the data stored in the database. Type the following:

$> mongo
> use rps
> db.status.drop()
> db.switches.drop()

This drops the relevant collections and all their data sets in the database with the name rps. I’m going to load new data sets for testing in the next step.

Open another shell window for loading test data into the database. Use the following commands:

$> cd to/top-level/project/directory
$> mongoimport --db rps --collection status --file data/status.json
$> mongoimport --db rps --collection switches --file data/switches.json

Now I can check if the data has been loaded into the database and how it looks like. For this purpose I go back to the second shell window (the mongodb command line) and type:

> db.status.find()
> db.switches.find()

This displays all data sets. I can start testing now.

OFF/ON Buttons

Open a browser and enter the following URL in the address field: http://localhost:9000/index.html. It should display the improved web page. The field Device Identifier should be empty, and the Status should display UNKNOWN. (Reloading the page should always return it to this state.)

  1. Enter 1 in the device identifier field and click on the OFF button –> After ~1s the status should change from UNKNOWN to OFF
  2. Enter 1 in the device identifier field and click on the ON button –> The status should stay OFF
  3. Enter 2 in the device identifier field and click on the ON button –> After ~1s the status should change from OFF to ON
  4. Enter 0 in the device identifier field and click on the OFF button –> After ~1s the status should change from OFF to UNKNOWN
  5. Enter 1 in the device identifier field and click on the OFF button –> After ~1s the status should change from UNKNOWN to OFF

Explanation: Entering a device identifier and clicking a button activates the polling of the status from the server. Device 1 is currently off. Device 2 is currently on. Device 0 is unknown to the server (no entry in the database), thus it’s state is unknown.

I want to check now if the requested status change made it into the server. For this purpose I need simulating the Remote Power Switch on the other end (or it’s embedded computer respectively). How’d I do that? Google’s Postman extension to Chrome is a possibility.
I open this application and issue the following HTTP message to the web server: GET http://localhost:9000/switches/1. The server should respond with a JSON message that indicates the requested state of the switch, which is currently OFF. That’s the last step of the test sequence above. If I enter device identifier 1 in the browser and click on the ON button, and then repeat the GET command in Postman, I should get an ON state back.

Status Display

Execute this step in the browser as a preparation for the test:

  • Enter 2 in the device identifier field and click on the OFF button –> The status should stay ON

In order to see a status change in the browser I need simulating the Remote Power Switch on the other end. I switch to the Postman window and issue the following HTTP message to the web server: POST http://localhost:9000/status/2/off. About 1s later, the status field on the web page should change from OFF to ON. Note that this change creates an entry in the database. If I’d power cycle my computer now and bring the web server up again, the status of device #1 will still be ON.
I can switch device 2 back to on by issuing a POST http://localhost:9000/status/1/on message.
If I wanted to change the status of device 1, I had to enter POST http://localhost:9000/status/1/on. This indicates that the Remote Power Switch with the device identifier 1 is on now.

Responsiveness of the HTML5/CSS3 Design

Since I’m using bootstrap, it should display well on tablets and smart phones. Bootstrap supports responsive web design. This can be simulated using Chrome’s dev tools (Ctrl-Shift-I), and I’ll of course see it on my cell phone once the web server is on-line in the cloud.

Summary and Outlook

With this work I am done on the client side. It’s far from being perfect but good enough for a starter project.
You find the source code here; it’s pre-release v0.5. Note that the node_modules folder isn’t part of the repository. After downloading the repo or its zip file you’ll have to change directory to the top-level folder of the project and run $> npm install.

Referring to the diagram in the first post of this series, I see what is missing:

  • The embedded computer
  • The software on the embedded computer
  • The power switch

I’ll buy the embedded computer and the power switch off the shelf. In order to simplify software development, I’ll order a Linux computer like the Raspberry Pi or BeagleBone. Compared to a smaller board (one with much less memory and CPU power) like ST Microelectronics’s NUCLEO-F401RE, the former offer free (Ethernet) network connectivity hardware and software wise.
The major advantage of a Raspberry Pi or Beaglebone is however that I can program, run and test the application on any Linux computer with a C/C++ environment. I’ll show how to do that in my next post.