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で動作を確認しています。