目次
- 2.1 Raspberry Piをネットワーク接続する
- 2.2 ライブラリのアップデート
- 2.3 Pythonの準備
- 2.4 Raspberry PiをWebサーバにしてみる
- 2.5 簡単なWebページを作る
- 2.6 テンプレートエンジンを使う
- 2.7 テンプレートエンジン応用
- 2.8 実習
2.1 Raspberry Piをネットワーク接続する
先週はRaspberry PiにUSB経由でログインしました。今日は、Raspberry Piを学内無線LANに接続します。
Raspberry Piを大学の学内無線LANに接続するための方法は、Google Classroomに資料をアップロードしてありますので、それを参照してください。
2.2 ライブラリのアップデート
2.2以降は必ず「2.1 Raspberry Piをネットワーク接続する」を終えてから進めてください。
まず始めにRaspberry Pi OSにインストールされているソフトウェアやライブラリの行います。
1 2 |
$ sudo apt update $ sudo apt upgrade |
apt
はパッケージ管理ツールです。apt update
でパッケージ一覧の更新、apt upgrade
で更新可能なパッケージを更新します。
以下のように聞かれたらエンターキーを押します。
1 |
Do you want to continue? [Y/n] |
sudo apt upgrade
には少し時間がかかります。
ここで、今後のためにgitをインストールしておきます。
1 |
$ sudo apt install git |
ここでも以下のように聞かれたらエンターキーを押します。
1 |
Do you want to continue? [Y/n] |
2.3 Pythonの準備
Raspberry Piにはpython3がインストールされています。念のために以下のようにして確認します。3.7.3
などと出力されればOKです。
1 |
$ python3 --version |
pythonのモジュールを管理するためのpipというツールをインストールします。コマンド名はpip3
になります。
1 2 |
$ sudo apt install python3-dev $ sudo apt install python3-pip |
pip3がインストールされたことを確認します。
1 |
$ pip3 --version |
現在pip3が管理しているpythonのモジュールを一覧表示してみましょう。
1 |
$ pip3 list |
すでにいくつかのモジュールがインストールされていることが分かります。
これでPythonの準備は完了です。
2.4 Raspberry PiをWebサーバにしてみる
Raspberry Pi OSはLinuxですから、ApacheやNginxなどのWebサーバを走らせることができます。しかし、これらのWebサーバは大掛かりで設定などが面倒臭いので、ここではPythonのFlaskというモジュールを使って簡易Webサーバを作ってみます。
FlaskはPythonのWebフレームワークです。Webサーバサイドの構築に使うフレームワークになります。オブジェクト指向技術で学習したVue.jsは、Webフロントエンドの構築に使うJavaScriptフレームワークでしたね。同じフレームワークという言葉を使っていますが、片方はサーバサイド、もう片方はフロントエンドということになります。混乱しないようにしてください。
FlaskはPythonの標準モジュールではないので、pip3を使ってインストールする必要があります。Raspberry Piにログインして、以下のように入力します。
1 |
$ sudo pip3 install Flask |
これで、Flaskというモジュールが使えるようになります。手始めにごく簡単なサンプルを動かしてみましょう。以下のコードをFlask
というディレクトリの下にhello_flask.py
というファイル名で保存します。
1 2 3 4 5 6 7 8 9 10 |
from flask import Flask app = Flask(__name__) @app.route('/') def root_page(): return 'Hello, Flask!' if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=8888, threaded=True) |
実行する前に、このRaspberry PiのIPアドレスを調べておきます。
1 |
$ ifconfig |
正しくWi-Fiに接続できていれば、2つのIPアドレスがあるのでしたよね。ここでは仮に外部と繋がっている方のIPアドレスを10.50.230.17
とし、USBで接続されている方のIPアドレスを169.254.30.242
であると仮定します。自宅で無線LANに接続している場合には10.50.X.X
ではなく192.168.X.X
になるはずです。
それでは、実行しましょう。Flask
ディレクトリに移動して、以下のように入力します。
1 |
$ python3 hello_flask.py |
正しく実行されていれば、以下のような出力が得られるはずです。
1 2 3 4 5 6 7 8 9 |
Serving Flask app "hello_flask" (lazy loading) Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. Debug mode: on Running on http://0.0.0.0:8888/ (Press CTRL+C to quit) Restarting with stat Debugger is active! Debugger PIN: 287-318-044 |
MacBookのWebブラウザで以下のアドレスにアクセスします。10.50.230.17
のところは各自で違います。
1 |
http://10.50.230.17:8888/ |
あるいは、以下のアドレスでもアクセスできます。これも169.254.30.242
のところは各自で違います。
1 |
http://169.254.30.242:8888/ |
両方アクセスできることを確認してください。
2.5 簡単なWebページを作る
Flaskを使って、簡単なWebページが表示できるようにしましょう。ここではFlaskそのものについては説明しません。Flaskについて興味がある人は以下の公式Webページを参照してください。
https://flask.palletsprojects.com/
以下のコードを元にします。これをFlaskデイレクトりの下にsimple_web_server.py
という名前で保存します。
1 2 3 4 5 6 7 8 9 10 |
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def root_page(): return render_template('index.html') if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=8888, threaded=True) |
Flask
ディレクトリの下にtemplates
とstatic
という2つのディレクトリを作成します。static
の下にはcss
というディレクトリを作成します。
templates
ディレクトリの下に、以下の内容でindex.html
を作成します。
1 2 3 4 5 6 7 8 9 10 11 12 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <link rel="stylesheet" href="/static/css/main.css" /> <title>Raspberry Pi Server</title> </head> <body> <p>Raspberry Piで動いています。</p> <p>現在のcpu温度は<span id="temp">23.5°C</span>です。</p> </body> </html> |
static/css
の下に、以下の内容でmain.css
を作成します。
1 2 3 |
#temp { color: blue } |
Flask
ディレクトリでsimple_web_server.py
を動かします。
1 |
$ python3 simple_web_server.py |
MacBookのWebブラウザでアクセスしてみましょう。以下のようになるはずです。

ここでは、FlaskのテンプレートエンジンであるJinja2を使っています。とはいえ、このサンプルではテンプレートエンジンらしいことは何もしておらず、ただindex.html
を表示するだけです。
htmlやcssはコードを読んでもらえば何をしているかは分かるはずです。
2.6 テンプレートエンジンを使う
今度はテンプレートエンジンにもう少し仕事をさせてみましょう。index.html
の以下の1行を書き換えます。
1 |
<p>現在のCPU温度は<span id="temp">{{ temperature }}</span>です。 |
Vue.jsのマスタッシュ構文のように見えますが、これはJinja2の構文になります。Jinja2とVue.jsを組み合わせるときには、Vue.jsのマスタッシュ構文を設定で変更する必要があります。
simple_web_server.py
の方も、以下の1行を書き換えます。
1 |
return render_template('index.html', temperature='24.5°C') |
render_template()
では、レンダリングに必要となるテンプレートファイル(htmlファイル)と、そこに引き渡す変数の値をカンマで並べて書きます。この例ではtemperature='24.5°C'
がテンプレートファイルであるindex.htmlに引き渡されます。この引き渡された値がindex.html
の{{ temperature }}
に代入されます。
実行してみると、Webページがきちんとレンダリングされていることが確認できるはずです。
さて、ここまでくると、実際のCPU温度を測ってWebページに表示したくなりますね。simple_web_server.py
を以下のように変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from flask import Flask, render_template import subprocess app = Flask(__name__) @app.route('/') def root_page(): proc = subprocess.run(['vcgencmd', 'measure_temp'], capture_output=True, text=True) temp = proc.stdout[5:9] return render_template('index.html', temperature=temp) if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=8888, threaded=True) |
以下の行は、Raspberry Pi OSに備わっているvcgencmd
というコマンドを実行して結果を持ってきています。
1 |
proc = subprocess.run(['vcgencmd', 'measure_temp'], capture_output=True, text=True) |
vcgencmd
はコマンドですから、以下のように実行できます。
1 |
$ vcgencmd measure_temp |
結果は以下のようになります。
1 |
temp=32.6'C |
この文字列から32.6
を切り出しているの次の行です。
1 |
temp = proc.stdout[5:9] |
proc
にはコマンドを実行した結果の色々な情報が入っています。proc.stdout
で標準出力に出力された文字列を取り出せます。この文字列から[5:9]
と位置を指定して部分文字列を切り出しています。
Webページにアクセスすると、アクセスした時点のCPU温度が表示されます。Webページをリロードすると、その度にCPU温度が変わることが観察できると思います。40°Cを超えている場合には、Raspberry Pi Zeroの表面に実装されている1cm四方くらいの黒いマイコンに指を当てると、少しCPU温度が下がります。
2.7 テンプレートエンジン応用
テンプレートにデータを渡すときには以下のようにしました。
1 |
return render_template('index.html', temperature=temp) |
この例では、1つの値をテンプレートに渡していますが、リストを渡すこともできます。
1 2 |
data = [1, 2, 3] return render_template('index.html', temperatures=data) |
テンプレートの方では、以下のように使います。
1 |
{{ temperatures[0] }} |
データの個数分だけ繰り返してhtml要素を作りたいときには以下のようにします。
1 2 3 |
{% for temp in temperatures} <p>temperatures[temp]</p> {% endfor %} |
2.8 実習
実験1
「2.4 Raspberry PiをWebサーバにしてみる」で、10.50.X.X
と169.254.X.X
の両方のアドレスが使えることを確認しました。両方きちんとアクセスできることを実験レポートとしてまとめてください。
実験2
2.6で作成したsimple_web_server.py
を改造して、過去5回のCPU温度計測結果を表示するようにしてみましょう。CPU温度を測るタイミングは、Webページにアクセスされた時とします。ただし、ここでは複数の人がこのWebページにアクセスしてくることは考慮しません。複数の人がアクセスしてくるような環境で、これをどう作るのかは色々なことが絡んで少し難しい話になります。
プログラムはCpuTemp
というフォルダを新たに作成して、その下に作ります。
まず、動作のイメージを説明します。サーバを起動して、最初にWebページにアクセスすると、以下のようになります。

リロードすると、表示が増えます。

4回以上リロードしても、最新の5件までしか表示されないようにします。ここがポイントで、すでにリストに5件データが入っていたら、古いデータを1件削除しなければいけません。リストのメソッドをうまく使って実装します。

Webページの見た目は自由に変更してもらって構いません。好きなようにcssを設定してください。
simple_web_server.py
では、Webページにアクセスされた時刻とCPU温度をテンプレートに渡します。pythonで現在時刻を取得するにはdatetime
というモジュールを使います。これは標準モジュールです。
https://docs.python.org/ja/3/library/datetime.html
1 2 3 4 |
import datetime now = datetime.datetime.now() print(str(now)) |
print()
の中でstr()
という関数を使っていますが、これはなくてもちゃんと出力してくれます。ただ、now
はdatetime.datetime
型なので、文字列として扱いときにはこのようにstr()
関数を使ってキャストする必要があります。
テンプレートにどのような値を渡すかは、色々な考え方があります。Pythonのタプルというデータ構造とリストを組み合わせたものを渡すこともできます。
1 |
[('時刻1', 'CPU温度1'), ('時刻2', 'CPU温度2'), ('時刻3', 'CPU温度3'), ...] |
タプルに関しては、以下を参照してください。
https://docs.python.org/ja/3/tutorial/datastructures.html#tuples-and-sequences
時刻とCPU温度それぞれにリストを使って、2つのリストをテンプレートに渡すということでも良いでしょう。
— by 石井 健太郎、沼 晃介、飯田 周作 専修大学ネットワーク情報学部