diff --git a/README.md b/README.md index 5d0270d..d67b91c 100644 --- a/README.md +++ b/README.md @@ -167,22 +167,19 @@ invocation is shown below: 3 passing (95ms) -ESLint +Code Climate ------ -The Airbnb JavaScript style guide is used as a reference. The eslint -linting tool can be run on the source code for validation. For -example: +The [Airbnb JavaScript](https://github.com/airbnb/javascript) style guide is used as a reference. - $ `npm bin`/eslint.js src/adapter.js - -JSHint +Lint ------ +Use [standard](https://github.com/feross/standard) for linting `npm install -g standard` + +To lint do `standard src/**/*.js src/*js` -The JavaScript code quality tool JSHint can be executed using the -following command: +To auto format files use `standard --fix src/filename.js` - $ npm run jshint Error and Exception Handling ---------------------------- diff --git a/package.json b/package.json index bd5e40e..566ea1f 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,6 @@ "dev": "$(npm bin)/node-dev ./server.js", "simulator": "$(npm bin)/nf start simulator", "start": "DEBUG=node-ssdp* node server.js", - "eslint": "./node_modules/eslint/bin/eslint.js src/*", - "jshint": "jshint --reporter=node_modules/jshint-stylish src/*", "tc:test": "./node_modules/istanbul/lib/cli.js cover _mocha", "tc:version": "node version" }, diff --git a/src/agent.js b/src/agent.js index 4ba4e21..6eb870e 100644 --- a/src/agent.js +++ b/src/agent.js @@ -62,12 +62,12 @@ app.use(function * lastResort (next) { let server function start () { - if (server) return new Promise((s) => s()) + if (server) return new Promise((resolve, reject) => resolve()) aggregator.start() - return new Promise((success) => { + return new Promise((resolve, reject) => { server = app.listen(agentPort, '0.0.0.0', () => { log.debug(`Starting agent on port: ${agentPort}`) - success() + resolve() }) }) } diff --git a/src/aggregator.js b/src/aggregator.js index c10dd29..5820960 100644 --- a/src/aggregator.js +++ b/src/aggregator.js @@ -1,17 +1,17 @@ // In charge of sniffing network and pulling devices into the db -const co = require('co'); -const config = require('./config/config'); -const through = require('through'); -const { deviceXML } = require('./utils'); -const Finder = require('./finder'); -const lokijs = require('./lokijs'); -const log = require('./config/logger'); -const common = require('./common'); -const devices = require('./store'); -const { urnSearch, deviceSearchInterval, path } = config.app.agent; -const query = `urn:schemas-mtconnect-org:service:${urnSearch}`; -const finder = new Finder({ query, frequency: deviceSearchInterval }); -const request = require('request'); +const co = require('co') +const config = require('./config/config') +const through = require('through') +const { deviceXML } = require('./utils') +const Finder = require('./finder') +const lokijs = require('./lokijs') +const log = require('./config/logger') +const common = require('./common') +const devices = require('./store') +const { urnSearch, deviceSearchInterval, path } = config.app.agent +const query = `urn:schemas-mtconnect-org:service:${urnSearch}` +const finder = new Finder({ query, frequency: deviceSearchInterval }) +const request = require('request') /** * processSHDR() process SHDR string * @@ -20,18 +20,18 @@ const request = require('request'); * return uuid * */ -function processSHDR(uuid) { +function processSHDR (uuid) { return through((data) => { - log.debug(data.toString()); - const stirng = String(data).trim(); - const parsed = common.inputParsing(stirng, uuid); - lokijs.dataCollectionUpdate(parsed, uuid); - }); + log.debug(data.toString()) + const stirng = String(data).trim() + const parsed = common.inputParsing(stirng, uuid) + lokijs.dataCollectionUpdate(parsed, uuid) + }) } devices.on('delete', (obj) => { - lokijs.updateBufferOnDisconnect(obj.uuid); -}); + lokijs.updateBufferOnDisconnect(obj.uuid) +}) /** * connectToDevice() create socket connection to device @@ -43,22 +43,22 @@ devices.on('delete', (obj) => { * */ -function connectToDevice({ ip, port, uuid }) { - const response = request(`http://${ip}:${port}`); - response.pipe(processSHDR(uuid)); +function connectToDevice ({ ip, port, uuid }) { + const response = request(`http://${ip}:${port}`) + response.pipe(processSHDR(uuid)) response.on('error', (err) => { // Remove device - if (err.errno !== 'ECONNREFUSED') return; - const found = devices.find({ $and: [{ address: err.address }, { port: err.port }] }); - if (found.length > 0) devices.remove(found); - }); + if (err.errno !== 'ECONNREFUSED') return + const found = devices.find({ $and: [{ address: err.address }, { port: err.port }] }) + if (found.length > 0) devices.remove(found) + }) response.on('close', () => { - const found = devices.find({ $and: [{ address: ip }, { port }] }); - if (found.length > 0) { devices.remove(found); } - log.debug('Connection closed'); - }); + const found = devices.find({ $and: [{ address: ip }, { port }] }) + if (found.length > 0) { devices.remove(found) } + log.debug('Connection closed') + }) - devices.insert({ address: ip, port, uuid }); + devices.insert({ address: ip, port, uuid }) } /** @@ -70,22 +70,22 @@ function connectToDevice({ ip, port, uuid }) { * * returns null */ -function handleDevice({ ip, port, uuid }) { - return function addDevice(xml) { - if (!common.mtConnectValidate(xml)) return; - if (lokijs.updateSchemaCollection(xml)) return; - const found = devices.find({ $and: [{ hostname: ip }, { port }] }); - const uuidFound = common.duplicateUuidCheck(uuid, devices); +function handleDevice ({ ip, port, uuid }) { + return function addDevice (xml) { + if (!common.mtConnectValidate(xml)) return + if (lokijs.updateSchemaCollection(xml)) return + const found = devices.find({ $and: [{ hostname: ip }, { port }] }) + const uuidFound = common.duplicateUuidCheck(uuid, devices) if ((found.length < 1) && (uuidFound.length < 1)) { - connectToDevice({ ip, port, uuid }); + connectToDevice({ ip, port, uuid }) } - }; + } } -function onDevice(info) { - co(deviceXML(Object.assign({ path }, info))).then(handleDevice(info)); +function onDevice (info) { + co(deviceXML(Object.assign({ path }, info))).then(handleDevice(info)) } -finder.on('device', onDevice); +finder.on('device', onDevice) -module.exports = finder; +module.exports = finder diff --git a/src/common.js b/src/common.js index 4cb1ee6..bedd3f0 100644 --- a/src/common.js +++ b/src/common.js @@ -16,111 +16,110 @@ // Imports - External -const xpath = require('xpath'); -const Dom = require('xmldom').DOMParser; -const fs = require('fs'); -const path = require('path'); -const moment = require('moment'); -const tmp = require('tmp'); -const defaultShell = require('child_process'); -const R = require('ramda'); +const xpath = require('xpath') +const Dom = require('xmldom').DOMParser +const fs = require('fs') +const path = require('path') +const moment = require('moment') +const tmp = require('tmp') +const defaultShell = require('child_process') +const R = require('ramda') // Imports - Internal -const log = require('./config/logger'); -const lokijs = require('./lokijs'); +const log = require('./config/logger') +const lokijs = require('./lokijs') // Functions -function getType(id, uuid) { - const dataItems = lokijs.getDataItem(uuid); - let type = ''; +function getType (id, uuid) { + const dataItems = lokijs.getDataItem(uuid) + let type = '' if (dataItems) { R.find((k) => { if (k.$.id === id || k.$.name === id) { - type = k.$.type; + type = k.$.type } - return type; // eslint - }, dataItems); + return type // eslint + }, dataItems) } - return type; + return type } -function checkForTimeSeries(id, uuid) { - const dataItems = lokijs.getDataItem(uuid); - let isTimeSeries = false; +function checkForTimeSeries (id, uuid) { + const dataItems = lokijs.getDataItem(uuid) + let isTimeSeries = false if (dataItems) { R.find((k) => { if (k.$.id === id || k.$.name === id) { if (k.$.representation === 'TIME_SERIES') { - isTimeSeries = true; + isTimeSeries = true } } - return isTimeSeries; // eslint - }, dataItems); + return isTimeSeries // eslint + }, dataItems) } - return isTimeSeries; + return isTimeSeries } -function getCategory(id, uuid) { - const dataItems = lokijs.getDataItem(uuid); - let category = ''; +function getCategory (id, uuid) { + const dataItems = lokijs.getDataItem(uuid) + let category = '' if (dataItems) { R.find((k) => { if (k.$.id === id || k.$.name === id) { - category = k.$.category; + category = k.$.category } - return category; // eslint - }, dataItems); + return category // eslint + }, dataItems) } - return category; + return category } - /** * inputParsing get the data from adapter, do string parsing * @param {String} inputString * @param {String} uuid * returns jsonData with time and dataitem */ -function inputParsing(inputString, uuid) { // ('2014-08-11T08:32:54.028533Z|avail|AVAILABLE') - const inputParse = inputString.split('|'); +function inputParsing (inputString, uuid) { // ('2014-08-11T08:32:54.028533Z|avail|AVAILABLE') + const inputParse = inputString.split('|') const jsonData = { time: inputParse[0], - dataitem: [], - }; + dataitem: [] + } if (jsonData.time === '') { - jsonData.time = moment.utc().format(); + jsonData.time = moment.utc().format() } - const dataItemId = inputParse[1]; + const dataItemId = inputParse[1] if (inputParse[1] === '@ASSET@' || inputParse[1] === '@UPDATE_ASSET@' || inputParse[1] === 'REMOVE_@ASSET@' || inputParse[1] === 'REMOVE_ALL_ASSETS') { - const value = inputParse.slice(2, Infinity); - jsonData.dataitem.push({ name: inputParse[1], value }); - return jsonData; + const value = inputParse.slice(2, Infinity) + jsonData.dataitem.push({ name: inputParse[1], value }) + return jsonData } - const category = getCategory(dataItemId, uuid); - const isTimeSeries = checkForTimeSeries(dataItemId, uuid); - const type = getType(dataItemId, uuid); + const category = getCategory(dataItemId, uuid) + const isTimeSeries = checkForTimeSeries(dataItemId, uuid) + const type = getType(dataItemId, uuid) if (category === 'CONDITION') { - const value = inputParse.slice(2, Infinity); - jsonData.dataitem.push({ name: inputParse[1], value }); + const value = inputParse.slice(2, Infinity) + jsonData.dataitem.push({ name: inputParse[1], value }) } else if (type === 'MESSAGE' || type === 'ALARM') { - const value = inputParse.slice(2, Infinity); - jsonData.dataitem.push({ name: inputParse[1], value }); + const value = inputParse.slice(2, Infinity) + jsonData.dataitem.push({ name: inputParse[1], value }) } else if (isTimeSeries) { // Eg: { time: '2', dataitem: [ { name: 'Va', value:[ SampleCount, SampleRate, 'value1 valu2 ...'] }] } - const value = inputParse.slice(2, Infinity); - jsonData.dataitem.push({ name: inputParse[1], value, isTimeSeries: true }); + const value = inputParse.slice(2, Infinity) + jsonData.dataitem.push({ name: inputParse[1], value, isTimeSeries: true }) } else { - const totalDataItem = (inputParse.length - 1) / 2; + const totalDataItem = (inputParse.length - 1) / 2 for (let i = 0, j = 1; i < totalDataItem; i++, j += 2) { // Eg: dataitem[i] = { name: (avail), value: (AVAILABLE) }; - jsonData.dataitem.push({ name: inputParse[j], value: inputParse[j + 1] }); + jsonData.dataitem.push({ name: inputParse[j], value: inputParse[j + 1] }) } } - return jsonData; + return jsonData } /** @@ -129,11 +128,10 @@ function inputParsing(inputString, uuid) { // ('2014-08-11T08:32:54.028533Z|avai * @param {Object} devices - database of devices connected * return uuidSet - array containing all uuids. */ -function getAllDeviceUuids(devices) { - return R.map((device => device.uuid), devices.data); +function getAllDeviceUuids (devices) { + return R.map(device => device.uuid, devices.data) } - /** * duplicateUuidCheck() checks the device collection for * received uuid @@ -141,8 +139,8 @@ function getAllDeviceUuids(devices) { * @param {Object} devices - database * return uuidFound - array of entries with same uuid */ -function duplicateUuidCheck(receivedUuid, devices) { - return devices.find({ uuid: receivedUuid }); +function duplicateUuidCheck (receivedUuid, devices) { + return devices.find({ uuid: receivedUuid }) } /** @@ -150,25 +148,25 @@ function duplicateUuidCheck(receivedUuid, devices) { * @param {String} deviceName * return uuid */ -function getDeviceUuid(deviceName) { - const schemaDB = lokijs.getSchemaDB(); - const schemaList = R.values(schemaDB.data); - let uuid; +function getDeviceUuid (deviceName) { + const schemaDB = lokijs.getSchemaDB() + const schemaList = R.values(schemaDB.data) + let uuid R.find((k) => { if (k.name === deviceName) { - uuid = k.uuid; + uuid = k.uuid } - return uuid; - }, schemaList); - return uuid; + return uuid + }, schemaList) + return uuid } /** * getCurrentTimeInSec() * returns the present time in Sec */ -function getCurrentTimeInSec() { - return moment().unix(Number); +function getCurrentTimeInSec () { + return moment().unix(Number) } /** @@ -178,58 +176,57 @@ function getCurrentTimeInSec() { * @param {String} message * @param {Boolean} exit */ -function processError(message, exit) { - log.error(`Error: ${message}`); +function processError (message, exit) { + log.error(`Error: ${message}`) - if (exit) process.exit(1); + if (exit) process.exit(1) } -function getMTConnectVersion(xmlString) { - let version = ''; +function getMTConnectVersion (xmlString) { + let version = '' try { - const doc = new Dom().parseFromString(xmlString); - const node = xpath.select("//*[local-name(.)='MTConnectDevices']", doc)[0]; - const ns = node.namespaceURI; - version = ns.split(':').pop(); + const doc = new Dom().parseFromString(xmlString) + const node = xpath.select("//*[local-name(.)='MTConnectDevices']", doc)[0] + const ns = node.namespaceURI + version = ns.split(':').pop() } catch (e) { - log.error('Error: obtaining MTConnect XML namespace', e); - return null; + log.error('Error: obtaining MTConnect XML namespace', e) + return null } - return version; + return version } -function mtConnectValidate(documentString) { - const version = getMTConnectVersion(documentString); - const deviceXMLFile = tmp.tmpNameSync(); +function mtConnectValidate (documentString) { + const version = getMTConnectVersion(documentString) + const deviceXMLFile = tmp.tmpNameSync() try { - fs.writeFileSync(deviceXMLFile, documentString, 'utf8'); + fs.writeFileSync(deviceXMLFile, documentString, 'utf8') } catch (err) { - log.error('Cannot write documentString to deviceXML file', err); - return false; + log.error('Cannot write documentString to deviceXML file', err) + return false } if (version) { - const schemaPath = `../schema/MTConnectDevices_${version}.xsd`; - const schemaFile = path.join(__dirname, schemaPath); + const schemaPath = `../schema/MTConnectDevices_${version}.xsd` + const schemaFile = path.join(__dirname, schemaPath) // candidate for validation worker - const child = defaultShell.spawnSync('xmllint', ['--valid', '--schema', schemaFile, deviceXMLFile]); - fs.unlinkSync(deviceXMLFile); + const child = defaultShell.spawnSync('xmllint', ['--valid', '--schema', schemaFile, deviceXMLFile]) + fs.unlinkSync(deviceXMLFile) if (child.stderr) { if (child.stderr.includes('fails to validate') || child.stderr.includes('failed to load external entity')) { - return false; + return false } } - return true; + return true } - return false; + return false } - // Exports module.exports = { @@ -240,5 +237,5 @@ module.exports = { getCurrentTimeInSec, getMTConnectVersion, mtConnectValidate, - duplicateUuidCheck, -}; + duplicateUuidCheck +} diff --git a/src/config/config.js b/src/config/config.js index 3842fa6..dd3fa27 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -1,5 +1,5 @@ -const env = process.env; -const R = require('ramda'); +const env = process.env +const R = require('ramda') // configuration parameter for each adapter @@ -11,7 +11,7 @@ const adapters = { RealTime: false, RelativeTime: false, FilterDuplicates: true, - UpcaseDataItemValue: true, + UpcaseDataItemValue: true }, 'VMC-4Axis': { IgnoreTimestamps: false, @@ -20,72 +20,72 @@ const adapters = { RealTime: false, RelativeTime: false, FilterDuplicates: false, - UpcaseDataItemValue: true, - }, -}; + UpcaseDataItemValue: true + } +} -function setConfiguration(device, parameter, value) { - if (!(device && device.id && device.$.name)) return; - adapters[device.$.name][parameter] = value; - return adapters[device.$.name][parameter]; +function setConfiguration (device, parameter, value) { + if (!(device && device.id && device.$.name)) return + adapters[device.$.name][parameter] = value + return adapters[device.$.name][parameter] } -function getConfiguredVal(devName, parName) { - const keys = R.keys(adapters); - let device; - let parameter; +function getConfiguredVal (devName, parName) { + const keys = R.keys(adapters) + let device + let parameter R.find((k) => { if (k === devName) { - device = k; + device = k } - return device; - }, keys); + return device + }, keys) if (device !== undefined) { - const subKeys = R.keys(adapters[device]); + const subKeys = R.keys(adapters[device]) R.find((k) => { if (k === parName) { - parameter = k; + parameter = k } - return parameter; - }, subKeys); + return parameter + }, subKeys) } else { - console.log(`The requested device name ${devName} is not present in list of adapters`); - return undefined; + console.log(`The requested device name ${devName} is not present in list of adapters`) + return undefined } if (parameter !== undefined) { - return adapters[device][parameter]; + return adapters[device][parameter] } - console.log(`The requested parameter name ${devName} is not present in device ${device}`); - return undefined; + console.log(`The requested parameter name ${devName} is not present in device ${device}`) + return undefined } module.exports = { app: { name: 'svc-agent-reader', - version: env.VI_VERSION || console.log('WARN: env.VI_VERSION not set unknown'), + version: env.MTC_VERSION || console.log('WARN: env.MTC_VERSION not set unknown'), simulator: { uuid: '000', machinePort: 7879, filePort: 8080, maxDelay: 3000, urn: 'VMC-3Axis', - inputFile: './public/vmc_10di.txt', + inputFile: './public/vmc_10di.txt' }, agent: { allowPut: true, AllowPutFrom: ['192.168.100.16', '192.168.1.37', 'localhost', '127.0.0.1'], deviceSearchInterval: 10000, agentPort: 7000, - bufferSize: env.VI_BUFFER_SIZE || 10, + bufferSize: env.MTC_BUFFER_SIZE || 10, checkPointIndex: 1000, path: '/VMC-3Axis.xml', - urnSearch: 'VMC-*', - }, + urnSearch: 'VMC-*' + } }, logging: { - logLevel: env.VI_LOG_LEVEL || 'warn', - logDir: env.VI_LOG_DIR, + logLevel: env.MTC_LOG_LEVEL || 'warn', + logDir: env.MTC_LOG_DIR }, getConfiguredVal, - setConfiguration, -}; + setConfiguration +} diff --git a/src/config/logger.js b/src/config/logger.js index 05bb6ae..2d9ddd8 100644 --- a/src/config/logger.js +++ b/src/config/logger.js @@ -1,9 +1,9 @@ -const config = require('./config'); -const bunyan = require('bunyan'); +const config = require('./config') +const bunyan = require('bunyan') module.exports = bunyan.createLogger({ name: config.app.name, version: config.app.version, logDir: config.logging.logDir, - level: config.logging.logLevel, -}); + level: config.logging.logLevel +}) diff --git a/src/dataItem.js b/src/dataItem.js index 950919a..58a177b 100644 --- a/src/dataItem.js +++ b/src/dataItem.js @@ -14,53 +14,51 @@ * limitations under the License. */ -const R = require('ramda'); - -function multiValuedConversion(value, conv) { - let mValue = ''; - const valueArr = value.split(' '); - const valArr = []; - for(i = 0; i < valueArr.length; i++) { - if(valueArr[i] !== '') { - valArr.push(valueArr[i]); +const R = require('ramda') + +function multiValuedConversion (value, conv) { + let mValue = '' + const valueArr = value.split(' ') + const valArr = [] + for (let i = 0; i < valueArr.length; i++) { + if (valueArr[i] !== '') { + valArr.push(valueArr[i]) } } R.map((v) => { - value = (Number(v) + conv.mConversionOffset) * conv.mConversionFactor; - mValue = mValue + `${value}` + ' '; - }, valArr); - mValue = mValue.slice(0, mValue.length - 1); // rermoving last space - return String(mValue); + value = (Number(v) + conv.mConversionOffset) * conv.mConversionFactor + mValue = mValue + `${value}` + ' ' + }, valArr) + mValue = mValue.slice(0, mValue.length - 1) // rermoving last space + return String(mValue) } - -function simpleFactor(units, obj) { - switch(units) - { +function simpleFactor (units, obj) { + switch (units) { case 'INCH': - return 25.4; + return 25.4 case 'FOOT': - return 304.8; + return 304.8 case 'CENTIMETER': - return 10.0; + return 10.0 case 'DECIMETER': - return 100.0; + return 100.0 case 'METER': - return 1000.0; + return 1000.0 case 'FAHRENHEIT': - obj.mConversionOffset = -32.0; - return 5.0 / 9.0; + obj.mConversionOffset = -32.0 + return 5.0 / 9.0 case 'POUND': - return 0.45359237; + return 0.45359237 case 'GRAM': - return 1 / 1000.0; + return 1 / 1000.0 case 'RADIAN': - return 57.2957795; + return 57.2957795 case 'MINUTE': - return 60.0; + return 60.0 case 'HOUR': - return 3600.0; + return 3600.0 case 'SECOND': case 'MILLIMETER': @@ -88,125 +86,121 @@ function simpleFactor(units, obj) { default: // Already in correct units - return 1.0; + return 1.0 } } - -function computeConversionFactors(nativeUnits, mUnits, mHasNativeScale) { - let units = nativeUnits; - let mConversionFactor = 1; - let needConversion = true; - let mThreeD = false; - let mConversionOffset = 0.0; +function computeConversionFactors (nativeUnits, mUnits, mHasNativeScale) { + let units = nativeUnits + let mConversionFactor = 1 + let needConversion = true + let mThreeD = false + let mConversionOffset = 0.0 const obj = { mConversionFactor, needConversion, mConversionOffset, - mThreeD, + mThreeD } - const threeD = units.search(/_3D/); - const slashLoc = units.search('/'); + const threeD = units.search(/_3D/) + const slashLoc = units.search('/') if (slashLoc === -1) { if (threeD !== -1) { - units = units.substring(0, threeD); - obj.mThreeD = true; + units = units.substring(0, threeD) + obj.mThreeD = true } mConversionFactor = simpleFactor(units, obj) if (mConversionFactor === 1.0) { if (mUnits === units) { - needConversion = false; - } else if ((units.substring(0,4) === 'KILO') && (units.substring(4) === mUnits)) { - mConversionFactor = 1000.0; - } else { - needConversion = false; + needConversion = false + } else if ((units.substring(0, 4) === 'KILO') && (units.substring(4) === mUnits)) { + mConversionFactor = 1000.0 + } else { + needConversion = false } } } else if (units === 'REVOLUTION/MINUTE') { - mConversionFactor = 1.0; - needConversion = false; + mConversionFactor = 1.0 + needConversion = false } else { - const numerator = units.substring(0, slashLoc); - const denominator = units.substring(slashLoc + 1); - const carotLoc = denominator.search('^'); + const numerator = units.substring(0, slashLoc) + const denominator = units.substring(slashLoc + 1) + const carotLoc = denominator.search('^') - if (numerator === "REVOLUTION" && denominator === "SECOND") { - mConversionFactor = 60.0; + if (numerator === 'REVOLUTION' && denominator === 'SECOND') { + mConversionFactor = 60.0 } else if (carotLoc === -1) { - mConversionFactor = simpleFactor(numerator) / simpleFactor(denominator); + mConversionFactor = simpleFactor(numerator) / simpleFactor(denominator) } else { - const unit = denominator.substring(0, carotLoc); - const power = denominator.substring(carotLoc + 1); - const div = Math.pow(simpleFactor(unit), Number(power)); - mConversionFactor = simpleFactor(numerator) / div; + const unit = denominator.substring(0, carotLoc) + const power = denominator.substring(carotLoc + 1) + const div = Math.pow(simpleFactor(unit), Number(power)) + mConversionFactor = simpleFactor(numerator) / div } } - if (mHasNativeScale) - { - const mNativeScale = mHasNativeScale; - needConversion = true; - mConversionFactor /= mNativeScale; - } - obj.mConversionFactor = mConversionFactor; - obj.needConversion = needConversion; - obj.mHasFactor = true; - return obj; + if (mHasNativeScale) { + const mNativeScale = mHasNativeScale + needConversion = true + mConversionFactor /= mNativeScale + } + obj.mConversionFactor = mConversionFactor + obj.needConversion = needConversion + obj.mHasFactor = true + return obj } -function conversionRequired(id, dataItem) { - const category = dataItem.$.category; - const type = dataItem.$.type; - const representation = dataItem.$.representation; - let status = true; +function conversionRequired (id, dataItem) { + const category = dataItem.$.category + const type = dataItem.$.type + const representation = dataItem.$.representation + let status = true if (dataItem.$.nativeUnits === undefined) { - status = false; - } else if (representation === 'TIME_SERIES' || category === 'CONDITION' || type === 'ALARM'|| type === 'MESSAGE') { - status = false; + status = false + } else if (representation === 'TIME_SERIES' || category === 'CONDITION' || type === 'ALARM' || type === 'MESSAGE') { + status = false } - return status; + return status } - // value will be a string -function convertValue(value, dataItem) { - let mValue = ''; - let factor = 1; - const nativeUnits = dataItem.$.nativeUnits; - const mUnits = dataItem.$.units; - const mHasNativeScale = dataItem.$.nativeScale; - const conv = computeConversionFactors(nativeUnits, mUnits, mHasNativeScale); +function convertValue (value, dataItem) { + let mValue = '' + // let factor = 1 + const nativeUnits = dataItem.$.nativeUnits + const mUnits = dataItem.$.units + const mHasNativeScale = dataItem.$.nativeScale + const conv = computeConversionFactors(nativeUnits, mUnits, mHasNativeScale) if (conv.needConversion === false) { - mValue = value; - return mValue; + mValue = value + return mValue } else if (conv.mHasFactor) { if (conv.mThreeD) { mValue = multiValuedConversion(value, conv) - return mValue; + return mValue } else { - mValue = (Number(value) + conv.mConversionOffset) * conv.mConversionFactor; - return String(mValue); + mValue = (Number(value) + conv.mConversionOffset) * conv.mConversionFactor + return String(mValue) } } } - -function convertTimeSeriesValue(value, dataItem) { - let mValue = ''; - const nativeUnits = dataItem.$.nativeUnits; - const mUnits = dataItem.$.units; - const mHasNativeScale = dataItem.$.nativeScale; - const conv = computeConversionFactors(nativeUnits, mUnits, mHasNativeScale); +function convertTimeSeriesValue (value, dataItem) { + let mValue = '' + const nativeUnits = dataItem.$.nativeUnits + const mUnits = dataItem.$.units + const mHasNativeScale = dataItem.$.nativeScale + const conv = computeConversionFactors(nativeUnits, mUnits, mHasNativeScale) if (conv.needConversion === false) { - mValue = value; - return value; + mValue = value + return value } else if (conv.mHasFactor) { - mValue = multiValuedConversion(value, conv); - return mValue; + mValue = multiValuedConversion(value, conv) + return mValue } } module.exports = { conversionRequired, convertValue, - convertTimeSeriesValue, -}; + convertTimeSeriesValue +} diff --git a/src/dataStorage.js b/src/dataStorage.js index c17f574..626dfa1 100644 --- a/src/dataStorage.js +++ b/src/dataStorage.js @@ -16,40 +16,40 @@ // Imports - External -const R = require('ramda'); -const CBuffer = require('CBuffer'); -const HashMap = require('hashmap'); +const R = require('ramda') +const CBuffer = require('CBuffer') +const HashMap = require('hashmap') // Imports - Internal -const log = require('./config/logger'); -const config = require('./config/config'); +const log = require('./config/logger') +const config = require('./config/config') // Constants -const checkPointIndex = config.app.agent.checkPointIndex; -const bufferSize = Number(config.app.agent.bufferSize); +const checkPointIndex = config.app.agent.checkPointIndex +const bufferSize = Number(config.app.agent.bufferSize) // Instances -const hashLast = new HashMap(); -const hashCurrent = new HashMap(); -const hashAssetCurrent = new HashMap(); -const assetBuffer = new CBuffer(1024); // TODO pass from config +const hashLast = new HashMap() +const hashCurrent = new HashMap() +const hashAssetCurrent = new HashMap() +const assetBuffer = new CBuffer(1024) // TODO pass from config // variables -let nextSequence = 0; +let nextSequence = 0 // Functions /* ******************** creating circularBuffer *************************** */ -function createCircularBuffer(size) { - const cBuffer = new CBuffer(size); - return cBuffer; +function createCircularBuffer (size) { + const cBuffer = new CBuffer(size) + return cBuffer } -const circularBuffer = createCircularBuffer(bufferSize); +const circularBuffer = createCircularBuffer(bufferSize) -function getBufferSize() { - return bufferSize; +function getBufferSize () { + return bufferSize } /* ************************** Supporting functions ************************* */ /** @@ -59,30 +59,28 @@ function getBufferSize() { * editedPath (removes '') [ 'Device', 'name="VMC-3Axis"', 'Axes', 'Rotary' ] */ -function pathIncludesRequestPath(path, requestPath) { - let editedPath = requestPath.replace(/\[|\]|and|\s/g, ''); // replaces [,], and. - editedPath = editedPath.split(/\/\/|@/); - editedPath = editedPath.filter(Boolean); // To remove empty string in array - let pathStr = path.replace(/\[|\]|and|\s/g, ''); - pathStr = pathStr.split(/\/\/|@/); - pathStr = pathStr.filter(Boolean); - const pathCheck = []; +function pathIncludesRequestPath (path, requestPath) { + let editedPath = requestPath.replace(/\[|\]|and|\s/g, '') // replaces [,], and. + editedPath = editedPath.split(/\/\/|@/) + editedPath = editedPath.filter(Boolean) // To remove empty string in array + let pathStr = path.replace(/\[|\]|and|\s/g, '') + pathStr = pathStr.split(/\/\/|@/) + pathStr = pathStr.filter(Boolean) + const pathCheck = [] R.map((k) => { - const temp = R.contains(k, pathStr); - pathCheck.push(temp); - return pathCheck; // to make eslint happy - }, editedPath); - return R.all((k) => R.equals(k, true))(pathCheck); + const temp = R.contains(k, pathStr) + pathCheck.push(temp) + return pathCheck // to make eslint happy + }, editedPath) + return R.all((k) => R.equals(k, true))(pathCheck) } - -function filterPath(arr, requestPath) { - return R.filter((v) => pathIncludesRequestPath(v.path, requestPath))(arr); +function filterPath (arr, requestPath) { + return R.filter((v) => pathIncludesRequestPath(v.path, requestPath))(arr) } - -function filterPathArr(arr, requestPath) { - return R.filter((v) => pathIncludesRequestPath(v, requestPath))(arr); +function filterPathArr (arr, requestPath) { + return R.filter((v) => pathIncludesRequestPath(v, requestPath))(arr) } /** * Check the given array of dataitems for matching uuid, id. @@ -93,19 +91,18 @@ function filterPathArr(arr, requestPath) { * returns an array of filtered result corresponding to the id. * */ -function filterChainForSample(arr, uuidVal, idVal, path) { - let result; +function filterChainForSample (arr, uuidVal, idVal, path) { + let result const filter = R.pipe(R.values, R.filter((v) => v.uuid === uuidVal), - R.filter((v) => v.id === idVal)); - result = filter(arr); + R.filter((v) => v.id === idVal)) + result = filter(arr) if (path) { - result = filterPath(result, path); + result = filterPath(result, path) } - return result; + return result } - /** * Check the array of dataitems for matching uuid, id and * sequenceId lessthan given seqId @@ -118,20 +115,19 @@ function filterChainForSample(arr, uuidVal, idVal, path) { * */ -function filterChain(arr, uuidVal, idVal, seqId, path) { - let result; +function filterChain (arr, uuidVal, idVal, seqId, path) { + let result const filter = R.pipe(R.values, R.filter((v) => v.uuid === uuidVal), R.filter((v) => v.id === idVal), - R.filter((v) => v.sequenceId <= seqId)); - result = filter(arr); + R.filter((v) => v.sequenceId <= seqId)) + result = filter(arr) if (path) { - result = filterPath(result, path); + result = filterPath(result, path) } - return result; + return result } - /** * gets called when the circularBuffer is upto overflow * inserts the evicted data to hashLast @@ -139,11 +135,9 @@ function filterChain(arr, uuidVal, idVal, seqId, path) { * */ circularBuffer.overflow = (data) => { - const idVal = data.id; - hashLast.set(idVal, data); - return; -}; - + const idVal = data.id + hashLast.set(idVal, data) +} /** * calculateCheckPoint gets the checkPoint @@ -152,35 +146,35 @@ circularBuffer.overflow = (data) => { * * return checkPoint */ -function calculateCheckPoint(obj) { - const k = circularBuffer.toArray(); - const objId = obj.id; - const sequenceId = obj.sequenceId; - let checkPoint; +function calculateCheckPoint (obj) { + const k = circularBuffer.toArray() + const objId = obj.id + const sequenceId = obj.sequenceId + let checkPoint if (k.length === 0) { - checkPoint = -1; + checkPoint = -1 } else if ((sequenceId % checkPointIndex === 0)) { - const keys = hashCurrent.keys(); - const arr = []; - let j = 0; + const keys = hashCurrent.keys() + const arr = [] + let j = 0 R.map((c) => { if (c !== objId) { - const index = (R.findLastIndex(R.propEq('id', c))(k)); + const index = (R.findLastIndex(R.propEq('id', c))(k)) // if id not present in circular buffer if (index === -1) { - arr[j++] = -1; + arr[j++] = -1 } else { - arr[j++] = k[index].sequenceId; + arr[j++] = k[index].sequenceId } } - return 0; // to make eslint happy - }, keys); + return 0 // to make eslint happy + }, keys) // smallest sequence id - checkPoint = R.sort((a, b) => a - b)(arr)[0]; + checkPoint = R.sort((a, b) => a - b)(arr)[0] } else { - checkPoint = null; + checkPoint = null } - return checkPoint; + return checkPoint } /** @@ -192,23 +186,22 @@ function calculateCheckPoint(obj) { * */ -function updateCircularBuffer(obj) { - const checkPoint = calculateCheckPoint(obj); +function updateCircularBuffer (obj) { + const checkPoint = calculateCheckPoint(obj) circularBuffer.push({ dataItemName: obj.dataItemName, - uuid: obj.uuid, - id: obj.id, - value: obj.value, - sequenceId: obj.sequenceId, - time: obj.time, - path: obj.path, - sampleCount: obj.sampleCount, - sampleRate: obj.sampleRate, - checkPoint, - }); + uuid: obj.uuid, + id: obj.id, + value: obj.value, + sequenceId: obj.sequenceId, + time: obj.time, + path: obj.path, + sampleCount: obj.sampleCount, + sampleRate: obj.sampleRate, + checkPoint + }) // const k = circularBuffer.toArray(); // firstSequence = k[0].sequenceId; // lastSequence = k[circularBuffer.length - 1].sequenceId; - return; } /** @@ -216,25 +209,24 @@ function updateCircularBuffer(obj) { * @param = nil * return obj = { firstSequence , lastSequence, nextSequence }; */ -function getSequence() { - const k = circularBuffer.toArray(); - let firstSequence; - let lastSequence; +function getSequence () { + const k = circularBuffer.toArray() + let firstSequence + let lastSequence if (!R.isEmpty(k)) { - firstSequence = k[0].sequenceId; - lastSequence = k[circularBuffer.length - 1].sequenceId; + firstSequence = k[0].sequenceId + lastSequence = k[circularBuffer.length - 1].sequenceId } else { - log.error('circularBuffer is empty'); + log.error('circularBuffer is empty') } const obj = { firstSequence, lastSequence, - nextSequence, - }; - return obj; + nextSequence + } + return obj } - /** * readFromHashLast() gets the latest * value of the dataitem from circular buffer @@ -245,19 +237,18 @@ function getSequence() { * return the latest entry for that dataitem * */ -function readFromHashLast(idVal, path) { - let result = hashLast.get(idVal); +function readFromHashLast (idVal, path) { + let result = hashLast.get(idVal) if (path) { - result = filterPath([result], path); + result = filterPath([result], path) if (!R.isEmpty(result)) { - return result[0]; + return result[0] } - return undefined; + return undefined } - return result; + return result } - /** * readFromHashCurrent() gets the latest * value of the dataitem from circular buffer @@ -270,16 +261,16 @@ function readFromHashLast(idVal, path) { * return the latest entry for that dataitem * */ -function readFromHashCurrent(idVal, path) { - let result = hashCurrent.get(idVal); +function readFromHashCurrent (idVal, path) { + let result = hashCurrent.get(idVal) if (path) { - result = filterPath([result], path); + result = filterPath([result], path) if (!R.isEmpty(result)) { - return result[0]; + return result[0] } - return undefined; + return undefined } - return result; + return result } /** @@ -295,37 +286,36 @@ function readFromHashCurrent(idVal, path) { * returns string 'ERROR' if from is outside the range of sequenceId. */ -function getRecentDataItemForSample(from, idVal, uuidVal, count, path) { - let lowerBound; - let upperBound; - let endPoint; - let cbArr = circularBuffer.toArray(); - const firstSequence = getSequence().firstSequence; - const lastSequence = getSequence().lastSequence; - const sequenceId = Number(from); +function getRecentDataItemForSample (from, idVal, uuidVal, count, path) { + let lowerBound + let upperBound + let endPoint + let cbArr = circularBuffer.toArray() + const firstSequence = getSequence().firstSequence + const lastSequence = getSequence().lastSequence + const sequenceId = Number(from) // if from value within the range if ((firstSequence <= sequenceId) && (sequenceId <= lastSequence)) { - endPoint = sequenceId + count; - lowerBound = (R.findIndex(R.propEq('sequenceId', sequenceId))(cbArr)); + endPoint = sequenceId + count + lowerBound = (R.findIndex(R.propEq('sequenceId', sequenceId))(cbArr)) // if from + count within the range if ((firstSequence <= endPoint) && (endPoint <= lastSequence)) { - upperBound = (R.findIndex(R.propEq('sequenceId', endPoint))(cbArr)); + upperBound = (R.findIndex(R.propEq('sequenceId', endPoint))(cbArr)) } else { // if from + count > lastSequence - upperBound = Infinity; + upperBound = Infinity } - cbArr = cbArr.slice(lowerBound, upperBound); - nextSequence = cbArr[cbArr.length - 1].sequenceId + 1; - const latestEntry = filterChainForSample(cbArr, uuidVal, idVal, path); - return latestEntry; + cbArr = cbArr.slice(lowerBound, upperBound) + nextSequence = cbArr[cbArr.length - 1].sequenceId + 1 + const latestEntry = filterChainForSample(cbArr, uuidVal, idVal, path) + return latestEntry } - log.debug('from out side the range of sequenceId'); - return 'ERROR'; + log.debug('from out side the range of sequenceId') + return 'ERROR' } - /** * readFromCircularBuffer() gets the latest * value of the dataitem from circular buffer @@ -337,35 +327,34 @@ function getRecentDataItemForSample(from, idVal, uuidVal, count, path) { * return the latest entry for that dataitem * */ -function readFromCircularBuffer(seqId, idVal, uuidVal, path) { - let lowerBound; - let upperBound; - const sequenceId = Number(seqId); - const firstSequence = getSequence().firstSequence; - const lastSequence = getSequence().lastSequence; +function readFromCircularBuffer (seqId, idVal, uuidVal, path) { + let lowerBound + let upperBound + const sequenceId = Number(seqId) + const firstSequence = getSequence().firstSequence + const lastSequence = getSequence().lastSequence if ((firstSequence <= sequenceId) && (sequenceId <= lastSequence)) { - let cbArr = circularBuffer.toArray(); - const index = (R.findIndex(R.propEq('sequenceId', sequenceId))(cbArr)); - const checkPoint = cbArr[index].checkPoint; + let cbArr = circularBuffer.toArray() + const index = (R.findIndex(R.propEq('sequenceId', sequenceId))(cbArr)) + const checkPoint = cbArr[index].checkPoint if ((checkPoint === -1) || (checkPoint === null)) { - lowerBound = 0; + lowerBound = 0 } else { - lowerBound = (R.findIndex(R.propEq('sequenceId', checkPoint))(cbArr)); + lowerBound = (R.findIndex(R.propEq('sequenceId', checkPoint))(cbArr)) } - upperBound = index; - cbArr = cbArr.slice(lowerBound, upperBound + 1); - const latestEntry = filterChain(cbArr, uuidVal, idVal, sequenceId, path); - let result = latestEntry[latestEntry.length - 1]; + upperBound = index + cbArr = cbArr.slice(lowerBound, upperBound + 1) + const latestEntry = filterChain(cbArr, uuidVal, idVal, sequenceId, path) + let result = latestEntry[latestEntry.length - 1] if (result === undefined) { - result = readFromHashLast(idVal, path); + result = readFromHashLast(idVal, path) } - return result; + return result } - log.debug('ERROR: sequenceId out of range'); - return 'ERROR'; + log.debug('ERROR: sequenceId out of range') + return 'ERROR' } - /** * pascalCase() converts the string to pascal case * @param {String} str @@ -374,71 +363,70 @@ function readFromCircularBuffer(seqId, idVal, uuidVal, path) { * Eg. str = hello_World res= Hello_World * Eg. str = helloworld res= Helloworld */ -function pascalCase(strReceived) { +function pascalCase (strReceived) { if (strReceived !== undefined) { return strReceived.replace(/\w\S*/g, (txt) => { - const str = txt.split('_'); - let res = ''; + const str = txt.split('_') + let res = '' if (str) { - let str0 = ''; - let str1 = ''; - str0 = str[0].charAt(0).toUpperCase() + str[0].substr(1).toLowerCase(); + let str0 = '' + let str1 = '' + str0 = str[0].charAt(0).toUpperCase() + str[0].substr(1).toLowerCase() if (str[1]) { - str1 = str[1].charAt(0).toUpperCase() + str[1].substr(1).toLowerCase(); + str1 = str[1].charAt(0).toUpperCase() + str[1].substr(1).toLowerCase() } - res = str0 + str1; + res = str0 + str1 } - return res; - }); + return res + }) } - return log.error('Internal Error'); + return log.error('Internal Error') } - -function handleCondition(objVal, value) { - const obj = objVal; +function handleCondition (objVal, value) { + const obj = objVal if (value[1] !== '') { - obj.$.nativeCode = value[1]; + obj.$.nativeCode = value[1] } if (value[2] !== '') { - obj.$.nativeSeverity = value[2]; + obj.$.nativeSeverity = value[2] } if (value[3] !== '') { - obj.$.qualifier = value[3]; + obj.$.qualifier = value[3] } if (value[4] !== '') { - obj._ = value[4]; + obj._ = value[4] } - return obj; + return obj } -function handleAlarm(objVal, value) { - const obj = objVal; +function handleAlarm (objVal, value) { + const obj = objVal if (value[0] !== '') { - obj.$.code = value[0]; + obj.$.code = value[0] } if (value[1] !== '') { - obj.$.nativeCode = value[1]; + obj.$.nativeCode = value[1] } if (value[2] !== '') { - obj.$.severity = value[2]; + obj.$.severity = value[2] } if (value[3] !== '') { - obj.$.state = value[3]; + obj.$.state = value[3] } if (value[4] !== '') { - obj._ = value[4]; + obj._ = value[4] } - return obj; + return obj } -function handleMessage(objVal, value) { - const obj = objVal; +function handleMessage (objVal, value) { + const obj = objVal if (value[0] !== '') { - obj.$.nativeCode = value[0]; + obj.$.nativeCode = value[0] } - obj._ = value[1]; + obj._ = value[1] } /** * createDataItemForEachId creates the dataItem with recent value @@ -452,55 +440,55 @@ function handleMessage(objVal, value) { * return dataItem - array of dataItem(s) for an id. */ -function createDataItemForEachId(recentDataEntry, data, category) { - const dataItem = []; +function createDataItemForEachId (recentDataEntry, data, category) { + const dataItem = [] - let type = pascalCase(data.type); + let type = pascalCase(data.type) for (let i = 0; i < recentDataEntry.length; i++) { - const value = recentDataEntry[i].value; + const value = recentDataEntry[i].value const obj = { $: { dataItemId: data.id, - timestamp: recentDataEntry[i].time, - sequence: recentDataEntry[i].sequenceId, - }, - }; + timestamp: recentDataEntry[i].time, + sequence: recentDataEntry[i].sequenceId + } + } if (data.name) { - obj.$.name = data.name; + obj.$.name = data.name } if (data.subType) { - obj.$.subType = data.subType; + obj.$.subType = data.subType } if (data.representation === 'TIME_SERIES') { - type = `${type}TimeSeries`; - obj.$.sampleCount = recentDataEntry[i].sampleCount; - obj.$.sampleRate = recentDataEntry[i].sampleRate; + type = `${type}TimeSeries` + obj.$.sampleCount = recentDataEntry[i].sampleCount + obj.$.sampleRate = recentDataEntry[i].sampleRate } if (category === 'CONDITION') { - obj.$.type = data.type; // TODO if (obj.$.type !== undefined) + obj.$.type = data.type // TODO if (obj.$.type !== undefined) if (Array.isArray(value)) { - dataItem[i] = R.assoc(pascalCase(value[0]), obj, {}); - handleCondition(obj, value); + dataItem[i] = R.assoc(pascalCase(value[0]), obj, {}) + handleCondition(obj, value) } else { - dataItem[i] = R.assoc(pascalCase(value), obj, {}); + dataItem[i] = R.assoc(pascalCase(value), obj, {}) } } else { if (data.type === 'MESSAGE') { if (Array.isArray(value)) { - handleMessage(obj, value); + handleMessage(obj, value) } } else if (data.type === 'ALARM') { if (Array.isArray(value)) { - handleAlarm(obj, value); + handleAlarm(obj, value) } } else { - obj._ = value; + obj._ = value } - dataItem[i] = R.assoc(type, obj, {}); + dataItem[i] = R.assoc(type, obj, {}) } } - return dataItem; + return dataItem } /** @@ -513,24 +501,23 @@ function createDataItemForEachId(recentDataEntry, data, category) { * * return dataItem - array of dataItem(s) for the particular category in the sequenceId bound. */ -function createSampleDataItem(categoryArr, sequenceId, category, uuidVal, countVal, path) { - const recentDataEntry = []; - const dataItem = []; - const seqId = Number(sequenceId); - const count = Number(countVal); +function createSampleDataItem (categoryArr, sequenceId, category, uuidVal, countVal, path) { + const recentDataEntry = [] + const dataItem = [] + const seqId = Number(sequenceId) + const count = Number(countVal) for (let i = 0, j = 0; i < categoryArr.length; i++) { - const data = categoryArr[i].$; - recentDataEntry[i] = getRecentDataItemForSample(seqId, data.id, uuidVal, count, path); + const data = categoryArr[i].$ + recentDataEntry[i] = getRecentDataItemForSample(seqId, data.id, uuidVal, count, path) if (!(R.isEmpty(recentDataEntry[i])) && (recentDataEntry[i] !== 'ERROR')) { - dataItem[j++] = createDataItemForEachId(recentDataEntry[i], data, category); + dataItem[j++] = createDataItemForEachId(recentDataEntry[i], data, category) } else if (recentDataEntry[i] === 'ERROR') { - return log.debug('OUT_OF_RANGE Error'); + return log.debug('OUT_OF_RANGE Error') } } - return dataItem; + return dataItem } - /** * createDataItem creates the dataItem with recent value * and append name and subType if present and associate it to Object type @@ -543,67 +530,66 @@ function createSampleDataItem(categoryArr, sequenceId, category, uuidVal, countV * return dataItem */ -function createDataItem(categoryArr, sequenceId, category, uuid, path) { - const recentDataEntry = []; - const dataItem = []; +function createDataItem (categoryArr, sequenceId, category, uuid, path) { + const recentDataEntry = [] + const dataItem = [] for (let i = 0; i < categoryArr.length; i++) { - const data = categoryArr[i].$; - let type = pascalCase(data.type); + const data = categoryArr[i].$ + let type = pascalCase(data.type) if ((sequenceId === undefined) || (sequenceId === '')) { // current - recentDataEntry[i] = readFromHashCurrent(data.id, path); + recentDataEntry[i] = readFromHashCurrent(data.id, path) } else { // current?at - recentDataEntry[i] = readFromCircularBuffer(sequenceId, data.id, uuid, path); + recentDataEntry[i] = readFromCircularBuffer(sequenceId, data.id, uuid, path) } if (recentDataEntry[i] !== undefined) { - const value = recentDataEntry[i].value; + const value = recentDataEntry[i].value const obj = { $: { dataItemId: data.id, - timestamp: recentDataEntry[i].time, - sequence: recentDataEntry[i].sequenceId, - }, - }; + timestamp: recentDataEntry[i].time, + sequence: recentDataEntry[i].sequenceId + } + } if (data.name) { - obj.$.name = data.name; + obj.$.name = data.name } if (data.subType) { - obj.$.subType = data.subType; + obj.$.subType = data.subType } if (data.representation === 'TIME_SERIES') { - type = `${type}TimeSeries`; - obj.$.sampleCount = recentDataEntry[i].sampleCount; - obj.$.sampleRate = recentDataEntry[i].sampleRate; + type = `${type}TimeSeries` + obj.$.sampleCount = recentDataEntry[i].sampleCount + obj.$.sampleRate = recentDataEntry[i].sampleRate } if (category === 'CONDITION') { - obj.$.type = data.type; + obj.$.type = data.type if (Array.isArray(value)) { - dataItem[i] = R.assoc(pascalCase(value[0]), obj, {}); - handleCondition(obj, value); + dataItem[i] = R.assoc(pascalCase(value[0]), obj, {}) + handleCondition(obj, value) } else { - dataItem[i] = R.assoc(pascalCase(value), obj, {}); + dataItem[i] = R.assoc(pascalCase(value), obj, {}) } } else { if (data.type === 'MESSAGE') { if (Array.isArray(value)) { - handleMessage(obj, value); + handleMessage(obj, value) } else { - obj._ = recentDataEntry[i].value; + obj._ = recentDataEntry[i].value } } else if (data.type === 'ALARM') { if (Array.isArray(value)) { - handleAlarm(obj, value); + handleAlarm(obj, value) } else { - obj._ = recentDataEntry[i].value; + obj._ = recentDataEntry[i].value } } else { - obj._ = recentDataEntry[i].value; + obj._ = recentDataEntry[i].value } - dataItem[i] = R.assoc(type, obj, {}); + dataItem[i] = R.assoc(type, obj, {}) } } } - return dataItem; + return dataItem } - /** * categoriseDataItem() categorise dataItem into EVENT, SAMPLE, CONDITION * @@ -613,159 +599,158 @@ function createDataItem(categoryArr, sequenceId, category, uuid, path) { * return DataItemVar with latest value appended to it. * It has three objects Event, Sample, Condition. */ -function categoriseDataItem(latestSchema, dataItemsArr, sequenceId, uuid, path, count) { - const DataItemVar = {}; - const eventArr = []; - const sample = []; - const condition = []; - let eventObj; - let sampleObj; - let conditionObj; +function categoriseDataItem (latestSchema, dataItemsArr, sequenceId, uuid, path, count) { + const DataItemVar = {} + const eventArr = [] + const sample = [] + const condition = [] + let eventObj + let sampleObj + let conditionObj for (let i = 0, j = 0, k = 0, l = 0; i < dataItemsArr.length; i++) { - const category = dataItemsArr[i].$.category; + const category = dataItemsArr[i].$.category if (category === 'EVENT') { - eventArr[j++] = dataItemsArr[i]; + eventArr[j++] = dataItemsArr[i] } else if (category === 'SAMPLE') { - sample[k++] = dataItemsArr[i]; + sample[k++] = dataItemsArr[i] } else { // if (category === 'CONDITION') - condition[l++] = dataItemsArr[i]; + condition[l++] = dataItemsArr[i] } } if (count) { - eventObj = createSampleDataItem(eventArr, sequenceId, 'EVENT', uuid, count, path); - sampleObj = createSampleDataItem(sample, sequenceId, 'SAMPLE', uuid, count, path); - conditionObj = createSampleDataItem(condition, sequenceId, 'CONDITION', uuid, count, path); + eventObj = createSampleDataItem(eventArr, sequenceId, 'EVENT', uuid, count, path) + sampleObj = createSampleDataItem(sample, sequenceId, 'SAMPLE', uuid, count, path) + conditionObj = createSampleDataItem(condition, sequenceId, 'CONDITION', uuid, count, path) } else { - eventObj = createDataItem(eventArr, sequenceId, 'EVENT', uuid, path); - sampleObj = createDataItem(sample, sequenceId, 'SAMPLE', uuid, path); - conditionObj = createDataItem(condition, sequenceId, 'CONDITION', uuid, path); + eventObj = createDataItem(eventArr, sequenceId, 'EVENT', uuid, path) + sampleObj = createDataItem(sample, sequenceId, 'SAMPLE', uuid, path) + conditionObj = createDataItem(condition, sequenceId, 'CONDITION', uuid, path) } - DataItemVar.Event = eventObj; - DataItemVar.Sample = sampleObj; - DataItemVar.Condition = conditionObj; - return DataItemVar; + DataItemVar.Event = eventObj + DataItemVar.Sample = sampleObj + DataItemVar.Condition = conditionObj + return DataItemVar } /* ****************************** ASSET reading ****************************** */ -function sortByTime(arr) { - const sortTime = R.sortBy(R.prop('time')); - const result = sortTime(arr); - return R.reverse(result); +function sortByTime (arr) { + const sortTime = R.sortBy(R.prop('time')) + const result = sortTime(arr) + return R.reverse(result) } - -function filterByCount(count, assetSet) { - let assetCount = 0; - let j = 0; let m = 0; - const result = []; - const assetId = []; - const assetList = assetSet; +function filterByCount (count, assetSet) { + let assetCount = 0 + let j = 0; let m = 0 + const result = [] + const assetId = [] + const assetList = assetSet if (!R.isEmpty(assetList)) { - result[j++] = assetList[0]; - assetCount++; - assetId[m++] = result[j - 1].assetId; + result[j++] = assetList[0] + assetCount++ + assetId[m++] = result[j - 1].assetId for (let i = 1; (assetCount < count && i < assetList.length); i--) { - let idPresent = false; + let idPresent = false for (let k = 0; k < assetId.length; k++) { if (assetList[i].assetId === assetId[k]) { - idPresent = true; + idPresent = true } } if (!idPresent) { - result[j++] = assetList[i]; - assetId[m++] = result[j - 1].assetId; - assetCount++; + result[j++] = assetList[i] + assetId[m++] = result[j - 1].assetId + assetCount++ } } } - return result; + return result } -function filterAssets(assetData, type, count, removed, target, archetypeId) { - let assetSet = assetData; +function filterAssets (assetData, type, count, removed, target, archetypeId) { + let assetSet = assetData if (type) { - assetSet = R.filter((v) => v.assetType === type)(assetSet); + assetSet = R.filter((v) => v.assetType === type)(assetSet) } if (removed) { // include removed assets also - assetSet = R.filter((v) => (v.removed === true || v.removed === false))(assetSet); + assetSet = R.filter((v) => (v.removed === true || v.removed === false))(assetSet) } else { - assetSet = R.filter((v) => v.removed === false)(assetSet); + assetSet = R.filter((v) => v.removed === false)(assetSet) } if (target) { - assetSet = R.filter((v) => v.target === target)(assetSet); + assetSet = R.filter((v) => v.target === target)(assetSet) } - assetSet = sortByTime(assetSet); + assetSet = sortByTime(assetSet) if (count) { - assetSet = filterByCount(count, assetSet); + assetSet = filterByCount(count, assetSet) } - return assetSet; + return assetSet } -function createAssetItemForAssets(assetDetails) { - const cuttingTool = []; - const obj = {}; - let i = 0; +function createAssetItemForAssets (assetDetails) { + const cuttingTool = [] + const obj = {} + let i = 0 if (!R.isEmpty(assetDetails)) { R.map((k) => { if (k !== undefined) { - const valueJSON = k.value; + const valueJSON = k.value if (k.assetType === 'CuttingTool') { - delete valueJSON.CuttingTool.Description; // remove Description - cuttingTool[i++] = valueJSON.CuttingTool; - const CuttingToolAttributes = cuttingTool[i - 1].$; - CuttingToolAttributes.assetId = k.assetId; - CuttingToolAttributes.timestamp = k.time; - CuttingToolAttributes.deviceUuid = k.uuid; + delete valueJSON.CuttingTool.Description // remove Description + cuttingTool[i++] = valueJSON.CuttingTool + const CuttingToolAttributes = cuttingTool[i - 1].$ + CuttingToolAttributes.assetId = k.assetId + CuttingToolAttributes.timestamp = k.time + CuttingToolAttributes.deviceUuid = k.uuid } } - return cuttingTool; // to make eslint happy - }, assetDetails); + return cuttingTool // to make eslint happy + }, assetDetails) } - obj.CuttingTool = cuttingTool; - return obj; + obj.CuttingTool = cuttingTool + return obj } -function createAssetItem(assetDetails) { - const obj = { CuttingTool: [] }; +function createAssetItem (assetDetails) { + const obj = { CuttingTool: [] } if (assetDetails !== undefined) { - const valueJSON = assetDetails.value; - delete valueJSON.CuttingTool.Description; // remove Description - obj.CuttingTool[0] = valueJSON.CuttingTool; - const CuttingToolAttributes = obj.CuttingTool[0].$; - CuttingToolAttributes.assetId = assetDetails.assetId; - CuttingToolAttributes.timestamp = assetDetails.time; - CuttingToolAttributes.deviceUuid = assetDetails.uuid; - } - return obj; + const valueJSON = assetDetails.value + delete valueJSON.CuttingTool.Description // remove Description + obj.CuttingTool[0] = valueJSON.CuttingTool + const CuttingToolAttributes = obj.CuttingTool[0].$ + CuttingToolAttributes.assetId = assetDetails.assetId + CuttingToolAttributes.timestamp = assetDetails.time + CuttingToolAttributes.deviceUuid = assetDetails.uuid + } + return obj } -function readAssets(assetCollection, type, count, removed, target, archetypeId) { - const assetData = []; - let assetDetails; - let i = 0; +function readAssets (assetCollection, type, count, removed, target, archetypeId) { + const assetData = [] + let assetDetails + let i = 0 R.map((k) => { - const obj = hashAssetCurrent.get(k); + const obj = hashAssetCurrent.get(k) if (obj !== undefined) { - assetData[i++] = obj; + assetData[i++] = obj } - return assetData; // eslint - }, assetCollection); + return assetData // eslint + }, assetCollection) if (type || count || removed || target || archetypeId) { - assetDetails = filterAssets(assetData, type, count, removed, target, archetypeId); + assetDetails = filterAssets(assetData, type, count, removed, target, archetypeId) } else { - assetDetails = sortByTime(assetData); + assetDetails = sortByTime(assetData) } - const assetResult = createAssetItemForAssets(assetDetails); + const assetResult = createAssetItemForAssets(assetDetails) - return assetResult; + return assetResult } -function readAssetforId(assetId, type, count, removed, target, archetypeId) { - const assetDetails = hashAssetCurrent.get(assetId); - const assetResult = createAssetItem(assetDetails); - return assetResult; +function readAssetforId (assetId, type, count, removed, target, archetypeId) { + const assetDetails = hashAssetCurrent.get(assetId) + const assetResult = createAssetItem(assetDetails) + return assetResult } // Exports @@ -790,5 +775,5 @@ module.exports = { getRecentDataItemForSample, filterPath, filterPathArr, - filterAssets, -}; + filterAssets +} diff --git a/src/finder.js b/src/finder.js index b35f001..48dcb6f 100644 --- a/src/finder.js +++ b/src/finder.js @@ -2,45 +2,45 @@ // * finding new devices on the network // * emit new event when one found // * consider setImmediate(func) to handle devices -const EventEmitter = require('events'); -const { Client } = require('node-ssdp'); -const { parseHeaders } = require('./utils'); -const log = require('./config/logger'); -const co = require('co'); -const wait = require('co-wait'); +const EventEmitter = require('events') +const { Client } = require('node-ssdp') +const { parseHeaders } = require('./utils') +const log = require('./config/logger') +const co = require('co') +const wait = require('co-wait') class Finder extends EventEmitter { - constructor({ query, frequency }) { - super(); - this.query = query; - this.frequency = frequency; - this.client = new Client(); - this.stop = this.stop.bind(this); - this.search = this.search.bind(this); - this.client.on('response', this.device.bind(this)); - this.client.on('error', log.error.bind(log)); + constructor ({ query, frequency }) { + super() + this.query = query + this.frequency = frequency + this.client = new Client() + this.stop = this.stop.bind(this) + this.search = this.search.bind(this) + this.client.on('response', this.device.bind(this)) + this.client.on('error', log.error.bind(log)) } - device(data) { - const info = parseHeaders(data); - this.emit('device', info); + device (data) { + const info = parseHeaders(data) + this.emit('device', info) } - *search() { + * search () { while (true) { - log.debug(this.query); - this.client.search(this.query); - yield wait(this.frequency); + log.debug(this.query) + this.client.search(this.query) + yield wait(this.frequency) } } - start() { - co(this.search).catch(log.error.bind(log)); + start () { + co(this.search).catch(log.error.bind(log)) } - stop() { - this.client.stop(); + stop () { + this.client.stop() } } -module.exports = Finder; +module.exports = Finder diff --git a/src/jsonToXML.js b/src/jsonToXML.js index e0c9c87..c987394 100644 --- a/src/jsonToXML.js +++ b/src/jsonToXML.js @@ -16,17 +16,17 @@ // Imports - External -const stream = require('stream'); -const through = require('through'); -const converter = require('converter'); -const moment = require('moment'); -const R = require('ramda'); -const md5 = require('md5'); +const stream = require('stream') +const through = require('through') +const converter = require('converter') +const moment = require('moment') +const R = require('ramda') +const md5 = require('md5') // Imports - Internal -const dataStorage = require('./dataStorage'); -const lokijs = require('./lokijs'); -const log = require('./config/logger'); +const dataStorage = require('./dataStorage') +const lokijs = require('./lokijs') +const log = require('./config/logger') /* ********* Helper functions to recreate the heirarchial structure *************** */ /** @@ -36,20 +36,20 @@ const log = require('./config/logger'); * @param {Object} arr - all dataItems in the timebound * @param {String} id - the id of dataitem required. */ -function findDataItemForSample(arr, id) { - let typeArr; - let res; +function findDataItemForSample (arr, id) { + let typeArr + let res for (let i = 0; i < arr.length; i++) { - typeArr = arr[i]; - const key = R.keys(typeArr[0]); - const pluckedData = (R.pluck(key, typeArr)); + typeArr = arr[i] + const key = R.keys(typeArr[0]) + const pluckedData = (R.pluck(key, typeArr)) if (pluckedData.length !== 0) { if (pluckedData[0].$.dataItemId === id) { - res = typeArr; + res = typeArr } } } - return res; + return res } /** @@ -60,30 +60,30 @@ function findDataItemForSample(arr, id) { * @param {String} reqType - 'SAMPLE' when the request is SAMPLE */ -function findDataItem(arr, id, reqType) { - let res; +function findDataItem (arr, id, reqType) { + let res if (reqType === 'SAMPLE') { - res = findDataItemForSample(arr, id); - return res; + res = findDataItemForSample(arr, id) + return res } for (let i = 0; i < arr.length; i++) { - const keys = R.keys(arr[i]); + const keys = R.keys(arr[i]) // k are the keys Eg: Availability, Load etc R.find((k) => { // pluck the properties of all objects corresponding to k if ((R.pluck(k, [arr[i]])) !== undefined) { - const pluckedData = (R.pluck(k, [arr[i]]))[0]; // result will be an array + const pluckedData = (R.pluck(k, [arr[i]]))[0] // result will be an array if (pluckedData.length !== 0) { if (pluckedData.$.dataItemId === id) { - res = arr[i]; + res = arr[i] } } } - return (res !== undefined); // to make eslint happy - }, keys); + return (res !== undefined) // to make eslint happy + }, keys) } - return res; + return res } /** @@ -95,22 +95,21 @@ function findDataItem(arr, id, reqType) { * with each category as seperate object. * @param {String} reqType - 'SAMPLE' when the request is SAMPLE */ -function parseCategorisedArray(category, id, DataItemVar, reqType) { +function parseCategorisedArray (category, id, DataItemVar, reqType) { if (category === 'EVENT') { - const arr = DataItemVar.Event; - const result = findDataItem(arr, id, reqType); - return result; + const arr = DataItemVar.Event + const result = findDataItem(arr, id, reqType) + return result } else if (category === 'SAMPLE') { - const arr = DataItemVar.Sample; - const result = findDataItem(arr, id, reqType); - return result; + const arr = DataItemVar.Sample + const result = findDataItem(arr, id, reqType) + return result } // category === CONDITION - const arr = DataItemVar.Condition; - const result = findDataItem(arr, id, reqType); - return result; + const arr = DataItemVar.Condition + const result = findDataItem(arr, id, reqType) + return result } - /** * parseDataItems * @param dataItems - DataItems from device schema @@ -122,40 +121,40 @@ function parseCategorisedArray(category, id, DataItemVar, reqType) { * @param {String} reqType -'SAMPLE' or undefined * return obj with eventArr, sampleArr, conditionArr in the required response format. */ -function parseDataItems(dataItems, DataItemVar, reqType) { - const sampleArr = []; - const conditionArr = []; - const eventArr = []; - const obj = {}; +function parseDataItems (dataItems, DataItemVar, reqType) { + const sampleArr = [] + const conditionArr = [] + const eventArr = [] + const obj = {} for (let k = 0; k < dataItems.length; k++) { - const dataItem = dataItems[k].DataItem; + const dataItem = dataItems[k].DataItem for (let l = 0, m = 0, n = 0, p = 0; l < dataItem.length; l++) { - const id = dataItem[l].$.id; - const category = dataItem[l].$.category; + const id = dataItem[l].$.id + const category = dataItem[l].$.category if (category === 'EVENT') { - const tempEvent = parseCategorisedArray(category, id, DataItemVar, reqType); + const tempEvent = parseCategorisedArray(category, id, DataItemVar, reqType) if (tempEvent !== undefined) { - eventArr[p++] = tempEvent; + eventArr[p++] = tempEvent } } if (category === 'SAMPLE') { - const tempSample = parseCategorisedArray(category, id, DataItemVar, reqType); + const tempSample = parseCategorisedArray(category, id, DataItemVar, reqType) if (tempSample !== undefined) { - sampleArr[m++] = tempSample; + sampleArr[m++] = tempSample } } if (category === 'CONDITION') { - const tempCondition = parseCategorisedArray(category, id, DataItemVar, reqType); + const tempCondition = parseCategorisedArray(category, id, DataItemVar, reqType) if (tempCondition !== undefined) { - conditionArr[n++] = tempCondition; + conditionArr[n++] = tempCondition } } } } - obj.eventArr = eventArr; - obj.sampleArr = sampleArr; - obj.conditionArr = conditionArr; - return obj; + obj.eventArr = eventArr + obj.sampleArr = sampleArr + obj.conditionArr = conditionArr + return obj } /** @@ -172,34 +171,34 @@ function parseDataItems(dataItems, DataItemVar, reqType) { * @param {Object} componentObj - pointer to ComponentStreams */ -function createComponentStream(obj, componentName, name, id, componentObj) { - const eventArr = obj.eventArr; - const conditionArr = obj.conditionArr; - const sampleArr = obj.sampleArr; - const componentObj1 = componentObj; - let len = 0; +function createComponentStream (obj, componentName, name, id, componentObj) { + const eventArr = obj.eventArr + const conditionArr = obj.conditionArr + const sampleArr = obj.sampleArr + const componentObj1 = componentObj + let len = 0 if (sampleArr.length !== 0 || eventArr.length !== 0 || conditionArr.length !== 0) { - const title = { $: { component: componentName, name, - componentId: id } }; - componentObj.push(title); + const title = { $: { component: componentName, + name, + componentId: id } } + componentObj.push(title) } if (sampleArr.length !== 0) { - len = componentObj.length - 1; - componentObj1[len].Samples = []; - componentObj1[len].Samples.push(sampleArr); + len = componentObj.length - 1 + componentObj1[len].Samples = [] + componentObj1[len].Samples.push(sampleArr) } if (eventArr.length !== 0) { - len = componentObj.length - 1; - componentObj1[len].Events = []; - componentObj1[len].Events.push(eventArr); + len = componentObj.length - 1 + componentObj1[len].Events = [] + componentObj1[len].Events.push(eventArr) } if (conditionArr.length !== 0) { - len = componentObj.length - 1; - componentObj1[len].Condition = []; - componentObj1[len].Condition.push(conditionArr); + len = componentObj.length - 1 + componentObj1[len].Condition = [] + componentObj1[len].Condition.push(conditionArr) } - return; } /** @@ -212,21 +211,21 @@ function createComponentStream(obj, componentName, name, id, componentObj) { * @param {String} reqType - 'SAMPLE' or undefined * */ -function parseLevelSix(container, componentObj, DataItemVar, reqType) { +function parseLevelSix (container, componentObj, DataItemVar, reqType) { for (let i = 0; i < container.length; i++) { - const keys = R.keys(container[i]); + const keys = R.keys(container[i]) R.find((k) => { - const pluckedData = (R.pluck(k)([container[i]]))[0]; // result will be an array - const componentName = k; + const pluckedData = (R.pluck(k)([container[i]]))[0] // result will be an array + const componentName = k for (let j = 0; j < pluckedData.length; j++) { - const name = pluckedData[j].$.name; - const id = pluckedData[j].$.id; - const dataItems = pluckedData[j].DataItems; - const obj = parseDataItems(dataItems, DataItemVar, reqType); - createComponentStream(obj, componentName, name, id, componentObj); + const name = pluckedData[j].$.name + const id = pluckedData[j].$.id + const dataItems = pluckedData[j].DataItems + const obj = parseDataItems(dataItems, DataItemVar, reqType) + createComponentStream(obj, componentName, name, id, componentObj) } - return 0; // to make eslint happy - }, keys); + return 0 // to make eslint happy + }, keys) } } @@ -240,20 +239,20 @@ function parseLevelSix(container, componentObj, DataItemVar, reqType) { * @param {String} reqType - 'SAMPLE' or undefined * */ -function parseLevelFive(container, componentName, componentObj, DataItemVar, reqType) { +function parseLevelFive (container, componentName, componentObj, DataItemVar, reqType) { for (let j = 0; j < container.length; j++) { - const name = container[j].$.name; - const id = container[j].$.id; + const name = container[j].$.name + const id = container[j].$.id if (container[j].DataItems !== undefined) { - const dataItems = container[j].DataItems; - const obj = parseDataItems(dataItems, DataItemVar, reqType); - createComponentStream(obj, componentName, name, id, componentObj, reqType); + const dataItems = container[j].DataItems + const obj = parseDataItems(dataItems, DataItemVar, reqType) + createComponentStream(obj, componentName, name, id, componentObj, reqType) } if (container[j].Components !== undefined) { - parseLevelSix(container[j].Components, componentObj, DataItemVar, reqType); + parseLevelSix(container[j].Components, componentObj, DataItemVar, reqType) } - return; + return } } @@ -263,25 +262,25 @@ function parseLevelFive(container, componentName, componentObj, DataItemVar, req * return obj with keys firstSequence, lastSequence, nextSequence * */ -function calculateSequence(reqType) { - let nextSequence; +function calculateSequence (reqType) { + let nextSequence - const getSequence = dataStorage.getSequence(); - const firstSequence = getSequence.firstSequence; - const lastSequence = getSequence.lastSequence; + const getSequence = dataStorage.getSequence() + const firstSequence = getSequence.firstSequence + const lastSequence = getSequence.lastSequence if (reqType === 'SAMPLE') { - const temp = getSequence.nextSequence; - nextSequence = temp; + const temp = getSequence.nextSequence + nextSequence = temp } else { - nextSequence = lastSequence + 1; + nextSequence = lastSequence + 1 } const obj = { firstSequence, lastSequence, - nextSequence, - }; - return obj; + nextSequence + } + return obj } /* ****************** JSON Creation for Sample and Current ******************************* */ @@ -300,213 +299,210 @@ function calculateSequence(reqType) { * @param {String} reqType -'SAMPLE' or undefined. * returns the JSON object with all values */ -function updateJSON(latestSchema, DataItemVar, instanceId, reqType) { - const xmlns = latestSchema[0].xmlns.xmlns; - const arr = xmlns.split(':'); - const version = arr[arr.length - 1]; - const newTime = moment.utc().format(); - const dvcHeader = latestSchema[0].device.$; - - const sequence = calculateSequence(reqType); - const firstSequence = sequence.firstSequence; - const lastSequence = sequence.lastSequence; - const nextSequence = sequence.nextSequence; - const DataItems = latestSchema[0].device.DataItems; - const Components = latestSchema[0].device.Components; - let newJSON = {}; +function updateJSON (latestSchema, DataItemVar, instanceId, reqType) { + const xmlns = latestSchema[0].xmlns.xmlns + const arr = xmlns.split(':') + const version = arr[arr.length - 1] + const newTime = moment.utc().format() + const dvcHeader = latestSchema[0].device.$ + + const sequence = calculateSequence(reqType) + const firstSequence = sequence.firstSequence + const lastSequence = sequence.lastSequence + const nextSequence = sequence.nextSequence + const DataItems = latestSchema[0].device.DataItems + const Components = latestSchema[0].device.Components + let newJSON = {} const newXMLns = { 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', - xmlns: `urn:mtconnect.org:MTConnectStreams:${version}`, - 'xmlns:m': `urn:mtconnect.org:MTConnectStreams:${version}`, - 'xsi:schemaLocation': `urn:mtconnect.org:MTConnectStreams:${version} http://www.mtconnect.org/schemas/MTConnectStreams${version}.xsd` }; + xmlns: `urn:mtconnect.org:MTConnectStreams:${version}`, + 'xmlns:m': `urn:mtconnect.org:MTConnectStreams:${version}`, + 'xsi:schemaLocation': `urn:mtconnect.org:MTConnectStreams:${version} http://www.mtconnect.org/schemas/MTConnectStreams${version}.xsd` } newJSON = { MTConnectStreams: - { $: newXMLns, - Header: - [{ $: - { creationTime: newTime, - assetBufferSize: '1024', - sender: 'localhost', - assetCount: '0', - version, - instanceId, - bufferSize: '10', - nextSequence, - firstSequence, - lastSequence } }], - Streams: - [{ DeviceStream: - [{ $: { name: dvcHeader.name, uuid: dvcHeader.uuid }, - ComponentStreams: [], - }] }] } }; - - const componentObj = newJSON.MTConnectStreams.Streams[0].DeviceStream[0].ComponentStreams; + { $: newXMLns, + Header: + [{ $: + { creationTime: newTime, + assetBufferSize: '1024', + sender: 'localhost', + assetCount: '0', + version, + instanceId, + bufferSize: '10', + nextSequence, + firstSequence, + lastSequence } }], + Streams: + [{ DeviceStream: + [{ $: { name: dvcHeader.name, uuid: dvcHeader.uuid }, + ComponentStreams: [] + }] }] } } + + const componentObj = newJSON.MTConnectStreams.Streams[0].DeviceStream[0].ComponentStreams if ((R.isEmpty(DataItemVar.Event)) && (R.isEmpty(DataItemVar.Sample)) && (R.isEmpty(DataItemVar.Condition))) { - log.debug('Empty'); - return newJSON; + log.debug('Empty') + return newJSON } if (DataItems !== undefined) { - const componentName = 'Device'; - const id = latestSchema[0].device.$.id; - const name = latestSchema[0].device.$.name; - const obj = parseDataItems(DataItems, DataItemVar, reqType); - createComponentStream(obj, componentName, name, id, componentObj); + const componentName = 'Device' + const id = latestSchema[0].device.$.id + const name = latestSchema[0].device.$.name + const obj = parseDataItems(DataItems, DataItemVar, reqType) + createComponentStream(obj, componentName, name, id, componentObj) } if (Components !== undefined) { for (let i = 0; i < Components.length; i++) { if (Components[i].Axes) { - const componentName = 'Axes'; - parseLevelFive(Components[i].Axes, componentName, componentObj, DataItemVar, reqType); + const componentName = 'Axes' + parseLevelFive(Components[i].Axes, componentName, componentObj, DataItemVar, reqType) } if (Components[i].Controller) { - const componentName = 'Controller'; - parseLevelFive(Components[i].Controller, componentName, componentObj, DataItemVar, reqType); + const componentName = 'Controller' + parseLevelFive(Components[i].Controller, componentName, componentObj, DataItemVar, reqType) } if (Components[i].Systems) { - const componentName = 'Systems'; - parseLevelFive(Components[i].Systems, componentName, componentObj, DataItemVar, reqType); + const componentName = 'Systems' + parseLevelFive(Components[i].Systems, componentName, componentObj, DataItemVar, reqType) } } } - return newJSON; + return newJSON } - /* ************************* JSON creation for Errors ************************** */ -function invalidPathError(path, errorObj) { - const errObj = errorObj; - let len = errObj.length - 1; +function invalidPathError (path, errorObj) { + const errObj = errorObj + let len = errObj.length - 1 if (errObj.length === 0 || errObj[len].Error === undefined) { - const title = { $: { } }; - errObj.push(title); - len = errObj.length - 1; - errObj[len].Error = []; + const title = { $: { } } + errObj.push(title) + len = errObj.length - 1 + errObj[len].Error = [] } - const CDATA = `The path could not be parsed. Invalid syntax: ${path}.`; + const CDATA = `The path could not be parsed. Invalid syntax: ${path}.` const obj = { $: { - errorCode: 'INVALID_XPATH', + errorCode: 'INVALID_XPATH' }, - _: CDATA, - }; - errObj[len].Error.push(obj); - return errObj; + _: CDATA + } + errObj[len].Error.push(obj) + return errObj } -function fromError(from, errorObj) { - const param = '\'from\''; - const sequence = dataStorage.getSequence(); - const firstSequence = sequence.firstSequence; - const lastSequence = sequence.lastSequence; - let CDATA; - let errorCode = 'OUT_OF_RANGE'; - const errObj = errorObj; - let len = errObj.length - 1; +function fromError (from, errorObj) { + const param = '\'from\'' + const sequence = dataStorage.getSequence() + const firstSequence = sequence.firstSequence + const lastSequence = sequence.lastSequence + let CDATA + let errorCode = 'OUT_OF_RANGE' + const errObj = errorObj + let len = errObj.length - 1 if (errObj.length === 0 || errObj[len].Error === undefined) { - const title = { $: { } }; - errObj.push(title); - len = errObj.length - 1; - errObj[len].Error = []; + const title = { $: { } } + errObj.push(title) + len = errObj.length - 1 + errObj[len].Error = [] } if (!Number.isInteger(from)) { - CDATA = `${param} must be a positive integer.`; + CDATA = `${param} must be a positive integer.` } else if (from < 0) { - CDATA = `${param} must be a positive integer.`; + CDATA = `${param} must be a positive integer.` } else if (from === 0) { - errorCode = 'INVALID_REQUEST'; - CDATA = `${param} must be greater than zero.`; + errorCode = 'INVALID_REQUEST' + CDATA = `${param} must be greater than zero.` } else if (from < firstSequence) { - CDATA = `${param} must be greater than or equal to ${firstSequence}.`; + CDATA = `${param} must be greater than or equal to ${firstSequence}.` } else { // if (from > lastSequence) - CDATA = `${param} must be less than or equal to ${lastSequence}.`; + CDATA = `${param} must be less than or equal to ${lastSequence}.` } - const obj = { $: { errorCode }, _: CDATA }; - errObj[len].Error.push(obj); - return errObj; + const obj = { $: { errorCode }, _: CDATA } + errObj[len].Error.push(obj) + return errObj } -function freqError(freq, errorObj) { - const param = '\'interval\''; - const errObj = errorObj; - const maxFreq = 2147483646; - let len = errObj.length - 1; - let CDATA; +function freqError (freq, errorObj) { + const param = '\'interval\'' + const errObj = errorObj + const maxFreq = 2147483646 + let len = errObj.length - 1 + let CDATA if (errObj.length === 0 || errObj[len].Error === undefined) { - const title = { $: { } }; - errObj.push(title); - len = errObj.length - 1; - errObj[len].Error = []; + const title = { $: { } } + errObj.push(title) + len = errObj.length - 1 + errObj[len].Error = [] } if (!Number.isInteger(freq)) { - CDATA = `${param} must be a positive integer.`; + CDATA = `${param} must be a positive integer.` } if (freq < 0) { - CDATA = `${param} must be a positive integer.`; + CDATA = `${param} must be a positive integer.` } if (freq > maxFreq) { - CDATA = `${param} must be greater than or equal to ${maxFreq}.`; + CDATA = `${param} must be greater than or equal to ${maxFreq}.` } const obj = { $: { - errorCode: 'OUT_OF_RANGE', + errorCode: 'OUT_OF_RANGE' }, - _: CDATA, - }; - errObj[len].Error.push(obj); - return errObj; + _: CDATA + } + errObj[len].Error.push(obj) + return errObj } - -function countError(count, errorObj) { - const param = '\'count\''; - const bufferSize = dataStorage.getBufferSize(); - const errObj = errorObj; - let len = errObj.length - 1; - let errorCode = 'OUT_OF_RANGE'; - let CDATA; +function countError (count, errorObj) { + const param = '\'count\'' + const bufferSize = dataStorage.getBufferSize() + const errObj = errorObj + let len = errObj.length - 1 + let errorCode = 'OUT_OF_RANGE' + let CDATA if (errObj.length === 0 || errObj[len].Error === undefined) { - const title = { $: { } }; - errObj.push(title); - len = errObj.length - 1; - errObj[len].Error = []; + const title = { $: { } } + errObj.push(title) + len = errObj.length - 1 + errObj[len].Error = [] } if (!Number.isInteger(count)) { - CDATA = `${param} must be a positive integer.`; + CDATA = `${param} must be a positive integer.` } if (count < 0) { - CDATA = `${param} must be a positive integer.`; + CDATA = `${param} must be a positive integer.` } if (count === 0) { - errorCode = 'INVALID_REQUEST'; - CDATA = `${param} must be greater than or equal to 1.`; + errorCode = 'INVALID_REQUEST' + CDATA = `${param} must be greater than or equal to 1.` } if (count > bufferSize) { - CDATA = `${param} must be less than or equal to ${bufferSize}.`; + CDATA = `${param} must be less than or equal to ${bufferSize}.` } - const obj = { $: { errorCode }, _: CDATA }; - errObj[len].Error.push(obj); - return errObj; + const obj = { $: { errorCode }, _: CDATA } + errObj[len].Error.push(obj) + return errObj } - /** * sequenceIdError() creates the CDATA and errorCode for * when given sequenceId is out of range and append it to Errors @@ -515,38 +511,37 @@ function countError(count, errorObj) { * */ -function sequenceIdError(sequenceId, errorObj) { - const param = '\'at\''; - const sequenceObj = dataStorage.getSequence(); - const firstSeq = Number(sequenceObj.firstSequence); - const lastSeq = Number(sequenceObj.lastSequence); - const errObj = errorObj; - let len = errObj.length - 1; +function sequenceIdError (sequenceId, errorObj) { + const param = '\'at\'' + const sequenceObj = dataStorage.getSequence() + const firstSeq = Number(sequenceObj.firstSequence) + const lastSeq = Number(sequenceObj.lastSequence) + const errObj = errorObj + let len = errObj.length - 1 if (errObj.length === 0 || errObj[len].Error === undefined) { - const title = { $: { } }; - errObj.push(title); - len = errObj.length - 1; - errObj[len].Error = []; + const title = { $: { } } + errObj.push(title) + len = errObj.length - 1 + errObj[len].Error = [] } - let CDATA; + let CDATA if (sequenceId < 0) { - CDATA = `${param} must be a positive integer.`; + CDATA = `${param} must be a positive integer.` } else if (sequenceId < firstSeq) { - CDATA = `${param} must be greater than or equal to ${firstSeq}.`; + CDATA = `${param} must be greater than or equal to ${firstSeq}.` } else { - CDATA = `${param} must be less than or equal to ${lastSeq}.`; + CDATA = `${param} must be less than or equal to ${lastSeq}.` } const obj = { $: { - errorCode: 'OUT_OF_RANGE', + errorCode: 'OUT_OF_RANGE' }, - _: CDATA, - }; - errObj[len].Error.push(obj); - return errObj; + _: CDATA + } + errObj[len].Error.push(obj) + return errObj } - /** * singleError() creates the CDATA and errorCode for * when the requested device is not present and append it to Errors @@ -554,20 +549,19 @@ function sequenceIdError(sequenceId, errorObj) { * @param {Object} errObj * */ -function singleError(errorObj, CDATA, errorCode) { - const title = { $: { } }; - const errObj = errorObj; - errObj.push(title); - const len = errObj.length - 1; - errObj[len].Error = []; +function singleError (errorObj, CDATA, errorCode) { + const title = { $: { } } + const errObj = errorObj + errObj.push(title) + const len = errObj.length - 1 + errObj[len].Error = [] const obj = { $: { - errorCode, + errorCode }, - _: CDATA, - }; - errObj[len].Error.push(obj); - return; + _: CDATA + } + errObj[len].Error.push(obj) } /** @@ -576,143 +570,143 @@ function singleError(errorObj, CDATA, errorCode) { * @param {String} errCategory (given to use this as a generic function) * @param {Any} value (depends on the errCategory) */ -function createErrorResponse(instanceId, errCategory, value) { +function createErrorResponse (instanceId, errCategory, value) { // const xmlns = latestSchema[0].xmlns.xmlns; // const arr = xmlns.split(':'); - const version = 1.3; // arr[arr.length - 1]; //TODO: move to config - const newTime = moment.utc().format(); + const version = 1.3 // arr[arr.length - 1]; //TODO: move to config + const newTime = moment.utc().format() const newXMLns = { 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', - xmlns: `urn:mtconnect.org:MTConnectError:${version}`, - 'xmlns:m': `urn:mtconnect.org:MTConnectError:${version}`, - 'xsi:schemaLocation': `urn:mtconnect.org:MTConnectError:${version} http://www.mtconnect.org/schemas/MTConnectError${version}.xsd` }; + xmlns: `urn:mtconnect.org:MTConnectError:${version}`, + 'xmlns:m': `urn:mtconnect.org:MTConnectError:${version}`, + 'xsi:schemaLocation': `urn:mtconnect.org:MTConnectError:${version} http://www.mtconnect.org/schemas/MTConnectError${version}.xsd` } - let errorJSON = {}; + let errorJSON = {} errorJSON = { MTConnectError: - { $: newXMLns, - Header: - [{ $: - { creationTime: newTime, - sender: 'localhost', - instanceId, - bufferSize: '10', - version, - } }], - Errors: [], - }, - }; - const errorObj = errorJSON.MTConnectError.Errors; - let CDATA; - let errorCode; + { $: newXMLns, + Header: + [{ $: + { creationTime: newTime, + sender: 'localhost', + instanceId, + bufferSize: '10', + version + } }], + Errors: [] + } + } + const errorObj = errorJSON.MTConnectError.Errors + let CDATA + let errorCode if (errCategory === 'NO_DEVICE') { - CDATA = `Could not find the device ${value}.`; - errorCode = 'NO_DEVICE'; - singleError(errorObj, CDATA, errorCode); + CDATA = `Could not find the device ${value}.` + errorCode = 'NO_DEVICE' + singleError(errorObj, CDATA, errorCode) } if (errCategory === 'UNSUPPORTED') { - CDATA = `The following path is invalid: ${value}.`; - errorCode = 'UNSUPPORTED'; - singleError(errorObj, CDATA, errorCode); + CDATA = `The following path is invalid: ${value}.` + errorCode = 'UNSUPPORTED' + singleError(errorObj, CDATA, errorCode) } if (errCategory === 'INVALID_REQUEST') { - CDATA = 'You cannot specify both the at and frequency arguments to a current request.'; - errorCode = 'INVALID_REQUEST'; - singleError(errorObj, CDATA, errorCode); + CDATA = 'You cannot specify both the at and frequency arguments to a current request.' + errorCode = 'INVALID_REQUEST' + singleError(errorObj, CDATA, errorCode) } if (errCategory === 'ASSET_NOT_FOUND') { - CDATA = `Could not find asset ${value}.`; - errorCode = 'ASSET_NOT_FOUND'; - singleError(errorObj, CDATA, errorCode); + CDATA = `Could not find asset ${value}.` + errorCode = 'ASSET_NOT_FOUND' + singleError(errorObj, CDATA, errorCode) } if (errCategory === 'MULTIPART_STREAM') { - const sequenceObj = dataStorage.getSequence(); - const firstSeq = Number(sequenceObj.firstSequence); - const lastSeq = Number(sequenceObj.lastSequence); + const sequenceObj = dataStorage.getSequence() + const firstSeq = Number(sequenceObj.firstSequence) + const lastSeq = Number(sequenceObj.lastSequence) if (value < firstSeq) { - CDATA = 'Client can\'t keep up with event stream, disconnecting'; + CDATA = 'Client can\'t keep up with event stream, disconnecting' } else { // firstSeq < lastSeq < value - CDATA = `from value must be less than or equal to ${lastSeq}, disconnecting.`; + CDATA = `from value must be less than or equal to ${lastSeq}, disconnecting.` } - errorCode = 'OUT_OF_RANGE'; - singleError(errorObj, CDATA, errorCode); + errorCode = 'OUT_OF_RANGE' + singleError(errorObj, CDATA, errorCode) } if (errCategory === 'UNSUPPORTED_PUT') { - CDATA = value; - errorCode = 'UNSUPPORTED'; - singleError(errorObj, CDATA, errorCode); + CDATA = value + errorCode = 'UNSUPPORTED' + singleError(errorObj, CDATA, errorCode) } if (errCategory === 'QUERY_ERROR') { - CDATA = `${value} cannot be empty`; - errorCode = 'QUERY_ERROR'; - singleError(errorObj, CDATA, errorCode); + CDATA = `${value} cannot be empty` + errorCode = 'QUERY_ERROR' + singleError(errorObj, CDATA, errorCode) } - return errorJSON; + return errorJSON } // To handle multiple error -function categoriseError(errorObj, errCategory, value) { - let errObj; +function categoriseError (errorObj, errCategory, value) { + let errObj if (errCategory === 'SEQUENCEID') { - errObj = sequenceIdError(value, errorObj); + errObj = sequenceIdError(value, errorObj) } if (errCategory === 'INVALID_XPATH') { - errObj = invalidPathError(value, errorObj); + errObj = invalidPathError(value, errorObj) } if (errCategory === 'FROM') { - errObj = fromError(value, errorObj); + errObj = fromError(value, errorObj) } if (errCategory === 'COUNT') { - errObj = countError(value, errorObj); + errObj = countError(value, errorObj) } if (errCategory === 'INTERVAL') { - errObj = freqError(value, errorObj); + errObj = freqError(value, errorObj) } - return errObj; + return errObj } /* ********************** MTConnectAsset Response *************************** */ -function createAssetResponse(instanceId, assetItem) { - const version = 1.3; - const assetBufferSize = '1024'; // TODO get from cfg - const assetCollection = lokijs.getAssetCollection(); - const assetCount = assetCollection.length; - const newTime = moment.utc().format(); +function createAssetResponse (instanceId, assetItem) { + const version = 1.3 + const assetBufferSize = '1024' // TODO get from cfg + const assetCollection = lokijs.getAssetCollection() + const assetCount = assetCollection.length + const newTime = moment.utc().format() const newXMLns = { 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', - xmlns: `urn:mtconnect.org:MTConnectAssets:${version}`, - 'xmlns:m': `urn:mtconnect.org:MTConnectAssets:${version}`, - 'xsi:schemaLocation': `urn:mtconnect.org:MTConnectAssets:${version} http://www.mtconnect.org/schemas/MTConnectAssets${version}.xsd` }; - let assetJSON = {}; + xmlns: `urn:mtconnect.org:MTConnectAssets:${version}`, + 'xmlns:m': `urn:mtconnect.org:MTConnectAssets:${version}`, + 'xsi:schemaLocation': `urn:mtconnect.org:MTConnectAssets:${version} http://www.mtconnect.org/schemas/MTConnectAssets${version}.xsd` } + let assetJSON = {} assetJSON = { MTConnectAssets: - { $: newXMLns, - Header: - [{ $: - { creationTime: newTime, - sender: 'localhost', - instanceId, - version, - assetBufferSize, - assetCount, - } }], - Assets: [], - }, - }; - const assetObj = assetJSON.MTConnectAssets.Assets; + { $: newXMLns, + Header: + [{ $: + { creationTime: newTime, + sender: 'localhost', + instanceId, + version, + assetBufferSize, + assetCount + } }], + Assets: [] + } + } + const assetObj = assetJSON.MTConnectAssets.Assets if (assetItem !== undefined) { - assetObj.push(assetItem); + assetObj.push(assetItem) } - return assetJSON; + return assetJSON } /* ************************ JSON to XML Conversion *********************** */ @@ -726,105 +720,102 @@ function createAssetResponse(instanceId, assetItem) { */ // TODO !!! remove response write from here -function jsonToXML(data, res) { - res.writeHead(200, { 'Content-Type': 'text/plain', Trailer: 'Content-MD5' }); - const source = new stream.Readable(); - source._read = function noop() {}; // redundant? see update below - source.push(data); - source.push(null); +function jsonToXML (data, res) { + res.writeHead(200, { 'Content-Type': 'text/plain', Trailer: 'Content-MD5' }) + const source = new stream.Readable() + source._read = function noop () {} // redundant? see update below + source.push(data) + source.push(null) const convert = converter({ from: 'json', - to: 'xml', - }); + to: 'xml' + }) - let buffer = ''; - const cleaner = through(function write(chunk) { - const result = chunk.toString().replace(/<[/][0-9]>[\n]|<[0-9]>[\n]/g, '\r'); + let buffer = '' + const cleaner = through(function write (chunk) { + const result = chunk.toString().replace(/<[/][0-9]>[\n]|<[0-9]>[\n]/g, '\r') // TODO: remove blank lines - buffer += result; - this.queue(result); - }); - source.pipe(convert).pipe(cleaner).pipe(res); - res.addTrailers({ 'Content-MD5': `${md5(buffer)}` }); + buffer += result + this.queue(result) + }) + source.pipe(convert).pipe(cleaner).pipe(res) + res.addTrailers({ 'Content-MD5': `${md5(buffer)}` }) // res.end(); } - -function jsonToXMLStream(source, boundary, res, isError) { - const s = new stream.Readable(); - const w = new stream.Writable({ decodeStrings: false }); - let convert = {}; - let options = {}; - let xmlString = ''; +function jsonToXMLStream (source, boundary, res, isError) { + const s = new stream.Readable() + const w = new stream.Writable({ decodeStrings: false }) + let convert = {} + let options = {} + let xmlString = '' // converting json string to stream - s._read = function noop() { - this.push(source); - this.push(null); - }; + s._read = function noop () { + this.push(source) + this.push(null) + } // writing stream to browser w._write = (chunk) => { - xmlString = chunk.toString(); - const resStr = xmlString.replace(/<[/][0-9]>[\n]|<[0-9]>[\n]/g, '\r'); + xmlString = chunk.toString() + const resStr = xmlString.replace(/<[/][0-9]>[\n]|<[0-9]>[\n]/g, '\r') // TODO: remove blank lines - const contentLength = resStr.length; - res.write(`\r\n--${boundary}\r\n`); - res.write(`Content-type: text/xml\r\n`); - res.write(`Content-length: ${contentLength}`); - res.write(`${resStr}\r\n`); + const contentLength = resStr.length + res.write(`\r\n--${boundary}\r\n`) + res.write(`Content-type: text/xml\r\n`) + res.write(`Content-length: ${contentLength}`) + res.write(`${resStr}\r\n`) if (isError) { - res.write(`\r\n--${boundary}--\r\n`); - res.end(); // ends the connection - return; + res.write(`\r\n--${boundary}--\r\n`) + res.end() // ends the connection } - }; + } options = { from: 'json', - to: 'xml', - }; - convert = converter(options); - s.pipe(convert).pipe(w); + to: 'xml' + } + convert = converter(options) + s.pipe(convert).pipe(w) } /* *****************************JSON CONCATENATION *************************/ -function concatenateDeviceStreams(jsonArr) { - const newJSON = jsonArr[jsonArr.length - 1]; +function concatenateDeviceStreams (jsonArr) { + const newJSON = jsonArr[jsonArr.length - 1] if (jsonArr.length > 1) { - const deviceObj = newJSON.MTConnectStreams.Streams[0].DeviceStream; + const deviceObj = newJSON.MTConnectStreams.Streams[0].DeviceStream for (let i = 0; i < jsonArr.length - 1; i++) { - deviceObj.push(jsonArr[i].MTConnectStreams.Streams[0].DeviceStream[0]); + deviceObj.push(jsonArr[i].MTConnectStreams.Streams[0].DeviceStream[0]) } - return newJSON; + return newJSON } - return newJSON; + return newJSON } - -function concatenateAssetswithIds(assetData) { - const newJSON = assetData[0]; +function concatenateAssetswithIds (assetData) { + const newJSON = assetData[0] if (assetData.length > 1) { - const deviceObj = newJSON.MTConnectAssets.Assets[0]; + const deviceObj = newJSON.MTConnectAssets.Assets[0] for (let i = 1; i < assetData.length; i++) { - deviceObj.CuttingTool.push(assetData[i].MTConnectAssets.Assets[0].CuttingTool[0]); + deviceObj.CuttingTool.push(assetData[i].MTConnectAssets.Assets[0].CuttingTool[0]) } - return newJSON; + return newJSON } - return newJSON; + return newJSON } -function concatenateDevices(jsonArr) { - const newJSON = jsonArr[jsonArr.length - 1]; +function concatenateDevices (jsonArr) { + const newJSON = jsonArr[jsonArr.length - 1] if (jsonArr.length > 1) { - const deviceObj = newJSON.MTConnectDevices.Devices[0].Device; + const deviceObj = newJSON.MTConnectDevices.Devices[0].Device for (let i = 0; i < jsonArr.length - 1; i++) { - deviceObj.push(jsonArr[i].MTConnectDevices.Devices[0].Device[0]); + deviceObj.push(jsonArr[i].MTConnectDevices.Devices[0].Device[0]) } - return newJSON; + return newJSON } - return newJSON; + return newJSON } // Exports @@ -839,5 +830,5 @@ module.exports = { concatenateAssetswithIds, createAssetResponse, createErrorResponse, - findDataItemForSample, -}; + findDataItemForSample +} diff --git a/src/lokijs.js b/src/lokijs.js index 3929665..8e1eff4 100644 --- a/src/lokijs.js +++ b/src/lokijs.js @@ -18,42 +18,41 @@ // Imports - External -const Loki = require('lokijs'); -const R = require('ramda'); -const moment = require('moment'); -const sha1 = require('sha1'); +const Loki = require('lokijs') +const R = require('ramda') +const moment = require('moment') +const sha1 = require('sha1') // Imports - Internal -const config = require('./config/config'); -const dataStorage = require('./dataStorage'); -const xmlToJSON = require('./xmlToJSON'); -const dataItemjs = require('./dataItem.js'); +const config = require('./config/config') +const dataStorage = require('./dataStorage') +const xmlToJSON = require('./xmlToJSON') +const dataItemjs = require('./dataItem.js') -const log = require('./config/logger'); +const log = require('./config/logger') // Instances -const Db = new Loki('loki.json'); +const Db = new Loki('loki.json') // Constants - datacollection pointers -const rawData = Db.addCollection('rawData'); -const mtcDevices = Db.addCollection('DeviceDefinition'); -const assetCollection = []; - +const rawData = Db.addCollection('rawData') +const mtcDevices = Db.addCollection('DeviceDefinition') +const assetCollection = [] // const mRealTime = config.getConfiguredVal('mRealTime'); // const FilterDuplicates = config.getConfiguredVal('FilterDuplicates'); // const AutoAvailable = config.getConfiguredVal('AutoAvailable'); // variables -let mBaseTime = 0; -let mBaseOffset = 0; -let sequenceId = 1; // sequenceId starts from 1. -let dataItemsArr = []; -let d = 0; -let isFirst = 1; +let mBaseTime = 0 +let mBaseOffset = 0 +let sequenceId = 1 // sequenceId starts from 1. +let dataItemsArr = [] +let d = 0 +// let isFirst = 1 /* ******************** handle to lokijs database ******************** */ /** @@ -62,91 +61,88 @@ let isFirst = 1; * * @param = null */ -function getSchemaDB() { - return mtcDevices; +function getSchemaDB () { + return mtcDevices } - /** * getRawDataDB() returns the SHDR collection * ptr in lokijs database * * @param = null */ -function getRawDataDB() { - return rawData; +function getRawDataDB () { + return rawData } /* ********************** support functions *************************** */ -function insertRawData(obj) { // TODO in future we should support moving window +function insertRawData (obj) { // TODO in future we should support moving window if (rawData.maxId >= 1000) { - rawData.clear(); - rawData.insert(obj); + rawData.clear() + rawData.insert(obj) } else { - rawData.insert(obj); + rawData.insert(obj) } - return; } // check if the Id already exist -function checkDuplicateId(id) { - const hC = dataStorage.hashCurrent; - return hC.has(id); +function checkDuplicateId (id) { + const hC = dataStorage.hashCurrent + return hC.has(id) } - -function getDeviceName(uuid) { - const schemaDB = getSchemaDB(); - const schemaList = R.values(schemaDB.data); - let deviceName; +function getDeviceName (uuid) { + const schemaDB = getSchemaDB() + const schemaList = R.values(schemaDB.data) + let deviceName R.find((k) => { if (k.uuid === uuid) { - deviceName = k.name; + deviceName = k.name } - return deviceName; // eslint - }, schemaList); - return deviceName; + return deviceName // eslint + }, schemaList) + return deviceName } -function getTime(adTime, device) { - const IgnoreTimestamps = config.getConfiguredVal(device, 'IgnoreTimestamps'); - const RelativeTime = config.getConfiguredVal(device, 'RelativeTime'); - let result; +function getTime (adTime, device) { + const IgnoreTimestamps = config.getConfiguredVal(device, 'IgnoreTimestamps') + const RelativeTime = config.getConfiguredVal(device, 'RelativeTime') + let result, offset + let mParseTime = true if (RelativeTime) { if (mBaseTime === 0) { - mBaseTime = moment().valueOf(); + mBaseTime = moment().valueOf() if (adTime.includes('T')) { - mParseTime = true; - mBaseOffset = moment(adTime).valueOf(); // unix value of received time + mParseTime = true + mBaseOffset = moment(adTime).valueOf() // unix value of received time } else { - mBaseOffset = Number(adTime); + mBaseOffset = Number(adTime) } - offset = 0; - } else if(mParseTime) { - offset = moment(adTime).valueOf() - mBaseOffset; + offset = 0 + } else if (mParseTime) { + offset = moment(adTime).valueOf() - mBaseOffset } else { - offset = Number(adTime) - mBaseOffset; + offset = Number(adTime) - mBaseOffset } - result = mBaseTime + offset; // unix time_utc - result = moment(result).toISOString(); + result = mBaseTime + offset // unix time_utc + result = moment(result).toISOString() } else if (IgnoreTimestamps || (adTime === '')) { // current time - result = moment().toISOString(); + result = moment().toISOString() } else { // time from adapter - result = adTime; + result = adTime } - return result; + return result } - -function getSequenceId() { - const MAX_VAL = Number.MAX_SAFE_INTEGER; // 9007199254740991 +function getSequenceId () { + const MAX_VAL = Number.MAX_SAFE_INTEGER // 9007199254740991 if (sequenceId < MAX_VAL) { - sequenceId = sequenceId + 1; - } else if (sequenceId === MAX_VAL){ - sequenceId = 0; + sequenceId = sequenceId + 1 + } else if (sequenceId === MAX_VAL) { + sequenceId = 0 } - return sequenceId; + return sequenceId } /** @@ -158,76 +154,75 @@ function getSequenceId() { * @param = {String} uuid: UUID from deviceSchema */ -function initiateCircularBuffer(dataItem,timeVal, uuid) { - const time = moment().toISOString(); - const device = getDeviceName(uuid); - let dupCheck = 0; - let dupId = 0; +function initiateCircularBuffer (dataItem, timeVal, uuid) { + const time = moment().toISOString() + const device = getDeviceName(uuid) + let dupCheck = 0 + let dupId = 0 R.map((k) => { - const dataItemName = k.$.name; - const id = k.$.id; - const type = k.$.type; - const path = k.path; - const constraint = k.Constraints; + const dataItemName = k.$.name + const id = k.$.id + const type = k.$.type + const path = k.path + const constraint = k.Constraints const seqVal = getSequenceId() - const obj = { sequenceId: seqVal, id, uuid, time, path }; + const obj = { sequenceId: seqVal, id, uuid, time, path } if (dataItemName !== undefined) { - obj.dataItemName = dataItemName; + obj.dataItemName = dataItemName } if (constraint !== undefined) { - obj.value = constraint[0].Value[0]; - } else if (type === 'AVAILABILITY' && config.getConfiguredVal(device, 'AutoAvailable' )) { - log.debug('Setting all Availability dataItems to AVAILABLE'); - obj.value = 'AVAILABLE'; + obj.value = constraint[0].Value[0] + } else if (type === 'AVAILABILITY' && config.getConfiguredVal(device, 'AutoAvailable')) { + log.debug('Setting all Availability dataItems to AVAILABLE') + obj.value = 'AVAILABLE' } else { - obj.value = 'UNAVAILABLE'; + obj.value = 'UNAVAILABLE' } // check dupId only if duplicateCheck is required if (config.getConfiguredVal(device, 'FilterDuplicates')) { - dupId = checkDuplicateId(id); + dupId = checkDuplicateId(id) } if (!dupId) { - insertRawData(obj); - const obj1 = R.clone(obj); - const obj2 = R.clone(obj); - dataStorage.hashCurrent.set(id, obj1); - dataStorage.hashLast.set(id, obj2); + insertRawData(obj) + const obj1 = R.clone(obj) + const obj2 = R.clone(obj) + dataStorage.hashCurrent.set(id, obj1) + dataStorage.hashLast.set(id, obj2) } else { - log.error(`Duplicate DataItem id ${id} for device ${getDeviceName(uuid)} and dataItem name ${dataItemName} `); - dupCheck = 1; + log.error(`Duplicate DataItem id ${id} for device ${getDeviceName(uuid)} and dataItem name ${dataItemName} `) + dupCheck = 1 } - return 0; // to make eslint happy - }, dataItem); - return dupCheck; + return 0 // to make eslint happy + }, dataItem) + return dupCheck } - /** * dataItemsParse() creates a dataItem array containing all dataItem from the schema * * @param {Object} container * */ -function dataItemsParse(dataItems, path) { +function dataItemsParse (dataItems, path) { for (let i = 0; i < dataItems.length; i++) { - const dataItem = dataItems[i].DataItem; + const dataItem = dataItems[i].DataItem for (let j = 0; j < dataItem.length; j++) { if (dataItem[j] !== undefined) { - let path3 = `${path}//DataItem`; + let path3 = `${path}//DataItem` if (dataItem[j].$.type) { - const typeVal = dataItem[j].$.type; + const typeVal = dataItem[j].$.type if (dataItem[j].$.subType) { - const subTypeVal = dataItem[j].$.subType; - path3 = `${path3}[@type=\"${typeVal}\" and @subType=\"${subTypeVal}\"]`; + const subTypeVal = dataItem[j].$.subType + path3 = `${path3}[@type="${typeVal}" and @subType="${subTypeVal}"]` } else { - path3 = `${path3}[@type=\"${typeVal}\"]`; + path3 = `${path3}[@type="${typeVal}"]` } } - const dataItemObj = R.clone(dataItem[j]); - dataItemObj.path = path3; - dataItemsArr[d++] = dataItemObj; + const dataItemObj = R.clone(dataItem[j]) + dataItemObj.path = path3 + dataItemsArr[d++] = dataItemObj } } } @@ -240,27 +235,26 @@ function dataItemsParse(dataItems, path) { * @param {Object} container * */ -function levelSixParse(container, path) { +function levelSixParse (container, path) { for (let i = 0; i < container.length; i++) { - const keys = R.keys(container[i]); + const keys = R.keys(container[i]) // k = element of array keys R.find((k) => { // pluck the properties of all objects corresponding to k if ((R.pluck(k)([container[i]])) !== undefined) { - const pluckedData = (R.pluck(k)([container[i]]))[0]; // result will be an array + const pluckedData = (R.pluck(k)([container[i]]))[0] // result will be an array for (let j = 0; j < pluckedData.length; j++) { - const path1 = `${path}//${k}`; - const dataItems = pluckedData[j].DataItems; - dataItemsParse(dataItems, path1); + const path1 = `${path}//${k}` + const dataItems = pluckedData[j].DataItems + dataItemsParse(dataItems, path1) } } - return 0; // to make eslint happy - }, keys); + return 0 // to make eslint happy + }, keys) } } - /** * levelFiveParse() separates Components and DataItems in level five * and call parsing in next level. @@ -268,13 +262,13 @@ function levelSixParse(container, path) { * @param {Object} container * */ -function levelFiveParse(container, path) { +function levelFiveParse (container, path) { for (let i = 0; i < container.length; i++) { if (container[i].Components !== undefined) { - levelSixParse(container[i].Components, path); + levelSixParse(container[i].Components, path) } if (container[i].DataItems !== undefined) { - dataItemsParse(container[i].DataItems, path); + dataItemsParse(container[i].DataItems, path) } } } @@ -289,16 +283,15 @@ function levelFiveParse(container, path) { * * returns the latest device schema entry for that uuid */ -function searchDeviceSchema(uuid) { - const deviceSchemaPtr = getSchemaDB(); +function searchDeviceSchema (uuid) { + const deviceSchemaPtr = getSchemaDB() const latestSchema = deviceSchemaPtr.chain() .find({ uuid }) .simplesort('time') - .data(); - return latestSchema; + .data() + return latestSchema } - /** * getDataItem() get all the dataItem(s) from the deviceSchema * @@ -306,143 +299,143 @@ function searchDeviceSchema(uuid) { * * return {Array} dataItemsArr */ -function getDataItem(uuid) { - dataItemsArr = []; - let path = ''; - d = 0; - const findUuid = searchDeviceSchema(uuid); +function getDataItem (uuid) { + dataItemsArr = [] + let path = '' + d = 0 + const findUuid = searchDeviceSchema(uuid) if (findUuid.length === 0) { - return null; + return null } - const device = findUuid[findUuid.length - 1].device; - const deviceName = device.$.name; + const device = findUuid[findUuid.length - 1].device + const deviceName = device.$.name if (!R.isEmpty(device)) { - path = `//Devices//Device[@name=\"${deviceName}\"]`; + path = `//Devices//Device[@name="${deviceName}"]` } - const dataItems = device.DataItems; - const components = device.Components; + const dataItems = device.DataItems + const components = device.Components if (dataItems !== undefined) { - dataItemsParse(dataItems, path); + dataItemsParse(dataItems, path) } if (components !== undefined) { for (let i = 0; i < components.length; i++) { if (components[i].Axes !== undefined) { - const path1 = `${path}//Axes`; - levelFiveParse(components[i].Axes, path1); + const path1 = `${path}//Axes` + levelFiveParse(components[i].Axes, path1) } if (components[i].Controller !== undefined) { - const path2 = `${path}//Controller`; - levelFiveParse(components[i].Controller, path2); + const path2 = `${path}//Controller` + levelFiveParse(components[i].Controller, path2) } if (components[i].Systems !== undefined) { - const path3 = `${path}//Systems`; - levelFiveParse(components[i].Systems, path3); + const path3 = `${path}//Systems` + levelFiveParse(components[i].Systems, path3) } } } - return dataItemsArr; + return dataItemsArr } - -function getDataItemForId(id, uuid) { - const dataItemsArr = getDataItem(uuid); - let dataItem = null; +function getDataItemForId (id, uuid) { + const dataItemsArr = getDataItem(uuid) + let dataItem = null R.find((k) => { - if(k.$.id === id) { - dataItem = k; + if (k.$.id === id) { + dataItem = k } - }, dataItemsArr); - return dataItem; + }, dataItemsArr) + return dataItem } -function addEvents(uuid, availId, assetChangedId, assetRemovedId) { - const findUuid = searchDeviceSchema(uuid); - const device = findUuid[findUuid.length - 1].device; - const deviceId = device.$.id; - const dataItems = device.DataItems; - const dataItem = dataItems[dataItems.length - 1].DataItem; +function addEvents (uuid, availId, assetChangedId, assetRemovedId) { + const findUuid = searchDeviceSchema(uuid) + const device = findUuid[findUuid.length - 1].device + const deviceId = device.$.id + const dataItems = device.DataItems + const dataItem = dataItems[dataItems.length - 1].DataItem if (!availId) { // Availability event is not present for the device - const obj = { $: { category: 'EVENT', id: `${deviceId}_avail`, type: 'AVAILABILITY' } }; - dataItem.push(obj); - config.setConfiguration(device, 'AutoAvailable', true); + const obj = { $: { category: 'EVENT', id: `${deviceId}_avail`, type: 'AVAILABILITY' } } + dataItem.push(obj) + config.setConfiguration(device, 'AutoAvailable', true) } if (!assetChangedId) { - const obj = { $: { category: 'EVENT', id: `${deviceId}_asset_chg`, type: 'ASSET_CHANGED' } }; - dataItem.push(obj); + const obj = { $: { category: 'EVENT', id: `${deviceId}_asset_chg`, type: 'ASSET_CHANGED' } } + dataItem.push(obj) } if (!assetRemovedId) { - const obj = { $: { category: 'EVENT', id: `${deviceId}_asset_rem`, type: 'ASSET_REMOVED' } }; - dataItem.push(obj); + const obj = { $: { category: 'EVENT', id: `${deviceId}_asset_rem`, type: 'ASSET_REMOVED' } } + dataItem.push(obj) } } - // TODO: call function to check AVAILABILITY, // if present change all AVAILABILITY event value to AVAILABLE. // Check AVAILABILTY, ASSET_CHANGED, ASSET_REMOVED events -function checkForEvents(uuid) { - const dataItemSet = getDataItem(uuid); - const device = getDeviceName(uuid); - let assetChangedId; - let assetRemovedId; - let availId; +function checkForEvents (uuid) { + const dataItemSet = getDataItem(uuid) + const device = getDeviceName(uuid) + let assetChangedId + let assetRemovedId + let availId if (!R.isEmpty(dataItemSet) || (dataItemSet !== null)) { R.map((k) => { - const type = k.$.type; + const type = k.$.type if (type === 'AVAILABILITY') { - availId = k.$.id; + availId = k.$.id } else if (type === 'ASSET_CHANGED') { - assetChangedId = k.$.id; + assetChangedId = k.$.id } else if (type === 'ASSET_REMOVED') { - assetRemovedId = k.$.id; + assetRemovedId = k.$.id } - return type; // eslint - }, dataItemSet); + return type // eslint + }, dataItemSet) - addEvents(uuid, availId, assetChangedId, assetRemovedId); + addEvents(uuid, availId, assetChangedId, assetRemovedId) } } - /** * read objects from json and insert into collection * @param {Object} parsedData (JSONObj) * */ -function insertSchemaToDB(parsedData, sha) { - let dupCheck = 0; - const parsedDevice = parsedData.MTConnectDevices; - const devices = parsedDevice.Devices; - const xmlns = parsedDevice.$; - const timeVal = parsedDevice.Header[0].$.creationTime; - const numberOfDevices = devices.length; - - const uuid = []; - const device = []; - const name = []; +function insertSchemaToDB (parsedData, sha) { + let dupCheck = 0 + const parsedDevice = parsedData.MTConnectDevices + const devices = parsedDevice.Devices + const xmlns = parsedDevice.$ + const timeVal = parsedDevice.Header[0].$.creationTime + const numberOfDevices = devices.length + + const uuid = [] + const device = [] + const name = [] for (let i = 0; i < numberOfDevices; i++) { - const devices0 = devices[i]; - const numberOfDevice = devices0.Device.length; + const devices0 = devices[i] + const numberOfDevice = devices0.Device.length for (let j = 0; j < numberOfDevice; j++) { - device[j] = devices0.Device[j]; - name[j] = device[j].$.name; - uuid[j] = device[j].$.uuid; - mtcDevices.insert({ xmlns, time: timeVal, name: name[j], - uuid: uuid[j], device: device[j], sha }); - checkForEvents(uuid[j]); - const dataItemArray = getDataItem(uuid[j]); - dupCheck = initiateCircularBuffer(dataItemArray, timeVal, uuid[j]); + device[j] = devices0.Device[j] + name[j] = device[j].$.name + uuid[j] = device[j].$.uuid + mtcDevices.insert({ xmlns, + time: timeVal, + name: name[j], + uuid: uuid[j], + device: device[j], + sha }) + checkForEvents(uuid[j]) + const dataItemArray = getDataItem(uuid[j]) + dupCheck = initiateCircularBuffer(dataItemArray, timeVal, uuid[j]) } } - return dupCheck; + return dupCheck } - /** * compareSchema() checks for duplicate entry * @param {object} foundFromDc - existing device schema @@ -450,21 +443,21 @@ function insertSchemaToDB(parsedData, sha) { * @param {object} newObj - received schema in JSON * returns true if the existing schema is same as the new schema */ -function compareSchema(foundFromDc, newObj) { - const dcHeader = foundFromDc[0].xmlns; - const dcTime = foundFromDc[0].time; - const dcDevice = foundFromDc[0].device; - const newHeader = newObj.MTConnectDevices.$; - const newTime = newObj.MTConnectDevices.Header[0].$.creationTime; - const newDevice = newObj.MTConnectDevices.Devices[0].Device[0]; +function compareSchema (foundFromDc, newObj) { + const dcHeader = foundFromDc[0].xmlns + const dcTime = foundFromDc[0].time + const dcDevice = foundFromDc[0].device + const newHeader = newObj.MTConnectDevices.$ + const newTime = newObj.MTConnectDevices.Header[0].$.creationTime + const newDevice = newObj.MTConnectDevices.Devices[0].Device[0] if (R.equals(dcHeader, newHeader)) { if (R.equals(dcTime, newTime)) { if (R.equals(dcDevice, newDevice)) { - return true; - } return false; - } return false; - } return false; + return true + } return false + } return false + } return false } /** @@ -473,49 +466,47 @@ function compareSchema(foundFromDc, newObj) { * @param {object} schemaReceived - XML from http.get * returns the lokijs DB ptr */ -function updateSchemaCollection(schemaReceived) { // TODO check duplicate first. - const xmlSha = sha1(schemaReceived); - const jsonObj = xmlToJSON.xmlToJSON(schemaReceived); - let dupCheck = 0; +function updateSchemaCollection (schemaReceived) { // TODO check duplicate first. + const xmlSha = sha1(schemaReceived) + const jsonObj = xmlToJSON.xmlToJSON(schemaReceived) + let dupCheck = 0 if (jsonObj !== undefined) { - const uuid = jsonObj.MTConnectDevices.Devices[0].Device[0].$.uuid; - const xmlSchema = getSchemaDB(); + const uuid = jsonObj.MTConnectDevices.Devices[0].Device[0].$.uuid + const xmlSchema = getSchemaDB() const checkUuid = xmlSchema.chain() .find({ uuid }) - .data(); + .data() if (!checkUuid.length) { - log.debug('Adding a new device schema'); - dupCheck = insertSchemaToDB(jsonObj, xmlSha); + log.debug('Adding a new device schema') + dupCheck = insertSchemaToDB(jsonObj, xmlSha) } else if (xmlSha === checkUuid[0].sha) { - log.debug('This device schema already exist'); + log.debug('This device schema already exist') } else { - log.debug('Adding updated device schema'); - dupCheck = insertSchemaToDB(jsonObj, xmlSha); + log.debug('Adding updated device schema') + dupCheck = insertSchemaToDB(jsonObj, xmlSha) } } else { - log.debug('xml parsing failed'); + log.debug('xml parsing failed') } - return dupCheck; + return dupCheck } - // ******************** Raw Data Collection ******************* // -function getPath(uuid, dataItemName) { - const dataItemArray = getDataItem(uuid); - let path; +function getPath (uuid, dataItemName) { + const dataItemArray = getDataItem(uuid) + let path if (dataItemArray !== null) { R.find((k) => { if ((k.$.name === dataItemName) || (k.$.id === dataItemName)) { - path = k.path; + path = k.path } - return path; // eslint - }, dataItemArray); + return path // eslint + }, dataItemArray) } - return path; + return path } - /** * getId() get the Id for the dataitem from the deviceSchema * @@ -524,23 +515,22 @@ function getPath(uuid, dataItemName) { * * return id (Eg:'dtop_2') */ -function getId(uuid, dataItemName) { - let id = undefined; - const dataItemArray = getDataItem(uuid); +function getId (uuid, dataItemName) { + let id + const dataItemArray = getDataItem(uuid) if (dataItemArray !== null) { R.find((k) => { if (k.$.name === dataItemName) { - id = k.$.id; + id = k.$.id } - return (id !== undefined); - }, dataItemArray); + return (id !== undefined) + }, dataItemArray) } else { - log.debug('error in getId'); + log.debug('error in getId') } - return id; + return id } - /** * searchId() get the Id for the dataitem from the deviceSchema * @@ -549,20 +539,20 @@ function getId(uuid, dataItemName) { * * return id (Eg:'dtop_2') */ -function searchId(uuid, dataItemName) { - let id; - const dataItemArray = getDataItem(uuid); +function searchId (uuid, dataItemName) { + let id + const dataItemArray = getDataItem(uuid) if (dataItemArray !== null) { R.find((k) => { if (k.$.id === dataItemName) { - id = k.$.id; + id = k.$.id } - return (id !== undefined); - }, dataItemArray); + return (id !== undefined) + }, dataItemArray) } else { - log.debug('Error in searchId'); + log.debug('Error in searchId') } - return id; + return id } /** @@ -574,94 +564,92 @@ function searchId(uuid, dataItemName) { * dataItemName:'avail', value: 'AVAILABLE' } */ rawData.on('insert', (obj) => { - const id = obj.id; - const obj1 = R.clone(obj); - const obj2 = R.clone(obj); - dataStorage.updateCircularBuffer(obj1); - dataStorage.hashCurrent.set(id, obj2); // updating hashCurrent -}); - + const id = obj.id + const obj1 = R.clone(obj) + const obj2 = R.clone(obj) + dataStorage.updateCircularBuffer(obj1) + dataStorage.hashCurrent.set(id, obj2) // updating hashCurrent +}) /* ****************************************Asset********************************* */ -function updateAssetChg(assetId, uuid, time) { - const device = getDeviceName(uuid); - const latestSchema = (searchDeviceSchema(uuid))[0]; - const deviceId = latestSchema.device.$.id; - const id = `${deviceId}_asset_chg`; - const dataItem = dataStorage.hashCurrent.get(id); +function updateAssetChg (assetId, uuid, time) { + const device = getDeviceName(uuid) + const latestSchema = (searchDeviceSchema(uuid))[0] + const deviceId = latestSchema.device.$.id + const id = `${deviceId}_asset_chg` + const dataItem = dataStorage.hashCurrent.get(id) if (dataItem === undefined) { - return log.debug('ASSET_CHANGED Event not present'); + return log.debug('ASSET_CHANGED Event not present') } if (dataItem.value === assetId) { // duplicate check - return log.debug('Duplicate Entry'); + return log.debug('Duplicate Entry') } - dataItem.sequenceId = sequenceId++; - dataItem.time = getTime(time, device); - dataItem.value = assetId; - const dataItemClone = R.clone(dataItem); - dataStorage.circularBuffer.push(dataItemClone); - return dataItem; // eslint + dataItem.sequenceId = sequenceId++ + dataItem.time = getTime(time, device) + dataItem.value = assetId + const dataItemClone = R.clone(dataItem) + dataStorage.circularBuffer.push(dataItemClone) + return dataItem // eslint } - -function updateAssetRem(assetId, uuid, time) { - const device = getDeviceName(uuid); - const latestSchema = (searchDeviceSchema(uuid))[0]; - const deviceId = latestSchema.device.$.id; - const id = `${deviceId}_asset_rem`; - const dataItem = dataStorage.hashCurrent.get(id); +function updateAssetRem (assetId, uuid, time) { + const device = getDeviceName(uuid) + const latestSchema = (searchDeviceSchema(uuid))[0] + const deviceId = latestSchema.device.$.id + const id = `${deviceId}_asset_rem` + const dataItem = dataStorage.hashCurrent.get(id) if (dataItem === undefined) { - return log.debug('ASSET_REMOVED Event not present'); + return log.debug('ASSET_REMOVED Event not present') } - const assetChgId = `${deviceId}_asset_chg`; - const assetChg = dataStorage.hashCurrent.get(assetChgId); + const assetChgId = `${deviceId}_asset_chg` + const assetChg = dataStorage.hashCurrent.get(assetChgId) if (assetChg.value === assetId) { - updateAssetChg('UNAVAILABLE', uuid, time); + updateAssetChg('UNAVAILABLE', uuid, time) } if (dataItem.value === assetId) { // duplicate check - return log.debug('Duplicate Entry'); + return log.debug('Duplicate Entry') } - dataItem.sequenceId = sequenceId++; - dataItem.time = getTime(time, device); - dataItem.value = assetId; - const dataItemClone = R.clone(dataItem); - dataStorage.circularBuffer.push(dataItemClone); - return dataItem; // eslint + dataItem.sequenceId = sequenceId++ + dataItem.time = getTime(time, device) + dataItem.value = assetId + const dataItemClone = R.clone(dataItem) + dataStorage.circularBuffer.push(dataItemClone) + return dataItem // eslint } -function removeAsset(shdrarg, uuid) { +function removeAsset (shdrarg, uuid) { const device = getDeviceName(uuid) - const time = shdrarg.time; - const assetItem = shdrarg.dataitem[0]; - const assetId = assetItem.value; - const assetPresent = dataStorage.hashAssetCurrent.get(assetId); + const time = shdrarg.time + const assetItem = shdrarg.dataitem[0] + const assetId = assetItem.value + const assetPresent = dataStorage.hashAssetCurrent.get(assetId) if (assetPresent === undefined) { - return log.debug('Error: Asset not Present'); + return log.debug('Error: Asset not Present') } - const assetToRemove = R.clone(assetPresent); - assetToRemove.removed = true; - assetToRemove.time = getTime(time, device); - dataStorage.hashAssetCurrent.set(assetId, assetToRemove); - updateAssetRem(assetId, uuid, time); - return assetToRemove; + const assetToRemove = R.clone(assetPresent) + assetToRemove.removed = true + assetToRemove.time = getTime(time, device) + dataStorage.hashAssetCurrent.set(assetId, assetToRemove) + updateAssetRem(assetId, uuid, time) + return assetToRemove } -function findKey(asset, object, key) { +function findKey (asset, object, key) { if (object.hasOwnProperty(key)) { - return asset; + return asset } - const keys = Object.keys(object); + const keys = Object.keys(object) for (let i = 0; i < keys.length; i++) { if (typeof object[keys[i]] === 'object') { - const o = findKey(asset[keys[i]], object[Object.keys(object)[i]], key); + const o = findKey(asset[keys[i]], object[Object.keys(object)[i]], key) if (o != null) { - return o; + return o } } } - return undefined; + return undefined } /** @@ -670,110 +658,108 @@ function findKey(asset, object, key) { * * */ -function updateAsset(assetToUpdate, dataItemSet) { - let key; - let value; - let foundKey; - const dataItem = []; +function updateAsset (assetToUpdate, dataItemSet) { + let key + let value + let foundKey + const dataItem = [] if (dataItemSet.length === 1) { // xml format - const jsonAsset = xmlToJSON.xmlToJSON(dataItemSet); - key = (R.keys(jsonAsset))[0]; - value = R.pluck(key)([jsonAsset])[0]; - foundKey = findKey(assetToUpdate.value, assetToUpdate.value, key); - foundKey[key][0] = value; + const jsonAsset = xmlToJSON.xmlToJSON(dataItemSet) + key = (R.keys(jsonAsset))[0] + value = R.pluck(key)([jsonAsset])[0] + foundKey = findKey(assetToUpdate.value, assetToUpdate.value, key) + foundKey[key][0] = value } else { // key value pair - const totalDataItem = (dataItemSet.length) / 2; + const totalDataItem = (dataItemSet.length) / 2 for (let i = 0, j = 0; i < totalDataItem; i++, j += 2) { // Eg: dataitem[i] = { name: (avail), value: (AVAILABLE) }; - let name = dataItemSet[j]; - let value = dataItemSet[j + 1] + let name = dataItemSet[j] + let value = dataItemSet[j + 1] if (name === 'CutterStatus') { - name = "Status" + name = 'Status' if (value.includes(',')) { // Eg: 'USED,AVAILABLE' - value = value.split(','); + value = value.split(',') } } - dataItem.push({ name, value }); + dataItem.push({ name, value }) } R.map((k) => { - key = k.name; - foundKey = findKey(assetToUpdate.value, assetToUpdate.value, key); + key = k.name + foundKey = findKey(assetToUpdate.value, assetToUpdate.value, key) if (foundKey.Status !== undefined) { // check status validity // const validValues = checkStatusValues(k.value); - foundKey.Status = k.value; + foundKey.Status = k.value } else { - foundKey[k.name][0]._ = k.value; + foundKey[k.name][0]._ = k.value } - return foundKey; // eslint - }, dataItem); + return foundKey // eslint + }, dataItem) } - return assetToUpdate; + return assetToUpdate } - -function updateAssetCollection(shdrarg, uuid) { // args: shdrarg, uuid - const device = getDeviceName(uuid); - const assetItem = shdrarg.dataitem[0]; - const time = shdrarg.time; - const assetId = assetItem.value[0]; +function updateAssetCollection (shdrarg, uuid) { // args: shdrarg, uuid + const device = getDeviceName(uuid) + const assetItem = shdrarg.dataitem[0] + const time = shdrarg.time + const assetId = assetItem.value[0] // Eg: Non xml assetDataItem : [ 'ToolLife', '120', 'CuttingDiameterMax', '40' ] /* Eg: xml assetDataItem : * [ '323.65' ] */ - const assetDataItem = assetItem.value.slice(1, Infinity); - const assetPresent = dataStorage.hashAssetCurrent.get(assetId); + const assetDataItem = assetItem.value.slice(1, Infinity) + const assetPresent = dataStorage.hashAssetCurrent.get(assetId) if (assetPresent === undefined) { - return log.debug('Error: Asset not Present'); + return log.debug('Error: Asset not Present') } - const assetToUpdate = R.clone(assetPresent); - const newVal = updateAsset(assetToUpdate, assetDataItem); - newVal.time = getTime(time, device);; - dataStorage.hashAssetCurrent.set(assetId, newVal); - dataStorage.assetBuffer.push(newVal); - return updateAssetChg(assetId, uuid, time); + const assetToUpdate = R.clone(assetPresent) + const newVal = updateAsset(assetToUpdate, assetDataItem) + newVal.time = getTime(time, device) + dataStorage.hashAssetCurrent.set(assetId, newVal) + dataStorage.assetBuffer.push(newVal) + return updateAssetChg(assetId, uuid, time) } -function createAssetCollection(assetId) { - let assetPresent = false; +function createAssetCollection (assetId) { + let assetPresent = false if (assetCollection.length === 0) { - assetCollection.push(assetId); - return; + assetCollection.push(assetId) + return } R.find((k) => { if (k === assetId) { - assetPresent = true; + assetPresent = true } - return assetPresent; - }, assetCollection); + return assetPresent + }, assetCollection) if (!assetPresent) { - assetCollection.push(assetId); + assetCollection.push(assetId) } - return; } -function addToAssetCollection(shdrarg, uuid) { - const device = getDeviceName(uuid); - const assetItem = shdrarg.dataitem[0]; - const time = shdrarg.time; - const assetId = assetItem.value[0]; - const assetType = assetItem.value[1]; - let assetValue = assetItem.value[2]; +function addToAssetCollection (shdrarg, uuid) { + const device = getDeviceName(uuid) + const assetItem = shdrarg.dataitem[0] + const time = shdrarg.time + const assetId = assetItem.value[0] + const assetType = assetItem.value[1] + let assetValue = assetItem.value[2] if (assetValue && assetValue.includes('--multiline--')) { - const start = assetValue.search('--multiline--'); - const end = assetValue.indexOf('\n', start); - const tag = assetValue.slice(start, end); - const stringEnd = assetValue.lastIndexOf(tag); - const valueString = assetValue.slice(end, stringEnd); - assetValue = valueString.replace('\n', ''); + const start = assetValue.search('--multiline--') + const end = assetValue.indexOf('\n', start) + const tag = assetValue.slice(start, end) + const stringEnd = assetValue.lastIndexOf(tag) + const valueString = assetValue.slice(end, stringEnd) + assetValue = valueString.replace('\n', '') } - const value = xmlToJSON.xmlToJSON(assetValue); + const value = xmlToJSON.xmlToJSON(assetValue) if (value === undefined) { - console.log(`addToAssetCollection: Error parsing asset ${assetId}`); - log.debug(`addToAssetCollection: Error parsing asset ${assetId}`); - return false; + console.log(`addToAssetCollection: Error parsing asset ${assetId}`) + log.debug(`addToAssetCollection: Error parsing asset ${assetId}`) + return false } - const target = getDeviceName(uuid); + const target = getDeviceName(uuid) const obj = { time, assetId, @@ -781,46 +767,45 @@ function addToAssetCollection(shdrarg, uuid) { target, assetType, removed: false, - value, - }; - obj.time = getTime(shdrarg.time, device); + value + } + obj.time = getTime(shdrarg.time, device) if (assetId !== undefined && assetType !== undefined && assetValue !== undefined) { - dataStorage.assetBuffer.push(obj); - const obj1 = R.clone(obj); - dataStorage.hashAssetCurrent.set(assetId, obj1); // if asset already present, it is rewritten. - updateAssetChg(assetId, uuid, time); - createAssetCollection(assetId); - return true; + dataStorage.assetBuffer.push(obj) + const obj1 = R.clone(obj) + dataStorage.hashAssetCurrent.set(assetId, obj1) // if asset already present, it is rewritten. + updateAssetChg(assetId, uuid, time) + createAssetCollection(assetId) + return true } log.debug(`Asset ${assetId} missing required type, id or body. Asset is rejected.`) - return false; + return false } - -function getAssetCollection() { - return assetCollection; +function getAssetCollection () { + return assetCollection } -function removeAllAssets(shdrarg, uuid) { - const device = getDeviceName(uuid); - const assets = getAssetCollection(); - const time = shdrarg.time; - const assetItem = shdrarg.dataitem[0]; - const assetType = assetItem.value; - const hashAssetCurrent = dataStorage.hashAssetCurrent; +function removeAllAssets (shdrarg, uuid) { + const device = getDeviceName(uuid) + const assets = getAssetCollection() + const time = shdrarg.time + const assetItem = shdrarg.dataitem[0] + const assetType = assetItem.value + const hashAssetCurrent = dataStorage.hashAssetCurrent R.map((k) => { - const assetData = hashAssetCurrent.get(k); + const assetData = hashAssetCurrent.get(k) if (assetData !== undefined) { if (assetData.assetType === assetType && assetData.removed !== true) { - const assetToRemove = R.clone(assetData); - assetToRemove.removed = true; - assetToRemove.time = getTime(time, device);; - dataStorage.hashAssetCurrent.set(k, assetToRemove); - return updateAssetRem(k, uuid, time); + const assetToRemove = R.clone(assetData) + assetToRemove.removed = true + assetToRemove.time = getTime(time, device) + dataStorage.hashAssetCurrent.set(k, assetToRemove) + return updateAssetRem(k, uuid, time) } } - return assetData; // eslint - }, assets); + return assetData // eslint + }, assets) } // TODO: include toUpperCase() depending on config param @@ -831,66 +816,66 @@ function removeAllAssets(shdrarg, uuid) { * @param {Object} shdrarg - with dataitem and time * */ -function dataCollectionUpdate(shdrarg, uuid) { - const dataitemno = shdrarg.dataitem.length; - const device = getDeviceName(uuid); - const ConversionRequired = config.getConfiguredVal(device, 'ConversionRequired'); - const UpcaseDataItemValue = config.getConfiguredVal(device, 'UpcaseDataItemValue'); - const FilterDuplicates = config.getConfiguredVal(device, 'FilterDuplicates'); - let rawValue; +function dataCollectionUpdate (shdrarg, uuid) { + const dataitemno = shdrarg.dataitem.length + const device = getDeviceName(uuid) + const ConversionRequired = config.getConfiguredVal(device, 'ConversionRequired') + const UpcaseDataItemValue = config.getConfiguredVal(device, 'UpcaseDataItemValue') + const FilterDuplicates = config.getConfiguredVal(device, 'FilterDuplicates') + let rawValue for (let i = 0; i < dataitemno; i++) { - const dataItemName = shdrarg.dataitem[i].name; + const dataItemName = shdrarg.dataitem[i].name // ASSSETS if (dataItemName === '@ASSET@') { - return addToAssetCollection(shdrarg, uuid); + return addToAssetCollection(shdrarg, uuid) } else if (dataItemName === '@UPDATE_ASSET@') { - return updateAssetCollection(shdrarg, uuid); + return updateAssetCollection(shdrarg, uuid) } else if (dataItemName === '@REMOVE_ASSET@') { - return removeAsset(shdrarg, uuid); + return removeAsset(shdrarg, uuid) } else if (dataItemName === '@REMOVE_ALL_ASSETS@') { - return removeAllAssets(shdrarg, uuid); + return removeAllAssets(shdrarg, uuid) } // DATAITEMS const obj = { sequenceId: undefined, - uuid}; - - obj.time = getTime(shdrarg.time, device); - let id = getId(uuid, dataItemName); - if (id !== undefined) { - obj.dataItemName = dataItemName; - } else { - id = searchId(uuid, dataItemName); - } - obj.id = id; - const path = getPath(uuid, dataItemName); - obj.path = path; - const dataItem = getDataItemForId(id, uuid); - const conversionRequired = dataItemjs.conversionRequired(id, dataItem); + uuid} + + obj.time = getTime(shdrarg.time, device) + let id = getId(uuid, dataItemName) + if (id !== undefined) { + obj.dataItemName = dataItemName + } else { + id = searchId(uuid, dataItemName) + } + obj.id = id + const path = getPath(uuid, dataItemName) + obj.path = path + const dataItem = getDataItemForId(id, uuid) + const conversionRequired = dataItemjs.conversionRequired(id, dataItem) // TimeSeries if (shdrarg.dataitem[i].isTimeSeries) { - let sampleCount; - let sampleRate; - const data = shdrarg.dataitem[i]; + let sampleCount + let sampleRate + const data = shdrarg.dataitem[i] if (data.value[0] === '') { - sampleCount = 0; + sampleCount = 0 } else { - sampleCount = data.value[0]; + sampleCount = data.value[0] } if (data.value[1] === '') { - sampleRate = 0; + sampleRate = 0 } else { - sampleRate = data.value[1]; + sampleRate = data.value[1] } - const value = data.value.slice(2, Infinity); - obj.sampleRate = sampleRate; - obj.sampleCount = sampleCount; + const value = data.value.slice(2, Infinity) + obj.sampleRate = sampleRate + obj.sampleCount = sampleCount if (ConversionRequired && conversionRequired) { - obj.value = [dataItemjs.convertTimeSeriesValue(value[0], dataItem)]; + obj.value = [dataItemjs.convertTimeSeriesValue(value[0], dataItem)] } else { - obj.value = value; + obj.value = value } } else { // allOthers - rawValue = shdrarg.dataitem[i].value; + rawValue = shdrarg.dataitem[i].value if (UpcaseDataItemValue) { if (!Array.isArray(rawValue)) { rawValue = rawValue.toUpperCase() @@ -900,63 +885,61 @@ function dataCollectionUpdate(shdrarg, uuid) { } if (ConversionRequired && conversionRequired) { - obj.value = dataItemjs.convertValue(rawValue, dataItem); + obj.value = dataItemjs.convertValue(rawValue, dataItem) } else { - obj.value = rawValue; + obj.value = rawValue } } if (!dataStorage.hashCurrent.has(id)) { // TODO: change duplicate Id check - log.debug(`Could not find dataItem ${id}`); + log.debug(`Could not find dataItem ${id}`) } else { if (FilterDuplicates) { - const dataItem = dataStorage.hashCurrent.get(id); - const previousValue = dataItem.value; + const dataItem = dataStorage.hashCurrent.get(id) + const previousValue = dataItem.value if (Array.isArray(previousValue) && (previousValue[0] === 'NORMAL') && (previousValue[0] === obj.value[0])) { - return log.debug('duplicate NORMAL Condition'); + return log.debug('duplicate NORMAL Condition') } else if ((previousValue === obj.value) && !Array.isArray(previousValue)) { - return log.debug('Duplicate entry'); // eslint + return log.debug('Duplicate entry') // eslint } } - obj.sequenceId = getSequenceId(); // sequenceId++; - insertRawData(obj); + obj.sequenceId = getSequenceId() // sequenceId++; + insertRawData(obj) } } - return log.debug('updatedDataCollection'); // eslint + return log.debug('updatedDataCollection') // eslint } - // To initiate the CB, hashCurrent and hashLast on disconnect -function updateBufferOnDisconnect(uuid) { - const dataItem = getDataItem(uuid); - const time = moment.utc().format(); - const hC = dataStorage.hashCurrent; +function updateBufferOnDisconnect (uuid) { + const dataItem = getDataItem(uuid) + const time = moment.utc().format() + const hC = dataStorage.hashCurrent R.map((k) => { - const id = k.$.id; - const hCData = hC.get(id); + const id = k.$.id + const hCData = hC.get(id) if (hCData.value !== 'UNAVAILABLE') { - const dataItemName = k.$.name; - const type = k.$.type; - const path = k.path; - const constraint = k.Constraints; - const obj = { sequenceId: sequenceId++, id, uuid, time, type, path }; + const dataItemName = k.$.name + const type = k.$.type + const path = k.path + const constraint = k.Constraints + const obj = { sequenceId: sequenceId++, id, uuid, time, type, path } if (dataItemName !== undefined) { - obj.dataItemName = dataItemName; + obj.dataItemName = dataItemName } if (constraint !== undefined) { - obj.value = constraint[0].Value[0]; + obj.value = constraint[0].Value[0] } else { - obj.value = 'UNAVAILABLE'; + obj.value = 'UNAVAILABLE' } // updates cb and hC - insertRawData(obj); + insertRawData(obj) } - return id; // eslint - }, dataItem); + return id // eslint + }, dataItem) } - /** * probeResponse() create json as a response to probe request * @@ -965,63 +948,67 @@ function updateBufferOnDisconnect(uuid) { * returns the JSON object with device detail. */ -function probeResponse(latestSchema) { - const newXMLns = latestSchema[0].xmlns; - const newTime = moment.utc().format(); - const dvcHeader = latestSchema[0].device.$; - const dvcDescription = latestSchema[0].device.Description; - const dataItems = latestSchema[0].device.DataItems; - const components = latestSchema[0].device.Components; - const instanceId = 0; - let dataItem; // TODO Update the value - - let newJSON = {}; +function probeResponse (latestSchema) { + const newXMLns = latestSchema[0].xmlns + const newTime = moment.utc().format() + const dvcHeader = latestSchema[0].device.$ + const dvcDescription = latestSchema[0].device.Description + const dataItems = latestSchema[0].device.DataItems + const components = latestSchema[0].device.Components + const instanceId = 0 + let dataItem // TODO Update the value + + let newJSON = {} const Device = [{ $: { name: dvcHeader.name, uuid: dvcHeader.uuid }, - Description: dvcDescription, - }]; + Description: dvcDescription + }] if (dataItems !== undefined) { for (let j = 0; j < dataItems.length; j++) { - dataItem = dataItems[j].DataItem; + dataItem = dataItems[j].DataItem } - Device[0].DataItems = [{ dataItem }]; + Device[0].DataItems = [{ dataItem }] } if (components !== undefined) { - Device[0].Components = components; + Device[0].Components = components } newJSON = { MTConnectDevices: { $: newXMLns, - Header: [{ $: - { creationTime: newTime, assetBufferSize: '1024', sender: 'localhost', assetCount: '0', - version: '1.3', instanceId, bufferSize: '524288' } }], - Devices: [{ Device }] } }; - - return newJSON; + Header: [{ $: + { creationTime: newTime, + assetBufferSize: '1024', + sender: 'localhost', + assetCount: '0', + version: '1.3', + instanceId, + bufferSize: '524288' } }], + Devices: [{ Device }] } } + + return newJSON } - /** * getPathArr creates an array of path parameter for given device collection * @param {String} uuidCollection : array of uuid of active devices. * returns pathArr: array of path */ -function getPathArr(uuidCollection) { - const pathArr = []; - let i = 0; +function getPathArr (uuidCollection) { + const pathArr = [] + let i = 0 R.map((k) => { - const dataItemsSet = getDataItem(k); + const dataItemsSet = getDataItem(k) // create pathArr for all dataItems if (dataItemsSet.length !== 0) { for (let j = 0; j < dataItemsSet.length; j++) { - pathArr[i++] = dataItemsSet[j].path; + pathArr[i++] = dataItemsSet[j].path } } - return pathArr; // eslint - }, uuidCollection); - return pathArr; + return pathArr // eslint + }, uuidCollection) + return pathArr } /** @@ -1030,13 +1017,13 @@ function getPathArr(uuidCollection) { * @param uuidCollection - array of uuid of active devices. * return true - if path Valid, false - invalid path. */ -function pathValidation(recPath, uuidCollection) { - const pathArr = getPathArr(uuidCollection); - const result = dataStorage.filterPathArr(pathArr, recPath); +function pathValidation (recPath, uuidCollection) { + const pathArr = getPathArr(uuidCollection) + const result = dataStorage.filterPathArr(pathArr, recPath) if (result.length !== 0) { - return true; + return true } - return false; + return false } // Exports @@ -1061,5 +1048,5 @@ module.exports = { initiateCircularBuffer, updateSchemaCollection, updateBufferOnDisconnect, - insertRawData, -}; + insertRawData +} diff --git a/src/routes/assets.js b/src/routes/assets.js index 1a8c162..40e6cbd 100644 --- a/src/routes/assets.js +++ b/src/routes/assets.js @@ -1,76 +1,74 @@ -const R = require('ramda'); -const moment = require('moment'); -const { errResponse, assetImplementation } = require('../utils/handlers'); -const common = require('../common'); -const lokijs = require('../lokijs'); +const R = require('ramda') +const moment = require('moment') +const { errResponse, assetImplementation } = require('../utils/handlers') +const common = require('../common') +const lokijs = require('../lokijs') // TODO handle routes here including id parsing -function *getAsset() { - let idsA; - const { ids, device } = this.params; +function * getAsset () { + let idsA + const { ids, device } = this.params if (ids) { - idsA = ids.split(';'); + idsA = ids.split(';') } - const { type, count, removed, target, archetypeId } = this.query; - assetImplementation(this.res, idsA, type, Number(count), removed, (target || device), archetypeId, this.headers.accept); + const { type, count, removed, target, archetypeId } = this.query + assetImplementation(this.res, idsA, type, Number(count), removed, (target || device), archetypeId, this.headers.accept) } - -function *createAsset() { - const { id } = this.params; - const { device, type } = this.query; - const { body } = this.request; - const uuidCollection = common.getAllDeviceUuids(this.mtc.devices); - let uuid = common.getDeviceUuid(device); +function * createAsset () { + const { id } = this.params + const { device, type } = this.query + const { body } = this.request + const uuidCollection = common.getAllDeviceUuids(this.mtc.devices) + let uuid = common.getDeviceUuid(device) if ((uuid === undefined) && !R.isEmpty(uuidCollection)) { - uuid = uuidCollection[0]; // default device + uuid = uuidCollection[0] // default device } else if (R.isEmpty(uuidCollection)) { - return errResponse(this.res, this.headers.accept, 'NO_DEVICE', device); + return errResponse(this.res, this.headers.accept, 'NO_DEVICE', device) } - const value = []; + const value = [] const jsonData = { time: '', - dataitem: [], - }; - value.push(id); - value.push(type); - let keys; + dataitem: [] + } + value.push(id) + value.push(type) + let keys if (body) { - keys = R.keys(body); + keys = R.keys(body) R.forEach((k) => { - let time; + let time if (k === 'time') { - time = R.pluck(k, [body]); - jsonData.time = time[0]; + time = R.pluck(k, [body]) + jsonData.time = time[0] } if (R.isEmpty(time)) { - jsonData.time = moment.utc().format(); + jsonData.time = moment.utc().format() } if (k === 'body') { - const data = R.pluck(k, [body]); - value.push(data[0]); + const data = R.pluck(k, [body]) + value.push(data[0]) } - }, keys); + }, keys) } - jsonData.dataitem.push({ name: 'addAsset', value }); + jsonData.dataitem.push({ name: 'addAsset', value }) console.log(value, jsonData, uuid) - const status = lokijs.addToAssetCollection(jsonData, uuid); + const status = lokijs.addToAssetCollection(jsonData, uuid) if (status) { - this.body = '\r\n'; - return false; + this.body = '\r\n' + return false } - this.body = '\r\n'; - return false; + this.body = '\r\n' + return false } -function *updateAsset() { - const { id } = this.params; +function * updateAsset () { + // const { id } = this.params } - module.exports = (router) => { router .get('assets', '/:device/assets/:ids', getAsset) @@ -78,5 +76,5 @@ module.exports = (router) => { .get('assets', '/assets/:ids', getAsset) .get('/assets', getAsset) .post('/assets/:id', createAsset) - .put('/assets/:id', updateAsset); -}; + .put('/assets/:id', updateAsset) +} diff --git a/src/routes/current.js b/src/routes/current.js index 009cba4..eab54e4 100644 --- a/src/routes/current.js +++ b/src/routes/current.js @@ -1,29 +1,29 @@ -const R = require('ramda'); -const { currentImplementation, giveResponse, errResponse, handleMultilineStream, validityCheck } = require('../utils/handlers'); -const common = require('../common'); -const devices = require('../store'); +const R = require('ramda') +const { currentImplementation, giveResponse, errResponse, handleMultilineStream, validityCheck } = require('../utils/handlers') +const common = require('../common') +const devices = require('../store') -function *current() { +function * current () { // eg: reqPath = /sample?path=//Device[@name="VMC-3Axis"]//Hydraulic&from=97&count=5 - let uuidCollection; + let uuidCollection if (!this.params.device) { - uuidCollection = common.getAllDeviceUuids(devices); + uuidCollection = common.getAllDeviceUuids(devices) } else { - uuidCollection = [common.getDeviceUuid(this.params.device)]; + uuidCollection = [common.getDeviceUuid(this.params.device)] } if (R.isEmpty(uuidCollection) || uuidCollection[0] === undefined) { - return errResponse(this.res, this.headers.accept, 'NO_DEVICE', this.params.device); + return errResponse(this.res, this.headers.accept, 'NO_DEVICE', this.params.device) } // TODO: implement casting for params parsing // default values will fail validation system // consider using db gateway for casting // start params parser - const at = Number(this.query.at) || undefined; - const path = this.query.path; - const freq = Number(this.query.frequency) || Number(this.query.interval) || undefined; + const at = Number(this.query.at) || undefined + const path = this.query.path + const freq = Number(this.query.frequency) || Number(this.query.interval) || undefined if (freq) { if (at) { @@ -31,7 +31,7 @@ function *current() { this.res, this.headers.accept, 'INVALID_REQUEST' - ); + ) } return handleMultilineStream( this.res, @@ -42,20 +42,20 @@ function *current() { at, undefined, this.headers.accept - ); + ) } // end params parser - const obj = validityCheck('current', uuidCollection, path, at); + const obj = validityCheck('current', uuidCollection, path, at) if (obj.valid) { - const jsonData = currentImplementation(this.res, this.headers.accept, at, path, uuidCollection); - return giveResponse(jsonData, this.headers.accept, this.res); + const jsonData = currentImplementation(this.res, this.headers.accept, at, path, uuidCollection) + return giveResponse(jsonData, this.headers.accept, this.res) } - return errResponse(this.res, this.headers.accept, 'validityCheck', obj.errorJSON); + return errResponse(this.res, this.headers.accept, 'validityCheck', obj.errorJSON) } module.exports = (router) => { router .get('/current', current) - .get('/:device/current', current); -}; + .get('/:device/current', current) +} diff --git a/src/routes/index.js b/src/routes/index.js index c749b05..2724e8b 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -1,11 +1,11 @@ -const probe = require('./probe'); -const sample = require('./sample'); -const assets = require('./assets'); -const current = require('./current'); +const probe = require('./probe') +const sample = require('./sample') +const assets = require('./assets') +const current = require('./current') module.exports = (router) => { - probe(router); - assets(router); - sample(router); - current(router); -}; + probe(router) + assets(router) + sample(router) + current(router) +} diff --git a/src/routes/probe.js b/src/routes/probe.js index 6645e85..a5683d5 100644 --- a/src/routes/probe.js +++ b/src/routes/probe.js @@ -1,38 +1,38 @@ -const R = require('ramda'); -const lokijs = require('../lokijs'); -const { concatenateDevices, jsonToXML } = require('../jsonToXML'); -const { errResponse } = require('../utils/handlers'); -const common = require('../common'); -const devices = require('../store'); +const R = require('ramda') +const lokijs = require('../lokijs') +const { concatenateDevices, jsonToXML } = require('../jsonToXML') +const { errResponse } = require('../utils/handlers') +const common = require('../common') +const devices = require('../store') -function *probe() { +function * probe () { // eg: reqPath = /sample?path=//Device[@name="VMC-3Axis"]//Hydraulic&from=97&count=5 - let uuidCollection; + let uuidCollection if (!this.params.device) { - uuidCollection = common.getAllDeviceUuids(devices); + uuidCollection = common.getAllDeviceUuids(devices) } else { - uuidCollection = [common.getDeviceUuid(this.params.device)]; + uuidCollection = [common.getDeviceUuid(this.params.device)] } if (R.isEmpty(uuidCollection) || uuidCollection[0] === undefined) { - return errResponse(this.res, this.headers.accept, 'NO_DEVICE', this.params.device); + return errResponse(this.res, this.headers.accept, 'NO_DEVICE', this.params.device) } const schema = R.map((uuid) => { - const latestSchema = lokijs.searchDeviceSchema(uuid); - return lokijs.probeResponse(latestSchema); - }, uuidCollection); + const latestSchema = lokijs.searchDeviceSchema(uuid) + return lokijs.probeResponse(latestSchema) + }, uuidCollection) if (schema.length) { - const json = concatenateDevices(schema); - if (this.header.accepts === 'application/json') return (this.body = json); - return jsonToXML(JSON.stringify(json), this.res); + const json = concatenateDevices(schema) + if (this.header.accepts === 'application/json') return (this.body = json) + return jsonToXML(JSON.stringify(json), this.res) } - return errResponse(this.res, this.headers.accepts, 'UNSUPPORTED', this.url); + return errResponse(this.res, this.headers.accepts, 'UNSUPPORTED', this.url) } module.exports = (router) => { router .get('/probe', probe) - .get('/:device/probe', probe); -}; + .get('/:device/probe', probe) +} diff --git a/src/routes/sample.js b/src/routes/sample.js index 0111895..e88a169 100644 --- a/src/routes/sample.js +++ b/src/routes/sample.js @@ -1,31 +1,31 @@ -const { sampleImplementation, giveResponse, errResponse, handleMultilineStream, validityCheck } = require('../utils/handlers'); -const common = require('../common'); -const { getSequence } = require('../dataStorage'); -const devices = require('../store'); +const { sampleImplementation, giveResponse, errResponse, handleMultilineStream, validityCheck } = require('../utils/handlers') +const common = require('../common') +const { getSequence } = require('../dataStorage') +const devices = require('../store') -function *sample() { +function * sample () { // eg: reqPath = /sample?path=//Device[@name="VMC-3Axis"]//Hydraulic&from=97&count=5 - let uuidCollection; + let uuidCollection if (!this.params.device) { - uuidCollection = common.getAllDeviceUuids(devices); + uuidCollection = common.getAllDeviceUuids(devices) } else { - uuidCollection = [common.getDeviceUuid(this.params.device)]; + uuidCollection = [common.getDeviceUuid(this.params.device)] } // TODO: implement casting for params parsing // default values will fail validation system // consider using db gateway for casting // start params parser - let count = Number(this.query.count); - if (isNaN(count)) count = 100; - const path = this.query.path; - const freq = Number(this.query.frequency) || Number(this.query.interval); - let from; + let count = Number(this.query.count) + if (isNaN(count)) count = 100 + const path = this.query.path + const freq = Number(this.query.frequency) || Number(this.query.interval) + let from if (this.query.from) { - from = Number(this.query.from); + from = Number(this.query.from) } else { - from = getSequence().firstSequence; + from = getSequence().firstSequence } // end params parser @@ -39,20 +39,20 @@ function *sample() { from, count, this.headers.accept - ); + ) } - const obj = validityCheck('sample', uuidCollection, path, from, count); + const obj = validityCheck('sample', uuidCollection, path, from, count) if (obj.valid) { - const jsonData = sampleImplementation(this.res, this.headers.accept, from, count, path, uuidCollection); + const jsonData = sampleImplementation(this.res, this.headers.accept, from, count, path, uuidCollection) console.log(JSON.stringify(jsonData)) - return giveResponse(jsonData, this.headers.accept, this.res); + return giveResponse(jsonData, this.headers.accept, this.res) } - return errResponse(this.res, this.headers.accept, 'validityCheck', obj.errorJSON); + return errResponse(this.res, this.headers.accept, 'validityCheck', obj.errorJSON) } module.exports = (router) => { router .get('/sample', sample) - .get('/:device/sample', sample); -}; + .get('/:device/sample', sample) +} diff --git a/src/simulator/adapter.js b/src/simulator/adapter.js index 276dcd1..a5ffaff 100644 --- a/src/simulator/adapter.js +++ b/src/simulator/adapter.js @@ -4,44 +4,44 @@ // https://github.com/diversario/node-ssdp/issues/70 // it is ok but unpredictable when testing -const log = require('../config/logger'); -const config = require('../config/config'); -const ip = require('ip').address(); -const { uuid, urn, machinePort, filePort } = config.app.simulator; -const { Server } = require('node-ssdp'); +const log = require('../config/logger') +const config = require('../config/config') +const ip = require('ip').address() +const { uuid, urn, machinePort, filePort } = config.app.simulator +const { Server } = require('node-ssdp') const ssdpOptions = { location: `${ip}:${machinePort}:${filePort}`, udn: uuid, adInterval: 10000, - allowWildcards: true, -}; + allowWildcards: true +} -let server; +let server -function stop() { - if (!server) return; - server.stop(); - server = false; +function stop () { + if (!server) return + server.stop() + server = false } // Start adapter // @retrurns promise -function start() { +function start () { // return immediately if server is running - if (server) return new Promise((success) => success()); - server = new Server(ssdpOptions); - server.on('advertise-alive', log.debug.bind(log)); - server.on('advertise-bye', () => setImmediate(log.debug.bind(log))); - server.on('error', log.error.bind(log)); - server.addUSN(`urn:schemas-mtconnect-org:service:${urn}:1`); - process.on('exit', server.stop.bind(server)); - server.start(); - return new Promise((success, failure) => { - if (!server.sock) failure(); - server.sock.once('listening', success); - server.sock.once('error', failure); - }); + if (server) return new Promise((resolve, reject) => resolve()) + server = new Server(ssdpOptions) + server.on('advertise-alive', log.debug.bind(log)) + server.on('advertise-bye', () => setImmediate(log.debug.bind(log))) + server.on('error', log.error.bind(log)) + server.addUSN(`urn:schemas-mtconnect-org:service:${urn}:1`) + process.on('exit', server.stop.bind(server)) + server.start() + return new Promise((resolve, reject) => { + if (!server.sock) reject() + server.sock.once('listening', resolve) + server.sock.once('error', reject) + }) } -module.exports = { start, stop }; +module.exports = { start, stop } diff --git a/src/simulator/device.js b/src/simulator/device.js index 1243cd1..f5d44e1 100644 --- a/src/simulator/device.js +++ b/src/simulator/device.js @@ -1,55 +1,55 @@ // Device - actual device // * emits data over http via http/event-stream -const log = require('../config/logger'); -const through = require('through'); +const log = require('../config/logger') +const through = require('through') // const common = require('../common'); -const config = require('../config/config'); +const config = require('../config/config') // const byline = require('byline'); -const es = require('event-stream'); -const koa = require('koa'); -const app = koa(); -const InfStream = require('../utils/infstream'); -const { inputFile } = config.app.simulator; +const es = require('event-stream') +const koa = require('koa') +const app = koa() +const InfStream = require('../utils/infstream') +const { inputFile } = config.app.simulator // send sends line with a delay to the client // line [String] single line of the input file // TODO: update stream to be infinent -function send(line) { - this.queue(line); - this.pause(); +function send (line) { + this.queue(line) + this.pause() const to = setTimeout(() => { - clearTimeout(to); - this.resume(); - }, 1000); + clearTimeout(to) + this.resume() + }, 1000) } // end finigshes the stream -function end() { - this.queue(null); +function end () { + this.queue(null) } app.on('error', (err, ctx) => { - log.error('server error', err, ctx); -}); + log.error('server error', err, ctx) +}) -app.use(function *response() { - this.type = 'text/event-stream; charset=utf-8'; - this.set('Cache-Control', 'no-cache'); - this.set('Connection', 'keep-alive'); +app.use(function * response () { + this.type = 'text/event-stream; charset=utf-8' + this.set('Cache-Control', 'no-cache') + this.set('Connection', 'keep-alive') this.body = (new InfStream({ file: inputFile })) .on('error', log.error.bind(log)) .pipe(es.split('\n')) - .pipe(through(send, end)); + .pipe(through(send, end)) - const socket = this.socket; - function close() { - socket.removeListener('error', close); - socket.removeListener('close', close); + const socket = this.socket + function close () { + socket.removeListener('error', close) + socket.removeListener('close', close) } - socket.on('error', close); - socket.on('close', close); -}); + socket.on('error', close) + socket.on('close', close) +}) -module.exports = app; +module.exports = app diff --git a/src/simulator/fileserver.js b/src/simulator/fileserver.js index 3d629ba..d206651 100644 --- a/src/simulator/fileserver.js +++ b/src/simulator/fileserver.js @@ -1,9 +1,9 @@ // File server // * serves static files (unsure why) // -const koa = require('koa'); -const serve = require('koa-static'); -const path = require('path'); -const app = koa(); -app.use(serve(path.join(__dirname, '../../public'))); -module.exports = app; +const koa = require('koa') +const serve = require('koa-static') +const path = require('path') +const app = koa() +app.use(serve(path.join(__dirname, '../../public'))) +module.exports = app diff --git a/src/simulator/index.js b/src/simulator/index.js index a7209f2..a91020d 100644 --- a/src/simulator/index.js +++ b/src/simulator/index.js @@ -1,11 +1,11 @@ -const log = require('../config/logger'); -const ip = require('ip').address(); -const config = require('../config/config'); -const adapter = require('./adapter'); -const device = require('./device'); -const fileServer = require('./fileserver'); -const { filePort, machinePort } = config.app.simulator; +const log = require('../config/logger') +const ip = require('ip').address() +const config = require('../config/config') +const adapter = require('./adapter') +const device = require('./device') +const fileServer = require('./fileserver') +const { filePort, machinePort } = config.app.simulator -adapter.start(); -device.listen(machinePort, ip, () => log.info(`Running device on ${machinePort}`)); -fileServer.listen(filePort, ip, () => log.info(`File server started on ${filePort}`)); +adapter.start() +device.listen(machinePort, ip, () => log.info(`Running device on ${machinePort}`)) +fileServer.listen(filePort, ip, () => log.info(`File server started on ${filePort}`)) diff --git a/src/store.js b/src/store.js index 59c5592..70ad0c6 100644 --- a/src/store.js +++ b/src/store.js @@ -1,4 +1,4 @@ // devices absraction -const Loki = require('lokijs'); -const Db = new Loki('agent-loki.json'); -module.exports = Db.addCollection('devices'); +const Loki = require('lokijs') +const Db = new Loki('agent-loki.json') +module.exports = Db.addCollection('devices') diff --git a/src/utils/handlers.js b/src/utils/handlers.js index cd1ce6f..27de887 100644 --- a/src/utils/handlers.js +++ b/src/utils/handlers.js @@ -15,37 +15,36 @@ */ // Imports - External -const net = require('net'); -const R = require('ramda'); -const moment = require('moment'); +const net = require('net') +const R = require('ramda') +const moment = require('moment') // Imports - Internal -const lokijs = require('../lokijs'); -const log = require('../config/logger'); -const common = require('../common'); -const dataStorage = require('../dataStorage'); -const jsonToXML = require('../jsonToXML'); -const md5 = require('md5'); -const devices = require('../store'); +const lokijs = require('../lokijs') +const log = require('../config/logger') +const common = require('../common') +const dataStorage = require('../dataStorage') +const jsonToXML = require('../jsonToXML') +const md5 = require('md5') +const devices = require('../store') // IgnoreTimestamps - Ignores timeStamp with agent time. -const instanceId = common.getCurrentTimeInSec(); -const c = new net.Socket(); // client-adapter - +const instanceId = common.getCurrentTimeInSec() +const c = new net.Socket() // client-adapter /* *** Error Handling *** */ -function errResponse(res, acceptType, errCode, value) { - let errorData; +function errResponse (res, acceptType, errCode, value) { + let errorData if (errCode === 'validityCheck') { - errorData = value; + errorData = value } else { - errorData = jsonToXML.createErrorResponse(instanceId, errCode, value); + errorData = jsonToXML.createErrorResponse(instanceId, errCode, value) } if (acceptType === 'application/json') { - res.send(errorData); - return ''; + res.send(errorData) + return '' } - return jsonToXML.jsonToXML(JSON.stringify(errorData), res); + return jsonToXML.jsonToXML(JSON.stringify(errorData), res) } /** @@ -60,49 +59,49 @@ function errResponse(res, acceptType, errCode, value) { * } * */ -function validityCheck(call, uuidCollection, path, seqId, count, freq) { - const errorJSON = jsonToXML.createErrorResponse(instanceId); - let errorObj = errorJSON.MTConnectError.Errors; - const getSequence = dataStorage.getSequence(); - const firstSequence = getSequence.firstSequence; - const lastSequence = getSequence.lastSequence; - const bufferSize = dataStorage.getBufferSize(); - const maxFreq = 2147483646; - let valid = true; +function validityCheck (call, uuidCollection, path, seqId, count, freq) { + const errorJSON = jsonToXML.createErrorResponse(instanceId) + let errorObj = errorJSON.MTConnectError.Errors + const getSequence = dataStorage.getSequence() + const firstSequence = getSequence.firstSequence + const lastSequence = getSequence.lastSequence + const bufferSize = dataStorage.getBufferSize() + const maxFreq = 2147483646 + let valid = true if (path) { if (!lokijs.pathValidation(path, uuidCollection)) { - valid = false; - errorObj = jsonToXML.categoriseError(errorObj, 'INVALID_XPATH', path); + valid = false + errorObj = jsonToXML.categoriseError(errorObj, 'INVALID_XPATH', path) } } if (freq) { if ((freq < 0) || (!Number.isInteger(freq)) || (freq > maxFreq)) { - valid = false; - errorObj = jsonToXML.categoriseError(errorObj, 'INTERVAL', freq); + valid = false + errorObj = jsonToXML.categoriseError(errorObj, 'INTERVAL', freq) } } if (call === 'current') { if (seqId || seqId === 0) { // seqId = 0, check whether it is in range if ((seqId < firstSequence) || (seqId > lastSequence)) { - valid = false; - errorObj = jsonToXML.categoriseError(errorObj, 'SEQUENCEID', seqId); + valid = false + errorObj = jsonToXML.categoriseError(errorObj, 'SEQUENCEID', seqId) } } } else { if ((seqId < 0) || (seqId < firstSequence) || (seqId > lastSequence) || isNaN(seqId)) { - valid = false; - errorObj = jsonToXML.categoriseError(errorObj, 'FROM', seqId); + valid = false + errorObj = jsonToXML.categoriseError(errorObj, 'FROM', seqId) } if ((count === 0) || (!Number.isInteger(count)) || (count < 0) || (count > bufferSize)) { - valid = false; - errorObj = jsonToXML.categoriseError(errorObj, 'COUNT', count); + valid = false + errorObj = jsonToXML.categoriseError(errorObj, 'COUNT', count) } } const obj = { valid, - errorJSON, - }; - return obj; + errorJSON + } + return obj } /** @@ -111,32 +110,32 @@ function validityCheck(call, uuidCollection, path, seqId, count, freq) { * * */ -function checkAndGetParam(res, acceptType, req, param, defaultVal, number) { - const param1 = `${param}=`; - let rest; - let paramEnd; +function checkAndGetParam (res, acceptType, req, param, defaultVal, number) { + const param1 = `${param}=` + let rest + let paramEnd if (req.includes(param1)) { - const paramStart = req.search(param1); - const length = param1.length; - const start = paramStart + length; - rest = req.slice(start); + const paramStart = req.search(param1) + const length = param1.length + const start = paramStart + length + rest = req.slice(start) } else { - return defaultVal; + return defaultVal } if (rest.includes('?') || rest.includes('&')) { - paramEnd = rest.search(/(\?|&)/); + paramEnd = rest.search(/(\?|&)/) } else { - paramEnd = Infinity; + paramEnd = Infinity } - let paramVal = rest.slice(0, paramEnd); + let paramVal = rest.slice(0, paramEnd) if (paramVal === '') { - return errResponse(res, acceptType, 'QUERY_ERROR', param); + return errResponse(res, acceptType, 'QUERY_ERROR', param) } if (number) { - paramVal = Number(paramVal); + paramVal = Number(paramVal) } - return paramVal; + return paramVal } /** @@ -146,14 +145,14 @@ function checkAndGetParam(res, acceptType, req, param, defaultVal, number) { * @param {Object} res - to give response to browser * */ -function giveResponse(jsonData, acceptType, res) { +function giveResponse (jsonData, acceptType, res) { if (jsonData.length !== 0) { - const completeJSON = jsonToXML.concatenateDeviceStreams(jsonData); + const completeJSON = jsonToXML.concatenateDeviceStreams(jsonData) if (acceptType === 'application/json') { - res.send(completeJSON); - return; + res.send(completeJSON) + return } - jsonToXML.jsonToXML(JSON.stringify(completeJSON), res); + jsonToXML.jsonToXML(JSON.stringify(completeJSON), res) } } @@ -164,19 +163,19 @@ function giveResponse(jsonData, acceptType, res) { * @param {Object} res - http response object * @param {String} acceptType - specifies required format for response */ -function giveStreamResponse(jsonStream, boundary, res, acceptType, isError) { +function giveStreamResponse (jsonStream, boundary, res, acceptType, isError) { if (acceptType === 'application/json') { - const contentLength = jsonStream.length; - res.write(`--${boundary}\r\n`); - res.write(`Content-type: text/xml\r\n`); - res.write(`Content-length:${contentLength}\r\n\r\n`); - res.write(`${jsonStream}\r\n`); + const contentLength = jsonStream.length + res.write(`--${boundary}\r\n`) + res.write(`Content-type: text/xml\r\n`) + res.write(`Content-length:${contentLength}\r\n\r\n`) + res.write(`${jsonStream}\r\n`) if (isError) { - res.write(`\r\n--${boundary}--\r\n`); - res.end(); // ends the connection + res.write(`\r\n--${boundary}--\r\n`) + res.end() // ends the connection } } else { - jsonToXML.jsonToXMLStream(jsonStream, boundary, res, isError); + jsonToXML.jsonToXMLStream(jsonStream, boundary, res, isError) } } @@ -187,23 +186,23 @@ function giveStreamResponse(jsonStream, boundary, res, acceptType, isError) { * @param {String} path - path specified in req Eg: path=//Axes//Rotary * @param {Array} uuidCollection - list of all the connected devices' uuid. */ -function currentImplementation(res, acceptType, sequenceId, path, uuidCollection) { - const jsonData = []; - let uuid; - let i = 0; +function currentImplementation (res, acceptType, sequenceId, path, uuidCollection) { + const jsonData = [] + let uuid + let i = 0 R.map((k) => { - uuid = k; - const latestSchema = lokijs.searchDeviceSchema(uuid); - const dataItemsArr = lokijs.getDataItem(uuid); - const deviceName = lokijs.getDeviceName(uuid); + uuid = k + const latestSchema = lokijs.searchDeviceSchema(uuid) + const dataItemsArr = lokijs.getDataItem(uuid) + const deviceName = lokijs.getDeviceName(uuid) if ((dataItemsArr === null) || (latestSchema === null)) { - return errResponse(res, acceptType, 'NO_DEVICE', deviceName); + return errResponse(res, acceptType, 'NO_DEVICE', deviceName) } - const dataItems = dataStorage.categoriseDataItem(latestSchema, dataItemsArr, sequenceId, uuid, path); - jsonData[i++] = jsonToXML.updateJSON(latestSchema, dataItems, instanceId); - return jsonData; // eslint - }, uuidCollection); - return jsonData; + const dataItems = dataStorage.categoriseDataItem(latestSchema, dataItemsArr, sequenceId, uuid, path) + jsonData[i++] = jsonToXML.updateJSON(latestSchema, dataItems, instanceId) + return jsonData // eslint + }, uuidCollection) + return jsonData } /** @@ -214,23 +213,23 @@ function currentImplementation(res, acceptType, sequenceId, path, uuidCollection * @param {Number} count - number of dataItems should be shown maximum. * @param {Array} uuidCollection - list of all the connected devices' uuid. */ -function sampleImplementation(res, acceptType, from, count, path, uuidCollection) { - const jsonData = []; - let uuid; - let i = 0; +function sampleImplementation (res, acceptType, from, count, path, uuidCollection) { + const jsonData = [] + let uuid + let i = 0 R.map((k) => { - uuid = k; - const latestSchema = lokijs.searchDeviceSchema(uuid); - const dataItemsArr = lokijs.getDataItem(uuid); - const deviceName = lokijs.getDeviceName(uuid); + uuid = k + const latestSchema = lokijs.searchDeviceSchema(uuid) + const dataItemsArr = lokijs.getDataItem(uuid) + const deviceName = lokijs.getDeviceName(uuid) if ((dataItemsArr === null) || (latestSchema === null)) { - return errResponse(res, acceptType, 'NO_DEVICE', deviceName); + return errResponse(res, acceptType, 'NO_DEVICE', deviceName) } - const dataItems = dataStorage.categoriseDataItem(latestSchema, dataItemsArr, from, uuid, path, count); - jsonData[i++] = jsonToXML.updateJSON(latestSchema, dataItems, instanceId, 'SAMPLE'); - return jsonData; - }, uuidCollection); - return jsonData; + const dataItems = dataStorage.categoriseDataItem(latestSchema, dataItemsArr, from, uuid, path, count) + jsonData[i++] = jsonToXML.updateJSON(latestSchema, dataItems, instanceId, 'SAMPLE') + return jsonData + }, uuidCollection) + return jsonData } /** @@ -239,24 +238,24 @@ function sampleImplementation(res, acceptType, from, count, path, uuidCollection * return {object} obj - { assetId, status } * */ -function validateAssetList(arr) { - const baseArr = lokijs.getAssetCollection(); - let valid; - let obj; +function validateAssetList (arr) { + const baseArr = lokijs.getAssetCollection() + let valid + let obj for (let i = 0; i < arr.length; i++) { - valid = false; + valid = false for (let j = 0; j < baseArr.length; j++) { if (arr[i] === baseArr[j]) { - valid = true; + valid = true } } if (!valid) { - obj = { assetId: arr[i], status: false }; - return obj; + obj = { assetId: arr[i], status: false } + return obj } } - obj = { assetId: 'all', status: true }; - return obj; + obj = { assetId: 'all', status: true } + return obj } /** @@ -270,30 +269,29 @@ function validateAssetList(arr) { * @param {String} acceptType - required output format - xml/json */ // /assets with type, count, removed, target, archetypeId etc -function assetImplementationForAssets(res, type, count, removed, target, archetypeId, acceptType) { - const assetCollection = lokijs.getAssetCollection(); - let assetItem; - const assetData = []; - let i = 0; +function assetImplementationForAssets (res, type, count, removed, target, archetypeId, acceptType) { + const assetCollection = lokijs.getAssetCollection() + let assetItem + const assetData = [] + let i = 0 if (!R.isEmpty(assetCollection)) { - assetItem = dataStorage.readAssets(assetCollection, type, Number(count), removed, target, archetypeId); - assetData[i++] = jsonToXML.createAssetResponse(instanceId, assetItem); - const completeJSON = jsonToXML.concatenateAssetswithIds(assetData); + assetItem = dataStorage.readAssets(assetCollection, type, Number(count), removed, target, archetypeId) + assetData[i++] = jsonToXML.createAssetResponse(instanceId, assetItem) + const completeJSON = jsonToXML.concatenateAssetswithIds(assetData) if (acceptType === 'application/json') { - res.send(completeJSON); - return; + res.send(completeJSON) + return } - jsonToXML.jsonToXML(JSON.stringify(completeJSON), res); - return; + jsonToXML.jsonToXML(JSON.stringify(completeJSON), res) + return } // empty asset Collection - assetData[i++] = jsonToXML.createAssetResponse(instanceId, { }); // empty asset response - const completeJSON = jsonToXML.concatenateAssetswithIds(assetData); + assetData[i++] = jsonToXML.createAssetResponse(instanceId, { }) // empty asset response + const completeJSON = jsonToXML.concatenateAssetswithIds(assetData) if (acceptType === 'application/json') { - res.send(completeJSON); - return; + res.send(completeJSON) + return } - jsonToXML.jsonToXML(JSON.stringify(completeJSON), res); - return; + jsonToXML.jsonToXML(JSON.stringify(completeJSON), res) } // max-len limit set to 150 in .eslintrc @@ -308,28 +306,28 @@ function assetImplementationForAssets(res, type, count, removed, target, archety * @param {String} archetypeId * @param {String} acceptType - required output format - xml/json */ -function assetImplementation(res, assetList, type, count, removed, target, archetypeId, acceptType) { - let valid = {}; - const assetData = []; - let i = 0; +function assetImplementation (res, assetList, type, count, removed, target, archetypeId, acceptType) { + let valid = {} + const assetData = [] + let i = 0 if (!assetList) { - return assetImplementationForAssets(res, type, count, removed, target, archetypeId, acceptType); + return assetImplementationForAssets(res, type, count, removed, target, archetypeId, acceptType) } - const assetCollection = assetList; - valid = validateAssetList(assetCollection); + const assetCollection = assetList + valid = validateAssetList(assetCollection) if (valid.status && !R.isEmpty(assetCollection)) { R.map((k) => { - const assetItem = dataStorage.readAssetforId(k); - assetData[i++] = jsonToXML.createAssetResponse(instanceId, assetItem); - return k; - }, assetCollection); - const completeJSON = jsonToXML.concatenateAssetswithIds(assetData); + const assetItem = dataStorage.readAssetforId(k) + assetData[i++] = jsonToXML.createAssetResponse(instanceId, assetItem) + return k + }, assetCollection) + const completeJSON = jsonToXML.concatenateAssetswithIds(assetData) if (acceptType === 'application/json') { - return res.send(completeJSON); + return res.send(completeJSON) } - return jsonToXML.jsonToXML(JSON.stringify(completeJSON), res); + return jsonToXML.jsonToXML(JSON.stringify(completeJSON), res) } - return errResponse(res, acceptType, 'ASSET_NOT_FOUND', valid.assetId); + return errResponse(res, acceptType, 'ASSET_NOT_FOUND', valid.assetId) } /* *********************************** Multipart Stream Supporting Functions **************************** */ @@ -344,59 +342,56 @@ function assetImplementation(res, assetList, type, count, removed, target, arche * @param {String} acceptType - required output format - xml/json * @param {String} call - current / sample */ -function streamResponse(res, seqId, count, path, uuidCollection, boundary, acceptType, call) { - let jsonData = ''; +function streamResponse (res, seqId, count, path, uuidCollection, boundary, acceptType, call) { + let jsonData = '' if (call === 'current') { - jsonData = currentImplementation(res, acceptType, seqId, path, uuidCollection); + jsonData = currentImplementation(res, acceptType, seqId, path, uuidCollection) } else { - jsonData = sampleImplementation(res, acceptType, seqId, count, path, uuidCollection); + jsonData = sampleImplementation(res, acceptType, seqId, count, path, uuidCollection) } if (jsonData.length !== 0) { - const completeJSON = jsonToXML.concatenateDeviceStreams(jsonData); - const jsonStream = JSON.stringify(completeJSON); - giveStreamResponse(jsonStream, boundary, res, acceptType, 0); + const completeJSON = jsonToXML.concatenateDeviceStreams(jsonData) + const jsonStream = JSON.stringify(completeJSON) + giveStreamResponse(jsonStream, boundary, res, acceptType, 0) } } // recursive function for current -function multiStreamCurrent(res, path, uuidCollection, freq, call, sequenceId, boundary, acceptType) { +function multiStreamCurrent (res, path, uuidCollection, freq, call, sequenceId, boundary, acceptType) { if (!res.req.client.destroyed) { setTimeout(() => { - streamResponse(res, sequenceId, 0, path, uuidCollection, boundary, acceptType, call); - return multiStreamCurrent(res, path, uuidCollection, freq, call, sequenceId, boundary, acceptType); - }, freq); + streamResponse(res, sequenceId, 0, path, uuidCollection, boundary, acceptType, call) + return multiStreamCurrent(res, path, uuidCollection, freq, call, sequenceId, boundary, acceptType) + }, freq) } - return; } - // recursive function for sample, from updated on each call with nextSequence -function multiStreamSample(res, path, uuidCollection, freq, call, from, boundary, count, acceptType) { +function multiStreamSample (res, path, uuidCollection, freq, call, from, boundary, count, acceptType) { if (!res.req.client.destroyed) { const timeOut = setTimeout(() => { - const firstSequence = dataStorage.getSequence().firstSequence; - const lastSequence = dataStorage.getSequence().lastSequence; + const firstSequence = dataStorage.getSequence().firstSequence + const lastSequence = dataStorage.getSequence().lastSequence if ((from >= firstSequence) && (from <= lastSequence)) { - streamResponse(res, from, count, path, uuidCollection, boundary, acceptType, call); - const fromValue = dataStorage.getSequence().nextSequence; - return multiStreamSample(res, path, uuidCollection, freq, call, fromValue, boundary, count, acceptType); + streamResponse(res, from, count, path, uuidCollection, boundary, acceptType, call) + const fromValue = dataStorage.getSequence().nextSequence + return multiStreamSample(res, path, uuidCollection, freq, call, fromValue, boundary, count, acceptType) } - clearTimeout(timeOut); - const errorData = jsonToXML.createErrorResponse(instanceId, 'MULTIPART_STREAM', from); - return giveStreamResponse(JSON.stringify(errorData), boundary, res, acceptType, 1); - }, freq); + clearTimeout(timeOut) + const errorData = jsonToXML.createErrorResponse(instanceId, 'MULTIPART_STREAM', from) + return giveStreamResponse(JSON.stringify(errorData), boundary, res, acceptType, 1) + }, freq) } - return; } /** * @parm {Number} interval - the ms delay needed between each stream. Eg: 1000 */ -function handleMultilineStream(res, path, uuidCollection, interval, call, sequenceId, count, acceptType) { +function handleMultilineStream (res, path, uuidCollection, interval, call, sequenceId, count, acceptType) { // Header - const boundary = md5(moment.utc().format()); - const time = new Date(); + const boundary = md5(moment.utc().format()) + const time = new Date() const header1 = 'HTTP/1.1 200 OK\r\n' + `Date: ${time.toUTCString()}\r\n` + 'Server: MTConnectAgent\r\n' + @@ -404,106 +399,106 @@ function handleMultilineStream(res, path, uuidCollection, interval, call, sequen 'Connection: close\r\n' + 'Cache-Control: private, max-age=0\r\n' + `Content-Type: multipart/x-mixed-replace;boundary=${boundary}` + - 'Transfer-Encoding: chunked\r\n\r\n'; // comment this line to remove chunk size from appearing - const freq = Number(interval); + 'Transfer-Encoding: chunked\r\n\r\n' // comment this line to remove chunk size from appearing + const freq = Number(interval) if (call === 'current') { - const obj = validityCheck('current', uuidCollection, path, sequenceId, 0, freq); + const obj = validityCheck('current', uuidCollection, path, sequenceId, 0, freq) if (obj.valid) { - res.setHeader('Connection', 'close'); // rewrite default value keep-alive - res.writeHead(200, header1); - streamResponse(res, sequenceId, 0, path, uuidCollection, boundary, acceptType, call); - return multiStreamCurrent(res, path, uuidCollection, freq, call, sequenceId, boundary, acceptType); + res.setHeader('Connection', 'close') // rewrite default value keep-alive + res.writeHead(200, header1) + streamResponse(res, sequenceId, 0, path, uuidCollection, boundary, acceptType, call) + return multiStreamCurrent(res, path, uuidCollection, freq, call, sequenceId, boundary, acceptType) } - return errResponse(res, acceptType, 'validityCheck', obj.errorJSON); + return errResponse(res, acceptType, 'validityCheck', obj.errorJSON) // return jsonToXML.jsonToXML(JSON.stringify(obj.errorJSON), res); } else if (call === 'sample') { - const obj = validityCheck('sample', uuidCollection, path, sequenceId, count, freq); + const obj = validityCheck('sample', uuidCollection, path, sequenceId, count, freq) if (obj.valid) { - res.setHeader('Connection', 'close'); // rewrite default value keep-alive - res.writeHead(200, header1); - streamResponse(res, sequenceId, count, path, uuidCollection, boundary, acceptType, call); - const fromVal = dataStorage.getSequence().nextSequence; - return multiStreamSample(res, path, uuidCollection, freq, call, fromVal, boundary, count, acceptType); + res.setHeader('Connection', 'close') // rewrite default value keep-alive + res.writeHead(200, header1) + streamResponse(res, sequenceId, count, path, uuidCollection, boundary, acceptType, call) + const fromVal = dataStorage.getSequence().nextSequence + return multiStreamSample(res, path, uuidCollection, freq, call, fromVal, boundary, count, acceptType) } - return errResponse(res, acceptType, 'validityCheck', obj.errorJSON); + return errResponse(res, acceptType, 'validityCheck', obj.errorJSON) // return jsonToXML.jsonToXML(JSON.stringify(obj.errorJSON), res); } - return log.error('Request Error'); + return log.error('Request Error') // TODO: ERROR INVALID request } /* **************************************** Request Handling ********************************************* */ -function getAssetList(receivedPath) { - let reqPath = receivedPath; - const firstIndex = reqPath.indexOf('/'); - let assetList; - reqPath = reqPath.slice(firstIndex + 1); // Eg1: asset/assetId1;assetId2; +function getAssetList (receivedPath) { + let reqPath = receivedPath + const firstIndex = reqPath.indexOf('/') + let assetList + reqPath = reqPath.slice(firstIndex + 1) // Eg1: asset/assetId1;assetId2; if (reqPath.includes('/')) { // check for another '/' - const index = reqPath.lastIndexOf('/') + 1; - assetList = reqPath.slice(index, Infinity); + const index = reqPath.lastIndexOf('/') + 1 + assetList = reqPath.slice(index, Infinity) if (assetList.includes(';')) { - assetList = assetList.split(';'); // array of assetIds = [assetId1, assetId2] + assetList = assetList.split(';') // array of assetIds = [assetId1, assetId2] } else if (assetList.includes('?')) { - const qm = assetList.indexOf('?'); // Eg: reqPath = /asset/assetId?type="CuttingTool" - assetList = [assetList.slice(0, qm)]; // one id created to array, [assetId] + const qm = assetList.indexOf('?') // Eg: reqPath = /asset/assetId?type="CuttingTool" + assetList = [assetList.slice(0, qm)] // one id created to array, [assetId] } else { - assetList = [assetList]; + assetList = [assetList] } } - return assetList; + return assetList } /* storeAsset */ // Possibly never used // * can't find a reverence in the doc) -function storeAsset(res, receivedPath, acceptType) { - const reqPath = receivedPath; - const body = res.req.body; - const assetId = getAssetList(reqPath)[0]; - const type = checkAndGetParam(res, acceptType, reqPath, 'type', undefined, 0); - const device = checkAndGetParam(res, acceptType, reqPath, 'device', undefined, 0); - const uuidCollection = common.getAllDeviceUuids(devices); - let uuid = common.getDeviceUuid(device); +function storeAsset (res, receivedPath, acceptType) { + const reqPath = receivedPath + const body = res.req.body + const assetId = getAssetList(reqPath)[0] + const type = checkAndGetParam(res, acceptType, reqPath, 'type', undefined, 0) + const device = checkAndGetParam(res, acceptType, reqPath, 'device', undefined, 0) + const uuidCollection = common.getAllDeviceUuids(devices) + let uuid = common.getDeviceUuid(device) if ((uuid === undefined) && !R.isEmpty(uuidCollection)) { - uuid = uuidCollection[0]; // default device + uuid = uuidCollection[0] // default device } else if (R.isEmpty(uuidCollection)) { - return errResponse(res, acceptType, 'NO_DEVICE', device); + return errResponse(res, acceptType, 'NO_DEVICE', device) } - const value = []; + const value = [] const jsonData = { time: '', - dataitem: [], - }; - value.push(assetId); - value.push(type); - let keys; + dataitem: [] + } + value.push(assetId) + value.push(type) + let keys if (body) { - keys = R.keys(body); + keys = R.keys(body) R.forEach((k) => { - let time; + let time if (k === 'time') { - time = R.pluck(k, [body]); - jsonData.time = time[0]; + time = R.pluck(k, [body]) + jsonData.time = time[0] } if (R.isEmpty(time)) { - jsonData.time = moment.utc().format(); + jsonData.time = moment.utc().format() } if (k === 'body') { - const data = R.pluck(k, [body]); - value.push(data[0]); + const data = R.pluck(k, [body]) + value.push(data[0]) } - }, keys); + }, keys) } - jsonData.dataitem.push({ name: 'addAsset', value }); - const status = lokijs.addToAssetCollection(jsonData, uuid); + jsonData.dataitem.push({ name: 'addAsset', value }) + const status = lokijs.addToAssetCollection(jsonData, uuid) if (status) { - res.send('\r\n'); + res.send('\r\n') } else { - res.send('\r\n'); + res.send('\r\n') } - return ''; + return '' } /** @@ -515,63 +510,62 @@ function storeAsset(res, receivedPath, acceptType) { */ // Req = curl -X PUT -d avail=FOOBAR localhost:7000/VMC-3Axis // adapter = VMC-3Axis, receivedPath = /VMC-3Axis, deviceName = undefined -function handlePut(adapter, receivedPath, deviceName) { - const { res, req } = this; - let device = deviceName; - const { body } = this.request; - const errCategory = 'UNSUPPORTED_PUT'; - let cdata = ''; +function handlePut (adapter, receivedPath, deviceName) { + const { res, req } = this + let device = deviceName + const { body } = this.request + const errCategory = 'UNSUPPORTED_PUT' + let cdata = '' if (device === undefined && adapter === undefined) { - cdata = 'Device must be specified for PUT'; - return errResponse(res, undefined, errCategory, cdata); + cdata = 'Device must be specified for PUT' + return errResponse(res, undefined, errCategory, cdata) } else if (device === undefined) { - device = adapter; + device = adapter } - const uuidVal = common.getDeviceUuid(device); + const uuidVal = common.getDeviceUuid(device) if (uuidVal === undefined) { - cdata = `Cannot find device:${device}`; - return errResponse(res, undefined, errCategory, cdata); + cdata = `Cannot find device:${device}` + return errResponse(res, undefined, errCategory, cdata) } // if (R.hasIn('_type', body) && (R.pluck('_type', [body])[0] === 'command')) { - console.log(`\r\n\r\ndeviceName${device}deviceNameEnd`); - const keys = R.keys(req.body); + console.log(`\r\n\r\ndeviceName${device}deviceNameEnd`) + const keys = R.keys(req.body) for (let i = 0; i < devices.data.length; i++) { - console.log(`port${devices.data[i].port}portEnd`); + console.log(`port${devices.data[i].port}portEnd`) R.each((k) => { - const value = R.pluck(k, [body])[0]; - const command = `${k}=${value}`; - console.log(`Sending command ${command} to ${device}`); - c.write(`*${command}\n`); - }, keys); + const value = R.pluck(k, [body])[0] + const command = `${k}=${value}` + console.log(`Sending command ${command} to ${device}`) + c.write(`*${command}\n`) + }, keys) } } else { - const keys = R.keys(body); + const keys = R.keys(body) const jsonData = { time: '', - dataitem: [], - }; - jsonData.time = moment.utc().format(); + dataitem: [] + } + jsonData.time = moment.utc().format() R.map((k) => { - const data = R.pluck(k, [body]); + const data = R.pluck(k, [body]) if (k === 'time') { - jsonData.time = data; + jsonData.time = data } else { - jsonData.dataitem.push({ name: k, value: data[0] }); + jsonData.dataitem.push({ name: k, value: data[0] }) } - return jsonData; - }, keys); + return jsonData + }, keys) - lokijs.dataCollectionUpdate(jsonData, uuidVal); + lokijs.dataCollectionUpdate(jsonData, uuidVal) } - this.body = '\r\n'; - return true; + this.body = '\r\n' + return true } - /** * handleRequest() classifies depending on the request method or assets * and call handleGet(), handlePut or handleAssetReq @@ -579,61 +573,60 @@ function handlePut(adapter, receivedPath, deviceName) { * @param {Object} res * returns null */ -function *handleRequest() { - const { req, res } = this; - const acceptType = req.headers.accept; +function * handleRequest () { + const { req, res } = this + const acceptType = req.headers.accept // '/mill-1/sample?path=//Device[@name="VMC-3Axis"]//Hydraulic' - const receivedPath = req.url; - let device; - let end = Infinity; - let call; + const receivedPath = req.url + let device + let end = Infinity + let call // 'mill-1/sample?path=//Device[@name="VMC-3Axis"]//Hydraulic' - let reqPath = receivedPath.slice(1, receivedPath.length); - const qm = reqPath.lastIndexOf('?'); // 13 + let reqPath = receivedPath.slice(1, receivedPath.length) + const qm = reqPath.lastIndexOf('?') // 13 if (qm !== -1) { // if ? found - reqPath = reqPath.substring(0, qm); // 'mill-1/sample' + reqPath = reqPath.substring(0, qm) // 'mill-1/sample' } - const loc1 = reqPath.search('/'); // 6 + const loc1 = reqPath.search('/') // 6 if (loc1 !== -1) { - end = loc1; + end = loc1 } - const first = reqPath.substring(0, end); // 'mill-1' + const first = reqPath.substring(0, end) // 'mill-1' // If a '/' was found if (loc1 !== -1) { - const loc2 = reqPath.includes('/', loc1 + 1); // check for another '/' + const loc2 = reqPath.includes('/', loc1 + 1) // check for another '/' if (loc2) { - let nextString = reqPath.slice(loc1 + 1, Infinity); - const nextSlash = nextString.search('/'); - nextString = nextString.slice(0, nextSlash); - return errResponse(res, acceptType, 'UNSUPPORTED', receivedPath); + let nextString = reqPath.slice(loc1 + 1, Infinity) + const nextSlash = nextString.search('/') + nextString = nextString.slice(0, nextSlash) + return errResponse(res, acceptType, 'UNSUPPORTED', receivedPath) } - device = first; - call = reqPath.substring(loc1 + 1, Infinity); + device = first + call = reqPath.substring(loc1 + 1, Infinity) } else { // Eg: if reqPath = '/sample?path=//Device[@name="VMC-3Axis"]//Hydraulic' - call = first; // 'sample' + call = first // 'sample' } - return handlePut.call(this, call, receivedPath, device, acceptType); + return handlePut.call(this, call, receivedPath, device, acceptType) } - -function isPutEnabled(ip, AllowPutFrom) { - return R.find(k => k === ip)(AllowPutFrom); +function isPutEnabled (ip, AllowPutFrom) { + return R.find(k => k === ip)(AllowPutFrom) } -function parseIP() { - return function *doParseIP(next) { - let ip = this.req.connection.remoteAddress; - const head = /ffff:/; +function parseIP () { + return function * doParseIP (next) { + let ip = this.req.connection.remoteAddress + const head = /ffff:/ if ((head).test(ip)) { - ip = ip.replase(head, ''); + ip = ip.replase(head, '') } else if (ip === '::1') { - ip = 'localhost'; + ip = 'localhost' } - this.mtc.ip = ip; - yield next; - }; + this.mtc.ip = ip + yield next + } } /** @@ -642,39 +635,39 @@ function parseIP() { * @param {Object} res * @param {String} method - 'GET', 'PUT, POST' etc */ -function validRequest({ AllowPutFrom, allowPut }) { - return function *validateRequest(next) { - let cdata = ''; - const { method, res, req } = this; +function validRequest ({ AllowPutFrom, allowPut }) { + return function * validateRequest (next) { + let cdata = '' + const { method, res, req } = this - const errCategory = 'UNSUPPORTED_PUT'; + const errCategory = 'UNSUPPORTED_PUT' if (allowPut) { if ((method === 'PUT' || method === 'POST') && (!isPutEnabled(this.mtc.ip, AllowPutFrom))) { - cdata = `HTTP PUT is not allowed from ${this.mtc.ip}`; - return errResponse(res, req.headers.accept, errCategory, cdata); + cdata = `HTTP PUT is not allowed from ${this.mtc.ip}` + return errResponse(res, req.headers.accept, errCategory, cdata) } if (method !== 'GET' && method !== 'PUT' && method !== 'POST') { - cdata = 'Only the HTTP GET and PUT requests are supported'; - return errResponse(res, req.headers.accept, errCategory, cdata); + cdata = 'Only the HTTP GET and PUT requests are supported' + return errResponse(res, req.headers.accept, errCategory, cdata) } } else { if (method !== 'GET') { - cdata = 'Only the HTTP GET request is supported'; - return errResponse(res, req.headers.accept, errCategory, cdata); + cdata = 'Only the HTTP GET request is supported' + return errResponse(res, req.headers.accept, errCategory, cdata) } } - return yield next; - }; + return yield next + } } -function logging() { - return function *doLogging(next) { - log.debug(`Request ${this.method} from ${this.host}:`); - const startT = new Date(); - yield next; - const ms = new Date() - startT; - log.debug('%s %s - %s', this.method, this.url, ms); - }; +function logging () { + return function * doLogging (next) { + log.debug(`Request ${this.method} from ${this.host}:`) + const startT = new Date() + yield next + const ms = new Date() - startT + log.debug('%s %s - %s', this.method, this.url, ms) + } } module.exports = { @@ -699,5 +692,5 @@ module.exports = { validRequest, parseIP, logging, - errResponse, -}; + errResponse +} diff --git a/src/utils/index.js b/src/utils/index.js index 17f89a4..439981a 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,21 +1,21 @@ -const request = require('co-request'); +const request = require('co-request') module.exports = { // parseHeaders Parse headers returned by UPnP server into info // @params [Object] Headers from SSDP search // @returns [Object] device information - parseHeaders({ LOCATION, USN }) { - const [ip, port, filePort] = LOCATION.split(':'); - const [uuid] = USN.split(':'); - return { ip, port, filePort, uuid }; + parseHeaders ({ LOCATION, USN }) { + const [ip, port, filePort] = LOCATION.split(':') + const [uuid] = USN.split(':') + return { ip, port, filePort, uuid } }, // deviceXML pulls device xml from the device // @params [Object] device info + path (xml location) // @returns [*function] generator function - *deviceXML({ ip, filePort, path }) { - if (!(ip && filePort && path)) throw new Error('Missing required arguments'); - const { body } = yield request(`http://${ip}:${filePort}${path}`); - return body; - }, -}; + * deviceXML ({ ip, filePort, path }) { + if (!(ip && filePort && path)) throw new Error('Missing required arguments') + const { body } = yield request(`http://${ip}:${filePort}${path}`) + return body + } +} diff --git a/src/utils/infstream.js b/src/utils/infstream.js index 09524cc..bfc4562 100644 --- a/src/utils/infstream.js +++ b/src/utils/infstream.js @@ -1,45 +1,45 @@ -const fs = require('fs-ext'); -const { Readable } = require('stream'); -const BUFF_SIZE = 256; +const fs = require('fs-ext') +const { Readable } = require('stream') +const BUFF_SIZE = 256 class InfReader extends Readable { - constructor(options) { - super(options); - this.fd = fs.openSync(options.file, 'r'); - this.position = 0; - this.finish = this.finish.bind(this); - this.onRead = this.onRead.bind(this); - this._read = this._read.bind(this); - this.readSource = this.readSource.bind(this); - process.on('exit', this.finish); - process.on('error', this.finish); + constructor (options) { + super(options) + this.fd = fs.openSync(options.file, 'r') + this.position = 0 + this.finish = this.finish.bind(this) + this.onRead = this.onRead.bind(this) + this._read = this._read.bind(this) + this.readSource = this.readSource.bind(this) + process.on('exit', this.finish) + process.on('error', this.finish) } - finish() { - fs.close(this.fd); + finish () { + fs.close(this.fd) } // _read will be called when the stream wants to pull more data in // the advisory size argument is ignored in this case. - onRead(err, bytes, readBuffer) { + onRead (err, bytes, readBuffer) { if (err) { - return process.nextTick(() => this.emmit('error', err)); + return process.nextTick(() => this.emmit('error', err)) } - this.position += bytes; + this.position += bytes if (bytes > 0) { - return this.push(readBuffer, 'ascii'); + return this.push(readBuffer, 'ascii') } - this.position = 0; - return this.push(Buffer.from(' '), 'ascii'); + this.position = 0 + return this.push(Buffer.from(' '), 'ascii') } - readSource(size) { - const readSize = size || BUFF_SIZE; - fs.read(this.fd, Buffer.alloc(readSize), 0, readSize, this.position, this.onRead); + readSource (size) { + const readSize = size || BUFF_SIZE + fs.read(this.fd, Buffer.alloc(readSize), 0, readSize, this.position, this.onRead) } - _read(size) { - this.readSource(size); + _read (size) { + this.readSource(size) } } -module.exports = InfReader; +module.exports = InfReader diff --git a/src/xmlToJSON.js b/src/xmlToJSON.js index c4675ca..66c1b07 100644 --- a/src/xmlToJSON.js +++ b/src/xmlToJSON.js @@ -16,32 +16,31 @@ // Imports - External -const xml2js = require('xml2js'); +const xml2js = require('xml2js') /** * xml device schema to json conversion * @param {object} XMLObj * returns JSON object */ -function xmlToJSON(XMLObj) { - let JSONObj; - const parser = new xml2js.Parser({ attrkey: '$' }); +function xmlToJSON (XMLObj) { + let JSONObj + const parser = new xml2js.Parser({ attrkey: '$' }) // XML to JSON parser.parseString(XMLObj, (err, result) => { - JSONObj = result; - }); + JSONObj = result + }) if (JSONObj === undefined) { - console.log('error in received xml'); - return undefined; // eslint + console.log('error in received xml') + return undefined // eslint } - return JSONObj; + return JSONObj } - // Exports module.exports = { - xmlToJSON, -}; + xmlToJSON +}