1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

桜前線の訪れをSlackに通知してみる🌸

Posted at

3月も下旬にさしかかり、うららかな陽気に心躍る季節となりました

いよいよ桜の開花も近づいてきましたね。
今回はそんなワクワク桜の開花予報をSlackへ通知してみようと思います🌸

完成イメージ

sustenでは毎朝天気などともに始業をお知らせしてくれる "sustenくん" というSlackBotがいます。
こちらに桜の開花予報通知機能(赤枠部分)を追加してみることにします。

image.png

こんな通知が毎朝通知がくれば 陰鬱な始業時間でも 朝からワクワクが止まらないことこの上なしですね!!

どうやって予測するのか

桜の開花に関する法則で「桜の開花600度の法則」という有名な法則があります。
これは、2月1日から毎日の最高気温を足していき、その累積が600度になったときに桜が開花するというものです。

今回はこの法則に従って2月以降の累積温度を計算し桜開花600度まであとどのくらいかSlackに通知することにします。

実装の流れ

お手軽に定時実行を行いたかったため GoogleAppsScript を利用した実装を行います。

  1. 気象庁のページから2/1から前日までの最高気温を取得(初回のみ)
  2. 気象庁のページから前日の最高気温を取得(デイリー)
  3. 取得した気温に当日の最高気温(予想)を足し合わせる
  4. 桜開花の進捗をSlackへ通知

前日の最高気温を取得する処理

気象庁のページでは気象に関する様々な情報を提供してくれています。
これらのデータは毎日5時、11時、17時の発表に基づいて更新されます。
今回はGASのParserというライブラリを用いて東京都の過去天気ページをクロールし、前日の最高気温を取得することにします。

image.png

/*
 * 気象庁のページから前日の最高気温を取得する
 */
function _getYesterdayMaxTemperature() {
  const now = new Date();
  const year = now.getFullYear();
  const month = now.getMonth() + 1;
  const TARGET_URL = `https://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php?prec_no=44&block_no=47662&year=${year}&month=${month}&day=&view=p1`;
  // 指定したURLからコンテンツを取得
  const html = UrlFetchApp.fetch(TARGET_URL).getContentText();
  // 取得したコンテンツデータから気象情報をフィルタする
  const rows = Parser.data(html)
    .from(
      '<tr class="mtx" style="text-align:right;">'
    )
    .to("</tr>")
    .iterate();

  // テーブル内の最高気温(8列目のデータ)をすべて抜き出して数値が入っているものだけ抜き出す
  const maxTemps = rows.map(row => row.split("</td>")[7].split('">')[1]).filter(data => data !== "");

  // 一番最後のものが直近(昨日のデータのはず)なので返却する
  return maxTemps.slice(-1)[0];
}

このような処理で前日の最高気温を取得してスプレッドシートに記録を行っており、累積気温はスプレッドシート側で計算させています。
かなり雑なコードですが社内用なので大目に見てください🙈

スクリーンショット 2024-03-25 17.42.58.png

スプレッドシートには記録せずにreduceで足し合わせてもよいのですが、月またぎの処理が面倒くさそうだったので今回はスプレッドシードに記録する方法を採用しました。

桜開花の進捗をSlackへ通知

次にSlackへの通知部分を実装してきましょう!

/*
 * 桜開花状況をSlackへ通知する
 */
function notifyCherryTreeBloom() {
  const MAX = 600;
  const sheet = SpreadsheetApp.openById("xxxxxxxxxxxxxx").getSheetByName("cherry_blossom");
  // シートから累積気温(実績)を取得
  const total = sheet.getRange("B1").getValue();
  // シートから今日の気温(予測)を取得
  const today = sheet.getRange("D1").getValue();

  // Slackに投稿するメッセージの組み立て
  const percent = Math.floor(((today + total) / MAX) * 100);
  const remain = Math.floor(((MAX - (today + total)) * 10) / 10);
  const cumulativeTemperature = Math.floor((today + total) * 10) / 10;
  const graph = [...Array(100 / 5)].map((_, i) =>
    (i + 1) * 5 <= percent ? "" : ""
  );
  let message = "";
  message += `2/1からの累積温度は ${cumulativeTemperature} ℃ :chart-up:\n`;

  // 累積気温が600度を超えていたら開花宣言
  if (MAX <= cumulativeTemperature) {
    message +=
      ":cherry_blossom::cherry_blossom: さくらは開花しています!! :cherry_blossom::cherry_blossom:";
  } else {
    message += `さくらの開花まであと ${remain} ℃ :exclamation:\n`;
    message += `:seedling: 0 ℃ [` + graph.join("") + "] 600 ℃:cherry_blossom:";
  }

  return message;
}

まとめ

記録したデータを基に日々の気温と累積気温をグラフにしてみました。

image.png

東京では3月18日に600度を超えてますが、この記事を書いている2024/03/26時点でまだ開花の発表はありません。
見事に外れてますが人生そんなもんです。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?