index.js 7.75 KB
/**
 * @fileOverview 调用入口
 * @author qiqi.zhou@yoho.cn
 */
//require("babel/register"); //es6 polyfill

/**
 * 连接器
 * @type {Connector}
 */
var Connector = require('./lib/connector');
/**
 * order config
 * @type {Object}
 */
var orders = require('./lib/interface');
/**
 * uhf dirctive module
 * @type {Uhf}
 */
var Uhf = require('./lib/directive/uhf');
/**
 * config dirctive module
 * @type {[Config]}
 */
var Config = require('./lib/directive/config');
/**
 * inventory dirctive module
 * @type {Inventory}
 */
var Inventory = require('./lib/directive/inventory');

var _ = require('lodash');
var util = require('./lib/util');

var appConfig = require('./config');

/**
 * 读写器初始化模块实例
 * @type {Uhf}
 */
var uhf = new Uhf();
/**
 * 配置读写器实例
 * @type {Config}
 */
var config = new Config();
/**
 * 读写器盘点实例
 * @type {Inventory}
 */
var inventory = new Inventory();

/**
 * 打开读写器
 * @method open
 * @exports index/open
 * @param {String} host 读写器IP
 * @param {Number} port 端口
 * @param {Function} callback 打开成功回调
 */
exports.open = function (host, port, callback) {
    if (!host || !port) {
        return;
    }
    //连接一个读写器
    var connector = new Connector({
        host: host,
        port: port
    }, function () {
        uhf.send(connector, orders.openUhf);
    }, receive);

    //当打开读写器模块
    connector.on('openUhf', function (data) {
        if ((data.code === 1 || data.code === 2) && callback) {
            callback(connector);
        }
    });
};

/**
 * 设置功率
 * @method setPower
 * @exports index/setPower
 * @param {Connector} connector 连接器
 * @param {Array}  传参,依次是4个天线的功率 eg: [15,15,15,0]
 */
exports.setPower = function (connector, param) {
    config.send(connector, orders.setPower, param);
};

/**
 * 设置灵敏度筛选
 * @method setFilter
 * @exports index/setFilter
 * @param {Connector} connect 连接器
 * param {Object} 是否开启灵敏度和灵敏度值 eg:{on:'1',rssi:-60}
 */
exports.setFilter = function (connector, param) {
    config.send(connector, orders.setFilter, param);
};

/**
 * 设置固定频率
 * @method setFrequency
 * @exports index/setFrequency
 * @param {Connector} connector 连接器
 * @param {Object} param 天线端口和定频的值 eg: {ant: 0, freq: 10 }
 */
exports.setFrequency = function (connector, param) {
    config.send(connector, orders.setFrequency, param);
};

/**
 * 设置盘点时长
 * @method setInventoryTime
 * @exports index/setInventoryTime
 * @param {Connector} connect 连接器
 * @param {Number} param 时长,单位毫秒 eg: 400
 */
exports.setInventoryTime = function (connector, param) {
    inventory.send(connector, orders.setInventoryTime, param);
};

/**
 * 开始盘点
 * @method sartInventory
 * @exports index/sartInventory
 * @param {Connector} connect 连接器
 */
exports.sartInventory = function (connector) {
    inventory.send(connector, orders.sartInventory);
};

/**
 * 结束盘点
 * @method stopInventory
 * @exports index/stopInventory
 * @param {Connector} connector 连接器
 */
exports.stopInventory = function (connector) {
    inventory.send(connector, orders.stopInventory);
};

/**
 * 开始间歇盘点封装
 * @method start
 * @exports index/start
 * @param {Object} options 传入的配置参数
 * @param {Function} callback 获取数据的回调
 * @example:
  exports.start({
        host: '172.16.13.6',//IP
        port: '9761',//端口
        filter: {//设置灵敏度的过滤
            'on': '1',
            rssi: -60
        },
        frequencys: [{//天线的定频
            ant: 0,
            freq: 10
        }, {
            ant: 1,
            freq: 10
        }, {
            ant: 2,
            freq: 10
        }, {
            ant: 3,
            freq: 10
        }],
        inventoryTime: 400,//设置盘点时长
        power: [15, 0, 0, 0]//功率设置
    }, function (data) {
        //console.log(data);
    });
 */
var isStop = false,
    checkInventoryFlag,
    checkSpeedFlag;
exports.start = function (options, callback) {
    var rets = [];
    var countMap = {};
    exports.open(options.host, options.port, function (connector) {

        if (options.filter) { //开启灵敏度过滤
            exports.setFilter(connector, options.filter);
        }

        if (options.frequencys) { //开启固定频率
            _.forIn(options.frequencys, function (val, key) {
                exports.setFrequency(connector, val);
            });
        }

        if (options.inventoryTime) { //设置盘点时长
            exports.setInventoryTime(connector, options.inventoryTime);
        }

        if (options.power) { //设置功率
            connector.on('setInventoryTime', function (data) {
                exports.setPower(connector, options.power);
            });

        }

        connector.on('setPower', function (data) {
            exports.sartInventory(connector); //开始盘点
        });

        connector.on('sartInventory', function (data) {
            //console.log(data.code);
            if (data.code !== 2 && !isStop) {
                exports.sartInventory(connector);
            } else if (data.code === 2) {
                rets = procTagInfo(countMap, rets, data.data);
            }
            callback(rets);
        });

        checkInventoryFlag = setInterval(function () { //检查是否在架
            for (var i = 0; i < rets.length; i++) {
                var offTime = 1 * new Date() - rets[i].updateTime;
                if (offTime > appConfig.offInventory) {
                    rets[i].state = 'off';
                    rets[i].speed = 0;
                }
            }
        }, appConfig.checkInventory);

        checkSpeedFlag = setInterval(function () { //检查读取速度(times/sec)
            for (var i = 0; i < rets.length; i++) {
                if (countMap[rets[i].epc]) {
                    var prevCount = Number(countMap[rets[i].epc]);
                    rets[i].speed = prevCount / (appConfig.checkCount / 1000);
                    countMap[rets[i].epc] = 0;
                }
            }
        }, appConfig.checkCount);
    });
};

/**
 * 停止间歇盘点
 * @method stop
 * @exports index/stop
 * @param {Connector} connect 连接器
 */
exports.stop = function (connector) {
    isStop = true;
    clearInterval(checkInventoryFlag);
    clearInterval(checkSpeedFlag);
};

/**
 * 标签处理
 * @method procTagInfo
 * @param {Object} countMap 标签读取的次数
 * @param {Array} rets 盘点结果集
 * @param {Object} data 读取一次的内容
 */
function procTagInfo(countMap, rets, data) {
    var isExist = false,
        now = 1 * new Date();
    for (var i = 0; i < rets.length; i++) {
        if (rets[i].epc === data.epc) {
            rets[i].rssi = data.rssi;
            rets[i].updateTime = now;
            rets[i].state = 'on';
            rets[i].ant = data.ant;
            countMap[rets[i].epc] ++;
            isExist = true;
        }
    }
    if (!isExist) {
        data.updateTime = now;
        data.state = 'on';
        data.speed = 0;
        countMap[data.epc] = 1;
        rets.push(data);
    }
    return rets;
}


/**
 * 接收数据处理
 * @method receive
 * @param {Socket} client socket客户端
 * @param {Object} data 接收到的数据
 */
function receive(client, data, err) {
    var className = null,
        ret = null;
    if (!data) {
        return;
    }
    if (err) {
        console.log(err);
    }
    className = util.locateOrder(orders, data).val.directive;

    switch (className) {
    case 'uhf':
        ret = uhf.receive(client, data);
        break;
    case 'config':
        ret = config.receive(client, data);
        break;
    case 'inventory':
        ret = inventory.receive(client, data);
        break;
    }
    return ret;
}