<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>BLE read</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>BLE read</h1>
<p>Micro:bitに接続完了後、ボタンA・Bを押してください。
ボタンの情報を取得します。</p>
<hr>
<p><button type="button" id="connect">接続</button> <span id="msg"></span></p>
<div id="buttonA"></div>
<div id="buttonB"></div>
<script>
  //microbit ボタンサービスのUUID
  const uuid1 = "E95D9882-251D-470A-A062-FA1922DFA9A8"; //buttonUuid
  const uuida = "E95DDA90-251D-470A-A062-FA1922DFA9A8"; //AButtonUuid
  const uuidb = "E95DDA91-251D-470A-A062-FA1922DFA9A8"; //BButtonUuid
  //デバイスの取得
document.getElementById('connect').addEventListener('click', function(e){
  if (document.getElementById('connect').textContent == '接続') {
    start() ;
    buttonA.innerHTML = "" ; buttonB.innerHTML = "" ;
  }
  else { gatt.disconnect() ; update(false) ; }
}) ;
function update(connected) {
  connect.textContent = connected ? '切断' : '接続'
  msg.innerHTML = connected ? 'BLE connected' : 'BLE disconnected'
//send.disabled = !connected ;
}
function start(){
  navigator.bluetooth.requestDevice({
    filters: [{namePrefix: 'BBC micro:bit'}],optionalServices:[uuid1.toLowerCase()]} )
    .then( device => { gatt = device.gatt ; return gatt.connect(); } )
    .then( server => { return server.getPrimaryService(uuid1.toLowerCase()); } )
    .then(         //サービスが取得できたら
    service => {
      return Promise.all([
        //characteristicsの取得(Aボタン用)
        service.getCharacteristic(uuida.toLowerCase())
        .then(chara => {
          //停止できるようにグローバルに保持
          charaA = chara;
          //通知サービスを開始
          chara.startNotifications();
          //リスナー関数の設定
          chara.addEventListener('characteristicvaluechanged',listenerButtonA);
          update(true) ;
        } ),
        //characteristicsの取得(Bボタン用)
          service.getCharacteristic(uuidb.toLowerCase())
          .then(chara => {
            //停止できるようにグローバルに保持
            charaB = chara;
            //通知サービスを開始
            chara.startNotifications();
            //リスナー関数の設定
            chara.addEventListener('characteristicvaluechanged',listenerButtonB);
            update(true) ;
          }
        )
      ]);
    }
//).catch( error => { console.log('sorry Error!'); } )
  ).catch( error => { msg.innerHTML = (error) ; } )
}
//通知停止
function Stop(){
  if( charaA ){
    //通知の停止
    charaA.stopNotifications().then(() => {
      //リスナーの解放
      charaA.removeEventListener('characteristicvaluechanged',listenerButtonA);
    });
  }
  if( charaB ){
    //通知の停止
    charaB.stopNotifications().then(() => {
      //リスナーの解放
      charaB.removeEventListener('characteristicvaluechanged',listenerButtonB);
    });
  }
}
            
//Aボタン用リスナ
function listenerButtonA(event){
  let chara = event.target;
  let message = 'Aボタンが' + getStatus( chara.value.getUint8(0) );
  document.getElementById('buttonA').innerHTML = message;
}
//Bボタン用リスナ
function listenerButtonB(event){
  let chara = event.target;
  let message = 'Bボタンが' + getStatus( chara.value.getUint8(0) );
  document.getElementById('buttonB').innerHTML = message;
}
//ボタンの状態を判別し文字列を返す
function getStatus( value ){
  switch(value){
    case 0: return '離されました'; break;
    case 1: return '押されました'; break;
    case 2: return '長押しされました'; break;
  }
}
</script>
</body>
</html>