index.js 6.95 KB
/**
 * @fileOverview 调用入口
 * @author qiqi.zhou@yoho.cn
 */

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

import _ from 'lodash';

import {
    locateOrder
}
from './lib/util';

import appConfig from './config';

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

/**
 * 打开读写器
 * @method open
 * @exports index/open
 * @param {String} host 读写器IP
 * @param {Number} port 端口
 * @param {Function} callback 打开成功回调
 */
export let open = function(host, port, callback) {
    if (!host || !port || !callback) {
        throw new Error("错误:ip,端口,回调必须要传");
    }
    //连接一个读写器
    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(null, connector);
        } else if (data) {
            var error = new Error(data.message);
            error.code = data.code;
            callback(error);
        }
    });
};

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

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

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

/**
 * 结束盘点
 * @method stopInventory
 * @exports index/stopInventory
 * @param {Connector} connector 连接器
 */
export let 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 (error,data) {
        //console.log(data);
    });
 */
let isStop = false;

export let start = function(options, callback) {
    var rets = [];
    var countMap = {};
    open(options.host, options.port, function(err, connector) {
        if (!options.filter || !options.frequencys || !options.inventoryTime || !options.power) {
            let error = new Error('Error:灵敏度,定频,盘点时长,功率必须要传!');
            callback(error);
        }
        //开启灵敏度过滤
        setFilter(connector, options.filter);

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

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

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

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

        connector.on('startInventory', function(data) {
            if (data.code !== 2 && !isStop) {
                startInventory(connector);
            } else if (data.code === 2) {
                rets = procTagInfo(countMap, rets, data.data);
            }
            callback(null, rets);
        });
    });
};

/**
 * 停止间歇盘点
 * @method stop
 * @exports index/stop
 */
export let stop = function() {
    isStop = true;
};

/**
 * 标签处理
 * @method procTagInfo
 * @param {Object} countMap 标签读取的次数
 * @param {Array} rets 盘点结果集
 * @param {Object} data 读取一次的内容
 */
function procTagInfo(countMap, rets, data) {
    let 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) {
    let className = null,
        ret = null;
    if (!data) {
        return null;
    }
    if (err) {
        throw err;
    }
    className = 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;
}