読者です 読者をやめる 読者になる 読者になる

Rock Me!開発者ブログ

DEVELOPERS BLOG

Amazon Dash Buttonを押したらSpreadSheetが更新されるようにしてみた(Mac, Python3編)

だいぶ今さら・・・感のあるネタですが、最近はじめたPythonの練習がてらにやってみました。
node.jsの例が多いのですが、やっている事は単純なのでもちろんPythonでもできます。
環境はmac(Sierra),Python3です。
まだ勝手がわからず、自分で書いたところはぎこちないですが。。

dash buttonを検知する

Python2の例が多かったのですが、こちらが3でやっていたので検知部分を参考にさせていただきました。
Hacking the Amazon Dash Button to Make a Simple, Cheap, IoT Place-Anywhere Networked Button

MACアドレスを調べる

参考スクリプトで取っ掛かりからつまづいて、原因がよくわからなかったので、ひとまずシェルで取得しちゃいました。(0.0.0.0じゃなかったみたい)
dash buttonを押して、下記のように表示されたら、MACアドレスの34:d2:70:ac:1b:c0 と192.168.1.13をメモ。普通は0.0.0.0なのかな。(あとで調べる)

$ sudo tcpdump -e arp -c 100
12:00:49.971730 34:d2:70:ac:1b:c0 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.1 tell 192.168.1.13, length 28

python環境の構築

# 仮想環境構築
python3 -m venv --copies dashbutton
cd dashbutton/
. bin/activate
    
# 必要ライブラリのインストール
pip install --upgrade pip
pip install scapy-python3
pip install netifaces

brew install --with-python libdnet

検知部分の作成

from scapy.all import *

def arp_display(pkt):
    if pkt[ARP].op == 1:
        if pkt[ARP].psrc == '192.168.1.13': # メモのIP
            if pkt[ARP].hwsrc == '34:d2:70:ac:1b:c0': # メモのMACアドレス
                print("Pushed Button 1")
            elif pkt[ARP].hwsrc == 'XX:XX:XX:XX:XX:XX':
                print("Pushed Button 2")
            else:
                print("ARP Probe from unknown device: " + pkt[ARP].hwsrc)

print(sniff(prn=arp_display, filter="arp", store=0))

実行

$ sudo python ./dash.py

GoogleSpreadsheetに書き込む

Google Drive APIの設定を行い、OAuthとSpreadSheet用のライブラリを使用します。
こちらの記事を参考にさせていただきました。
pythonでGoogle Spread Sheetをいじる(OAuth) - Qiita

OauthのライブラリでSignedJwtAssertionCredentialsからServiceAccountCredentialsへの変更があったようなので、こちらの書き方が良いようです。

さきほどの検知部分に処理を追加すると、下記のようになります。
書き込み内容は用途によって変更してください。

gspreadの使い方はGitHubに載っているので参考に。

from scapy.all import *
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from datetime import datetime


def update_spreadsheet():
    scope = ['https://spreadsheets.google.com/feeds']
    doc_id = 'doc_id'
    path = os.path.expanduser('./XXXXXXX-XXXXXXXXX.json')

    credentials = ServiceAccountCredentials.from_json_keyfile_name(path, scope)
    client = gspread.authorize(credentials)
    gfile = client.open_by_key(doc_id)
    worksheet = gfile.sheet1
    records = worksheet.get_all_values()
    new_row = len(records) + 1

    now = datetime.now()
    worksheet.update_cell(new_row, 1, now.strftime("%Y/%m/%d %H:%M:%S"))
    worksheet.update_cell(new_row, 2, 1)


def arp_display(pkt):
    if pkt[ARP].op == 1:
        if pkt[ARP].psrc == '192.168.1.13':
            if pkt[ARP].hwsrc == '34:d2:70:ac:1b:c0':
                print("Pushed Button 1")
                update_spreadsheet()
            elif pkt[ARP].hwsrc == 'XX:XX:XX:XX:XX:XX':
                print("Pushed Button 2")
            else:
                print("ARP Probe from unknown device: " + pkt[ARP].hwsrc)


if __name__ == "__main__":
    print(sniff(prn=arp_display, filter="arp", store=0))