仕事中の問題と解決メモ。

最近はPythonとGoogle Cloud Platformがメイン。株式会社ビズオーシャンで企画と開発運用、データ活用とか。 http://mstdn.bizocean.co.jp/@uyamazak https://github.com/uyamazak/

Raspberry Piで既存のコードを利用して複数のLEDチカチカさせたり、ブザーを鳴らしたりする

研究開発という建前で経費でRaspberry pi 3を買った。

いろいろ揃えるのが面倒なので下記のセットを購入。


Google Assistant SDKを入れていろいろやろうとしたけど、まだ英語しか使えず勇気を振り絞って「Ok,Google」といっても、私の発音では反応してくれないのが辛すぎるので、まずはLEDをチカチカさせるLチカから始めようと入門書と、スターターキットを買った。


本の通り、まずは単体でLEDを光らせるのは30分もかからず終わってしまったので、せっかくなので、他のシステムと組み合わせてたくさんチカチカさせようと思った。

そして考えた。データ収集を行っているoceanusではbizoceanの各種イベント(ページビューとか、書式ダウンロードとか)をGoogle Cloud Pub/Subに流しているので、それを受信して種類によっていろんなLEDを光らせればいいと。

github.com

Google Cloud Pub/Sub とは  |  Cloud Pub/Sub  |  Google Cloud Platform


と、やろうとしたときにはRaspbery pi 3は新人の勉強用になってしまったので、以前いた人が買って引き出しに封印されていた古いRaspbery pi Model B+でやることにした。GPIOは全く一緒なので処理がめっちゃ遅い以外は特に不都合がなかった。

で、できたやつがこれ。

ページビューで白、書式ダウンロードで緑、会員登録で黄色、会員退会で赤とブザーが鳴る。

f:id:uyamazak:20170914105254j:plain

f:id:uyamazak:20170914105300j:plain

f:id:uyamazak:20170914105304j:plain


コードは基本的にはrevelationを使ってるけど、一部下記のように書きたしたりしている。

ラズパイ操作用

from RPi import GPIO

# 前回が異常終了だと起動時にエラーで起動できないので最初にやってしまう。それはそれでエラーが出るけど気にしない
GPIO.cleanup()


# 使うGPIOのポートと繋げたLEDの色の頭文字でdictにして、指定しやすくした
GPIO_PORTS = {"w": 22,
              "y": 23,
              "g": 24,
              "r": 25,
              }
# 起動時のセットアップ
for key, num in GPIO_PORTS.items():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(num, GPIO.OUT)

# 光らせる関数を作る
def flash_led(key, time=0.01):
    GPIO.output(GPIO_PORTS[key], GPIO.HIGH)
    sleep(time)
    GPIO.output(GPIO_PORTS[key], GPIO.LOW)

こっちが光らせる関数を呼び出す部分を抜粋。少ないしめんどいからif文。
イベントの重要度によって光る時間も変えている。

if data.get("evt") == "pageview":
    logger.info("{}:pageview".format(data.get("dt")))
    flash_led("w")
    if "/download/complete" in data.get("url"):
        logger.info("{}:download".format(data.get("dt")))
        flash_led("g", 1)
    if "/entry/complete" in data.get("url"):
        logger.info("{}:entry".format(data.get("dt")))
        flash_led("y", 1)
    if "/quit/complete" in data.get("url"):
        logger.info("{}:quit".format(data.get("dt")))
        flash_led("r", 0.5)

問題としては、Googleの公式Pub/Subクライアントが重いせいか、ラズパイB+では処理が追い付かずどんどん溜まってしまい、しばらくするとスレッドが起動できずに死亡するところ。

おそらく3で動かせば大丈夫なはず。

1日もかからない作業だったけど、GPIOで3VのON、OFFができることは感覚的に理解できた。

次はスターターキットの各種センサーを使った何かをやってみる。