このサイトはMacを使って Raspberry Pi 3 の動作や活用法を学びます。

PythonでWebアプリを作る

ラズパイには、Pythonがあらかじめインストールされています。そのPythonに組み込まれているWebサーバー機能を利用して、Pythonだけで、動的Webアプリを作ります。

動的Webアプリの概要

ラズパイには標準で、CGIHTTPServerという、ユーザからの入力により、ダイナミックに出力処理を変更するCGIに対応したWebサーバーが組み込まれています。この機能を利用して、iMacやiPhoneなどのクライアントのブラウザーに表示されたホームページのHTML画面のボタンを操作すると、ラズパイに接続されたLEDの点灯を制御できるアプリを作成します。
クライアント機はWiFiでラズパイWebサーバーの index.html を読み込み表示します。ブラウザーでの操作情報はWebサーバーを経由し、Pythonで処理されます。Pythonの処理プログラム(querytest.py)では、LEDを点灯し、処理結果はHTMLデータにして、クライアントに返信されます。

CGI HTTP Server

NOTE: LEDは、GPIO 11,GPIO 9,GPIO 10 pinに、12v用抵抗入りLEDを接続しました。

使用するファイルの保存

まず、外部からの入り口となるディレクトリー PythonWeb をユーザールートディレクトリーに作成し、PythonWeb 内に、短いファイル3つを保存します。このファイルは、Webサーバーを起動させる Pythonプログラム cgiserber.py と ホームページのトップページとなる index.html と style.css です。
さらに、動的アプリを実現するPythonプロブラムを保存するための ディレクトリ cgi-bin を作成し、その中に querytest.py を保存します。
これらをラズパイ上で直接 NANO で作成しても、また、MACなどで作成し、SFTP で、ラズパイに転送しても構いません。自分の環境にあった方法で作成してください。
なお、ファイルは UTF-8 でテキストエンコーディングします。

CGI files

ドキュメントルートに保存した index.html でボタンを3つ表示し、その一つをクリックすると、その情報を「GET」手法で cgi-bin ディレクトリーにある querytest.py に渡します。
querytest.py で、どのボタンが押されたかのかを示す HTML データを生成し、MACのブラウザーに返送し結果を表紙します。
cgiserber.py は、Webサーバーを起動させる Pythonプログラム

cgiserver.py

import CGIHTTPServer
CGIHTTPServer.test()

index.html,

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1,
      maximum-scale=1">
    <link rel="stylesheet" href="style.css" type="text/css" />
    <title>CGIHTML</title>
  </head>
  <body>
    <p>LED On/Off !</p>
    <form method="GET" action="cgi-bin/querytest.py">
      <input type="submit" name="btn" value="1">
      <input type="submit" name="btn" value="2">
      <input type="submit" name="btn" value="3">
    </form>
  </body>
</html>

NOTE: <meta name="viewport" ... は、iPhoneで表示させた時に縮小表示させないための指示。

style.css

@charset "UTF-8";
input{
    -webkit-appearance: none;
    font: 130% Arial;
    background-color: lightgrey;
    border: 1px solid gray;
    width: 70px; height: 70px;
    border-radius: 10px;
}

NOTE: CSSで、ページに表示されるINPUTボタンの大きさと色を変更します。
-webkit-appearance: none; は、iPhoneでCSSの指示を反映させるコマンド。

querytest.py

#!/usr/bin/env python
# coding: utf-8

html_body="""
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1,
      maximum-scale=1">
    <link rel="stylesheet" href="../style.css" type="text/css" />
    <title>CGIHTML</title>
  </head>
  <body>
    <p>ボタン %s をクリックしました。!</p>
    <form method="GET" action="cgi-bin/querytest.py">
      <input type="submit" name="btn" value="1">
      <input type="submit" name="btn" value="2">
      <input type="submit" name="btn" value="3">
      <input type="submit" name="btn" value="Off">
    </form>
  </body>
</html>
"""

# CGI関連命令読込
import cgi
# GET情報を thebtn に読込
form=cgi.FieldStorage()
thebtn=form.getvalue('btn','N/A')
# GET入力情報を反映したページを返信
print "Content-type: text/html\n"
print html_body % thebtn

# GPIO関連命令読込
import RPi.GPIO as GPIO
# LED設置ピンの定義
LED9 = 9
LED10 = 10
LED11 = 11
LEDs = (9,10,11)
# GPIO LEDピンを出力に設定
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(LEDs, GPIO.OUT)

# GET入力情報によりLED点滅
if thebtn == "1":
  GPIO.output(LED11,not(GPIO.input(LED11)))
elif thebtn == "2":
  GPIO.output(LED9,not(GPIO.input(LED9)))
elif thebtn == "3":
  GPIO.output(LED10,not(GPIO.input(LED10)))
else:
  GPIO.output(LEDs,0)
  # GPIO リセット
  GPIO.cleanup()

NOTE: このファイルには実行権限を付与させること。

CGIHTTPServerの起動

Webサーバーを起動するには、ディレクトリー PythonWeb に移動して、cgi-bin ディレクトリ内の querytest.py に実行権限があることを確認し、Python で、cgiserver.py を実行します。ちょっと遅れて、「Serving HTTP on 0.0.0.0 port 8000 ...」と表示されれば、稼働しています。

pi@raspberrypi:~ $ cd PythonWeb
pi@raspberrypi:~ $ ls
cgi-bin  cgiserver.py  index.html  style.css
pi@raspberrypi:~ $ chmod 755 cgi-bin/querytest.py
pi@raspberrypi:~ $ ls -l cgi-bin
total 4
-rwxr-xr-x 1 pi pi 1195 Jan  8 11:30 querytest.py
pi@raspberrypi:~ $ python cgiserver.py
Serving HTTP on 0.0.0.0 port 8000 ...
動的アプリの動作確認

Macなどのブラウザーを立ち上げ、アドレス欄に
raspberrypi.local:8000
と入力します。
表示されたページのボタンをクリックします。
どのボタンをクリックしたかが正しくブラウザーに表示され、ラズパイのLEDが点灯・消灯すればOKです。

pages
CGIHTTPServerの停止

Webサーバーサービスを停止するには。ターミナル画面で「CTL + c」をキーボードから入力します。また、単にターミナルソフトを終了させてもWebサーバーサービスを停止させることができます。