ヤマムギ

growing hard days.

*

Twilio APIでOpenWeatherMap APIで取得した天気情報を毎朝モーニングコールする

      2015/10/18


owm-twilio

OpenWeatherMap APIのJsonから取得した気温と天気の情報を、TwilioのAPIを使って毎朝5時にモーニングコール設定してみました。
ソースコード詳細は、GitHubを見ていただければと思います。

デモ動画です。

※SlidShareに発表資料をアップしましたので、概要はこちらをご確認ください。

OpenWeatherMap API Jsonから天気情報を取得する

Twilio APIでメッセージを送るために、次のようなXMLを動的に作成します。

[vim]


2015年06月07日の天気をお知らせします。現在の気温は19.812度。天気は軽い雨です。明日0時の気温は14.24度。天気は晴れです。明日6時の気温は15.43度。天気は軽い雨です。

[/vim]

取得する情報は今とおよそ6時間後、12時間後の天気と気温です。

JsonをString変数へ格納

2種類のJsonをString形式で扱う事にしました。

抜粋していますので、全体はGitHub GenerateJsonString.javaを見てください。

[java]
public void setJsonData(String urlString) {
StringBuilder builder = new StringBuilder();
try {
URL url = new URL(urlString);
Object content = url.getContent();
if (content instanceof InputStream) {
BufferedReader reader = new BufferedReader(
new InputStreamReader((InputStream) content));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
this.jsonDataString = builder.toString();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
[/java]

指定URLのContentをBufferedReaderに入れて読んだ情報をStringBuilderに追加していきます。

今の天気情報の取得

まず今の天気情報を取得するために、OpenWeatherMap APIのCurrentを取得します。
タイプは「Weather」です。
解析用のクラスは次のようになりました。
抜粋していますので、全体はGitHub WeatherJson.javaを見てください。

[java]
public class WeatherJson {
private ArrayList weather;
public class weather {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
private main main;
public class main {
private double temp;
public double getTemp() {
return temp;
}
public void setTemp(double temp) {
this.temp = temp;
}
}
public ArrayList getWeather() {
return weather;
}
public void setWeather(ArrayList weather) {
this.weather = weather;
}
public main getMain() {
return main;
}
public void setMain(main main) {
this.main = main;
}
}
[/java]

クラスの階層化や配列のところは少し調べながら作りました。
APIのURLを叩いて得られるJsonの形式にあわせて作っていく感じです。

JsonをGsonを使ってパースする

JsonのパースはGsonライブラリを使ってやりました。

抜粋していますので、全体はGitHub GenerateXMLFile.javaを見てください。

[java]
GenerateXMLFile() {
gson = new Gson();
todayString = getTodayString();
sayString = todayString.substring(0, 4) + “” + “年”
+ todayString.substring(5, 7) + “月”
+ todayString.substring(8, 10) + “日の天気をお知らせします。”;
}

public void GenerateWeatherString(String jsonString) {
WeatherJson weatherJson = gson.fromJson(jsonString, WeatherJson.class);
ArrayList<weathermap.WeatherJson.weather> weatherWeather = weatherJson
.getWeather();
WeatherJson.main weatherMain = weatherJson.getMain();
ConditionCode conditionCode = new ConditionCode();
conditionCode.setConditionString(weatherWeather.get(0).getId());
sayString += “現在の気温は” + weatherMain.getTemp() + “度。天気は”
+ conditionCode.getConditionString();
conditionCode = null;
}
[/java]

GsonのfromJsonで解析用クラスを引数に渡してJavaオブジェクト化しています。

XMLに設定するメッセージのための文字列を生成しています。

およそ6時間後と12時間後の予報の取得

OpenWeatherMAP APIの「Forecast」では3時間単位で今の時間帯を含む未来のデータが取得出来ます。

まずは、解析用クラスです。
抜粋していますので、全体はGitHub ForecastJson.javaを見てください。

[java]
public class ForecastJson {
private ArrayList list;
public class list {
private main main;
public class main {
private double temp;
public double getTemp() {
return temp;
}
public void setTemp(double temp) {
this.temp = temp;
}
}
private ArrayList weather;
public class weather {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
public ArrayList getWeather() {
return weather;
}
public void setWeather(ArrayList weather) {
this.weather = weather;
}
public main getMain() {
return main;
}
public void setMain(main main) {
this.main = main;
}
}
public ArrayList getList() {
return this.list;
}
public void setList(ArrayList list) {
this.list = list;
}
}
[/java]

先ほどの「Weather」より階層がひとつ深くなっています。

およそ6時間後と12時間後のJsonのパース

抜粋していますので、全体はGitHub GenerateXMLFile.javaを見てください。

[java]
public void GenerateForecastString(String jsonString) {
ForecastJson forecastJson = gson.fromJson(jsonString,
ForecastJson.class);
ArrayList forecastLists = forecastJson.getList();

     int loopNumber = 0;
for (list forecastList : forecastLists) {
switch (loopNumber) {
case 3:
case 5:
main forecastMain = forecastList.getMain();
ArrayList forecastWeather = forecastList.getWeather();
ConditionCode conditionCode = new ConditionCode();
conditionCode
.setConditionString(forecastWeather.get(0).getId());
sayString += getJpTimeString(forecastList.getDt_txt()) + “時の気温は” + forecastMain.getTemp()
+ “度。天気は” + conditionCode.getConditionString();
conditionCode = null;
break;
}
loopNumber++;
}
}
[/java]

リストの順番はOpenWeatherMAP APIの仕様を信じるとして添え字で3番目と5番目がおよそ6時間後、12時間後になるはずなのでこれでXMLメッセージ用のStringを生成しています。

XMLファイル生成

ここまでで得たStringでXMLを生成します。

XMLはTwilioの仕様どおりに作成します。

抜粋していますので、全体はGitHub GenerateXMLFile.javaを見てください。

[java]
public Document SayXMLDocument(String sayString) {
DocumentBuilder builder = null;
String voice = “alice”;
String language = “ja-jp”;
try {
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
Document XMLDocument = builder.newDocument();
Element response = XMLDocument.createElement(“Response”);
XMLDocument.appendChild(response);
Element say = XMLDocument.createElement(“Say”);
say.setAttribute(“voice”, voice);
say.setAttribute(“language”, language);
say.appendChild(XMLDocument.createTextNode(sayString));
response.appendChild(say);
return XMLDocument;
}
public void WriteXMLFile(Document XMLDocument, String filePath) {
Transformer transformer = null;
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
try {
transformer = transformerFactory.newTransformer();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
}
transformer.setOutputProperty(“indent”, “yes”);
transformer.setOutputProperty(“encoding”, “UTF-8”);
try {
transformer.transform(new DOMSource(XMLDocument), new StreamResult(
filePath));
} catch (TransformerException e) {
e.printStackTrace();
}
}
[/java]

voiceはaliceにしています。
で、やってみて思ったのですが、今のところ漢字の読み間違いはないです。
凄いですね。

Twilio APIを使って自動で電話をかける。

プログラムから電話をかける

素晴らしく簡単です。

抜粋していますので、全体はGitHub TwilioCall.javaを見てください。

[java]
public class TwilioCall {
    public void doCall(Properties properties) {
TwilioRestClient client = new TwilioRestClient(
properties.getAccount_sid(), properties.getAuth_token());
List params = new ArrayList();
params.add(new BasicNameValuePair(“To”, properties.getTo()));
params.add(new BasicNameValuePair(“From”, properties.getFrom()));
params.add(new BasicNameValuePair(“Url”, properties.getUrl()));
params.add(new BasicNameValuePair(“Method”, “GET”));
params.add(new BasicNameValuePair(“FallbackMethod”, “GET”));
params.add(new BasicNameValuePair(“StatusCallbackMethod”, “GET”));
params.add(new BasicNameValuePair(“Record”, “false”));
CallFactory callFactory = client.getAccount().getCallFactory();
Call call = null;
try {
call = callFactory.create(params);
} catch (TwilioRestException e) {
e.printStackTrace();
}
System.out.println(call.getSid());
}
}
[/java]

propertiesファイルから各パラメータを取得しているので、それぞれ簡単に説明を書きます。

  • ACCOUNT_SID,AUTH_TOKEN
    Twilioのサイトでログインして、「Show API Credentials」で表示されます。
    twilio-api-credentials

  • To
    かけたい相手の電話番号です。

  • From
    発信元となる電話番号です。
    Twilioで購入した電話番号となります。
    トライアルアカウントでは無料です。
    twilio-phonnumber

  • Url
    生成したXMLを置いているURLです。

mainメソッドで各処理を実行する

[java]
public static void main(String[] args) {
Properties properties = new Properties();
String filePath = properties.getFile_path();
APIURL apiUrl = new APIURL(properties.getCity(), “weather”);
GenerateJsonString generateJsonString = new GenerateJsonString();
GenerateXMLFile generateXmlFile = new GenerateXMLFile();
generateJsonString.setJsonData(apiUrl.getUrlString());
generateXmlFile.GenerateWeatherString(generateJsonString.getJsonData());
apiUrl.setUrlString(properties.getCity(), “forecast”);
generateJsonString.setJsonData(apiUrl.getUrlString());
generateXmlFile
.GenerateForecastString(generateJsonString.getJsonData());
String sayString = generateXmlFile.getSayString();
Document xmlDocument = generateXmlFile.SayXMLDocument(sayString);
generateXmlFile.WriteXMLFile(xmlDocument, filePath);
TwilioCall twilioCall = new TwilioCall();
twilioCall.doCall(properties);
}
[/java]

ほとんどはXML生成のためのコードで、Twilioは本当に数行のコードで出来ました。

毎朝5時に自動で電話をかける

root権限で実行してもらいます。

[bash]
$ sudo crontab -e
[/bash]

[vim]
0 5 * * * java -jar MorningCall.jar
[/vim]

エラー処理、ログなどはこれから実装していきます。


最後までお読みいただきましてありがとうございました!

【PR】 「AWS認定試験対策 AWS クラウドプラクティショナー」という本を書きました。

【PR】 「AWSではじめるLinux入門ガイド」という本を書きました。

 - Java, Twilio, Web , , ,

ad

ad

  関連記事

Java SE 7 Silver対策勉強をしながらメモ 2015/1/29

さて本日は少しだけですが、試験対策のメモをいつものごとくマークダウンで記載したの …

ホームページ、自作サイトにアメブロの新着情報を掲載する

MagipieRSSを使用 なので下記サイトでダウンロード http://mag …

PHP 共通ヘッダ、フッタの内容をページによって動的に変更する

共通ヘッダ、フッタ それぞれ必要な内容を書いたheader.php、footer …

Java SE 7 Silver対策勉強をしながらメモ 2015/1/30

本日は配列です。 いつものごとくマークダウンで記載したのでそのままJetpack …

Google Apps ScriptでAdmin SDK Directory Serviceを使ってユーザの最終ログイン情報一覧を出力する

GoogleAppsで使わなくなったアカウントを確認する方法として、最終ログイン …

Googleカレンダーの予定をPHPからXMLで取得してWebページに表示する(現在廃止されたAPIなので使えません)

ご注意 ※下記の記事で使用していたAPIは2016年現在使用出来なくなっています …

Java SE 7 Silver模擬テストの結果気になる問題をメモ 2015/2/13

違う種類の模擬テスト1回目。 90問中77問正解。 正解率85%。 まだまだ不安 …

C#でOpenWeatherMap APIを使って天気情報を取得する

C#でOpenWeatherMapAPIを使って現在の天気を取得してみました。 …

Java SE 7 Silver対策勉強をしながらメモ 2015/2/1

本日は繰り返し処理。 配列や演算でひっかけてくる問題に苦戦。 繰り返しだけに頭を …

Java SE 7 Silver受験直前 練習問題総確認 2015/2/14

カーリング中継見ながら、iTunesシャッフルでかけながら、練習問題。 集中って …