lib/zpiObject.js
function ZpiObject(subsys, cmd, args) { // args is optional, and can be an array or a value-object if given
    var subsystem = zmeta.Subsys.get(subsys),
        command,
        reqParams;

    this.type = undefined;      // string after assgined
    this.subsys = undefined;    // string after assigned
    this.cmd = undefined;       // string after assigned
    this.cmdId = undefined;     // number after assigned
    this.args = undefined;      // array after assigned: [ { name, type, value }, ... ]

    if (!subsystem)
        throw new Error('Unrecognized subsystem');

    this.subsys = subsystem.key;
    command = zmeta[this.subsys].get(cmd);

    if (!command)
        throw new Error('Unrecognized command');

    this.cmd = command.key;
    this.cmdId = command.value;

    this.type = zmeta.getType(this.subsys, this.cmd);

    if (!this.type)
        throw new Error('Unrecognized type');

    // if args is given, this is for REQ transmission
    // otherwise, maybe just for parsing RSP packet
    if (args)
        reqParams = zmeta.getReqParams(this.subsys, this.cmd);    // [ { name, type }, ... ]

    if (reqParams) {
        if (Array.isArray(args)) {
            // arg: { name, type } -> { name, type, value }
            reqParams.forEach(function (arg, idx) {
                arg.value = args[idx];
            });
        } else if (typeof args === 'object') {
            reqParams.forEach(function (arg, idx) {
                if (!args.hasOwnProperty(arg.name))
                    throw new Error('The argument object has incorrect properties');
                else
                    arg.value = args[arg.name];
            });
        }

        this.args = reqParams;              // [ { name, type, value }, ... ]
    }
}
function ZpiObject(subsys, cmd, args) { // args is optional, and can be an array or a value-object if given
    var subsystem = zmeta.Subsys.get(subsys),
        command,
        reqParams;

    this.type = undefined;      // string after assgined
    this.subsys = undefined;    // string after assigned
    this.cmd = undefined;       // string after assigned
    this.cmdId = undefined;     // number after assigned
    this.args = undefined;      // array after assigned: [ { name, type, value }, ... ]

    if (!subsystem)
        throw new Error('Unrecognized subsystem');

    this.subsys = subsystem.key;
    command = zmeta[this.subsys].get(cmd);

    if (!command)
        throw new Error('Unrecognized command');

    this.cmd = command.key;
    this.cmdId = command.value;

    this.type = zmeta.getType(this.subsys, this.cmd);

    if (!this.type)
        throw new Error('Unrecognized type');

    // if args is given, this is for REQ transmission
    // otherwise, maybe just for parsing RSP packet
    if (args)
        reqParams = zmeta.getReqParams(this.subsys, this.cmd);    // [ { name, type }, ... ]

    if (reqParams) {
        if (Array.isArray(args)) {
            // arg: { name, type } -> { name, type, value }
            reqParams.forEach(function (arg, idx) {
                arg.value = args[idx];
            });
        } else if (typeof args === 'object') {
            reqParams.forEach(function (arg, idx) {
                if (!args.hasOwnProperty(arg.name))
                    throw new Error('The argument object has incorrect properties');
                else
                    arg.value = args[arg.name];
            });
        }

        this.args = reqParams;              // [ { name, type, value }, ... ]
    }
}
********************************************************************************************** * ZpiObject Class                                                                           ** *   1. Provides command framer (SREQ)                                                       ** *   2. Provides parser (SRSP, AREQ)                                                         ** **********************************************************************************************