見出し画像

【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 スケジューラの設定は、この記事を参考にするとスムーズに設定できました。


この記事が気に入ったらサポートをしてみませんか?