経緯
仕事の宿題でWeb(ブラウザ)からローカルにあるPythonを実行させるものを作りたかったのでWebIOPiをインストールしようと思いましたが、悪戦苦闘してしまったので雑に記事に書き起こそうと思います。
事前情報
まず、ラズパイのサイトからNOOBSを落としてOSをインストールします。(バージョンは3.2.0現在)
この時、インストール時に自動的にPythonもインストールされましたが、バージョンは3.7.3でした。
WebIOPiのインストール
以下のサイトを参考にWebIOPiをインストール。
WebIOPiを使ってブラウザからRaspberry PiのGPIOを操作してみる
sudo ./setup.sh
の時点で既にエラーになっていたが、気づかずにスルー
sudo systemctl start webiopi
でWebIOPiを実行、ここで失敗していることに気づく。
試しに、sudo webiopi start
で実行させると以下のようなエラーが発生しました。
なぜかSyntaxErrorが発生しました。
(この時点で察した人もいるかも知れません、ちなみにsetup.shのログにも上記のエラーが出ていました。)
原因
Python3.7ではasyncは予約語となったそうです。(知らなかった。。。)
asyncio --- 非同期 I/O
そのせいでSyntaxErrorが発生したみたいです。
対策
- Python3.7より以下をインストールするバージョンのRaspbianをインストール
- Python3.7より以下を手動でインストールする
上記2つを考えましたが、3.5は使いたくないし、3.7より以下をインストールするバージョンなんてわかんないし。
親のDebianを覗いてみると、最新が3.7.3で1個前が3.5だったのでたぶん3.6はない(根拠はない)
ということで手動でPython3.6をインストールした次第です。
余談1
上記対策の他に、pyenvを入れてからPython3.6を入れようと試みたが、setup.shは直接ディレクトリを覗くっぽく、結局3.7.3のバージョンをインストールされた。
また、後述するが、オプションを付けないとせっかくインストールしたのにデフォルト(この場合Python3.7.3)に戻ってしまう。結果的にpyenvを消す工数が増えてしまった。
Python3.6のインストール
インストールの前に、sodo apt-get remove python3
を実行
その後に以下の記事を参考にインストール (今回はなんとなく3.6.8をインストール)
[Raspberry Pi に Python 3.7.0 をインストールする] (https://qiita.com/GuitarBuilderClass/items/d6d2798bebf7b916c5c6)
さらにpython3.6のリンクをpython3に変更
WebIOPiの実行
この時はなぜかうまく動かなかった(おそらくオプションを付け忘れた)
余談2
この後再起動したら今度はguiが起動しなくなった(真っ暗な画面にマウスカーソルのみが映る状態)
その日は諦めてふて寝しました。
次の日、OSインストールからやり直しましたがある意味よかったのかもしれない。
再チャレンジ
もう原因はわかっているので、Python3.6からインストール。
Python3のリンク書き換えを行ったのち、
WebIOPiをインストール
(今回はpython3をremoveしなかった)
setup.shを実行する時は、---skip-apt
を付けないと、python3を書き換えてしまうので、
sudo ./setup.sh --skip-apt
簡単な実行テストの作成
Raspberry Piでラジコンをつくってみる
上記記事を参考にしました。(実はこれがやりたいことだったりする)
上記記事の
適当な場所にscript.pyとindex.htmlのファイルを作成し
のとこから。
今回やりたいことはとりあえず、
- 戻り値をalertで表示
- tada.wavを再生
これをボタンから実行するというもの。
1はなんとかできたけど、tada.wavの再生ができない。
pygameを使って再生しようと思ったが、python3.6を入れたせいか、
pip3 list
を実行すると、WebIOPiぐらいしか入っていなかった。
sudo pip3 install pygame
を実行すると以下のようなエラーが発生
あまり見たことないエラーだったのでとりあえずエラー文でぐぐると以下のstackoverflowの質問を発見
pip is showing error 'lsb_release -a' returned non-zero exit status 1
/usr/bin/lsb_release
のPythonのバージョンを書き換えればいいっぽかったのでsudoで変えてみる。
私の場合は以下
!/usr/bin/python3 -Es
!/usr/bin/python3.6 -Es
pip3は使えるようになったが、相変わらずpygameはインストールができなかった。(エラー文は変わった)
もう少し探してみると、以下の記事を発見
raspberry pi上のpython3にpygameを入れる際のエラーを解決
早速試してみると、すんなりpygameがインストールできた。
まとめ
長い道のりだったが、結局のところ
Python3.7より以前のバージョンにする
それに似合った対応をする、ということだった。
もっと早くasyncのこと知ってればこんなに時間かからなかったのかも・・・。
参考サイト・記事
- WebIOPiを使ってブラウザからRaspberry PiのGPIOを操作してみる
- asyncio --- 非同期 I/O
- Raspberry Pi に Python 3.7.0 をインストールする
- Raspberry Piでラジコンをつくってみる
- pip is showing error 'lsb_release -a' returned non-zero exit status 1
- raspberry pi上のpython3にpygameを入れる際のエラーを解決
スペシャルサンクス
お世話になりました。 @kiritan
ソースコード
一応置いておきます。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>webiopi_Test</title>
</head>
<body>
<!--
<script type="text/javascript" src=""></script>
-->
<script type="text/javascript" src="/webiopi.js"></script>
<script type="text/javascript">
let valuefnc = function(macro, args, response){
value = response;
alert(`Pythonからのメッセージ:${value}`)
}
function getValueFromPython(){
webiopi().callMacro("sendValue", "Hello", valuefnc);
}
function play(){
webiopi().callMacro("playTada_wav");
}
</script>
<p>
<input type="button" name="getValue" value="Pythonから値を取得" onclick="getValueFromPython()">
<input type="button" name="playSound" value="tada.wav" onclick="play()">
</p>
</body>
</html>
import webiopi
import pygame.mixer
import time
pygame.mixer.init()
pygame.mixer.music.load("/home/pi/webiopi/media/tada.wav")
webiopi.setDebug()
value = " From Python."
@webiopi.macro
def sendValue(text):
return str(text) + value
@webiopi.macro
def playTada_wav():
pygame.mixer.music.play(1)
time.sleep(1.5)
pygame.mixer.music.stop()