2013年12月2日

【FHC】今日の天気を教えてもらう。をアップデートしました。

題名のとおりです。

以前記事にした「【FHC】今日の天気を教えてもらう」のスクリプトを修正しました。

この機能、我が家で最も使われている機能だったりします。
(本来のリモコン的用途はというと。。。)




FHC Ver1.27より追加のマッシュアップAPIを利用する

Ver1.27のシステムアップデートで、マッシュアップAPIという機能がFHCに搭載されました。

簡単に言ってしまえば「WEBサービスが提供するAPIを利用するための機能」と言ったところでしょうか。

現在マッシュアップAPIでは、天気取得API電車遅延APIの2つが提供されています。

今回はタイトルのとおり、せっかく公式で天気情報の取得APIが実装されたのだから、今ある不具合を直しつつ、こちらの方も対応しようかという感じで進めていきます。



天気情報取得スクリプトを自作し、FHC TENKIを利用できるようにする

天気情報取得スクリプトはデフォルトでweather_openweather.jsのコマンドが用意されております。
このweather_openweather.jsは天気情報を提供するフリーなAPIである「OpenWeatherMap」から情報を得ています。

フリーなAPIなので、煩わしい権利などが絡まず実装することのできる数少ないサービスなので採用されたのでしょうが、如何せん海外のサービスですので、僕がほしいと思っている情報があまり得ることができません。(降水確率とか)

なので、今まで使っていた鹿せんべい氏(TwitterID: @shika_senbei)作の天気予報フィードであるFHC TENKIを取得するスクリプトを、マッシュアップAPI用に作り直しました。


[weather_fhc_tenki.js]

///@arg1@must@地域コード@例:4410(東京)@text
function main(code)
{
  dump(code);
  var result = http_get("http://pipes.yahoo.com/pipes/pipe.run?_id=11aaf6db1647c2155de5739ff587db1f&_render=json&code=" + code);
  var obj = JSON.parse(result);
  var arr = obj.value.items[0]["wm:forecast"]["wm:content"];
  
  var dataList = {};
  dataList["weather"] = arr["wm:weather"];
  dataList["date"] = arr["date"];
  dataList["wday"] = arr["wday"];
  dataList["maxTemp"] = arr["wm:temperature"]["wm:max"];
  dataList["minTemp"] = arr["wm:temperature"]["wm:min"];
  dataList["rain06-12"] = "--";
  dataList["rain12-18"] = "--";
  dataList["rain18-24"] = "--";
  
  for (var i = 0; i < arr["wm:rainfall"]["wm:prob"].length; i++){
    dataList["rain"+arr["wm:rainfall"]["wm:prob"][i]["hour"]] = arr["wm:rainfall"]["wm:prob"][i]["content"];
    //dump(arr["wm:rainfall"]["wm:prob"][i]["hour"] + ":" + arr["wm:rainfall"]["wm:prob"][i]["content"]);
  }
  return dataList;
}



上記スクリプトを「設定」→「コマンド設定を行う」のページから「新規作成」して保存してください。

保存したら試しに実行画面の引数1のテキストボックスに「4410」(東京のコード)を入力して実行してみてください。
FHCが正しくインターネットに接続されていれば天気情報が出力されているはずです。



weather_fhc_tenki.jsで得られる情報

weather_fhc_tenki.jsから得られる情報はweather_openwether.jsとは全く異なるため、APIリファレンスにある連想配列とは異なるデータを返してきますので、注意が必要です。
返してくる値は↓のような感じ

{
  "weather": "晴れ", ←天気概要。「晴れ/くもり/雨/雪、時々/のち」
  "date": "12/2", ←天気の予報日。18時以降は翌日の天気を予報する。
  "wday": "Mon", ←曜日。英字3文字
  "maxTemp": "15", ←最高気温。
  "minTemp": "--", ←最低気温。12時以降は出力されず "--" 表記となる
  "rain06-12": "--", ←午前の降水確率。12時以降は出力されず "--" 表記となる
  "rain12-18": "10", ←午後の降水確率
  "rain18-24": "10" ←夜の降水確率
}

天気取得スクリプトを置き換える

「設定」→「システム全般の設定を行う」の「天気取得スクリプト」の「コマンドを選択する」を押下し、先ほど作成したコマンドを指定します。

これを設定することにより、FHCが提供する「weather_info()」関数から、上記コマンドが呼び出されるようになります。

次に、以前作成した取得した天気を読み上げてくれるコマンドである「read_weather.js」の内容を修正します。



[read_weather.js]

///@args1@must@ 日時 (0:読み上げない、1:読み上げる)@0 or 1@int
///@args2@must@ 天気 (0:読み上げない、1:読み上げる)@0 or 1@int
///@args3@must@ 最高気温 (0:読み上げない、1:読み上げる)@0 or 1@int
///@args4@must@ 最低気温 (0:読み上げない、1:読み上げる)@0 or 1@int
///@args5@must@ 時間別降水確率 (0:読み上げない、1:読み上げる)@0 or 1@int
function main(arg1, arg2, arg3, arg4, arg5)
{
  var code = "4410"; //地域コード(デフォルトは東京の4410)
  var voice = "";
  var wdate = Number(arg1);
  var weather = Number(arg2);
  var maxTemp = Number(arg3);
  var minTemp = Number(arg4);
  var rainRate = Number(arg5);
  
  var arr = weather_info(code);
  
  if (wdate) {
    voice = kanaDate(arr["date"]) + "、";
    voice += kanaWeek(arr["wday"]) + "ようび";
    if (weather + maxTemp + minTemp) {
      voice += "の";
    }
    voice += " ";
  }
  
  if (weather) {
    voice += "てんきは ";
    voice += kanaTenki(arr["weather"]);
    if (maxTemp + minTemp + rainRate) {
      voice += "、";
    }
  }
  
  if (maxTemp) {
    voice += "さいこうきおんは ";
    voice += kanaNum(arr["maxTemp"], 1) + "ど ";
    if (minTemp + rainRate) {
      voice += "、";
    }
  }
  if (minTemp && arr["minTemp"] != "--") {
    voice += "さいていきおんは ";
    voice += kanaNum(arr["minTemp"], 1) + "ど ";
    if (rainRate) {
      voice += "です。";
    }
  }
  if (rainRate) {
    voice += "こうすいかくりつは";
    if (arr["rain06-12"] != "--") {
      voice += "、ごぜんちゅう " + kanaNum(arr["rain06-12"]) + " ぱーせんと";
    }
    if (arr["rain12-18"] != "--") {
      voice += "、ごご " + kanaNum(arr["rain12-18"]) + " ぱーせんと";
    }
    voice += "、よる " + kanaNum(arr["rain18-24"], 0) + " ぱーせんと ";
  }
  voice += "です";
  speak(voice);
  dump(voice);
}
function kanaNum(num, hatsu)
{
  KanaArr = new Array("ぜろ","いち","に","さん","よん","ご","ろく","なな","はち","きゅう");
  n = Number(num);
  Kana = "";
  if (n == 0) {
    Kana = "ぜろ";
  } else {
    if (n < 0) {
      Kana = "マイナス";
      n = -n;
    }
    if (n >= 100) {
      Kana += "ひゃく";
    }
    n %= 100;
    if (n >= 20) {
      
      Kana += KanaArr[Math.floor(n/10)];
    }
    if (n >= 10) {
      if (hatsu)
      {
      Kana += "じゅう";
      } else {
        Kana += "じゅっ";
      }
      n %= 10;
    }
    if (n > 0){
      Kana += KanaArr[n];
    }
  }
  return Kana;
}

function kanaDate(dateValue)
{
  month = new Array("","いちがつ ","にがつ ","さんがつ ","しがつ ","ごがつ ","ろくがつ ","しちがつ ",
                    "はちがつ ","くがつ ","じゅうがつ ","じゅういちがつ ","じゅうにがつ ");
  day = new Array("","ついたち","ふつか","みっか","よっか","いつか","むいか","なのか","ようか",
                  "ここのか","とおか","じゅういちにち","じゅうににち","じゅうさんにち","じゅうよんにち",
                  "じゅうごにち","じゅうろくにち","じゅうしちにち","じゅうはちにち","じゅうくにち",
                  "はつか","にじゅういちにち","にじゅうににち","にじゅうさんにち","にじゅうよっか",
                  "にじゅうごにち","にじゅうろくにち","にじゅうしちにち","にじゅうはちにち",
                  "にじゅうくにち","さんじゅうにち","さんじゅういちにち");
  dateArr = dateValue.split("/");
  return month[Number(dateArr[0])] + day[Number(dateArr[1])];
}

function kanaTenki(tenki)
{
  tenki = tenki.replace("時々", "ときどき");
  tenki = tenki.replace("晴", "は");
  tenki = tenki.replace("雨", "あめ");
  tenki = tenki.replace("雪", "ゆき");
  return tenki;
}

function kanaWeek(week){
  KanaArr = {Mon: "げつ", Tue: "か", Wed: "すい", Thu: "もく", Fri: "きん", Sat: "ど", Sun: "にち"};
  return KanaArr[week];
}


上記スクリプトをまるっとそのまま置き換えて保存。
試しに引数をすべて1で設定して動かしてみましょう。

正しく設定されていればFHCさんがその日のこれからの天気を読み上げてくれます。