Skip to content
Snippets Groups Projects
Verified Commit 79913334 authored by Erick Hitter's avatar Erick Hitter
Browse files

Rewrite as single API endoint, ensuring lock is always disconnected before request completes

Resolves issue where lock would remain connected, blocking subsequent requests (and those from the official apps) until the node server was restarted.
parent e8f69fd0
No related branches found
No related tags found
No related merge requests found
'use strict'; 'use strict';
var augustctl = require('./index'); var augustctl = require( './index' );
var express = require('express'); var express = require( 'express' );
var morgan = require('morgan'); var morgan = require( 'morgan' );
var await = require('asyncawait/await'); var await = require( 'asyncawait/await' );
var async = require('asyncawait/async'); var async = require( 'asyncawait/async' );
var config = require(process.env.AUGUSTCTL_CONFIG || './config.json');
var serverConfig = require(process.env.AUGUSTCTL_SERVER_CONFIG || './server-config.json');
var DEBUG = process.env.NODE_ENV !== 'production';
var address = serverConfig.address || 'localhost';
var port = serverConfig.port || 3000;
var app = express();
app.use(morgan(DEBUG ? 'dev' : 'combined'));
var ret = {'status': -1, 'ret': '', 'msg': ''};
app.get('/api/unlock/:lock_name', function(req, res) {
var lock = app.get('lock' + req.params.lock_name);
if (!lock) {
res.sendStatus(503);
return;
}
var execStatus = async(function() {
var status = await(lock.status());
if(status == 'locked')
{
var cmd = await(lock.forceUnlock());
ret['msg'] = 'Command completed. Disconnected.';
ret['status'] = 0;
ret['ret'] = 'unlocked';
console.log('Released unlock request');
}
else
{
ret['status'] = 1;
ret['msg'] = 'Lock is already unlocked';
res.json(ret);
}
lock.disconnect();
res.json(ret);
});
lock.connect().then(function(){
var exec = execStatus();
}).finally(function(){
console.log('Finally');
});
});
app.get('/api/lock/:lock_name', function(req, res) {
var lock = app.get('lock' + req.params.lock_name);
if (!lock) {
res.sendStatus(503);
return;
}
var execLock = async(function() {
var status = await(lock.status());
if(status == 'unlocked')
{
var cmd = await(lock.forceLock()); var config = require( process.env.AUGUSTCTL_CONFIG || './config.json' );
ret['msg'] = 'Command completed. Disconnected.'; var serverConfig = require( process.env.AUGUSTCTL_SERVER_CONFIG || './server-config.json' );
ret['status'] = 0;
ret['ret'] = 'locked';
console.log('Released lock request');
} var DEBUG = process.env.NODE_ENV !== 'production';
else var address = serverConfig.address || 'localhost';
{ var port = serverConfig.port || 3000;
ret['status'] = 1;
ret['msg'] = 'Lock is already locked';
}
res.json(ret);
lock.disconnect();
});
lock.connect().then(function(){
var status = execLock();
}).finally(function(){
console.log('Finally');
});
});
app.get('/api/status/:lock_name', function(req, res){
var lock = app.get('lock' + req.params.lock_name);
if(!lock) {
res.sendStatus(503);
return;
}
var execStatus = async(function() {
var status = await(lock.status());
ret['ret'] = status;
ret['status'] = 0;
ret['msg'] = 'Command completed.';
console.log('Disconnecting');
lock.disconnect();
console.log('Returning');
res.json(ret);
});
lock.connect().then(function() {
var status = execStatus();
}).finally(function() {
console.log('Finally');
});
});
Object.keys(config).forEach( function( lockName ) {
var lockConfig = config[lockName];
augustctl.scan(lockConfig.lockUuid).then(function (peripheral) { var app = express();
app.use( morgan( DEBUG ? 'dev' : 'combined' ) );
// Default return arguments
var ret = {
'status': -1,
'ret': '',
'msg': ''
};
// Endpoint to perform all lock actions
app.get( '/api/:lock_action/:lock_name', function( req, res ) {
// Parse allowed request arguments
var action = req.params.lock_action,
allowedActions = [ 'unlock', 'lock', 'status' ];
if ( -1 === allowedActions.indexOf( action ) ) {
res.sendStatus( 400 );
return;
}
var lock = app.get( 'lock' + req.params.lock_name );
if ( ! lock ) {
res.sendStatus( 400 );
return;
}
// Suspendable functions to interact with lock based on requested action
if ( 'status' === action ) {
// Checks lock's state and returns it
var actionFunction = async( function() {
var status = await( lock.status() ),
statusInt = -1;
if ( 'locked' === status ) {
statusInt = 0;
} else if ( 'unlocked' === status ) {
statusInt = 1;
}
ret.ret = status;
ret.status = statusInt;
ret.msg = "Status checked successfully.";
lock.disconnect();
res.json( ret );
} );
} else {
// Locks or unlocks a requested lock, if not already in that state
var actionFunction = async( function() {
var status = await( lock.status() );
if ( 'lock' === action && 'unlocked' === status ) {
var cmd = await( lock.forceLock() );
ret.ret = 'locked';
ret.status = 0;
ret.msg = 'Locked as requested.';
} else if ( 'unlock' === action && 'locked' === status ) {
var cmd = await( lock.forceUnlock() );
ret.ret = 'unlocked';
ret.status = 1;
ret.msg = 'Unlocked as requested.';
} else {
var statusInt = -1;
if ( 'locked' === status ) {
statusInt = 0;
} else if ( 'unlocked' === status ) {
statusInt = 1;
}
ret.ret = status;
ret.status = statusInt;
ret.msg = "No change made. Lock was already '" + status + "'.";
}
lock.disconnect();
res.json( ret );
} );
}
// Perform requested action
lock.connect().then( actionFunction ).catch( function( err ) {
console.error( err );
lock.disconnect();
res.sendStatus( 500 );
} );
} );
// Parse lock configurations
Object.keys( config ).forEach( function( lockName ) {
var lockConfig = config[ lockName ];
augustctl.scan( lockConfig.lockUuid ).then( function( peripheral ) {
var lock = new augustctl.Lock( var lock = new augustctl.Lock(
peripheral, peripheral,
lockConfig.offlineKey, lockConfig.offlineKey,
lockConfig.offlineKeyOffset lockConfig.offlineKeyOffset
); );
app.set('lock' + lockName, lock); app.set('lock' + lockName, lock);
}); } );
}); } );
var server = app.listen(port, address, function() {
console.log('Listening at %j', server.address()); // Start Express server
}); var server = app.listen( port, address, function() {
console.log( 'Listening at %j', server.address() );
} );
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment