IoT検定対策2章 産業システム(2/2)

産業システム(2/2)

産業界のIoT

  • インダストリー4.0
    • ドイツ政府の技術戦略。高度スマート工場の実現によるビジネスモデル創出の取組み
    • 「OPC(Open Platform Communications)」は1996年にMicrosoftと大手制御機器メーカーが共同で策定した工場機器の連携インターフェイス規格。現在、この規格は「OPC Classic」と呼ばれており、後継の「OPC-UA」が主流である。
    • インダンストリー4.0で工場内データ連携に使用する通信規格には、「OPC-UA(OPC Unified Architecture)」がある。日本国内では同じ規格として「ORiN(Open Resource interface for the Network)」がある。
  • インダストリアル・インターネット
    • 製造業の取組みであるインダストリー4.0に対し、これも含めたエネルギー・ヘルスケア・製造業、公共、運用を対象としたグローバルネットワークによる取り組みが、「インダストリアル・インターネット」である。
    • 世界100社以上の参加企業があり、GE(General Electric)、IntelCiscoIBMAT&Tが主導。
    • ソフトウェア基盤は、GE社の「Predix」というクラウド上のIoTプラットフォームを使用。
    • センサーデータを無構造の「データレイク」に蓄積し、そのデータを分析することで、運用・保守や、次の製品やサービスの開発に活かす。
  • スマートコンストラクション
    • 2015年に日本の建設機械メーカー「コマツ」の主導により開始された、建設工事現場におけるICTを活用した取組み。労働力減少への対応や、現場の安全性確保のほか、ベテラン技術者からの技能承継を実現する。
    • 同社では1996年から「KOMTRAX」というIoTプラットフォームが自社開発されており、世界的にも有名なIoT事例である。ブルドーザなどの建設機器にGPSや通信機器を装備し、Webを介して遠隔で稼働状況・位置・燃料残数などを確認しつつ、遠隔操作で稼働・停止を制御できる。

海外におけるIoTプロジェクト

  • 主な海外プロジェクトの一覧
    • ドイツ:インダストリー4.0
    • フランス:インダストリー オブ ザ フユーチャー
    • インド:スマートシティー 建設プロジェクト
    • 中国:中国製造2025
    • 日本:日本版インダストリー4.0
    • シンガポール:スマート・ネーション・プラットフォーム
    • アメリカ:インダストリアル・インターネット
      f:id:camelrush:20200816011257p:plain

IoT関連の標準規格

  • AllJoyn
    • QualComm社が主導している団体Allseen Allianceが開発したホームネットワークの相互通信規格。現在はOCFに合流。
    • 通信はAES128、PSK、ECDSAによりセキュア化可能
    • 機器へのアクションや制御メッセージはXMLで定義される
  • HomeKit
    • Apple社が開発したホームネットワークの通信規格。iOS機器(iPhoneiPadApple TVなど)から、HomeKit対応機器を統合ネットワーク管理する。
  • Thread

    • Google社参加のNet Labs社が開発した家電IoT向けの無線通信規格。近距離・省電力無線通信が主目的。
    • OSI参照モデルでは3層(Network)、4層(Transport)に該当
    • IEEE 802.15.4(WirelessPAN)上のIPv6(6LoWPAN)を基盤とするIPネットワーク。
    • Wifiネットワークとは変換ノードを介して相互に通信することが可能。
  • 機器に関する安全規格

    • IEC61508:機能安全(Functional Safety)について規定
    • IEC62304:医療機器ソフトウェア開発・保守に関する「安全性の向上」を目的とした要求仕様集。ISO19471、ISO13485と併用。
    • ISO14971:医療機器のリスク管理
    • ISO26262:IEC61508の自動車版(機能安全の規定)
  • 情報セキュリティマネジメントに関する規格

    • ISO/IEC 27000シリーズ:情報セキュリティにおける管理基準の策定。ISMSを組織内に確立することが目的。

IoT検定対策2章 産業システム(1/2)

産業システム(1/2)

エネルギー関連のIoT

  • 通信機能付きの電気メーター(電力計)を「スマートメーター」と呼ぶ
  • これを家庭内で可視化して電力消費状況などを確認できる家が「スマートハウス」である
  • さらに商用電力からの享受や家庭内の太陽光発電とのバランスを調整するのが「スマートグリッド」である。
  • 家庭内の電力管理を行うシステムが「HEMS(Home Energy Management System)」である。
  • ガスコジェネレーションシステム:エコシステム。排出されるガスエネルギーの中から再利用可能な排熱を用いて発電を行ったり給油を行うシステム。
  • HEMSで使うネットワークのことを「HAN(Home Area Network)」と呼び、日本では通信規格 にECHONET Lite(OSI5層以上)、無線通信方式には Wi-Sun が採用されている。
  • スマートメーターには、A~Cルートが存在する。
    • Aルート:電力会社から家のスマートメーター迄。30分ごとの自動検針、メーターの遠隔操作。
    • Bルート:スマートメーターから家庭内。HEMSコントローラから電力使用量取得。
    • Cルート:電力会社から他社に電力を供給するルート f:id:camelrush:20200814231415p:plain
  • Aルートを使用し、遠隔で電力使用状況を検針する仕組みがAMI(Advanced Metering Infrastructure)であり、光回線・PLC、無線が用いられる。電力会社にはAMIによって取得したデータを管理するMDMS(Meter Data Management System)が存在する。

身近なIoT

  • スマートホーム
    • スマートホーム」は照明調整や施錠管理など、生活を便利するための「賢い家」のこと。エネルギー管理を重点に置いている「スマートハウス」とは異なる。次世代自動車をConnectedCarと呼ぶように、スマートホームはConnectedHomeとも呼ばれる。
    • 室内温度調節「Nest」とは、Google社が買収した米Nest Lab社が発売したサーモスタット製品である。利用者の生活パターンを学習し、自動的に温度調節を行い、光熱費20%~30%の節電効果がある。
    • 代表的なスマートホームのプラットフォームにAppleの「Home Kit」と、Nest Labs社の「Brillo」がある。それぞれ iPhoneAndroidアプリケーションを使ってスマート電球やスマートロックなどの家庭用機器の制御を可能とする。
  • ヘルスケア
    • 2015年から「ストレスチェック制度」が制定。従業員50人以上の事業所が行う必要があり、このチェックにウェアラブルの収集データを活用できる。
    • NEDO北海道大学東京大学が協力し、2016年にヘルスケアIoTコンソーシアムを設立。健康データ流通横断プラットフォームの開発を進めている。
    • 現在は個々の病院で管理されている医療や介護のデータについて、マイナンバーを媒介に共有化を図り、ビッグデータ分析によって疾病の早期発見や傾向把握を進める動きがある。これらを交換・共有するための規約に、国内では「SS-MIX」米国では「HL7」がある。
    • 「HealthKit」はApple社が提供するヘルスケア機器に使用されるアプリケーションプラットフォームである。体重計、エアロバイク、ウォーキングマシンの運動量の管理を行い、病院アプリケーションと連携する。
    • 「GoogleFit」もまた、同様の健康管理データの管理サービスであり、ウォーキングやランニングの歩数や時間データをスマートフォンで記録できる。
  • コネクテッドカー、自動運転、テレマティクス

    • テレマティクス」とは「コネクテッドカー」の前身とも言える技術。2つの大きな違いはネットワークへの接続・通知形態であり、テレマティクスはメールなどのプル型なのに対し、コネクテッドカーは常時接続である。テレマティクスはCANデータをGPS情報などと併せてセンターに送信し、車両走行状況や位置をセンターで一元管理することができた。
      • 「CANデータ」は「Controlller Area Network データ」の略であり、自動車をはじめFA産業機器の故障監視や燃費計測に用いられる制御データの集積である。
    • コネクテッドカー用のOSとしてApple社の「CarPlay」や、Google社の「Android Auto」が提案されている。
    • 「SENSORIS」は、ドイツのHere社が提案した、運転時に得られた渋滞や障害物データを車両からクラウドに収集するインターフェイスの標準化規格である。
    • 「ITS」は「Intelligent Transport Systems」の略であり、高度道路交通システムとも呼ばれる、クルマ同士で情報交換し事故防止や交通渋滞の解決を図る交通システムである。
    • 自動運転のレベルは米国のNHTSA(国家道路交通安全局)が下表のとおり5段階で定めている。
      f:id:camelrush:20200814221443p:plain
  • 農業のIoT

    • 植物工場を活用した農業の自動化。植物工場には光合成の実現にあたり、「完全人工光型」と「太陽光利用型」、その両方の併用型がある。「完全人工光型」は屋内でのLED照明等を活用し、天候不順、病害虫、土壌の連鎖障害などの影響を受けず、安定した生産が可能である。
    • スマート農業には、以下のような特徴がある。
      • 農業機械の自動運転、自動走行[超省力・大規模生産]
      • 過去データを活用した精密農業[作物の能力を最大化]
      • 荷物積み下ろし等の重労働の軽量化(アシストスーツ)、水管理自動化[きつい・危険な作業からの解放]
      • 技能承継。栽培ノウハウのデータ化による成果均一化[取り組み易い農業の実現]
      • 生産情報の共有、産地と消費者を直結[先進的な流通の実現]

IoT検定対策1章 戦略とマネジメント

IoTの資格取得について

これまでの経験値と、体系知識の学びを目指して、春ごろから、IoTの技術資格習得を考えていました。2020年現在、国内には2つのIoT試験が存在します(【】は私の受験予定レベル)

  • IoTシステム技術検定 【基礎】
    • モバイルコンピューティング推進コンソーシアム(MCPC)が主催
    • どちらかというと技術力に特化した内容
    • 試験日は、年2回 固定日
  • IoT検定 【レベル1】
    • IoT検定制度委員会が主催
    • どちらかというとIoTの活用力(IoTコーディネータ)
    • 試験は週1程度、プロメトリックが支援

最初、「IoTシステム技術検定」を受験することを考えていたのですが、コロナ禍の影響で今年度の試験が中止となってしまいました。鞍替えというわけではないのですが、停滞しているのもイヤだったので、8月~9月に「IoT検定」を受験する予定です。

勉強は、以下の書籍を基に進めていきます。

以下、勉強で知らなかった・分からなかった箇所をしっかりアウトプットして、記憶に定着させていきたいと思います。

戦略とマネジメント

戦略・企画

  • ファイブフォース分析

    • 企業の現状把握において競争状況を分析するためのフレームワーク。ライバル動向を分析するだけではなく、5つの競争要因で分析すべきという考え方。
    • マイケル・ポーターの『競争の戦略』
      1. 新規参入者 : 業界に新たに参入する可能性のある企業等
        • 「海外大手アパレル企業の進出」
      2. 競争業者(自社はこの中にあると考える) : 競合同士の敵対関係
        • 「値引き販売の常態化」
        • 「テレビCM中心とした広告宣伝合戦」
        • 「海外展開」
      3. 代替品 : 代替可能な製品やサービス
        • 「インターネット通販の普及」
      4. 買い手 : 顧客
        • 「ブランドロイヤリティの低下」
        • 「不要不急ものは購入しない」
        • 「良質なものを選んで購入」
      5. 供給業者・売り手 : 原材料やサービスを提供する企業等
        • 「円安による値上げ要請」
    • マクドナルドを例にした場合
      f:id:camelrush:20200813092722p:plain
  • バリューチェーン(価値連鎖)

    • 原材料を加工し、最終製品を組み立てて販売し、購入者に届けるという一連のプロセスのことを指す。
    • 主活動:購買・製造・出荷・販売・アフターサービス
    • 支援活動:企業インフラ構築、人材管理、技術研究開発
  • ブルーオーシャン戦略

    • レネ・モボルニュW・チャン・キムの『ブルー・オーシャン戦略』
    • 企業間の競争が激しい事業領域「レッド・オーシャン」に対し、比較的緩い事業領域を「ブルー・オーシャン」と定義。
    • 低コスト化のために一般機能を減らし、付加価値を増やすことが必要。
  • アンゾフの成長マトリクス

    • イゴール・アンゾフの『企業戦略論』
      • 企業の長期的な成長戦略を決めるためのツール
      • 「既存技術と新規技術」「既存市場と新規市場」から成るマトリクス
        1. 市場浸透戦略(既市/既技):高付加価値・営業力・ブランド力が必要(下図①)
        2. 市場開拓戦略(新市/既技):これまで利用していない層への売込み(下図③)
        3. 新商品対策戦略(既市/新技):近年では機能差別化が難しく、難易度が高い(下図②)
        4. 多角化戦略(新市/新技):組織改革・新たな原資が必要。買収(MA)などの戦略(下図④)
      • 富士フィルムを例にした場合
        f:id:camelrush:20200813094405p:plain
  • プロセス・イノベーション

    • これまでのやり方や手法をすべて新しくすることでイノベーションを起こすこと
    • 人工知能を使ってカスタマイズ製品を効率よく大量に作り出すマス・カスタマイゼーションなど
  • イノベーションのジレンマ

  • スマート製品のケイパビリティ

    • スマート製品に必要となる(組織的・システム間連携)能力
      1. モニタリング
      2. 制御
      3. 最適化
      4. 自律性
    • 上記は独立したものではなく、それぞれが前項の段階を備えていること。

プロジェクト・マネジメント

  • PMBOK
    • Project Management Body Of Knowrage の略
  • CMMI
    • Capability Maturity Model Integration の略
    • 組織のプロセス管理の成熟度を評価する指標
    • 一様の指標を定めているだけではなく、成熟度3以上では自主改善を進めるもの(PDCA、ISO的な?)
      1. 成熟度1. Initial:場当たり的、環境が安定しない
      2. 成熟度2. Managed:基本的な管理。一部の組織で成功を反復して実現。
      3. 成熟度3. Defined:組織内でプロセス標準を確立。自主改善。テーラリング指針でプロセスを確立 ※テーラリング:「仕立て直し」の意。組織規程の指針やプロセスを基に、プロジェクトに応じた具体的な標準を策定すること。
  • リーン思考
    • 「ムダの排除」を目指したトヨタの「かんばん方式」がベース。そのうえでリーン思考は以下の考えが基本。
      • 「顧客目線の製品価値定義」
      • 「価値創造以外のムダ排除」
      • 「役割分担から製品担当へ」
      • 「オーダー生産」
      • 「永続的改善追及」
    • 「売れない製品を大量に生産して不良在庫を抱える」ようなリスクを回避。
  • QC手法

人材育成と企業間連携

  • スキル標準
    • ITSSITスキル標準):IT関連の職種と専門分野ごとに求められるスキルの規定
    • ETSS(組み込みスキル標準)
    • UISS(情報システムユーザースキル標準):情報システムユーザー企業向け、システム利用に関する人物像と必要スキルの規定
  • 企業連携
    • 垂直統合:いち企業が主体となり、サプライチェーン(調達、販売、サービス)に沿って得意な企業を統制した連携を行う。
    • 水平分業:複数の企業が集まり、得意な分野ごとに分業して目的達成すを目指す。協調が必要。
    • 垂直分業:サプライチェーン(調達、販売、サービス)の上下で別々の企業が分業する。
  • クラウドソーシング
    • 不特定多数から特定業務の従事者を募るサービス
    • ランサーズやクラウドワークスなどが該当
    • トラブル防止のため、契約時に発注側は運営サイトに対し、仮払い状態で預ける運用が一般的。
  • IoT推進コンソーシアム
    1. 目的1:IoTに関する技術の開発・実証及び標準化等の推進
    2. 目的2:IoTに関する各種プロジェクトの創出及び当該プロジェクトの実施に必要となる規制改革等の提言等を推進

釣り竿センサーの検知結果をLINEへ通知

キャストした釣り竿の「引き」をセンサーで検知し、一定の敷居値を超えた場合に、LINEにメッセージを通知する内容を実装しましたので、まとめてみました。 f:id:camelrush:20200617233215p:plain

加速度センサーの実装

基本的な機器の実装と、加速度の取得は、以下の記事を参考にしてください。今回はx,y,z軸への移動距離を「振動のふり幅」とするので、取得した値のうち、Acceloretor値を使用します。 camelrush.hatenablog.com

システム構成図

今回の構成図は以下の通りです。MobilePC上でグラフを表示しつつ、スマホ(SmartPhone)のLINEにAPI通知をPushメッセージを通知します。

f:id:camelrush:20200617235834p:plain

LINE「Messaging API」の使用

LINEのAPIのうち、今回は「Messaging API」を使用します。作成したチャネルのエントリポイント(WebHook)に対して、JSON形式でHTTPリクエストをPOSTすると、あらかじめチャネルを登録しているユーザに対してメッセージを発信することができます(発信先は、Toパラメータで個別指定ができますが、今回はブロードキャスト(全体)発信とします)詳細の仕様は以下に書かれています。
Messaging APIリファレンス | LINE Developers

LINEアカウントがあれば、LINE Developersにログインすることで、フリープランのAPIチャネルを使用することができます。

※アカウントの登録方法、チャネルの作成方法は省略します。

プログラム

RaspberryPiには、以下のPythonプログラムを配置します。

  • mqttAccelerometer.py
from devices.accelerometer import AccelerometerMPU6050 as MPU6050
import paho.mqtt.client
import ssl
import asyncio
import json
import time
import datetime
import requests
import random

# Mqtt Define
AWSIoT_ENDPOINT = "[AWS IoT Entry Point]"
MQTT_PORT = 8883
MQTT_TOPIC_PUB = "mqttAccelerometer"
MQTT_ROOTCA = "./awscert/AmazonRootCA1.pem"
MQTT_CERT = "./awscert/xxxxxxxxxxx-certificate.pem.crt"
MQTT_PRIKEY = "./awscert/xxxxxxxxxxx-private.pem.key"

LINE_THRESHOLD = 5
MSG_LIST = ['ヒットしてない!?',
            '来てる来てるw',
            'Fish on!',
            'Gone!']

def mqtt_connect(client, userdata, flags, respons_code):
    print('mqtt connected.') 
    # Entry Mqtt Subscribe.
    client.subscribe(MQTT_TOPIC_SUB)
    print('subscribe topic : ' + MQTT_TOPIC_SUB) 
 
def mqtt_message(client, userdata, msg):
    # Get Received Json Data 
    json_dict = json.loads(msg.payload)
    # if use ... json_dict['xxx']

def line_post(asum,tmstr):
    access_token = [LINE API Access Token]
    headers = {'Authorization': 'Bearer {}'.format(access_token)}
    uri = "https://api.line.me/v2/bot/message/broadcast"
    msg = random.choice(MSG_LIST) + "\n" + tmstr + "(" + asum + ")"
    print(msg)
    item_data = {
            "messages":[
                {
                    "type":"text",
                    "text":msg 
                }
            ]
        }
    r_post = requests.post(uri, headers=headers, json=item_data)
    print(r_post)
    
# Publish Loop
async def pub_loop():
    acmeter = MPU6050()
    sendtime = time.time()
    while True:
        # get Sensor data
        temp = acmeter.get_temp()
        ax, ay, az = acmeter.get_accel()
        gx, gy, gz = acmeter.get_gyro()
        tm = datetime.datetime.now()
        asum = abs(ax)+abs(ay)+abs(az)
        
        print('ax:{0:> .6f} ,ay:{1:> .6f} ,az:{2:> .6f} ,asum:{3:> .6f}'.format(ax,ay,az,asum))
        json_msg = json.dumps({"dt":tm.strftime('%Y-%m-%d %H:%M:%S.%f'),"ax":ax,"ay":ay,"az":az,"asum":asum,"threshold":LINE_THRESHOLD,"gx":gx,"gy":gy,"gz":gz,"temp":temp})

        # Line Message Send
        if (asum > LINE_THRESHOLD):
            if (time.time() - sendtime) > 1:
                sendtime = time.time()
                line_post('G:{0:>.2f}'.format(asum),
                    tm.strftime('%H時').lstrip("0") + 
                    tm.strftime('%M分').lstrip("0") + 
                    tm.strftime('%S秒').lstrip("0"))

        # mqtt Publish
        client.publish(MQTT_TOPIC_PUB ,json_msg)
        time.sleep(0.01)

# Main Procedure
if __name__ == '__main__':
    # Mqtt Client Initialize
    client = paho.mqtt.client.Client()
    client.on_connect = mqtt_connect
    client.on_message = mqtt_message
    client.tls_set(MQTT_ROOTCA, certfile=MQTT_CERT, keyfile=MQTT_PRIKEY, cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)

    # Connect To Mqtt Broker(aws)
    client.connect(AWSIoT_ENDPOINT, port=MQTT_PORT, keepalive=60)

    # Start Mqtt Subscribe 
    client.loop_start()

    # Start Publish Loop 
    loop = asyncio.get_event_loop()
    loop.run_until_complete(pub_loop())

加速度センサー「MPU6050」を制御する処理は、以下のとおりとなります。

  • devices/accelerometer.py
from abc import ABCMeta
import smbus
import math
from time import sleep

# MPU6050 Register Map
DEV_ADDR = 0x68
ACCEL_XOUT = 0x3b
ACCEL_YOUT = 0x3d
ACCEL_ZOUT = 0x3f
TEMP_OUT = 0x41
GYRO_XOUT = 0x43
GYRO_YOUT = 0x45
GYRO_ZOUT = 0x47
PWR_MGMT_1 = 0x6b
PWR_MGMT_2 = 0x6c   

class AbstractAccelerometer(metaclass=ABCMeta):
    def __init__(self ,devadr):
        self._devadr = devadr
        self._bus = smbus.SMBus(1)
        acc_conf = self._bus.read_byte_data(self._devadr ,0x1C)
        acc_conf = acc_conf | 0x18
        self._bus.write_byte_data(self._devadr, 0x1C, acc_conf)

    def startup(self ,pwr_mgmt_adr):
        self._bus.write_byte_data(self._devadr, pwr_mgmt_adr, 0)

    def _read_word(self ,adr):
        high = self._bus.read_byte_data(self._devadr, adr)
        low = self._bus.read_byte_data(self._devadr, adr+1)
        val = (high << 8) + low
        return val

    def read_word_sensor(self ,adr):
        val = self._read_word(adr)
        if (val >= 0x8000):         # minus
            return -((65535 - val) + 1)
        else:                       # plus
            return val

class AccelerometerMPU6050(AbstractAccelerometer):

    def __init__(self):
        super().__init__(DEV_ADDR)
        super().startup(PWR_MGMT_1)

    def get_temp(self):
        temp = super().read_word_sensor(TEMP_OUT)
        x = temp / 340 + 36.53      # data sheet(register map)記載の計算式.
        return x

    def get_gyro(self):
        x = super().read_word_sensor(GYRO_XOUT)/ 131.0
        y = super().read_word_sensor(GYRO_YOUT)/ 131.0
        z = super().read_word_sensor(GYRO_ZOUT)/ 131.0
        return [x, y, z]

    def get_accel(self):
        #x = super().read_word_sensor(ACCEL_XOUT)/ 16384.0
        #y = super().read_word_sensor(ACCEL_YOUT)/ 16384.0
        #z = super().read_word_sensor(ACCEL_ZOUT)/ 16384.0
        x = super().read_word_sensor(ACCEL_XOUT)/ 2048.0
        y = super().read_word_sensor(ACCEL_YOUT)/ 2048.0
        z = super().read_word_sensor(ACCEL_ZOUT)/ 2048.0
        return [x, y, z]

結果

以下のとおり、加速度センサーのふり幅(水色)が敷居値(灰色:5.0G)を超えた場合だけ、LINEに通知が送られてきました。

f:id:camelrush:20200617233527g:plain

べからず

LINE API は、フリープランのうちは、60メッセージ/日、合計でも1.000メッセージが上限であり、それ以上を送ると通知してくれなくなります。センサーの通知メッセージをノーウエイトで送るとあっという間に上限に達し「429 Too Many Requests」を応答するようになりますので、注意してください。

chart.jsで加速度・ジャイロセンサーを可視化してみた

Kibana可視化と問題点

前回、温湿度センサーのデータをOSSのElasticSearchとKibanaを使ってグラフ化しました。

camelrush.hatenablog.com

しかし、このツールはグラフの描画間隔の最小単位で1秒となっており、リアルタイムな描画ができませんでした。

chartjs-plugin-streaming

加速度センサーなど、プロッタのようなグラフ描画を行う方法を調べたところ、OSSとして、chart.jsの派生プラグインである「chartjs-plugin-streaming」がgitに公開されていました。

https://nagix.github.io/chartjs-plugin-streaming/ja/

描画サンプル

f:id:camelrush:20200526061709g:plain

加速度センサーの可視化

上記を基にして、加速度センサーから取得した駆動データを、グラフにプロットすることにします。
今回、計測には以下の慣性センサーを使用します。製品仕様として、3軸加速度+3軸角速度(ジャイロ)のセンサーを搭載した製品となっています。

慣性センサーの知識

慣性センサーとはセンサーの種類を示す大きな分類であり、具体的な計測対象に応じて「加速度」を計測する「加速度センサー」、「角速度」を計測する「ジャイロセンサー」が存在します。

加速度センサー

加速度センサーとは、物体の加速度(単位時間当たりの速度の変化量)を計測する装置であり、機器の移動の変化を検知するものです。センサは、その方向に応じて「x」「y」「z」の3軸のベクトルへの移動値を出力します。単位は「m/s^2」で表されます。一秒間でどの程度の距離を進んだかという表現になります。 f:id:camelrush:20200526063210p:plain

ジャイロセンサー

ジャイロセンサーは、ジャイロスコープとも呼ばれ、角度(傾き)や角速度(回転の速さ)を測るセンサーです。単位は「°/s」「rad/s」で表されます。一秒間で何度角度が回転したかという表現になります。 f:id:camelrush:20200526064251p:plain

システム構成

構成としては、RaspberryPiで受信したセンサーデータをMQTTによって送信します。MQTTブローカーには、AWSのIoTCoreを使用しています。最終的に表示するWebページで「chartjs-plugin-streaming」を使用してリアルタイムグラフを表示します。 f:id:camelrush:20200527054645p:plain

プログラム

以下のGitHubにプログラムを掲載しています。
github.com

加速度センサー「MPU6050」制御

加速度センサーのデバイス制御は「devices/accelerometer.py」に記載しています。データシートをもとに、I2Cによってデータを取得します。

from abc import ABCMeta
import smbus
import math
from time import sleep

# MPU6050 Register Map
DEV_ADDR = 0x68
ACCEL_XOUT = 0x3b
ACCEL_YOUT = 0x3d
ACCEL_ZOUT = 0x3f
TEMP_OUT = 0x41
GYRO_XOUT = 0x43
GYRO_YOUT = 0x45
GYRO_ZOUT = 0x47
PWR_MGMT_1 = 0x6b
PWR_MGMT_2 = 0x6c   

class AbstractAccelerometer(metaclass=ABCMeta):
    def __init__(self ,devadr):
        self._devadr = devadr
        self._bus = smbus.SMBus(1)

    def startup(self ,pwr_mgmt_adr):
        self._bus.write_byte_data(self._devadr, pwr_mgmt_adr, 0)

    def _read_word(self ,adr):
        high = self._bus.read_byte_data(self._devadr, adr)
        low = self._bus.read_byte_data(self._devadr, adr+1)
        val = (high << 8) + low
        return val

    def read_word_sensor(self ,adr):
        val = self._read_word(adr)
        if (val >= 0x8000):         # minus
            return -((65535 - val) + 1)
        else:                       # plus
            return val

class AccelerometerMPU6050(AbstractAccelerometer):

    def __init__(self):
        super().__init__(DEV_ADDR)
        super().startup(PWR_MGMT_1)

    def get_temp(self):
        temp = super().read_word_sensor(TEMP_OUT)
        x = temp / 340 + 36.53      # data sheet(register map)記載の計算式.
        return x

    def get_gyro(self):
        x = super().read_word_sensor(GYRO_XOUT)/ 131.0
        y = super().read_word_sensor(GYRO_YOUT)/ 131.0
        z = super().read_word_sensor(GYRO_ZOUT)/ 131.0
        return [x, y, z]

    def get_accel(self):
        x = super().read_word_sensor(ACCEL_XOUT)/ 16384.0
        y = super().read_word_sensor(ACCEL_YOUT)/ 16384.0
        z = super().read_word_sensor(ACCEL_ZOUT)/ 16384.0
        return [x, y, z]

データシートは以下を参照ください。

http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Components/General%20IC/PS-MPU-6000A.pdf

配線図

配線は比較的シンプルです。データ取得にはI2Cバスを使用します。 f:id:camelrush:20200527060721p:plain

動作結果

数10ms程度のタイムラグはありますが、センサーデータのリアルタイムプロットができました。
youtu.be

ElasticSearch+Kibana と DHT11で温湿度をグラフ表示する

RaspberryPiとセンサーでデータ受信

RaspberryPiを活用する事例として、これまでモーターやカメラを使用したロボットやマニュピレーションを注意に勉強をしてきました。掌握とはいかないまでも、いくつかのプラットフォームやH/W制御を理解し、制御できるようになってきました。
しかし、一般的な産業用IoTとしてはセンターデータ収集(ビッグデータ)と活用も重要では?と思い、今回は温湿度センサー(DTH11)からの受信データの可視化を試してみたいと思います。

f:id:camelrush:20200512200557p:plain

ソフトウェア(データの可視化)

受信した温度・湿度データの可視化には、全文検索エンジンである「ElasticSearch」とBIツールの「Kibana」を使用します。このあたりは流行り廃りがありますが、割とメジャーどころを選んでみました。AWSにも同様のサービスがありますが、EC2前提のため費用がかかると思い、一旦オンプレで実践することにしました。

f:id:camelrush:20200512202930p:plain

最終的に、表示されたイメージは以下のようになります。tempertureが温度、Humidityが湿度です。線がいびつなのは、途中でセンサーを手でつまんで、無理に温湿度を上げたためです。

f:id:camelrush:20200513234925g:plain

用意するもの

事前に準備するハードウェアは、以下の2つです。

  • Windows PC
  • RaspberryPi3 Model B+
  • 温湿度センサー DHT11

  

ちなみに、私はDHT11の導入で少しハマりまして、最初に購入したHiLetgoさんのセンサーキットでは、うまく動作しませんでした。詳しくは調べていませんが、ハンダの問題による初期不良かもしれません。上のリンクの製品を買いなおしたところ、簡単に接続できました。また(写真のような接続ボードがない)センサー部品だけのものも販売されており、この場合は、接続過程でプルアップ抵抗を付与する必要があるそうです。以下を参考にしてください。

iot.keicode.com

システム構成

今回の構成は以下の通り、比較的シンプルです。RaspberryPiに接続した、センサーDHT11から温湿度データをPythonで読み取り、ElasticSearchClientライブラリを介してHTTP RequestでElasticSearchのデータベース(index)にデータを格納します。格納されたデータはブラウザ経由でKibanaのポートにアクセスし、画面に表示します。
f:id:camelrush:20200512210401p:plain

ElasticSearchセットアップ

環境構築

  • WindowsPCから、以下のElasticSearchページにアクセスします。
    Download Elasticsearch Free | Get Started Now | Elastic | Elastic

  • 遷移したページで、以下のリンクをクリックしてzipファイルをダウンロードします。
    f:id:camelrush:20200512211049p:plain

  • zipファイルをダウンロードしたら、適当なフォルダに解凍・展開します(ex. C:\ElasticSearch)

  • RaspberryPiからのリクエストデータを受信するため、解凍したフォルダにある「/config/elasticsearch.yml」ファイルを開き、以下の箇所を修正します。

# ---------------------------------- Network -----------------------------------
 :
#network.host: 192.168.0.1
network.host: 0.0.0.0
 :

# --------------------------------- Discovery ----------------------------------
 :
#discovery.seed_hosts: ["host1", "host2"]
discovery.seed_hosts: ["127.0.0.1"]
 :
  • 同様の目的で、ファイアウォールに、ElasticSearchの受信ポート(デフォルトは9200)に対する接続許可を設定します。

    • 「受信の規則の例外」に「新しい規則」を指定します。
      f:id:camelrush:20200513053650p:plain

    • 「規則の種類」に「ポート」を指定します。
      f:id:camelrush:20200513053802p:plain

    • プロトコルおよびポート」で「TCP」「9200」を指定します。
      f:id:camelrush:20200513053906p:plain

    • 「操作」に「接続を許可する」を指定します。
      f:id:camelrush:20200513053951p:plain

    • 「名前」に「ElasticSearch」と指定します(任意)
      f:id:camelrush:20200513054045p:plain

  • ElasticSearchの環境構築は以上です。

実行方法

PowerShellを起動し、次のコマンドでElasticSearchサービスを開始します。

start (Install Folder)\bin\ElasticSearch.bat

起動にはしばらく時間がかかります。最後に以下のような表示が出ればOKです。

[2020-05-12T19:47:57,614][INFO ][o.e.n.Node               ] [DESKTOP-L0AQN2J] started

動作確認

RaspberryPi側で、以下のコマンドを実行します。

$ sudo curl https://(WindowsPC IPAddress):9200/

次のような結果が表示されれば、OKです。

{
  "name" : "DESKTOP-L0AQN2J",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "Yl0C61rVSV6qCa4Q294O6A",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "zip",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

Kibanaセットアップ

環境構築

  • WindowsPCから、以下のKibanaページにアクセスします。
    https://www.elastic.co/jp/downloads/kibana

  • 遷移したページで、以下のリンクをクリックしてzipファイルをダウンロードします。
    f:id:camelrush:20200513055817p:plain

  • zipファイルをダウンロードしたら、適当なフォルダに解凍・展開します(ex. C:\Kibana)

  • (任意)外部からKibanaページを参照させたい場合は、解凍したフォルダにある「/config/kibana.yml」ファイルを開き、以下の箇所を修正します。

#server.host: "localhost"
server.host: "0.0.0.0"
  • (任意)外部からKibanaページを参照させたい場合、ファイアウォールに、Kibanaの受信ポート(デフォルトは5601)に対する接続許可を設定します。
    ※この手順の記載は省略します。ElasticSearchの手順を参考に、ポートを追加してください。

実行方法

PowerShellを起動し、次のコマンドでKibanaサービスを開始します。

start (Install Folder)\bin\Kibana.bat

こちらの起動には、ElasticSearchよりも、さらに時間がかかります。最後に以下のような表示が出ればOKです。

log   [10:52:22.688] [info][server][Kibana][http] http server running at http://0.0.0.0:5601

動作確認

WindowsPCで、ブラウザから以下のページへアクセスします。

http://localhost:5601

次のような結果が表示されれば、OKです。 f:id:camelrush:20200513232310p:plain

f:id:camelrush:20200513060647p:plain

RaspberryPiセットアップ

センサー接続

以下の図を参考に配線してください。
f:id:camelrush:20200514000722p:plain

プログラム作成 on Python

今回のプログラムはPythonで開発しています。以下に開発の流れを示しますが、開発したプログラムはGitHubにも上げていますのでご確認ください。

github.com

  • RaspberryPiにログインし、最初に、ElasticSearchClientのライブラリをpipコマンドでインストールします。
$ sudo pip3 install elasticsearch
  • DHT11はGitHubにセンサー制御用のライブラリが公開されています。プログラムを配置するフォルダを作成し、CDコマンドでフォルダに移動したら、git cloneコマンドでライブラリを取得します。
$ sudo git clone https://github.com/szazo/DHT11_Python.git
  • プログラムフォルダに、以下の内容でプログラム「elasticThermoHygroMeter.py」ファイルを作成します。
import RPi.GPIO as GPIO
from DHT11_Python import dht11
import datetime
import time
from elasticsearch import Elasticsearch

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()

# ElasticSearch Client作成(引数はWindowsPCのIPアドレス)
es = Elasticsearch('192.168.3.11:9200')

# DHT11センサーのインスタンス作成
instance = dht11.DHT11(pin=14)

# ポーリング(1秒間隔)
while True:

    # センサーからデータ取得
    sensorData = instance.read()
    timestamp = datetime.datetime.now()

    if sensorData.is_valid():
        es_body = {
            '@timestamp' : timestamp.isoformat(),
            'temperture' : sensorData.temperature,
            'humidity' : sensorData.humidity,
        }

    # ElasticSearchのデータ(index'raspi_accel_meter')に対して、
    # センサーから取得したデータを登録
    response = es.index(index='raspi_accel_meter',doc_type='doc',body=es_body)

    # 1秒ウエイトして次のループへ
    time.sleep(1)
    print(es_body)
  • 次のコマンドでプログラムを開始してください。センサーが正しく接続されていれば、データがWindowsPC上のElasticSearchに登録されていきます。
$ sudo python3 elasticThermoHygroMeter.py

f:id:camelrush:20200514002305p:plain

Kibanaグラフ設定

登録されたデータを可視化するため、WindowsPCでKibanaのページにアクセスし、グラフビューを設定します。 最初に、ブラウザから、アドレスhttp://localhost:5601にアクセスします。

  • 左のメニューバーの上から3つ目あたりにある「visualize」を選択します。
    f:id:camelrush:20200513063326p:plain

  • 「+Create New Visualization」ボタンをクリックします。 f:id:camelrush:20200513063434p:plain

  • 今回は、一番左列にある「Line」アイコンをクリックします。 f:id:camelrush:20200513230112p:plain

  • 画面右に「Create Index pattern」が表示されます。ここで受信データ(index)から、データパターンを作成します。 f:id:camelrush:20200513232734p:plain

  • 「index pattern」に「raspi*」と入力し、RaspberryPiのPythonプログラムから登録したindex「raspi_accel_meter」が表示されることを確認し、「Next step」ボタンをクリックします。 f:id:camelrush:20200513232807p:plain

  • 「Time Filter field name Refresh」には、「I don't want to use Time Filter」を選択して、「Create index pattern」ボタンをクリックします。 f:id:camelrush:20200513232848p:plain

  • 以上でindex patternデータが作成されます。再度、左のメニューから「visualize」を選択し、「Line」をクリックしてください。 f:id:camelrush:20200513232918p:plain

  • 先ほど作成したindex patternが表示されますので、このリンクをクリックします。 f:id:camelrush:20200513233023p:plain

  • index patternをベースにした、グラフ設定画面が表示されます。 f:id:camelrush:20200513230215p:plain

  • 最初に、X軸に「時間」経過を指定していきます。画面左側の「Buckets」の「+Add」をクリックし、「X-axis」を選択します。
    f:id:camelrush:20200513230300p:plain

  • 追加した「X-axis」には、以下のとおり設定します。

    • Aggregation : Date Histogram
    • Field : @timestamp
    • Minimum interval : Second f:id:camelrush:20200513230350p:plain
  • 次に、Y軸に「温度」(Temperture)を指定していきます。画面左側の「Metrics」の「Y-axis」に、以下の通り設定します。

    • Aggregation : Max
    • Field : temperture f:id:camelrush:20200513230446p:plain
  • ここまでの登録が済んだら、「Metrics」エリアの上にある▶マーク(Apply)をクリックしてください。登録しt温度の内容がグラフ表示されるはずです。 f:id:camelrush:20200513233138p:plain

  • 「Y-axis」で「+Add」をクリックして、表示内容に「湿度」(Humadity)を追加します。設定後、▶マークをクリックしてApplyすると、湿度グラフが表示されます。

    • Aggregation : Max
    • Field : humadity f:id:camelrush:20200513233352p:plain
  • 最初の表示のままでは、累積したindexデータをすべて横軸に表示してしまうため、時間の経過とともに見づらくなっていきます。今回は設定を変更し、直近3分間だけを表示することにします。

  • 画面上部にある「Add Filter」をクリックし、ウィンドウに次のとおり設定して、「Save」ボタンをクリックします。
    • Field : @timestamp
    • operator : is between
    • range : now+9h-3m → now+9h
  • 上の「now+9h」は、UTCから日本の時差9時間を加算しています。そこから、3m(3分)前までの間(between)を表示するという指定になります。
    f:id:camelrush:20200513233444p:plain

  • 上記の設定により、グラフのX軸の間隔が3分分になるはずです。なお、グラフの表記を日本時間に変更するには、左のメニューからManagement - Advanced Settings - TimeZone~ を設定する必要があります。 f:id:camelrush:20200513233505p:plain

  • 今回はさらに、定期的に画面を更新させましょう。上部の時計アイコン(Quick select)をクリックし、下部の「Refresh every」に「1 seconds」を指定して、右の「□ Start」ボタンをクリックします。 f:id:camelrush:20200513233658p:plain

  • 以上で、1秒ごとにセンサーデータをグラフ表示する画面が作成できました。 f:id:camelrush:20200513234925g:plain

所感

Kibana環境の構築が思ったより簡単で、データ可視化は簡単に行えました。最近ですと、Kibana Canvasを使用した素敵な表示画面が今度挑戦したいと思っています。

www.elastic.co

課題

最後に実施した画面更新ですが、秒単位の周期しか指定できませんでした。温湿度変化程度であればこれで問題なさそうですが、よりリアルタイムなセンサーデータの表示(たとえば加速度センサによる振動計のプロッタのようなもの)には、向かないような気がします。こちらはMQTTによるインプットから、Chart.jsとかで作った方がいいのかもと思いました。

AWS IoT AnalyticsとQuickSightで操作ログを可視化する(1/2)

AWS IoT Analyticsとは

AWSのサービスの一つで、IoTから得たデータを分析、可視化できるサービスです。IoTCoreからの入力データに限らず、あらかじめ集計されたS3データや、RedShiftなどの登録済みデータも使用することができます。

QuickSightとは

こちらもサービスの一つで、AWSの各種データベースに蓄積されたデータを可視化するBIサービスです。

データの蓄積

AWSコンソールからAWS IoT Analyticsを操作し、IoTからの受信データを蓄積する設定を行います。本来、温湿度計等、各種センサーデータを扱うところですが、今回は、以前の書き込みで作成したMQTT受信データ(ラジコンの操作ログ)を集計してくことにします。

ルールの作成

AWS IoT Coreで、ルールの作成を行います。

  • ACT - ルールを選択し、「ルールの作成」を選択します。
    f:id:camelrush:20200420221710p:plain
  • 任意のルール名を入力します。
    f:id:camelrush:20200420221819p:plain
  • 中部の「ルールクエリステートメント」で「編集」を押し、「SELECT * FROM xxxxxxx」の xxxxxxx部分に、サブスクライブするトピック名を指定します。
    f:id:camelrush:20200420223935p:plain
  • 下部の「1 つ以上のアクションを設定する」で「アクションの追加」をクリックし、一覧から「IoT Analytics にメッセージを送る」を選択します。
    f:id:camelrush:20200420221932p:plain
  • 「IoT Analyticsリソースをすばやく作成する」を選択し、リソースプレフィックスに任意の名称を登録後、「Quick Create」ボタンを押します。
    f:id:camelrush:20200420222133p:plain
  • しばらくすると、AnalyticsのためのDataSet、Channel、PipeLine、Role、DataStoreが自動作成されますので、「アクションの追加」をクリックします。
    f:id:camelrush:20200420222152p:plain
  • ルールの作成画面に戻りますので「ルールの作成」ボタンをクリックします。
    f:id:camelrush:20200420222541p:plain
    以上で設定は終了です。IoT Coreの所定トピックに対してパブリッシュした後、コンソール画面でサービス「AWS IoT Analytics」を選択してみましょう。Channel を選択し、下部のダッシュボードにデータが表示されていれば受信、データ蓄積が成功しています。
    f:id:camelrush:20200420224155p:plain

次回はデータを加工して、QuickSightで蓄積した可視化します。