Source: SensorManager.js

var fs = require('fs');
var TemperatureDS18B20 = require('./drivers/temperature_ds18b20.js').TemperatureDS18B20;

/**
 * Generic SensorManager object which hold information about all supported sensors
 * @constructor
 */
var SensorManager = {};

/**
 * Initialize list of sensors from package.json file
 * @private
 * @memberof SensorManager
 */
var setListOfSensors = function () {
    var listOfSensors;
    try {
        var data = fs.readFileSync('./package.json', 'utf8');
        listOfSensors = JSON.parse(data);
        for (loop = 0; loop < listOfSensors.sensors.length; loop++) {
            listOfSensors.sensors[loop].multiple = false;
            listOfSensors.sensors[loop].used = false;
            var ids = Sensors.getIds(listOfSensors.sensors[loop].type);
            if (ids !== null) {
                listOfSensors.sensors[loop].multiple = true;
                delete (listOfSensors.sensors[loop].used);
                listOfSensors.sensors[loop].list = [];
                for (i = 0; i < ids.length; i++) {
                    var sensorInList = {
                        "id": ids[i],
                        "used": false
                    };
                    listOfSensors.sensors[loop].list.push(sensorInList);
                }
            }
        }
        // re-write to package.json
        var updateJSONStr = JSON.stringify(listOfSensors);
        fs.writeFileSync("package.json", updateJSONStr, "utf8");

    } catch (err) {
        console.log(err.name + "[code: " + err.code + "]:" + err.message);
        console.log(err.stack);
    }
    return listOfSensors.sensors;
}

/**
 * Retrieve all IDs supported by the sensor type
 * @param {String} type - Sensor type
 * @returns {Array} Array of ids
 */ 
SensorManager.getIds = function (type) {
    if (type === "temperature_ds18b20") {
        return TemperatureDS18B20.getIds();
    }
    return null;
}

/** 
 * Initial value of listOfSensors
 * @private
 * @memberof SensorManager
 */
var sensors = setListOfSensors();

/**
 * Define property 'listOfSensors' of SensorManager
 */
Object.defineProperty(SensorManager, 'listOfSensors', {
    enumerable: true,
    writable:true,
    value: sensors
});

/**
 * Check the validity of a sensor type. Errors will be thrown if the sensor type isn’t supported 
 * by the system or it is using. If isValid() is passed without any error, 
 * this sensor type and id (if existed) is eligible to use.
 * @param {String} type - Sensor type
 * @param {String} id - Sensor id
 * @return {Boolean} - True if valid, false if not
 * @throws Error when this type of sensor is using or unsupported
 */
SensorManager.isValid = function (type, id) {
    var list = SensorManager.listOfSensors;
    for (loop = 0; loop < list.length; loop++) {
        if (list[loop].type === type) { 
            if (list[loop].multiple === false) {
                if (list[loop].used === false) {
                    return 1;
                }
                return 2;
            } else {
                if (id === undefined) {
                    return 6;
                } else {
                    for(count = 0; count < list[loop].list.length; count++) {
                        if (list[loop].list[count].id === id) {
                            if (list[loop].list[count].used === false) {
                                return 1;
                            }
                            return 4;
                        }
                    }
                    return 8;
                }
            }
        }
    }
    return 7;
};

/**
 * Register or inform to the system that the sen-sor is going to be used. 
 * The used attribute of the sensor in the listOfSensors variable will be 
 * set to true if the sensor is eligible to be used. 
 * Appropriated error will be thrown if the sensor is using or unsupported.
 * @param {String} type - Sensor type
 * @param {String} id - Sensor id
 * @return {Boolean} True if register successful, false if not
 * @throws Error when this type of sensor is using or unsupported
 */
SensorManager.assignSensor = function (type, id) {
    var list = SensorManager.listOfSensors;
    for (loop = 0; loop < SensorManager.listOfSensors.length; loop++) {
        if (list[loop].type === type) {
            if (list[loop].multiple === false) {
                if (list[loop].used === false) {
                    list[loop].used = true;
                    return 1;
                } else {
                    return 2;
                }
            } else {
                if (id === undefined) {
                    return 6;
                } else {
                    for (count = 0; count < list[loop].list.length; count++) {
                        if (list[loop].list[count].id === id) {
                            if (list[loop].list[count].used === false) {
                                list[loop].list[count].used = true;
                                return 1;
                            } else {
                                return 4;
                            }
                        }
                    }
                    return 8;
                }
            }
        }
    }
    return 7;
}

/**
 * Unregister or inform to the system that the sensor is going to stop using. 
 * The re-sources assigned to this sensor will be freed, 
 * and used attribute of this sensor in the listOfSensors variable will be set to false. 
 * @param {String} type - Sensor type
 * @param {String} id - Sensor id
 * @return {Boolean} True if unregister successful, false if not
 * @throws Error when this type of sensor is unused or unsupported
 */
SensorManager.unassignSensor = function (type, id) {
    var list = SensorManager.listOfSensors;
    for (loop = 0; loop < list.length; loop++) {
        if (list[loop].type === type) {
            if (list[loop].multiple === false) {
                if (list[loop].used = true) {
                    list[loop].used = false;
                    return 1;
                } else {
                    return 2;
                }
            } else {
                if (id === undefined) {
                    return 6;
                } else {
                    for (count = 0; count < list[loop].list.length; count++) {
                        if (list[loop].list[count].id === id) {
                            if (list[loop].list[count].used === true) {
                                list[loop].list[count].used = false;
                                return 1;
                            } else {
                                return 5; // ErrorCode = 5: 
                            }
                        }
                    }
                    return 8;
                }
            }
        }
    }
    return 7;
}

/**
 * Check whether the input sensor type (along with its id if existed) is available in the system, 
 * regardless it is using or not.
 * @param {String} type - Sensor type
 * @param {String} id - Sensor id
 * @return {Boolean} True if this sensor type is supported, false if not
 */
SensorManager.isSupport = function (type, id) {
    var list = SensorManager.listOfSensors;
    for (loop = 0; loop < list.length; loop++) {
        if (list[loop].type === type) {
            if (list[loop].id === undefined) {
                return true;
            } else {
                if (list[loop].multiple === false) {
                    console.log('Warning: There is only one ' + type + ' sensor. ID will be ignored!');
                    return true;
                } else {
                    for (count = 0; count < list[loop].list.length; count++) {
                        if (list[loop].list[count].id === id) {
                            return true;
                        }
                    }
                    return false;
                }
            }
        }
    }
    return false;
}

/**
 * Check whether this sensor type (with specific id) is using
 * @param {String} type - Sensor type
 * @param {String} id - Sensor id
 * @return {Boolean} True if it is using, false if it is not
 */ 
SensorManager.isUsing = function (type, id) {
    var list = SensorManager.listOfSensors;
    for (loop = 0; loop < list.length; loop++) {
        if (list[loop].type === type) {
            if (list[loop].multiple === false) {
                return list[loop].used;
            } else {
                for (count = 0; count < list[loop].list.length; count++) {
                    if (list[loop].list[count].id === id) {
                        return list[loop].list[count].used;
                    }
                }
                // TODO: Print notification: "The sensor type doesn't have that id"
            }
        }
    }
    //TODO: print notification: "The sensor type is not exist in the system"
}

/**
 * Print the list of supported sensors, along with their ids.
 */
SensorManager.printListOfSensors = function () {
    var list = SensorManager.listOfSensors;
    console.log("List of supported sensors: ");
    console.log("-----------------------------");
    for (loop = 0; loop < list.length; loop++) {
        console.log(list[loop].type);
        if (list[loop].multiple === true) {
            // Print ids too
            for (i = 0; i < list[loop].list.length; i++) {
                console.log('id[' + i + '] = ' + list[loop].list[i].id);
            }
        }
    }
    console.log("-----------------------------");
}

/**
 * Print the list of sensors using at that time, along with their ids.
 */
SensorManager.printListOfUsingSensors = function () {
    var list = SensorManager.listOfSensors;
    console.log("List of sensors are using: ");
    console.log("-----------------------------");
    for (loop = 0; loop < list.length; loop++) {
        if (list[loop].multiple === false) {
            if (list[loop].used === true) {
                console.log(list[loop].type);
            }
        } else {
            var ids = [];
            for (count = 0; count < list[loop].list.length; count++) {
                if (list[loop].list[count].used === true) {
                    ids.push(list[loop].list[count].id);
                }
            }
            // print the result
            console.log(list[loop].type);
            ids.forEach(function (member) {
                console.log("id = " + member);
            })
        }
    }
    console.log("-----------------------------");
}

/**
* @exports Sensor
*/
module.exports.SensorManager = SensorManager;