0

For a project im working on i want to make my hybrid app (phonegap) switch screens when the app detects the BluetoothLE signal from an Arduino. For this I made the code loop trough a couple of list items and check of the content of the li item is the same as "TEST123"(the name i gave the Arduino). If these would be the same, the app should switch to another page. I edited the code called "cordova-plugin-ble-central made by Don Coleman on GitHub) to reach this goal.

I made the code so it would scroll trough the li items within a ul, read the content and called the connect function if the string was the same as "TEST123", but my pages do not seem to switch.

Thanks for your help!

HTML:

    <body>
    <div class="app">

        <h1>BluefruitLE</h1>
        <div id="mainPage" class="show">

            <ul id="deviceList">                    
            </ul>
            <button id="refreshButton">Refresh</button>

        </div>

        <div id="detailPage" class="hide">

            <div id="resultDiv"></div>
            <div>
                <input type="text" id="messageInput" value="Hello"/>
                <button id="sendButton">Send</button>                    
            </div>
            <button id="disconnectButton">Disconnect</button>

        </div> 

    </div>


    <script type="text/javascript" src="cordova.js"></script>
    <script type="text/javascript" src="js/index.js"></script>
    <script type="text/javascript">
        app.initialize();
    </script>
</body>

CSS:

     body {
        font-family: "Helvetica Neue";
        font-weight: lighter;
        color: #2a2a2a;
        background-color: #f0f0ff;

        -webkit-appearance: none;  
        -webkit-touch-callout: none;
        -webkit-tap-highlight-color: rgba(0,0,0,0); 

        -webkit-touch-callout: none; -webkit-user-select: none;
    }

    button {
        margin: 15px;
        -webkit-appearance:none;    
        font-size: 1.2em;
    }

    #mainPage {
        text-align:center;
        width: 100vw;
        height: 100vh;
    }

    #detailPage {
        text-align:center;
        font-size: 2em;
        width: 100vw;
        height: 100vh;
        background-color: red;
    }

button {
    -webkit-appearance: none;
    font-size: 1.5em;
    border-radius: 0;
}

#resultDiv {
    font: 16px "Source Sans", helvetica, arial, sans-serif;
    font-weight: 200;
    display: block;
    -webkit-border-radius: 6px;
    width: 100%;
    height: 140px;
    text-align: left;    
    overflow: auto;
}

#mainPage.show{
    display: block;
}

#mainPage.hide{
    display: none;
}

#detailPage.show{
    display: block;
}

#detailPage.hide{
    display: none;
}

And ofcourse my JavaScript:

'use strict';

// ASCII only
function bytesToString(buffer) {
    return String.fromCharCode.apply(null, new Uint8Array(buffer));
}

// ASCII only
function stringToBytes(string) {
    var array = new Uint8Array(string.length);
    for (var i = 0, l = string.length; i < l; i++) {
        array[i] = string.charCodeAt(i);
    }
    return array.buffer;
}

// this is Nordic's UART service
var bluefruit = {
    serviceUUID: '6e400001-b5a3-f393-e0a9-e50e24dcca9e',
    txCharacteristic: '6e400002-b5a3-f393-e0a9-e50e24dcca9e', // transmit is from the phone's perspective
    rxCharacteristic: '6e400003-b5a3-f393-e0a9-e50e24dcca9e'  // receive is from the phone's perspective
};

var app = {
    initialize: function() {
        this.bindEvents();
        detailPage.hidden = true;
        //ale paginas hidden behalve login
    },

    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
        refreshButton.addEventListener('touchstart', this.refreshDeviceList, false);
        sendButton.addEventListener('click', this.sendData, false);
        disconnectButton.addEventListener('touchstart', this.disconnect, false);
        deviceList.addEventListener('touchstart', this.connect, false); // assume not scrolling
    },

    onDeviceReady: function() {
        app.refreshDeviceList();
    },

    refreshDeviceList: function() {
        deviceList.innerHTML = ''; // empties the list
        if (cordova.platformId === 'android') { // Android filtering is broken
            ble.scan([], 5, app.onDiscoverDevice, app.onError);
        } else {
            ble.scan([bluefruit.serviceUUID], 5, app.onDiscoverDevice, app.onError);
        }
    },

    onDiscoverDevice: function(device) {
        var listItem = document.createElement('li'),
            html = '<b>' + device.name + '</b><br/>' +
                'RSSI: ' + device.rssi + '&nbsp;|&nbsp;' +
                device.id;

        listItem.dataset.deviceId = device.id;
        listItem.innerHTML = html;
        deviceList.appendChild(listItem);
    },

    ulScroll: function() {
        var ul = document.getElementById("deviceList");
        var items = ul.getElementsByTagName("li");
            for (var i = 0; i < items.length; i++) {
                if ((items.textContent || items.innerText) == "TEST123"){

                            connect: function(e) {
        var deviceId = e.target.dataset.deviceId,
            onConnect = function(peripheral) {
                app.determineWriteType(peripheral);

                // subscribe for incoming data
                ble.startNotification(deviceId, bluefruit.serviceUUID, bluefruit.rxCharacteristic, app.onData, app.onError);
                sendButton.dataset.deviceId = deviceId;
                disconnectButton.dataset.deviceId = deviceId;
                resultDiv.innerHTML = "";
                app.showDetailPage();
            };

        ble.connect(deviceId, onConnect, app.onError);
    },

}


    }

}

    disconnect: function(event) {
        var deviceId = event.target.dataset.deviceId;
        ble.disconnect(deviceId, app.showMainPage, app.onError);
    },

    showMainPage: function() {
        document.getElementById("mainPage").className = "show";
        document.getElementById("detailPage").className = "hide";
    },

    showDetailPage: function() {
        document.getElementById("detailPage").className = "show";
        document.getElementById("mainPage").className = "hide";
    },

    onError: function(reason) {
        alert("ERROR: " + reason);
    }

};

P.S. Very sorry for the unorganized code

Wilrick B
  • 135
  • 8
  • what should connect:function(e) do inside a function?? Thats object syntax !! – Jonas Wilms Jan 02 '17 at 13:39
  • I'm relatively new to this, could you please explain what you mean? What i'm guessing is that i should call the function there and place the connect:function outside the function – Wilrick B Jan 02 '17 at 13:40
  • deviceList is undefined, and it makes no sense to me to write a functions output to html, and then parse it back from that. Thats against every logic... – Jonas Wilms Jan 02 '17 at 13:42
  • The whole structure makes no sense, may rewrite it from start, and learn proper js before writing copy+paste code... – Jonas Wilms Jan 02 '17 at 13:44
  • The writing a functions output to html is what we were thought in class, which seemed weird to me too. The deviceList is something i got from the code i edited from github. I couldnt see what it did and think of a solution to solve it – Wilrick B Jan 02 '17 at 13:46
  • ok i will rewrite your code, one last question: who should call ulScroll?? – Jonas Wilms Jan 02 '17 at 13:48
  • I instantly saw that that was a very big mistake. sorry, i shouldve seen that. After onDiscoverDevice the app should scroll trough the list to see if signal "TEST123" is present, – Wilrick B Jan 02 '17 at 13:51
  • You're a big help thank you very much! – Wilrick B Jan 02 '17 at 13:51

1 Answers1

0

How i would structure the code:

var app={
  devices:[], //thats were the devices are stored
  onDeviceReady:refreshDeviceList,

  refreshDeviceList: function() {
     deviceList.innerHTML = ''; // empties the list
     this.devices=[];
     if (cordova.platformId === 'android') { // Android filtering is broken
          ble.scan([], 5, app.onDiscoverDevice, app.onError);
     } else {
         ble.scan([bluefruit.serviceUUID], 5, app.onDiscoverDevice, app.onError);
     }
     //all devices checked, lets search ours:
     var my=this.devices.find(device => { device.name=="TEST123"});
     if(my){
          ble.connect(my.id,app.onconnect,errorhandling);
     }else{
        alert("my device not found");
    }
   },


   onDiscoverDevice: function(device) {
   //add to html
    var listItem = document.createElement('li'),
        html = '<b>' + device.name + '</b><br/>' +
            'RSSI: ' + device.rssi + '&nbsp;|&nbsp;' +
            device.id;
    listItem.innerHTML = html;
    deviceList.appendChild(listItem);
   //add to devices:
  this.devices.push(device);
   },
   onconnect:function(e){
      //your connect function
   }
  }

Additional notes:

  refreshButton etc are undefined. You need to find them:
 var refreshButton=document.getElementById("refreshButton");
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • I'm getting rid of the refreshbuttons etc. because i want the switch to take place when the signal is found. i see the restructuring and thanks for that! I'm going to check if the code works this way, and when i fix the mistakes that are currently in my code. – Wilrick B Jan 02 '17 at 14:26
  • I'm guessing the onconnect function should contain the app.showDetailPage(); but this does not seem to work. I also tried the connect part of the code but this doesnt seem to work either. I see that you already used ble.connect which triggers the onconnect function, is this right? Because if thats true i think that app.ShowDetailPage (); should suffice. – Wilrick B Jan 02 '17 at 15:09
  • yep exactly, thats true – Jonas Wilms Jan 02 '17 at 15:17
  • And am i right if im thinking your newly structured code covers the old code from refreshdevicelist till the disconnect function? because if thats true i think i mightve made another mistake because of which the screens dont switch – Wilrick B Jan 02 '17 at 15:21
  • my code just covers the device refreshing/connecting stuff wich was completely wrong in your code – Jonas Wilms Jan 02 '17 at 15:41