IoT 入門~Raspberry Pi を使って温度センサーを kintone に連携させてみよう!

著者名: 山下 竜 (External link)

目次

昨今、機械やセンサー等がネットワークに接続され、クラウドサービスと連携する Machine to machine(M2M、機器間通信)や Internet of things(IoT、モノのインターネット)が注目を集めています。
その考え方や一部分野での適用は以前からあったものですが、近年の「ネットワーク回線構築の低コスト化」や「ハードとソフトのボーダレス化」等も相まって、たとえば次のようなさまざまな分野での活用が進んでいます。

  • ヘルスケア
  • 交通
  • 産業用機器・設備の保守業務の効率化
  • 農業などにおける環境管理の自動化

さらに、M2M と「2H(to human)」を組み合わせる Machine to machine to human(M2M2H) (External link) という取り組みがあります。
これは、M2M で集まったデータをチーム内に共有し、ワークフロー化して業務プロセスの改善を目指す取り組みです。
kintone の活用事例もあり、kintone の非オフィス業務での活用方法の例として広がりを見せています。

活用事例:太陽光発電所のM2Mデータをkintoneで集約・管理するYKD (External link)
動画:【サイボウズ】kintone導入事例 八街太陽光発電所(横浜環境デザイン様) (External link)

今回は、M2M2H の入門として、電子工作でよく用いられている Raspberry Pi(コーディングは Python)を使ってセンサーの値読み出しから、REST API による kintone への連携を試みたいと思います。
これは、私自身が「 kintothon#1 in Okinawa (External link) (kintone の Hackathon)」で取り組んだ内容の一部書下ろしでもあります。

環境

  • Raspberry Pi Model B Revision 2 以上(RASPBIAN とネットワークの設定を終えた状態)
  • I2C 温度センサー(ADT7410)

できあがりイメージ

温度データですので、時系列グラフを設定すると次のような画面になります。

何やらカメラらしきものも実装されていますが、これについては次回お届けしたいと思います。

アプリの準備

次のフィールドを含むアプリを準備してください。

フィールド名(例) フィールドコード フィールドタイプ
温度[℃] tempC 数値

Raspberry Pi の準備

ここでは Raspberry Pi のハード的な準備を紹介します。
各項目の括弧内にはコマンドを記載しています。

  1. Raspberry Pi とセンサーを結線します。
    Raspberry Pi 側とセンサー側の対応を見ながらブレッドボードにジャンパー線を差し込んでいきましょう

    図中線色 Raspberry Pi 端子 センサー端子 内容
    3.3V VDD センサー電源線
    GND GND センサー接地線
    SDA SDA データ線
    SCL SCL クロック線
  2. /etc/modulesi2c-dev を追記します。

    1
    
    sudo vi /etc/modules
  3. /etc/modprobe.d/raspi-blacklist.conf で、blacklist i2c-bcm2708 をコメントアウトします。

    1
    
    sudo vi /etc/modprobe.d/raspi-blacklist.conf
  4. ここで、設定有効化のため一度再起動します。

    1
    
    sudo reboot
  5. I2C 動作確認ツールをインストールします。

    1
    
    sudo apt-get install i2c-tools
  6. センサーの動作確認を行います。
    センサーを外した状態と付けた状態で比較すると、今回使っているセンサーの判別がしやすいです。
    チャンネルは、今回対象としている Rev.2 以上の場合には 1、Rev.1 の場合には 0 とします。

    チャンネルを 1 としてコマンドを入力すると、アドレスは、「0x48」であることがわかります。

    1
    
    sudo i2cdetect -y {channel}
  7. Python の I2C ツールの「python3-smbus」をインストールします。

    1
    
    sudo apt-get install python3-smbus

以上で Raspberry Pi で I2C センサーを使うための準備は完了です。

kintone 連携用 Python3 ソースコード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# Raspberry Pi 連携
# Copyright (c) 2014 Cybozu
#
# Licensed under the MIT License
# https://opensource.org/license/mit/
# coding: utf-8

import smbus
import time
import requests

INTERVAL = 60*1 # 測定間隔(秒)
ADDRESS = 0x48 # ADT7410のアドレス
CHANNEL = 1 # Rasbperry Piのチャンネル

SUBDOMAIN = "{subdomain}" # kintoneのサブドメイン({subdomain}.cybozu.com)
APP_ID = "{app ID}" # kintoneのアプリID
API_TOKEN = "{API token}" # kintoneのAPIトークン

class ADT7410:
    def __init__(self, address, channel):
        self.address = address
        self.channel = channel

    # センサー(ADT7410)の値読出し
    def readValue(self):
        try:
            data = smbus.SMBus(self.channel).read_i2c_block_data(self.address, 0x00, 2)
            temp = (data[0] << 8 | data[1]) >> 3 # データ形成
            if(temp >= 4096): # 温度が0未満の場合
                temp -= 8192
            value = temp * 0.0625 # 13bitの場合の係数
            return value
        except Exception as e:
            print(e) # エラー出力
            return None

    # kintoneへのPOST
    def registToKintone(self, subdomain, appId, apiToken):
        url = "https://" + subdomain + ".cybozu.com/k/v1/record.json"
        headers = {"X-Cybozu-API-Token": apiToken, "Content-Type": "application/json"}
        record = {"tempC": {"value": self.readValue()}}
        params = {"app": appId, "record": record}
        response = requests.post(url, json=params, headers=headers)
        return response

sensor = ADT7410(ADDRESS, CHANNEL)

while True:
    value = sensor.readValue()
    if value is not None:
        print("Temperature: %6.2f [Deg. C.]" %value)
        sensor.registToKintone(SUBDOMAIN, APP_ID, API_TOKEN)
    time.sleep(INTERVAL)

Python ソースコードの説明

今回は Raspberry Pi の「Pi」が「Python」に由来していることから、Python で連携スクリプトを記述しました。
中身は次の 4 部構成になっています。

  • I2C(SMBUS)の設定
  • センサーの値読み出し
  • kintone REST API 連携
  • ループによる定期実行

全項目、簡単に説明します。

I2C(SMBUS)の設定

I2C でセンサーをコントロールするためには Raspberry Pi のチャンネルとセンサーのアドレスを指定する必要がありますので、これらを引数としておきます。
また、クラス名は今回のセンサーの型式「ADT7410」としておきます。

Raspberry Pi Model B Revision 2 以上(B+含む)はチャンネル 1 で、ADT7410 のアドレスは先に確認したとおり 0x48 ですので、初期化時にこれらの値を代入しておきます。

センサーの値の読出し

計算式は データシート (External link) を見ながら与えていくことになりますが、ADT7410 の特徴を簡単に押さえておきましょう。

  • 標準分解能 13bit(1bit は符号ビット、12bit が情報ビット)を利用
  • 13bit 係数は 0625(1/16)
  • 換算式は、データシート P12 を参照

read_i2c_block_data() 関数でレジスタの値を読み出します。
self.address は I2C センサーのアドレス(今回は 0x48)、0x00 は読み出す先頭レジスタのアドレス、2 は読み出すビット数を表しています。

kintone REST API 連携

kintone REST API の単一レコードの登録(GET/record.json)を実行します。
また、認証には API トークンを利用しました。

Python で HTTP リクエストするためにはいくつかモジュールがありますが、今回は「requests」を使うことにします。

1
sudo apt-get install python3-requests

ループによる定期実行

定期実行は今回のようにプログラム中に入れてしまう方法(一種の常駐アプリ)と crontab を使った方法が考えられます。
今回は組込みらしくプログラム中に入れる方法を採用しました。
こうした場合には、常駐アプリの死活監視を crontab に任せたりしますが、ここでは割愛させていただきます。

Python スクリプトの実行

先に紹介したサンプルコードを「sample.py」として保存したとします。
I2C デバイスへのアクセスが必要なため、先頭に「sudo」をつけて実行します。

1
sudo python sample.py

最後に

今回は、Raspberry Pi を使って、センサーの値の読出しと kintone REST API による取得値のデータ連携を実施しました。
多少の準備は必要ですが、M2M2H も意外と手軽にできることがお分かりいただけたのではないでしょうか?

I2C 対応のセンサーは種類豊富で比較的安価に入手できますし、複数のセンサーを組み合わせた実装も可能です。
電子工作とクラウドとの連携、M2M2H に興味をお持ちの方はぜひお試しいただければと思います。

Raspberry Pi やセンサー、掲載しているスクリプトはサポートの対象外です。

次回は Raspberry Pi にカメラをアタッチして kintone に静止画をアップロードしてみたいと思います。

information

この Tips は、2014 年 12 月版 kintone で動作を確認しています。