先は長いけれどがんばる!
Preparing AppMessage
watchappでもwatchfaceでも、通信で用いる主なAPIは「AppMessage API」です。
「key」と「value」のセットを用いて、Pebbleとその親機となるスマートフォンとの間で送受信をすることができます。キーとバリューのセットというのは、「key:温度」&「value:29度」とか「key:天気」&「value:晴れ」という感じです。keyを指定して値をセットしたり取得したりできるのです。
1.メッセージやエラーを受け取るための、AppMessageのコールバック関数を作る。
2.コールバック関数をシステムに登録する。
3.AppMessageをオープンする。
オープンすると、メッセージが届くことで AppMessageInboxReceived コールバックが呼び出されるようになりますので、アプリはそれに応じた処理をすればよいと。
コールバック関数は使用される前に定義する必要があるので、init()より上に記載するのが良いでしょう。
static void inbox_received_callback(DictionaryIterator *iterator, void *context) {
}
コールバック関数をあと3つ定義します。メッセージ消失の検出、送信エラーの検出、送信完了の検出です。
static void inbox_dropped_callback(AppMessageResult reason, void *context) {
APP_LOG(APP_LOG_LEVEL_ERROR, "Message dropped!");
}
static void outbox_failed_callback(DictionaryIterator *iterator, AppMessageResult reason, void *context) {
APP_LOG(APP_LOG_LEVEL_ERROR, "Outbox send failed!");
}
static void outbox_sent_callback(DictionaryIterator *iterator, void *context) {
APP_LOG(APP_LOG_LEVEL_INFO, "Outbox send success!");
}
それぞれの処理が行われたことがわかるように、APP_LOG関数でログを出力するようにしています。
次に、init()の中で上記関数の登録を行います。
// Register callbacks app_message_register_inbox_received(inbox_received_callback); app_message_register_inbox_dropped(inbox_dropped_callback); app_message_register_outbox_failed(outbox_failed_callback); app_message_register_outbox_sent(outbox_sent_callback);
最後に、メッセージが届くように、AppMessage をオープンします。
// Open AppMessage app_message_open(app_message_inbox_size_maximum(), app_message_outbox_size_maximum());
メッセージの取りこぼしをしないために、順番として、オープン処理の前に必ず登録処理をしてください。
Pebble側の送受信の処理はこれで完了です。次に、実際に送受信される内容を決めます。
送信時のキーとなる値ですね。整数値で決めます。ここでは
「温度」を「KEY_TEMPERATURE」でプログラムとしての値は「0」
「天気」を「KEY_CONDITIONS」でプログラムとしての値は「1」
とします。
ソースファイルでは#defineで定義しとくといいです。
#define KEY_TEMPERATURE 0 #define KEY_CONDITIONS 1
定義が多い時は、enum使うのもいいっすよ、とのこと。
enum {
KEY_TEMPERATURE = 0,
KEY_CONDITIONS = 1
}
Preparing PebbleKit JS
次は PebbleKit JS の準備です。ここでは、天気情報を PebbleKit JSを通して取得するわけですが、そもそも、PebbleKit JSってナニモンじゃあ、という感じです。そこはまあ、実装しながら、理解していくことにします。
最初に「SOURCE FILES」で「ADD NEW」、FILE TYPEは「JavaScript file」を選択。名前は「weather.js」にして「CREATE」します。
PebbleKit JS SDKを使うための基本的なテンプレートがありまして、2つのイベントリスナーがあります。
・readyイベント
Pebbleでwatchapp/watchfaceが実行された後で、PebbleKit JSが準備OKになったときに発生。
・appmessageイベント
AppMessageがPebbleから親機スマートフォンに送られたときに発生。
テンプレートは下記のようになります。「weather.js」に貼り付けてセーブしといてください。
// Listen for when the watchface is opened
Pebble.addEventListener('ready',
function(e) {
console.log('PebbleKit JS ready!');
}
);
// Listen for when an AppMessage is received
Pebble.addEventListener('appmessage',
function(e) {
console.log('AppMessage received!');
}
);
ここまでで、いったん動作確認してみます。
起動完了したら「VIEW LOGS」でログ見てみてください。
うまくいってると「[PHONE] pebble-app.js:?: PebbleKit JS ready!」が出てると思います。
「DISMISS」押しちゃった場合は左メニュー「COMPILATION」の「VIEW APP LOGS」からログ見れます。
Cファイルからは「APP_LOG」、JSファイルからは「console.log()」でログ出力ができるのですね。
「表示準備」「Pebbleとスマートフォンのデータ送受信準備」ができましたので、実際に表示するための情報を取得する部分に入ります。
Getting Weather Information
OpenWeatherMap.org から天気情報を取得してWatchfaceに表示する手順は下記の通り。
1.スマートフォンからユーザの位置情報を取得
2.XMLHttpRequest オブジェクトを使ってOpenWeatherMap API を呼ぶ。このとき1.で取得した位置情報を渡す。
3.XMLHttpRequestの戻り値から取得した情報をPebbleに送り、Watchfaceに表示する。
最初に「SETTING」の「USES LOCATION」のチェックを入れて、位置情報が使用できるようにします。(「SAVE CHANGES」忘れずに!)
次に位置情報取得の処理をJSに追加します。パラメータとしてtimeoutにタイムアウト時間、maximumAgeにキャッシュ最大保存時間を指定します
function locationSuccess(pos) {
// We will request the weather here
}
function locationError(err) {
console.log('Error requesting location!');
}
function getWeather() {
navigator.geolocation.getCurrentPosition(
locationSuccess,
locationError,
{timeout: 15000, maximumAge: 60000}
);
}
// Listen for when the watchface is opened
Pebble.addEventListener('ready',
function(e) {
console.log('PebbleKit JS ready!');
// Get the initial weather
getWeather();
}
位置情報取得でエラーが起きる可能性もあるのでその場合の処理も入ってますね。
「ready」イベントが起きると「getWeather()」が呼ばれ、さらに「getCurrentPosition()」が呼ばれます。
うまく位置取得できれば「locationSucess()」が呼ばれて位置情報が入っている「pos」が引数で送られてきます。
次に取得した「pos」を使って天気情報を取得します。
XMLHttpRequest を使って OpenWeatherMap.org から情報取得ですね。
最初にシンプルにリクエストするだけの関数を作りましょう。
locationSuccess();の前に書いておいてください。
var xhrRequest = function (url, type, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function () {
callback(this.responseText);
};
xhr.open(type, url);
xhr.send();
};
引数は、URL、type(GET または POST)、受信完了時のcallback関数です。
呼び出すURLは、OpenWeatherMapのAPI pageに仕様が載っています。「pos」の値で緯度/経度を指定して、下記のようになります
var url = 'http://api.openweathermap.org/data/2.5/weather?lat=' + pos.coords.latitude + '&lon=' + pos.coords.longitude;
typeはGETを使います。戻り値を処理するcallback関数も書いて、全体では下記のようになります。
function locationSuccess(pos) {
// Construct URL
var url = 'http://api.openweathermap.org/data/2.5/weather?lat=' +
pos.coords.latitude + '&lon=' + pos.coords.longitude;
// Send request to OpenWeatherMap
xhrRequest(url, 'GET',
function(responseText) {
// responseText contains a JSON object with weather info
var json = JSON.parse(responseText);
// Temperature in Kelvin requires adjustment
var temperature = Math.round(json.main.temp - 273.15);
console.log('Temperature is ' + temperature);
// Conditions
var conditions = json.weather[0].main;
console.log('Conditions are ' + conditions);
}
);
これで、位置情報が正しく取得されれば、
xhrRequestが呼ばれて、その戻りのJSONをパースすることで温度と天気を獲得することができます。全体では、どんな値が返ってきているかというと、
こういう感じです。これはロンドンの例ですね。
戻ってきた値から、下記情報を取得しています。
・main.temp →温度(ケルビンなのでセ氏に直す)
・weather[0].main →天気
その他、風速が知りたければ「wind.speed」を見ればいいですし、いろいろ情報が取れますね。実行してログ確認して、下記のように取得できてればOKです。
[PHONE] pebble-app.js:?: Temperature is 12 [PHONE] pebble-app.js:?: Conditions are Clouds
CloudPebbleでPCで動作させていると、正しい位置は取れないようなのですけども、そこはまあ、しょうがない…。
値が取れるようになったので、あとはこれをPebble側に渡して表示するのじゃあ!


