Close

Box0 + Node.js = REST Server

A project log for Box0

Free and open source tool for exploring science and electronics anytime anywhere

Kuldeep Singh DhakaKuldeep Singh Dhaka 05/03/2016 at 11:160 Comments

Introduction

Today we will make a REST server using Node.js.
For this tutorial, it is assume that you are familiar Node.js & Express

API

Read Device information

URL: /
Method: GET
Response: {"name":"Box0","manuf":"Mad Resistor","serial":"A2005400E015843503134302"}

Read DIO0 information

URL: /dio/0
Method: GET
Success Response: {"name":"DIO0","count":8,"ref":{"low":"0.000000","high":"3.300000"}}

Read DIO0 pin information

URL: /dio/0/:pin
Method: GET
Success Response: {"pin":0,"name":"0","value":"low","dir":"input","hiz":"enabled"}

Get DIO0 pin value

URL: /dio/0/:pin/value
Method: GET
Success Response: {"pin":0,"value":"low"}

Set DIO0 pin value

URL: /dio/0/:pin/value/:value
Method: GET
Note: :value can be low or high
Success Response: {"pin":0}

Toggle DIO0 pin value

URL: /dio/0/:pin/toggle
Method: GET
Success Response: {"pin":0}
Note: Should only be called when pin is in output direction

Get DIO0 pin direction

URL: /dio/0/:pin/dir
Method: GET
Success Response: {"pin":0,"dir":"input"}

Set DIO0 pin direction

URL: /dio/0/:pin/dir/:value
Method: GET
Note: :value can be input or output
Success Response: {"pin":0}

Get DIO0 pin High Impedence value

URL: /dio/0/:pin/hiz
Method: GET
Success Response: {"pin":0,"hiz":"enabled"}

Set DIO0 pin High Impedence value

URL: /dio/0/:pin/hiz/:value
Method: GET
Note: :value can be enable or disable
Success Response: {"pin":0}

Common Error Response:

Code

"use strict";

var express = require('express')
var box0 = require('box0')
var util = require('util')

var dev = box0.usb.open_supported()
var dio0 = dev.dio()

var app = express()

function invalid_arg(res, msg) {
    res.set('Content-Type', 'text/plain')
    res.status(400).send(msg)
}

function handle_exception(res, cb) {
    try {
        cb();
    } catch (e) {
        res.set('Content-Type', 'text/plain')
        res.status(500).send(e.message)
    }
}

app.get('/', function (req, res) {
    res.json({
        name: dev.name,
        manuf: dev.manuf,
        serial: dev.serial
    })
})

app.get('/dio/0', function (req, res) {
    var low = dio0.ref.low.toFixed(6)
    var high = dio0.ref.high.toFixed(6)

    res.json({
        name: dio0.header.name,
        count: dio0.count.value,
        ref: {low, high}
    })
})

app.param('pin', function(req, res, next, pin) {
    var pin_value = parseInt(pin)
    if (pin_value >= 0 && pin_value < dio0.count.value) {
        req.pin = pin_value
        next()
        return
    }

    invalid_arg(res, util.format(&apos;Invalid pin "%s"&apos;, pin))
})

app.get(&apos;/dio/0/:pin&apos;, function (req, res) {
    handle_exception(res, function () {
        var pin = req.pin
        var name = (pin < dio0.label.values.length) ?
                dio0.label.values[pin] : &apos;CH&apos; + pin

        var value = dio0.value_get(pin)
        var dir = dio0.dir_get(pin)
        var hiz = dio0.hiz_get(pin)

        value = {true: &apos;high&apos;, false: &apos;low&apos;}[value]
        dir = {true: &apos;output&apos;, false: &apos;input&apos;}[dir]
        hiz = {true: &apos;enabled&apos;, false: &apos;disabled&apos;}[hiz]

        res.json({pin, name, value, dir, hiz})
    })
})

app.get(&apos;/dio/0/:pin/value&apos;, function (req, res) {
    handle_exception(res, function () {
        var pin = req.pin
        var value = dio0.value_get(pin)
        value = {true: &apos;high&apos;, false: &apos;low&apos;}[value]
        res.json({pin, value})
    })
})

app.get(&apos;/dio/0/:pin/dir&apos;, function (req, res) {
    handle_exception(res, function () {
        var pin = req.pin
        var dir = dio0.dir_get(pin)
        dir = {true: &apos;output&apos;, false: &apos;input&apos;}[dir]
        res.json({pin, dir})
    })
})

app.get(&apos;/dio/0/:pin/hiz&apos;, function (req, res) {
    handle_exception(res, function () {
        var pin = req.pin
        var hiz = dio0.hiz_get(pin)
        hiz = {true: &apos;enabled&apos;, false: &apos;disabled&apos;}[hiz]
        res.json({pin, hiz})
    })
})

app.get(&apos;/dio/0/:pin/toggle&apos;, function (req, res) {
    handle_exception(res, function () {
        var pin = req.pin
        dio0.value_toggle(pin)
        res.json({pin})
    })
})

app.get(&apos;/dio/0/:pin/value/:value&apos;, function (req, res) {
    var pin = req.pin
    var value = String(req.params.value).toLowerCase()
    value = {&apos;high&apos;: true, &apos;low&apos;: false}[value]

    if (value === undefined) {
        var msg = util.format(&apos;Invalid value "%s"&apos;, req.params.value)
        return invalid_arg(res, msg)
    }

    handle_exception(res, function () {
        dio0.value_set(pin, value)
        res.json({pin})
    })
})

app.get(&apos;/dio/0/:pin/dir/:value&apos;, function (req, res) {
    var pin = req.pin
    var value = String(req.params.value).toLowerCase()
    value = {&apos;output&apos;: true, &apos;input&apos;: false}[value]

    if (value === undefined) {
        var msg = util.format(&apos;Invalid value "%s"&apos;, req.params.value)
        return invalid_arg(res, msg)
    }

    handle_exception(res, function () {
        dio0.dir_set(pin, value)
        res.json({pin})
    })
})

app.get(&apos;/dio/0/:pin/hiz/:value&apos;, function (req, res) {
    var pin = req.pin
    var value = String(req.params.value).toLowerCase()
    value = {&apos;enable&apos;: true, &apos;disable&apos;: false}[value]

    if (value === undefined) {
        var msg = util.format(&apos;Invalid value "%s"&apos;, req.params.value)
        return invalid_arg(res, msg)
    }

    handle_exception(res, function () {
        dio0.hiz_set(pin, value)
        res.json({pin})
    })
})

app.listen(3000, function () {
    console.log(&apos;Listening on port 3000!&apos;)
})

process.on(&apos;SIGINT&apos;, function() {
    console.log("\nGracefully shutting down from SIGINT (Ctrl+C)")
    dio0.close()
    dev.close()
    process.exit(1)
})

Interacting

You can use your Internet Browser / telnet to interact with the REST server.

Get device information

Request: GET /
Response: {"name":"Box0","manuf":"Mad Resistor","serial":"A2005400E015843503134302"}

Get DIO0 module information

Request: GET /dio/0
Response: {"name":"DIO0","count":8,"ref":{"low":"0.000000","high":"3.300000"}}

There are 8 pins for this device with low voltage 0V and high voltage 3.3V
You can reference 8 pins via 0, 1, 2, ... 7

Turn On LED on pin number 3

Requests:

  1. GET /dio/0/3/dir/output
  2. GET /dio/0/3/value/high
  3. GET /dio/0/3/hiz/disable

Your led will blink

Reading from pin 4

Requests:

  1. GET /dio/0/4/dir/input
  2. GET /dio/0/4/hiz/disable
  3. GET /dio/0/4/value

Resonse (from 3rd query): {"pin":4,"value":"low"}
This tells that pin 4 is LOW.

Toggle pin 3 value

Requests:

  1. GET /dio/0/3/dir/output
  2. GET /dio/0/3/value/low
  3. GET /dio/0/3/hiz/disable
  4. GET /dio/0/3/toggle
  5. GET /dio/0/3/toggle
  6. GET /dio/0/3/toggle

and continue toggling it!

Discussions