地震を検知してGoogle Nest Hubにリアルタイム震度マップを表示しよう

## はじめに

地震が心配なので、家に 地震の見張り番＠home という緊急地震速報機を置いてます。
ただ、皆さんもご存じのとおり緊急地震速報のアラーム音は心臓に悪いので、本当に危ない震度5以上の地震だけを通知する設定にしています。

https://www.century.co.jp/products/jmb-ah.html

ちょっと揺れるぐらいの地震の場合、もうちょっとマイルドに地震情報を知りたいのですが、スマホの地震情報通知アプリの場合はたいてい揺れが来た後の通知となります。出来れば揺れる前に通知が欲しい。

そこで、地震発生後なるべく早いタイミングで、リアルタイム震度情報を自動で表示してくれるシステムを作りました。

![MVIMG_20211212_123145.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12960/f5206d4a-ac42-c2f4-1fc5-2f7ee4351b9f.jpeg)

## システム構成

用意したのは２つ:

- Node-REDをインストールしたRaspberry Pi
- 画面付きスマートスピーカーのGoogle Nest Hub

![P2P地震情報でリアルタイム震度マップを表示.システム構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12960/86a8291d-4085-e186-e3a9-7f06fbc1847f.png)

大まかな流れは以下となります：

- P2P地震情報サーバーが、Raspberry Pi (Node-RED)に地震の情報を通知
- Raspberry Pi(Node-RED) がGoogle Nest Hubに強震モニタのWebページを表示するように通知

Raspberry Piのセットアップ手順はこちら:

https://qiita.com/tinoue@github/items/10b31e51032259559a79

## Google Nest Hubを使ったリアルタイム震度マップの表示

Google Nest Hubに防災科学研究所の強震モニタのページを表示します。

http://www.kmoni.bosai.go.jp/

### Google Cast APIで、Nest HubにWebページを表示

Google HomeやNest Hubは、Google Chromecastとしての機能も持っています。このためGoogle Cast APIを使用すれば、面倒な認証などなしでストリーミング音声やYoutube動画の再生・Webページの表示が行えます。

今回はcatt (https://github.com/skorokithakis/catt) というPythonプログラムを使用しました。Raspberry Pi上で以下のようなコマンドを実行することで、「リビング」と名付けたGoogle Nest Hubに、防災科学研究所の強震モニタのページを表示できます。

```bash
#catt -d リビング cast_site http://www.kmoni.bosai.go.jp/
```

### Raspberry Pi (Node-RED)を中継して横画面で表示

強震モニタの表示は縦長の画面を想定したもので、Nest Hubだと左半分に小さく表示されてしまいます。
そのため、Node-REDのWebサーバ機能を使って、強震モニタの画面を90度回転させて表示するwebページを用意しました。強震モニタをiframe内に表示し、CSSで90度回転させています。
Nest Hubには`http://<Raspberry PiのIP address>/earthquake` を表示するようにリクエストします。

### Google Nest HubのCast APIの動作仕様変更に対応する

2021年8月頃からWebサイトのキャストで以下のような動作仕様変更がGoogle Nest Hubにおこなわれています。

- cast_siteで表示したWebページが30秒で消される（従来は10分）
- cast_siteした後、stopをリクエストしないと、以後のcast_siteリクエストが無視される。

特に後者は致命的なので、表示リクエストの29秒後にstopリクエストを行うように対応しています。ともあれ、30秒で表示が消えるのは今後何とかしたいところです。

作成したフローはこちら: https://github.com/tinoue/node-red-flows/blob/master/earthquake-warning/nest-hub-earthquake-map.json

※ `node-red-contrib-credentials`, `node-red-contrib-hostip`を事前にインストールしてください。

![スクリーンショット 2021-12-20 22.13.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12960/a37230de-b2b7-ae3d-6916-edd86f0c04cd.png)
このフロー、IFTTTと連携して「OK Google, 地震情報」と言うとこの震度マップを表示する機能もついてるのですが、今回は割愛します。

なお、cattコマンドは重量級プログラムで、Raspberry Pi4でも実行に秒単位で時間がかかります。実行時間短縮のためサービス化したcattを使用しています。通常のコマンドライン版cattのノードもフロー中に残しているので、そちらを使う場合は繋ぎ変えてください。

https://qiita.com/tinoue@github/items/98ecdf223ed5cbc46b76

## P2P地震情報APIを使った地震発生の検知

P2P地震情報 (https://www.p2pquake.net/) は、気象庁が発表する地震情報と、ユーザ同士の「揺れた！」という地震感知情報をP2Pネットワークで共有するサービスです。

[P2P地震情報 JSON API (v2)](https://github.com/p2pquake/epsp-specifications/blob/master/json-api-v2.yaml)のWebsocket APIを使用し、以下の情報をサーバーからRaspberry Pi(Node-RED)に通知してもらいます。



### 緊急地震速報 (code 554):

```json
  {
    "code": 554,
    "id": "61b1647002add632b0cf6ba0",
    "time": "2021/12/09 11:05:35.839",
    "type": "Full"
  }  
```

NHKテレビ・ラジオの緊急地震速報相当です。日本のどこかで震度5弱またはそれ以上の地震が発生した場合に通知されます。これが来た場合は、常にリアルタイム震度マップを表示します。

### 地震検知情報の評価結果 (code 9611): 

```json
  {
    "area_confidences": {
      "205": {
        "confidence": 0.0024614206148173075,
        "count": 1,
        "display": "E"
      },
      "215": {
        "confidence": 0.003644880157817441,
        "count": 1,
        "display": "E"
      },
    },
    "code": 9611,
    "confidence": 0.97024,
    "count": 5,
    "id": "61b56d01adc2d40dc85f6c65",
    "started_at": "2021/12/12 12:31:12.373",
    "time": "2021/12/12 12:31:13.514",
    "updated_at": "2021/12/12 12:31:13.276",
    "user-agent": "userquake-aggregator 20200713",
    "ver": "20200713"
  }
```

これに関しては地域での絞り込みを行います。`area_condidences`に含まれる検知対象地域を参照します。地域コード一覧は [GitHub: epsp-specifications/epsp-area.csv · p2pquake/epsp-specifications](https://github.com/p2pquake/epsp-specifications/blob/master/epsp-area.csv) 参照。

今回は関東を対象とし、200番台の地域コードが存在するかどうかで判定を行います。速報性重視のために、関東でちょっとでも揺れを検知すると表示を行うことにします。
そのため、有感地震でない場合も表示の対象となってしまいます。夜中にこれで起こされるのはきついので、0:00AM - 6:59AMの間は`display`(信頼度)が"E","F"と低い場合は表示対象外とします。

作成したフローはこちら： https://github.com/tinoue/node-red-flows/blob/master/earthquake-warning/earthquake-detector.json
![スクリーンショット 2021-12-20 22.16.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12960/d5b5332f-554d-9436-a7b1-f80bdc3fd8bd.png)
利用する場合、function node中の地域コード判定を自分のいる場所に応じて修正してください。

## 実際の動作例

2121年12月12日の茨城県西部が震源の震度4の地震を例に挙げます。

https://typhoon.yahoo.co.jp/weather/jp/earthquake/20211212123108.html?t=2

自分のいる多摩地区では、残念ながら揺れだして数秒後に震度マップが表示されました。

- P2P地震情報の地震感知データ

```json
  {
    "area_confidences": {
      "205": {
        "confidence": 0.0024614206148173075,
        "count": 1,
        "display": "E"
      },
      "215": {
        "confidence": 0.003644880157817441,
        "count": 1,
        "display": "E"
      },
      "225": {
        "confidence": 0.0022779776991412675,
        "count": 1,
        "display": "E"
      },
      "231": {
        "confidence": 0.00045538907233090694,
        "count": 1,
        "display": "E"
      },
      "250": {
        "confidence": 0.00015625197986033522,
        "count": 1,
        "display": "E"
      }
    },
    "code": 9611,
    "confidence": 0.97024,
    "count": 5,
    "id": "61b56d01adc2d40dc85f6c65",
    "started_at": "2021/12/12 12:31:12.373",
    "time": "2021/12/12 12:31:13.514",
    "updated_at": "2021/12/12 12:31:13.276",
    "user-agent": "userquake-aggregator 20200713",
    "ver": "20200713"
  }
```

地震の際、地震感知情報はほぼ毎秒通知されますが、それを可視化したのがこちらのアニメーションGIF ([P2P地震情報 Web版](https://www.p2pquake.net/app/web/)よりダウンロード)
![61b56e5fadc2d40dc85f6cde.optimized.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12960/8dba9313-d3b5-db0d-cbd0-084e0df55ed7.gif)
これを見ると、山梨県東部や千葉県南部などでは地震検知の感度が低いことがわかります。ユーザー情報ベースなので、ユーザーが少ない地方での検知感度は都市部に比べると劣ります。

P2P地震情報 Web版 (https://www.p2pquake.net/app/web/) を見ると、自分のいる地域での地震感知の感度を把握することができると思います。

- Yahooリアルタイム震度のデータ

比較のために、同時刻のYahooリアルタイム震度 (https://typhoon.yahoo.co.jp/weather/jp/earthquake/kyoshin/) のデータを見てみます（`intensity`データは省略）。

```json
{
  "realTimeData": {
    "dataTime": "2021-12-12T12:31:11+09:00",
    "siteConfigId": "20191010150000",
    "intensity": ""
  },
  "psWave": {
    "items": [
      {
        "latitude": "N36.2",
        "longitude": "E139.9",
        "pRadius": "65.6662",
        "sRadius": null
      }
    ]
  },
  "hypoInfo": {
    "items": [
      {
        "reportTime": "2021-12-12T12:31:11+09:00",
        "regionCode": "301",
        "regionName": "茨城県南部",
        "longitude": "E139.9",
        "isCancel": "false",
        "depth": "60km",
        "calcintensity": "04",
        "isFinal": "false",
        "isTraining": "false",
        "latitude": "N36.2",
        "originTime": "2021-12-12T12:30:58+09:00",
        "magnitude": "5.1",
        "reportNum": "1",
        "reportId": "20211212123108"
      }
    ]
  },
  "estShindo": {
    "startMeshIdx": 5199,
    "intensity": "",
  },
  "copyright": [
    "National Research Institute for Earth Science and Disaster Resilience",
    "Yahoo Japan Corporation"
  ],
  "version": "2.0"
}
```

Yahooのデータでは、12:30:58発生の地震を13秒遅れの12:31:11に通知しています。P2P地震情報では12:31:13と地震発生後15秒遅れの通知ということになります。
P2P地震情報がYahooより2秒遅く見えますが、Yahooのデータはポーリング取得のため、実時間の数秒遅れの取得になるようです(ブラウザでの動作を検証すると2秒遅れの取得でした)。したがってP2P地震情報でもYahooとそん色のない早さでの地震検知ができるようです。

https://techblog.yahoo.co.jp/entry/2021030830078060/

Yahooのデータは震源・震度・そして揺れの到着時間が推定できるのが特徴なのでちょっと使いたい気もするのですが利用規約的にグレーなので、その心配がないP2P地震情報はありがたい存在です。

なお、地震を検知してからGoogle Nest Hubに震度マップが表示されるのに約8秒かかります。このため今回の例だと地震発生から震度マップ表示完了まで15+8で計23秒。地震のS波はその間に約70km進むことになります。