Help us understand the problem. What is going on with this article?

気象庁の雨量データをスクレイピングしM5Stackで表示する

概要

  • 集合住宅では雨の様子が窓からは分からず、エントランスに出てから雨に気づき傘を取りに戻ることが良くあった
  • 一部のオフィスビル(30階建て以上)では、エレベーターホールに傘のサインで降水を知らせてくれていた
  • ベランダに降水センサーを設置しアラームを通知する方法もあるが、電源確保、センサーの耐久性の面から難しい
  • 気象庁の観測データページを、常時起動しているサーバー(Raspberry Pi)でスクレイピングした結果をM5Stackで表示する
    https://www.data.jma.go.jp/obd/stats/data/mdrr/pre_rct/alltable/pre1h00.html

IMG_9811.JPG

用意するもの

  • Raspberry Pi3 Model B (4でもおそらく大丈夫)
  • Raspberry Pi用のケース
  • Raspberry Pi用のヒートシンク
  • Raspberry Pi3 Model B B+ 対応 電源セット(5V 3.0A)
  • M5Stack
  • M5Stack用の電源
  • Arduino IDEが動くPC (Mac/Windows)

※サーバーは前回作成した来客通知システム(常時起動)を兼用する
https://qiita.com/cami_oshimo/items/b4e4002f7c47dd00ba84

環境構築

(1)Arduino IDEをインストール
https://www.arduino.cc/en/main/software
(2)M5Stack関連のライブラリをインストール
https://mag.switch-science.com/2018/02/28/getting-started-with-m5stack/
(3)Raspberri PiにApache(httpサーバー)をインストールしておく
※Raspberry Pi側のセットアップは割愛

準備

  • 気象庁の降水量のページをChromeのDeveloperToolで開き、該当地区の降水量が出力されている場所を確認する

例)広島市中区 ※私は広島市よりリモート勤務中です
スクリーンショット 2020-09-23 9.57.37.png

プログラミング

  • 常時起動したRaspberry PiでPythonを使ったコードでスクレイピングを行い index.html に出力する
  • M5Stackで index.html を表示する

メインプログラム
広島(ヒロシマ) を他地域に変更すればその土地の降水量が取得できます。

/var/www/html/rain.php
<?php

mb_language("Japanese");//処理言語の設定
mb_internal_encoding("UTF-8");//文字コードの指定
date_default_timezone_set('Asia/Tokyo');//timezoneをセット

$url = "http://www.data.jma.go.jp/obd/stats/data/mdrr/pre_rct/alltable/pre1h00.h
tml";

//webページの読み込み
$contents= file_get_contents($url);

//文字コードの変換
$contents_utf = mb_convert_encoding($contents,"UTF-8","auto");

//指定した文字列で囲まれた部分を取り出す。
$startString = '<td style="white-space:nowrap">広島(ヒロシマ)*</td><td style="
text-align:right;white-space:nowrap;">';
$endString = '</td>';

$startPoint = mb_strpos($contents_utf,$startString) ;//$startStringが現れる位置を調べる
$startPoint = $startPoint + mb_strlen($startString);//開始位置
//echo $startPoint;
//echo"";

$endPoint = mb_strpos($contents_utf,$endString,$startPoint );//$endStringが次に
現れる位置を調べる
//echo $endPoint;
//echo"";

$length = $endPoint - $startPoint;//文字列の長さを求める。
$rainfallString = mb_substr($contents_utf,$startPoint,$length)." mm"."\n\n"."GET
 Time"."\n".date("H:i:s")."\n";
echo $rainfallString;
file_put_contents("/var/www/html/index.html", $rainfallString);
?>

PHP実行用のシェルスクリプト

/var/www/html/cron.php
#!/bin/sh
/usr/bin/php /var/www/html/rain.php

PHP実行結果

/var/www/html/index.html
0.0 mm

GET Time
09:30:02

ブラウザからも見えることを確認する。
スクリーンショット 2020-09-23 9.37.08.png

自動起動の設定(この例では1時間毎に降水量を取得)
*/60 * * * * root sudo sh /var/www/html/cron.sh

M5Stack側のプログラミング

rain.ino
#include <M5Stack.h>
#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid       = "XXXXXXXXXXXXX";  // Wifi SSID
const char* password   = "XXXXXXXXXXXXX";  // Wifi Password

const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;


void setup()
{
  M5.begin();
  M5.Lcd.setBrightness(10);
  M5.Lcd.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      M5.Lcd.printf(".");
  }

  M5.Lcd.println(" CONNECTED");
  M5.Lcd.fillScreen(BLACK);
}

void getrain()
{
  M5.Lcd.fillScreen(BLACK);
  HTTPClient http;

  http.begin("http://xxx.xxx.xxx.xxx/index.html");  // Raspberry PiのIPアドレス
  int httpCode = http.GET();

  String result = http.getString();
  M5.Lcd.setTextSize(5);
  M5.Lcd.setCursor(0,0);
  M5.Lcd.print(result);

  http.end();

}

void loop()
{
  getrain();
  delay(xxxxxxx);  // raspberryPiから `index.html` を取得する間隔(ミリ秒)
}

注意点

  • スクレイピングの頻度を上げすぎると相手側のサーバーの負荷となり、問題になるので気をつける

使ってみて

  • スマホアプリでも降水量が見られるが、玄関先などに置いておくと簡単に確認できるので便利
  • 当初さくらのVPS(Linux)で2年ほど稼働させていたが、月額固定費用がかかることもあり廃止し、Raspberry Piに移行した(1ヶ月程度経過したが問題なし)
cami_oshimo
IoT/DXエンジニア 本業は主にインフラエンジニア。 仕事と趣味で、マイコン、ハードウェア周りも触っています。 ものづくり、メイカーイベントの企画運営も行っています。
https://cami.jp
cami-inc
IoTとクラウドが好きなエンジニア集団
https://cami.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away