Loading...

DIYでIoT! 「センサーを使って温度をデータベースに記録してみよう」 – SoftLayer編 –

第1回(機材準備編)と第2回(初期設定編)の続きとして、今回はSoftLayer上に構築したデータベース(以下DB)に、Raspberry Pi でセンサーから取得した温度を記録する仕組みについて解説します。

SoftLayer上にDB環境を用意

DBには、MySQLを使用します。インフラにはSoftLayerです。SoftLayerは、負荷が増えたらメモリやCPUコア数を増やすことができ、かつ月単位の課金ができるので、長期運用する際に会社の予算を取りやすいサービスです。
先ず、SoftLayerカスタマーポータルにアクセスし、下記の仮想サーバーを1つ用意します。このスペックは検証に用いたスペックですので、これ以上でも構いません。

  • デバイス:仮想サーバー 時間単位 → 長期運用であれば、月単位で課金にした方が良いです。
  • データセンター ロケーション:Tokyo
  • OS:Ubuntu14.04-64 Minimal for VSI
  • CPU:1コア × 2.0GHz
  • メモリ:1GB
  • 1番目のディスク:25GB
  • ネットワーク:100 Mbps Public & Private Network Uplinks

注文後、サーバーが起動するまで待ちます。待っている間に、Raspberry Pi に繋がっているグローバルIPを特定しましょう。
お使いのPCから有線でRaspberry Pi にブリッジ接続でつながっている場合は、PCとRaspberry Pi が同じネットワークにいますから、PCにてグローバルIP検索サービス等で対象のグローバルIPを特定することができます。
特定したグローバルIPからMySQLへの接続を許可しますので、グローバルIPが変更する可能性がある場合は、サブネットマスクでIPアドレスを範囲指定する手があります。
ここでは、125.xxx.100.xxx をグローバルIPとします。125.xxx.100.xxxからの接続に対してMySQL(ポート 3306)を許可します。

rootパスワードが割り当てられましたら、Tera Termで起動したSoftLayer上の仮想サーバーのパブリックIPに対してSSH接続を行います。接続後、サーバーのタイムゾーンを日本に変更しつつ、ファイアウォール「UFW」の設定を行います。「UFW」は、OSのUbuntuに内蔵されている標準のファイアウォールです。

# apt-get update -y
# apt-get upgrade -y
# echo "Asia/Tokyo" | tee /etc/timezone
# dpkg-reconfigure --frontend noninteractive tzdata
# ufw allow from 10.0.0.0/8 to any port 48000:48020 proto tcp
# ufw allow from 125.xxx.100.xxx to any port 3306 proto tcp
# ufw allow 22/tcp
# ufw enable
# ufw status

次にMySQL(MariaDB)をインストールします。インストールのために手順を踏む必要がありますので1つ1つ進めていきます。

# apt-get install -y software-properties-common curl sysv-rc-conf git wget unzip nano
# apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
# add-apt-repository 'deb [arch=amd64,i386] http://ftp.yz.yamagatau.ac.jp/pub/dbms/mariadb/repo/10.1/ubuntu trusty main'
# apt-get update -y
# apt-get install mariadb-server

MySQL(MariaDB)をインストールでは、管理者(root)ユーザーのパスワード登録を求められますので入力します。この後の作業で使用しますので、忘れずに覚えておくか、一時的にメモしておいてください。
DBの初期設定を行います。

# service mysql start
# mysql_secure_installation
# sysv-rc-conf mysql on

初期設定後、サーバーを再起動します。

# reboot

再起動後、Tera Termで仮想サーバーにSSH接続を行います。MySQL(MariaDB)にてデータベースを作成します。# mysql -u root -p を実行すると、先ほどのパスワードを求められます。Raspberry Pi から接続するためのデータベース、データベース用ユーザー、権限割り当てを行います。

# mysql -u root -p
MariaDB [(none)]> CREATE DATABASE raspi3;
MariaDB [(none)]> CREATE USER 'user3'@'%' IDENTIFIED BY 'raspberry';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON raspi3.* TO 'user3'@'%';
MariaDB [(none)]> FLUSH PRIVILEGES;
MariaDB [(none)]> quit

作成したデータベース用ユーザー(user3)に切り替え、データベース内にテーブルを作成します。# mysql -u user3 -p を実行すると、パスワードを求められます。ここでは、先ほど「MariaDB [(none)]> CREATE USER ‘user3’@’%’ IDENTIFIED BY ‘raspberry’;」で指定したパスワードの raspberry を使用します。

# mysql -u user3 -p
MariaDB [(none)]> use raspi3;
MariaDB [(none)]> CREATE TABLE temperature (id int auto_increment primary key,date datetime NOT NULL,value float(8, 4) NOT NULL);
MariaDB [(none)]> SHOW TABLES;
MariaDB [(none)]> SELECT id,date,value FROM temperature;
MariaDB [(none)]> SHOW COLUMNS FROM temperature ;
MariaDB [(none)]> quit

これで、SoftLayer側の準備が終わりました。次は、Raspberry Pi 側の作業になります。

Raspberry Pi 用プログラム

SoftLayer側の準備が終わりましたので、Raspberry Pi 側にTera TermでSSH接続し、プログラム言語にはPythonを用いてセンサー情報をSoftLayer側のDBに記録する仕組みを実装します。プログラムを書くにあたり、使用する温度センサー ADT7410のデータシートを読みます。とはいえ英語ですし見慣れない数式ですから、今回は、こちらのブログ記事を参考にしました。

SoftLayer上の仮想サーバー内に構築したMySQL(MariaDB)に接続するプログラムをPythonで書きます。
先ず、python -V コマンドを実行し、Raspberry Pi 上で使用するPythonのバージョンを確認します。この記事作成時点では、Python 2.7.9 を使用しています。次に、プログラムを格納するディレクトリ(sensor)を作成し、作成したディレクトリに移動します。

$ python -V
$ mkdir sensor
$ cd sensor

作成したディレクトリに移動したら、エディタのnanoを用いて、softlayer.py という名称でPythonプログラムを作成します。

~/sensor $ nano softlayer.py

nano softlayer.pyを実行すると、すぐに入力画面が表示されますので、下記コードをコピー&ペーストします。

# -*- coding: utf-8 -*-

import MySQLdb
import smbus
import time

if __name__ == "__main__":

    i2c = smbus.SMBus(1)
    address = 0x48

    data = i2c.read_i2c_block_data(address, 0x00, 2)
    value = (data[0] << 8 | data[1]) >> 3
    if(value >= 4096):
       value -= 8192
    temp_value = value * 0.0625

    connector = MySQLdb.connect(host="xxx.xxx.xxx.xxx", db="database name", user="userXXX", passwd="password", charset="utf8")
    cursor = connector.cursor()


    sql = u"insert into temperature(`id`,`date`,`value`) values(0,now(),%s)" % temp_value
    cursor.execute(sql)
    connector.commit()

    cursor.close()
    connector.close()

    print(temp_value)

コピー&ペースト後、各項目を書き換えます。

  • host=”xxx.xxx.xxx.xxx” は、xxx.xxx.xxx.xxxを、SoftLayer上で稼働中の仮想サーバーのパブリックIPに変更
  • db=”database name” は、database nameを先に作成したデータベースの raspi3 に変更
  • user=”userXXX” は、userXXXを user3 に変更
  • passwd=”password” は、password を raspberry に変更

各項目を先に作成したデータベース情報に合わせます。
[変更前]:MySQLdb.connect(host=”xxx.xxx.xxx.xxx”, db=”database name”, user=”userXXX”, passwd=”password”, charset=”utf8″)
[変更後]:MySQLdb.connect(host=”パブリックIP”, db=”raspi3″, user=”user3″, passwd=”raspberry”, charset=”utf8″)
となります。
変更後、Ctrl キー + x キーを押し、yキーで保存します。変更と保存が終わったら、下記を実行し実際に動かしてみましょう。

~/sensor $ sudo python softlayer.py
27.1875

温度が表示されれば、成功です。Raspberry Pi では、sudoをつけないとエラーになります。

10分おきに自動実行するにように設定

次に、pwdコマンドを実行し、softlayer.pyがあるディレクトリの位置を確認します。

~/sensor $ pwd
/home/pi/sensor

softlayer.pyは、/home/pi/sensor にあることがわかりました。この情報を元に、crontabコマンドにて、10分おきに作成したプログラムを自動実行するようにします。

~/sensor $ crontab -e

を実行し、末尾に */10 * * * * sudo python /home/pi/sensor/softlayer.py を記述します。記述後、Ctrl キー + x キーを押し、yキーで保存します。

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command
*/10 * * * * sudo python /home/pi/sensor/softlayer.py

先ほどのpwdコマンドで、作成したプログラム「softlayer.py」が、「/home/pi/sensor」にあることがわかりました。crontabには、プログラムの実行に必要なパスを記述する必要があります。また、10分置きに実行するには、*/10 * * * * と記述しなければいけません。10分おきに、「/home/pi/sensor」にある「softlayer.py」を実行するという意味で、*/10 * * * * sudo python /home/pi/sensor/softlayer.py と記述し、保存しています。
もし、1時間おきに実行であれば、0 */1 * * * とすると、毎時0分に1時間おきにプログラムを実行という意味になります。
crontab -l を実行し、記述内容が正しいか確認します。その後、Raspberry Pi を再起動します。

~/sensor $ crontab -l
~/sensor $ sudo reboot

ここまでの作業により、SoftLayer上で稼働する仮想サーバーのファイアウォールで、ポート番号 3306に接続を許可したグローバルIPに、Raspberry Pi が繋がっている限りにおいて、Raspberry Pi に接続した温度センサーで温度を10分おきに取得し、SoftLayer上の稼働する仮想サーバーのデータベースに記録し続けます。プログラムやRaspberry Pi の設定を変更する場合は、再度、Tera TermにてRaspberry Pi 側にSSH接続します。

なお、記録内容を確認するには、Tera TermからSoftLayer上で稼働する仮想サーバーにSSH接続し、下記コマンドを実行します。使用するデータベース用ユーザーは、取得した温度を格納しているデータベースのものを使用します。

# mysql -u user3 -p
Enter password:

MySQL(MariaDB)に接続後、温度を格納しているデータベース(raspi3)に切り替え、SQL文(SELECT~)を実行すると、格納された温度と取得日時の一覧が表示されます。

MariaDB [(none)]> use raspi3;
MariaDB [raspi3]> SELECT id,date,value FROM temperature;

実行例

次回について

今回は、センサーで取得した温度をSoftLayer上に構築したデータベースに格納するまでを取扱いしました。基本的には、ここまで出来れば、BI(ビジネス・インテリジェンス)ソリューションで可視化ということになります。BIソリューションですと話が大きくなりやすいので、次回は、JDBCとGoogleのサービスを用いてシンプルに可視化する方法についてお話する予定です。たとえば、下図のように温度をグラフとしてスマートフォンから確認することができるようになります。

次回(第4回)の記事はこちらからご覧になれます。