最近、37,38度などの猛暑日が続いています。
会社では、出社日が基本的に多いのですが、台風などの災害時には、
RWでOK
、という方針をチームで決めました。
災害級の猛暑なら、行き倒れても困るし、RWでOK!
ということに同じようにしよう、ということにしました。
ただし、熱中症アラートが出た日に限定
。
熱中症アラートとは?
気象庁が出しているものですが、暑さ指数というものに準じてだしています。
気温ではありません。
暑さ指数31以上だと、危険域に入る
とされています。
ので、一旦基準としては、暑さ指数31以上だったら、ということにしました。
しかし、暑さ指数をどこから取れば良いのか。
調べたところ、暑さ指数(WBGT)は、気象庁のサイトでcsvとしてアクセスできるとのこと。
情報提供期間:2023年4月26日(水)~2023年10月25日(水)
という記載があるので、GASでの通知は年ごとに更新する必要はあるかもしれません。
ここから、CSV情報を引っ張ってくれば良さそうです。
2024年に同じスプレッドシートを流用してみましたが、同様に更新されていたので、同じURLを公開しているようです。
暑さ指数の実測値取得
実測値の取得を都道府県別、地点別、などで取得できるようになっています。
詳しくは、前項に貼ったリンクのPDFから確認してください。
岐阜県の暑さ指数実測値URL
https://www.wbgt.env.go.jp/est15WG/dl/wbgt_gifu_202304.csv
これを紐解くと
https://www.wbgt.env.go.jp/est15WG/dl/wbgt_ + 都道府県 _ + 日付.csv
というわけです。天気予報のjsonだと都道府県コードになっているので、それより簡単そうです。
東京の暑さ指数実測値URL
こんな感じですね。
外部CSVデータをGASで取得・・・しかし
通常、csvのデータ取得は、
var input = 'https://www.wbgt.env.go.jp/est15WG/dl/wbgt_tokyo_202307.csv';
let response = UrlFetchApp.fetch(input, options);
で取得できるが、気象庁の暑さ指数のcsvはどういうわけか、UrlFetchAppで取得しようとすると、
Exception: Address unavailable
が出てしまい、アクセスが不可能。
試しに、spreadsheetで、IMPORTDATA()でデータ取得してみると、取得は可能だった。
ただし、日付や時刻は文字化けしているような感じがある。
少し確認してみると、読み込んだcsvのデータが、自動で表示されているため、適宜日時や時間に治す必要がある。
googleか、サイトの権限上の問題がありそうだが、どうにも解決方法が見つからないので、IMPORTDATA()にてシートを介してやりくりする。
地域観測点
csvのデータを覗くと、数字のIDが振られている。これは地域観測点。
気象庁が出しているpdf一覧に記載がある。
44132:東京
こちらを採用してみる。
SpreadSheetで、IMPORTDATA()
GASが読み込むためのシートを用意する。
ただ、さっき引用したのは実測値だったので、当日危険指数31を超えるかどうかは、出勤前には判断ができない。
そのため、見るcsvとしては予測値でなければならない。
東京の暑さ指数予測値
https://www.wbgt.env.go.jp/prev15WG/dl/yohou_tokyo.csv
暑さ指数は、通常の暑さ指数に対して10をかけている。
つまり、310以上になったら、アラートを出せば良い、ということになる。
202307xx15 -> 7月某日、15時に310以上になるなら、アラートを通知する
という仕様としてみる。
スプレッドシートに関数を入れていく
まず結果から
※テストのために、暑さ指数しきい値を200ってことにして出しています。
L2に、危険域かどうか、TRUE or FALSEが入ります。
XLOOKUPで、該当の時間の暑さ指数を探す
XLOOKUPは、スプレッドシートの関数ですが、交差した場所の検索が可能。
まず、WBGT値を割り出す。
セル | 値 | 補足 |
---|---|---|
F1 | 44132 | 東京丸の内の地点 |
H1 | =today() | |
J1 | 21 | テストのためとりあえず21時 |
L1 | =VALUE(CONCATENATE(H1, J1) | |
J2 | =XLOOKUP(F1, B4:B14,XLOOKUP(L1, D3:W3,D4:W14)) | |
L2 | =IF(J2>=200,true,false) | テストのためしきい値を200としておく |
XLOOKUPは、入れ子で呼ぶことで、交差した値を検索することができる。
GAS側の処理
GAS側はこのシートのTRUE or FALSEを引っ張ってきてトリガー通知するだけ。
// スプレッドシートの読み込み
function loadSpreadSheet(url) {
var spredId = url.replaceAll("https://docs.google.com/spreadsheets/d/", '');
Logger.log("id : " + spredId);
return SpreadsheetApp.openById(spredId);
}
/**
* メッセージの送信
*/
function sendSlackMessage(message, channel) {
Logger.log("Send Slack Message");
var url = "https://slack.com/api/chat.postMessage";
var bot_token = PropertiesService.getScriptProperties().getProperty("slackbot_token");
var payload = {
"token": bot_token,
"channel": channel,
"text": message
};
var options =
{
"method": "post",
"payload": payload
};
UrlFetchApp.fetch(url, options);
}
// 暑さ指数についてアラートを出す
// 気象庁のシートをインポートしているが、コレは公開時期が限定されているので注意
function alertWBGT() {
// heat_wbgtシート
var sheet = loadSpreadSheet('シートid');
var wbgt = sheet.getRange("J2");
var wbgtValue = wbgt.getValue();
if (isNaN(wbgtValue)) {
Logger.log('値とれないっす');
return;
} else {
Logger.log("WBGT値:" + wbgtValue);
}
var alert = sheet.getRange("L2");
var alertValue = alert.getValue();
// 暑さ指数が31超えてたら通知する
if (!isNaN(alertValue) && alertValue) {
Logger.log("熱中症アラート:" + alertValue);
var message = ":alert:暑さ指数31を超えてます! :hot_face: 熱中症アラートに注意してください!:alert:"
sendSlackMessage(message, '通知するCH');
}
}
トリガー設定については割愛。
基本的には、スプレッドシートで暑さ指数と、時間を調整する。
補足・・・。
気象庁のCSVじゃなくて、環境庁でした。
実際のしきい値としては、310、時間は12,15時あたりを取ってくるのが良いかと思います。