【IoT】アメダスの気象データをSORACOMに送信する方法
気象庁が発表しているアメダスの気象データを、SORACOM Lagoonで可視化する方法を解説します。IoTデバイスで取得したデータに、気象データを重ねることができます。
背景と目的
IoTデバイスで取得したデータが、雨量や気温などの気象データに関連している場合、IoT取得データと気象データを重ねて表示させることができれば、データ分析が容易になります。それぞれのデータをExcel等で重ね合わせることもできますが、クラウド上のデータ可視化ツールであるSORACOM Lagoonに表示する方法を考えます。
詳細
1. システム全体構成
下記に、システム全体構成図を示します。
図の上段は、IoTデバイスで取得したデータをSORACOM Lagoonに表示させるフローです。図の下段が、アメダスの気象データをSORACOM Lagoonに表示させるフローです。この構成であれば、IoTデバイス取得データと、気象データを、同じLagoon上(同じグラフ上)に重ねることができます!
それでは、
・どのように、アメダスから気象データを取得するか?
・どのように、気象データをSORACOMに送信するか?
・どのように、気象データ送信用Lambda関数を定期実行させるか?
・ChatGPTでLambda関数を作成する方法
を順に考えます。
2. アメダスから気象データを取得する
まず、どのようにアメダスから気象データを取得するかを考えます。
全アメダス観測所を、下記JSONで取り出せます。
https://www.jma.go.jp/bosai/amedas/const/amedastable.json
例えば、高知観測所のデータを取り出すと、下記のようになっています。高知観測所の番号は74182であり、この番号をキーとし、緯度経度や観測所名が定義されていることがわかります。
{
"74182": {
"type": "A",
"elems": "11111111",
"lat": [
33,
34.0
],
"lon": [
133,
32.9
],
"alt": 1,
"kjName": "高知",
"knName": "コウチ",
"enName": "Kochi"
}
}
次に、下記URLを指定すると、任意時刻の気象データを取得できます。
https://www.jma.go.jp/bosai/amedas/data/map/{YYYYMMDDhhmm00}.json
# 例えば2024/04/13 22:00の気象データを取得したい場合、
# https://www.jma.go.jp/bosai/amedas/data/map/20240413220000.json
2024/04/13 22:00の気象データのうち、高知観測所データは下記の通りでした。高知観測所の番号である74182をキーとし、気圧、 気温、湿度、降雪量、日照時間、降雨量、風向、風速をJSONで取得できることがわかります。各観測所のアメダスWebサイトと比較すると、変数名の意味がよくわかります。なお、各変数に2つの数字が入っていますが、このサイトから、1つ目の値を取り出せばよいことがわかります。
{
"74182": {
"pressure": [
1019.5,
0
],
"normalPressure": [
1020.1,
0
],
"temp": [
16.1,
0
],
"humidity": [
77,
0
],
"visibility": [
20000.0,
0
],
"snow": [
null,
5
],
"weather": [
0,
0
],
"snow1h": [
0,
6
],
"snow6h": [
0,
6
],
"snow12h": [
0,
6
],
"snow24h": [
0,
6
],
"sun10m": [
0,
0
],
"sun1h": [
0.0,
0
],
"precipitation10m": [
0.0,
0
],
"precipitation1h": [
0.0,
0
],
"precipitation3h": [
0.0,
0
],
"precipitation24h": [
0.0,
0
],
"windDirection": [
12,
0
],
"wind": [
1.2,
0
]
}
}
以上から、まず、取得したい観測所の観測所番号を調べ、その上で、任意時刻のURL文字列を生成し、観測所番号をキーとした気象データを取得する関数を作ると良さそうです。今回は、AWS Lambdaで本関数をつくります。
3. SORACOM Inventoryで気象データをSORACOMへ
従来、SORACOM Harvestへのデータ蓄積や、SORACOM Lagoonでのデータ可視化は、SORACOMのSIMからのデータに限定されていました。しかし現在は、インターネット経由のデータもSORACOM HarvestやSORACOM Lagoonに送ることができます。その際に使うサービスが、SORACOM Inventoryです。SORACOM Inventoryで生成したキーで、データ送信先のURLを作ります。URLは下記の通りです。
https://api.soracom.io/v1/devices/${deviceId}/publish?device_secret=${deviceKey.secret}
# ${deviceId}と${deviceKey.secret}は、SORACOM Inventory設定時に生成されるシークレットなキーです。このURLに、アメダスで得られた気象データJSONをPOSTすると、SORACOM Lagoonで可視化することができます!
4. 気象データ送信関数を定期実行させる
作成したLambda関数は、アメダス気象データを取得し、SORACOMに送信するものでした。例えば1hごとのアメダス気象データをSORACOM Lagoon上にプロットしたい場合、1hごとにLambda関数を実行する必要があります。
このように、Lambda関数を定期実行させる必要がありますが、定期実行には、Amazon EventBridge スケジューラが便利です。例えば、hh:10にLambda関数を実行させるといった設定が可能です。このサイトに従い、設定できました。
5. ChatGPTを活用してLambda関数を作成する
コード作成にあたり、ChatGPT4.0に以下のプロンプトを与えました。
## 設定
あなたは大変有能なAWSエンジニアです。
## 条件
・アメダスの気象データは、以下URLから取り出すことができます。
https://www.jma.go.jp/bosai/amedas/data/map/{YYYYMMDDhhmm00}.json
・なお、{YYYYMMDDhhmm00}の時刻は、日本の現在時刻の分を0とした時刻としてください。
・取り出した気象データは、観測所コードキーとしたJSON構造となっています。
・この内、取得する気象データは、高知観測所の74182としてください。ただし、今後任意の番号を指定したいため、環境変数(OBSERVATION_CODE)としてください。
・取得した気象データは、各変数に2つの数値が入っています。1つ目の数値が必要な数値であるため、1つ目の数値のみを送信するようにしてください。
・SORACOMに送信する際の、URLは以下の通りです。
https://api.soracom.io/v1/devices/${deviceId}/publish?device_secret=${deviceKey.secret}
・${deviceId}と${deviceKey.secret}は、任意の文字列であり、環境変数(DEVICE_ID,DEVICE_SECRET)としてください。
・このURLに高知観測所の気象データをJSONで送信したいです。
・時刻取得には、datetimeのみを用いてください。
## 命令
上記条件をもと、気象庁のアメダスから、1hごとに、任意観測所の気象データを取得し、SORACOMに送信するLambda関数をPythonで作成してください。
## 質問
質問があれば聞いて下さい。
## 確実性
確実性が低いところがあれば示してください。
すると、以下のコードが返ってきました。
(2024/04/24 コードを微修正しました。)
import os
import json
import requests
from datetime import datetime, timedelta, timezone
def lambda_handler(event, context):
# 環境変数から設定を取得(全て大文字で指定)
OBSERVATION_CODE = os.environ['OBSERVATION_CODE']
DEVICE_ID = os.environ['DEVICE_ID']
DEVICE_SECRET = os.environ['DEVICE_SECRET']
# 日本時間 (JST) に設定、UTC+9
jst = timezone(timedelta(hours=+9))
now = datetime.now(jst)
# 分を00に設定してフォーマット
formatted_time = now.replace(minute=0, second=0, microsecond=0).strftime('%Y%m%d%H%M00')
# アメダスAPIのURL
url = f'https://www.jma.go.jp/bosai/amedas/data/map/{formatted_time}.json'
# アメダスデータを取得
response = requests.get(url)
data = response.json()
# 観測所のデータを取得
station_data = data.get(OBSERVATION_CODE)
# データが見つかった場合のみ処理
if station_data:
# データから1つ目の数値のみ抽出
cleaned_data = {key: value[0] for key, value in station_data.items() if isinstance(value, list)}
# SORACOMへの送信データ
soracom_url = f'https://api.soracom.io/v1/devices/{DEVICE_ID}/publish?device_secret={DEVICE_SECRET}'
headers = {'Content-Type': 'application/json'}
payload = json.dumps(cleaned_data)
# SORACOMにデータ送信
soracom_response = requests.post(soracom_url, headers=headers, data=payload)
# 送信結果をログ出力
print(f"Data sent to SORACOM: {cleaned_data}")
print(f"Response Status Code: {soracom_response.status_code}")
else:
print("No data found for the specified observation station.")
return {
'statusCode': 200,
'body': json.dumps('Execution completed.')
}
このコードをLambda関数に貼り付けて実行すると、SORACOM Harvestにデータが飛んできました!あとは、Lagoonで設定すれば、グラフ化できます。
上記は、高知観測所の2024/4/14 19:00のデータですが、高知観測所のWebページを見てみると、データが一致していることがわかります。
ChatGPT4.0を用い、必要最低限のLambda関数を作成することができました!あとは観測所名や取得時刻をJSONに入れると、よりわかりやすくなると思います。またエラー処理も追加したいですね。
まとめと今後の課題
・どのように、アメダスから気象データを取得するか?
・どのように、気象データをSORACOMに送信するか?
・どのように、気象データ送信用Lambda関数を定期実行させるか?
・ChatGPTでLambda関数を作成する方法
を整理してきました。
IoTデバイスで取得した現場データを、気象データと組み合わせることで、データ分析を一歩進めることができました。
今後は、気象データを有効活用するとともに、SORACOM Inventoryの活用や、ChatGPTの活用も進めていきたいと感じました。
IoT現場データx気象データを是非試してみてください。
参考
・アメダスデータをSORACOMに送信できること知った記事です。大変参考になりました。
・アメダスURLの構造は、下記記事も参考にしました。
・AWS Lambdaをpythonで実行するには、requestsライブラリが必要になりますが、レイヤー追加を用いると便利です。
・SORACOM Inventoryの使い方は下記記事がわかりますいです。Inventoryは、アイデア次第で色々と応用が効くサービスだと思っています。
・Amazon EventBridge スケジューラの設定は、この記事を参考にするとスムーズに設定できました。