読者です 読者をやめる 読者になる 読者になる

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

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感あって新鮮な経験でした.

AlternoteでEvernoteに保存したMarkdownを,Markedでプレビューするやつを作った話.

概要

軽量EvernoteクライアントであるAlternoteを使ってMarkdownでメモをとり,
それをMarkdownビューワであるMarkedでプレビューするものを作った.

これは,設定さえしておけば,いつものメモ動作にHotkeyを一発加えるだけで実行できる.
また,最終的にEvernoteにデータが保持されるのであれば,エディタはなんでも良い.
以下の図のような感じでプレビューできる.右の黒いアプリがAlternoteで,左側のMarkdownビューワがMarkedである.

f:id:concre_shiitake:20150726170959p:plain

Markdownが好きだ

Markdownはいい感じだ.
メモをMarkdownで取ると,構造化されたメモがわりと簡単に取りやすい.
だからみんなMarkdownのこと結構好きだと思う. そんなこともあってオンラインストレージを使ったMarkdownメモツールというのがいくつかあって,ぼくもこれまで色々試してきた.

例えば,Vim用にはEverVimがあったり,
ブラウザから利用可能なwri.peがあったり,
MaciPhone用のアプリではDayOneがあったりする.

github.com

wri.pe

dayoneapp.com

と,色々試してきたし,どれも好きだったんだけどメモがとりにくかったり,シンタックスハイライトが微妙だったり,見返しづらかったりして結局定着しなかった(個人の感想です.)

で,最近はAlternoteというMac用の軽量Evernoteクライアントを使っていた.
Evernote,クライアントは重いしメモとるのめんどくさかったりと個人的にはだいぶ好きじゃないんだけど,Alternoteはそのへんがけっこうよかった.
ただ,EvernoteはなぜかMarkdownに対応してないので,そこをどうにかする必要があった.

Evernoteに書いたMarkdownをプレビューしてきた先人たち

まあこれは色々いらっしゃる.
個人的には,MacでMarkdown書くときは,Vimで書いてvim-quickrunでMarkedを呼び出してプレビューしていたので, 同じようにMarkedを使っている人を探した.

以下の方はEvernoteで最も最近更新されたメモをMarkedで表示するシェルスクリプトを書かれている.
ただEvernoteがバージョンアップしてディレクトリ構造が変わったのでこのスクリプトはもう動かなかった.

turubee.hatenablog.com

今回作ったものを利用する流れ

というわけで,先人のプログラムをForkして,以下のような流れで動くようにした.
今回新たに作成したプログラムは以下の2つ.

  • Evernote更新取得アプリ

    • Evernoteを開いて同期を行い,他のエディタで行ったEvernoterメモへの変更をクラウドからローカルに取り込むプログラム
  • Evernote更新検知アプリ

    • ローカルに保存されているEvernoteデータの更新を検知して,プレビューアプリを起動するプログラム

これらを利用する流れは以下のようになる.

  1. Evernote更新検知アプリを起動しておく.
  2. Alternoteでメモを書いて保存・同期する.
  3. Hotkeyを叩いて,Evernote更新取得アプリを起動.
  4. Evernote更新検知アプリが更新を検知して,Markedでプレビュー.

つまり,人が行う動作としては,

  1. Evernoteの更新を検知するアプリの起動(初回のみ)
  2. Alternoteでメモを書く
  3. 保存
  4. Hotkey押下

のみであり,これまでのメモ動作にHotkeyを加える形になる.
すると,以下の図のような感じでMarkedでプレビューが実行される.

f:id:concre_shiitake:20150726170959p:plain

プログラムの作成

Evernote更新検知アプリ

シェルスクリプトAutomatorを使ってアプリに固めたものを利用する.

turuさんのシェルスクリプトを基に最新版のEvernoteに対応させたプログラムを保存しておく.ID(ユーザ名ではなく数字7桁のID)は自分の環境に合わせたものをシェルスクリプトに記述する.
保存したら,Automatorを開き,アプリケーションの作成を選択.
以下の図のようにシェルスクリプトを登録しておく.ディレクトリは各自の環境に合わせて変更して欲しい.
あとは保存の際に保存形式をアプリケーション(.app)にして,/Applicationディレクトリとかに入れておく.デフォルトだと裏で動き続けるプログラムなので,ログイン時に起動させたり,Alternote起動させるときにいっしょに起動するなどして欲しい.

f:id:concre_shiitake:20150726173224p:plain

Evernote更新取得アプリ

Hotkeyで呼び出すプログラムを,サービスとしてAutomatorで作る.

EvernoteクライアントはAppleScirptをサポートしているので,以下のAppleScriptEvernoteの同期を実行することができる.

on run {input, parameters}
        tell application "Evernote"
    
            synchronize
    
            repeat until isSynchronizing is false
            end repeat
        end tell
    return input
end run

このスクリプトを組み込んだ以下の図のようなAutomatorサービスを作成し保存する.これは,Evernoteを起動し,同期を実行したらAlternoteを起動する,というプログラム.

f:id:concre_shiitake:20150726173442p:plain

サービスを保存したら,Macのシステム環境設定から,ショートカットキーで作成したサービスを呼び出すように,以下のように設定する.
(名前は自由に設定すれば良い.ここではAlternote_viewerという名前をつけていた.) Hotkeyは好みなので自由に変えて良い.

f:id:concre_shiitake:20150726173456p:plain

補足

今回,AlternoteをEvernoteエディタとして利用しているが,ここはVimでもEmacsでも,公式Evernoteクライアントでもなんでもいい.
(でもVimとかだったらquickrunからMarked呼び出したほうがラク)

公式クライアントを使う場合は Evernote更新検知アプリのみが必要になり,Evernote更新取得アプリは必要ない.

iPhoneについて

個人的にはiPhoneみたいなスマホでmarkdownをプレビューする必要はあんまりないと思ってる.
それよりも,markdownを使って出先でサクッとメモをとって,家のMacで読み返すっていう使い方をしてる.
ただ,iPhone向けのEvernoteクライアントはなんかしっくりくるのが見つかってないので,このへんもなんか考えたい.

Docker + gitBucket + Dropboxでプライベートgithubな話@さくらVPS

概要

Docker上でgitBucketコンテナを動かして,gitBucketのデータ置き場をDropboxにする話.
環境は,CentOS6.5なさくらVPS.
プライベートgithub的なやつをつくろう!

経緯

さくらVPSを借りているんだけど,最近はいろいろと便利なサービスがあって,正直全然使う機会がなくなってる.

一方で,githubのプライベートリポジトリが使いたくて月額課金しているんだけど,これが地味に痛い.bitBucketとか,gitlabとか微妙に使いづらいからしょうがないかと思ってたんだけど,最近gitBucketというgithubクローンが結構いい感じなことを知った.

そんで,gitBucketのDockerイメージがDockerHubにあったので,さくらVPSにDocker導入しようと思った.
環境移行するときのラクさも考えて,データはDropboxに置くことにした.


環境

  • CentOS 6.5(kernel 2.6.32-431.11.2.el6.x86_64)

    さくら借りた時にデフォルトだったやつです.

事前準備:dropboxとの連携

dropboxをサーバで使えるようにしておく.例えばこの方のブログなどが参考になりそうだと思う.

Dockerをいれる

このへんは公式の手順どおりにいく.
yumを使うと1.5.0が入るので,最新版が欲しければyumを使わない方法が公式に載ってるのでそれを参考にする.

# docker のインストール
$ sudo yum install device-mapper-event-libs
$ sudo yum -y remove docker
$ sudo yum install docker-io
# docker初期設定
$ sudo service docker start
$ sudo chkconfig docker on
# sudoしなくていいようにdockerグループに追加
$ sudo usermod -aG docker user
$ exit
# 動作確認
$ docker info

gitBucketをDropboxにデータ置くように設定して起動する

以下のコマンドで行う.このコマンドだと8080にアクセスするとgitbucketにアクセスできる.
デフォルトユーザは,IDパスともにroot.あとはふつーのgithubみたいに使える.

# gitbucket用のディレクトリをDropboxに作る.
$ cd Dropbox
$ mkdir gitbucket
# Dropboxと紐付けてgitbucketコンテナを起動する
$ docker run -d -p 8080:8080 -v /home/user/Dropbox/gitbucket:/gitbucket sken/gitbucket

おまけ:githubからリポジトリを移行する

この方のブログを参考にした. githubからリポジトリをまるっと取ってくる.タグとかブランチもそのままもってこれる.

# githubから該当リポジトリを手元にミラーオプションでクローン
$ git clone --mirror <SOURCE_REPOSITORY_URL>
$ cd <REPOSITORY>
# gitBucketで移行先リポジトリを作っておく.ミラーオプションつけてプッシュ.
$ git push --mirror <DESTINATION_REPOSITORY_URL>

SonyのMeshをハックしている話

概要

Sony のMeshがやってきたのでハックしてる.
ひとまずタグの白色LEDiPhoneアプリから制御できるようにした.
公式のアプリは使っていない.

youtu.be

Meshがどんなもんかっていうと,Makeクラスタの人にとって一番わかりやすいのは,未踏で開発されたTangramだろう. 単機能な電子ブロックをネットワークでつないで,アプリケーションを実現する. www.trangram.cc

もうちょっとどういうものか知りたければ,公式ページはもちろん,以下の様なページがある.

現状の不満

で,現在目立った不満としては,大きく,タグと開発環境(アプリ)の2点が挙げられると思う.

  • タグの種類が少ない.
    • 個人的にGPIOタグはチートすぎるし思想とズレてる感じもするし死ぬほどダサいと思ってる.
  • 開発環境がiPadだけ.
    • ソフトがめっちゃ重い.
    • バックグラウンドで動作しない.

となればすることはひとつで,Meshの通信プロトコルの解析です.
これができれば,タグを自前で量産することも,AndroidアプリやiPhoneアプリを作ることもできていい感じだと思う.

というわけで,ひとまずMeshタグの白色LEDを制御するiPhoneアプリを作った.
ただこれが正しくハックできているかというと結構微妙なところで,各タグの機能(ボタンとかLEDとか)はちょっとまだバグがあって公開にはもう少し時間がかかる感じです.
お楽しみに〜👋

youtu.be