ケース別設定

myThingsをはじめようキットで、部屋の温度をGmailで通知する

使用したキット

スイッチサイエンス社

スイッチサイエンス社のWebサイト 新規ウィンドウを開きます で購入できます。

IDCFチャンネル公式サポート窓口

GitHub IDCFChannel 新規ウィンドウを開きます にログイン後、各リポジトリ画面右側の「Issues」からお問い合わせください。

Part1 サーバーの準備 myThingsをはじめようキットで、部屋の温度をGmailで通知する

「IDCF」チャンネルを使うと、Raspberry Piと環境センサーが計測した気温が27度を超えたときなど閾値を監視して、myThingsのトリガーを作成することができます。 今回はトリガーを作成するサンプルを紹介します。

myThingsをはじめようキット

今回はスイッチサイエンスから発売された myThingsをはじめようキットを使います。このスターターキットを使うと IDCFクラウドを経由して、自作したIoT機器を myThingsと連係できるようになります。はじめてのRaspberry Piの入門キットとして必要な部品が集まっています。

用意するもの

Raspberry Piなどをすでに持っている場合は、個別に必要な部品を用意します。Lチカだけだと物足りないので、気温、湿度、気圧が計測できる環境センサの BME280もあわせて使います。

USBシリアル変換アダプター

USBシリアル変換アダプターを用意してホストマシンと直接シリアル接続できるようにします。

FTDI USBシリアル変換アダプター(5V/3.3V切り替え機能付き)を使ってOSXとRaspberry Pi 2を接続します。 Software Installation (Mac)を参考にしてGPIOピンにつなぎます。電圧切り換えジャンパは 3.3V側にしてください。電源はUSB ACアダプタから供給するのでこのUSBシリアル変換アダプタから電源供給はしないでください。

  • GND 黒 (USB-TTL) -> GND P6 (Raspberry Pi)
  • RXD 黄色 (USB-TTL) -> TXD GPIO14 P8 (Raspberry Pi)
  • TXD 緑 (USB-TTL) -> RXD GPIO15 P10 (Raspberry Pi)

raspi-ftdi2.png

FTDIのFT232RL用のドライバは VCP Driversからダウンロードしてインストールします。今回のホストマシンはOSX Yosemite 10.10.4です。 Mac OS X 10.9 and aboveFTDIUSBSerialDriver_v2_3.dmgをインストールします。 Mac OS X 10.3 to 10.8の場合は、 FTDIUSBSerialDriver_v2_2_18.dmgを使います。

OSXからScreenを使ってターミナル接続します。 Axxxxの箇所は環境によって異なります。

$ screen /dev/tty.usbserial-Axxxx 115200

無線LAN USBアダプタ

インターネットに接続するために無線LANの設定をします。無線LAN USBアダプタは PLANEX GW-USNANO2Aを使います。
wpa_passphraseコマンドから /etc/wpa_supplicant/wpa_supplicant.confにssidとpskの設定を入れます。
{ssid}の部分に自宅のssid, {passphrase}にパスフレーズを入力して実行してください。

$ sudo sh -c 'wpa_passphrase {ssid} {passphrase} >> /etc/wpa_supplicant/wpa_supplicant.conf'

さらに複数のネットワーク設定を記述する場合は、 /etc/wpa_supplicant/wpa_supplicant.confpriorityを追加します。デフォルトは0で、値が大きい方が優先されます。

また、今回の無線LAN環境はSSIDステルスモードだったので /etc/wpa_supplicant/wpa_supplicant.confを編集して scan_ssid=1を追加しています。

/etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
        priority=0
        scan_ssid=1
        ssid="xxx"
        proto=WPA2
        key_mgmt=WPA-PSK
        #psk="xxx"
        psk=xxx
}

/etc/network/interfacesを編集します。今回はIPアドレスはDHCPから取得するため、 iface wlan0 inet manualiface wlan0 inet dhcpまた wpa-confになっていることを確認します。今回は wlan1は使いませんがこちらもdhcpに変更しておきます。

/etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
allow-hotplug eth0
iface eth0 inet manual

auto wlan0
allow-hotplug wlan0
#iface wlan0 inet manual
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

auto wlan1
allow-hotplug wlan1
#iface wlan1 inet manual
iface wlan1 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

wlan0を再起動します。

$ sudo ifdown wlan0
$ sudo ifup wlan0

DHCPからIPアドレスが取得できたら、pingでインターネットに接続できることを確認します。

$ ip addr show wlan0
$ ping -c 1 www.yahoo.co.jp
PING www.g.yahoo.co.jp (183.79.198.116) 56(84) bytes of data.
64 bytes from f9.top.vip.kks.yahoo.co.jp (183.79.198.116): icmp_req=1 ttl=50 time=20.8 ms

--- www.g.yahoo.co.jp ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 20.884/20.884/20.884/0.000 ms

raspi-configの初期設定

raspi-configをroot権限で実行して、Raspberry Pi 2の初期設定をしていきます。

$ sudo raspi-config

ファイルシステムの拡張とタイムゾーンの変更を行います。

  • Expand Filesystem > Select
  • Internationalisation Options > Change Timezone > Asia > Tokyo

再起動します。

$ sudo reboot

再起動後にファイルシステムがリサイズされました。ようやくパッケージをインストールする準備ができました。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs          7.3G  2.4G  4.6G  35% /
/dev/root       7.3G  2.4G  4.6G  35% /
devtmpfs        460M     0  460M   0% /dev
tmpfs            93M  240K   93M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           186M     0  186M   0% /run/shm
/dev/mmcblk0p1   56M   19M   37M  34% /boot

ファームウェアの更新

初期状態の確認

今回利用している Raspberry Pi用microSD 8GB(Raspbian OS 書き込み済)のバージョンを確認します。

$ uname -a
Linux raspberrypi 3.18.11-v7+ #781 SMP PREEMPT Tue Apr 21 18:07:59 BST 2015 armv7l GNU/Linux
$ cat /proc/version
Linux version 3.18.11-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03) ) #781 SMP PREEMPT Tue Apr 21 18:07:59 BST 2015

Raspbian OSは 3.18.11-v7+が入っていました。つぎにpiユーザーのグループを確認すると、i2cグループに最初から入っています。piユーザーはsudoなしでi2cデバイスを操作できるようになっています。

$ id -a
uid=1000(pi) gid=1000(pi) groups=1000(pi),4(adm),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),106(netdev),996(gpio),997(i2c),998(spi),999(input)

パッケージの更新とアップグレードをします。

$ sudo apt-get update
$ sudo apt-get upgrade

ファームウェアの更新もしておきます。

$ sudo rpi-update
...
 *** A reboot is needed to activate the new firmware

rebootします。

$ sudo reboot

カーネルのバージョン、RaspbianOSのバージョンが 4.0.8-v7+にあがりました。

$ uname -a
Linux raspberrypi 4.0.8-v7+ #805 SMP PREEMPT Thu Jul 16 18:46:20 BST 2015 armv7l GNU/Linux
$ cat /proc/version
Linux version 4.0.8-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03) ) #805 SMP PREEMPT Thu Jul 16 18:46:20 BST 2015

その他設定

vim

エディタは好みですがvimを使います。

$ sudo apt-get install vim
$ mkdir ~/tmp

バックアップを作らない設定だけします。

~/.vimrc
set backupdir=~/tmp

時間合わせ

NTPサーバーを日本のサーバーに設定します。

/etc/ntp.conf
#server 0.debian.pool.ntp.org iburst
#server 1.debian.pool.ntp.org iburst
#server 2.debian.pool.ntp.org iburst
#server 3.debian.pool.ntp.org iburst
pool ntp.nict.jp iburst

ntpdの再起動をして時間あわせをします。

$ sudo /etc/init.d/ntp restart
Stopping NTP server: ntpd.
Starting NTP server: ntpd.

Python

Raspberry Pi 2でセンサーデータを取得する場合はPythonを使うことが多いです。Pythonの開発環境をインストールします。

$ sudo apt-get update
$ sudo apt-get install python-dev
$ python -V
Python 2.7.3
$ curl https://bootstrap.pypa.io/get-pip.py -o - | sudo python
$ pip -V
pip 7.1.0 from /usr/local/lib/python2.7/dist-packages (python 2.7)

Lチカ

温度モーターとは関係ありませんが、電子工作に慣れるため、Lチカをやってみます。


Raspberry Pi 2 Model B GPIO 40 Pin Block Pinoutを参考にブレッドボード配線をします。LEDのアノード( 足がながい方)は GPIO 17につなぎます。

  • アノード (LED) -> GPIO17 P11 (Raspberry Pi)
  • カソード (LED) -> 抵抗器1K(茶黒赤金) -> GND P14 (Raspberry Pi)

raspi-led2.png

RPi.GPIOはRaspberry Pi 2にインストール済になっています。

$ apt-cache show python-rpi.gpio
Package: python-rpi.gpio
Source: rpi.gpio
Version: 0.5.11-1
Architecture: armhf
Maintainer: Ben Croston <ben@croston.org>
Installed-Size: 174
...

最初にプログラムを配置するディレクトリを作成します。

$ mkdir -p ~/python_apps

LチカをするPythonのプログラムを書きます。 GPIO17 P11を使います。PINに11を指定します。

~/python_apps/led-blink.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time

COUNT = 3
PIN = 11
GPIO.setmode(GPIO.BOARD)
GPIO.setup(PIN,GPIO.OUT)

for _ in xrange(COUNT):
    GPIO.output(PIN,True)
    time.sleep(1.0)
    GPIO.output(PIN,False)
    time.sleep(1.0)

GPIO.cleanup()

GPIOを操作する場合はroot権限が必要になります。プログラムを実行すると3回、1秒間隔でLチカします。

$ chmod +x led-blink.py
$ sudo ./led-blink.py

I2Cを使う

I2Cのバスを有効にします。最初に必要なパッケージをインストールします。

$ sudo apt-get install python-smbus i2c-tools

raspi-configを実行してI2Cサポートを有効にします。

$ sudo raspi-config
  • Advanced Options > I2C

rebootします。

$ sudo reboot

カーネルが3.18 以上の場合は /boot/config.txtに以下の設定が入ります。

/boot/config.txt
dtparam=i2c_arm=on

/etc/modulesにI2Cを有効にする設定します。 snd-bcm2835の下に追記します。

/etc/modules
snd-bcm2835

i2c-bcm2708
i2c-dev

rebootします。

$ sudo reboot

lsmodでi2c_devとi2c_bcm2708が表示されるとI2Cが有効になっています。

$ lsmod
Module                  Size  Used by
i2c_dev                 6047  0
snd_bcm2835            19761  0
snd_pcm                74433  1 snd_bcm2835
snd_seq                53553  0
snd_seq_device          6455  1 snd_seq
snd_timer              18205  2 snd_pcm,snd_seq
snd                    51646  5 snd_bcm2835,snd_timer,snd_pcm,snd_seq,snd_seq_device
8192cu                528381  0
i2c_bcm2708             5006  0
uio_pdrv_genirq         2958  0
uio                     8219  1 uio_pdrv_genirq

BME280

Raspberry Pi 2にBME280を配線します。

SDI      (BME280)  -> GPIO2 P03 (Raspberry Pi SDA1)
SCK      (BME280)  -> GPIO3 P05 (Raspberry Pi SCL1)
GND,SDO  (BME280)  -> GND  P09 (Raspberry Pi)
Vio,CSB  (BME280)  -> 3.3v P01 (Raspberry Pi)

raspi-bme280.png

i2cdetectコマンドで正しく配線できたか確認します。0x76アドレスを使っています。

$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 --

サンプルプログラムをダウンロードします。

$ cd ~/python_apps
$ git clone https://github.com/IDCFChannel/bme280-meshblu-py
$ cd bme280-meshblu-py

bme280_sample.pyを実行すると、temp(気温)、pressure(気圧)、hum(湿度)のデータを取得することができます。

$ python bme280_sample.py
temp : 29.66  ℃
pressure : 1004.27 hPa
hum :  49.71 %

Part2 myThingsアプリ トリガーでGmailのアクションを実行する

「Gmail」チャンネルの承認

myThingsのトリガーに「Gmail」チャンネルを使います。myThingsアプリを開きチャンネル一覧から選択して認証します。

gmail-channel.png

組み合わせの作成

ホーム画面から右上のプラスボタンをタップします。

mythings-home.png

組み合わせ作成画面ではトリガーとアクションのチャンネルをプラスボタンをタップして選択します。

recipe.png

「IDCF」トリガー

トリガーのプラスボタンをタップして、チャンネル一覧から「IDCF」をトリガーに選択します。「IDCF」チャンネルの認証をまだしていない場合は、 作成したサーバーをmyThigsで使えるように認証を行いますの手順で認証します。

idcf-trigger.png

「条件を満たしたら」のリストボックスから、 trigger-1を選択します。

idcf-trigger-selected.png

OKボタンをタップすると組み合わせの作成画面に戻ります。

recipe-trigger.png

「Gmail」アクション

アクションのプラスボタンをタップして、チャンネル一覧から「Gmail」をアクションに選択します。

gmail-action.png

アクションの選択画面で「メールを送信する」をタップします。

gmail-action-mail.png

送信先メールアドレス、件名、本文はすべて必須項目です。

gmail-action-detail.png

アクションの詳細設定が終わったらOKボタンをタップすると、組み合わせの作成画面に戻ります。

とりあえず「実行タイミング」と「曜日指定」はデフォルトのまま、「作成」ボタンをタップして終了します。

gmail-action-created.png

組み合わせの作成が完了して組み合わせ一覧画面に戻ります。

「IDCF」チャンネルサーバー

トリガーのURLとデータの保存

myThingsサーバーは一定間隔でメッセージの受信を確認しています。「IDCF」チャンネルをトリガーに使う場合は、myThingsサーバーが非同期でメッセージを取得できるようにデータを保存しておく必要があります。

HTTPを使う場合は、 /data/{triggerのuuid}にメッセージをPOSTすると「IDCF」チャンネルのデータベースにデータが保存されます。myThingsサーバーは新しいデータが取得できると、トリガー条件を満たしてアクションを実行します。

trigger-1デバイスの確認

最初に「IDCF」チャンネルサーバーをインストールしたIDCFクラウドの仮想マシンにログインします。myThingsアプリのアクションに選択した trigger-1のuuidとtokenを確認します。

$ cd ~/iot_apps/meshblu-compose
$ docker-compose run --rm iotutil show -- -k trigger-1

> iotutil@0.0.1 start /app
> node app.js "show" "-k" "trigger-1"

┌───────────┬──────────┬──────────────────────────────────────┐
│ keyword   │ token    │ uuid                                 │
├───────────┼──────────┼──────────────────────────────────────┤
│ trigger-1 │ d74ebedf │ 21c83792-b25e-4ae7-a627-714af57a1a4b │
└───────────┴──────────┴──────────────────────────────────────┘

curlコマンドでトリガーを出し、動作を確認する

確認したデバイス情報を使ってcurlコマンドを実行します。URLの dataの後ろに trigger-1のuuidを指定します。また、HTTPヘッダの認証情報にmyThingsアプリのトリガーに指定した trigger-1のuuidとtokenを指定します。

  • URL: 「IDCF」チャンネルに割り当てたIPアドレス + '/data/' + uuid
  • データ: 任意(現在このデータをアクションに渡す事はできません)
  • meshblu_auth_uuid: trigger-1のuuid
  • meshblu_auth_token: trigger-1のtoken
$ curl -X POST \
  "http://210.140.162.58/data/21c83792-b25e-4ae7-a627-714af57a1a4b" \
  -d 'temperature=over' \
  --header "meshblu_auth_uuid: 21c83792-b25e-4ae7-a627-714af57a1a4b" \
  --header "meshblu_auth_token: d74ebedf"

Raspberry Pi上で動作するPythonからトリガーを出す

スイッチサイエンスから発売されている myThingsをはじめようキットにも同梱されている BME280の環境センサーを使ったサンプルコードです。リポジトリは こちらです。5秒間隔で計測した気温がconfig.pyに定義した閾値の27度を超えたら、「IDCF」チャンネルサーバーにHTTP POSTします。

bme280_data.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from time import sleep
import json
import bme280
import requests
from config import conf

def sensing():
    return bme280.readData()

def main():
    # HTTP
    url = "http://{0}/data/{1}".format(conf["IDCF_CHANNEL_URL"],
                                       conf["TRIGGER_1_UUID"])
    headers = {
        "meshblu_auth_uuid": conf["TRIGGER_1_UUID"],
        "meshblu_auth_token": conf["TRIGGER_1_TOKEN"]
    };
    payload = {"trigger":"on"}

    while True:
        sleep(5)
        retval = sensing()
        if retval:
             if float(retval["temperature"]) > conf["THRESHOLD"]:
                 r = requests.post(url, headers=headers, data=payload)

if __name__ == '__main__':
    main()

設定ファイルには、「IDCF」チャンネルサーバーのパブリックIPアドレス、 trigger-1のuuidとtokenも指定します。

config.py
conf = {
     "IDCF_CHANNEL_URL": "210.140.162.58",
     "TRIGGER_1_UUID": "21c83792-b25e-4ae7-a627-714af57a1a4b",
     "TRIGGER_1_TOKEN": "d74ebedf",
     "THRESHOLD": 27.0
}

依存関係にある requestsパッケージをインストールします。

$ sudo pip install requests

プログラムの実行にはroot権限が必要です。

$ chmod +x bme280_data.py
$ sudo ./bme280_data.py

データの確認

IDCFクラウドの仮想マシンにログインして「IDCF」チャンネルをインストールしたディレクトリに移動してMongoDBのレコードを確認してみます。

$ cd ~/iot_apps/meshblu-compose
$ docker exec -it meshblucompose_mongo_1 mongo skynet
> db.data.find().sort({ $natural: -1 }).limit(1)
{ "_id" : ObjectId("55e55ba8a9f3a50f0013bcee"), "temperature" : "over", "ipAddress" : "210.168.36.155", "uuid" : "21c83792-b25e-4ae7-a627-714af57a1a4b", "timestamp" : "2015-09-01T08:02:48.465Z" }
>

手動実行でテスト

myThingsサーバ側からの状態確認は15分毎なので、myThingsアプリをつかって、手動で強制的にmyThingsサーバからIDCFチャンネルサーバに状態を確認しにいかせます。

myThingsアプリから組み合わせ一覧を開きます。

recipe-list.png

IDCFとGmailの組み合わせをタップして詳細画面に移動します。

gmail-action-created.png

「手動実行」ボタンをタップすると、デフォルトで15分間隔の実行タイミングを待たなくても、すぐに組み合わせを実行することができます。

recipe-executed.png

「タイムライン」画面に移動すると、手動実行の履歴が表示されています。

recipe-history.png

Gmailアプリの受信トレイを開くと、myThingsのアクションからメールが届きました。

gmail-received.png