DIO0 REST Server using Express & NodeJS

Introduction

Today we will make a REST server using NodeJS. For this tutorial, it is assume that you are familiar NodeJS & 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:

  • Device related problem (example: communication)
    Code: 500 Internal Server Error
    Type: text/plain
    Content: B0_ERR_IO: Device I/O error

  • Invalid argument
    Code: 400 Bad Request
    Type: text/plain
    Content: Invalid pin "a"

Code

In [ ]:
"use strict";

var express = require('express')
var box0 = require('../lib/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.pin_count,
        ref: {low, high}
    })
})

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

    invalid_arg(res, util.format('Invalid pin "%s"', pin))
})

app.get('/dio/0/:pin', function (req, res) {
    handle_exception(res, function () {
        var pin = req.pin
        var name = dio0.label.pin[pin]
        if (name == null) {
            name = 'CH' + pin
        }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    if (value === undefined) {
        var msg = util.format('Invalid value "%s"', 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('Listening on port 3000!')
    dio0.basic_prepare()
    dio0.basic_start()
})

process.on('SIGINT', function() {
    console.log("\nGracefully shutting down from SIGINT (Ctrl+C)")
    dio0.basic_stop()
    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!