Web Bluetooth ile PLAYBULB mumu kontrol edin

1. Neyle ilgili?

IMG_19700101_023537~2~2.jpg

Aydınlatılmış bu codelab'de, Web Bluetooth API sayesinde yalnızca JavaScript kullanarak PLAYBULB LED alevsiz mum nasıl kontrol edeceğinizi öğreneceksiniz. Bu süreçte Sınıflar, Ok işlevleri, Harita ve Promises gibi JavaScript ES2015 özellikleriyle de oynayacaksınız.

Neler öğreneceksiniz?

  • JavaScript'te yakındaki bir Bluetooth cihazla nasıl etkileşimde bulunulur?
  • ES2015 sınıfları, ok işlevleri, harita ve vaatler nasıl kullanılır?

Gerekenler

2. İlk önce oynayın

Bu codelab'i ayrıntılı olarak incelemeden önce, oluşturmak üzere olduğunuz uygulamanın son sürümünü https://googlecodelabs.github.io/candle-bluetooth adresinden kontrol edebilir ve elinizdeki PLAYBULB Mudle Bluetooth cihazıyla oynayabilirsiniz.

Renk değişikliklerimi ayrıca https://www.youtube.com/watch?v=fBCPA9gIxlU adresinden de izleyebilirsiniz.

3. Hazırlanın

Örnek kodu indirin

ZIP dosyasını buradan indirerek bu kod için örnek kodu alabilirsiniz:

veya şu git deposunu klonlayarak:

git clone https://github.com/googlecodelabs/candle-bluetooth.git

Kaynağı zip dosyası olarak indirdiyseniz paketi açtığınızda candle-bluetooth-master kök klasörünün olması gerekir.

Web sunucusunu yükleme ve doğrulama

Kendi web sunucunuzu kullanabilirsiniz ancak bu codelab, Chrome Web Sunucusu ile uyumlu çalışacak şekilde tasarlanmıştır. Bu uygulama henüz yüklü değilse, Chrome Web Mağazası'ndan yükleyebilirsiniz.

Chrome için Web Sunucusu uygulamasını yükledikten sonra yer işareti çubuğundaki Uygulamalar kısayolunu tıklayın:

Screen Shot 2016-11-16 at 4.10.42 PM.png

Açılan pencerede Web Sunucusu simgesini tıklayın:

9f3c21b2cf6cbfb5.png

Sonrasında, yerel web sunucunuzu yapılandırmanıza olanak tanıyan aşağıdaki iletişim kutusunu görürsünüz:

Screen Shot 2016-11-16 at 3.40.47 PM.png

Klasör seç düğmesini tıklayın ve klonlanan (veya arşivden çıkarılmış) deponun kök dizinini seçin. Böylece, devam eden çalışmanızı, web sunucusu iletişim kutusunda (Web Sunucusu URL'leri bölümünde) vurgulanan URL aracılığıyla sunabilirsiniz.

Seçenekler altında, aşağıda gösterildiği gibi, "index.html'yi otomatik olarak göster" seçeneğinin yanındaki kutuyu işaretleyin:

Screen Shot 2016-11-16 at 3.40.56 PM.png

Şimdi web tarayıcınızda sitenizi ziyaret edin (vurgulanan Web Sunucusu URL'sini tıklayarak) aşağıdaki gibi bir sayfa göreceksiniz:

Screen Shot 2016-11-16 at 3.20.22 PM.png

Bu uygulamanın Android telefonunuzda nasıl göründüğünü görmek istiyorsanız Android'de uzaktan hata ayıklama özelliğini etkinleştirmeniz ve Bağlantı noktası yönlendirmeyi ayarlamanız gerekir (bağlantı noktası varsayılan olarak 8887'dir). Bundan sonra, Android telefonunuzda http://localhost:8887 adresine giderek yeni bir Chrome sekmesi açabilirsiniz.

Sonraki bölüm

Bu web uygulaması şu anda pek bir şey yapmıyor. Bluetooth desteği eklemeye başlayalım.

4. Muumu keşfedin

PLAYBULB Candle Bluetooth cihazı için JavaScript ES2015 Class kullanan bir kitaplık yazarak başlayacağız.

Sakin olun. Sınıf söz dizimi, JavaScript'e yeni bir nesne odaklı devralma modeli sunmaz. Aşağıda okuyabileceğiniz gibi, nesne oluşturmak ve devralmayla ilgilenmek için çok daha net bir söz dizimi sağlar.

Öncelikle playbulbCandle.js içinde bir PlaybulbCandle sınıfı tanımlayalım ve daha sonra app.js dosyasında kullanılabilecek bir playbulbCandle örneği oluşturalım.

playbulbCandle.js

(function() {
  'use strict';

  class PlaybulbCandle {
    constructor() {
      this.device = null;
    }
  }

  window.playbulbCandle = new PlaybulbCandle();

})();

Yakındaki bir Bluetooth cihazına erişim isteğinde bulunmak için navigator.bluetooth.requestDevice numarasını aramamız gerekir. PLAYBULB Mudle cihazı, önceden eşlenmemişse, kısa biçimiyle 0xFF02 olarak bilinen sabit Bluetooth GATT Hizmeti UUID'sinin sürekli olarak reklamını yaptığı için basit bir şekilde bir sabit değer tanımlayabilir ve bunu, PlaybulbCandle sınıfındaki yeni bir herkese açık connect yönteminde filtre hizmetleri parametresine ekleyebiliriz.

Gerekirse daha sonra erişebilmek için BluetoothDevice nesnesinin dahili kaydını da tutacağız. navigator.bluetooth.requestDevice, JavaScript ES2015 Promise döndürdüğü için bunu then yönteminde yapacağız.

playbulbCandle.js

(function() {
  'use strict';

  const CANDLE_SERVICE_UUID = 0xFF02;

  class PlaybulbCandle {
    constructor() {
      this.device = null;
    }
    connect() {
      let options = {filters:[{services:[ CANDLE_SERVICE_UUID ]}]};
      return navigator.bluetooth.requestDevice(options)
      .then(function(device) {
        this.device = device;
      }.bind(this)); 
    }
  }

  window.playbulbCandle = new PlaybulbCandle();

})();

Bir güvenlik özelliği olarak, navigator.bluetooth.requestDevice ile yakındaki Bluetooth cihazların keşfedilmesi, dokunma veya fare tıklaması gibi bir kullanıcı hareketiyle yapılmalıdır. Bu nedenle, kullanıcı "Bağlan"ı tıkladığında connect yöntemini çağıracağız. düğme: app.js

app.js

document.querySelector('#connect').addEventListener('click', function(event) {
  document.querySelector('#state').classList.add('connecting');
  playbulbCandle.connect()
  .then(function() {
    console.log(playbulbCandle.device);
    document.querySelector('#state').classList.remove('connecting');
    document.querySelector('#state').classList.add('connected');
  })
  .catch(function(error) {
    console.error('Argh!', error);
  });
});

Uygulamayı çalıştırma

Bu noktada, web tarayıcınızda sitenizi ziyaret edin (web sunucusu uygulamasında vurgulanmış Web Sunucusu URL'sini tıklayın) veya mevcut sayfayı yenileyin. Yeşil "Bağlan"ı tıklayın düğmesinden cihazı seçin, Ctrl + Üst Karakter + J klavye kısayoluyla favori Geliştirici Araçları konsolunuzu açın ve BluetoothDevice nesnesinin günlüğe kaydedildiğini görün.

Screen Shot 2016-11-16 at 3.27.12 PM.png

Bluetooth kapalıysa ve/veya PLAYBULB Candle Bluetooth cihazı kapalıysa hata alabilirsiniz. Bu durumda, özelliği etkinleştirip tekrar devam edin.

Zorunlu Bonus

Sizi bilmiyorum ama bu kodda zaten çok fazla function() {} var. Bunun yerine () => {} JavaScript ES2015 Ok İşlevlerine geçelim. Mutlaka hayat kurtaranlardır: Anonim işlevlerin tüm güzellikleri, bağlamanın üzücü hissi yok.

playbulbCandle.js

(function() {
  'use strict';

  const CANDLE_SERVICE_UUID = 0xFF02;

  class PlaybulbCandle {
    constructor() {
      this.device = null;
    }
    connect() {
      let options = {filters:[{services:[ CANDLE_SERVICE_UUID ]}]};
      return navigator.bluetooth.requestDevice(options)
      .then(device => {
        this.device = device;
      }); 
    }
  }

  window.playbulbCandle = new PlaybulbCandle();

})();

app.js

document.querySelector('#connect').addEventListener('click', event => {
  playbulbCandle.connect()
  .then(() => {
    console.log(playbulbCandle.device);
    document.querySelector('#state').classList.remove('connecting');
    document.querySelector('#state').classList.add('connected');
  })
  .catch(error => {
    console.error('Argh!', error);
  });
});

Sonraki bölüm

- Tamam... Bu mumla konuşabilir miyim ya da neyle konuşabilirim?

- Elbette... Sonraki adıma geç

Sık Sorulan Sorular

5. Bir şeyler okuma

Peki, navigator.bluetooth.requestDevice tarafından sözü edilen BluetoothDevice karşılığında geri döndüğünüze göre şimdi ne yapacaksınız? device.gatt.connect() numaralı telefonu arayarak Bluetooth hizmetini ve özellik tanımlarını barındıran Bluetooth uzak GATT sunucusuna bağlanalım:

playbulbCandle.js

  class PlaybulbCandle {
    constructor() {
      this.device = null;
    }
    connect() {
      let options = {filters:[{services:[ CANDLE_SERVICE_UUID ]}]};
      return navigator.bluetooth.requestDevice(options)
      .then(device => {
        this.device = device;
        return device.gatt.connect();
      });
    }
  }

Cihaz adını okuma

Burada PLAYBULB Candle Bluetooth cihazının GATT Sunucusuna bağlıyız. Şimdi birincil GATT hizmetini (daha önce 0xFF02 olarak reklamı yapılan) almak ve bu hizmete ait cihaz adı özelliğini (0xFFFF) okumak istiyoruz. Bu, PlaybulbCandle sınıfına yeni bir getDeviceName yöntemi eklenip device.gatt.getPrimaryService ve service.getCharacteristic kullanılarak kolayca gerçekleştirilebilir. characteristic.readValue yöntemi aslında TextDecoder ile kodunu çözeceğimiz bir DataView döndürür.

playbulbCandle.js

  const CANDLE_DEVICE_NAME_UUID = 0xFFFF;

  ...

    getDeviceName() {
      return this.device.gatt.getPrimaryService(CANDLE_SERVICE_UUID)
      .then(service => service.getCharacteristic(CANDLE_DEVICE_NAME_UUID))
      .then(characteristic => characteristic.readValue())
      .then(data => {
        let decoder = new TextDecoder('utf-8');
        return decoder.decode(data);
      });
    }

Bağlandıktan ve cihaz adını gösterdikten sonra playbulbCandle.getDeviceName numaralı telefonu arayarak bunu app.js cihazına ekleyelim.

app.js

document.querySelector('#connect').addEventListener('click', event => {
  playbulbCandle.connect()
  .then(() => {
    console.log(playbulbCandle.device);
    document.querySelector('#state').classList.remove('connecting');
    document.querySelector('#state').classList.add('connected');
    return playbulbCandle.getDeviceName().then(handleDeviceName);
  })
  .catch(error => {
    console.error('Argh!', error);
  });
});

function handleDeviceName(deviceName) {
  document.querySelector('#deviceName').value = deviceName;
}

Bu noktada, web tarayıcınızda sitenizi ziyaret edin (web sunucusu uygulamasında vurgulanmış Web Sunucusu URL'sini tıklayın) veya mevcut sayfayı yenileyin. PLAYBULB Mumunun açık olduğundan emin olun ve "Bağlan"ı tıklayın. renk seçicinin altında cihaz adını görebilirsiniz.

Screen Shot 2016-11-16 at 3.29.21 PM.png

Pil seviyesini okuma

PLAYBULB Mudle Bluetooth cihazında, cihazın pil seviyesini belirten standart bir pil seviyesi Bluetooth özelliği de vardır. Bu, Bluetooth GATT Hizmeti UUID'si için battery_service ve Bluetooth GATT Özelliği UUID'si için battery_level gibi standart adlar kullanabileceğimiz anlamına gelir.

Şimdi PlaybulbCandle sınıfına yeni bir getBatteryLevel yöntemi ekleyip pil seviyesini yüzde olarak okuyalım.

playbulbCandle.js

    getBatteryLevel() {
      return this.device.gatt.getPrimaryService('battery_service')
      .then(service => service.getCharacteristic('battery_level'))
      .then(characteristic => characteristic.readValue())
      .then(data => data.getUint8(0));
    }

Ayrıca, options JavaScript nesnesini de optionalServices anahtarına pil hizmetini ekleyecek şekilde güncellememiz gerekiyor. Çünkü bu, PLAYBULB Mudle Bluetooth cihazı tarafından tanıtılmadığı, ancak yine de cihaza erişilmesi zorunlu olduğu için.

playbulbCandle.js

      let options = {filters:[{services:[ CANDLE_SERVICE_UUID ]}],
                     optionalServices: ['battery_service']};
      return navigator.bluetooth.requestDevice(options)

Daha önce olduğu gibi, cihaz adını öğrendikten ve pil seviyesini gösterdikten sonra playbulbCandle.getBatteryLevel numaralı telefonu arayarak bunu app.js cihazına bağlayacağız.

app.js

document.querySelector('#connect').addEventListener('click', event => {
  playbulbCandle.connect()
  .then(() => {
    console.log(playbulbCandle.device);
    document.querySelector('#state').classList.remove('connecting');
    document.querySelector('#state').classList.add('connected');
    return playbulbCandle.getDeviceName().then(handleDeviceName)
    .then(() => playbulbCandle.getBatteryLevel().then(handleBatteryLevel));
  })
  .catch(error => {
    console.error('Argh!', error);
  });
});

function handleDeviceName(deviceName) {
  document.querySelector('#deviceName').value = deviceName;
}

function handleBatteryLevel(batteryLevel) {
  document.querySelector('#batteryLevel').textContent = batteryLevel + '%';
}

Bu noktada, web tarayıcınızda sitenizi ziyaret edin (web sunucusu uygulamasında vurgulanmış Web Sunucusu URL'sini tıklayın) veya mevcut sayfayı yenileyin. "Bağlan"ı tıklayın düğmesine bastığınızda, hem cihaz adını hem de pil seviyesini görebilirsiniz.

Screen Shot 2016-11-16 at 3.29.21 PM.png

Sonraki bölüm

- Bu ampulün rengini nasıl değiştirebilirim? Bunun için buradayım.

- Çok yakınsınız söz veriyorum...

Sık Sorulan Sorular

6. Rengi değiştirin

Rengi değiştirmek, 0xFF02 adıyla reklamı yapılan Birincil GATT Hizmeti'ndeki bir Bluetooth Özelliğine (0xFFFC) belirli bir komut grubunu yazmak kadar kolaydır. Örneğin, PLAYBULB Mumunuzu kırmızıya çevirdiğinizde, [0x00, 255, 0, 0] değerine eşit olan 8 bitlik bir imzasız tam sayı dizisi yazılır. 0x00, beyaz doygunluğu, 255, 0, 0 ise sırasıyla kırmızı, yeşil ve mavi değerleri temsil eder.

PlaybulbCandle sınıfının herkese açık yeni setColor yöntemindeki Bluetooth özelliğine bazı veriler yazmak için characteristic.writeValue değerini kullanacağız. Ayrıca, söz yerine getirildiğinde gerçek kırmızı, yeşil ve mavi değerleri döndürürüz. Böylece bu değerleri daha sonra app.js uygulamasında kullanabiliriz:

playbulbCandle.js

  const CANDLE_COLOR_UUID = 0xFFFC;

  ...

    setColor(r, g, b) {
      let data = new Uint8Array([0x00, r, g, b]);
      return this.device.gatt.getPrimaryService(CANDLE_SERVICE_UUID)
      .then(service => service.getCharacteristic(CANDLE_COLOR_UUID))
      .then(characteristic => characteristic.writeValue(data))
      .then(() => [r,g,b]);
    }

"Efektsiz" ayarı etkin olmadığında app.js işlevini playbulbCandle.setColor çağırmak için changeColor işlevini güncelleyelim. radyo düğmesinin işaretli olması gerekir. Kullanıcı, renk seçici tuvalini tıkladığında genel r, g, b renk değişkenleri zaten ayarlanmış.

app.js

function changeColor() {
  var effect = document.querySelector('[name="effectSwitch"]:checked').id;
  if (effect === 'noEffect') {
    playbulbCandle.setColor(r, g, b).then(onColorChanged);
  }
}

Bu noktada, web tarayıcınızda sitenizi ziyaret edin (web sunucusu uygulamasında vurgulanmış Web Sunucusu URL'sini tıklayın) veya mevcut sayfayı yenileyin. "Bağlan"ı tıklayın düğmesini tıklayın ve PLAYBULB Mumunuzun rengini istediğiniz kadar değiştirmek için renk seçiciyi tıklayın.

Screen Shot 2016-11-16 at 3.31.37 PM.png

Moar mum efektleri

Daha önce bir mum yaktıysanız ışığın sabit olmadığını anlarsınız. Neyse ki Birincil GATT Hizmeti'nde, 0xFF02 adıyla reklamı yapılan ve kullanıcının bazı mum efektlerini ayarlamasına olanak tanıyan başka bir Bluetooth özelliği (0xFFFB) var.

"Mum efekti" ayarlama Örneğin, [0x00, r, g, b, 0x04, 0x00, 0x01, 0x00] yazarak gerçekleştirilebilir. "Yanıp sönen efekti"ni de [0x00, r, g, b, 0x00, 0x00, 0x1F, 0x00] ile birlikte.

setCandleEffectColor ve setFlashingColor yöntemlerini PlaybulbCandle sınıfına ekleyelim.

playbulbCandle.js

  const CANDLE_EFFECT_UUID = 0xFFFB;

  ...

    setCandleEffectColor(r, g, b) {
      let data = new Uint8Array([0x00, r, g, b, 0x04, 0x00, 0x01, 0x00]);
      return this.device.gatt.getPrimaryService(CANDLE_SERVICE_UUID)
      .then(service => service.getCharacteristic(CANDLE_EFFECT_UUID))
      .then(characteristic => characteristic.writeValue(data))
      .then(() => [r,g,b]);
    }
    setFlashingColor(r, g, b) {
      let data = new Uint8Array([0x00, r, g, b, 0x00, 0x00, 0x1F, 0x00]);
      return this.device.gatt.getPrimaryService(CANDLE_SERVICE_UUID)
      .then(service => service.getCharacteristic(CANDLE_EFFECT_UUID))
      .then(characteristic => characteristic.writeValue(data))
      .then(() => [r,g,b]);
    }

Son olarak, "Mum Efekti" devre dışı bırakıldığında playbulbCandle.setCandleEffectColor yöntemini çağırmak için app.js içindeki changeColor işlevini güncelleyelim. radyo düğmesi işaretli olduğunda, "Yanıp sönen" seçeneğinde playbulbCandle.setFlashingColor radyo düğmesinin işaretli olması gerekir. Bu kez, sizin için bir sorun yoksa switch alanını kullanacağız.

app.js

function changeColor() {
  var effect = document.querySelector('[name="effectSwitch"]:checked').id;
  switch(effect) {
    case 'noEffect':
      playbulbCandle.setColor(r, g, b).then(onColorChanged);
      break;
    case 'candleEffect':
      playbulbCandle.setCandleEffectColor(r, g, b).then(onColorChanged);
      break;
    case 'flashing':
      playbulbCandle.setFlashingColor(r, g, b).then(onColorChanged);
      break;
  }
}

Bu noktada, web tarayıcınızda sitenizi ziyaret edin (web sunucusu uygulamasında vurgulanmış Web Sunucusu URL'sini tıklayın) veya mevcut sayfayı yenileyin. "Bağlan"ı tıklayın düğmesini tıklayın ve Mum ve Yanıp Sönme Efektleriyle oynayın.

Screen Shot 2016-11-16 at 3.33.23 PM.png

Sonraki bölüm

- Hepsi bu kadar mı? 3 kötü mum efekti? Ben bu yüzden mi buradayım?

- Dahası da olacak, ancak bu sefer kendi başınıza olacaksınız.

7. Ekstra çaba sarf edin

İşte buradayız! İçeriklerinizin neredeyse bittiğini düşünebilirsiniz ancak uygulama henüz bitmemiştir. Bu codelab sırasında kopyalayıp yapıştırdıklarınızı gerçekten anlayıp anlamadığınızı görelim. İşte bu uygulamayı öne çıkarmak için şimdi kendi başınıza yapmak istedikleriniz.

Eksik efektleri ekle

Eksik efektlerle ilgili veriler şunlardır:

  • Nabız: [0x00, r, g, b, 0x01, 0x00, 0x09, 0x00] (r, g, b değerlerini oradan ayarlamak isteyebilirsiniz)
  • Gökkuşağı: [0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00] (Epileptik kişiler bundan uzak durmak isteyebilir)
  • Gökkuşağı Karartma: [0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x26, 0x00]

Bu, PlaybulbCandle sınıfına yeni setPulseColor, setRainbow ve setRainbowFade yöntemlerinin eklenmesi ve bunların changeColor içinde çağrılması anlamına gelir.

"Efekt yok" sorununu düzeltme

Fark etmiş olabileceğiniz gibi, bu işlemin "hiçbir etkisi yok" seçeneği devam etmekte olan herhangi bir efekti sıfırlamaz. Bu küçük bir işlemdir, ancak yine de geçerlidir. Gelin bu sorunu çözelim. setColor yönteminde, _isEffectSet adlı yeni bir sınıf değişkeninde bir etkinin devam edip etmediğini kontrol etmeniz gerekir. true ise bu verilerle yeni renk ayarlamadan önce efekti devre dışı bırakın: [0x00, r, g, b, 0x05, 0x00, 0x01, 0x00].

Cihaz adını yazın

Bu çok kolay. Özel bir cihaz adı yazmak, önceki Bluetooth cihaz adı özelliğine yazmak kadar basittir. Cihaz adını içeren bir Uint8Array almak için TextEncoder encode yöntemini kullanmanızı öneririm.

Ardından, bu alana bir "giriş" Basit tutmak için document.querySelector('#deviceName') numaralı telefona eventListener ve playbulbCandle.setDeviceName numaralı telefonu arayın.

Şahsen kendime PLAY💡 CANDLE adını verdim.

8. İşte bu kadar.

Öğrendikleriniz

  • JavaScript'te yakındaki bir Bluetooth cihazla nasıl etkileşimde bulunulur?
  • ES2015 sınıfları, ok işlevleri, harita ve vaatler nasıl kullanılır?

Sonraki Adımlar