Node.js based Web Application for mbed Device Connector specific to GR-PEACH_mbed-os-client-ZXingSample

Getting Started

Installing Node.js and npm

You need to have Node.js and npm installed.

To check if you have them installed, open a terminal or command prompt and run the following commands:

node --version
npm --version

If you see an number output similar to x.x.x for each command, then they are both installed and you can continue to the next section.

To install on Windows or mac, you can download the installer from https://nodejs.org/en/download.

To install on Linux, you can use a package manager. Instructions for installing Node.js on your distribution can be found in the following link:
https://nodejs.org/en/download/package-manager

Pre-requisite

This example assumes that you have the following example that can connect to mbed Device Connector:

Import programGR-PEACH_mbed-os-client-ZXingSample

This is a mbed Client sample where ZXing is incorporated, and works on GR-PEACH and GR-LYCHEE.

Configuring the App

Before running this app, you need to set some config options. This is done through environment variables or .env file stored in the root of the project.

The following variables are available to be configured:

  • ACCESS_KEY
    Set this to your Access Key you created in mbed Device Connector. If you don't have an Access Key, please create it by the following procedure:
    1. Access https://connector.mbed.com/#accesskeys.
    2. Click Create New Access Key.
    /media/uploads/HinoNaka/screenshot7.png
    When prompted, enter a name for the access key (ex. "demo") and click ADD.
    /media/uploads/HinoNaka/screenshot8.png
    3. Copy the access key you just created and use it in .env file.

  • PORT:
    Set this to override the default port for this example. The default port is 8080.

The .env file format is as follows:

ACCESS_KEY=Your ACCESS KEY
PORT=Port to be overridden (This is optional and can be omitted.)

Configuring the App

Once you've configured the example, you need to install its dependencies. Open a terminal or command prompt and run the following command:

npm install

If all the dependencies successfully installed, you can now run the app by using the following command:

node app.js

You should receive the following output:

mbed Device Connector Quickstart listening at http://localhost:8080

Copy and paste the printed URL into your browser and you should see the following screen: /media/uploads/HinoNaka/screenshot9-1.png

Deploying this example on HEROKU

HEROKU ( https://id.heroku.com ) is PaaS (Platform as a Service) on which Node.js application can deploy free-of charge. By utilizing it, user can confirm the decode result and control LED blink from your mobile terminal.

Here is the procedure to deploy this application on HEROKU:

  1. Create your HEROKU account at https://signup.heroku.com/login if you haven't created it yet.
  2. Open a terminal or command prompt and invoke the command heroku login. If Email and password is required, please type those registered at the step 1.
  3. Invoke git init to create a local git repository.
  4. Invoke git add . to add all the files to the local repository.
  5. Invoke git commit -m "[commit message]" to commit the files.
  6. Invoke heroku create at the root of the project. When successfully terminated, the remote repository heroku should be created and associated with the local repository.
  7. Invoke git push heroku master. When successfully terminated, this example application should be deployed on HEROKU.
  8. Invoke heroku open. If the example is successfully deployed, Webapp Quickstart shown above should be displayed on your browser. Also, by accessing the URL shown in the browser from your mobile terminal (e.g. iPhone), you can confirm the decode result and control LED blink from there.

    /media/uploads/HinoNaka/screenshot10.png

app.js

Committer:
Osamu Nakamura
Date:
2017-03-10
Revision:
4:a682455428ae
Parent:
0:ee84b944af4c

File content as of revision 4:a682455428ae:

// Load .env config (silently fail if no .env present)
require('dotenv').config({ silent: true });

// Require necessary libraries
var async = require('async');
var ioLib = require('socket.io');
var http = require('http');
var path = require('path');
var express = require('express');
var MbedConnectorApi = require('mbed-connector-api');

// CONFIG (change these)
var accessKey = process.env.ACCESS_KEY || "ChangeMe";
var port = process.env.PORT || 8080;

// Paths to resources on the endpoints
var blinkResourceURI = '/3201/0/5850';
var blinkPatternResourceURI = '/3201/0/5853';
var colorResourceURI = '/3201/0/5855';
var ZXingURI = '/3202/0/5700';

// Instantiate an mbed Device Connector object
var mbedConnectorApi = new MbedConnectorApi({
  accessKey: accessKey
});

// Create the express app
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use(express.static(path.join(__dirname, 'public')));

app.get('/', function (req, res) {
  // Get all of the endpoints and necessary info to render the page
  mbedConnectorApi.getEndpoints(function(error, endpoints) {
    if (error) {
      throw error;
    } else {
      // Setup the function array
      var functionArray = endpoints.map(function(endpoint) {
        return function(mapCallback) {
          mbedConnectorApi.getResourceValue(endpoint.name, blinkPatternResourceURI, function(error, value) {
            endpoint.blinkPattern = value;
            mbedConnectorApi.getResourceValue(endpoint.name, colorResourceURI, function(error, value) {
              endpoint.color = value;
              mapCallback(error);
            });
          });
        };
      });

    // Fetch all blink patterns in parallel, finish when all HTTP
    // requests are complete (uses Async.js library)
      async.parallel(functionArray, function(error) {
        if (error) {
          res.send(String(error));
        } else {
          res.render('index', {
            endpoints: endpoints
          });
        }
      });
    }
  });
});

// Handle unexpected server errors
app.use(function(err, req, res, next) {
  console.log(err.stack);
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: err
  });
});

var sockets = [];
var server = http.Server(app);
var io = ioLib(server);

// Setup sockets for updating web UI
io.on('connection', function (socket) {
  // Add new client to array of client upon connection
  sockets.push(socket);

  socket.on('subscribe-to-decode', function (data) {
    // Subscribe to all changes of resource /3202/0/5700 (Barcode decoded Data)
    mbedConnectorApi.putResourceSubscription(data.endpointName, ZXingURI, function(error) {
      if (error) throw error;
      socket.emit('subscribed-to-decode', {
        endpointName: data.endpointName
      });
    });
  });

  socket.on('unsubscribe-to-decode', function(data) {
    // Unsubscribe from the resource /3202/0/5700 (Barcode decoded Data)
    mbedConnectorApi.deleteResourceSubscription(data.endpointName, ZXingURI, function(error) {
      if (error) throw error;
      socket.emit('unsubscribed-to-decode', {
        endpointName: data.endpointName
      });
    });
  });

  socket.on('get-decode', function(data) {
    // Read data from GET resource /3202/0/5700 (Barcode decoded Data)
    mbedConnectorApi.getResourceValue(data.endpointName, ZXingURI, function(error, value) {
      if (error) throw error;
      socket.emit('decode', {
        endpointName: data.endpointName,
        value: value
      });
    });
  });

  socket.on('update-blink-pattern', function(data) {
    // Set data on PUT resource /3201/0/5853 (pattern of LED blink)
    mbedConnectorApi.putResourceValue(data.endpointName, blinkPatternResourceURI, data.blinkPattern, function(error) {
      if (error) throw error;
    });
  });

  socket.on('update-color', function(data) {
    // Set data on PUT resource /3201/0/5855 (LED color)
    mbedConnectorApi.putResourceValue(data.endpointName, colorResourceURI, data.color, function(error) {
      if (error) throw error;
    });
  });

  socket.on('blink', function(data) {
    // POST to resource /3201/0/5850 (start blinking LED)
    mbedConnectorApi.postResource(data.endpointName, blinkResourceURI, null, function(error) {
      if (error) throw error;
    });
  });

  socket.on('disconnect', function() {
    // Remove this socket from the array when a user closes their browser
    var index = sockets.indexOf(socket);
    if (index >= 0) {
      sockets.splice(index, 1);
    }
  })
});

// When notifications are received through the notification channel, pass the
// button presses data to all connected browser windows
mbedConnectorApi.on('notification', function(notification) {
  if (notification.path === ZXingURI) {
    sockets.forEach(function(socket) {
      socket.emit('decode', {
        endpointName: notification.ep,
        value: notification.payload
      });
    });
  }
});

// Start the app
server.listen(port, function() {
  // Set up the notification channel (pull notifications)
  mbedConnectorApi.startLongPolling(function(error) {
    if (error) throw error;
    console.log('mbed Device Connector Quickstart listening at http://localhost:%s', port);
  })
});