【RaspberryPi】CPUの温度を監視し、リアルタイムで可視化する

最近、ラズベリーパイの発熱が気になってきました。

そこで、CPUの温度を監視し、リアルタイムで可視化するシステムを作ってみました。

ソースはココにあります。デモページはココ

環境・前提

端末OS
Raspberry Pi 4BUbuntu Server 20.04 LTS (64bit)
前提
  1. ラズパイにWebサーバを構築済み

構成

全体の構成としては以下のようになります。

機能一覧

ソースコードだけでは分かりづらいと思ったので、機能を列挙します。

  1. ログは日付け毎に出力される (日付が変わったら自動で新しいログファイルが作られる)
  2. ブラウザ画面で日付を選択し、日付け毎のグラフが見れる
  3. CPUの温度が指定した値以上になると、ラズパイをシャットダウンさせる

CPUの温度を監視

まずはシェルスクリプトでCPUの温度を監視し、ログを出力させます。

また、ログの出力先は次章に記載の「log」直下にしてください。

#!/bin/bash

# 入力個所
logdir="ログの保存ディレクトリを指定(末尾にスラッシュ不要)"
maxtemp="CPU温度の上限値を指定(例:60度なら60000)"

# 日時とCPU温度
date=$(date "+%Y-%m-%d %H:%M:%S")
today=$(date "+%Y-%m-%d")
logfile="${logdir}/${today}.log"
temp=$(cat /sys/class/thermal/thermal_zone0/temp)

# ログ生成
if [ ! -e $logfile ]; then
    touch $logfile
fi

# ログ出力
echo "$date,$temp" >> $logfile

# 温度上昇時の処理
if [ $temp \> $maxtemp ]; then
    #設定を間違えると、
    #ラズパイが起動しても
    #すぐ直後にシャットダウンされる事態になるので、
    #慎重に設定してください
    #eval "sudo shutdown -t 120"
    echo "hoge"
fi

exit 0

実行権限を与えます。

$ chmod 755 cpu_monitoring.sh

次に、今作ったスクリプトをcronに登録します。

$ crontab -e

# 最終行に以下を追加し保存(毎分実行させる)
* * * * * /home/ubuntu/cpu_monitoring.sh

# 登録されているか確認
$ crontab -l

これでCPUの温度を監視し、ログを出力させることが出来ました。

CPUの温度を可視化する

次に、Chart.jsを使ってCPUの温度を可視化していきます。

(Chart.jsとは、グラフを描画するためのJavaScriptオープンソースライブラリです)

また、ディレクトリ構造は以下のようにしました。

./
├ index.html
├ bash/
│└ cpu_monitoring.sh
├ js/
└ mychart.js
└ log/
 └ yyyy-mm-dd.log

まずはindex.htmlを作成します。

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"></script>
    <script type="text/javascript" src="js/mychart.js"></script>
    <title>cpu-temp-chart</title>
</head>

<body>
    <form id="form1" action="#">
        <input type="date" id="datetxt" value="2021-08-29">
        <input type="button" onclick="main()" value="実行">
    </form>
    <!--グラフ挿入-->
    <div style="width: 100%; height: 100%;">
        <canvas id="myChart" style="width: 100%; height: auto;"></canvas>
    </div>
</body>

</html>

次に、mychart.jsを作成します。

// csvを配列に変換
function csvToArray(csv) {
    var array = [];
    var lines = csv.split("\n");
    for (var i = 0; i < lines.length; ++i) {
        var cells = lines[i].split(",");
        array.push(cells);
    }
    return array;
}

// 配列からチャートを生成
function arrayToChart(array) {
    var data1 = [], data2 = [];
    for (var row in array) {
        data1.push(array[row][0])
        data2.push(array[row][1])
    }
    var ctx = document.getElementById("myChart").getContext("2d");
    var myChart = new Chart(ctx, {
        type: "line",
        data: {
            labels: data1,
            datasets: [{
                label: "cpu temp [m℃]",
                fill: false,
                borderColor: 'rgba(0, 0, 255, 0.5)',
                data: data2
            }],
        },
        options: {
            scales: {
                xAxes: [{
                    ticks: {
                        minRotation: 0,
                        maxRotation: 0,
                        maxTicksLimit: 10
                    },
                }]
            }
        }
    });
}

// 主処理
function main() {
    let datea = document.getElementById('datetxt');
    let date = datea.value;
    var req = new XMLHttpRequest();
    var filePath = '../log/' + date + '.log';
    req.open("GET", filePath, true);
    req.onload = function () {
        data = csvToArray(req.responseText);
        arrayToChart(data);
    }
    req.send(null);
}

以上でログファイルを可視化することができるようになりました。

外出先からでも確認できるので、安心です(温度上昇時にメール送信をする、という処理を入れてみるのも良いかもしれません)。

デモページを作ったので参考までにどうぞ。

最後に

今回の内容は、正直なところZabbixで実装した方が早いです。

ただ、インフラ〜フロントまでを自分自身で実装できたので、今後の開発の幅が広がったように思えます。

また、新たな機能を追加していく予定ですので、随時更新していきます。

参考資料