const fs = require('fs');
const request = require('request');
/**
* Device class.
*
* Represents a the current device running the code.
* @class Device
* @constructor
*/
module.exports = class Device {
constructor(file) {
this.file = file || '/etc/device.json'
const json = JSON.parse(fs.readFileSync(this.file, 'utf8'));
Object.assign(this, json);
this.measurementPath = 'measurements.json';
this.actionPath = '';
this.actions = [];
this.measurements = [];
}
/**
* Register a measurement taken by the device
*
* @method registerMeasurement
* @param {string} label - the Measurement label to post.
* @param {string} base - the base URL of where to post.
* @param {number} interval - the interval to execute the measurement at.
* @param {function} action - the action used to calculate the measurement (must return a valid {@link Measurement}).
* @param {function} callback - the callback to execute after the measurement has been posted.
* @return {array} the list of all current actions.
*/
registerMeasurement(label, base, interval, action, after) {
const available = this.inputs.filter((a) => a.label === label);
if (available.length <= 0) {
throw new Error('Action is not registered with device');
}
const post = () => {
const measurementData = action();
this.postMeasurement(label, base, measurementData, after);
};
const measurement = {
label: label,
interval: interval,
callback: post
};
this.measurements.push(measurement);
return this.measurements;
}
/**
* Register an action by the device
*
* @method registerAction
* @param {string} label - the Measurement label to post.
* @param {function} action - the action to be carried out on the device
* action label, with an optional input argument, `(input) => {}`.
* @return {array} the list of all current actions.
*/
registerAction(label, action) {
const available = this.device_actions.filter((a) => a.label === label);
if (available.length <= 0) {
throw new Error('Action is not registered with device');
}
this.actions.push({
label: label,
action: action
});
return this.actions;
}
/**
* Execute an action given a label
*
* @method executeAction
* @param {string} label - the Measurement label to post.
* @return {object} the result of executing the action.
*/
executeAction(label, input) {
const action = this.actions.filter(a => a.label === label);
if (!action || action.length <= 0) {
throw new Error('Action is not registered with device');
}
return action[0].action(input);
}
/**
* Post a measurement to the Hive Server.
*
* @method postMeasurement
* @param {string} label - the Measurement label to post.
* @param {string} base - the url to the Hive server.
* @param {object} data - the data to be posted like { name: ..., value:... }.
* @return {object} the response from the API.
*/
postMeasurement(label, base, data, callback) {
const obj = {}
if (!callback) {
callback = (err, res, body) => {
};
}
const url = `${base}/${this.measurementPath}`;
const options = {
url: url,
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
json: data,
};
request(options, callback);
}
}