How do I use Meteor and a Cordova BLE plugin to connect to a BLE device

1.3k views Asked by At

I'm trying to use Meteor and this Cordova plugin -https://github.com/don/cordova-plugin-ble-central - added to my project using meteor add cordova in order to connect to a Bluetooth LE device (TI Sensortag). All I want to do to begin with is, when a link is clicked, to connect to the device and show a message.

I have the following code in the events section of my template javascript.

Template.measure.events({'click [data-action=scan-connect-stream]':
  function(event, template) {
    event.preventDefault();
    if (Meteor.isCordova) {
      Meteor.startup(function () {
          ble.connect('24:09:00:DE:00:42', 
                function(){
                    alert('Connect success');
                    return;
                }, 
                function(){
                    alert('Connect failed');
                    return;
                });
            });
        }
    }
});

My problem is that sometimes the code works and I get a 'Connect success' alert but more often than not it it fails to connect and shows the 'Connect failed' alert. Before I added the return statements in the success and fail callbacks it didn't work at all.

I'm debugging this on an android device (meteor run android-device --verbose) and can see via adb logcat that the BLE Connect event in the Cordova plugin is firing but then doesn't connect. I get the same issue debugging on two different phones and when using a BLE device that isn't a TI Sensortag so I'm guessing this is an problem with the way the plugin is interacting with Meteor (maybe Meteor isn't waiting long enough for a success callback?).

Has anyone used this plugin successfully with Meteor or can anyone provide any clue as to what I'm doing wrong? Should I try wrapping it in a Meteor package or is there any way I can give the plugin more time to respond before the success or fail callbacks fire? Any help would be much appreciated!

1

There are 1 answers

0
apeman On BEST ANSWER

For anyone who's having similar issues this is what sorted it for me. I put the ble.connect call into the success callback of the ble.scan function. Not sure why but scanning for a few seconds first does the job.

  Template.measure.events({
    'click [data-action=scan-connect-stream]': function(event, template) {
      event.preventDefault();
      if (Meteor.isCordova) {
        Meteor.startup(function () {
          device_id = '24:09:00:DE:00:42';
          ble.scan([], 5,
              function(peripherals){
                connectDevice(device_id);
              },
              function(){
                 alert('No devices found');
              }
            );
        });
      }
    }
  });


  var connectDevice = function (device_id) {
        ble.connect(device_id,
                        function(){
                          alert('Device ' + device_id + ' connnected');
                          },
                        function(){
                          alert('Couldn\'t connect to device ' + device_id);
                          });
  }

If anyone can explain why the ble.connect won't work on its own that'd be great!

EDIT: Looking at the Android code it seems that the plugin is designed in such a way that ble.scan has to be called before calling ble.connect. The ble.scan causes a LinkedHashMap in the Android code to be populated with any discovered devices. Only once the device is listed in the LinkedHashMap can you then connect to it using ble.connect.