Raspberry Piを使って簡単・低コストで天気予報を大型画面に表示する方法

## はじめに

前回は、毎日の天気予報をLINEに通知し、Googleスプレッドシートに記録するアプリを作成しました。

https://qiita.com/nishifeoda/items/7e458b261111f201c724

このアプリは、特定の人向けに情報を提供するものでしたが、今回はより多くの人がわかりやすく情報を確認できるよう、天気予報を大きな画面に表示するシステムを作ってみました。

大きな画面に情報を表示する仕組みは「デジタルサイネージ」と呼ばれ、駅や店舗などで見かけるようなディスプレイを使って情報を伝えるものです。近年では、東京駅や大阪駅などの主要な場所でも目にする機会が増えています。実際にデジタルサイネージを導入すると高額な費用が必要ですが、今回はこれをRaspberry Piを使って安価に実現する方法を紹介します。

このシステムをオフィスや食堂など、多くの人が集まる場所に設置すれば、簡単に天気予報を確認できるようになります。便利でわかりやすい仕組みを作ることで、みんなが気軽に情報をチェックできる環境を目指し、このプロジェクトに取り組みました。




### デジタルサイネージとは？

デジタルサイネージは、駅や店舗、施設、オフィスなどにディスプレイやプロジェクターなどの映像表示装置を設置して情報を発信するシステムです。最近では、東京駅や大阪駅など日本の主要な駅でもよく見かけるようになりました。看板や標識のデジタル版と考えてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561875/cab59de8-6954-9ca9-3c39-19f0944e291f.png)
（引用元: [駅デジタルサイネージ - 交通広告・屋外広告の情報サイト　交通広告ナビ](https://www.koutsu-navi.com/station/digital/)）

### Raspberry Piとは？
Raspberry Pi（ラズベリーパイ）は、英国のRaspberry Pi財団が開発した手のひらサイズの小型コンピュータです。ディスプレイやキーボード、マウスを接続することで、一般的なパソコンのように使うことができます。いわば、小さなPCとして利用できるのが特徴です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561875/e86c3073-ea8c-acdb-4b63-c8c0ec7e329d.png)
（引用元: [意外に知らない「ラズパイ」の正体、生まれたきっかけと今までの歴史 | 日経クロステック（xTECH）](https://xtech.nikkei.com/atcl/nxt/column/18/02839/052100001/)）

## ソースコード
今回使用したソースコードは下記のレポジトリにあります。ぜひ参考にしてみてください。

https://github.com/Nakkinakki55/real-time-weather/blob/main/README.md


## 完成図
今回は、Raspberry Piを使ってデジタルサイネージを低コストで実現します。普通のデスクトップPCを使うと数万円かかりますが、Raspberry Piを使えば誰でも、しかも格安で手軽に始められます。なお、今回の完成イメージは以下のとおりです。本来は駅にあるような大型のモニターを用意するのは難しかったので、普通のモニターで代用しました笑。ご了承ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561875/072735a0-85a0-845c-d977-e5d7e5ff2318.png)



## 必要なもの
- モニター
- WindowsPC
- Raspberry Pi 一式

## ソースコード

では、今回使用するコードを紹介します。ファイルの拡張子は`html`です。特別な開発環境を構築する必要はありません。まずはWindowsPC上に下記のコードを書きます。このファイルを保存する際は **UTF-8** を使用してください。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>天気予報</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="bg-dark text-white d-flex justify-content-center align-items-start vh-100">
    <div class="mt-5 text-center">
        <p id="time" class="display-6"></p>
        <p id="weather" class="display-1 fw-bold mt-3"></p>
    </div>

    <script>
        function fetchWeatherForecast() {
            const url = "https://www.jma.go.jp/bosai/forecast/data/forecast/130000.json";
            let todayForecast;

            const xhr = new XMLHttpRequest();
            xhr.open("GET", url, false);  // 同期実行
            try {
                xhr.send();
                if (xhr.status === 200) {
                    const data = JSON.parse(xhr.responseText);
                    // 東京都の今日の天気
                    todayForecast = data[0].timeSeries[0].areas[0].weathers[0];
                } else {
                    throw new Error("ステータスコード: " + xhr.status);
                }
            } catch (error) {
                todayForecast = "エラーが発生しました: " + error.message;
            }

            return todayForecast;
        }

        function getCurrentTime() {
            const now = new Date();
            const hours = now.getHours().toString().padStart(2, '0');
            const minutes = now.getMinutes().toString().padStart(2, '0');
            return `${hours}:${minutes}`;
        }

        function reloadPage() {
            location.reload();
        }

        document.addEventListener('DOMContentLoaded', (event) => {
            const weather = fetchWeatherForecast();
            const currentTime = getCurrentTime();
            document.getElementById('time').innerText = `今日の天気予報（${currentTime}現在）`;
            document.getElementById('weather').innerText = weather;
            setTimeout(reloadPage, 180000); // 3分ごとにページをリロード
        });
    </script>
</body>
</html>
```

このHTMLコードは、気象庁のAPIから天気予報を取得し、画面で簡単に表示するシンプルなWebページを作成するものです。Bootstrapを使用して黒い背景に白文字で天気予報を見やすく中央に表示します。主な動作は下記のとおりです。

- **天気予報の取得**  
気象庁のAPIから天気データを取得し、JSON形式で処理します。XMLHttpRequestを使って同期モードで天気情報を取得し、表示用に抽出します。エラー時にはメッセージを表示します。

- **現在時刻の表示**  
  現在の時刻を取得し、HH:MM形式で表示します

- **ページ初期化と表示**  
  ページが読み込まれると、天気予報と時刻が自動で表示されます

- **3分ごとの更新**  
  3分ごとにページを自動リロードし、最新情報を表示します

### 使用するAPIについて  

[https://www.jma.go.jp/bosai/forecast/data/forecast/130000.json](https://www.jma.go.jp/bosai/forecast/data/forecast/130000.json) は、東京都の天気予報データを取得できる公式のAPIです。  

このURLにアクセスすると、東京都の天気予報がJSON形式で提供されます。データはプログラムで扱いやすいように構造化されており、特定の情報を簡単に取得できます。  

なお、URL内の **「130000」** は東京都の都道府県コードを指しており、他の地域の天気予報を取得するには、異なる都道府県コードを使用します。  都道府県コードの詳細については、こちらの[ドキュメント](https://anko.education/webapi/jma)を参考にしてください。


### 注意点

通常、こういったシステムを作る場合は、フロントエンドのコードに加えてサーバーサイドのコードも必要になります。しかし、今回はフロントエンドのコードだけで十分です。その理由を以下にまとめました。

- **ファイルの読み込みが速い**  
  フロントエンドのみで完結するため、動作が軽くスムーズです

- **トークンやアクセスキーの心配がない**  
  一般的にAPIを利用する場合、トークンやアクセスキーなどを安全に管理する必要があります。しかし、今回のコードではそういった情報を扱わないため、サーバーサイドに配置する必要がありません

- **開発環境の準備が不要**  
  サーバーサイドで使うプログラム言語の環境構築は手間がかかりますが、今回はその必要がありません

- **HTMLファイルを開くだけでOK**  
  すべてがHTMLファイル内で完結するので、誰でも簡単に動作を確認できます

- **とにかく簡単に実現できる**  
  必要なことを簡単に達成できる点も大きな魅力です

このように、フロントエンドのコードのみで手軽に天気予報を表示できる方法を選びました。


## 手順

### Windows PCでの確認
1. HTMLファイルをWindows PCで開き、表示が確認できることを確認

### Raspberry Piの設定
1. Raspberry Piにモニター、マウスやキーボードを繋げる  
2. Raspberry Piの初期設定を完了  
3. Raspberry PiのSSHを有効化  
4. Windows PCにFileZillaをインストール  
5. FileZillaを使用してHTMLファイルを転送  

詳しくは下記リンクのものを参考にしてください。
[【2024年最新版】OSインストールから初期設定まで｜ラズベリーパイ セットアップ手順のすべて | sozorablog](https://sozorablog.com/raspberrypi_initial_setting/)
[ラズベリーパイをリモート操作（SSHコマンド）](https://raspi-school.com/ssh/)
[FTPクライアントソフトを使ってRaspberry Piとパソコン間でファイルをやり取りする方法](https://darmus.net/raspberry-pi-filezilla/)



## 表示の確認
必要な設定が完了したら、以下のコマンドをRaspberry Pi上で実行してHTMLファイルを表示してください。

```bash
chromium-browser --kiosk /home/username/Desktop/weather_forecast_display.html
```
このコマンドは、Raspberry Piの環境で、Chromiumブラウザを「キオスクモード」で特定のHTMLファイルを全画面表示するためのものです。

- **`chromium-browser`**: Chromiumブラウザを起動します
- **`--kiosk`**: 全画面表示（キオスクモード）で起動し、通常のブラウザ機能を非表示にします。デジタルサイネージ用途に適しています
- **`/home/username/Desktop/weather_forecast_display.html`**: 指定されたパスのHTMLファイルを表示します

実行すると、指定したHTMLページが全画面表示され、ユーザーが閉じるまで下記のように全画面モードが維持されます。なお、キオスクモードを解除する際は「**Alt + F4**」キーを押下してください。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561875/9ab661e5-ce5d-c70b-a48a-8320ffcea782.png)


## まとめ
今回のプロジェクトでは、手軽で低コストなRaspberry Piを使い、天気予報を大画面で表示するシステムを作りました。このシステムがあれば、オフィスや食堂など、さまざまな場所で多くの人がリアルタイムの天気予報を簡単に確認できます。大規模な設備が必要ないため、導入コストを抑えつつ、日常的に役立つシステムとして利用できるのが大きな魅力です。ぜひ、この方法を参考にして、気軽に試してみてください。

## 参考文献
[駅デジタルサイネージ - 交通広告・屋外広告の情報サイト　交通広告ナビ](https://www.koutsu-navi.com/station/digital/)
[意外に知らない「ラズパイ」の正体、生まれたきっかけと今までの歴史 | 日経クロステック（xTECH）](https://xtech.nikkei.com/atcl/nxt/column/18/02839/052100001/)
[【Raspberry Pi】コマンドでChromiumをフルスクリーンで起動させる - ソースに絡まるエスカルゴ](https://rikoubou.hatenablog.com/entry/2021/05/25/171645)