randdusing / ng-cordova-bluetoothle

Angular 1.x wrapper for the PhoneGap/Cordova Bluetooth Low Energy Plugin
Other
47 stars 34 forks source link

read method misbehave when a response of bigger size has been received #35

Open nikolaof opened 5 years ago

nikolaof commented 5 years ago

Hi.

I'm trying to build an app using this library. More specifically, I want to call a specific function within a specified interval time. So to do this I'm using the following code:

vm.startExperimentLoop = function() {
       vm.myCall = $interval( loop, 5000);        
};

vm.apiStop = function(){
    $interval.cancel(vm.myCall);
}

function loop(){
    getTemp();
}

function getTemp(){
    return bleReadgetTemp()
    .then (function(response){
        response = atob(response.value);
        debugWrite("Response@getTemp: " + response + "\n");
        if(response.status){
            // Do nothing
        } else {
            // Stop the loop :p
        }
        return response;
    })
    .catch( function(error){
        console.log("getTemp");
    })
}

function bleReadgetTemp(){
    var service_id = '12ab';
    var characteristic_id = '31cd';

    var params = {
            address: $stateParams.address,
            service: service_id,
            characteristic: characteristic_id,
    };

    return $cordovaBluetoothLE.read(params);
} 

The bluetooth peripheral is running nodeJS with bleno library and on this specific read request returns an object like {"temp": 2455555555}. As long the value of temp attribute has 10 or less digits everything work as expected. If I put one more digit and make them 11 in total, the $interval function seems not to be work and sends read requests continuously to the peripheral.

Any idea why this could happen?

randdusing commented 5 years ago

Maybe it's hitting the max value for a 32 bit integer? 2,147,483,647

nikolaof commented 5 years ago

Is there any work-around? I also tried to send the {"temp":24, "status":"ok"} object and also did crash. If I remove the status attribute and left only the {"temp":24} it working again.

It seems weird not being able to send a more complicated object.

randdusing commented 5 years ago

You just need to send an array of bytes and let the client decode accordingly.

nikolaof commented 5 years ago

So could you give me an example? For example, If the nodeJS peripheral would have to send something like {"temp":24, "status":"ok"} how should I transform it into an array of bytes?

randdusing commented 5 years ago

Check out the example, but something like this. I can't really say unless the nodeJs peripheral is also using my plugin.

var obj = { temp: 25, status: 'ok' };
var bytes = bluetoothle.stringToBytes(JSON.stringify(obj));
nikolaof commented 5 years ago

Hmm.. Its seems weird because nodeJS is sending the response like this: var buffer = Buffer.from( JSON.stringify(res) ) Which is the same (I think) as the one you proposing.

randdusing commented 5 years ago

So on the receiving end, you need to do something like:

var bytes = bluetoothle.encodedStringToBytes(res);
var string = bluetoothle.bytesToString(bytes);
var obj = JSON.parse(string);
nikolaof commented 5 years ago

Mmm still not working and has the same behaviour. Also it triggers the .catch() part of the promise but without printing any particular message.

Here is my code:

function getTemp(){
        return bleReadgetTemp()
        .then (function(response){
                 var bytes = bluetoothle.encodedStringToBytes(response.value);
                 var string = bluetoothle.bytesToString(bytes);
                 var response = JSON.parse(string);

                  //response = JSON.parse(atob(response.value));
                  Log.add("[+] getTemp: " + JSON.stringify(response) );
                  var tempTimePoint = { time: Date.now() / 1000, y: response.temp };
                  // Push the temp value into rootScope vars.
                   $rootScope.experiment.actualTemp = [];
               $rootScope.experiment.actualTemp.push( tempTimePoint );
               $rootScope.experiment.historyTemp[0].values.push( tempTimePoint )

               Log.add("[+] TempBuffer: " + $rootScope.experiment.actualTemp[0] );
               return response;
        })
        .catch( function(error){
            Log.add('[!] getTemp Error' + JSON.stringify(error));
        })
    }

and what I'm getting is [!] getTemp Error {} .

randdusing commented 5 years ago

Unfortunately I can't really debug your code. It doesn't look related to the plugin or wrapper.