GAミント至上主義

Web Monomaniacal Developer.

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ができることは感覚的に理解できた。

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

pythonのslackbotを使ってJSONを整形するボットを作る

新しく入ってきた人にPythonでSlack上の会話を翻訳するbotを作るにあたり、まずは自分でも作ってみた。

yfp5521.hatenablog.com


使ったライブラリはこれ。普通にpipで入れられてすぐ使える。
GitHub - lins05/slackbot: A chat bot for Slack (https://slack.com).


もう一つGoogle Cloud Natural Language APIの結果を返す動作確認用のボットも作ったけど、ぐちゃぐちゃなので公開しづらい。



下記をjson.pyとして、slackbotのインストール時に作ったpluginsに置く。

# coding: utf-8
from slackbot.bot import respond_to     # @botname: で反応するデコーダ
# from slackbot.bot import listen_to      # チャネル内発言で反応するデコーダ
# from slackbot.bot import default_reply    # 該当する応答がない場合に反応するデコーダ
import json
import logging
logger = logging.getLogger(__name__)


@respond_to('^[\{\[].*[\}\]]$')
def json_listen_func(message):
    json_text = message._body.get("text")
    logger.debug(json_text)
    try:
        json_obj = json.loads(json_text)
    except Exception as e:
        logger.debug(e)
    else:
        text = json.dumps(json_obj,
                          ensure_ascii=False,
                          indent=2,
                          sort_keys=True)
        users = message._client.users
        attachments = [{"text": text,
                        "author_name": users.get(message._body["user"], "none"),
                        
        message.reply_webapi("",
                             attachments=attachments,
                             as_user=True,
                             in_thread=False)

slackbot_settings.pyは下記のような感じ。

# coding: utf-8
# botアカウントのトークンを指定
API_TOKEN = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# このbot宛のメッセージで、どの応答にも当てはまらない場合の応答文字列
DEFAULT_REPLY = "ルームに招待してくれたら自然言語解析、ダイレクトメッセージでJSONの変換ができるよ"

# プラグインスクリプトを置いてあるサブディレクトリ名のリスト
PLUGINS = ['plugins.json']

ERRORS_TO = "uyamazak"

DEBUG = True

ざっくりと条件として、@respond_toで最初と最後が{}、[]だけのときに反応するようにしている。

どっかのサーバーで動かすと下記のようになる

f:id:uyamazak:20170912135633p:plain

よくデータをBigQueryにJSONでぶち込んでるけど、その中身をさっと確認したいとき、今まではWEBサービスをググって使ってたけどslackでもできるようになった。


新しく入ってきた人にLinux、vim、Dockerなど開発環境を叩き込む1週間

詳しくは本人のブログだけど


yfp5521.hatenablog.com


大きめのSlerに1年ちょっといた人がビズオーシャンに入ってきてくれた。


bizocean本体はクラウドではなく、データーセンターにあったり、CentOS6だったりPHPだったり、いろいろと退屈なので、私がoceanusの開発でやっている環境をとりあえず叩き込んだ。

WEB系の開発がやりたいとのことだったので、まずは全体像を理解してもらうという目的。


具体的には

  • 作業はすべて自分のPC(Windows)から社内のサーバー(Ubuntu)にSSHでつなげて行う。
  • 効率化のためにzsh使う
  • エディタはvimIDEなんぞいらん市ね。
  • tmux使う
  • 開発はすべてDockerのコンテナを使って構築、動作までさせることで、サーバー構成の明文化、本番まで一気通貫を目指す。


と、Linuxすらあんまり触ったことない人にとって、いたるところに無理がある内容だったけど、実際にDockerコンテナを立てるのを何回かやってもらって、全体のイメージはつかんでくれたっぽい。


5日目ぐらいに、部長から社内に英語しかしゃべれない外国人がいるので、翻訳bot作ってよと来たので、ちょうどいいと思い作ってもらった。


横から口出しをしながら、Google Translate APIを使うことで、多言語に対応したボットを1日半ぐらいで完了し、その外国人との会話テストまでやってもらえて、1週間で小さい成功体験ができたのはよかったと思う。


PyQも試しに契約して進めてもらってるけど、実際に役立つものが作れるなら作った方が面白いと思った。



次は、Linuxの勉強もかねて、会社に転がっているRaspbery pi 3の初期インストールから、Dockerの動作環境づくりまで行い、作ったbotをそこで動かしてもらおうと思う。

買ったのは下記のフルセット。SDカードは彼用に新しく買った。


早速インストールしたけど動かないと言われ、もしかしたらSDカードの相性問題かと思ったので、私が試しにやったら問題なく動いた。

Linux教材としてはラズパイの当初の目的だけあって、かなりいいと思う。安いから1人1台買ってもいいし、SDを買い足すことで使いまわしも簡単。

SDはこれ買った。もちろん使えるかどうか私は保証できない。