Browse Source

Upload files to ''

master
cse47122 4 years ago
parent
commit
f0c0ae5597
  1. 151
      fake-device-manager.js
  2. 168
      fake-device.js
  3. 23
      index.js
  4. 2438
      package-lock.json
  5. 30
      package.json

151
fake-device-manager.js

@ -1,96 +1,73 @@
const sizeof = require('object-sizeof')
const FakeDevice = require('./fake-device')
/* globals describe it */
module.exports = function FakeDeviceManager ({
connection,
deviceCount = 10,
spawnInterval = 200,
metricsInterval = 200,
sendInterval = 15000,
measurements,
onUpdateStats
}) {
if (!connection) {
throw new Error('Missing connection param')
}
if (!measurements) {
throw new Error('Missing measurements param')
}
let devices = []
const expect = require('chai').expect
let stats = {
devices: 0,
measurements: 0,
writes: 0,
size: 0,
errors: 0
}
const FakeDeviceManager = require('../src/fake-device-manager')
const measurements = {
usage: {type: 'integer', min: 0, max: 100},
voltage: {type: 'integer', min: 0, max: 15},
temperature: {type: 'integer', min: -20, max: 60}
}
/**
* Return device list
*/
const getDevices = () => {
return devices
// create fake influx connection
// let connectionWriteData = false
const connection = {
send: (deviceId, data) => {
return new Promise((resolve, reject) => {
// connectionWriteData = {deviceId, data}
resolve()
})
}
}
/**
* Return stats data
*/
const getStats = () => {
return stats
}
describe('FakeDeviceManager', function () {
let fakeDeviceManager = null
/**
* Update stats on device data send event
*/
const onDeviceSendData = (err, data) => {
if (err) {
console.log(err)
stats.errors++
return
}
stats.measurements += data.length
data.forEach(chunk => {
stats.size += sizeof(chunk)
})
stats.writes++
}
it('should throw error if no params are passed', function () {
expect(FakeDeviceManager).to.throw(Error)
})
/**
* Start device spawn process
*/
const start = () => {
let __spawnInterval = setInterval(() => {
stats.devices++
devices.push(FakeDevice({
deviceId: stats.devices,
connection,
measurements,
onSendData: onDeviceSendData,
autoStart: true,
metricsInterval,
sendInterval
}))
// when device limit is reached stop spawn inteval
if (stats.devices === deviceCount) {
clearTimeout(__spawnInterval)
}
}, spawnInterval)
}
it('shold throw missing connection param', function () {
expect(() => FakeDeviceManager({})).to.throw('Missing connection param')
})
/**
* Stop all spawned devices
*/
const stop = () => {
for (let i = 0; i < stats.devices; i++) {
devices[i].stop()
}
}
it('shold throw missing measurements param', function () {
expect(() => FakeDeviceManager({
connection
})).to.throw('Missing measurements param')
})
return {
start,
stop,
getDevices,
getStats
}
}
it('should create instance', function () {
fakeDeviceManager = FakeDeviceManager({
connection,
measurements,
sendInterval: 500
})
expect(fakeDeviceManager).to.have.property('start')
})
it('should spawn device instances', function (done) {
fakeDeviceManager.start()
setTimeout(() => {
let devices = fakeDeviceManager.getDevices()
done(!devices.length)
}, 500)
})
it('should collect device stats', function (done) {
setTimeout(() => {
let stats = fakeDeviceManager.getStats()
if (!stats) return done('No data')
if (
stats.devices &&
stats.measurements &&
stats.writes &&
stats.size
) {
done()
} else {
done('Invalid write data format')
}
}, 1000)
})
})

168
fake-device.js

@ -1,111 +1,81 @@
/**
* Create FakeDevice
*
* @param {any} {
* deviceId,
* metricsInterval = 100,
* sendInterval = 15000
* }
* @returns FakeDevice
*/
module.exports = function FakeDevice ({
deviceId,
connection,
metricsInterval = 100,
sendInterval = 30000,
onSendData,
autoStart = false,
measurements
}) {
if (!deviceId) {
throw new Error('Missing deviceId param')
}
if (!connection) {
throw new Error('Missing connection param')
}
if (!measurements) {
throw new Error('Missing measurements param')
}
/* globals describe it */
let data = []
const expect = require('chai').expect
let __metricsInterval = null
let __sendInterval = null
const FakeDevice = require('../src/fake-device')
const measurements = {
usage: {type: 'integer', min: 0, max: 100},
voltage: {type: 'integer', min: 0, max: 15},
temperature: {type: 'integer', min: -20, max: 60}
}
/**
* Return data buffer
*/
const getData = () => {
return data
// create fake influx connection
let connectionWriteData = false
const connection = {
send: (deviceId, data) => {
return new Promise((resolve, reject) => {
connectionWriteData = {deviceId, data}
resolve()
})
}
}
/**
* Read data from sensors
* Will generate fake random data
*/
const readData = () => {
function getRandomArbitrary (min, max) {
return Math.random() * (max - min) + min
}
describe('FakeDevice', function () {
let fakeDevice = null
let chunk = {}
Object.keys(measurements).forEach(measurement => {
switch (measurements[measurement].type) {
case 'integer':
chunk[measurement] = getRandomArbitrary(measurements[measurement].min, measurements[measurement].max)
break
default:
throw new Error('Invalid measurement type')
}
})
chunk['timestamp'] = new Date()
it('should throw error if no params are passed', function () {
expect(FakeDevice).to.throw(Error)
})
data.push(chunk)
}
it('shold throw missing deviceId param', function () {
expect(() => FakeDevice({})).to.throw('Missing deviceId param')
})
/**
* Send data to db and clear data buffer
* Calls onSendData function if set
*/
const send = () => {
// send data buffer to connection
connection.send(deviceId, data)
.then(() => {
if (!onSendData) return
onSendData(null, data)
// clear internal data buffer on successfull send
data = []
})
.catch(err => {
if (!onSendData) return
onSendData(err)
})
}
it('shold throw missing connection param', function () {
expect(() => FakeDevice({
deviceId: 1
})).to.throw('Missing connection param')
})
/**
* Stop collecting data
*/
const stop = () => {
clearInterval(__metricsInterval)
clearInterval(__sendInterval)
}
it('shold throw missing measurements param', function () {
expect(() => FakeDevice({
deviceId: 1,
connection
})).to.throw('Missing measurements param')
})
/**
* Start collecting data
*/
const start = () => {
__metricsInterval = setInterval(readData, metricsInterval)
__sendInterval = setInterval(send, sendInterval)
}
it('should create instance', function () {
fakeDevice = FakeDevice({
deviceId: 1,
connection,
sendInterval: 1000,
measurements
})
expect(fakeDevice).to.have.property('start')
})
if (autoStart) {
start()
}
it('should generate data', function (done) {
fakeDevice.start()
setTimeout(() => {
let data = fakeDevice.getData()
done(!data.length)
}, 500)
})
return {
stop,
start,
send,
getData
}
}
it('should send data to influx', function (done) {
setTimeout(() => {
if (!connectionWriteData) return done('No data')
if (!connectionWriteData.deviceId) return done('Invalid write data - missing deviceId')
if (
connectionWriteData.data[0].usage &&
connectionWriteData.data[0].voltage &&
connectionWriteData.data[0].temperature &&
connectionWriteData.data[0].timestamp
) {
done()
} else {
done('Invalid write data format')
}
}, 1000)
})
})

23
index.js

@ -0,0 +1,23 @@
const DeviceManager = require('./src/fake-device-manager')
const FakeDeviceConnection = require('./src/fake-device-connection')()
const updateStats = require('./src/stats')
console.log('Generating data - send interval: 30s')
let deviceManager = DeviceManager({
deviceCount: 10,
metricsInterval: 30,
connection: FakeDeviceConnection,
onUpdateStats: updateStats,
measurements: {
temperature: {type: 'integer', min: -10, max: 50},
air_humidity: {type: 'integer', min: 30, max: 100},
ground_humidity: {type: 'integer', min: 30, max: 100},
airforce: {type: 'integer', min: 30, max: 100}
}
})
updateStats(deviceManager)
deviceManager.start()

2438
package-lock.json

File diff suppressed because it is too large

30
package.json

@ -0,0 +1,30 @@
{
"name": "iot-dummy-data-generator",
"version": "0.1.0",
"description": "Spawn dummy IoT devices and generate custom data that can be send to some data store.",
"main": "index.js",
"scripts": {
"test": "mocha --watch --reporter spec"
},
"author": "Vedran Jukic",
"license": "MIT",
"dependencies": {
"influx": "^5.0.3",
"object-sizeof": "^1.1.1",
"progress": "^1.1.8"
},
"devDependencies": {
"eslint": "^3.11.1",
"eslint-config-standard": "^6.2.1",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^2.0.1",
"chai": "^3.5.0",
"deepstream.io": "^2.0.0",
"deepstream.io-client-js": "^2.0.0",
"diff": "^3.0.1",
"jsdoc": "^3.4.3",
"mocha": "^3.1.2",
"sinon": "^1.17.6",
"winston": "^2.3.0"
}
}
Loading…
Cancel
Save