API Gateway + Lambdaを使ってMETARデータをLINEに返してみた!
みなさん、こんにちは!
AWSのアカウントを作って、はや2年。。。
やったことはこのWordPressを使うために作ったLightsailだけ。。。という寂しい状況だったのですが、
やっと、、、やっと、、、
エンジニアらしいことをしてみました!!!(プライベートAWSで)
何をしたのか?
今回作った構成図はこちらです。
まずAWS環境で使ったものは・・・
・API Gateway
・Lambda
以上です!!!(キリッ)
そして、LINE投稿がトリガーとなっています。
構成図
ざっくりと構成図を書いていますが、インプットデータはNOAAのAPIです。
LINEでRJTT(羽田空港)と入力して送信すると、AWSのAPI Gatewayを通って、Lambdaに行きます。
LambdaでNOAAのAPIをコールするのですが、その時にLINEで来るRJTTをそのまま使ってNOAAのAPIをコールしてアウトプットをLINEに投稿します。
どのように作ったのか?
これと言って特には。。。とおもいつつ、今回はコンソール上で作りました。
CFn書くのめんどくさいんだもん、、、というと怒られそうですね。
まずはLambdaを作成し、その後にAPI Gatewayをコンソール上で作成しました。
REST APIになっていましたが、まあいいか。ということでそのままスルーしました。
一番苦戦したのは、NOAAのAPIのJSONです。
さすがアメリカ、
アメリカ独自のフォーマットに変換されて入っていました。
NOAA API
NOAAから帰ってくるJSONを見てみましょう(え)
[ { "metar_id": 535341489, "icaoId": "RJTT", "receiptTime": "2024-04-25 07:38:28", "obsTime": 1714030200, "reportTime": "2024-04-25 07:30:00", "temp": 23, "dewp": 15, "wdir": 170, "wspd": 3, "wgst": null, "visib": "6+", "altim": 1004, "slp": null, "qcField": 16, "wxString": null, "presTend": null, "maxT": null, "minT": null, "maxT24": null, "minT24": null, "precip": null, "pcp3hr": null, "pcp6hr": null, "pcp24hr": null, "snow": null, "vertVis": null, "metarType": "METAR", "rawOb": "RJTT 250730Z 17003KT 130V210 9999 FEW030 23/15 Q1004 NOSIG RMK 1CU030 A2965", "mostRecent": 1, "lat": 35.553, "lon": 139.781, "elev": 5, "prior": 0, "name": "Tokyo/Haneda Intl, 13, JP", "clouds": [ { "cover": "FEW", "base": 3000 } ], "rawTaf": "TAF RJTT 250505Z 2506/2612 18008KT 9999 FEW030 BECMG 2509/2511 36010KT TEMPO 2518/2600 FEW003 BKN008 BECMG 2603/2606 18010KT" } ]
インデントで分けてよって言いたくなる声はわかりますが、、、まあ展開するとそれはそれで結構長くなっちゃので、、、w
Rawデータ
Rawの部分はrawObの部分を読めば出てきます。
"rawOb": "RJTT 250730Z 17003KT 130V210 9999 FEW030 23/15 Q1004 NOSIG RMK 1CU030 A2965",
JMAチックなというと怒られそうですが、航空気象通報式に則った記載をされていますね。
気圧
気圧のところも先ほどのRawをみると、Q1004となっていますね。
で対応するJSONも"altim": 1004で入っているので確からしい。。。おおっ!
風向風速
こちらもRawをみると、17003KT となっていて、JSONでみると、、、
"wdir": 170, "wspd": 3
これも大丈夫そう!!!
これなら使えそう!!??とはならない。。。
このデータはNOAAなので、ダニエル・K・イノウエ国際空港でもやってみましょうか。
[ { "metar_id": 535351294, "icaoId": "PHNL", "receiptTime": "2024-04-25 08:00:10", "obsTime": 1714031580, "reportTime": "2024-04-25 08:00:00", "temp": 22.8, "dewp": 18.9, "wdir": 60, "wspd": 17, "wgst": 24, "visib": "10+", "altim": 1021.1, "slp": 1020.8, "qcField": 4, "wxString": "-RA", "presTend": null, "maxT": null, "minT": null, "maxT24": null, "minT24": null, "precip": 0.005, "pcp3hr": null, "pcp6hr": null, "pcp24hr": null, "snow": null, "vertVis": null, "metarType": "METAR", "rawOb": "PHNL 250753Z 06017G24KT 10SM -RA FEW020 SCT035 SCT080 23/19 A3015 RMK AO2 SLP208 P0000 T02280189", "mostRecent": 1, "lat": 21.3151, "lon": -157.924, "elev": 2, "prior": 0, "name": "Honolulu Intl, HI, US", "clouds": [ { "cover": "FEW", "base": 2000 }, { "cover": "SCT", "base": 3500 }, { "cover": "SCT", "base": 8000 } ], "rawTaf": "PHNL 250520Z 2506/2612 06012KT P6SM VCSH SCT025 BKN040 FM252000 07018G26KT P6SM SCT025 SCT045" } ]
おおっ!!出た出た!!!ってあれ?なんか、、、うん。。。
ということで、間違い探しのコーナーですw
日本のMETARと違うところ。
rawObの部分でムムッと気になったのが、
A3015 と10SM。。
なにこれ。。。
ということでChatGPTで聞いてみました。(今時ですね。)
A3015:水銀柱インチ(inHg)だそうです。3015水銀柱インチ(噛みそう)
10SM:視程をマイル単位で表されている。この場合は10マイル
JSONの項目を見てみると、
気圧:"altim": 1021.1 →これはよかった。むしろこっちがいいならMETARもそう書いてよ。。。
視程:"visib": "10+" →まじかぁ。。。計算必要。。。?
という感じになりました。
ということでPythonを書く。
基本的にはJSONをそのままパースでもよいかと思いましたが、いくつか対応をかませて。。。
視程のところをどう書くか?
視程のところはマイルで入るため扱いづらい。このままLINEで返してもわからない人にはわからないかなぁということで、rawObから取得することにしました。
visib_raw = raw_ob_parts[visib_index] if visib_raw == '9999': visib = "10km以上" elif visib_raw == 'CAVOK': visib = "CAVOK" elif "SM" in visib_raw: visib = f'{visib_raw}' else: visib = f'{visib_raw}m'
9999で入ってくる場合は、10km以上なので、そこはそのまま10km以上にします。
CAVOKの時はわざわざ変換せずにCAVOKで返す、
SM(マイル)になっていたらそのまま返す、それ以外の時は後ろにmをつけて返す。
という単純なものになりました。
気象現象。
これまた厄介なのは、気象現象が-RAとかSNとか、、、航空関係の方なら逆に解読されると見づらい。。。のですが、初めての人が勉強する時とかにこうなるのね。と慣れればと思い全て解読してそのまま出すようにしましたw
LINEでのアウトプットは??
ということで、LINEでのアウトプットを見てみましょう!
まだまだ改良の必要もありますが。。。
でも、API GatewayとLambdaだけで、、、たった2つだけでLINE Botが作れちゃうということは、、、
たとえばこんなこともできそう!??
・ICカードをかざしたことをトリガーにAPI Gatewayを通してLINEに投稿するBotとか??
なんか色々と夢が広がりそうですね!
この記事が気に入ったらサポートをしてみませんか?