[スマート?][ヒゲ?] Higerable Deviceが今(だけ)俺の中で熱い!

 藪下@2課のガジェオタです。

 ちょっとあまりにおもしろかったので記事の紹介を。

世界初のヒゲ型ウェアラブルデバイス TRIPLESSO “Higerable Device”登場 2014年3月27(木)体験ムービー公開
http://sankei.jp.msn.com/economy/news/140327/prl14032714380089-n1.htm

 買う気は全くしないですが一度試してみたいですね。
 どこかでトライアルイベントやってくれないかなー。

[Firefox OS][お知らせ][イベント情報] FxOSコードリーディングミートアップ#6を開催します

 藪下@2課のガジェオタです。

 4/22にFxOSコードリーディングミートアップの六回目を開催します。
 いつもは金曜日にやることが多いんですが今回は火曜日です。

FxOSコードリーディングミートアップ#6
http://atnd.org/events/48791

 四月は出会いの時期です。FxOSコードリーディングミートアップでFxOS好きな人たちと出会ってみませんか?

[Firefox OS][WebAPI] Idle APIの使い方

 藪下@2課のガジェオタです。

 先週の続きでFxOS勉強会のLTネタ解説5回目を書こうと思っていたんですが、思ったより時間がかかりそうなので別のAPIを 解説することにします。
 今回はIdle APIの使い方を見ていきます。

目次

  • Idle APIのインターフェイス
  • 使い方

Idle APIのインターフェイス

 Idle APIの主なメソッドはnavigatorに用意されている以下のメソッドになります。

partial interface Navigator {
  void addIdleObserver(IdleObserver);
  void removeIdleObserver(IdleObserver);
};

 void addIdleObserver(IdleObserver)とvoid removeIdleObserver(IdleObserver)はそれぞれアイドル時とアクティブ時に通知されるハンドラと秒数を表すオブジェクトIdleObserverを受け取ります。

navigator.addIdleObserver(IdleObserver)

 addIdleObserverはIdleObserverオブジェクト受け取ってnavigatorに設定します。
 アイドル状態になってからIdleObserverオブジェクトに設定された秒数を経過した時点でアイドル状態を知らせるハンドラが呼ばれます。またアクティブ状態になった時アクティブ状態を知らせるハンドラが呼ばれます。

navigator.removeIdleObserver(IdleObserver)

 removeIdleObserverはnavigatorからIdleObserverオブジェクトを取り除きます。
 removeIdleObserver後は渡したIdleObserverに設定されているハンドラは呼ばれなくなります。

IdleObserver

 ここまで何度かIdleObserverという名前が出てきていますが、これはaddIdleObserverとremoveIdleObserverに渡す秒数とハンドラをセットにしたオブジェクトです。

[NoInterfaceObject]
interface IdleObserver {
  attribute long time; // seconds
  void onidle();
  void onactive();
};

 timeは非アクティブになってからonidle()が呼び出されるまでの秒数。
 onidleが非アクティブになってからtime秒経過した際に呼ばれるハンドラ。
 onactiveがアクティブになった際に呼ばれるハンドラです。

使い方

 使い方はいつものaddEventListenerと似ています。
 navigator.addIdleObserverでIdleObserverを渡せば無操作になってからIdleObserver.time秒後にIdleObserver.onidleが、アクティブ復帰時にIdleObserver.onactiveが呼ばれます。

 具体的な例で示すと。

navigator.addIdleObserver({ time: 4, onidle: myIdleHandler, onactive: myActiveHandler});

 とした場合ユーザの最後の操作から4秒後にmyIdleHandleerが呼ばれ、ユーザが操作したときにmyActiveHandlerが呼ばれます。

 試しに動かしてみました。
 以下のリポジトリにサンプルコードを置いたので試す環境がある方は試してみてください。

https://github.com/aoitan/gcg_labo/tree/master/api_reading/20140323_using_Idle_API

 Firefox OSで試す場合は、Idle APIがFirefox OSではCertifiedなのでgaiaのビルドが必要になります。
 デスクトップとAndroidでは dom.idle-observers-api.enabled というプリファレンスがtrueならIdle APIを使用可能です。

 とまあまるで動いたかのように書いてるんですが、動きませんでした。
 addIdleObserverがないと怒られます。navigatorのプロパティを覗いてみてもaddIdleObserverがありませんでした。

 ちょっとJSから追ってても原因がわからないので次回はAPIの中に進んでみたいと思います。

[Firefox OS][FxOS] バックグラウンドタスクとアラームAPIを使ってみたお話その4

 藪下@2課のガジェオタです。

 関東Firefox OS勉強会5thで話したLTがもともと20分枠向けのアイデアだったのもあって駆け足で消化不良なことになってたりFxOS Gecko勉強会その2のセッションも資料作りからしてやっつけだったのでちゃんと書くシリーズの四回目です。
 資料はSlideShareに上がってます。




 全部ひとつのエントリに書いてしまうと長いので何度かにわけます。
 今回はグラフ描画についてです。

目次

グラフ描画(d3,js)

 グラフ描画にはd3.jsを使ってみたので折れ線グラフの描画の仕方を説明します。
 d3.jsでの折れ線グラフの描画はざっくり言うと以下の手順になります。

  • SVGを描画する領域を準備
  • svg.line().x()とsvg.line().y()に関数を渡してデータからパスを作れるように用意
  • svg.append(“path”)で折れ線描画

 実際のコードでは軸に目盛りを入れたりするためにもうちょっとごにょごにょしてます。

SVGを描画する領域を準備

 まずSVGでグラフを表示する領域を準備します。
 d3.jsではセレクタを使って要素を取ってきて操作します。グラフを表示する領域を作成するには、グラフを描画したい箇所の要素をとってきてsvg要素を加えます。領域の大きさは.attrで設定します。
 さらにg要素を加えているのがグラフ表示のルート要素になります。.attrでg要素の位置をずらしていますが、これが原点になります。x軸とy軸とそれらのラベルを描画する隙間を空けるためです。

        <!-- グラフ -->
        <div id="level_graph"></div>
            var svg = d3.select("#level_graph").append("svg")
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
                .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.line().x()とsvg.line().y()に関数を渡してデータからパスを作れるように用意

 パスを作るまでにやることはざっくりとみっつあります。

  • svg.line().x()とsvg.line().y()に関数を渡す
  • 値を描画領域にマッピングする関数を用意する
  • スケーリング関数に定義域を設定する

 このほかにx軸とy軸を描画する準備もしますがとりあえずグラフ表示する分には必要ないので割愛します。

svg.line().x()とsvg.line().y()に関数を渡す

 svg.line()は線を表すオブジェクトです。線の各点のx座標を返す関数を受け取る関数x()とy座標を返す関数を受け取る関数y()をメンバに持ちます。
 今回は後ほど追加する関数オブジェクトxとyを使って値を座標にマッピングします。

            var line = d3.svg.line()
                .x(function(d) { return x(d.date); })
                .y(function(d) { return y(d.level); });

値を描画領域にマッピングする関数を用意する

 データから座標に変換する関数を用意します。d3.jsにはユーティリティが用意されているのでそれを使います。
 キャンバスの幅と高さでスケールするのはd3.jsにユーティリティなオブジェクトがありました。
 x軸は時間パラメータなのでd3.time.scale()を利用してます。y軸は0から100の範囲を持つ値なのでd3.scale.linear()です。
 これらのスケール関数には定義域と値域と関数が設定され、実際のデータがパスやグラフを作るときに渡されて値域にマップされる作りです。
 スケーリング自体は定義域から区間(0,1.0)への関数と区間(0,1.0)から値域への関数の合成のようです。
 今回は使用しませんが、linear以外の関数には以下のようなものがあります。

  • identity
    • 恒等関数
    • 入力値をそのまま出力します。データがピクセル位置を表すときなどに有用です。
  • sqrt
    • 平方根
  • pow
    • 累乗
  • log
    • 対数
  • quantize
    • 量子化
    • 連続値を離散化します。ある範囲の入力をより粗い離散的な値にするものです。典型的には少数を整数にするなどですね。
    • quantizeの場合定義域から値域への変換は範囲に基づきます。定義域が{0,1,50,100}で値域が{0,50,100}なら{0,0,50,100}に変換されます。1は50よりも0に近いので0に寄せられています。
01                      50                      100
++-----------------------+------------------------+
        0       |       50       |       100
  • quantile
    • 分位
    • quantileも量子化に似て離散化します。
    • quantileの場合定義域から値域への変換は値の数に基づきます。定義域が{0,1,50,100}で値域が{0,50,100}なら{0,50,100,100}に変換されます。
            0            1          50          100
------------+------------+-----------+------------+
        0       |       50       |       100
  • ordinal
    • 序数
    • 値域として量的でない値を使えます。プログラマ的には列挙値のイメージです。

d3.time.scale()

 d3.time.scale()は日付や時刻のデータを扱うための関数を作ります。引数は日付/時刻をマッピングしたい座標の範囲です。

            var x = d3.time.scale()
                .range([0, width]);

 d3.time.scale()が返す関数は与えられた日付のデータからx座標を計算します。
 3/17, 3/18, 3/19, 3/21のデータをプロットする場合5日間のデータであることを認識して3/19と3/21の間は一日分隙間を作ってくれます。

d3.scale.linear()

 d3.scale.linear()は与えられたデータと座標を線形に変換します。
 今回は描画位置として(0,height)を取る値域を設定します。ここでheightは描画範囲の高さ-上マージン-下マージンで200になります。
 それとsvgの座標系が左上原点なので引数の順序を逆にしています。変換された結果左下原点のように振舞わせるためです。

            var y = d3.scale.linear()
                .range([height, 0]);

スケーリング関数に定義域を設定する

 スケーリングに使うオブジェクトに定義域も設定します。
 xの定義域にd3.extentを使ってますが、これは[最小値, 最大値]を返す関数です。
 yは前述の通りバッテリーレベルなので0から100ですね。

                        x.domain(d3.extent(data, function(d) { return d.date; }));
                        y.domain([0, 100]);

svg.append(“path”)で折れ線描画

 SVGからグラフの描画対象になる要素を取ってきてappend(“path”)することで折れ線を描画します。
 今回はclassにlineを指定しているので線を描画しますが、ここの値を変えると棒グラフを描画したりもできます。

                        var chart = svg.selectAll(&quot;.chart&quot;)
                            .data(domains)
                            .enter().append(&quot;g&quot;)
                            .attr(&quot;class&quot;, &quot;chart&quot;);

<pre><code>                    chart.append(&amp;quot;path&amp;quot;)
                        .attr(&amp;quot;class&amp;quot;, &amp;quot;line&amp;quot;)
                        .attr(&amp;quot;d&amp;quot;, function(d) { return line(d.values); })
                        .style(&amp;quot;stroke&amp;quot;, function(d) { return color(d.name); });
</code></pre>

 これでグラフも怖くないですね!
 次回はバックグラウンドタスクの仕組みです。

[Firefox OS][FxOS] バックグラウンドタスクとアラームAPIを使ってみたお話その3

 藪下@2課のガジェオタです。

 関東Firefox OS勉強会5thで話したLTがもともと20分枠向けのアイデアだったのもあって駆け足で消化不良なことになってたりFxOS Gecko勉強会その2のセッションも資料作りからしてやっつけだったのでちゃんと書くシリーズの三回目です。
 資料はSlideShareに上がってます。




 全部ひとつのエントリに書いてしまうと長いので何度かにわけます。
 今回はバッテリーAPIについてです。

目次

バッテリーAPIの使い方

 バッテリーAPIの使い方は大きく分けて二つのポイントがあります。イベントリスナを登録してイベントを待つことと、バッテリー状態の値を取ることです。
 今回はその大きな二つのポイントと、バッテリーロガーでは使わなかったのでLTでは話さなかった他のイベントや値について説明します。

イベントリスナを登録する方法

 バッテリーAPIはnavigator.batteryとして用意されています。
 navigator.batteryにaddEventListenerすることでイベントオブジェクトとしてバッテリー状態を取得出来ます。
 イベントにはchargingchangeとlevelchangeがあり、chargingchangeは充電中状態の変化時に呼ばれるイベントで、levelchageは充電量の変化時に呼ばれるイベントです。
 以下の様な感じでイベントリスナを登録します。

navigator.battery.addEventListener("chargingchange", function () {
    なんかなんか
});
navigator.battery.addEventListener("levelchange", function () {
    なんかなんか
});

 或いは以下のようにプロパティにfunctionオブジェクトを代入する形でも登録できます。

navigator.battery.onchargingchange = function () {
    なんかなんか
};
navigator.battery.onlevelchange = function () {
    なんかなんか
};

バッテリー状態の値を取る

 バッテリー状態の変更でイベントが取れることはわかりました。次はバッテリー状態の値を取ります。
 イベントと同じく値もnavigator.batteryを利用します。
 バッテリー状態の値はnavibator.battery.chargingとnavigator.battery.levelに入っています。この値はイベントリスナが呼ばれたタイミングで更新されます。更新される度に値を取りたければイベントリスナの中で参照することになります。

navigator.battery.addEventListener("chargingchange", function () {
    // 充電中状態が変わった
    var chargingstatus = navigator.battery.charging;
        :
    なんかなんか
});
navigator.battery.addEventListener("levelchange", function () {
    // バッテリー残量が変わった
    var batterylevel = navigator.battery.level;
        :
    なんかなんか
});

 chargingはbooleanの値を取ります。充電中ならtrue、非充電中はfalseです。
 levelはdoubleで0から1.0の値を取ります。空だと0で満充電だと1.0です。

 以前の記事で書いたとおりバックグラウンドタスクを作ることができるので、その中でこのようにイベントを待ってバッテリーレベルを記録することでバッテリーログを取ることが出来ます。
 とは言えCertifiedアプリはOSのビルドが必要になるのでバックグラウンドタスクでイベントを待つ方法は使えません。なので普通の使い方はアラームAPIで間欠起動してバッテリーの値をDBに憶えていくことになりそうです。

その他のイベントと値

 以上はバッテリーログを取るために使ったのでLTで話しましたが、ここからはLTで話していないバッテリーAPIの話です。
 ここまでバッテリーAPIにはchargingchangeとlevelchangeというイベントがあり、chargingとlevelという値が取れることを見てきました。他にもバッテリーAPIには用意されているイベントと値があります。
 chargingtimechangeとchargingTimeは満充電までの時間、dischargingtimechangeとdischargingTimeは残可動時間を表します。

battery.addEventListener("chargingtimechange", function () {
    // 満充電までの時間が変わった
    var chargingtime = navigator.battery.chargingTime;
        :
    なんかなんか
});
battery.addEventListener("dischargingtimechange", {
    // 残可動時間が変わった
    var dischargingtime = navigator.battery.dischargingTime;
        :
    なんかなんか
});

 chargingTimeはunrestricted doubleで0からdoubel maxと正の無限を取ります。バッテリーが満充電の時とバッテリーが装着されていない時は0、非充電状態の時や残り充電時間のレポートが実装出来ない時は正の無限となります。正の無限でない時は満充電までの秒数を表します。
 dischargingTimeはunrestricted doubleで0からdoubel maxと正の無限を取ります。バッテリーが充電中や残稼働時間の報告が実装出来ない時、バッテリーが装着されていない時は正の無限となります。正の無限でない時はバッテリー残量0までの秒数を表します。

 これでバッテリー状態の取得は困りませんね。次回はグラフ表示についてです。

[Firefox OS][FxOS] バックグラウンドタスクとアラームAPIを使ってみたお話その2

 藪下@2課のガジェオタです。

 関東Firefox OS勉強会5thで話したLTがもともと20分枠向けのアイデアだったのもあって駆け足で消化不良なことになってたりFxOS Gecko勉強会その2のセッションも資料作りからしてやっつけだったのでちゃんと書くシリーズの二回目です。
 資料はSlideShareに上がってます。




 全部ひとつのエントリに書いてしまうと長いので何度かにわけます。
 今回はアラームAPIの使い方についてです。

目次

アラームAPIの使い方

 アラームAPIを使う手順は大まかに以下のステップです。

  1. manifest.webappへの記述
  2. アラームの追加
  3. メッセージハンドラの登録

manifest.webappへの記述

 アラームを使うにはアラームを管理しているオブジェクトにアクセス出来なければなりません。
 そのためにmanifest.webappにパーミッションを設定する必要があります。

  "permissions": {
    "alarms": {}
  },

 更にアラームはメッセージとして飛んでくるのでメッセージの送信先もmanifest.webappに書いておきます。

  "messages": [
    { "alarm": "/index.html" }
  ]

アラームの追加

 navigatorにmozAlarmsというアラームを管理しているオブジェクトにアラームを追加します。
 mozAlarms.add()には

  • いつ発火するか
  • タイムゾーンを考慮するか
  • 発火したときに渡され るデータ

 を指定します。

var request = navigator.mozAlarms.add(
        new Date((new Date()) .getTime() + time),
        "ignoreTimezone",
        {message:"battery_log"});
request.onsuccess = function () {
    alarmId = this.result;
}

メッセージハンドラの登録

 メッセージとしてく るのでメッセージハ ンドラを登録します。
 今回はアラームなので “alarm”のハンドラで すよと指定しましょう。

navigator.mozSetMessageHandler( "alarm",
        function (mozAlarm) {
            なんかなんか
        }); 

 これで指定した発火時間になるとアラームのメッセージハンドラが呼ばれます。
 ハンドラの部分に次のアラームの設定とバッテリー状態の取得を書いておけばバッテリーログが取れますね。

 次回はバッテリーAPIの使い方です。