Yahoo天気予報をESP8266-WROOM-02やESP–32などのマイコンから参照しやすくしてみる
天気予報はYahooやLivedoorが無料でRSSを提供してくれています。他にもgooとかもやってみたいです。今回はYahoo!の天気予報をマイコンで表示したりするのに利用しやすくするためにごにょごにょしたことをまとめておきたいと思います。
まず、Yahooの天気予報のRSSは、次のページで各地域ごとにxml形式で提供されています。
https://weather.yahoo.co.jp/weather/rss/
実際に開いてみるとわかりますが、更新日時とか、警報や注意報など天気以外の表示するのに必要なさそうな情報も沢山入っています。この大量の文字列からパターンマッチをして必要な文字列を切り出して来なければなりません。なんて考えていたらマイコンでこの処理をさせるのは大変だーと思ってきました。さらに、Yahooの天気予報はhttpsなのでセキュア通信もさせなくてはなりません…。うーん、httpsだとプロキシ経由だったりするとページを取得するだけでも難しそうだな、、、などなど色々考えた結果。扱いやすいデータに変換してからマイコンで受信したほうが簡単じゃないか(?)というとこに至ったのでした。
前置きが長くなりましたが、今回やってみるのは、PHPを使ってマイコンで使いやすい天気予報データに変換しちゃおう♪というのが狙いです。
概要:
・Yahooの天気予報のRSSを利用
・WEBサーバ上で動くPHPプログラムを作成してみる
(PHPにした理由はPHPだと簡単だから)
■getytenki.phpのプログラム
<?php header('Content-type: application/xml; charset=UTF-8'); date_default_timezone_set('Asia/Tokyo'); //リクエストURLから数字文字列を取得 $placeNo = htmlspecialchars($_GET["p"]); //Yahoo天気のxmlファイルのURL $xmlurl = "https://rss-weather.yahoo.co.jp/rss/days/" . $placeNo . ".xml"; //xml読み込む $lines = file($xmlurl); echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; echo "<root>\n"; echo "<sourceurl>" . $xmlurl . "</sourceurl>\n"; echo "<dataprovider>Yahoo!天気・災害</dataprovider>\n"; foreach ($lines as $line_num => $line) { //copyright表示 if(preg_match('/<copyright(.+)copyright>/',$line,$matches)){ echo $matches[0] . "\n"; echo "<today>" . date('Y年m月d日') . "</today>\n"; } //<title>タグの情報を読み込む if(preg_match_all('/<title>(.+?)<\/title>/',$line,$matches)){ //print_r($matches); //場所の文字列を抜き出す if(preg_match('/災害 - (.+)の天気/',$matches[1][0],$place)){ echo "<place>" . mb_convert_kana($place[1],'a','UTF-8') . "</place>\n"; //全角→半角にもしておく } //天気情報を抜き出す foreach ($matches[1] as $mt_num => $mt) { if(preg_match_all('/【 (.+日.+?)).+ 】 (.+) - (.+) - /',$mt,$dt)){ //print_r($dt); echo "<item>"; echo mb_convert_kana($dt[1][0],'a','UTF-8') . ":" . $dt[2][0] . ":" . $dt[3][0]; echo "</item>\n"; } } } } echo "</root>\n";
プログラムはたったこれだけです。
上記プログラムをPHPが動くWEBサーバに置いてアクセスしてみます。ゆくゆくはマイコンでアクセスさせますが、まずはパソコンで確認です。
http://bmicom.dmsk.com/php/getytenki.php?p=4820
URLのおしりの数字は、Yahooの天気予報のxmlファイル名の数字です。ブラウザによっては文字が羅列されているかもしれませんが、ソースを見てもらうとxml形式になっているのがわかります。
今回は4820なので長野県松本の天気情報が取得できました。
出力されるxmlの文字コードはUTF-8になっています。
もしかしたらフォントの関係とかでShift-JISで受信したい場合もあるかもしれません。そんなときは以下のようにして、PHP側でShift-JISにしてしまうのも手かと思います。
■getytenkisj.phpのプログラム
<?php header('Content-type: application/xml; charset=Shift_JIS'); date_default_timezone_set('Asia/Tokyo'); //リクエストURLから数字文字列を取得 $placeNo = htmlspecialchars($_GET["p"]); //Yahoo天気のxmlファイルのURL $xmlurl = "https://rss-weather.yahoo.co.jp/rss/days/" . $placeNo . ".xml"; //xml読み込む $lines = file($xmlurl); echo mb_convert_encoding("<?xml version=\"1.0\" encoding=\"Shift-JIS\"?>\n", "SJIS", "UTF-8"); echo mb_convert_encoding("<root>\n", "SJIS", "UTF-8"); echo mb_convert_encoding("<sourceurl>" . $xmlurl . "</sourceurl>\n", "SJIS", "UTF-8"); echo mb_convert_encoding("<dataprovider>Yahoo!天気・災害</dataprovider>\n", "SJIS", "UTF-8"); foreach ($lines as $line_num => $line) { //copyright表示 if(preg_match('/<copyright(.+)copyright>/',$line,$matches)){ echo mb_convert_encoding($matches[0] . "\n", "SJIS", "UTF-8"); echo mb_convert_encoding("<today>" . date('Y年m月d日') . "</today>\n", "SJIS", "UTF-8"); } //<title>タグの情報を読み込む if(preg_match_all('/<title>(.+?)<\/title>/',$line,$matches)){ //print_r($matches); //場所の文字列を抜き出す if(preg_match('/災害 - (.+)の天気/',$matches[1][0],$place)){ echo mb_convert_encoding("<place>" . mb_convert_kana($place[1],'a','UTF-8') . "</place>\n", "SJIS", "UTF-8"); //全角→半角にもしておく } //天気情報を抜き出す foreach ($matches[1] as $mt_num => $mt) { if(preg_match_all('/【 (.+日.+?)).+ 】 (.+) - (.+) - /',$mt,$dt)){ //print_r($dt); echo mb_convert_encoding("<item>", "SJIS", "UTF-8"); echo mb_convert_encoding(mb_convert_kana($dt[1][0],'a','UTF-8') . ":" . $dt[2][0] . ":" . $dt[3][0], "SJIS", "UTF-8"); echo mb_convert_encoding("</item>\n", "SJIS", "UTF-8"); } } } } echo "</root>\n";