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

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

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

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

Contents

環境・前提

端末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で実装した方が早いです。

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

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

参考資料