目次
- 2.1 Raspberry Pi をWi-Fiネットワークに接続する
- 2.2 ライブラリのアップデート
- 2.3 Pythonの準備
- 2.4 Raspberry PiをWebサーバにしてみる
- 2.5 簡単なWebページを作る
- 2.6 テンプレートエンジンを使う
- 2.7 テンプレートエンジン応用
- 2.8 実習
2.1 Raspberry Pi をWi-Fiネットワークに接続する
先週の宿題では Raspberry Pi にUSB経由でログインしました。今日は、 Raspberry Pi を無線LANに接続します。
Raspberry Pi を無線LANに接続するための方法は、 Google Classroom に資料をアップロードしてありますので、それを参照してください。
2.2 ライブラリのアップデート
2.2以降は必ず「2.1 Raspberry Pi をWi-Fiネットワークに接続する」を終えてから進めてください。
まず始めに Raspberry Pi OS にインストールされているソフトウェアやライブラリのアップデートを行います。
1 2 |
$ sudo apt update $ sudo apt upgrade |
apt
はソフトウェアパッケージ管理ツールです。ソフトウェアのインストール・更新・削除等には、apt
を使用すると覚えておくと役に立ちます。apt update
でパッケージ一覧の更新、apt upgrade
で更新可能なパッケージを更新します。
以下のように聞かれたらエンターキーを押します。(何も入力しないでエンターキーを押すと、大文字で示されているデフォルト回答(以下の例では「Y」)が入力されたことになります。)
1 |
Do you want to continue? [Y/n] |
sudo apt upgrade
には少し時間がかかります。
ここで、今後のためにgitをインストールしておきます。
1 |
$ sudo apt install git |
ここでも以下のように聞かれたらエンターキーを押します。(何も入力しないでエンターキーを押すと、大文字で示されているデフォルト回答(以下の例では「Y」)が入力されたことになります。)
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 |
$ sudo apt install python3-pip |
pip3がインストールされたことを確認します。command not found
とならなければOKです。
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/ |
両方アクセスできることを確認してください。
プログラムを終了するときは、Ctrlキーを押しながらCキーを押します。このことを、今後Ctrl-Cと書きます(コントロールシーと呼びます)。
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
を動かします。(終了するときはCtrl-Cです。)
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 }}
に代入されます。
書き換えたsimple_web_server.py
を実行してみると、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:11] 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'C
を切り出しているの次の行です。
1 |
temp = proc.stdout[5:11] |
proc
にはコマンドを実行した結果の色々な情報が入っています。proc.stdout
で標準出力に出力された文字列を取り出せます。この文字列から[5:11]
と位置を指定して部分文字列を切り出しています。
Webページにアクセスすると、アクセスした時点のCPU温度が表示されます。Webページをリロードすると、その度にCPU温度が変わることが観察できると思います。40°Cを超えている場合には、 Raspberry Pi の表面に実装されている1.5cm四方くらいの銀色のICチップ(BROADCOMと書いてある)に指を当てると、少しCPU温度が下がります。(ここに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] }} |
リストの要素の数だけ繰り返して処理したいときは、テンプレートエンジンのfor文を使用します。例えば、リストの要素の数だけhtml要素(pタグ)を作りたいときには以下のようにします。temp
にリストの先頭の要素から順に代入されて処理が繰り返されます。
1 2 3 |
{% for temp in temperatures %} <p>{{ temp }}</p> {% endfor %} |
2.8 実習
実験1
「2.4 Raspberry Pi をWebサーバにしてみる」で、10.50.X.X
と169.254.X.X
の両方のアドレスが使えることを確認しました。また、「2.6 テンプレートエンジンを使う」で、 Raspberry Pi で測定したデータをWebページに反映できることを確認しました。この2つを両方とも達成したことを、実験レポートとしてまとめてください。つまり,10.50.X.X
と169.254.X.X
の両方のアドレスから、実際のCPU温度が記載されているWebページを表示できたことを示してください。
実験2
2.6で作成したsimple_web_server.py
とindex.html
を改造して、CPU温度を測ったときの時刻も一緒に表示してみましょう。今後は特段の指示をしませんが、今回のように過去のプログラムを改造して新しいプログラムを作るときには、いったん別の名前で過去のプログラムのコピーを保存し、コピーのファイルを編集していくようにしてください。古いファイルを見返したくなることもけっこうあるはずだからです。また、自分だけにでよいので、見てわかりやすい名前をつけましょう。テーマごとにフォルダを分けるというようなことも有効です。

このプログラムの実現のためには、CPU温度に加えて、現在時刻をテンプレートに渡します。pythonで現在時刻を取得するにはdatetime
というモジュールを使います。これは標準モジュールです。
https://docs.python.org/ja/3/library/datetime.html
試しに、以下のPythonプログラムを作成して実行してみると、now
に現在時刻が格納され、print()
でその現在時刻が表示されます。(datetime.datetime.now()
で現在時刻が取得できます。.replace(microsecond=0)
は秒未満の細かい時刻を切り捨てるおまじないです。)このことを参考に、プログラムを作成してください。
1 2 3 4 |
import datetime now = datetime.datetime.now().replace(microsecond=0) print(str(now)) |
print()
の中でstr()
という関数を使っていますが、print()
の場合はなくてもちゃんと出力してくれます。ただ、now
はdatetime.datetime
型なので、文字列として扱いたいときにはこのようにstr()
関数を使って型を変換する必要があります。
実験3
「2.7 テンプレートエンジン応用」で取り組んだリストを利用して、実験2で作成したプログラムとWebページをさらに改造して、過去5回のCPU温度計測結果を表示するようにしてみましょう。ただし、ここでは複数の人がこのWebページにアクセスしてくることは考慮しません。複数の人がアクセスしてくるような環境で、これをどう作るのかは色々なことが絡んで少し難しい話になります。
まず、動作のイメージを説明します。サーバを起動して、最初にWebページにアクセスすると、以下のようになります。

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

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

Webページの見た目は自由に変更してもらって構いません。好きなようにcssを設定してください。
テンプレートにどのような値を渡すかは、色々な考え方があります。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 飯田 周作、沼 晃介、石井 健太郎 専修大学ネットワーク情報学部