Show:
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);
  }
}