2017年7月16日日曜日

Pebble TimeでWatchfaceを作った時の色々

色々終わってしまってて遅いのですが。ここ数日でまたPebble TimeのWatchfaceを作っていました。どうせなので作業手順を晒しておこうという感じです。ドット絵を用意して、アニメーションとしてWatchfaceに組み込んでみた話になります。



0. 環境
WindowsでPebbleの開発を行うなら、やはり公式ガイドで説明されているように仮想マシンを用意するのが一番良い手ですね。重いのは仕方ないとして。

使った環境はVirtual boxでのUbuntu 16.04で、割り当てメモリは1024MB、ストレージは16GBです。
動きが貧弱なので、基本的にWindows側で素材を作ってから仮想OSを立ち上げて、設定しておいた共有フォルダ経由で移動させて…という形を取っていました。


以前、Winodow10のBash on Ubuntu on Windowsを使ってPebble開発ができるというネタを書きましたが、いくつかWatchfaceを使ってみて止めておいたが良いなと感じました。
SDKを突っ込んで作ることはできますが、折角Pebbleに用意されている「Pebbleと接続している端末のIPアドレスを指定してインストール」の機能や「実機のログを取得」が使えないというのが勿体無いです(このあたりは、SSLErrorとあるのでネット周りが改善すれば使えそうですが)。後はQEMUで用意されているエミュレータが使えないというのも若干痛いというのも。





1. 素材の作成
アニメーションを付ける為、Edge(ドット絵を作れるエディタ)で必要なものを作り、透過やディレイを設定してからgifの形で保存。ちなみに使える色はColor Pickerで確認できます。なおこちらに乗っていない色も自動で補正してくれるので、あまり気にしなくても良い気がします。

ドット絵である必要がなければ、そのままGIMPから開始して良いと思います。


2. GIMPでgif読み込み、再保存
Edgeで作成したgifをそのまま持っていくと最終的にPebbleで実行時に「failed to load palette」で落ちるので、GIMPで形式を変更します。
そのまま対象のgifをインポートした上で、ツールバーから「画像」->「モード」を選択し、「RGB」に変更します。 多分変更前は「インデックス」になっていると思います。
変更後はgifとしてエクスポート。

3.gif2apngでapngを作成
Pebbleはgifには対応せず、apngという形式を要求しているので、そちらに変更します。
gif2apngは、http://gif2apng.sourceforge.net/ からダウンロード。公式ガイドではgif2apngはCUIで実行していますが、GUIでも問題ありません。ただし、必ず変換前に右下の設定ボタンから設定画面を開いて、
Compression Method: zlib
Optimization palette: unchecked
という設定をするのを忘れずに。CUIでは「-z0」のオプションを付ければOKです。
なお、apngの拡張子はpngです。


4.フォントの用意
システムフォント(デフォルトで用意されているフォント)を使いたくない場合は、拡張子がttfのフォントファイルを用意します。ただ、システムフォントの一覧を見ると結構数があるようです。

5. 仮想OSの起動とプロジェクト作成
ここで仮想OSの方を起動します。起動後はpebble new-project watchface <name>でプロジェクトを作成します。作成後は「resources」というディレクトリを作成して、そこに、ホストOSで作成した素材を保存します。
Virtual boxなら設定すればドラッグ&ドロップでホストOSからデータを持ち込めるはずなのですが、どうも上手くいってないので、共有フォルダの設定をした上で
sudo cp /media/<filename>/<data> <path>
と打ってデータをゲストOSに持ち込んで、chmodで権限を変更して使っています。

6. コードを書く,package.jsonの編集
普段からEmacsなので、ゲストOSで作っていますが、別にこれもホストOSで書いてからゲストOSに持ち込んでもいいのかなという気はしています。
package.jsonには、素材の分だけmediaに登録します。

7.ビルド,インストール
ビルド後は、buildディレクトリの中にpbwファイルが作成されます。これが本体です。
buildが正常に終了しているのであれば、pebble installします。
実機にインストールしたい場合は、実機と接続している端末(iPhone/Android)のPebbleアプリをsettingsからdeveloperを選択して、実機を通信待機状態にし、そのうえでpebble install --phone <IP address> します。
IPアドレスは、端末アプリのdeveloperを選択すれば確認できます。

エミュレータの場合は pebble install --emulator <version> とすれば動きます。ここではPebble Timeなので、pebble install --emulator basaltです。
(自分の環境だとかなり時間がかかってしまった為、これは実機でいいと思いました)
ちなみに、どちらの場合も--logsオプションを付けるとログが出力されます。実行時エラーは大体これで分かります。
動作確認ができ、ストアに登録する予定があるならば、この時点で
pebble screenshot <FILENAME>
と入力してスクリーンショットを取っておくと良いと思います。


8.ストアに登録
せっかくなのでストアに。 
固有のUUIDが必要なので、https://www.uuidgenerator.net/ でUUID(version 4)を生成。
(もともとpackage.jsonにUUIDは書いてあるのですが、自動生成されてるか分からなかったので念の為)
https://dev-portal.getpebble.com/developerにアクセスして、開発者用のアカウントを登録。後は書いてある通りに設定すれば簡単に登録できます。
なお、Package.jsonで指定した対応端末の分だけスクリーンショットが要求されます。面倒だったので、Basalt(Pebble Time)のスクリーンショットを使い回して登録しましたが。
Publishでストアに登録して、30分程で登録画面にストアへのリンクが表示されます。



2017年1月15日日曜日

pydbgをMSYS2環境で使いたいけどできない

未解決です。


「リバースエンジニアリング Pythonによるバイナリ解析技法/Justin Seitz 著,安藤慶一 訳」を触っていたのですが、途中でpyDbgが必要になったのでメモです。

MSYS2の環境で、python2.7を利用しました。
初めはmingw64でコード書いていたのですが、CPUのレジスタ確認のコードあたりで、エラーが出てないのにすべての値が0x0になるという事態が起きていて、不安だなと思っていたところ、
https://github.com/OpenRCE/pydbg のpyDbgを導入したらpyDbg内のwindows_h.pyのでassert文によるエラーが出てしまいました。


AssertionError: 8

windows_h.pyを見るとsizeofによる構造体のサイズ確認だったようで、MSDNの方で確認すると32bit環境と64bit環境でサイズが違うからそのエラーなんだろうと思い、適当にassertを全部コメントアウトして動くか確かめたところ、windows_h.pyを抜けた先で、

import pydasm
ImportError: DLL load failed: %1 は有効な Win32 アプリケーションではありません。

となりました。

pydasmに関しては、本でもpython26.dllをpython27.dllに書き換えるなどの指示があったのでそのあたりをいじったのですが、駄目でした。
pydasm.pydが32bit用だからということで、64bit環境のものを探せばいいだろうと思ってもうまく動かず。


諦めてmingw32にpython2.7入れることにしてpyDbg(今度はhttps://github.com/reider-roque/pydbg-pydasm-paimeiから)を用意したところ、pydasmで「指定されたモジュールが見つかりません」に。
(確かこのときsetup.py installでpydasmのインストールでMINGW用のpydasm.pydがないとかいうエラーが出ますが新しくmingw-2.7とかフォルダを作って、内部にwin向けのpydasmを入れたら成功します、動きませんが)
dependency walkerとかを使って色々調べていたのですが、全然わからず諦めようかと思っていたところ、


Now, go to C:\Python27\Lib\site-packages\pydbg and delete the pydasm.pyd file (it’s compiled for an older python version and it causes the pydbg library not to load)

という内容を発見。試しにpydasm.pydをpydasm_tmp.pydなどにリネームしたところ、実行中のプロセスを列挙するテストコードが動きました。


dbgObj = pydbg()  # Create PyDbg object
print dbgObj.enumerate_processes()
これでとりあえず行けるだろうと思ってそのまま進めていたのですが、今度はpyDbgを利用してprintfが実行されるタイミングでメモリを書き換える(printf__random.py)という部分でまたこけました。
Traceback (most recent call last):

  File "printf_random.py", line 27, in <module>

    dbg.run()

  File "C:/mingw-w64/msys64/mingw32/lib/python2.7/site-packages/pydbg/pydbg.py", line 2900,in  run

    self.debug_event_loop()

  File "C:/mingw-w64/msys64/mingw32/lib/python2.7/site-packages/pydbg/pydbg.py", line 942,in  debug_event_loop

    self.debug_event_iteration()

  File "C:/mingw-w64/msys64/mingw32/lib/python2.7/site-packages/pydbg/pydbg.py", line 875,in  debug_event_iteration

    continue_status = self.event_handler_load_dll()

  File "C:/mingw-w64/msys64/mingw32/lib/python2.7/site-packages/pydbg/pydbg.py", line 1458,in event_handler_load_dll

    dll = system_dll(self.dbg.u.LoadDll.hFile,self.dbg.u.LoadDll.lpBaseOfDll)

  File "C:/mingw-w64/msys64/mingw32/lib/python2.7/site-packages/pydbg/system_dll.py", line 96, in __init__

    self.path = os.sep + filename.value.split(os.sep, 3)[3]

IndexError: list index out of range

[1]+  終了 3                  python printf_loop.py
 なんでpyDbgの中でインデックス超えるエラー出てくるんだと数時間戦ったのですが、printなどで出力してみると、system_dll.pyの自身のパスを格納する作業でパスの切り分けがうまいこと出来てないようでした。
#system_dll.py line96周辺
 self.path = os.sep + filename.value.split(os.sep, 3)[3]
ここに出てくるos.sepというのは、OS毎のパスの区切り文字のようで、Winであれば\ であるはずのものです。ここの区切り文字とfilenameのパスで使われている区切り文字が異なっていた為にうまいこと切り分けが出来ず、インデックスのエラーが起きたと思われます。MinGW環境なのが失敗だったのでしょうか。
とりあえず該当部分を
self.path = os.sep + filename.value.split("\\", 3)[3]                             
に変更。
 これでIndexErrorは消えたぞと思ったら、今度はメモリの読み書きを行う
#printf_random.py内
counter=dbg.read_process_memory(parameter_addr,4)
dbg.write_process_memory(parameter_addr,random_counter) 

が変な動きをしているようで読めないし書き込めないしでsegmentation falutを起こしてました。
未解決なので、気が向いたら調べてみようと思います。どうすればいいんだ…。 
というか大人しくMSYS2とか使わないで進めればこんなことにならなかったような…。

2016年12月13日火曜日

今更Pebble Timeを買った話を

この記事は、腕時計Advent Calender 2016 第12日目の記事になります。
毎年何かしらのアドベントカレンダーに参加できたらいいなとは考えては突っ込んだりしているのですが、更新が遅くなりすみません。
 
腕時計という話なので、半年ほど前に買ったスマートウォッチに関して雑感を書こうかなと思います。
ちなみに環境としてはPebble Time+iPhoneです。
 

Pebble Timeを買ったわけ


Pebbleが気になった理由と言えば、「アプリや盤面を自分で手軽に作ることができる」からでした。もともと本当に小さいプログラムをちょこちょこ書いて遊んでたりしたのですが、コンピュータ以外の実機で自分の作ったものが動く姿を見たいなと思っていたところに、Pebbleというスマートウォッチの話が転がってきて、しかも2万切って購入できるというので、気が付いたらポチっていた感じです。
非スマートウォッチからスマートウォッチに変えるという差ですが、もともと自分が普段から腕時計に関して求めていたのは「雑に扱ってもついてきてくれる耐久性がある」と「電池と時間ズレを気にせずに使える」という2点で、プログラミング用以外の単なる腕時計としてみても、十分要件は満たしていたのであまり気になりませんでした。


本体


ネットで見たままのものが届いたなという感じです。手元に来る前は、正面から見ると表示可能面積が小さいかなと不安に思う部分もあったのですが、使っているうちに慣れました。飲み会に持っていくと「AppleWatch?」って聞かれるのでネタにできます。半年使ってシリコンベルトがかなりへたってしまっていますが、交換できそうなので検討中です。


プログラミング練習用として


文字盤とアプリという2つのものを作って遊ぶことができます。文字盤はボタン入力を受け付けないようになっていて、潔くて良いと思っています。開発環境はかなり整えられており、きちんと設定すればwebIDEで書いてそのまま本体に転送という技も可能です。webでなくても、ツール落として書いてビルドして転送までコマンドでできてしまうようです。自分の環境ではうまくいかなかったのですが、それでもコンピュータで書いてDropbox経由でiPhoneに送ってPebbleに乗せるという形で遊べるので楽しいです。
 

文字盤が変えられる楽しさ


「今日はデジタルにしよう」「今日は時間配分を気にするからアナログの方が都合がいい」「カレンダーが見れるのが欲しい」など、好き勝手選べるのは面白いです。
 

スマートウォッチとして


買った理由が理由なので、あんまりスマートウォッチでよく押されているような通知などにこだわってはいませんでした。届いてから数日は、思ったより振動に気付けないという事態が続いていましたし(これは1週間くらいで慣れましたが)。ただ、通知を受け取れることに慣れてから、携帯を別の部屋で充電しながら、離れた場所でLINEやメールを受け取ったりできるようになるというのは、結構開放感がありました。通知で相手の名前や要件を確認して急ぎであれば対応すると、事前に振り分けできるのは後から嫌な気持ちにならなくて助かります。
 
あと、電話に気付く確率がかなり上がったのは本当に良かったです。連続で震えるとさすがに気づくし、電話番号が出ているのもありがたい。欲を言うのであれば、Facetimeの着信でも電話と同じように連続で震えてくれたらいいのになんて思いますが。

予定の確認ができるというのも売りになっていましたが、予定そのものはPebbleでは見ないかなという感じです。ただ、予定のタイトルを授業名と教室にしておくと、10分前くらいに教えてくれるという使い方を発見してからは、いちいち時間割を確認しなくてよくなったので重宝しました。



アプリはそこまで使わない


Pebbleの押しとして、いろんな人が作ったアプリを使えるというのがありますが、買って数か月くらいであまり使わないなと思いました。todoアプリと連携させてすぐにみられるのは便利かもと思ったのですが、自分が外にいる時は、腕時計をしている左腕に荷物を持つことが多いので、持ちあげたりボタン操作したりが意外と煩わしくて習慣にならないという感じです。
ただ、タイマーはよく使います。プレゼンでのカウントとカップラーメン用に。特に前者は。かなり大きく表示してくれる上に、割とどこでも持ち込めるので助かっています。
 

スマートウォッチ最高にはならなかった


なんだかんだ買ってみて便利なので満足していますが、「もう手放せない」とはならない感じです。こういう高機能なものは一度使うと戻れないようなイメージが強かったので、変化がなかったのには結構驚きました。見た目的にスーツとは合わせられないので、そういう時は外していくのですが、「Pebbleだったら…」と思うような機会は全くありませんでしたし。
PebbleもFitbitに買収で販売終了という話も持ち上がっていますが、もう二度と買えないとか買い置きしようとはならない感じです。残念だと思うし販売継続してほしいですけど。こう感じるのは、Pebbleの出来がどうのこうのというわけではなくて、自分の性分に寄るのだと思います。正直スマートウォッチにドハマりしてほかの腕時計を「デザイン的につけてみたいけど機能的に我慢できない」という状態にならなくて安心していたり。


最後に


なんだかんだ言ってますがPebbleは非常に好きです。壊れるまで遊び倒そうと思いますし、色々作って楽しみたいと思っています。あとFitbitはPebbleの作ってきたストアとか開発のシステムとか何らかの形で引き継いでくれたらなと願っています。