sandeepmistry / node-bleacon

A Node.js library for creating, discovering, and configuring iBeacons
MIT License
498 stars 88 forks source link

Estimote.writePowerLevel error (value is out of bounds) #43

Open mvenditto opened 8 years ago

mvenditto commented 8 years ago

Hello,

When i try to use Estimote.writePowerLevel passing a value other than 7 or 8 i get the following error:

...
function(callback) {
    var powerLevel = 4;
        estimote.writePowerLevel(powerLevel, function(error){
            console.log(error);
            callback();
        });
      },
...

buffer.js:969
    throw new TypeError('value is out of bounds');
    ^
TypeError: value is out of bounds
    at checkInt (buffer.js:969:11)
    at Buffer.writeUInt8 (buffer.js:1017:5)
    at NobleDevice.writeUInt8Characteristic (/home/vendo/node_modules/noble-device/lib/noble-device.js:189:10)
    at Estimote.writePowerLevel (/home/vendo/node_modules/bleacon/estimote/estimote.js:263:8)
    at /home/vendo/Code/write_pl_test.js:23:18
    at /home/vendo/node_modules/async/dist/async.js:3326:13
    at replenish (/home/vendo/node_modules/async/dist/async.js:808:21)
    at /home/vendo/node_modules/async/dist/async.js:814:29
    at /home/vendo/node_modules/async/dist/async.js:776:16
    at /home/vendo/node_modules/async/dist/async.js:3331:17

I noticed that power levels 7 and 8 are the only one mapped with >= 0 values and the error is thrown when triyng to write the value to buffer in writeUInt8Characteristic.

Estimote.prototype.writePowerLevel = function(powerLevel, callback) {
  if (powerLevel < 1) {
    powerLevel = 1;
  } else if (powerLevel > 8) {
    powerLevel = 8;
  }

  var POWER_LEVEL_MAPPER = {
    1: -30,
    2: -20,
    3: -16,
    4: -12,
    5:  -8,
    6:  -4,
    7:   0,
    8:   4
  };

  var rawLevel = POWER_LEVEL_MAPPER[powerLevel];

  this.writeUInt8Characteristic(ESTIMOTE_SERVICE_UUID, POWER_LEVEL_UUID, rawLevel, callback);
};
NobleDevice.prototype.writeUInt8Characteristic = function(serviceUuid, characteristicUuid, value, callback) {
  var buffer = new Buffer(1);
  buffer.writeUInt8(value, 0); 
  this.writeDataCharacteristic(serviceUuid, characteristicUuid, buffer, callback);
};

So i'm wondering if are negative values causing the problem (missing conversion?) or there is something wrong with my code ?

Thank you in advance.

sandeepmistry commented 8 years ago

@mvenditto

So i'm wondering if are negative values causing the problem (missing conversion?)

Yes, I think the following change is needed:

this.writeUInt8Characteristic(ESTIMOTE_SERVICE_UUID, POWER_LEVEL_UUID, rawLevel, callback);

should be:

this.writeInt8Characteristic(ESTIMOTE_SERVICE_UUID, POWER_LEVEL_UUID, rawLevel, callback);

It would be great if you could try this out and maybe submit a pull request.

dross94 commented 8 years ago

Hi,

I have experienced the same problem but i think another solution could be to leave the 'write' method unchanged

this.writeUInt8Characteristic(ESTIMOTE_SERVICE_UUID, POWER_LEVEL_UUID, rawLevel, callback);

and add a conversion in writePowerLevel function:

Estimote.prototype.writePowerLevel = function(powerLevel, callback) {
  if (powerLevel < 1) {
    powerLevel = 1;
  } else if (powerLevel > 8) {
    powerLevel = 8;
  }

  var POWER_LEVEL_MAPPER = {
    1: -30,
    2: -20,
    3: -16,
    4: -12,
    5:  -8,
    6:  -4,
    7:   0,
    8:   4
  };

  var rawLevel = POWER_LEVEL_MAPPER[powerLevel];

 var rawLevel = var rawLevel & 0xFF // ex. -12 --> 244

  this.writeUInt8Characteristic(ESTIMOTE_SERVICE_UUID, POWER_LEVEL_UUID, rawLevel, callback);
};
sandeepmistry commented 8 years ago

@dross94 that could also work.

I'd prefer to add/use writeInt8Characteristic to/from noble-device.