Weather.php概要
Yahoo!JAPANの気象情報APIを用いて、指定した緯度経度の雨の強さを取得します。取得した絵、現在時刻の降水強度実測値から、60分後までの降水強度予測値をもとに、今後の雨予報を行います。
スクリプト仕様
- Yahoo!JAPANの気象APIより現在の降水量実測値と60分後までの降水量を取得します
- 降水量予測は、10分単位で取得を行います。1https://map.yahooapis.jp/weather/V1/place?interval=10&output=json&coordinates=139.745451,35.658577&appid=@YAHOO_API_ID@
以下、XMLで取得した際のサンプル。12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061<YDF xmlns="http://olp.yahooapis.jp/ydf/1.0" firstResultPosition="1" totalResultsAvailable="1" totalResultsReturned="1"><ResultInfo><Count>1</Count><Total>1</Total><Start>1</Start><Status>200</Status><Latency>0.003471</Latency><Description/><Copyright>(C) Yahoo Japan Corporation.</Copyright></ResultInfo><Feature><Id>201907082015_139.74545_35.658577</Id><Name>地点(139.74545,35.658577)の2019年07月08日 20時15分から60分間の天気情報</Name><Geometry><Type>point</Type><Coordinates>139.74545,35.658577</Coordinates></Geometry><Property><WeatherAreaCode>4410</WeatherAreaCode><WeatherList><Weather><Type>observation</Type><Date>201907082015</Date><Rainfall>0.00</Rainfall></Weather><Weather><Type>forecast</Type><Date>201907082025</Date><Rainfall>0.00</Rainfall></Weather><Weather><Type>forecast</Type><Date>201907082035</Date><Rainfall>0.00</Rainfall></Weather><Weather><Type>forecast</Type><Date>201907082045</Date><Rainfall>0.00</Rainfall></Weather><Weather><Type>forecast</Type><Date>201907082055</Date><Rainfall>0.00</Rainfall></Weather><Weather><Type>forecast</Type><Date>201907082105</Date><Rainfall>0.00</Rainfall></Weather><Weather><Type>forecast</Type><Date>201907082115</Date><Rainfall>0.00</Rainfall></Weather></WeatherList></Property></Feature></YDF> - 現在(observation)の雨量(Rainfall)を取得し、将来(forecast)の雨量を順番に見てゆきます。雨判定のしきい値を超えた時点で、雨予報のトリガーを実施します。(home-api.phpへ通知します)
- このままだと、checkインターバルにもよりますが通知回数が多くなるので、通知間隔を調整する設定値を準備しております。
雨が降り始めても、止むことなく降り続ける場合は少ないので、少し時間が空いた後の、雨の降り始めが通知出来るようにしております。 - 雨トリガー実行、現時点の雨や60分先までの雨を検知した時点の時間を記憶し、インターバル時間以上の雨検知まで、雨トリガーを抑制します。
インターバルを70分と設定した場合。
雨トリガー実施08:00(次回09:10以降の雨検知までトリガー抑止)→数十分先の雨を検知08:40(次回9:50以降の雨検知までトリガー抑止)
雨が降り続いている限り(70分以上の雨検知がなくなるまで)、雨トリガーは抑止されます。
動作定義
- @URL4HOMEAPI@:home-api.phpのURLを登録 home-api.php V1
- @APIKEY@:home-api.php のAPI KEYを登録 home-api.php V1
- @YAHOO_API_ID@:Yahoo! JAPANのアプリケーションID
Yahoo!JAPANアプリケーションの管理 - @PLACE@:経度・緯度の順番で、コンマ区切りで指定
例:https://www.geocoding.jp/?q=東京都港区芝公園4丁目2−8
東京都港区芝公園4丁目2−8 座標(WGS84) 緯度: 35.658577 経度: 139.745451
139.745451,35.658577
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | //ログのファイル名 define("HOME_API_LOG_NAME","log-weather"); //前回通知時間記録ファイル define("HOME_API_TEMP_NAME","temp"); //home-api-key define("HOME_API_URL","http://@URL4HOMEAPI@/home-api.php"); define("HOME_API_KEY","@APIKEY@"); //動作設定 //雨判定閾値(通常0.5mm/hが雨(小雨)) define("MIN_RAIN_VALUE",0.55); //雨判定閾値(小雨以上の雨、通常1.0mm/h以上) define("STD_RAIN_VALUE",1.0); //雨アナウンス後の次アナウンスまでの間隔(分) アナウンスなし期間の小雨以上判定で期間延長 define("NO_NOTICE_TIME",70); //Yahoo API Infromation $appid = '@YAHOO_API_ID@'; $coordinates ='@PLACE@'; |
スクリプトファイル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | <?php /************************************************************************* * home-api (Weather) * Home Tools for private. Using IFTTT and Google Home etc * * PHP 5 or later * * @category Home IoT * @author Miki * @url https://www.miki-ie.com/ * @copyright 2019 (c) MIKI-IE All rights Reserved. * @license https://opensource.org/licenses/mit-license.html MIT License * @version 1.0 *************************************************************************/ //各種設定 //ログのファイル名 define("HOME_API_LOG_NAME","log-weather"); //前回通知時間記録ファイル define("HOME_API_TEMP_NAME","temp"); //home-api-key define("HOME_API_URL","http://@URL4HOMEAPI@/home-api.php"); define("HOME_API_KEY","@APIKEY@"); //動作設定 //雨判定閾値(通常0.5mm/hが雨(小雨)) define("MIN_RAIN_VALUE",0.55); //雨判定閾値(小雨以上の雨、通常1.0mm/h以上) define("STD_RAIN_VALUE",1.0); //雨アナウンス後の次アナウンスまでの間隔(分) アナウンスなし期間の小雨以上判定で期間延長 define("NO_NOTICE_TIME",70); //Yahoo API Infromation $appid = '@YAHOO_API_ID@'; $coordinates ='@PLACE@'; $base_url = 'https://map.yahooapis.jp/weather/V1/place'; $url = $base_url.'?interval=10&output=json&coordinates='.$coordinates.'&appid='.$appid; function logger($text, $level) { $datetime = date('Y-m-d H:i:s'); $yearMonth = date('Ym'); $file_name = __DIR__ . "/log/".HOME_API_LOG_NAME."-{$yearMonth}.log"; $text = "{$datetime} [{$level}] {$text}" . PHP_EOL; echo $text; if(!(file_exists($file_name))){ touch($file_name); chmod($file_name, 0777); } return error_log(print_r($text, TRUE), 3, $file_name); } function checkNotice(){ //true:通知する、false:通知スキップし通知スキップ時間延長 $datetime = date('Y-m-d H:i:s'); $file_name = __DIR__ . "/log/".HOME_API_TEMP_NAME.".txt"; $text = "{$datetime}"; if(!(file_exists($file_name))){ touch($file_name); chmod($file_name, 0777); $content = "2019-05-01 00:00:00"; }else{ $content = file_get_contents($file_name); } $diff_min = (strtotime($text) - strtotime($content)) / 60; logger("updateTime in checkNotice. last_time=".$content." diff_min=".$diff_min,"INFO"); file_put_contents($file_name, $text); if ($diff_min > NO_NOTICE_TIME){ return true; }else{ return false; } } function notice($text){ logger("Start notice function TEXT=".$text,"INFO"); $data = array( "APIKEY"=> HOME_API_KEY, "KEY" => "Weather", "TEXT" => "$text" ); $url = HOME_API_URL; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_POST, TRUE); curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // jsonデータを送信 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // curl_execの結果を文字列で返す $response = curl_exec($curl); $result = json_decode($response, true); curl_close($curl); } logger("Start weather script","INFO"); //echo $url; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET'); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 証明書の検証を行わない curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // curl_execの結果を文字列で返す $response = curl_exec($curl); $result = json_decode($response, true); curl_close($curl); $weatherList = $result['Feature']['0']['Property']['WeatherList']['Weather']; $current_date = $weatherList[0]["Date"]; $current_rainfall = $weatherList[0]["Rainfall"]; for ($i = 1; $i <= 6; $i++) { $target_date = $weatherList["$i"]["Date"]; $target_rainfall = $weatherList["$i"]["Rainfall"]; $diff_min = (strtotime($target_date) - strtotime($current_date)) / 60; if($current_rainfall < MIN_RAIN_VALUE){ if($target_rainfall >= MIN_RAIN_VALUE){ if($target_rainfall >= STD_RAIN_VALUE){ $text = $diff_min."分後に雨が降ります。".$target_rainfall."ミリの雨予報です。"; logger("天候変化:".$text." Current_date=".$current_date.", current_rainfall=".$current_rainfall. ", new_date=".$target_date.", new_rainfall=".$target_rainfall,"INFO"); if(checkNotice()){ notice($text); } break; }else{ $text = $diff_min."分後に小雨が降ります。".$target_rainfall."ミリの雨予報です。"; logger("天候変化:".$text." Current_date=".$current_date.", current_rainfall=".$current_rainfall. ", new_date=".$target_date.", new_rainfall=".$target_rainfall,"INFO"); if(checkNotice()){ notice($text); } break; } } }elseif($current_rainfall >= STD_RAIN_VALUE){ if($target_rainfall <= STD_RAIN_VALUE){ if($target_rainfall <= MIN_RAIN_VALUE){ $text = $diff_min."分後に雨が上がります。".$target_rainfall."ミリの雨予報です。"; logger("天候変化:".$text." Current_date=".$current_date.", current_rainfall=".$current_rainfall. ", new_date=".$target_date.", new_rainfall=".$target_rainfall,"INFO"); //notice($text); break; }else{ $text = $diff_min."分後に雨が小雨になります。".$target_rainfall."ミリの雨予報です。"; logger("天候変化:".$text." Current_date=".$current_date.", current_rainfall=".$current_rainfall. ", new_date=".$target_date.", new_rainfall=".$target_rainfall,"INFO"); if(checkNotice()){ //notice($text); } break; } } }else{ // MIN_RAIN_VALUE <= $current_rainfall < STD_RAIN_VALUE if($target_rainfall < MIN_RAIN_VALUE){ $text = $diff_min."分後に雨が弱くなります".$target_rainfall."ミリの雨予報です。"; logger("天候変化:".$text." Current_date=".$current_date.", current_rainfall=".$current_rainfall. ", new_date=".$target_date.", new_rainfall=".$target_rainfall,"INFO"); if(checkNotice()){ //notice($text); } break; } if($target_rainfall >= STD_RAIN_VALUE){ $text = $diff_min."分後に雨が強くなります。".$target_rainfall."ミリの雨予報です。"; logger("天候変化:".$text." Current_date=".$current_date.", current_rainfall=".$current_rainfall. ", new_date=".$target_date.", new_rainfall=".$target_rainfall,"INFO"); if(checkNotice()){ //notice($text); } break; } } } logger("END weather script. current_date=".$current_date.", current_rainfall=".$current_rainfall,"INFO"); ?> |
Gist
https://gist.github.com/kenichimiki/42fb1736da90a911dd9c3bffda4a8f10