| name | mountain-weather |
| description | 登山対象の山の天気を、てんくらの登山指数 (A/B/C) ・気象庁の麓の天気・Open-Meteo の山頂標高指定の数値予報・標高差からの推定で判断する手順。 「○○山の天気」「登山の天気」「明日山に登れるか」「登山指数」「山頂の気温」などを聞かれた際に使う。 てんくらの登山指数は無料のサーバ HTML から取得でき、気象庁の麓・登山口周辺の気象と Open-Meteo の山頂標高指定の数値予報を併せて判断する。 山頂のピンポイント気象数値そのものは保証されないため、指数・麓の天気・数値予報・推定で総合判断し、その限界をユーザに伝える。 |
山の天気の判断
登山対象の山の天気を、登山指数・麓の気象・山頂標高指定の数値予報・標高差からの推定で総合的に判断する手順。
前提: 何が取れて何が取れないか
山頂のピンポイントな気象数値そのものは一般に保証されないが、判断材料となる指標は無料で取得できる。
| ソース | 取得方法 | 中身 | 山頂相当か |
|---|
てんくら (tenkura.n-kishou.co.jp) | fetch-index script (無料のサーバ HTML) | 登山指数 A/B/C (今日・明日は時間帯別、約 1 週間分)、気圧面ごとの気温・風 | 山ごとの独自指数 (山頂を含む予報ベース) |
| 気象庁 (JMA) | curl + jq (無料の JSON) | 麓・登山口を含む細分区の天気・風・降水確率、麓のアメダス地点の気温 | 麓・地域レベル |
Open-Meteo (api.open-meteo.com) | fetch-openmeteo script (無料の JSON API) | 山頂標高指定の気温・湿度・風・突風・降水・降水確率・凍結高度・天気コード (1 時間ごと、最大 7 日) | 標高補正済みの NWP (数値予報) 値 |
判断の主軸はてんくらの登山指数とし、気象庁で麓の実データを、Open-Meteo で山頂標高指定の数値予報を併せて見る。
限界をユーザに伝える
- てんくらの登山指数 (A/B/C) は同社が独自基準で算出した指標であり、山頂の実況気象そのものではない。気象庁データは麓・地域レベルで、山頂とは乖離しうる。
- 山は標高・地形で天気が急変する。麓が晴れでも山頂は強風・荒天ということが普通に起きる。指数や麓の予報を山頂の確定予報のように断定して伝えない。
- 標高差から算出する山頂気温などは推定であると明記する。判断に迷う場合は危険側 (寒い・荒れる前提) に倒し、下振れ (暖かい・穏やか) に丸めて軽装・強行を促さない。
- Open-Meteo の値は数値予報モデルの生値を山頂標高で補正したものであり、予報士による検証を経ていない。地形性の局地風・雷・急変の読みは載らない。てんくらの登山指数を主軸とする判断構造は変えない。
- Open-Meteo の風速は格子平均地形上の 10m 風であり、稜線・山頂の地形による風の加速は反映されず過小になりうる (標高補正の主対象は気温で、風は補正されない)。風は参考値として「実際はこれより強い」前提で扱い、体感温度・行動判断では突風値 (
wind_gusts_10m) やてんくらの気圧面風と比べて強い側を採る。
DANGER: 値がズレると危険なので慎重側に倒す
山の気象判断は安全に直結する。指数・気温・天気を実際より楽観的に (良い指数・暖かい・穏やか) 報告した結果、ユーザが軽装・強行で入山して事故った場合の被害は甚大である。次のガードレールを必ず守る。
- 下振れ方向への丸めは禁止する。不確実な値は危険側に倒す。危険側の向きはリスクごとに決まり、寒い側固定ではない: 低体温・荒天の評価では寒い・強風・荒天側、夏の低山の熱中症の評価では暑い側が危険側。良い方向への切り上げ・楽観はしない。雲量・眺望 (ご来光が見えるか等) は安全リスクでなく目的達成のリスクなので、危険側に倒す対象ではなく両論併記で断定を避ける。
- 推測で値を埋めない。取得できない・確度が低いときはその旨を明示し、安全側で伝える。
- 複数ソース (てんくら・気象庁・Open-Meteo・推定) が食い違うときは楽観側を採らない。悪い方の見立てを主に置き、両方を併記する。Open-Meteo の標高指定気温とてんくらの気圧面気温が食い違う場合も同じ原則に従い、寒い・強風・荒天側を主に置く。比較は同一時刻 (または同一時間帯) の値同士で行う。粒度が違う値 (時間別と日単位など) を突き合わせるときは、細かい側の値が粗い側の期間内で悪くなる時間帯を特定し、その時間帯を悪い側として併記する。
- 山頂気温は逓減率と風の影響で寒い側に寄せる (後述「山頂気温の概算」と接続)。氷点下・強風・発雷・荒天の兆候は省略せず必ず強調する。
- 登山指数は二値ではなく、A = 安全と読み替えない。指数は降水量・風速・雲量ベースで暑熱を主に見ておらず、指数 A でも夏の低山などでは熱中症のリスクがある。逆に指数 C でも樹林帯の登山道では雨・風の影響が小さいことはあるが、これは楽観の根拠にしない。C は荒天前提で扱い、軽装・強行を促さない (良い側の非対称: 悪い含意は残し、良い含意は判断材料にしない)。
- 最終判断はユーザに委ねる。skill 側で「行ける」「問題ない」と断定しない。中止・撤退・日程変更の選択肢を常に残す。
1. てんくらの登山指数 (主軸)
登山指数 (A/B/C) の取得・抽出は scripts の fetch-index に、山コードの検索は find-mountain に集約してある (後述)。kad.html ・ kasel.html を手で curl ・ iconv ・ grep して自前パースしない。この禁止は登山指数・気温・風の抽出に限る。山の同定のために kad.html の標高・近隣市町村の表記を手で確認するのは可 (次節)。
登山指数はてんくらの公式定義で「登山をするための快適さを、山頂や山麓の気象条件から気象学的知見を用いてレベル値で表現した指数。降水量・風速・雲量などを総合的に考慮して独自計算したもの」とされる。数値の気象要素そのものでなく指数として出すのは、気象業務法により無料での山の天気予報の掲載が禁じられているためで、指数は山頂の予報から算出した目安にすぎず、山頂の実況気象そのものではない。
指数の性質は運営元への取材記事 (https://yamahack.com/4594) で次のとおり補強されている。読み違えると楽観に倒れるので判断に織り込む。
- 指数は「指定時間帯の山頂の天気」の判定で、登山口・ルート上の天候は反映されない。麓が雨でも山頂が雲の上で晴れなら A がありうる。だから気象庁の麓データとの併用 (「2.」) は必須で、指数 A を「ルート全体が良い」と読まない。
- B と C の差は雨が降る確率ではなく、雨・風の強さの度合い。「B = 降らないかもしれない、C = 確実に雨」という読みは誤りで、B でも基準値以上の雨・風が予想されている。
- 局所的な発雷の可能性は指数に入っていない。指数 A でも雷リスクは別途評価する (「2.」の発雷の項)。
- 梅雨・前線・台風の時期は前線位置のわずかな変化で天気が大きく変わり、予報が当たりにくい。この時期は指数の確度を落として扱い、直前 (前日・当日朝) の取り直しを必ず案内する。
- 的中率は検証されていない (山頂に測定器が無く検証不能、と運営元)。指数を確率的な保証として扱わない。
山のコードを引く
対象の山の名前から、てんくらの山コード (kad.html?code= の数値) を find-mountain で引く。skill 内のキャッシュ (assets/tenkura-mountains.json。全 9 地域の山リスト kasel.html から生成済み) を検索するのでネットワーク不要。
deno task -q --cwd "$SKILL_DIR/scripts" find-mountain --name=旭岳
-
検索は部分一致。0 件のときは exit 1 で止まるので、--update でキャッシュを取り直してから再判断する (山リストの更新頻度は低いが、新規追加・改名はありうる)。--update はスクリプトが各エントリの ba echo を照合し、CDN キャッシュによる別地域の混入を弾く。
-
pref はコード先頭 2 桁の都道府県。地域は ba (hk 北海道/th 東北/kk 関東・甲信/hr 北陸/tk 東海/kn 近畿/cg 中国/sk 四国/ks 九州・沖縄)。
-
同名の山が複数あることがある (例: 別の山域の同名峰。「旭岳」は北海道と福島県の両方に居る)。pref や標高で対象を確定する。find-mountain の出力は標高を持たないので、同県に同名の山頂候補が複数あるときは kad.html (https://tenkura.n-kishou.co.jp/tk/kanko/kad.html?code=<code>&type=15) を取得し、ページ表記の標高・近隣市町村で確定する (Shift_JIS。iconv で UTF-8 化して見る)。一意に定まらなければユーザに確認する。憶測で 1 つに決めない。候補をユーザに提示するときは、pref ・ code を識別キーとして列挙し、通称への変換は推測しない。
-
リストには山頂以外の地点も混じる (赤岳鉱泉 赤岳山荘 旭岳石室 など)。名前が 山荘 ・ 小屋 ・ ヒュッテ ・ 石室 ・ 鉱泉 ・ 温泉 などの施設語で終わる項目は山頂候補と分けて扱う。同じ山に 富士山山頂 ・ 富士山北麓5合目 ・ 富士山吉田口8合目 のように複数の地点エントリがあるときは、山頂の気象判断には 山頂 を含むエントリを主に使う。 合目 ・ 北麓 ・ 登山口 ・ 施設語・ルート名などのエントリは登山口側のクロスチェック用で、山頂の指数・気温には使わない。対象の山に 山頂 エントリが無く施設・登山口エントリしか無いときは、最も山頂に近い 1 つ (施設語で終わらない山名そのものの項目) を採り、山頂の値は推定である旨を強めに添える。
-
登山カテゴリ (type=15) は find-mountain のキャッシュ生成に固定してある。観光・桜など別カテゴリの地点は混ざらない。
-
県境・独立峰の山はてんくらのエントリが登山口と別の県・別の ba に入ることがある (例: 富士山は ba=kk ・コード先頭 19 = 山梨だが登山口は静岡)。 ba は省略でき code + type=15 で直に引けるので、コードが分かれば ba に依存しない。
-
リスト (kasel) の CDN キャッシュによる別地域の混入は、find-mountain --update がエントリの ba echo 照合で機械的に弾く。手で kasel.html を取得して照合する必要はない。
登山指数を取得する
山のコードが決まったら fetch-index で取得する。ba は不要で code と type=15 (既定) だけでよい。
deno task -q --cwd "$SKILL_DIR/scripts" fetch-index --code=01150271
スクリプトは取得・Shift_JIS デコード・キャッシュ照合・検証・抽出を一括で行い、今日・明日 (時間帯別) と週間の登山指数・気温・風を JSON で出力する。内部動作 (デコード・キャッシュ回避の突き合わせ・検証) は scripts/README.md。
出力の tables[] は tit_day 見出し 1 つ = 1 テーブル。kind が timeband (今日・明日、時刻列) か weekly (週間、日付列) か。各テーブルは次を持つ。
columns: 時刻 (00,03,...) または日付 (7/5(日),...)。
index: 各列の登山指数 A/B/C (mnt1/2/3.gif→A/B/C。A が登山に適、C が不適)。null は過去時間帯 (表示なし) か予報範囲外 (週間の最も先)。欠測ではないので補完しない。指数と時刻・日付は同じ列インデックスで対応する。
levels: 気圧面 (hPa) ごとの temp (℃) と wind (dir 16 方位・ms m/s)。過去・範囲外は null。
出力を読むときの判断 (呼び出し側の責務)。
- 山頂相当の気温・風は気圧面選択で決める。Open-Meteo の標高指定値が正常に取れているときは、この気圧面計算はクロスチェック専用で、回答の主数値には使わない (「4.」参照)。表示される気圧面は日・標高で変わる (
levels[].hPa を都度読む。ハードコードしない)。高度の目安は 950hPa が約 500m、925hPa が約 760m、850hPa が約 1500m、800hPa が約 2000m、700hPa が約 3000m、600hPa が約 4400m。この早見表は概算のフォールバックにすぎない。各気圧面の高度は levels[].alt (例: 高度3100m付近) に実値が入るので、実値が正本。早見表と食い違えば実値を採る。次の 3 ケースは排他で、どれか 1 つだけが当てはまる。 (a) 山頂が表示中の最下面より低い → 山頂標高に最も近い気圧面の値を使う。 (b) 山頂が表示 2 面の間に挟まれる → その 2 面を内挿した値と、直下の面から逓減率で山頂高度まで外挿した値の両方を算出し、寒い側を採る (どちらか一方に決め打ちしない)。 (c) 山頂が表示中の最上面よりさらに上 → 最上面を基点に「4. 山頂気温の概算」の逓減率で山頂まで再外挿する。いずれも確証が持てなければ寒い側 (高い気圧面 = 低い気温) に倒す。
- 気圧面の気温は自由大気の値 (上空の気温) であり、麓や山頂の地表気温・地表体感とは別物。これをそのまま「地表の最高気温」として扱わない。夏の低山の熱中症など地表の暑熱・体感は、気圧面気温ではなく気象庁の麓の地表気温 (アメダス) を主に見る。山頂の寒さ・風は気圧面気温に逓減率と風の体感補正を掛けて寒い側で見る。低山 (山頂が概ね最下気圧面高度前後かそれ以下で、寒さより暑熱の評価が主になる山) では、気圧面ケース (a)(b) のどちらに落ちても、山頂の地表気温は気圧面気温でなく麓アメダスの地表気温から逓減率で概算するのが実態に近い。気圧面気温は寒さ確認の補助に留める。高山 (氷点下・強風のリスク帯) では逆に気圧面気温を主にする。この低山規則は、最寄りアメダスが遠隔参考値しか無い場合 (「2.」の遠隔地点規則) と同時成立しても優先する。暑熱の危険側は暑い側なので、遠隔アメダス由来の逓減率概算と Open-Meteo の標高指定値の暑い側を採り、遠隔・概算である旨を添える。遠隔地点規則が山頂側を気圧面気温に寄せるのは寒さ評価の話で、暑熱評価には適用しない。
- 時間粒度は部位で変わる。今日・明日 (
timeband) は 3 時間ごと、週間 (weekly) は当日 9 時予想の単一値。ユーザが「週間」「今週」を求めた場合は両方を統合して提示する (週間だけでは当日・翌日が欠ける)。対象日が weekly 部にしかないとき (今日・明日より先) は、てんくらの指数・気温については当日 9 時予想の単一値で日内変動が取れない旨を必ず添える (この限界はてんくらのデータに限る。気温・天気・風の日内変動そのものは Open-Meteo の 1 時間値で補える。風は突風 wind_gusts_10m を強い側の照合に使う。登山指数の時間変化だけはどのソースでも補えない。この書き分けを回答に反映する)。
timeband の複数列 (時間帯) を 1 つの代表値に縮約するときは、登山の行動想定時間帯の列を採る (時刻が未指定なら日中を既定とする)。ただし対象の山に夜間・早朝行動が慣行的な場合 (富士山のご来光登山など) は、その冷える時間帯も安全側の代表に含めるか、行動時間帯をユーザに確認する。日中だけを見て夜間の寒さを落とさない。その範囲では指数の悪い列・気温の寒い列・風の強い列を安全側で選ぶ。山頂気温の内挿・外挿は同一時刻の鉛直 2 点で行う (別々の時刻の最寒値を混ぜない)。行動時間帯の各時刻で山頂気温を出し、その中で最も寒い時刻を安全側の代表として採る。時間帯で振れが大きいとき (例: 夕方に指数が C へ急落する) は最悪の時間帯を必ず併記し、良い時間帯だけで代表させない。推定気温は単一の点でなく、寒い側を下限とする幅で示す (内挿値〜逓減率を大きめに取った外挿値のレンジ。代表値は最寒側)。細かい方式選択 (逓減率 0.6〜1.0 のどこ、内挿か外挿か) は運用判断でよく、常に寒い側に倒して幅で伝えれば足りる。
- どのテーブルがどの日かは
heading (今日7/3(金) 等) で確定する。先頭 = 今日と決め打ちしない (夜遅くは今日分が落ち先頭が明日になる)。
- 登山指数は二値ではない。指数と気温・風の数値の断定に確証が持てないときは、指数 (A/B/C) を主に使い、気温・風の数値の断定は避け、山頂気温は「4. 山頂気温の概算」の逓減率で安全側に出す。
- DANGER: 指数と日付・時刻の対応を手 grep の行近接 (
grep -A/-B/-C) で取らない。日付行と指数行は別々の <tr> で、行近接は指数行の先頭列を別日と取り違える (例: grep -A5 '7/3' が 7/1 の指数を 7/3 の指数と誤読する)。スクリプトはこれを列インデックスで対応づけている。スクリプトを使わず自前で解析する場合も、必ず列位置 (日付行の N 列目と指数行の N 列目が同じ日) で取る。
抽出の検証
fetch-index が exit 1 で停止したら値を捏造しない。停止理由 (登山指数 0 件 = type 誤りや HTML 構造変化、code 不一致 = CDN が別ページを返した、テーブル抽出 0 件) を報告し、必要なら scripts・skill を更新する。
- スクリプトは
code= と alt="登山指数" で取得物を照合し、cache-bust の 2〜3 回取得で CDN の別版・古い版 (日付ヘッダ・指数 gif・気圧面の fingerprint 不一致) を弾く。それでも title・近隣市町村名が対象の山と合うかは最終的に人が確認する。別の山・別県のデータを山頂判断に使うのは危険。
- 指数と日付・時刻の対応がずれると別の日の指数を読む。
heading と columns の並びが妥当か確認し、ずれを疑ったらユーザに提示して確認する。
- HTML 構造が変わって抽出に失敗したら
scripts/cli/parse.ts とこの skill を更新する。
2. 気象庁の麓の天気 (補完・クロスチェック)
てんくらの指数に加え、麓・登山口周辺の実データ (天気・気温・降水確率) を気象庁から取る。気象庁の予報は気象台 (都道府県) 単位で、その中の細分区 (北部・南部・山沿いなど) に分かれる。
DANGER (実行): forecast の取得から照合・値の抽出までを 1 つの Bash 呼び出しにまとめる。エージェントのシェルはコール間で cwd・変数・mktemp -d のパスが失われるため、取得と抽出を別の Bash 呼び出しに分けると一時ファイルを見失って取り直しになる。実行時は mktemp -d で作った 1 つのディレクトリを使い、forecast 取得・照合・抽出を同一コマンド内で連結する。細分区・office の解決はネットワーク不要の find-area (次節) で先に済ませてよい。
区域コードを引く (find-area)
どの細分区かは地理勘で決めず、登山口の市町村名から決定的に引く。find-area が skill 内のキャッシュ (assets/jma-area.json。気象庁 area.json から生成済み) を使い、class20s (市町村・地区レベル) → class15s → class10 (細分区) → office (気象台) の parent 連鎖を辿る。ネットワーク不要。
deno task -q --cwd "$SKILL_DIR/scripts" find-area --municipality=富士宮市
-
0 件のときは exit 1 で止まる。より広い市名・近隣地名で引き直し、市町村合併等でキャッシュが古い可能性があれば --update で取り直す。
-
細分区名は都道府県ごとに異なる (北部・南部、内陸・沿岸、南部山沿い・北部平野部など)。固定の名前を決め打ちせず、必ず上の方法で登山口の市町村から細分区を引く。
-
class20s の地区名は細かい (例: 松本市乗鞍上高地)。登山口に対応する地区語で引くと精度が上がる。市町村名でヒットしないときは、より広い市名や近隣地名で引き直す。
-
てんくらが表示する「近隣市町村」は山頂位置基準で選ばれ、登山口と一致しないことがある。気象庁の細分区・アメダスは必ず登山口の実所在地から独立に引き、ソース間で地点が違えば回答に明記する。
-
登山口が複数県にまたがる山 (例: 富士山の吉田口 = 山梨と富士宮口 = 静岡) でルートが未指定の場合は、主要登山口を複数併記するか、ユーザにルートを確認する。1 つの登山口に決め打ちしない。
-
山沿い・内陸の区分がある県では、山に近い区を優先する。平野部の天気は山と乖離しやすい。
-
北海道は気象台が複数に分かれるので、登山口を管轄する office を選ぶ。
予報を取得する (forecast)
tmpdir=$(mktemp -d)
curl -sS 'https://www.jma.go.jp/bosai/forecast/data/forecast/200000.json' -o "$tmpdir/forecast.json"
配列は 2 要素で [0] が 3 日予報、[1] が週間予報。[0].timeSeries は 3 本あり区分単位が異なる。
| timeSeries | 内容 | 区分単位 |
|---|
[0] | 天気 weathers ・天気コード weatherCodes ・風 winds | 細分区 (class10) |
[1] | 降水確率 pops | 細分区 (class10) |
[2] | 気温 temps (最低・最高) | アメダス観測地点 (麓の地点) |
天気・降水確率は細分区単位だが、気温だけはアメダス地点単位で粒度が違う。気温を細分区から探すと空振りする。3 日予報の temps は timeDefines の 00 時が最低・09 時が最高に対応するのが通例だが、位置に意味を決め打ちせず、週間予報側の tempsMin/tempsMax と突き合わせて解釈を確認する。
jq '.[0].timeSeries[0].areas[] | select(.area.code == "200020") | {area: .area.name, weathers, winds}' "$tmpdir/forecast.json"
jq '.[0].timeSeries[1].areas[] | select(.area.code == "200020") | {area: .area.name, pops}' "$tmpdir/forecast.json"
jq '.[0].timeSeries[2].areas[] | {name: .area.name, temps}' "$tmpdir/forecast.json"
- 気温のアメダス地点は登山口に最も近いものを名前で選ぶ。判断できない場合は複数地点を併記して幅で伝える。憶測で 1 地点に決め打ちしない。最寄り地点が登山口から離れているとき (県に近傍地点が 1 つも無い場合 = 例: 東京は都心・離島のみ、最寄りは在るが水平距離が遠い場合 = 例: 富士宮口に対する三島、最寄りでも登山口と標高差が大きい場合 = 例: 旭岳の登山口 (約 1100m) に対する平地のアメダス旭川 (約 120m)) は、その 1 点を「遠隔地点の参考値」と明記して採り、山頂側の気温は Open-Meteo の標高指定値 (取れなければてんくらの気圧面気温) を主とする (序列は「4.」に従う)。近い・遠いの線引きに迷えば遠隔参考値として扱い断定を避ける。遠隔参考値を暑熱評価に使うときは、登山口側がこれより暑い可能性 (都心・沿岸の地点と内陸の登山口の傾向差) を注記する。
- 各値がどの日時に対応するかは同じ
timeSeries の timeDefines で必ず確認する。配列の index に意味を決め打ちしない (取得時刻によって入る要素が変わる)。[0] 内でも系列ごとに終端日が揃わない (深夜取得では weathers に翌日があっても pops/temps が当日までのことがある)。目的日の値が timeDefines に無ければ週間予報 [1] へフォールバックし、県単位・遠隔地点の参考値である旨を必ず併記する。フォールバック要否は抽出後にしか分からないため、初回の同一コマンド内で 3 日予報 [0] の weathers・weatherCodes・winds・pops・temps と、週間予報 [1] の weatherCodes・pops・temps を無条件に抽出しておく (後から要ると分かって取り直さない。[0] の weathers・weatherCodes は後述の天気コード和名照合にも使うため必ず初回リストに含める)。
- 取得した forecast が別の県の内容になっていないか検証する。レスポンスの
publishingOffice と areas[].code の先頭桁が要求した office と一致するか確認し、不一致なら (キャッシュ等で別府県を掴んでいる) 取り直す。別県の予報を山頂判断に使うと危険。取り直すときはクエリ文字列 (例: ?_=1) を付けるか -H 'Cache-Control: no-cache' で CDN キャッシュを回避する。
- 数日先 (週間予報
[1]) は粒度が落ちる。 weather・降水確率が細分区ではなく office (県) 単位、気温がアメダス少数地点になり、登山口近傍の細分区・地点が得られないことがある。時間粒度も落ち、降水確率・天気は日単位の代表値になる (時間帯別は取れない)。その場合は県単位・遠い地点・日単位の値だと明記して参考扱いにする (地点粒度と時間粒度の両方の低下を併記する)。最寄りアメダスの目的日の値が取れないときは、同地点の当日・直近日の値を「別日の参考」とラベルして添えてよい (目的日の値の代用にはしない)。3 日予報と週間予報の両方に同一日・同一対象の値があって食い違う場合も、ソース間の食い違いと同じ原則 (危険側を採り両方併記) で扱う。
publishingOffice・area.code が正しい県でも、気温 timeSeries[2] のアメダスだけ別県が混入することがある (office・code 照合では気温の県跨ぎを検出できない)。気温地点名が対象県の地点か照合し、県外の地名が出たらキャッシュを回避して取り直す。別県の気温で山頂を概算するのは危険。
- 天気コードの和名は別ファイルに頼らず、同じ forecast の
[0].timeSeries[0].weathers (日本語文字列) で同コードの意味を確認する。週間部だけに出るコードが [0] に無いときは、コードの百の位 (2xx = くもり系・3xx = 雨系・4xx = 雪系) で安全側 (降水・降雪あり前提) に解し、ピンポイントの和名は断定しない。
- 発雷は山で最も危険な現象の 1 つ (小屋以外に逃げ場がない)。
weathers/weatherCodes に雷 (「雷」の語・コードの一部) が出たら、時間帯と併せて必ず強調する。ピンポイントの天気マークに出ていなくても、周辺の細分区・広域の概況に雷傾向があれば急変の兆候として扱う。
- 登山前日の天気も確認する。前日が大雨だと登山道のぬかるみ・沢の増水・土砂崩れが当日の行動に影響する。当日分の予報だけで判断せず、前日の降水を併せて見る (前日に予報を取得しておく、または当日にアメダスの前日降水量で補う)。
3. Open-Meteo の山頂数値予報 (標高指定の第三のソース)
山頂の緯度・経度・標高を指定した数値予報を Open-Meteo (api.open-meteo.com) から取る。キー不要・非商用無料の JSON API で、elevation に山頂標高を渡すと 90m DEM ベースの標高補正が適用された値が返る。取得・検証は scripts の fetch-openmeteo に集約してある (内部動作は scripts/README.md)。
deno task -q --cwd "$SKILL_DIR/scripts" fetch-openmeteo --lat=35.3606 --lon=138.7274 --elevation=3776
- 引数は
--lat ・ --lon ・ --elevation (いずれも必須。標高は山頂の m)。--days は任意 (既定 3、最大 7)。timezone は Asia/Tokyo、風速単位は m/s に固定してある。
- 出力は 1 時間ごとのレコード (
hourly[]) で、気温・湿度・風速・突風・降水量・降水確率・凍結高度 (freezing_level_height)・天気コードを持つ。単位は units に入る。
- スクリプトはレスポンスの
elevation が指定値と一致することを検証する。不一致・HTTP エラー・error: true のレスポンスは exit 1 で停止する。停止したら値を捏造せず理由を報告する (取得失敗時は止めて報告する原則)。
- 山頂の緯度・経度・標高は地図・公的資料から確定して渡し、憶測で置かない。確定手段: 国土地理院の標高 API (
https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?outtype=JSON&lon=<経度>&lat=<緯度>) に候補座標を渡し、返る標高が対象の山頂標高と数十 m 以内で一致することを確認してから使う。大きくずれる座標は山頂を指していない。レスポンスの latitude/longitude はモデル格子に丸めた値が返るが、elevation は指定値がそのまま echo される (これを検証に使う)。
weather_code は WMO コードの数値のまま出る (スクリプト側で和名変換しない)。大まかな系列 (0〜3 = 晴れ〜くもり、45/48 = 霧、5x = 霧雨、6x = 雨、7x = 雪、8x = にわか、95 以上 = 雷雨) で安全側に読み、細かい和名の断定はしない。95 以上 (雷) が出たら時間帯と併せて必ず強調する。
freezing_level_height (凍結高度) が山頂標高を下回る時間帯は山頂付近が氷点下になりうる。防寒・凍結・降雪のリスクとして必ず伝える。逆に凍結高度が山頂より上でも、直接値の temperature_2m が氷点下ならそちらを採って氷点下として扱う。直接値と派生指標が食い違うときは常に寒い・危険側を採る。降水の相 (雨か雪か) は weather_code を正とし、凍結高度は補助に留める。両者が矛盾するとき (凍結高度が山頂より上なのに雪コードが出る等) は雪・凍結側 (危険側) で伝える。
- 降水量・降水確率・
weather_code が食い違うとき (量 0 なのに確率が高い等) も危険側で読む。確率が高ければ量 0 でも「降りうる」前提で伝え、雨具・行動打ち切りの判断材料に含める。
- 風の取得元の主はてんくらの気圧面風とする (「1.」の気圧面選択規則で採る)。Open-Meteo の
wind_speed_10m は地形加速が載らず過小になりうるため参考値に留め (「限界をユーザに伝える」参照)、wind_gusts_10m は強い側の照合に使う。体感補正・行動判断は各値の強い側を採る。
4. 山頂気温の概算 (Open-Meteo 主・標高差フォールバック)
山頂気温は前節 Open-Meteo の標高指定値を主とする。山頂標高そのもので補正した 1 時間ごとの値が取れるため、気圧面からの内挿・外挿や麓からの概算より直接的である。ただし数値予報の生値であり山頂の実測ではない (「限界をユーザに伝える」参照)。てんくらの気圧面気温と食い違えば寒い側を主に置く。この比較は同一時刻の値同士で行う (てんくら週間部の 9 時単一値と比べるなら Open-Meteo も同日 9 時の値を使う。行動時間帯の代表値の選定はその後に別途行う)。単一時刻でしか比較できない場合、その時刻で観測した乖離を他時刻へ定数として展開しない。乖離の事実は「他の時刻も同程度ずれる可能性がある」という幅の悪い側の注記としてのみ反映する。Open-Meteo が正常に取れているとき、気圧面からの内挿・外挿はクロスチェック専用で、回答の主数値には使わない。提示する幅は主ソース内の不確実性 (時間帯の振れ・逓減率の幅) で構成し、ソース間の乖離が大きいときは乖離を幅に混ぜて広げず、寒い側ソースの値を代表・幅として他ソースの値は「別ソースでは X ℃」と注記で併記する。「乖離が大きい」かの判定は標準逓減率 (0.6) での推定値と主ソース値の差で測り、迷ったら閾値の議論で止まらず寒い側を代表にする。クロスチェックの計算は行動時間帯内の代表 1〜2 時刻で足りる (全時刻分は不要)。行動時間帯の既定と安全側の列の選び方は「1.」の timeband 縮約規則と共通で、Open-Meteo の 1 時間値の縮約にも同じ規則を適用する。乖離を検出したら比較できていない時刻も「同程度ずれる可能性」として幅の悪い側の注記に反映し、代表に採った時刻が比較できた時刻と異なるときはその旨 (比較は 9 時のみ等) を添える。
Open-Meteo が取得できない場合 (API 停止・ネットワーク断・fetch-openmeteo が検証不一致で停止した場合) は、次の標高差からの概算にフォールバックする。てんくらが上空の気温を出すが、取れない場合や麓のデータしかない場合も同様に標高差から概算する。いずれも推定であり山頂の実測ではない。危険側に倒し、下振れに丸めない。なお、てんくらの上空気温は参照気圧面の値 (例: 800hPa は約 2000m) で、山頂標高より低いことがある。その場合はてんくら上空気温を基点に、下式で山頂標高まで再外挿する。
標高が 100 m 上がるごとに気温は約 0.6 度下がる (気温逓減率)。
山頂気温の概算 = 麓の気温 - 0.6 × ((山頂標高 - 基点標高) / 100)
- 基点標高は「その気温を観測・予想した地点の標高」を使う。アメダス地点の値ならアメダス地点の標高、登山口の値なら登山口標高。遠隔アメダスの気温を採ったのに基点だけ登山口標高にすると差し引きがずれる。アメダス地点の標高は気象庁の地点一覧 (
https://www.jma.go.jp/bosai/amedas/const/amedastable.json、地点名 kjName・標高 alt) で引ける。引けないときは 0m とみなしてよいが、その簡略化と向き (山頂側の概算が涼しく出る) を回答に明記する。
- 式の入力 (基点標高・山頂標高) は地図・公的資料から確定し、概算値を使ったときはその旨を回答に明記する。取得手段の無い変数を勝手な精度で断定しない。
- 逓減率 0.6 度/100m は標準的な目安。晴れて乾いた日は約 1.0、湿って雲が多い日は約 0.5 と幅がある。1 点の値で断定せず、迷うときは寒い側 (大きい逓減率) で見積もる。
- 体感温度は風速 1 m/s ごとに約 1 度下がる。稜線・山頂は麓より強く吹くのが通常なので、麓基準より厳しくなる前提で伝える。風速も気温と同じ気圧面選択規則で採り、2 面で迷う場合は強い側の風速を使う (体感は寒い側に倒す)。風の取得元の主はてんくらの気圧面風とし、Open-Meteo の 10m 風・突風と食い違うときも体感補正には強い側を採る。風も気温と同じ 2 段階で処理する: まず同一時刻の値同士でソース間比較して強い側を採り、次に行動時間帯の中の最悪 (最強) の時刻を代表に選ぶ。
- 最低気温側で氷点下・一桁になるなら、防寒・低体温のリスクとして必ず伝える。
注意
- 取得結果には対象の山・都道府県・細分区・アメダス地点・日時を必ず添える。どの地点・どの時間の値かを曖昧にしない。
- 「ユーザに確認する」と指示された分岐 (同名の山・登山口ルート・行動時間帯など) で確認が取れない実行環境では、依頼文の文脈 (地名・
pref・標高・慣行) から安全側に仮確定して進め、採った仮定と識別キー (code・pref 等) を回答に必ず明記する。複数の解釈が同程度に成り立つ場合は全候補を併記する。
- この skill が扱うのは天気の判断のみ。開山期・登山道の開通/通行止め・入山規制・登山届などは天気とは別事項で、skill 側で開通可否を断定しない。該当しそうな場面 (例: 富士山の週末が開山前) では「天気とは別に開通状況を必ず確認する」と一言添えるに留める。
- 登山指数は同社の独自指標、山頂気温・体感温度は推定であり、いずれも山頂の実況を保証しない。断定せず、安全側に倒して伝える。
- てんくら・気象庁のデータは明示的なオープンデータライセンスが確認できていない。取得した生データの無断の二次配布・公開はしない。Open-Meteo のデータは CC BY 4.0 で、ユーザへの提示時に出典 (Open-Meteo) を添える。
- scripts の実行は必ず
deno task -q で行う。-q が無いとタスクランナーのバナー行が stdout に混ざり、jq 等での機械処理が壊れる。
- 気象庁側で使う一時ファイル (
forecast.json) は mktemp -d で実行ごとに一意なディレクトリを作りその中へ置く (固定パスは並行タスクに上書きされ、別対象のデータを掴む事故が起きる)。後続の jq も同じ絶対パスを参照し、照合と値の抽出は同一コマンド内で行う。山コード検索 (find-mountain)・区域解決 (find-area)・てんくら取得 (fetch-index)・Open-Meteo 取得 (fetch-openmeteo) は script が一括で行うので一時ファイルを手で持たない。
- 取得・抽出に失敗した場合 (
find-mountain・find-area が --update しても 0 件/fetch-index が登山指数 0 件で停止/fetch-openmeteo が elevation 不一致で停止/forecast の構造が変わる等) は値を捏造しない。処理を止めて報告し、scripts・skill を更新する。
- てんくらの活用ガイド (指数の定義・見方・注意) : https://tenkura.n-kishou.co.jp/tk/info/tozan_guide.html。指数の性質の取材記事: https://yamahack.com/4594。