🍓

ラズパイで超簡易HTMLサーバーにする【Raspberry pi】

に公開

Raspberry pi 3A でサーバーを建ててCPU温度をモニターする

家に眠っていたラズパイ3をサーバーにします。HTMLファイルでcpu温度を表示します。

はじめに

私は電子工作を始めるために買った本でRaspberry pi を使っていたので購入しました。今はpico wを主に使っているのでpiを使うことは無くなりました。CLI版osであれば動作が軽くサーバーにできると聞いたので実際に試してみました。何も表示するものがないのでCPU温度を表示してみます。

1. 事前準備

最初は最新のOSを試しましたが、上手くいきませんでした。Raspberry Pi 3のスペックと動作の安定性を重視して**Raspberry Pi OS Lite (Legacy 32-bit)**を選択しました。Raspberry Pi Imagerで、以下の項目を事前に入力しておくのがコツです。Raspberry Pi Imagerの最新版はとても使いやすかったです。

  • SSHを有効化
  • Wi-Fi設定(SSID/パスワード)
  • Wi-Fiを使う国を「JP」にする(これを忘れるとWi-Fiが有効にならない場合があります)

2. SSH接続とディレクトリ構成

PCからSSHでログイン後、ファイルを整理するために以下の構成を作成しました。

/home/ユーザー名/code/
├── temp_test.py        # CPU温度取得プログラム(Python)
└── public/             # Web公開用ディレクトリ
    ├── index.html      # フロントエンド
    └── temp.json       # データ中継用ファイル

またこのタイミングでMicrosoftから出ているVScodeのssh拡張機能をインストールしました。VScodeで編集できると何かと便利なのでおすすめです。

3. バックエンド:Pythonで温度取得

CPU温度を1秒おきに取得し、JSON形式で保存し続けるプログラムを作成しました。cpu温度は"/sys/class/thermal/thermal_zone0/temp"に保存されています。このファイルを開いて中身を読み取り数値に変換します。

小数第一位までで丸め、取得時間と併せてjsonにします。

temp_test.py
import time
import json
import os

TEMP_FILE_PATH = "/sys/class/thermal/thermal_zone0/temp"
OUTPUT_JSON_PATH = "/home/yama/code/public/temp.json"

def get_cpu_temp():
    with open(TEMP_FILE_PATH, "r") as f:
        temp_raw = int(f.read())
    return temp_raw / 1000

print("温度計測を開始します... (Ctrl+C で終了)")

try:
    while True:
        temp = get_cpu_temp()
        # 保存するデータを辞書形式で作る
        data = {
            "temperature": round(temp, 1),
            "last_update": time.strftime("%H:%M:%S")
        }

        # ファイルに書き出す
        with open(OUTPUT_JSON_PATH, "w") as f:
            # json.dumpを使うと、辞書をJSON形式に変換して書き込んでくれます
            json.dump(data, f)

        print(f"\r保存中: {data['temperature']} ℃ ({data['last_update']})", end="")
        
        time.sleep(1)

except KeyboardInterrupt:
    # Ctrl+C が押された時の処理
    print("\n計測を終了しました。")

4. フロントエンド:JavaScriptでリアルタイム更新

python3 -m http.server でWeb公開し、JavaScriptの fetch と setInterval を使って、ページをリロードせずに温度を更新させます。

temp.js
const temp_value = document.getElementById('temp-value');
const temp_time  = document.getElementById('time-value');

function updateTemp() {
    // temp.jsonを取得しに行く(Fetch API)
    fetch('./temp.json')
        .then(response => response.json()) // JSONとして解析
        .then(data => {
            // HTMLの書き換え
            temp_value.textContent = data.temperature;
            temp_time.textContent = data.last_update;
        })
        .catch(error => console.error('Error:', error));
}

// 1000ミリ秒(1秒)ごとにupdateTempを実行する
setInterval(updateTemp, 1000);

// 最初の一回を実行
updateTemp();

HTMLは以下のように書きました。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Welcome to Ras Server</title>
</head>
<body>
    <h1>Welcome to Ras Server</h1>
    <div class="temp-display">
        <span id="temp-value">--.-</span> ℃
    </div>
    
    <p class="info">最終更新: <span id="time-value">--:--:--</span></p>
    <script src="temp.js"></script>
</body>
</html>

5. 実行と結果

  1. python3 temp_test.py を実行してデータの書き出しを開始。
  2. cd public && python3 -m http.server 8000 でサーバー起動。
  3. ブラウザで http://raspberrypi.local:8000/ にアクセス。

実行の様子
指でcpuのところを触ると39℃付近まで下がりました。また、動画には映っていませんがsshログインしていない状態だと38℃付近で安定していますがshhログインを試行すると一時的に48℃まで上がりその後40.8℃付近で安定しました。

https://youtu.be/b8BCVa04krs

ブラウザ上の温度が1秒ごとにパタパタと更新されたときは、感動しました!

まとめ

Raspberry Pi 3のようなリソースが限られたデバイスでも、Lite版OSとシンプルなPython/JavaScriptの組み合わせで、十分に実用的な「自分専用サーバー」が作れることがわかりました。

今後はpython3 temp_test.pyではなくNGINXなどを入れたり、open weather APIのような他サービスを使って自分好みのダッシュボードを作っていこうと思います。

発展

Geminiに聞きながら実機が起動したタイミングで自動でサーバーとtemp.pyが実行されるようにしました。お褒めの言葉を賜りました。

Discussion

Hidden comment