Example #1
0
Orvibo.prototype.prepareMessage = function(commandID, macAddress, macPadding, data, callback) {
  var args = Args([{
    commandID: Args.STRING | Args.Required
  }, {
    macAddress: Args.STRING | Args.Optional,
    _default: ""
  }, {
    macPadding: Args.STRING | Args.Optional,
    _default: options.macPadding
  }, {
    data: Args.OBJECT | Args.Optional,
    _default: {}
  }, {
    callback: Args.FUNCTION | Args.Optional
  }], arguments);

  var packet, len
  var dataStr = ""

  // Go through all of data's properties and merges the values into a single string
  for (key in args.data) {
    dataStr += args.data[key]
  }

  // We need to define packet twice, because we can't determine the length of the string as we're building it.
  // So we build the string, count the length, then redefine the string, with the length we stored earlier.
  packet = options.magicWord + "0000" + args.commandID + args.macAddress + args.macPadding + dataStr
  packet = options.magicWord + _.padLeft((packet.length / 2).toString(16).toLowerCase(), 4, "0") + args.commandID + args.macAddress + args.macPadding + dataStr

  if (typeof args.callback !== "undefined") {
    args.callback(message)
  }
  return packet
}
Example #2
0
Orvibo.prototype.switchEndian = function(data) {
  var args = Args([{
    data: Args.STRING | Args.Required
  }], arguments);

  return _.flatten(_.chunk(args.data, 2).reverse()).join("")
}
Example #3
0
function parallel() {
    const args = Args([
        {arr: Args.ARRAY | Args.Required},
        {func: Args.FUNCTION | Args.Optional},
        {callback: Args.FUNCTION | Args.Required}
    ], arguments);
    const arrLength = args.arr.length;
    let results = {length: arrLength};
    if (arrLength === 0) {
        args.callback(null, []);
    } else if (args.func) {
        args.arr.forEach(function (value, index) {
            args.func(value, parallelCallback(index));
        });
    } else {
        args.arr.forEach(function (func, index) {
            func(parallelCallback(index));
        });
    }


    function parallelCallback(index) {
        return function (error, data) {
            if (error) {
                args.callback(error, []);
            } else {
                results[String(index)] = data;
                if (Object.keys(results).length - 1 === results.length) {
                    args.callback(error, Array.from(results, (v, k) => v));
                }
            }
        };
    }
}
Example #4
0
exports.forArgs = function(args) {
  return Args([
    {conditions: Args.OBJECT},
    {generator: Args.STRING | Args.Optional, _default: 'predicate'},
    {placeholderOffset: Args.INT | Args.Optional, _default: 0}
  ], args);
};
Example #5
0
exports.glob = function(patterns, globOptions, outputDir, options, callback, updateCallback, removeCallback) {

  args = Args([
    { patterns:  Args.ANY | Args.Required },
    { globOptions: Args.ANY | Args.Required },
    { outputDir: Args.STRING | Args.Required },
    { options: Args.OBJECT | Args.Optional, _default: {} },
    { callback: Args.FUNCTION | Args.Optional, _default: function() {} },
    { updateCallback: Args.FUNCTION | Args.Optional, _default: function() {} },
    { removeCallback: Args.FUNCTION | Args.Optional, _default: function() {} }
  ], arguments)

  var patterns = args.patterns,
      globOptions = args.globOptions,
      outputDir = args.outputDir,
      options = args.options,
      callback = args.callback,
      updateCallback = args.updateCallback,
      removeCallback = args.removeCallback;

  mirrorGlob(patterns, globOptions, outputDir, function(inputFile, outputFile, extraFiles, cb) {

    var fileFunOptions = _.omit(options, [ 'sourceMapDir', 'watch', 'extension' ]);
    fileFunOptions.sourceMap = extraFiles.sourceMap;

    exports.file(inputFile, outputFile, fileFunOptions, cb);
  }, { extension: 'css', sourceMapDir: options.sourceMapDir, watch: options.watch }, callback, updateCallback, removeCallback);
}
Example #6
0
Orvibo.prototype.enterLearningMode = function(device) {
  var args = Args([{
    device: Args.OBJECT | Args.Optional
  }, {
    callback: Args.FUNCTION | Args.Optional
  }], arguments);

  if (typeof args.device === "undefined") {
    debug("Putting all AllOnes into learning mode")
    this.devices.forEach(function(item) {
      if (item.type != "AllOne") {
        return
      }
      this.enterLearningMode(item)
    }.bind(this))
  } else {
    if (args.device.type != "AllOne") {
      return
    }
    message = this.prepareMessage({
      commandID: "6c73",
      macAddress: args.device.macAddress,
      macPadding: args.device.macPadding,
      data: {
        // Not sure what this data is for. I don't know what half of the data does, frankly!
        other: "010000000000"
      }
    })
    this.sendMessage(message, args.device.ip)
    this.emit("learningmode", device)
    if (typeof args.callback !== "undefined") {
      args.callback(device)
    }
  }
}
Example #7
0
Orvibo.prototype.updateTimer = function(device, date, index, state, repeat) {
  var args = Args([{
    device: Args.OBJECT | Args.Required
  }, {
    date: Args.DATE | Args.Required
  }, {
    index: Args.INT | Args.Optional,
    _default: -1
  }, {
    state: Args.BOOLEAN | Args.Optional, // Should this be required instead? What about AllOne?
    _default: false
  }, {
    repeat: Args.STRING | Args.Optional,
    _default: "ff"
  }, {
    callback: Args.FUNCTION | Args.Optional
  }], arguments);

  this.addTimer({
    device: args.device,
    date: args.date,
    index: args.index,
    state: args.state,
    update: true,
    repeat: args.repeat,
  })
}
Example #8
0
Orvibo.prototype.modifyRemotePassword = function(device, oldpassword, newpassword) {
  var args = Args([{
    device: Args.OBJECT | Args.Required
  }, {
    oldpassword: Args.STRING | Args.Optional,
    _check: function(ssid) {
      return ssid.length <= 12
    },
    _default: "888888"
  }, {
    newpassword: Args.STRING | Args.Optional,
    _default: "",
    _check: function(password) {
      return password.length <= 12
    }
  }, {
    callback: Args.FUNCTION | Args.Optional
  }], arguments);

  message = this.prepareMessage({
    macAddress: args.device.macAddress,
    macPadding: args.device.macPadding,
    commandID: "6d70",
    data: {
      unknown: "78ed40",
      recordlength: "0c",
      oldpassword: hex.hex(_.padRight(args.oldpassword, 12, " ")),
      newpassword: hex.hex(_.padRight(args.newpassword, 12, " "))
    }
  })

  this.sendMessage(message, args.device.ip)
}
Example #9
0
Orvibo.prototype.query = function(device, table, callback) {
  var args = Args([{
    device: Args.OBJECT | Args.Optional
  }, {
    table: Args.STRING | Args.Optional,
    _default: "04"
  }, {
    callback: Args.FUNCTION | Args.Optional
  }], arguments);

  if (typeof args.device === "undefined") {
    debug("Subscribing to all devices")
    this.devices.forEach(function(item) {
      this.query(item)
    }.bind(this))
  } else {
    message = this.prepareMessage({
      commandID: "7274",
      macAddress: args.device.macAddress,
      macPadding: args.device.macPadding,
      data: {
        blank: "00000000",
        // There are two tables we're interested in,
        // Table 04 is neat info about the device, Table 03
        // is timing data (e.g. turn socket on at 8pm etc.)
        table: args.table,
        blank2: "000000000000"
      }
    })
    this.sendMessage(message, args.device.ip)
  }
  if (typeof args.callback !== "undefined") {
    args.callback(args.device, args.table)
  }
}
Example #10
0
Orvibo.prototype.discover = function(device, callback) {
  // args-js handles optional and required arguments, along with default values.
  // We use it here to determine if we need to append a MAC address to the discover packet
  var args = Args([{
    device: Args.OBJECT | Args.Optional,
    _default: {
      macAddress: "",
      macPadding: ""
    }
  }, {
    callback: Args.FUNCTION | Args.Optional
  }], arguments);

  // prepareMessage is a helper function that puts together various info into
  // a ready-to-send packet. See the function definition further down for specifics
  message = this.prepareMessage({
    commandID: "7161",
    macAddress: args.device.macAddress,
    macPadding: args.device.macPadding,
  })

  debug("Discovery packet sent")
    // Tell any listeners that we've sent a discovery message
  this.emit("discoverysent", args.device)
  this.sendMessage(message, options.broadcastIP)

  if (typeof args.callback !== "undefined") {
    args.callback(args.device)
  }
}
Example #11
0
exports.findArgs = function(args){
  return Args([
    {conditions : Args.ANY | Args.Optional, _default : {}},
    {options : Args.OBJECT | Args.Optional, _default : {}},
    {next : Args.FUNCTION | Args.Optional, _default : function(err,res){
      if(err) console.log(err)
      else console.log(res)
    }}
  ], args);
}
Example #12
0
Orvibo.prototype.addTimer = function(device, date, index, state, update, repeat) {
  var args = Args([{
    device: Args.OBJECT | Args.Required
  }, {
    date: Args.DATE | Args.Required
  }, {
    index: Args.INT | Args.Optional,
    _default: -1
  }, {
    state: Args.BOOLEAN | Args.Optional, // Should this be required instead? What about AllOne?
    _default: false
  }, {
    update: Args.BOOLEAN | Args.Optional, // Should this be required instead? What about AllOne?
    _default: false
  }, {
    repeat: Args.STRING | Args.Optional,
    _default: "ff"
  }, {
    callback: Args.FUNCTION | Args.Optional
  }], arguments);

  if (args.index == -1) {
    args.index = args.device.timers.length + 1
  }

  args.date = moment(args.date)

  if (args.device.type == "Socket") {
    message = this.prepareMessage({
      macAddress: args.device.macAddress,
      macPadding: args.device.macPadding,
      commandID: "746d",
      data: {
        blank: "00000000",
        table: "03",
        command: args.update ? "0001" : "0000", // 0000 = Create, 0001 = Update, 0002 = Delete
        unknown: "1c00",
        index: this.switchEndian(_.padLeft(args.index, 4, "0")),
        name: "6e756c6c202020202020202020202020", // null + padding. For an AllOne, I suspect this would be the name of an IR command or something?
        state: args.state ? "0100" : "0000",
        year: this.switchEndian(_.padLeft(args.date.year().toString(16), 4, "0")),
        month: this.switchEndian(_.padLeft((args.date.month() + 1).toString(16), 2, "0")),
        day: this.switchEndian(_.padLeft((args.date.day() + 1).toString(16), 2, "0")),
        hour: this.switchEndian(_.padLeft((args.date.hour() + 1).toString(16), 2, "0")),
        minute: this.switchEndian(_.padLeft((args.date.minute() + 1).toString(16), 2, "0")),
        second: this.switchEndian(_.padLeft((args.date.second() + 1).toString(16), 2, "0")),
        repeat: args.repeat
      }
    })

    this.sendMessage(message, args.device.ip)
  } else {
    debug("NOT SOCKET")
  }
}
Example #13
0
exports.whereArgs = function(args){
  var args = Args([
    {where : Args.STRING | Args.Optional, _default : "1=1"},
    {params : Args.ANY | Args.Optional, _default : []},
    {next : Args.FUNCTION | Args.Optional, _default : function(err,res){
      if(err) console.log(err)
      else console.log(res)
    }}
  ], args);
  if(!_.isArray(args.params)) args.params = [args.params];

  return args;
}
Example #14
0
exports.queryArgs = function(args){
  var args = Args([
    {sql : Args.STRING | Args.Required},
    {params : Args.ARRAY | Args.Optional, _default : []},
    {options : Args.OBJECT | Args.Optional, _default : {single : false}},
    {next : Args.FUNCTION | Args.Optional, _default : function(err,res){
      if(err) console.log(err);
      else console.log(res);
    }}
  ], args);
  if(!_.isArray(args.params)) args.params = [args.params];
  return args;
}
Example #15
0
Orvibo.prototype.getDevice = function(macAddress, callback) {
  var args = Args([{
    macAddress: Args.STRING | Args.Required
  }], arguments);

  var device = _.where(this.devices, {
    macAddress: args.macAddress
  })[0]

  if (typeof callback !== "undefined") {
    args.callback(device)
  }
  return device
}
Example #16
0
exports.searchArgs = function(args, source){
  args = Args([
    {fields : Args.OBJECT | Args.Optional, _default: {}},
    {options: Args.OBJECT | Args.Optional, _default: {}},
    {next : Args.FUNCTION | Args.Optional, _default: function(err, res){
      if(err) console.log(err);
      else console.log(res);
    }}
  ], args);

  args.options = new QueryOptions(args.options, source);

  return args;
};
Example #17
0
  self.parseResource = function(str) {
    args = Args([
      {str:       Args.STRING | Args.Required},
    ], arguments);

    var match = str.match('(.+) '+self.keyword+' (.+)');
    if(match === null) {
      throw new Error('Invalid resource specification expected format: "<url> '+self.keyword+' <variable>"');
    }

    return {
      url: match[1],
      variable: match[2]
    };
  };
Example #18
0
  self.pipe = function pipe() {
    var args = arg([
      {target:        arg.OBJECT | arg.FUNCTION | arg.Required},
    ], arguments);

    var p = _stream.promise;
    p.then(function(source){
      if(typeof args.target === 'function') {
        return args.target(source);
      } 

      return source.pipe(args.target);
    });

    return p;
  };
 schema.statics.findOneOrCreate = function findOneOrCreate() {
     var self = this;
     var args = Args([
         {cond:     Args.OBJECT     | Args.Required},
         {doc:      Args.OBJECT     | Args.Optional},
         {callback: Args.FUNCTION   | Args.Optional}
     ], arguments);
     return self.findOne(args.cond, function(err, result) {
         if (result) {
             args.callback(err, result);
         } 
         else {
             self.create(args.doc || args.cond, args.callback);
         }
     });
 };
Example #20
0
Orvibo.prototype.hexToInt = function(data, switchendian) {
  var args = Args([{
    data: Args.STRING | Args.Required
  }, {
    switchendian: Args.BOOLEAN | Args.Optional,
    _default: true
  }], arguments);

  if (args.switchendian) {
    args.data = this.switchEndian({
      data: args.data
    })
  }

  return parseInt(args.data, 16)
}
Example #21
0
exports.findArgs = function(args, source) {
  args = Args([
    {conditions : Args.ANY | Args.Optional, _default : {}},
    {options : Args.OBJECT | Args.Optional, _default: {}},
    {next : Args.FUNCTION | Args.Optional, _default : function(err,res){
      if(err) console.log(err);
      else console.log(res);
    }}
  ], args);

  if (_.isFunction(args.conditions)) {
    //this is our callback as the only argument, caught by Args.ANY
    args.next = args.conditions;
  }

  args.options = new QueryOptions(args.options, source);

  return args;
};
Example #22
0
function FeignRequestClient(){
  var args  = Args([
      { defaults: Args.OBJECT | Args.Optional},
      { debug: Args.BOOL | Args.Optional, _default: false},
      { json:  Args.BOOL | Args.Optional, _default: true}
    ], arguments);

  this.requestFn = request;
  this.requestFn.debug = args.debug;
  if (args.defaults){
    this.requestFn = this.requestFn.defaults(args.defaults);
  }
  
  this.isJson = args.json;
  if (args.json){
    this.requestFn = this.requestFn.defaults({json: true});
  }
  
}
Example #23
0
FeignRequestClient.prototype._createRequestJsOptions = function(baseUrl, requestOptions, parameters){
  var options  = Args([
      { method: Args.STRING | Args.Optional, _default: 'GET' },
      { uri: Args.STRING | Args.Required}
    ], [requestOptions]);


  if (options.method == 'GET'){
    options.qs = parameters;
  } else if (this.isJson) {
    if (parameters != null)
      options.body = parameters;
  } else {
    options.form = parameters;
  }

  options.baseUrl = baseUrl;
  return options;
}
Example #24
0
Orvibo.prototype.updateDevice = function(device, table, data) {
  var args = Args([{
    device: Args.OBJECT | Args.Required
  }, {
    table: Args.STRING | Args.Optional,
    _default: "04"
  }, {
    data: Args.STRING | Args.Required,
  }, {
    callback: Args.FUNCTION | Args.Optional
  }], arguments);

  // 00000000 04 00018a0001004325accfdeadbeef202020202020efbeaddecfac202020202020383838383838202020202020446561646c7920426565662020202020040010000000090000000500000010272a796fd01027766963656e7465722e6f727669626f2e636f6d20202020202020202020202020202020202020202019001600002c0a80101ffffff000100000a00000
  this.prepareMessage({
    macAddress: args.device.macAddress,
    macPadding: args.device.macPadding,
    commandID: "746d",
    blank: "00000000",
    table: args.table || "04"
  })
}
Example #25
0
Orvibo.prototype.extractRecords = function(data, lengthcount, littleendian) {
  var args = Args([{
    data: Args.STRING | Args.Required
  }, {
    lengthcount: Args.INT | Args.Optional,
    _default: 2
  }, {
    littleendian: Args.BOOLEAN | Args.Optional,
    _default: true
  }], arguments);

  var res = []
  debug("Extracting records from %s", data)
    // Only interested in looping while we have data
  while (args.data != "") {
    debug("Data left: %s", data)
    if (args.littleendian) {
      num = parseInt(_.flatten(_.chunk(args.data.substr(0, args.lengthcount * 2), 2).reverse()).join(""), 16) * 2
    } else {
      num = parseInt(args.data.substr(0, args.lengthcount * 2), 16) * 2
    }
    // Get the first two bytes and make it into a number. Spin it all around because these numbers are little endian

    // If the number of bytes to get (factoring in 2 bytes for the length) is less than our remaining data,
    if (num + args.lengthcount * 2 <= args.data.length) {
      debug("Pushing %s to the array", args.data.substr(args.lengthcount * 2, num))
        // Shove it onto our array
      res.push(args.data.substr(args.lengthcount * 2, num))
        // And reset `data` to be the data, less our already-extracted record
      args.data = args.data.substr(num + args.lengthcount * 2)
    } else {
      // If we've got more bytes to grab than there is available, stop
      args.data = ""
    }
  }
  // Return what we've got.
  debug("Extracted %d records", res.length)
  return res
}
Example #26
0
Orvibo.prototype.deleteTimer = function(device, index) {
  var args = Args([{
    device: Args.OBJECT | Args.Required
  }, {
    index: Args.INT | Args.Optional,
    _default: -1
  }, {
    callback: Args.FUNCTION | Args.Optional
  }], arguments);

  this.prepareMessage({
    macAddress: args.device.macAddress,
    macPadding: args.device.macPadding,
    commandID: "746d",
    data: {
      extra: "0000000003",
      command: "0002",
      index: this.switchEndian(_.padLeft(args.index, 4, "0")),
    }
  })
  this.sendMessage(message, args.device.ip)
}
Example #27
0
Orvibo.prototype.setState = function(device, state, callback) {
  var args = Args([{
    device: Args.OBJECT | Args.Required
  }, {
    state: Args.BOOL | Args.Required
  }, {
    callback: Args.FUNCTION | Args.Optional
  }], arguments);

  if (args.device.type != "Socket") {
    return
  }

  // Sets our device's state property to our new value.
  args.device.state = args.state

  message = this.prepareMessage({
    commandID: "6463",
    macAddress: args.device.macAddress,
    macPadding: args.device.macPadding,
    data: {
      // Session ID?
      blank: "00000000",
      // Ternary operators are cool, but hard to read.
      // This one says "if state is true, set state to 01, otherwise, set to 00"
      state: args.state ? "01" : "00"
    }
  })

  // This is a misnomer. addDevice also updates devices if they exist
  this.addDevice(args.device)

  this.emit("setstate", args.device, args.state)
  this.sendMessage(message, args.device.ip)
  if (typeof args.callback !== "undefined") {
    args.callback(args.device, args.state)
  }
}
Example #28
0
Orvibo.prototype.sendMessage = function(message, address, port, sock, callback) {
  var args = Args([{
    message: Args.STRING | Args.Required
  }, {
    address: Args.STRING | Args.Required
  }, {
    sock: Args.OBJECT | Args.Optional,
    _default: socket
  }, {
    port: Args.INT | Args.Optional,
    _default: options.port
  }], arguments);

  args.message = new Buffer(args.message.toLowerCase(), "hex"); // We need to send as a buffer. this line takes our message and makes it into one.
  args.sock.send(args.message, 0, args.message.length, args.port, args.address, function(err, bytes) { // Send the message. Parameter 2 is offset, so it's 0.
    if (err) throw err; // Error? CRASH AND BURN BB!
    debug("Message sent to %s:%s with length %d", args.address, args.port, args.message.length)
    this.emit("messageSent", args.message, args.address, args.sock.address().address, args.sock); // Tell the world we've sent a packet. Include message, who it's being sent to, plus the address it's being sent from
  }.bind(this)); // Again, we do .bind(this) so calling this.emit(); comes from OrviboAllOne, and not from scktClient
  if (typeof callback !== "undefined") {
    args.callback(message, address, port)
  }
}
Example #29
0
Orvibo.prototype.subscribe = function(device, callback) {
  var args = Args([{
    device: Args.OBJECT | Args.Optional,
  }, {
    callback: Args.FUNCTION | Args.Optional
  }], arguments);

  if (typeof args.device === "undefined") {
    debug("Subscribing to all devices")
    this.devices.forEach(function(item) {
      this.subscribe(item)
    }.bind(this))
  } else {
    debug("Subscribing to", device.macAddress)
      // prepareMessage is used a little differently here.
      // anything within "data" is flattened into a single string (so order matters!)
      // "macReversed" could be called "jslkdf" -- it doesn't matter in the end
    message = this.prepareMessage({
      commandID: "636c",
      macAddress: args.device.macAddress,
      macPadding: args.device.macPadding,
      data: {
        // This takes a MAC address, splits it up into chunks of 2 (so [A, C], [C, F] etc.)
        // then reverses the chunks (so it becomes [C, F], [A, C]), flattens the array,
        // then finally joins it together as one long string. Phew!
        macReversed: this.switchEndian(args.device.macAddress),
        macPadding: args.device.macPadding
      }
    })

    this.sendMessage(message, device.ip)
  }

  if (typeof args.callback !== "undefined") {
    args.callback(args.device)
  }
}
Example #30
0
Orvibo.prototype.emitRF = function(device, sessionID, state, rfkey, rfid, callback) {
  var args = Args([{
    device: Args.OBJECT | Args.Required
  }, {
    sessionID: Args.STRING | Args.Optional,
    _default: "00000000"
  }, {
    state: Args.BOOL | Args.Required
  }, {
    rfkey: Args.STRING | Args.Optional,
    _default: "2a00"
  }, {
    rfid: Args.STRING | Args.Required
  }, {
    callback: Args.FUNCTION | Args.Optional
  }], arguments);

  message = this.prepareMessage({
    commandID: "6463",
    macAddress: args.device.macAddress,
    macPadding: args.device.macPadding,
    data: {
      sessionID: args.sessionID,
      randomA: _.padLeft(Math.floor((Math.random() * 255)).toString(16), 2, "0"),
      randomB: _.padLeft(Math.floor((Math.random() * 255)).toString(16), 2, "0"),
      state: args.state ? "01" : "00",
      rfkey: args.rfkey,
      rfid: args.rfid
    }
  })
  this.sendMessage(message, args.device.ip)
  this.emit("rfemitted", args.device, args.sessionID, args.state, args.rfkey, args.rfid)
  if (typeof args.callback !== "undefined") {
    args.callback(args.device, args.sessionID, args.state, args.rfkey, args.rfid)
  }
}