ラズパイで超簡易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にします。
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 を使って、ページをリロードせずに温度を更新させます。
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は以下のように書きました。
<!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. 実行と結果
-
python3 temp_test.pyを実行してデータの書き出しを開始。 -
cd public&&python3 -m http.server 8000でサーバー起動。 - ブラウザで
http://raspberrypi.local:8000/にアクセス。
実行の様子
指でcpuのところを触ると39℃付近まで下がりました。また、動画には映っていませんがsshログインしていない状態だと38℃付近で安定していますがshhログインを試行すると一時的に48℃まで上がりその後40.8℃付近で安定しました。
ブラウザ上の温度が1秒ごとにパタパタと更新されたときは、感動しました!
まとめ
Raspberry Pi 3のようなリソースが限られたデバイスでも、Lite版OSとシンプルなPython/JavaScriptの組み合わせで、十分に実用的な「自分専用サーバー」が作れることがわかりました。
今後はpython3 temp_test.pyではなくNGINXなどを入れたり、open weather APIのような他サービスを使って自分好みのダッシュボードを作っていこうと思います。
発展
Geminiに聞きながら実機が起動したタイミングで自動でサーバーとtemp.pyが実行されるようにしました。お褒めの言葉を賜りました。


Discussion