BCSphere入門教程05:標準Profile與自定義Profile

李治發表於2014-07-26

在第0章導言和知識儲備中,我們提到了Profile的概念。一個Profile可以理解為一個硬體的操作標準,也可以類比為硬體的“驅動”或者SDK,它其中可以包括多個Service。本章先介紹如何使用BCSphere提供的標準Profile,再通過剖析標準Profile的寫法來介紹如何使用自定義的Profile讓您的智慧硬體應用程式碼結構更加清晰。

硬體最小支援

Service: Immediate Alert
UUID: 00001802-0000-1000-8000-00805f9b34fb

Characteristic: Immediate Alert
UUID: 00002a26-0000-1000-8000-00805f9b34fb
Property: Write || WriteWithoutResponse
Function: 寫入Hex值0,裝置停止發出聲音;寫入Hex值1,裝置發出聲音;


使用標準Profile

Find Me Profile是Bluetooth4.0中定義的標準Pofile,可以通過讓裝置發出聲音來尋找到裝置,其中只包含一個Service:Immediate Alert Service。通過引用BCSphere提供的標準Profile模組,可以大大簡化標準應用的開發量,並讓智慧硬體功能標準化。使用如下程式碼在index.html中引入一個標準Profile(注意引入順序):

    <script type="text/javascript" src="http://115.29.149.19:3000/framework/org.underscorejs.underscore/underscore.js"></script>
    <script type="text/javascript" src="http://115.29.149.19:3000/framework/org.bcsphere.bluetooth/bluetoothapi.js"></script>
    <script type="text/javascript" src="http://115.29.149.19:3000/framework/org.bcsphere/bc.js"></script>
    <script type="text/javascript" src="http://115.29.149.19:3000/framework/org.bluetooth.service/immediate_alert.js"></script>
    <script type="text/javascript" src="http://115.29.149.19:3000/framework/org.bluetooth.profile/find_me.js"></script>

deviceready事件中引入find_me的模組,並例項化findmeProfile物件,在bcready事件中新建並連線在BCSphere掃描頁面選取的裝置物件:

    var findmeProfile = {};
    var device = {};
    document.addEventListener('deviceready',function(){
        var BC = window.BC = cordova.require("org.bcsphere.bcjs");
        var BC = window.BC = cordova.require("org.bluetooth.profile.find_me");
        findmeProfile = new BC.FindMeProfile();
    },false);

    document.addEventListener('bcready', function(){
        device = new BC.Device({deviceAddress:DEVICEADDRESS,type:DEVICETYPE});
        device.connect();
    }, false);

最後就可以在頁面上繫結一個事件,讓他呼叫如下的函式來讓裝置發出聲音了:

    function findme(){
        findmeProfile.high_alert(app.device);
    }

可以看到,Profile中實現了掃描標準Immediate Alert服務,並向指定的特徵值中寫入了資料。下面就讓來看看Find Me Profile中的程式碼到底做了什麼。

Profile的基本結構

通過最簡單的Find Me Profile的完整例項來解釋一下如何編寫一個自定義的Profile:

//在deviceready事件後才可以安全使用cordova介面
document.addEventListener('deviceready',function(){

    //定義了一個id為"org.bluetooth.profile.find_me"的模組
    cordova.define("org.bluetooth.profile.find_me", function(require, exports, module) {

        //引入需要的Service
        var BC = require("org.bluetooth.service.immediate_alert");

        //指定所操作的Service的UUID
        var serviceUUID = "1802";

        //繼承BC.Profile物件,並實現對應的介面
        var FindMeProfile = BC.FindMeProfile = BC.Profile.extend({

            no_alert : function(device){
              this.alert(device,'0');
            },

            mild_alert : function(device){
              this.alert(device,'1');
            },

            high_alert : function(device){
              this.alert(device,'2');
            },

            alert : function(device,level){
                //需要首先查詢該裝置的Service,如果device.services存在,不會重複查詢
                device.discoverServices(function(){

                    //通過serviceUUID來獲取傳入device中的指定強型別的Service
                    var service = device.getServiceByUUID(serviceUUID)[0];

                    //呼叫強型別的Immediate Alert Service物件中封裝的介面
                    service.alert(level);
                });
            },

        });

        //匯出附加了FindMeProfile的BC物件
        module.exports = BC;

    });

},false);

Service的基本結構

通過Immediate Alert的基本結構來解釋如何編寫一個自定義的Service:

document.addEventListener('deviceready',function(){
    cordova.define("org.bluetooth.service.immediate_alert", function(require, exports, module) {            
        //基於bc.js模組進行實現
        var BC = require("org.bcsphere.bcjs");

        //繼承BC.Service類
        var ImmediateAlertService = BC.ImmediateAlertService = BC.Service.extend({

               //所包含的特徵值UUID
               characteristicUUID:'2a06',

               no_alert : function(){
                  this.alert('0');
               },

               mild_alert : function(){
                  this.alert('1');
               },

               high_alert : function(){
                  this.alert('2');
               },

               alert:function(writeValue,writeType,successFunc,errorFunc){
                  successFunc = successFunc || this.writeSuccess;
                  errorFunc = errorFunc || this.writeError;
                  writeType = writeType || 'hex';

                  //在查詢到特徵值列表之後對特定的特徵值進行操作
                  this.discoverCharacteristics(function(){
                        this.getCharacteristicByUUID(this.characteristicUUID)[0].write(writeType,writeValue,successFunc,errorFunc);
                  });
               },

               writeSuccess : function(){
                  console.log('writeSuccess');
               },

               writeError : function(){
                  console.log('writeFailed');
               },

        });

        //將ImmediateAlertService類註冊到BC.bluetooth的Service載入表中
        //如此寫入後,當device呼叫discoverService介面的時候,會根據UUID載入對應的強型別Service
        document.addEventListener('bccoreready',function(){
            BC.bluetooth.UUIDMap["00001802-0000-1000-8000-00805f9b34fb"] = BC.ImmediateAlertService;
        });

        //匯出附加了ImmediateAlertService的BC物件
        module.exports = BC;
    });
},false);

至此,您已經可以使用標準Profile,並可以嘗試將您的智慧硬體操作封裝成Profile的形式進行操作,這有利於其他使用BCSphere開發智慧硬體應用的開發者複用您的程式碼。如果您希望將自己硬體的Profile共享,可以通過team@bcsphere.org聯絡我們。本章同樣提供了示例原始碼

下一章將著重介紹如何在BCSphere中使用Cordova提供的標準模組。

相關文章