666 lines
14 KiB
JavaScript
666 lines
14 KiB
JavaScript
'use strict'
|
|
|
|
const restify = require('restify')
|
|
const log = require('./lib/log')('main')
|
|
const { readFile } = require('fs-extra')
|
|
const { exec } = require('child_process')
|
|
|
|
const BLE = require('./lib/ble')
|
|
const Intval = require('./lib/intval')
|
|
const intval = new Intval()
|
|
const Sequence = require('./lib/sequence')
|
|
const sequence = new Sequence(intval)
|
|
|
|
const PACKAGE = require('./package.json')
|
|
const PORT = process.env.PORT || 6699
|
|
const APPNAME = PACKAGE.name
|
|
const INDEXPATH = './app/www/index.html'
|
|
|
|
let app = restify.createServer({
|
|
name: APPNAME,
|
|
version: PACKAGE.version
|
|
})
|
|
|
|
let ble
|
|
|
|
async function execAsync (cmd) {
|
|
return new Promise((resolve, reject) => {
|
|
return exec(cmd, (err, stdio, stderr) => {
|
|
if (err) {
|
|
return reject(err)
|
|
}
|
|
return resolve(stdio)
|
|
})
|
|
})
|
|
}
|
|
|
|
async function info () {
|
|
const data = {
|
|
version : PACKAGE.version,
|
|
node : null,
|
|
npm : null,
|
|
os : null,
|
|
kernel : null
|
|
}
|
|
|
|
try {
|
|
data.node = await execAsync('node -v')
|
|
data.node = data.node.replace(/(\r\n|\n|\r)/gm, '')
|
|
} catch (err) {
|
|
log.error(err)
|
|
}
|
|
|
|
try {
|
|
data.npm = await execAsync('npm -v')
|
|
data.npm = data.npm.replace(/(\r\n|\n|\r)/gm, '')
|
|
} catch (err) {
|
|
log.error(err)
|
|
}
|
|
|
|
try {
|
|
data.kernel = await execAsync('uname -r')
|
|
data.kernel = data.kernel.replace(/(\r\n|\n|\r)/gm, '')
|
|
} catch (err) {
|
|
log.error(err)
|
|
}
|
|
|
|
try {
|
|
data.os = await execAsync('lsb_release -a | grep "Description"')
|
|
data.os = data.os.replace('Description:', '').replace(/(\r\n|\n|\r)/gm, '').trim()
|
|
} catch (err) {
|
|
log.error(err)
|
|
}
|
|
|
|
return data
|
|
}
|
|
|
|
function createServer () {
|
|
app.use(restify.plugins.queryParser())
|
|
app.use(restify.plugins.bodyParser({ mapParams: false }))
|
|
app.get( '/', index)
|
|
app.get( '/dir', rDir)
|
|
app.post('/dir', rDir)
|
|
app.get( '/exposure', rExposure)
|
|
app.post('/exposure', rExposure)
|
|
app.get( '/delay', rDelay)
|
|
app.post('/delay', rDelay)
|
|
app.get( '/counter', rCounter)
|
|
app.post('/counter', rCounter)
|
|
app.get( '/frame', rFrame)
|
|
app.post('/frame', rFrame)
|
|
app.get( '/sequence', rSequence)
|
|
app.post('/sequence', rSequence)
|
|
|
|
app.get( '/status', rStatus)
|
|
app.get( '/info', rInfo)
|
|
app.post('/reset', rReset)
|
|
app.post('/update', rUpdate)
|
|
app.post('/restart', rRestart)
|
|
|
|
|
|
app.listen(PORT, () => {
|
|
log.info('server', { name : APPNAME, port : PORT })
|
|
})
|
|
}
|
|
|
|
function createBLE () {
|
|
ble = new BLE(() => {
|
|
return intval.status()
|
|
})
|
|
ble.on('frame', bFrame)
|
|
ble.on('dir', bDir)
|
|
ble.on('exposure', bExposure)
|
|
ble.on('delay', bDelay)
|
|
ble.on('counter', bCounter)
|
|
ble.on('sequence', bSequence)
|
|
|
|
ble.on('reset', bReset)
|
|
ble.on('update', bUpdate)
|
|
ble.on('restart', bRestart)
|
|
}
|
|
|
|
async function rInfo (req, res, next) {
|
|
let data = {}
|
|
try {
|
|
data = await info()
|
|
} catch (err) {
|
|
log.error(err)
|
|
return next(err)
|
|
}
|
|
res.send(data)
|
|
return next()
|
|
}
|
|
|
|
//Restify functions
|
|
function rDir (req, res, next) {
|
|
let dir = true
|
|
let set = false
|
|
if (req.query && typeof req.query.dir !== 'undefined') {
|
|
if (typeof req.query.dir === 'string') {
|
|
dir = (req.query.dir === 'true')
|
|
} else {
|
|
dir = req.query.dir
|
|
}
|
|
set = true
|
|
} else if (req.body && typeof req.body.dir !== 'undefined') {
|
|
if (typeof req.body.dir === 'string') {
|
|
dir = (req.body.dir === 'true')
|
|
} else {
|
|
dir = req.body.dir
|
|
}
|
|
set = true
|
|
}
|
|
if (set) {
|
|
intval.setDir(dir)
|
|
} else {
|
|
dir = intval._state.frame.dir
|
|
}
|
|
log.info('/dir', { method: req.method, set : set, dir : dir})
|
|
res.send({ dir : dir })
|
|
return next()
|
|
}
|
|
|
|
function rExposure (req, res, next) {
|
|
let exposure = 0
|
|
let set = false
|
|
if (req.query && typeof req.query.exposure !== 'undefined') {
|
|
if (typeof req.query.exposure === 'string') {
|
|
exposure = parseInt(req.query.exposure)
|
|
} else {
|
|
exposure = req.query.exposure
|
|
}
|
|
set = true
|
|
} else if (req.body && typeof req.body.exposure !== 'undefined') {
|
|
if (typeof req.body.exposure === 'string') {
|
|
exposure = parseInt(req.body.exposure)
|
|
} else {
|
|
exposure = req.body.exposure
|
|
}
|
|
set = true
|
|
}
|
|
if (set) {
|
|
if (exposure <= intval._frame.expected) {
|
|
exposure = 0;
|
|
}
|
|
intval.setExposure(exposure)
|
|
} else {
|
|
exposure = intval._state.frame.exposure
|
|
}
|
|
log.info('/exposure', { method: req.method, set : set, exposure : exposure })
|
|
res.send({ exposure : exposure })
|
|
return next()
|
|
}
|
|
|
|
function rDelay (req, res, next) {
|
|
let delay = 0
|
|
let set = false
|
|
if (req.query && typeof req.query.delay !== 'undefined') {
|
|
if (typeof req.query.delay === 'string') {
|
|
delay = parseInt(req.query.delay)
|
|
} else {
|
|
delay = req.query.delay
|
|
}
|
|
set = true
|
|
}
|
|
if (req.body && typeof req.body.delay !== 'undefined') {
|
|
if (typeof req.body.delay === 'string') {
|
|
delay = parseInt(req.body.delay)
|
|
} else {
|
|
delay = req.body.delay
|
|
}
|
|
set = true
|
|
}
|
|
if (set) {
|
|
intval.setDelay(delay)
|
|
} else {
|
|
delay = intval._state.frame.delay
|
|
}
|
|
log.info('/delay', { method: req.method, set : set, delay : delay })
|
|
res.send({ delay : delay })
|
|
return next()
|
|
}
|
|
|
|
function rCounter (req, res, next) {
|
|
let counter = 0
|
|
let set = false
|
|
if (req.query && typeof req.query.counter !== 'undefined') {
|
|
if (typeof req.query.counter === 'string') {
|
|
counter = parseInt(req.query.counter)
|
|
} else {
|
|
counter = req.query.counter
|
|
}
|
|
set = true
|
|
}
|
|
if (req.body && typeof req.body.counter !== 'undefined') {
|
|
if (typeof req.body.counter !== 'string') {
|
|
counter = parseInt(req.body.counter)
|
|
} else {
|
|
counter = req.body.counter
|
|
}
|
|
set = true
|
|
}
|
|
if (set) {
|
|
intval.setCounter(counter)
|
|
} else {
|
|
counter = intval._state.counter
|
|
}
|
|
log.info('/counter', { method : req.method, set : set, counter : counter })
|
|
res.send({ counter : counter })
|
|
return next()
|
|
}
|
|
|
|
async function rFrame (req, res, next) {
|
|
let dir = true
|
|
let exposure = 0
|
|
let success = false
|
|
if (intval._state.frame.dir !== true) {
|
|
dir = false
|
|
}
|
|
if (intval._state.frame.exposure !== 0) {
|
|
exposure = intval._state.frame.exposure
|
|
}
|
|
if (req.query && typeof req.query.dir !== 'undefined') {
|
|
if (typeof req.query.dir === 'string') {
|
|
dir = (req.query.dir === 'true')
|
|
} else {
|
|
dir = req.query.dir
|
|
}
|
|
}
|
|
if (req.body && typeof req.body.dir !== 'undefined') {
|
|
if (typeof req.body.dir === 'string') {
|
|
dir = (req.body.dir === 'true')
|
|
} else {
|
|
dir = req.body.dir
|
|
}
|
|
}
|
|
if (req.query && typeof req.query.exposure !== 'undefined') {
|
|
if (typeof req.query.exposure === 'string') {
|
|
exposure = parseInt(req.query.exposure)
|
|
} else {
|
|
exposure = req.query.exposure
|
|
}
|
|
}
|
|
if (req.body && typeof req.body.exposure !== 'undefined') {
|
|
if (typeof req.body.exposure === 'string') {
|
|
exposure = parseInt(req.body.exposure)
|
|
} else {
|
|
exposure = req.body.exposure
|
|
}
|
|
}
|
|
|
|
log.info('/frame', { method : req.method, dir : dir, exposure : exposure })
|
|
|
|
if (exposure < 30000) {
|
|
success = await intval.frame(dir, exposure)
|
|
res.send({ dir : dir, len : exposure, success })
|
|
return next()
|
|
} else {
|
|
intval.frame(dir, exposure)
|
|
res.send({ dir : dir, len : exposure, delaying : true })
|
|
return next()
|
|
}
|
|
}
|
|
|
|
function rStatus (req, res, next) {
|
|
const obj = intval.status()
|
|
res.send(obj)
|
|
return next()
|
|
}
|
|
|
|
async function rSequence (req, res, next) {
|
|
let dir = true
|
|
let exposure = 0
|
|
let delay = 0
|
|
let options = {}
|
|
|
|
if (intval._state.frame.dir !== true) {
|
|
dir = false
|
|
}
|
|
if (intval._state.frame.exposure !== 0) {
|
|
exposure = intval._state.frame.exposure
|
|
}
|
|
if (intval._state.frame.delay !== 0) {
|
|
options.delay = intval._state.frame.delay
|
|
}
|
|
|
|
if (req.query && typeof req.query.dir !== 'undefined') {
|
|
if (typeof req.query.dir === 'string') {
|
|
dir = (req.query.dir === 'true')
|
|
} else {
|
|
dir = req.query.dir
|
|
}
|
|
}
|
|
if (req.body && typeof req.body.dir !== 'undefined') {
|
|
if (typeof req.body.dir === 'string') {
|
|
dir = (req.body.dir === 'true')
|
|
} else {
|
|
dir = req.body.dir
|
|
}
|
|
}
|
|
if (req.query && typeof req.query.exposure !== 'undefined') {
|
|
if (typeof req.query.exposure === 'string') {
|
|
exposure = parseInt(req.query.exposure)
|
|
} else {
|
|
exposure = req.query.exposure
|
|
}
|
|
}
|
|
if (req.body && typeof req.body.exposure !== 'undefined') {
|
|
if (typeof req.body.exposure === 'string') {
|
|
exposure = parseInt(req.body.exposure)
|
|
} else {
|
|
exposure = req.body.exposure
|
|
}
|
|
}
|
|
if (req.query && typeof req.query.delay !== 'undefined') {
|
|
if (typeof req.query.delay === 'string') {
|
|
delay = parseInt(req.query.delay)
|
|
} else {
|
|
delay = req.query.delay
|
|
}
|
|
}
|
|
if (req.body && typeof req.body.delay !== 'undefined') {
|
|
if (typeof req.body.delay === 'string') {
|
|
delay = parseInt(req.body.delay)
|
|
} else {
|
|
delay = req.body.delay
|
|
}
|
|
}
|
|
|
|
if (req.query && typeof req.query.len !== 'undefined') {
|
|
if (typeof req.query.len === 'string') {
|
|
options.len = parseInt(req.query.len)
|
|
} else {
|
|
options.len = req.query.len
|
|
}
|
|
}
|
|
if (req.body && typeof req.body.len !== 'undefined') {
|
|
if (typeof req.body.len === 'string') {
|
|
options.len = parseInt(req.body.len)
|
|
} else {
|
|
options.len = req.body.len
|
|
}
|
|
}
|
|
|
|
if (req.query && typeof req.query.multiple !== 'undefined') {
|
|
if (typeof req.query.multiple === 'string') {
|
|
options.multiple = parseInt(req.query.multiple)
|
|
} else {
|
|
options.multiple = req.query.multiple
|
|
}
|
|
}
|
|
if (req.body && typeof req.body.multiple !== 'undefined') {
|
|
if (typeof req.body.multiple === 'string') {
|
|
options.multiple = parseInt(req.body.multiple)
|
|
} else {
|
|
options.multiple = req.body.multiple
|
|
}
|
|
}
|
|
|
|
if (intval._state.sequence && sequence.active) {
|
|
intval._state.sequence = false
|
|
sequence.stop()
|
|
res.send({ stopped : true })
|
|
|
|
return next()
|
|
|
|
} else {
|
|
intval._state.sequence = true
|
|
sequence.start(options)
|
|
res.send({ started : true })
|
|
|
|
return next()
|
|
}
|
|
}
|
|
|
|
function rReset (req, res, next) {
|
|
log.info(`/reset`, {time : +new Date()})
|
|
intval.reset()
|
|
setTimeout(() => {
|
|
const obj = intval.status()
|
|
res.send(obj)
|
|
return next()
|
|
}, 10)
|
|
}
|
|
|
|
function rUpdate (req, res, next) {
|
|
log.info(`/update`, { time : +new Date() })
|
|
exec('sh ./scripts/update.sh', (err, stdio, stderr) => {
|
|
if (err) {
|
|
log.error(err)
|
|
}
|
|
log.info(`/update`, { git : stdio })
|
|
res.send({ success : true, action : 'update', output : stdio })
|
|
res.end()
|
|
next()
|
|
setTimeout(() => {
|
|
process.exit(0)
|
|
}, 100)
|
|
})
|
|
}
|
|
|
|
function rRestart (req, res, next) {
|
|
log.info(`/restart`, { time : +new Date() })
|
|
res.send({ success : true, action : 'restart' })
|
|
res.end()
|
|
next()
|
|
setTimeout(() => {
|
|
process.exit(0)
|
|
}, 100)
|
|
}
|
|
|
|
//Ble functions
|
|
|
|
async function bFrame (obj, cb) {
|
|
let dir = true
|
|
let exposure = 0
|
|
let success = false
|
|
|
|
if (sequence.active) {
|
|
return cb()
|
|
}
|
|
|
|
if (intval._state.frame.dir !== true) {
|
|
dir = false
|
|
}
|
|
if (intval._state.frame.exposure !== 0) {
|
|
exposure = intval._state.frame.exposure
|
|
}
|
|
if (typeof obj.dir !== 'undefined') {
|
|
if (typeof obj.dir === 'string') {
|
|
dir = (obj.dir === 'true')
|
|
} else {
|
|
dir = obj.dir
|
|
}
|
|
}
|
|
if (typeof obj.exposure !== 'undefined') {
|
|
if (typeof obj.exposure === 'string') {
|
|
exposure = parseInt(obj.exposure)
|
|
} else {
|
|
exposure = obj.exposure
|
|
}
|
|
}
|
|
log.info('frame', { method : 'ble', dir : dir, exposure : exposure })
|
|
|
|
if (exposure < 5000) {
|
|
success = await intval.frame(dir, exposure)
|
|
return cb()
|
|
} else {
|
|
intval.frame(dir, exposure)
|
|
return cb()
|
|
}
|
|
|
|
//setTimeout(cb, exposure === 0 ? 630 : exposure)
|
|
}
|
|
|
|
function bDir (obj, cb) {
|
|
let dir = true
|
|
let set = false
|
|
if (obj.dir !== 'undefined') {
|
|
if (typeof obj.dir === 'string') {
|
|
dir = (obj.dir === 'true')
|
|
} else {
|
|
dir = obj.dir
|
|
}
|
|
}
|
|
intval.setDir(dir)
|
|
log.info('dir', { method: 'ble', dir : dir })
|
|
cb()
|
|
}
|
|
|
|
function bExposure (obj, cb) {
|
|
let exposure = 0
|
|
if (typeof obj.exposure !== 'undefined') {
|
|
if (typeof obj.exposure === 'string') {
|
|
exposure = parseInt(obj.exposure)
|
|
} else {
|
|
exposure = obj.exposure
|
|
}
|
|
}
|
|
intval.setExposure(exposure)
|
|
log.info('exposure', { method: 'ble', exposure : exposure })
|
|
return cb()
|
|
}
|
|
|
|
function bDelay (obj, cb) {
|
|
let delay = 0
|
|
let set = false
|
|
if (typeof obj.delay !== 'undefined') {
|
|
if (typeof obj.delay === 'string') {
|
|
delay = parseInt(obj.delay)
|
|
} else {
|
|
delay = obj.delay
|
|
}
|
|
set = true
|
|
}
|
|
intval.setDelay(delay)
|
|
log.info('delay', { method: 'ble', delay : delay })
|
|
return cb()
|
|
}
|
|
|
|
function bCounter (obj, cb) {
|
|
let counter = 0
|
|
if (typeof obj.counter !== 'undefined') {
|
|
if (typeof obj.counter !== 'string') {
|
|
counter = parseInt(obj.counter)
|
|
} else {
|
|
counter = obj.counter
|
|
}
|
|
}
|
|
intval.setCounter(counter)
|
|
log.info('counter', { method : 'ble', counter : counter })
|
|
return cb()
|
|
}
|
|
|
|
function bSequence (obj, cb) {
|
|
let dir = true
|
|
let exposure = 0
|
|
let delay = 0
|
|
let options = {}
|
|
|
|
if (intval._state.frame.dir !== true) {
|
|
dir = false
|
|
}
|
|
if (intval._state.frame.exposure !== 0) {
|
|
exposure = intval._state.frame.exposure
|
|
}
|
|
if (intval._state.frame.delay !== 0) {
|
|
delay = intval._state.frame.delay
|
|
}
|
|
|
|
if (typeof obj.dir !== 'undefined') {
|
|
if (typeof obj.dir === 'string') {
|
|
dir = (obj.dir === 'true')
|
|
} else {
|
|
dir = obj.dir
|
|
}
|
|
}
|
|
if (typeof obj.exposure !== 'undefined') {
|
|
if (typeof obj.exposure === 'string') {
|
|
exposure = parseInt(obj.exposure)
|
|
} else {
|
|
exposure = obj.exposure
|
|
}
|
|
}
|
|
if (typeof obj.len !== 'undefined') {
|
|
if (typeof obj.len === 'string') {
|
|
options.len = parseInt(obj.len)
|
|
} else {
|
|
options.len = obj.len
|
|
}
|
|
}
|
|
if (typeof obj.multiple !== 'undefined') {
|
|
if (typeof obj.multiple === 'string') {
|
|
options.multiple = parseInt(obj.multiple)
|
|
} else {
|
|
options.multiple = obj.multiple
|
|
}
|
|
}
|
|
|
|
if (intval._state.sequence && sequence.active) {
|
|
//should not occur with single client
|
|
intval._state.sequence = false
|
|
sequence.stop()
|
|
log.info('sequence stop', { method : 'ble' })
|
|
return cb()
|
|
} else {
|
|
intval._state.sequence = true
|
|
sequence.start(options)
|
|
log.info('sequence start', { method : 'ble' })
|
|
return cb()
|
|
}
|
|
}
|
|
|
|
function bSequenceStop (obj, cb) {
|
|
if (intval._state.sequence && sequence.active) {
|
|
sequence.stop()
|
|
intval._state.sequence = false
|
|
log.info('sequence stop', { method : 'ble' })
|
|
return cb()
|
|
}
|
|
}
|
|
|
|
function bReset (obj, cb) {
|
|
log.info(`reset`, { method: 'ble' })
|
|
intval.reset()
|
|
setTimeout(cb, 10)
|
|
}
|
|
|
|
function bUpdate (obj, cb) {
|
|
log.info('update', { method : 'ble' })
|
|
exec('sh ./scripts/update.sh', (err, stdio, stderr) => {
|
|
if (err) {
|
|
log.error('update', err)
|
|
}
|
|
log.info('update', { stdio : stdio })
|
|
cb()
|
|
setTimeout(() => {
|
|
process.exit(0)
|
|
}, 20)
|
|
})
|
|
}
|
|
|
|
function bRestart (obj, cb) {
|
|
log.info('restart', { method : 'ble' })
|
|
cb()
|
|
setTimeout(() => {
|
|
process.exit(0)
|
|
}, 20)
|
|
}
|
|
|
|
async function index (req, res, next) {
|
|
let data
|
|
|
|
try {
|
|
data = await readFile(INDEXPATH, 'utf8')
|
|
} catch (err) {
|
|
return next(err)
|
|
}
|
|
}
|
|
|
|
function init () {
|
|
createServer()
|
|
createBLE()
|
|
}
|
|
|
|
init()
|