|
375 | 375 | </div>
|
376 | 376 | <div class="content readme">
|
377 | 377 | <div class="content-data">
|
378 |
| - <p align="center"> |
379 |
| - <img src="https://cloud.githubusercontent.com/assets/1699357/21510721/556f650c-cc97-11e6-8a69-ddd67eeeebb8.png" width="250"> |
380 |
| - </p> |
| 378 | + <p><div align="center"> |
| 379 | + <img src="https://cloud.githubusercontent.com/assets/1699357/21510721/556f650c-cc97-11e6-8a69-ddd67eeeebb8.png" width="250" /> |
| 380 | + </div></p> |
381 | 381 | <h2 align="center">The missing Web Bluetooth module for Angular (>=2) <img src="https://circleci.com/gh/manekinekko/angular-web-bluetooth.svg?style=svg"></h2>
|
382 | 382 |
|
383 |
| - ### Yarn it |
384 |
| - |
385 |
| - <code>yarn add @manekinekko/angular-web-bluetooth</code> |
386 |
| - |
387 |
| - ### NPM it |
388 |
| - |
389 |
| - <code>npm i -S @manekinekko/angular-web-bluetooth</code> |
390 |
| - |
391 |
| - ## Use it |
392 |
| - |
393 |
| - ## 1) import the <code>WebBluetoothModule</code> module |
394 |
| - |
395 |
| - <code>typescript |
396 |
| - import { NgModule } from '@angular/core'; |
397 |
| - import { WebBluetoothModule } from '@manekinekko/angular-web-bluetooth'; |
398 |
| - |
399 |
| - @NgModule({ |
400 |
| - imports: [ |
401 |
| - //..., |
402 |
| - WebBluetoothModule.forRoot() |
403 |
| - ], |
404 |
| - //... |
405 |
| - }) |
406 |
| - export class AppModule { }</code> |
407 |
| - |
408 |
| - ## 2) use it in your service/component |
409 |
| - |
410 |
| - Here is an annotated example using the <code>BluetoothCore</code> service: |
411 |
| - |
412 |
| - <code>typescript |
413 |
| - import { Injectable } from '@angular/core'; |
414 |
| - import { Observable } from 'rxjs/Observable'; |
415 |
| - |
416 |
| - import { |
417 |
| - BluetoothCore, |
418 |
| - BluetoothRemoteGATTServer, |
419 |
| - BluetoothRemoteGATTService, |
420 |
| - BluetoothRemoteGATTCharacteristic, |
421 |
| - DataView |
422 |
| - } from '@manekinekko/angular-web-bluetooth'; |
423 |
| - |
424 |
| - |
425 |
| - @Injectable() |
426 |
| - export class BatteryLevelService { |
427 |
| - |
428 |
| - static GATT_CHARACTERISTIC_BATTERY_LEVEL = 'battery_level'; |
429 |
| - static GATT_PRIMARY_SERVICE = 'battery_service'; |
430 |
| - |
431 |
| - constructor( |
432 |
| - public ble: BluetoothCore |
433 |
| - ) {} |
434 |
| - |
435 |
| - getFakeValue() { |
436 |
| - this.ble.fakeNext(); |
437 |
| - } |
438 |
| - |
439 |
| - getDevice() { |
440 |
| - |
441 |
| - // call this method to get the connected device |
442 |
| - return this.ble.getDevice$(); |
443 |
| - } |
444 |
| - |
445 |
| - streamValues() { |
446 |
| - |
447 |
| - // call this method to get a stream of values emitted by the device |
448 |
| - return this.ble.streamValues$() |
449 |
| - .map( (value: DataView) => value.getUint8(0)); |
450 |
| - } |
451 |
| - |
452 |
| - /** |
453 |
| - * Get Battery Level GATT Characteristic value. |
454 |
| - * This logic is specific to this service, this is why we can't abstract it elsewhere. |
455 |
| - * The developer is free to provide any service, and characteristics she wants. |
456 |
| - * |
457 |
| - * @return {Observable<number>} Emites the value of the requested service read from the device |
458 |
| - */ |
459 |
| - getBatteryLevel(): Observable<number> { |
460 |
| - console.log('Getting Battery Service...'); |
461 |
| - |
462 |
| - try { |
463 |
| - return this.ble |
464 |
| - |
465 |
| - // 1) call the discover method will trigger the discovery process (by the browser) |
466 |
| - .discover$({ |
467 |
| - |
468 |
| - // give it a service UUID |
469 |
| - optionalServices: [BatteryLevelService.GATT_PRIMARY_SERVICE] |
470 |
| - |
471 |
| - }) |
472 |
| - .mergeMap( (gatt: BluetoothRemoteGATTServer) => { |
473 |
| - |
474 |
| - // 2) get that service |
475 |
| - return this.ble.getPrimaryService$(gatt, BatteryLevelService.GATT_PRIMARY_SERVICE); |
476 |
| - }) |
477 |
| - .mergeMap( (primaryService: BluetoothRemoteGATTService) => { |
478 |
| - |
479 |
| - // 3) get a specific characteristic on that service |
480 |
| - return this.ble.getCharacteristic$(primaryService, BatteryLevelService.GATT_CHARACTERISTIC_BATTERY_LEVEL); |
481 |
| - }) |
482 |
| - .mergeMap( (characteristic: BluetoothRemoteGATTCharacteristic) => { |
483 |
| - |
484 |
| - // 4) ask for the value of that characteristic (will return a DataView) |
485 |
| - return this.ble.readValue$(characteristic); |
486 |
| - }) |
487 |
| - .map( (value: DataView) => { |
488 |
| - |
489 |
| - // 5) on that DataView, get the right value |
490 |
| - return value.getUint8(0) |
491 |
| - }); |
492 |
| - } |
493 |
| - catch(e) { |
494 |
| - console.error('Oops! can not read value from %s'); |
495 |
| - } |
496 |
| - |
497 |
| - } |
498 |
| - |
499 |
| - }</code> |
500 |
| - |
501 |
| - See the <a href="https://github.com/manekinekko/angular-web-bluetooth-starter/tree/master/src/app">starter</a> for a complete use case. |
502 |
| - |
503 |
| - ## Need a starter? |
504 |
| - |
505 |
| - You can use <a href="https://github.com/manekinekko/angular-web-bluetooth-starter">this starter</a> to start building your first Web Bluetooth module. |
506 |
| - |
507 |
| - ## Documentation |
508 |
| - |
509 |
| - The API documentation can be found <a href="./documentation">here</a>. |
510 |
| - |
511 |
| - ## Blog post |
512 |
| - Checkout my post on medium. |
513 |
| - |
| 383 | + <h3 id="yarn-it">Yarn it</h3> |
| 384 | + <p><code>yarn add @manekinekko/angular-web-bluetooth</code></p> |
| 385 | + <h3 id="npm-it">NPM it</h3> |
| 386 | + <p><code>npm i -S @manekinekko/angular-web-bluetooth</code></p> |
| 387 | + <h2 id="use-it">Use it</h2> |
| 388 | + <h2 id="1-import-the-webbluetoothmodule-module">1) import the <code>WebBluetoothModule</code> module</h2> |
| 389 | + <pre><code class="hljs typescript"><span class="hljs-keyword">import</span> { NgModule } from <span class="hljs-string">'@angular/core'</span>;<br><span class="hljs-keyword">import</span> { WebBluetoothModule } from <span class="hljs-string">'@manekinekko/angular-web-bluetooth'</span>;<br><br><span class="hljs-meta">@NgModule</span>({<br> imports: [<br> <span class="hljs-comment">//...,</span><br> WebBluetoothModule.forRoot()<br> ],<br> <span class="hljs-comment">//...</span><br>})<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppModule { }</code></pre><h2 id="2-use-it-in-your-service-component">2) use it in your service/component</h2> |
| 390 | + <p>Here is an annotated example using the <code>BluetoothCore</code> service:</p> |
| 391 | + <pre><code class="hljs javascript"><span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;<br><span class="hljs-keyword">import</span> { Observable } <span class="hljs-keyword">from</span> <span class="hljs-string">'rxjs/Observable'</span>;<br><br><span class="hljs-keyword">import</span> {<br> BluetoothCore,<br> BluetoothRemoteGATTServer,<br> BluetoothRemoteGATTService,<br> BluetoothRemoteGATTCharacteristic,<br> <span class="hljs-built_in">DataView</span><br>} <span class="hljs-keyword">from</span> <span class="hljs-string">'@manekinekko/angular-web-bluetooth'</span>;<br><br><br>@Injectable()<br><span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BatteryLevelService</span> </span>{<br><br> <span class="hljs-keyword">static</span> GATT_CHARACTERISTIC_BATTERY_LEVEL = <span class="hljs-string">'battery_level'</span>;<br> <span class="hljs-keyword">static</span> GATT_PRIMARY_SERVICE = <span class="hljs-string">'battery_service'</span>;<br><br> <span class="hljs-keyword">constructor</span>(<br> public ble: BluetoothCore<br> ) {}<br><br> getFakeValue() {<br> <span class="hljs-keyword">this</span>.ble.fakeNext();<br> }<br><br> getDevice() {<br><br> <span class="hljs-comment">// call this method to get the connected device</span><br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.ble.getDevice$();<br> }<br><br> streamValues() {<br><br> <span class="hljs-comment">// call this method to get a stream of values emitted by the device</span><br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.ble.streamValues$()<br> .map( <span class="hljs-function">(<span class="hljs-params">value: <span class="hljs-built_in">DataView</span></span>) =></span> value.getUint8(<span class="hljs-number">0</span>));<br> }<br><br> <span class="hljs-comment">/**<br> * Get Battery Level GATT Characteristic value.<br> * This logic is specific to this service, this is why we can't abstract it elsewhere.<br> * The developer is free to provide any service, and characteristics she wants.<br> *<br> * @return {Observable<number>} Emites the value of the requested service read from the device<br> */</span><br> getBatteryLevel(): Observable<number> {<br> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Getting Battery Service...'</span>);<br><br> <span class="hljs-keyword">try</span> {<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.ble<br><br> <span class="hljs-comment">// 1) call the discover method will trigger the discovery process (by the browser)</span><br> .discover$({<br><br> <span class="hljs-comment">// give it a service UUID</span><br> optionalServices: [BatteryLevelService.GATT_PRIMARY_SERVICE]<br><br> })<br> .mergeMap( <span class="hljs-function">(<span class="hljs-params">gatt: BluetoothRemoteGATTServer</span>) =></span> {<br><br> <span class="hljs-comment">// 2) get that service</span><br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.ble.getPrimaryService$(gatt, BatteryLevelService.GATT_PRIMARY_SERVICE);<br> })<br> .mergeMap( <span class="hljs-function">(<span class="hljs-params">primaryService: BluetoothRemoteGATTService</span>) =></span> {<br><br> <span class="hljs-comment">// 3) get a specific characteristic on that service</span><br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.ble.getCharacteristic$(primaryService, BatteryLevelService.GATT_CHARACTERISTIC_BATTERY_LEVEL); <br> })<br> .mergeMap( <span class="hljs-function">(<span class="hljs-params">characteristic: BluetoothRemoteGATTCharacteristic</span>) =></span> {<br><br> <span class="hljs-comment">// 4) ask for the value of that characteristic (will return a DataView)</span><br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.ble.readValue$(characteristic);<br> })<br> .map( <span class="hljs-function">(<span class="hljs-params">value: <span class="hljs-built_in">DataView</span></span>) =></span> {<br><br> <span class="hljs-comment">// 5) on that DataView, get the right value</span><br> <span class="hljs-keyword">return</span> value.getUint8(<span class="hljs-number">0</span>) <br> });<br> }<br> <span class="hljs-keyword">catch</span>(e) {<br> <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Oops! can not read value from %s'</span>);<br> }<br><br> }<br><br>}</code></pre><p>See the <a href="https://github.com/manekinekko/angular-web-bluetooth-starter/tree/master/src/app">starter</a> for a complete use case.</p> |
| 392 | + <h2 id="need-a-starter-">Need a starter?</h2> |
| 393 | + <p>You can use <a href="https://github.com/manekinekko/angular-web-bluetooth-starter">this starter</a> to start building your first Web Bluetooth module.</p> |
| 394 | + <h2 id="documentation">Documentation</h2> |
| 395 | + <p>The API documentation can be found <a href="./documentation">here</a>.</p> |
| 396 | + <h2 id="blog-post">Blog post</h2> |
| 397 | + <p>Checkout my post on medium.</p> |
514 | 398 | <p align="center">
|
515 | 399 | <a href="https://medium.com/google-developer-experts/the-web-bluetooth-module-for-angular-9336c9535d04#.f6dp9z163">
|
516 | 400 | <img src="https://cloud.githubusercontent.com/assets/1699357/21696708/7e33cca4-d38f-11e6-8a03-6833b88e82fa.png" >
|
|
0 commit comments