ブラウザからRaspberry Pi内のPythonスクリプトを実行してみる

どうも!大阪オフィスの西村祐二です。前回、WebIOPiを使ってブラウザからRaspberry PiのGPIOを操作するブログをかきました。今回はブラウザからRaspberry Pi内にあるPythonスクリプトを実行してみたいと思います。
2018.05.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

どうも!大阪オフィスの西村祐二です。

前回、WebIOPiを使ってブラウザからRaspberry PiのGPIOを操作するブログをかきました。

WebIOPiを使ってブラウザからRaspberry PiのGPIOを操作してみる

WebIOPiはそれ以外にもRaspberry Piの中にあるPythonスクリプトをブラウザから実行することや、WEBページをHTML,CSS,JSを使って自分でカスタマイズするができます。

今回は、それをやってみたいと思います。

環境

  • Raspberry Pi
    • Raspberry Pi 3 Model B
    • Linux raspberrypi 4.9.59-v7+ #1047 SMP Sun Oct 29 12:19:23 GMT 2017 armv7l GNU/Linux
  • Python
    • Python 3.5.3

WebIOPiの設定変更

  • WebIOPiのコンフィグファイルを変更します。
$ cd /etc/webiopi/
$ sudo vi config
  • デフォルトのHTMLとリソースファイルの場所を指定します。

今回は/home/pi/work/webiopi/配下にファイルを作成のでこのパスを設定します。

・
・
・
[HTTP]
# HTTP Server configuration
enabled = true
port = 8000

# File containing sha256(base64("user:password"))
# Use webiopi-passwd command to generate it
#passwd-file = /etc/webiopi/passwd

# Change login prompt message
prompt = "WebIOPi"

# Use doc-root to change default HTML and resource files location
#doc-root = /home/pi/webiopi/examples/scripts/macros
doc-root = /home/pi/work/webiopi/

# Use welcome-file to change the default "Welcome" file
#welcome-file = index.html
・
・
・
  • ブラウザとサーバ側のハブとなるPythonスクリプトを指定します。

今回は/home/pi/work/webiopi/static/gpio.pyに書いていくので、このパスを設定します。

・
・
・
[SCRIPTS]
# Load custom scripts syntax :
# name = sourcefile
#   each sourcefile may have setup, loop and destroy functions and macros
#myscript = /home/pi/webiopi/examples/scripts/macros/script.py
myscript = /home/pi/work/webiopi/static/gpio.py
・
・
・

ファイル作成

  • ディレクトリ構成は下記のようなかんじです。

test_python.pyがブラウザから実行したいpythonスクリプトになります。

/home/pi/work/webiopi
├── index.html
└── static
    ├── css
    │   └── style.css
    ├── gpio.py
    ├── js
    │   └── main.js
    └── test_python.py

web画面を作成

web画面を作成していきます。今回は簡単に実行ボタンを設置するだけです。

  • HTML

Pythonスクリプトを実行するボタンを用意しておきます。クリックイベントでpython()を実行するようにしています。

index.html

<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>WebIOPi | Python Script Run</title>
        <script type="text/javascript" src="/webiopi.js"></script>
        <script type="text/javascript" src="/static/js/main.js"></script>
        <link rel="stylesheet" type="text/css" href="/static/css/style.css">
    </head>
    <body>
        <input type="button" value="python script run" class="python" onClick="python()">
    </body>
</html>
  • CSS

ボタンをスタイリングしています。

style.css

.python {
    font-size: 20px;
    display: inline-block;
    padding: 0.5em 1em;
    text-decoration: none;
    background: #668ad8;
    /*ボタン色*/
    color: #FFF;
    border-bottom: solid 4px #627295;
    border-radius: 3px;
    /*線を消す*/
    outline:none;
}

.python:active {
    /*ボタンを押したとき*/
    -ms-transform: translateY(4px);
    -webkit-transform: translateY(4px);
    transform: translateY(4px);
    /*下に動く*/
    border-bottom: none;
    
}
  • JS

クリックイベンドで呼び出されるpython()を設定します。

ブラウザからRaspberry Pi内のスクリプトを実行するためにはwebiopi().callMacro(<func_name>, <argument>, <callbackfunc_name>)を使うことで実行できます。

main.js

webiopi()

function python() {
    webiopi().callMacro("run_script", 0, callbackGetValue);
}

function callbackGetValue(macro, args, data) {
    console.log(macro);
    console.log(args);
    console.log(data);
}

webiopi().callMacro(<func_name>, <argument>, <callbackfunc_name>)について説明すると、

<func_name> => run_script

コンフィグで指定したサーバ側のpythonファイルgpio.py内にある関数を指定します。

<argument> => 0

<func_name>に渡す引数になります。

<callbackfunc_name> => callbackGetValue

<func_name>実行後にかえってくる値を処理するコールバック関数を指定します。コールバック関数の処理として、今回はコンソールに出力するだけとしています。

Raspberry Pi内のpythonスクリプトを作成

  • gpio.py

WebIOPiのコンフィグで指定したファイルを作成していきます。ここでは実行したいスクリプトを読み込み、関数に@webiopi.macroというデコレータをつけることで、ブラウザから関数を実行することが可能になります。

ここではtest_python.pyを読み込み、テキストファイルを作成する関数を実行するようにしています。また、returnで返すことによってJSのコールバック関数に値を渡すことができます。

※WebIOPiはPython3で実行するようで、Python3で記述する必要がありますのでご注意ください。

import webiopi
import sys
import os

sd = os.path.dirname(os.path.abspath(__file__))
sys.path.append(sd)

import test_python

@webiopi.macro
def run_script(data):
    if data == "0":
        result = test_python.create_file(sd)
        return str(result)
    else:
        return 'error'

sys.path.append(sd)は外部ファイルをインポートする際のパスを通すために設定しています。

  • test_python.py

test.txtというファイルを作成する処理を書いています。また、'OK : create file'という値を返すようにしています。

def create_file(path):
    f = open(path + '/test.txt','a')
    f.write('run from web')
    f.close()
    return 'OK : create file'

動作確認

  • 設定の反映

pythonなどのプログラムを変更した際はWebIOPiのサービスを再起動しないと反映されないの、注意してください。

$ sudo systemctl restart webiopi
  • ブラウザからボタンをクリック

問題なく実行完了すれば、ブラウザのコンソール上に下記画像の下から3行のようなログが出力されます。

また、Pythonスクリプトの実行結果として、Raspberry Piにtest.txtが作成されています。

$ pwd
/home/pi/work/webiopi/static
$ ls -l
total 24
drwxr-xr-x 2 pi   pi   4096 May 24 14:02 css
-rw-r--r-- 1 pi   pi    288 May 24 15:09 gpio.py
drwxr-xr-x 2 pi   pi   4096 May 24 14:05 js
drwxr-xr-x 2 root root 4096 May 24 15:11 __pycache__
-rw-r--r-- 1 pi   pi    131 May 24 15:09 test_python.py
-rw-r--r-- 1 root root   12 May 24 15:15 test.txt    <= ファイルが作成されている

さいごに

いかがだったでしょうか。

WebIOPiを使ってブラウザからRaspberry Pi内のPythonスクリプトを実行してみました。

自分でカスタマイズできるので、いろいろなことができそうですね。

だれかの参考になれば幸いです。