やわらかくて色がかわいい導線にとても満足している話 (しかも机の上に置いておきやすい!)

概要

ウレタンワイヤはやわらかくてかわいくて最高!
5色も入っているのにせまい自宅の作業スペースでもあんまじゃまにならない!!

f:id:concre_shiitake:20200805165436j:plain
シリコンワイヤー: 色がかわいい

f:id:concre_shiitake:20200805165512j:plain
AirPods Proとの大きさ比較:パッケージがそのまま収納になる

プロトタイピングにおける煩わしさ:扱いずらい導線

プロトタイピングをしていたり,モジュールの動作確認をしていると,とりあえず長めに導線をとっておくということをよくやる.
そういう時は,UEWとか,ビニールで被膜されているタイプの細い導線を使ってきた.
これにはあんまり深い理由はなくて,なんか部品屋行くと売ってるから使ってたくらいのノリだった.

でもこのタイプの導線というのは,硬さがあって本数が増えた時に扱いずらかったり,曲げていると変な癖がついてしまったりと,なんか意外と満足していない感じがあった.
特に,身につけるものを作ったりしているとこれがめちゃくちゃ不便だなあと感じていた.

やわらかくて扱いやすい導線:シリコンワイヤ

さて話は変わって,在宅勤務をするにあたって家の作業場にある工具を見直していた.
ちょうど導線のストックがなくなっていたので,狭い作業机に置ける程度で何色かある導線を探していると,よさそうなサイズのセットをAmazonでみつけた.

シリコン被膜のワイヤーというのを使ったことがなかったので,収納箱つきのワイヤセット,くらいのテンションで買った.
届いてみると,シリコンワイヤーのやわらかさと扱いやすさに驚いた.
見た目も彩度がすこし低いけど明度は高い感じの淡い色で,なんかビニル被膜の導線特有のあのドギツイ感じがなくてめちゃくちゃ良い.
作ったものに対する愛着がなんかこういうとこでも変わってくるのだなというのを感じている.
なんか困ったことがない限りはたぶんこれずっと使うと思う.経年劣化はどうかなあ.

あと被膜むくときにはこういうのあると便利ですね.

困っているので改善したいこと

全部がいいってことはなくて,困っていることもある.
導線を取り出すための穴が箱に開いているんだけど,ストッパーとかがないから勝手に箱の中に線が戻っていってしまう.
そうするといちいち箱をあけて,ワイヤを穴に通して…… みたいなことをしないといけなくてめんどくさい.
以下のような案を思いついたけど,最初のやつ以外は作業している際のアクションがひとつ増えてめんどくさそうなので,後でスポンジを買ってこようと思ってる.
- 小さな穴を明けたスポンジを,箱の穴に貼り付ける
- 粘着力のあるテープを穴の下あたりに取り付けて,そこにワイヤを貼っておく
- 箱の穴に切り込みをいれて,そこにワイヤをはさんでおく

最後に

ゴリゴリにアフィリンクです!ポチポチしましょう!! アフィリンク踏まなくてもいいので,ふつうに便利だと思うのでポチっていきましょう!!

BetterTouchTool を使って Touchbar にショートカットを表示してるときに、Escボタンの隣に出るバツマークを表示しないようにしつつ音量とか輝度も調節できるようにした話

タイトルが長い。
Touchbarを便利に使いつつ、ストレスを減らそうという話。

TouchBar+BetterTouchTool=便利

shokai さんのScrapboxを見て、BetterTouchToolを使うとTouchbarに任意のショートカットを置けるという便利Tipsを知った。
これはたいそう便利なので常にFunctionキーないと死ぬと思い込んでる人はいっぺん使ってみるといいと思う。
IDEとかCAD使ってるときなんかはFunctionキー便利だけど、ふだんはFnキーおしたら出てくるくらいで十分だと感じてきた。 scrapbox.io

問題:TouchbarのEscボタンの横に出てくるバツマークがアホみたいにジャマ。

早速自分のMacbook Proでもこれを導入してみたのだが、Escボタンの隣にバツマークが出て来るようになってしまった。
このバツマークを押すとControlStripが展開される。
つまり、変なポップアップが出たり、Spinnerの展開をキャンセルしたりする時なんかにEscボタンをポンと押そうとすると間違えてバツマークを押してしまって、AppControl + Control Stripな画面が表示されてしまう。
こうなるともう最悪で、TouchBarを見ながらEscボタンを押して再びBetterTouchToolのボタンを押してショートカットを表示し直す必要があってとてもだるい。
f:id:concre_shiitake:20170118230814p:plain

解決方法:BetterTouchToolの設定を変更する

海外ブログを徘徊してると、BetterTouchTool最高だぜ!っていうポストが結構あって、そういう人たちの中にはEscボタン横のバツマークが出ていなかったり、省略されたControlStripが右側に出ていなかったりした。
できるのかな〜〜?と思いながらググっていると、BetterTouchTool α版のブログに以下のエントリがあった。最高だ。

www.boastr.net

現行のBetterTouchToolでの設定方法

上のブログは α版の話なので、現行の設定画面とは少し違う(ドキュメントにあるんだろうけど探すのめんどくさいおじさん。)
BetterTouchToolのPreferencesを開くと以下のような画面になる。
この画面下部にある General Touch Bar Settings を押下するとTouchbar への表示に関する設定が表示される。

f:id:concre_shiitake:20170119001915p:plain

以下が、ぼくが現在行っている設定。
ミソは、上から2番めにある Show macOS Control Strip だ。
ただ、これをオフにすると右側に出ていた 短いControl Stripもいっしょに消えてしまい、輝度とか音量の調整に困る。

f:id:concre_shiitake:20170118235316p:plain

バツマークを消しつつも輝度とか音量を調整する方法

バツマークを消しつつも音量や輝度の調整を行うには2つの方法がある。
1つ目は、AppControl + ControlStrip を表示するためのボタンを表示する方法。
上で述べた設定画面の一番下にある、 If Control Strip is hidden: Show BetterTouchTool Icon on the left side をオンにすれば良い。 Touchbar上のBetterTouchToolアイコンを押すと AppControl + ControlStrip 画面が表示される。 f:id:concre_shiitake:20170118235658p:plain Escの右隣にあるボタンがそれ。 f:id:concre_shiitake:20170119003634p:plain

2つ目は、音量や輝度の調整を行うためのボタンを BetterTouchTool上に配置してしまう方法。
システム操作系はPredefined Actionという形ですでに用意されているので、ボタンを追加してこれを選択するだけでよい。
例えば以下のようなTouchbarになる。絵文字は便利。
Ctrl - Cmd - Space して、brightness とか speaker とか入れるといい感じの絵文字が用意されている。

f:id:concre_shiitake:20170118235903p:plain f:id:concre_shiitake:20170119003559p:plain

ただベタ置きすると限られたスペースが消費されてもったいないので、 特定のキーをおした時だけ表示するようにしておくと良いと思う。
Advanced Button Configuration を押すと以下のような画面が出るので、 Only show while modifiers are pressed から好きなキーを選んでおくと良いと思う。 f:id:concre_shiitake:20170119002800p:plain

まとめ

BetterTouchToolを使ってTouchbar上にショートカットを配置してる状態で、Escの隣のバツマークを消しつつ音量や輝度調整もできる方法についてまとめた。
あとScrapboxは画像を使った一覧性の高さがとても良いので、みなさんトライしてみましょう。

Pokemon Go Plusを自作して歩きスマホから開放された話

はじめに

歩きスマホ危ないとか以前に,画面見ながら歩くのまじでだるいと思う.
公式からPokemon Go Plusっていういい感じのデバイスが出るらしいんだけど,待ってらんないし,自分のスキルセット的にばっこしな感じがしたので自作してみた.
以下の動画のような感じで,スマホの画面をチェックしなくても,ポケモンを見つけたり捕まえたりすることができて便利.

youtu.be

このエントリではまずはじめに,全体としてどんな感じで動いているのかを記すのみとし,具体的なプログラムについては別のエントリとして記すこととする.

ポケモンGo Plusとは

スマホをポッケにいれたままPokemonGoを楽しむためのデバイスで,以下のような機能を持つ.
え〜〜〜ポケモンの名前わかんないの〜〜〜って思うかもしれんけど,特に目的のポケモンがいないときとかはお気楽に遊ぶことができて意外といいと思う.

機能

BLEでつながる.

バイスが振動するので,スマホを出さなくても,近くにポケモンがいることがわかる

ボタンを押すと近くにいるポケモンを捕まえる.対象となるポケモンはランダムだと思われるが,ぼうけんノートから確認可能.また,結果をLEDと振動のパターンで教えてくれる

  • ポケストップが近くにあることを知らせる

近くにいるポケモンを知らせてくれるのと同様に,振動で知らせてくれる.ポケモンの時とはLEDの色と振動パターンが異なる.

  • 近くのポケストップにチェックインする

ボタンを押すと近くのポケストップにチェックインして道具が手に入る

外観

コンパスとモンスターボールを足したような形をしてる.
うでにはめたり,クリップでむねぽっけにつけたりする.
正直,え〜〜〜〜これ〜〜〜〜みたいな顔すると思うんだけど,DIYなら外装も自分好みにできちゃうんですよ(これからやります).

http://www.pokemongo.jp/plus/display1.png Pokemon Go公式ページより

実装

ハードウェア(デバイス)

バイスはシンプル.慣れてる人ならファームも含めてチャチャッと実装できちゃうくらいシンプル.
ファームは,上で述べた機能が利用できるように作成している.

ソフトウェア

実はキモはソフトウェア側.現在の公式アプリではまだデバイスと連携する設定がない.
そこで,NianticAPIを叩くライブラリとスマホアプリを連携させることで,デバイスを通してPokemon Goが遊べるようにする.

アプリ

まずはAndroidで作ったが,iOSも作れると思うし,ふだんiOS使ってるので作る予定.
アプリの主な機能は以下の2つであり,デバイスとサーバの仲介役みたいなもんである.

  • バイスとBLEで通信する.

ポケモンが見つかったなどの通知をデバイスへ送信し,デバイス側のボタンが押されたことを検知する.

  • サーバと通信する機能

サーバから通知されるポケモンが見つかったなどの通知を受信し,ポケモンを捕まえるようサーバへ指示を送信する.また,自身の緯度経度もサーバへ送信する.

サーバ

昨日おとといくらいに,ある場所の近くにいるポケモンをSlackへ通知するっていう記事がはやってたけど,あれと同じようなもんをつかってる.
プロトタイプのしやすさ的にPythonではないなと思ったので,Poke.ioというnpmモジュールを使った.
ここでNianticAPIを叩いて,近くにいるポケモンを見つけてアプリへ送信したり,アプリからのポケモン捕まえて命令に基づいてポケモン捕まえたりする.

これから

ひとまずデバイスのガワを作る.プログラムは公開に向けて準備するとともに,ブログにまとめる予定.
また,PebbleやAndroid Wearでも,ソフトウェアPokemon Go Plusみたいな感じで同様の機能が利用できるアプリを作っているので,そちらも進めていきたい.実際こっちのが便利でしょ.

youtu.be

Google Brillo をビルドして DragonBoard にインストールする

DragonBoardにBrilloを入れよう!

マイコンボードにしては箱がカッチョいい.Adobeみたいだ. https://gyazo.com/eba989162ed47942cea96af5fb3da851

謎のマークがついていてうさんくさい. https://gyazo.com/5e67efafe3c7cf0a9a6b3350acad0a80

1. 概要

GoogleのIoT向けOSであるBrilloをボードにインストールする方法について説明する.ボードはBrilloが公式でサポートしているDragonBoardを使う.Brilloとはなんぞやという話については,UbiquityでのBrilloセッションを見てもらうと早いとおもう.DalvikVMとかを持たない,軽量なAndroidくらいのイメージ.アプリ相当のものはHALを使ってデーモンとして書いていくんだと思う.

ここではあくまでBrilloをビルドしてボードにインストールするところまでを行う.そのため,Wi-FiBluetooth,GPIO等の外部インタフェースや,weaveを利用したやりとりなどはここでは説明しない.

2. 利用環境

2.1 DragonBoardの準備

2.2 クロスビルド用環境

  • Ubuntu 15.10
    • VMでいいんだけど,最初のビルド終えた時点で60GBくらいになるし,すぐ100GB近くなるので,外付けSSDとかを用意しとくといいと思う.

3. インストール手順

3.1 依存ライブラリの準備

クロスビルド環境や,ボードへイメージをインストールする際に利用するライブラリを導入する.Ubuntu 15.10ではほとんどがapt経由で導入可能なのでとても楽ちん.
Brillo-m9のビルドにはJDK7を用いる.

$ sudo apt-get update
$ sudo apt-get install openjdk-7-jdk
$ sudo apt-get install git-core gnupg flex bison gperf build-essential   zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386   lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache   libgl1-mesa-dev libxml2-utils xsltproc unzip
$ sudo apt-get install android-tools-adb android-tools-fastboot
$ wget -S -O - http://source.android.com/source/51-android.rules | sed "s/<username>/$USER/" | sudo tee >/dev/null /etc/udev/rules.d/51-android.rules; sudo udevadm control --reload-rules

// gitアカウントの設定
$ git config --global user.user "user"
$ git config --global user.email "user@mail.com"

// repoコマンドの導入
$ mkdir ~/bin
$ PATH=~/bin:$PATH
$ echo $PATH
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

3.2 Brilloのソースもってくる

Brilloのソースをさきほど導入したrepoコマンドを使って持ってくる.AOSPのビルドやったことある人ならわかると思うけどめっちゃ時間かかるので,別のことして待ってましょ.

// 作業用ディレクトリ作成
$ mkdir build_brillo
$ cd build_brillo
// ここでは,2016年2月26日での最新版であるm9-releaseブランチからソースをもってくることとする.
$ repo init -u https://android.googlesource.com/brillo/manifest -b brillo-m9-release
$ repo sync -j<ジョブ数>

3.3 ボードごとの依存ファイルもってくる

実機にインストールする際には,各ボードごとのハードウェア等に起因する依存ファイルが必要になる. これはbrunchコマンドで持ってくることができる.
brunchは,Brillo向けに追加されたコマンドで,イメージを作成・管理するために必要ないろいろな作業が行えるコマンド.くわしいことはhelpやソースを参照.

// 対応済みボードのリストが確認できる
$ ./toolsbdk/brunch/brunch bsp list
// ここではdragonboard用のものを導入する
$ ./toolsbdk/brunch/brunch bsp install dragonboard

3.4 ビルド

3.3でも述べたように,Brilloのイメージを管理するための brunch というコマンドが追加されている.なのでビルド方法は従来通りの方法と,brunchを利用した方法の2つがある.
あるのだが,brunchを利用したビルドは36時間経っても終わらなかったので諦めてしまった……
というわけでぼくは従来どおりの方法でビルドしている.

3.4.1 従来どおりの方法

初回ビルドは,ジョブ数4で3時間くらいだった.

$ source build/envsetup.sh 
// lunchでは,dragonboard-engを選択.
$ lunch
// ビルドの際にninjaを使うので環境変数へ設定しておく
$ export USE_NINJA=true
$ make -j<ジョブ数>

3.4.2 brunchコマンドを使った方法

brunchを使ったビルド方法はおそらく以下の方法.ビルドがまったく終わる気配がないのでこれでいいのか自信がない… けど,この方法だとプロダクトごとに管理するのが楽ちんそう.ぜひ使えるようになりたい.
brunch build ではジョブ数指定するオプションが見当たらなかったんだけど,なんかもうそういう問題じゃない感じがする.特にエラーが出てなくて,CPUの使用率も100%近くのまま変化してないのがまたよくわからない.

$ cd toolsbdk/brunch
$ ./brunch product create my_brillo dragonboard
$ cd my_brillo
$ ../brunch product envsetup
$ ../brunch product build -b eng

4. ボードへインストールする

ボードのUSB-Microポートを使ってUbuntuにボードを接続する.ボードをfastboot状態にしてからインストールスクリプト(protivsion-device)を実行するとインストールプロセスが実行される.ぼくの環境だとデフォルトのままだとディレクトリの指定がおかしく,インストール作業が途中で終了してしまったので,そこだけ修正した.具体的には, $OS と, $VENDOR がおかしかった.

// デバイスの確認
$ sudo adb devices
// ボードをfastboot状態にする
$ sudo adb reboot-bootloader
// fastboot状態のデバイス一覧から確認
$ sudo fastboot devices
// インストールスクリプトの実行
$ sudo ./device/qcom/dragonboard/provision-device
// fastbootをぬけて再起動する
$ sudo fastboot reboot

5. 確認

インストールが完了したら,ADBで接続して確認する.

$ sudo adb devices
$ sudo adb shell

なんかこう,Brilloホントにはいってるのかよくわからないんだけど,weavedとかが動いてたりするので,お〜〜〜なるほど〜〜〜〜ってなる.

$ ps | grep weave

なんかこう,Brilloホントにはいってるのかよくわからないんだけど,weavedとかが動いてたりするので,お〜〜〜なるほど〜〜〜〜ってなる.
あとconfigファイルちょっといじるか〜〜〜と思ってもviすら入ってない.Immutable Infrastructure みたいな言葉がよぎるけど,デバッグ時とかめんどくさくないですか……

今後

大きく2つの方向で探ってきたい

  1. Brilloから他のインタフェースを制御する.
  2. Weaveを使って他のデバイス,サーバと連携する.

ひとまず次回以降は,以下について書く予定.

  • DragonBoard上のLEDを使ったLチカ
  • GPIOを使ったIN/OUT制御

www.youtube.com

www.youtube.com

Sony Mesh をハックする LEDタグの使い方編

概要

Sony のMeshで利用するLEDタグのBLE経由での使い方について説明する.
最近がっつり何かに取り組む時間もなかなかとれないので,少しづつ追記していく形にしようと思う.

meshprj.com

経緯

SonyのMeshが市場に出回るようになった.
今日からスイッチサイエンスでも取り扱うらしい.

個人的に,ユーザのためのプログラミング環境にとても興味があって論文読んだり,製品調べたりしていてその一環でいじっている.

じゃあなんでMeshに限ってこんなことしてるのかと言うと,ユーザにとってビジュアルプログラミング言語によるハードウェアまで含めたプログラミングが生活に浸透しうるのか,という点に興味があるからだ.仮説としては難しいと思っているが,そこでどのようなハードルが,実際の一般ユーザにおいては存在するのかということに興味がある.
そのためにはもう少しデータがオープンになって,エコシステムが形成されていく必要があるのではないかと思っていてちょこちょことこんなことをしている.

本エントリでは複数あるタグのうちからLEDタグの利用方法について述べる.
LEDタグには,LightUp, Firefly, Blink, Offという4つの振る舞いが存在する.

LEDタグのBLE Service

LEDタグは,MESH-100LE1000159という名前でアドバタイズしている.

Service UUID プロパティ
Service 72C90001-57A9-4D40-B746-534E22EC9F9E
Characteristics 72C90002-57A9-4D40-B746-534E22EC9F9E Write Without Response
72C90003-57A9-4D40-B746-534E22EC9F9E Notify
72C90004-57A9-4D40-B746-534E22EC9F9E Write
72C90005-57A9-4D40-B746-534E22EC9F9E Indicate

Light Up

Light Upのパラメータは,Color, Brightness, Duration(sec)の3つがある. Color = white, Brightness = 1, Duration = 0.1の際のペイロードデータを以下に示す.

01:00:0c:00:0c:00:0c:64:00:64:00:00:00:01:ee

以下では,2~7Byte目のColor, Brightness,8~9Byte目のDurationについて説明する.

Color

フルカラーLEDが搭載されているためColorは,RGBの3要素の割合によって表現される. 各要素の明るさは,次に説明するBrightnessに基づいて設定される. 各要素は,設定されているBrightnessの値を基準として,その半分の値,オフ(0)という3パターンを取る.なので色は全部で以下の13色が利用できる.

f:id:concre_shiitake:20150801022343p:plain

以下の表では,その時設定されたBrightnessの値を1として,各色を表現する際のRGB各要素の値を示している.

色名 R G B
1 1 1
1 1 0
黄緑 0.5 1 0
0 1 0
緑味の青 0 1 0.5
水色 0 1 1
青味の緑 0 0.5 1
0 0 1
青紫 0.5 0 1
1 0 1
赤紫 1 0 0.5
1 0 0
オレンジ 1 0.5 0

Brightness

LEDの明るさを示す.
明るさは8bitで表現され,以下の5段階をとる.
また,Colorの項で述べたように,RGB各要素では色を表現するために,設定したBrightnessの1/2の値も利用されるので,これも合わせて記載する.

brightness 1/2の値
1 0x0C(12) 0x06(16)
2 0x19(25) 0x0c(12)
3 0x26(38) 0x13(19)|
4 0x52(82) 0x29(41)
5 0x7f(127) 0x40(69)

Duration (sec)

LEDが光る秒数を示す.
Durationは16bitのリトルエンディアンで表現されている.
設定するDurationの値は以下の式で求めることができる.

value = Duration(sec) * 1000        [0.1 <= Duration <= 30]

上記の3パラメータに従うと,以下のような例において,次のようなペイロードによりLEDタグを動作させることができる.

  • 黄緑,brightness = 1, duration = 0.1
01:00:06:00:0c:00:00:64:00:64:00:00:00:01:dc
  • オレンジ,brightness = 5, duration = 0.1
01:00:7f:00:40:00:00:64:00:64:00:00:00:01:89
  • 白,Brightness = 1, duration = 1.0
01:00:0c:00:0c:00:0c:e8:03:64:00:00:00:01:75
  • 白,brightness = 1, duration = 30.0
01:00:0c:00:0c:00:0c:30:75:64:00:00:00:01:2f

シーケンス

Apple Media Service(AMS)を使ってAndroid WearからiPhoneのメディアを操作する話

1. 概要

iPhoneAndroid wearを使う話をしてきた.
で,その仕組み編として,前回の[通知に関するANCS話]に続いて, BLE経由でのメディアの操作や情報取得に関する Apple Media Service(AMS) についての話をする.
アプリを作った当初はこれに気づかずに,iPhone側にBLEで音楽を操作するアプリを仕込んだりしていた.

ぼくみたいなにわかiOSデベロッパが気づきにくい理由としては,AMSに関する解説記事とかブログみたいなものが全くなくて,公式のDeveloper Libraryでひっそりと公開されているだけだからだと思う.

iOS x BLEの参考書として有名な,堤さん(@shu223), 松村さん(@reo_matsumura)の,iOS×BLE Core Bluetoothプログラミング 本にもAMSのことは載ってなかったと思う.

www.amazon.co.jp

なので,メディア操作,楽曲情報取得に絞ってではあるが,簡単な解説記事を書こうと思う.

2. AMS: Apple Media Service の概要

これを利用して,BLE経由でiPhoneの音楽やビデオといったメディアが制御できるようになる. iPhoneの画面を下からスワイプした時にでてくるドロワーに音楽操作したり音量変えたりできるGUIがあるけど,あれをBLE経由で操作できると考えるといいと思う.なので,音楽だけでなくて,例えばビデオなんかも制御できる.

だから例えば,スマホ経由での操作だけじゃなくて,
BLEと慣性センサが載ったオリジナルデバイスからiPhoneのメディアを操作したりといったことがお手軽にできるようになる.

制御としては,次のようなことができる.

  • 再生/停止
  • 前の曲に戻る,次の曲に進む
  • 音量Up/Down
  • 曲情報や,プレイヤーアプリ状態の取得

補足: AMS用語

  • MS: Media Source
    • iOSデバイス等のメディアを保持,再生するデバイス
  • MR: Media Remote
    • MSのメディアを遠隔から操作するアクセサリデバイス

3. AMSのもつCharacteristicsについて

AMSは以下のUUIDのService,Characteristicsを持つ.これらのCharacteristicsの概要と利用方法は以降で述べる.

名前 UUID プロパティ 機能
Service Apple Media Service 89D3502B-0F36-433A-8EF4-C502AD55F8DC
Characteristics Remote Command 9B3C81D8-57B1-4A8A-B8DF-0E56F7CA51C2 write メディア,音量の操作
Entity Update 2F7CABCE-808D-411F-9A0C-BB92BA96C102 read, write, notify メディアや,プレイヤーアプリ情報のやりとり
Entity Attribute C6B2F38C-23AB-46D8-A6AB-A3A870BBD5D7 read, write EntityUpdateでは大きすぎるデータのやりとり

3.1. Remote Command Characteristic

このCharacteristicにコマンドを書き込むことで,メディアの操作(再生停止,前,次)や音量の操作を行う.

  • コマンド

以下のような,命令したい1Byteのコマンド(RemoteCommand)を書き込む.

Byte 1
Value RemoteCommendID
  • Remote Command IDの種類

現在は以下の11種類が提供されている.それぞれの機能はコマンド名そのまんま.

コマンド名 Value
RemoteCommandIDPlay 0
RemoteCommandIDPause 1
RemoteCommandIDTogglePlayPause 2
RemoteCommandIDNextTrack 3
RemoteCommandIDPreviousTrack 4
RemoteCommandIDVolumeUp 5
RemoteCommandIDVolumeDown 6
RemoteCommandIDAdvanceRepeatMode 7
RemoteCommandIDAdvanceShuffleMode 8
RemoteCommandIDSkipForward 9
RemoteCommandIDSkipBackward 10

3.2. Entity Update Characteristic

再生するメディアの情報やプレイヤーアプリの状態をやりとりする.Notifyを申し込んだ後に,欲しい情報を以下のコマンドを利用してCharacteristicに送信することで,その情報がNotifyされるようになる.

  • コマンド

以下のように,1Byte目でエンティティを選択,2Byte目以降でそのエンティティの中で取得したいアトリビュートを指定する.アトリビュート複数指定することができる.

Byte 1 2 3
Value EntityID Attribute1 Attribute2
  • Entity IDの種類

Entityは以下のようなものがある.例えば,曲情報が欲しい場合には "2"というEntityIDを使う.

名前 Value 説明
EntityIDPlayer 0 プレイヤーアプリ名や再生状態,音量に関するエンティティ
EntityIDQueue 1 メディアQueueに関するEntity
EntityIDTrack 2 曲等のTrackに関するEntity
  • TrackAttributeの種類(EntityIDTrackの場合)

EntityIDごとのAttributeについては公式資料を確認して欲しい.ここでは,例としてEntityIDTrackを指定した場合に選択可能なAttributeについて説明する.

名前 Value 説明
TrackAttributeIDArtist 0 アーティスト名
TrackAttributeIDAlbum 1 アルバム名
TrackAttributeIDTitle 2 曲名
TrackAttributeIDDuration 3 曲の長さ(秒単位)
  • コマンドを送信するコードの例

Notifyを申請した後に,その成功/失敗がonDescriptorWriteを通して通知される.成功だった場合に,以下のようにコマンドを送信して欲しい情報を申請する.この例では,EntityIDTrackのうち,曲名とアーティスト名に関する情報を取得する.

 @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            Log.d(TAG_LOG, " onDescriptorWrite:: " + status);

            // Notification source
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.d(TAG_LOG, "status: write success ");

                //find AMS
                BluetoothGattService service = bluetooth_gatt.getService(UUID.fromString(service_ams));
                if(service != null) {
                    BluetoothGattCharacteristic chara = service.getCharacteristic(UUID.fromString(characteristics_entity_update));
                    if(chara != null) {
                        chara.setValue(new byte[]{(byte) 0x02, (byte) 0x00, (byte) 0x02});
                        bluetooth_gatt.writeCharacteristic(chara);
                    }
                }
            }
        }

Notifyされてくるデータ

  • パケット構造

1Byte目にエンティティを示すIDが入っており,2Byte目にAttributeを示すIDが入っており,4Byte目以降は実際の情報が入っている.

  @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            Log.d(TAG_LOG, "onCharacteristicChanged:: " + characteristic.getUuid().toString());

            if (characteristics_entity_update.toString().equals(characteristic.getUuid().toString())) {
                Log.d(TAG_LOG, "entity update ");

                byte[] get_data = characteristic.getValue();
                String music_info = characteristic.getStringValue(3);
                Log.d(TAG_LOG, "new music info: " + music_info);

                if(get_data[1] == (byte)0x00) {
                    Log.d(TAG_LOG, "get artist info: " + music_info);
                }else if(get_data[1] == (byte)0x02) {
                    Log.d(TAG_LOG, "get title info: " + music_info);
                }
            }
        }

Entity Attribute

Entity Updateでは,データが大きすぎて伝えられない情報をやりとりする.
ちなみに作成したアプリでは,Android wearで表示する文字が多くなると文字が小さくなって見づらくなるのでこれを利用していない.

  • パケット

取得したい情報のEntity,AttributeのIDを指定する.

Byte 1 2
Value EntityID AttributeID

3. シーケンス

3-1. 準備

AMSのEntityUpdateCharacteristicを探してほしい情報を登録すると,曲が変わったタイミングなどでNotifyされてくる.

fig2-2

3-2. メディアの操作

RemoteCommandCharacteristicを探して,操作したいコマンドを送信すると,MS側でその操作が実行される.

Fig 2-3

3-3. メディア情報の取得

3-1. 準備 の手順で曲名の一部(曲名が長い場合は先頭のみ)が送られてくるが,正式なタイトル情報が知りたい場合はEntityAttributeへコマンドを書き込み情報を読み出す.

Fig2-4

4. まとめと実際のコード

音楽のアーティスト名と曲名を取得するという例にそって,AMSの使い方を簡単に説明した.
シンプルなので,BLE Centralなプログラムが書ける人には難しくないと思う.
実際にアプリの中では,MusicControlActivityの中で利用している.

Android wearをiPhoneで使えるようにした話 - いきさつなどと,仕組み編その1 -

いきさつと整理

だいぶ前のエントリで書いたように,iPhoneでAndroidWearを使えるようにした.

github, APKのリンクと,Playストアリンク

そもそも何に貢献してるのか

Android Wear端末をAndroid OSの載ってるスマホ以外で使えるようにした.
AndroidWear端末のRootを取ることも,iPhoneを脱獄する必要もない. (Root取ると,iPhoneだけで時刻同期ができるようになる.)

Android WearはAndroid用のスマートウォッチなのでそのままだとiOSみたいな異なるOSを使ってるスマホの通知を受け取ったりすることができない.
つまり,iPhoneならApple Watch以外選択肢が無い!という状況を変えることができる.

できること

  • 通知の確認,削除
  • 電話着信の確認,応答/拒否
  • 音楽とか動画の操作とタイトル表示
  • Androidスマホ無しでの時刻合わせ(これだけAndroidWear端末のRoot化が必要)

  • 最近の動画

アップデートする度に動画をYoutubeに上げてる.これは一番最近あげた動画.

www.youtube.com

他にもぼくのチャンネルにいろいろあげてる. www.youtube.com

なぜこれまでこのようなアプリがでてこなかったのか

Android Wearの主眼はNotificationを中心としたユーザとのインタラクションだと思う. そのためAndroidが提供しているフレームワークでは,Notificationを抽象化したAPIを提供することで,スマホ側の通知を簡単にWear側に出したり,それに対するアクションを行うことができる.よってAndroidWearの活用としてはこれが主眼となっており,そもそもこのような提供されたフレームワークから逸脱し,iOSに対処するという考えがあまりなかったのかと思う.(そもそも持ってる人少ないという問題がある……)

この資料がサクッとつかみやすいと思う.

ではどうすればiPhoneに対応できるのか

方法としては以下の2つが考られる.

  • iOS側で対応する

    • iOS側での対処としては例えば,ANCSをAndroid Wearが解釈できるIntentに変換する,
  • Wear側で対応する

    • Wear側での対処はANCSをWearが解釈するメソッドを実装する.

先のSlideshareにもあったように,AppleはANCS(Apple Notification Center Service)というものを利用することを推薦していますので,Wear側でANCSに対応できればよいことになります.
また,Apple watchではBLEを利用するためのAPIが提供されていませんが,Android wearでは提供されているため,実装がしやすいです.
Appleの開発者によると,WatchOS2でも提供していないとのこと……)

次回

Android wearでANCSを解釈するメソッドを実装するために,その仕様について解説します.
ANCSの概要とか,とっかかりについてはいくつかのブログ記事が見られますが,実際に欲しい通知を受け取ったり,通知に対するアクションを送信したりといったところを触れている資料がないのでそのへんを中心に書きたいと思います.

おまけ

iPhoneAndroid wearを使えるようにするアプリのこれまで.

  • @MohamadAGがプロトタイプを作成,動画がバズる.未だに公開されていない.
  • @Shiitakeo(ぼく)がMohammadAGの動画を見て触発され,アプリをフルスクラッチで作り,github,PlayStoreで公開する.日本で全然バズんないけど外国の方には結構人気.
  • @Shiitakeoが,iPhoneAndroid wearの接続が切れた後に自動再接続を行うためのiOSアプリを作成.AppStoreでリジェクトされたため,Cydiaで公開.
  • @Skytek65が@shiitakeoのコードをフォークして,アイコンや,利用方法の動画を加えたアプリを公開.その後のアップデートはなし.
  • AppStoreで公開されているBLEUtilityでも自動再接続が可能なことに気づき,iPhone側で利用するアプリをLightBlueから変更.
  • @alialmahdi が自作したとTwitter,ブログで発言.リジェクトされたという発言の後,特に言及,アプリ公開はない.
  • @GuiyeCがShiitakeoのアプリをフォークし,アプリアイコンやアプリ名の変更,通信シーケンスの改善等を行う.マーケット公開済み.

ぼくは,こんなことできるかなっていうのをプロトタイピングしながら確かめていくのが好きで,今はこのアプリより他のことやりたい(というか他のことしかしてない)ので,熱意のありそうな@GuiyeCさんが引き継いでいい感じのアプリに成長させていってもらえるとうれしいなあと思ってます.OSS感あって新鮮な経験でした.