masato-ka's diary

日々思ったこととか、やったことの備忘録。

SORACOM Lagoonと AndroidThingsでIoT X AIをやってみた。

この記事について

この記事はSORACOM Adventcalendar 2018 18日目の記事です。SORACOM Adventcalendar 2018もいよいよ終盤に差し掛かってきました。今回は2018 年11月24日に開催されたIoTつくるよで展示した SORACOM LagoonとAndroidThingsを使った物体温度計測システムについて紹介します。当日のLTの資料は以下の通りです。

speakerdeck.com

物体温度計測とは?

温度センサなどで部屋の温度や外気温を計測し可視化・モニタリングすることはIoTのユースケースとして一般的に紹介される例です。こう言った場合、部屋の住環境のモニタリングや商品が保管してある倉庫などの環境モニタリングとして実施されることが大半でしょう。 しかし、温度計測が必要であるが、前述の例のような部屋や空間といった面としてのセンシングではなく、ピンポイントで温度を計測したい場合が出てきます。例えば機械設備の保守では設備のある特定の部分の温度上昇を検知したい場合です。また、ショウケースに入った食品などの品質監視を行う場合、ショウケース内の温度を1箇所測っただけでは実際の食品の温度を知ることはできません。 こういった場合、測りたい物に直接センサを貼り付けて温度を監視したくなりますが、以下の理由から難しいと考えます。

  1. 計測対象にセンサの設置が困難
  2. 計測する個数があらかじめ特定できない
  3. 計測箇所があらかじめ特定できない。

この課題を非接触温度センサとDeep Learningによる物体検知を行うことで解決します。また取得したデータをSORACOM Lagoonでダッシュボードとして提供します。

作成したシステムの仕組みについて

全体概要

全体構成は以下のようになっています。

f:id:masato-ka:20181217221236j:plain

詳細については以下で順に説明します。

Android ThingsとSORACOMの接続について

今回デバイス構築に利用したのはGoogleが提供しているIoTデバイス向けのOSであるAndroidThingsを利用します。Android Thingsについての紹介記事は以下の過去記事を参照ください。

masato-ka.hatenablog.com

Android ThingsはSIMを利用する環境が整っていないため、SORACOMに接続する際はSORACOM Inventoryからデバイス登録を行い、デバイスのシークレットを取得します。取得したシークレットを元にSORACOM HarvestのAPIへインターネット経由でデータを送信します。具体的な手順は以下ソラコムさんのサイトを参照してください。

dev.soracom.io

AndroidThingsからAPIを叩く際はokhttpを使い。以下のコードスニペットを使い、データの送信を行なっています。実験用のため、デバイスIDやシークレットをハードコートしていますが、実際にはAndroidのKey storeなどに保存しておくと良いと思います。

private static final String HARVEST_ENDPOINT = "https://api.soracom.io/v1/devices/";
private static final String DEVICE_ID = "<デバイスID>";
private static final String DEVICE_SECRET_KEY = "<デバイスシークレット>";

private OkHttpClient mOkHttpClient;
private ObjectMapper mObjectMapper;


String payload = mObjectMapper.writeValueAsString(harvestSummaryPayload);

MediaType MINE_TYPE = MediaType.parse("application/json; charset=utf-8");
//"x-device-secret: <シークレットキー>"
Request request = new Request.Builder()
          .url(HARVEST_ENDPOINT+DEVICE_ID+"/publish")
           .addHeader("x-device-secret", DEVICE_SECRET_KEY)
          .addHeader("Content-Type", "application/json")
          .post(RequestBody.create(MediaType.parse("application/json;charset=utf-8"), payload))
           .build();
Response response = mOkHttpClient.newCall(request).execute();
response.body().string();

物体検出について

今回の物体検出は学習済みのTensorflowモデルをTensorflow liteモデルへ変換し、AndroidThings場で動作させました。動作させたモデルはSSD Mobilenet v1 cocoと呼ばれるモデルです。AndroidThingsでの動作については以下の過去記事を参照ください。

masato-ka.hatenablog.com

接触温度センサについて

接触温度センサはPanasonic社のAMG8833赤外線アレイセンサを利用します。このセンサは8X8の格子状に非接触で温度データを取得することができます。データの取得インタフェースはI2C です。エアコンに内蔵され、人発見などの利用されるセンサーです。

masato-ka.hatenablog.com

実行結果

 デバイス側でおの物体検知と温度計測について

AndroidThings側での実行結果は以下の動画のようになっています。物体検出でマグカップを認識しています。その後、マグカップにお湯を注ぐことで発生する温度上昇をセンサーで捉えています。このようにAIだけ、センサーだけではできない事象を多次元的に捉えることがAI X IoTの醍醐味でしょう。

youtu.be

SORACOM Lagoonでの可視化について

SORACOm Lagoonでの可視化は以下のようになっています。このダッシュボードでは缶コーヒーの温度と個数を計測しています。これらを1つのデバイスで実現出来つところがみそです。

f:id:masato-ka:20181217220642p:plain

まとめ

今回はIoT X AIということでAndroidThingsで取得したセンサ情報と画像認識の結果をSORACOM Lagoonで可視化させてみました。ソラコムのサービス自体は昨年まではセルラー前提といった印象が強かったですが今年のDiscoveryイベントを境にセルラーだけでなくより幅の広いIoT プラットフォームとしての進化を遂げています。そんなソラコムサービスだからこそ、IoT X AIなサービスでも活躍できるのではないのでしょうか。来年もソラコムさんからますます目が離せません!

SORACOM LTE-M Buttonで家庭内PoCをやってみた話

1. この記事について

この記事はSORACOM LTE-M Button powerd by AWS Advent Calendar 2018 8日目の記事になる。前回このブログではSORACOM LTE-M ButtonがIoTデバイスとしてとて素晴らしいお手本となっていることを紹介した。

masato-ka.hatenablog.com

この意見は今も1mmとして変わってない。その上で、どんな素晴らしいデバイスを使ったとしてもアプリケーションとユーザとの関係を考えユースケースを実装することが価値になるということをお伝えしたい。そうでなければせっかくの素晴らしいデバイスを台無しにしてしまう。今回はおうちハック的にSORACOM LTE-M Buttonを使ってみたお話となる。

2. 検討したユースケース

今回SORACOM LTE-M Buttonを利用して実装したアプリケーションのユースケースは日用品の在庫管理ユースケースである。

これはSORACOM LTE-M Buttonをクリックするたびに日用品の在庫の数をカウントする機能を持っている。あらかじめ備蓄品の数を設定しておき、備蓄品を利用したらボタンをワンクリックする。そうすると、在庫数を減算していく仕組みである。管理している在庫数を可視化させることでリアルタイムに備蓄品の数を確認することができる。家庭内でよく使う備蓄品としてトイレットペーパやティッシュといった日用品から卵などの食品まで色々なものを割り当てることができる。今回は冷蔵庫の卵の数をカウントするEgg Counterを実装した。

2.1 ユースケースにおける課題感

ユースケースに対する課題として考えたことは、「帰宅途中に買い物をする際に冷蔵庫の中身を覚えておらず買い物に苦慮する場面」であった。 例えば夕飯の支度に卵を使いたいが、卵の残数やその賞味期限などを出先で確認することが難しい。我が家は共働きの2人暮らしである。そののため、特にこういった食品の残数について、「お互いがいつ使ったかわからない」ことから残数の把握は困難になる。

2.2 在庫の減り具合を見ることの意義

在庫状況を可視化することで上記の課題に対して、出先にて最新の在庫状況を確認することが可能となる。そのため、無駄な買い物を抑止することができる。また、可視化状況を共有することでコミュニケーションにより多重購入という悲劇を未然に防ぐ手立てともなる。

2.3 本家ダッシュボタンとの違い

本家ダッシュボタンでは似たような課題に対して、無くなる、無くなりそうなタイミングですぐに注文できるという価値を提供している。一方で現在の家の中の在庫数については管理することができない。この場合、上記に挙げた課題感に対しては対応することができない。また時系列で在庫の消費量を記録することで将来の消費予測やカイゼン活動につなげることができる。

3. Egg Counterのアーキテクチャ

ここで実際に作成したSORACOM IoT Buttonを利用した在庫管理アプリケーション、Egg Counterについて紹介する。

3.1 アーキテクチャ方針

Egg Counterのアーキテクチャを決定する上で以下の二点をポイントとしてて検討を行った。

  1. 簡便に在庫の管理を実現する機能
  2. 簡易PoCに的を絞り簡易なつくりとすること。

1についてはセンサーなどは使わずにSORACOM Buttonを、使うことで簡単に在庫の記録を行えるようにした。 2.については既存サービスを活用することで構築の手間を省いた。また利用するサービス数を絞れるように各サービスの使い方を工夫した。

3.2 構成

上記アーキテクチャ方針にしたがって以下のような構成とした。

f:id:masato-ka:20181208110531j:plain
Egg Counter アーキテクチャ

以下のように冷蔵庫から卵を取り出すごとにSORACOM LTE-M Buttonを押すことで在庫数をカウントしていく。カウントされた在庫数は Lagoon上で可視化されるようにした。データの永続化自身はSORACOM Harvestに任せ、AWS Lambdaからアクセスするようにしている。

  • ボタンに割り当てられたイベントは以下のようになっている。
ボタンイベント 動作 意味
シングル 在庫減算 卵を使った時に卵の在庫を減らす。
ダブル 在庫加算 卵の補充や誤押の際の在庫修正に利用する。
ロング 在庫のリセット 卵を新規に補充した際に設定された値に在庫を更新する。

3.3 AWS Lambda のコード

Lambdaのコードは以下のリポジトリに掲載している。

github.com

CloudFormationを使いデプロイすることができる。今回は先日のAWS reInventで公開されたIntteliJ IDEAWS Toolkits pluginを使って開発を進めた。

Lamda ファンクション本体は以下のようにクリックに応じて各イベント処理にディスパッチするコードのみになっている。

def lambda_handler(event, context):

    click_type = event['deviceEvent']['buttonClicked']['clickType']
    if click_type == "SINGLE":
        do_single_click_event()
        logger.info("Called single click event.")
    if click_type == "DOUBLE":
        do_double_click_event()
        logger.info("Called double click event.")
    if click_type == "LONG":
        do_long_click_event()
        logger.info("Called Long press event.")
    return {"result":"success"}

SINGLEクリックイベントのメソッドではSORACOM APIから現在の在庫数を取得するget_latest_remainingメソッドを実行し、在庫の減算を行なっている。減算した結果をpersistent_remainingHarvestのAPIで送っているようにしている。

def do_single_click_event():
    latest_remaining = get_latest_remaining()
    remaining = latest_remaining - 1 if latest_remaining > 0 else 0
    persistent_remaining(remaining)

ダブルクリックやロングについても加算、リセットのみが違うだけで動きは同じである。ソラコムのAPIについてもオーソドックスにアクセスすれば問題ない。この部分は今年ソラコム側でセルラー回線以外へサービスの対応を進めているため、実現できるようになった。

参考2では記載されていないが、参考1で入れたデータを取得するためのエンドポイントはhttps://api.soracom.io/v1/data/Device/{DEVICE ID}?sort=desc&limit=1となる。詳細は上述のGitHubのコードをご覧いただきたい。

4. 改善ポイント

4.1 AWS Lambdaに渡すキーの多さ

SORACOMHarvestの WEB APIとSORACOM APIのDATA APIを使うことで、AWS Lambdaは以下の4つの情報を持つことになる。 これらはAWS Lambdaに環境変数として設定している。SORACOM Harvestへデータを送信するためにはAWS Lambdaをデバイスと登録してキーを払い出す必要がある。SORACOM Buttonが出てきたタイミングでボタンの情報をHarvestに連携するために従来のSORACOM APIとHarvestのAPIを一緒にしてもいいと思う。AWS側にDB持たせればいいというのはごもっとも。

キー名 説明 用途
バイスID SORACOM Inventoryから払い出されたデバイスID SORACOM Harvestへデータを送る際に利用
バイスシークレット SORACOM Inventoryから払い出されたデバイスのシークレットキー SORACOM Harvestへデータを送る際に利用
Authキー SAMユーザのAuthキー SORACOM Harvestからデータを取得する際に利用
AuthキーID SAMユーザのAuthキーID SORACOM Harvestからデータを取得する際に利用

4.2 AWS Lambdaの環境変数

環境変数の値として記号を含む文字列を設定するとエスケープされてしまう。また、環境変数から文字列として取り出した場合、エスケープされた文字列が取り出されるため、エスケープを除去する必要がある。今回の場合、SORACOM Inventoryで払い出したデバイスシークレットキーに「=」が含まれており、これが「\」でエスケープされていた。そのため、以下のようなコードでエスケープ文字を除去した。

KEY_NAME = os.environ['key name'].replace('/','')

5. ユーザレビュー

仕組み自体の構築は1〜2時間で完了し、いざ家庭内 PoCとして投入してみた。

5.1 ユーザの感想

意気揚々と仕組みの説明と使い方、意義を説明した結果ユーザから「めんどくせぇ」という感想をいただいた。UXへの敗北である。「ボタンを押す煩わしさ>卵の個数がわかるメリット」の図式が出来上がったために発生した問題だ。前述したように、仕組みやデバイスが良くてもそれを活用するアプリケーションの価値に問題があった。

6. まとめ

SORACOM LTE-M Buttonは非常に優れたデバイスである。しかし、それを活かすユースケースをしっかりと作り込むべきだろう。今回は卵を取り出すという行為に無理やりボタンを押すという行為を繋げてしまい、ユーザへの手間を増やす結果となった。SORACOM LTE-M Buttonを活かすためには。ボタンを押すという行為がユースケースで無理なく出てくることが重要じゃないかと思う。良いデバイスなだけに見落としやすい。

SORACOM LTE-M Button powerd by AWSがIoTアーキテクチャの優れたリファレンスモデルな件

この記事について

この記事ではSORACOM LTE-M Button powerd by AWSについてのファーストインプレッションを紹介する。7月の発表から発売まで首を長くして待ち、ようやく手元に届いたこの製品。IoTを実現するシステム、デバイスのお手本と言ってもいいくらい綺麗な作りになっていた。この記事ではSORACOM LTE-M Button powerd by AWSがなぜIoTのお手本と言えるのか考察していく。 以下のツイートをしっかりと文章にした内容だ。

SORACOM LTE-M Buttonについて

SORACOM LTE-M Buttonは7月に行われたSORACOM Discoveryイベントで発表されたソラコム初の自社デバイスだ。中身はAWS IoT ボタンAmazon dashボタンのベース)で、AWS IoT 1Clickサービスを使って利用することができる。 このデバイスができることはAmazon dashボタンのように、ボタンをクリックすること。ボタンのクリックは3パターンあり、それぞれシングルクリック、ダブルクリック、長押しである。ボタンをクリックするとAWS IoT 1Clickへイベント情報を送信する。ユーザはAWS IoT 1Clickに送られたイベントを処理することで任意のアプリケーションを実装することができる。処理はAWS Lambdaで記述する。  このようにデバイス自体の機能は本家AWS IoTボタンと一緒である。しかし、SORACOM LTE-M Button powerd by AWSKDDI社の LTE-Mと呼ばれる、LTEの通信網を利用したLPWA規格を採用している。この回線を利用することでWiFiを必要とせず、デバイス単体でAWSへのコネクティビティを確保している。

blog.soracom.jp

何がIoTアーキテクチャのリファレンスとして優れているのか?

ここからはSORACOM LTE-M Button powerd by AWSがIoTのお手本たる理由について語っていきたい。

1. シームレスなデバイスアクティベート

SORACOM LTE-M Button powerd by AWSはパッケージ開封後、すぐにAWSに接続することができる。すぐという言葉は曖昧だがおそらく最短30秒もあれば十分な時間だろう。本体の裏にあるデバイスコードをAWS IoT 1Clickのデバイス登録画面に入力し、画面の案内に従い、デバイスのボタンを一回クリックすれば完了する。  もちろんAWS IoT 1Clickの仕組みがシンプルという見方もできる。しかし、最も大きい理由はLTE-Mを使うことで、WiFi接続をすっ飛ばすことができるという点だ。 従来この手のデバイスWiFiを利用していた。そのためにデバイスを一度設定モードで起動(WiFiアクセスポイントになったりする)しスマートフォンから専用アプリかWebブラウザで接続し、WiFiのパスワードや酷い場合は専用クラウドサービスのパスワード入力を必要というお世辞にもスマートとは言えない解決方法を提供してくれていた。またWiFi接続を利用することで実質的に屋内での利用に限定されていた。この問題をLTE-Mとソラコムの基盤でものの見事に解決してくれたのだ。  当然利用するユーザにとって接続の利便性を提供するだけでなく、利用するシーンを限定しないという利点がある。ユーザがデバイスを利用するために何を提供すれば良いのか、非常に参考になる。

  • 実際の設定方法がみたい方は以下公式ドキュメント参考のこと。

SORACOM LTE-M Button powered by AWS をクリックしてSlackに通知する | Getting Started with SORACOM LTE-M Button | SORACOM Developers

2. 標準で提供されるデバイス管理機能

SORACOM LTE-M Button powerd by AWSAWSへの登録以外にソラコムの対応サービスへ登録を行う必要がある。登録しなくても利用はできるのだが、通信料の更新などができない。欲を言えばこの部分はAWS登録と連動してほしかった。が、この一点に目を瞑れば、この登録もユーザにはメリットがある。なぜならば登録することでデバイスの管理がソラコムのユーザコンソール画面から行えるからだ。実際の管理画面は以下のように見える。

f:id:masato-ka:20181104145439p:plain

残りのクリック回数や残電池量を見ることができる。また、最後に接続した時間やその際のイベントのペイロードとしてJSONデータを確認することができる。デバイスや障害調査だけでなく、ユーザの利用状況調査などIoTサービスの本質的な情報の収集という点で非常にありがたい情報だ。デバイス管理を行う上で何の情報に気をつけて取得すれば良いのか参考になる。

3. 責務の境界とセキュリティ

 最後にユーザの 目に触れないが、無意識のうちに重要な部分だ。実は前項で紹介したシームレスなデバイスアクティベートも標準で提供されるデバイス管理機能も、ソラコムサービスとAWSの役割がしっかりしているため、結果として実現されいる機能だと考えている。  現状知りうる範囲から推測できるSORACOM LTE-M Button powerd by AWSアーキテクチャを起こしてみた。

f:id:masato-ka:20181104160255p:plain

 SORACOM LTE-M Button powerd by AWSKDDI社のLTE-M網を経由してソラコムの基盤につながる。ここは他のソラコムサービスと同じだと考えられる。そこからSORACOM Beamを使ってAWS IoT 1clickへ接続されているようだ。そのため、公衆インターネット回線へ出ることなくデータをセキュアにAWSへ転送できる。 また、デバイス管理機能はソラコムのサービス内で完結している。もちろんAWS側で同等の機能を組むこともできるだろうが、基本的にはAWSはアプリケーションの実現に集中することができる。  つまり、アプリケーションを実現するAWSサービスとデバイスの安全なコネクティビティと管理を実現するソラコムサービスというサービス間の責務の分解が施されている。IoTサービスで様々なサービスが似たような機能を重複して提供している。その中でソラコムのサービスの位置付けとしてIoTアーキテクチャの下回りをしっかりと提供し、他者クラウドサービスはアプリケーション実現のみに利用できるという一種のレイヤー構造を提示しているのではないだろうか。今回のSORACOM LTE-M Button powerd by AWSでは難しいかもしれないが、こういったレイヤー構造を組んでおけば、アプリケーション層をオンプレミスな環境として組むことや、費用やサービスのスケールに伴い、利用するクラウドを変えいてくことをユーザやデバイスへの負担なく実現できることだろう。IoTの全体アーキテクチャを考える際に非常に参考にしたい点だ。

まとめ

このようにソラコムの基盤とAWSのサービスをうまく繋ぎこみ、デバイスの提供と運用を実現している。ソラコム自社で提供する基盤だけあってソラコムのポテンシャルが十分に発揮できていると思った。もちろんエンドユーザ向けサービスとしてのユースケースやビジネスモデルは存在しない。これはこのデバイスを使うユーザが作り上げる必要がある。しかし、どうやってデバイスをユーザに届けるか、どうやって自分たちのビジネスモデルを実現するアプリケーションを作るか、どうやってサービスを運用していくか、こういったIoTサービスを実現する上考えなければならない問題についてその解の示唆を与えてくれている。SORACOM LTE-M Button powerd by AWSはまさしくIoTアーキテクチャの優れたリファレンスモデルとなっている。きっと僕たちがいつまでも実現しないからソラコムが自分たちで作ってしまったのだ!

ちなみに現在(2018年11月4日)キャンペーン価格中で3980円で購入することができる。キャンペーンの終了時期は未定だが、この機会にぜひこのデバイスを体験していただきたい。Amazon dashボタンをハックして喜んだり、温度センサの値をWEBブラウザでグラフにしてIoTとか言って喜んでいる場合ではない。

soracom.jp

Android ThingsとRaspberry Pi 3Bでお手軽物体検出

この記事について

この記事ではRaspberry Pi 3B にAndroidThings 1.0.3をインストールした環境で、TensorFlow Liteを使った物体検出を実行してみた。AndroidThingsを問わずTensorFlown Liteを使った物体認識ではClassificationのモデルを使った方法がサンプルとして公開されている。Classificationは画像そのものをラベリングするもので、例えば猫の画像や犬の画像といった具合に画像自体をクラス分けしていく。これに対して物体検出(object detection)とは一枚の画像中に写っている物体を検出する手法となっている。今回は'''coco-ssd-mobilenet_v1'''と呼ばれるモデルをTensorFlow liteを使って動かしてみた。動かすだけならディープラーニングの知識は必要なく、学習済みのモデルとそのモデルに沿った入力と出力に合わせたデータを渡してあげれば良い。

f:id:masato-ka:20180826202603j:plain

物体検出周りについて

coco-ssd-mobilenet_v1について

技術的な詳細は専門ではないため割愛する。Mobilenetは計算量を削減するように工夫された物体識別用のDNN(Deep Nural Network)のネットワーク構造を指している。また、SSDは'''Single Shot multibox Detector'''の略で、1枚の画像から複数の物体を切り出すDNNのネットワーク構造を指す。cocoは物体検出タスク用の学習セットの名前だ。それぞれの詳細について詳しく知りたい方は専門的な書籍や論文を参照し欲しい。

TensorFlow Lite

今回はAndroidThings上でTensorFlow Liteと言うはDNN用の数値計算ライブラリを使った。TensorFlow LiteはTensorFlowをモバイル環境(AndroidiOS)でも動くようにカスタマイズしたものだ。普通のTensorFlowの学習済みモデルを量子化という形で圧縮して使用する。量子化とはモデルのパラメータを浮動小数点から整数に置き換え計算負荷を抑えたものらしい。専門的なところは微妙に違うかもしれないが理解はそんな感じだ。

物体検出の実行

実行結果

以下はRaspberry Pi 3B上で動かした結果だ。10FPSくらいで動いている。工夫すればもう少し早くなるかもしれない。カメラはRaspberry Pi CAMERA V2を使用している。SONY製センサが搭載されているモデルを購入した。一度640X480で画像を撮影して、300X300にリサイズしている。リサイズ後の画像をディスプレイに表示させているので表示が潰れたようになっている。

youtu.be

使用したモデルファイル

モデルファイルはTensorFlowで学習したものが公開されている。このモデルを元にTensorFlow Liteで利用できるように量子化されたモデルも公開されている。TensorFlow LiteのAndroidサンプルでも利用されているモデルだ。ツールを使い自分でモデルを圧縮する方法もあるが今回は実施していない。オリジナルのモデルを試す場合は必須となる。

https://storage.googleapis.com/download.tensorflow.org/models/tflite/coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.zip

ソースコードのポイント

ソースコードは以下のGitHubに掲載している。これをgradeleでビルドすればAndroidThings上で実行できるはずだ。ところどころフォルダがないと言われるかもしれないが、その場合は自分で当該のフォルダを作成すれば問題ない。

github.com

プロジェクトはモジュールに分かれている。

  • アプリケーション部のappモジュール
  • カメラ制御のcameraモジュール
  • 物体検出部のobjectdetectionモジュール

解説というほどでもないが物体検出処理のポイントについて記載する。TensorFlow Liteで実装する場合はモデルにあった入力を与え、モデルが吐き出す出力に合わせて結果を受け取る必要がある。しかし、それだけ合わせればどんなモデルでも利用するだけなら簡単に実装できそうである。今回の場合、入力は300X300pixelのカラー画像となる。つまり270000次元のデータ(300300RGB)となる。またそれぞれは1byteのデータになる。つまり270000要素の1次元のバイト配列を与えることになる。(配列のデータ構造の次元と与えるデータの次元が違うことに注意)

TensorFlowLiteのライブラリはbuild.gradleファイルに以下を設定するだけでいい。その他の環境設定は不要。

dependencies {
   implementation 'org.tensorflow:tensorflow-lite:1.9.0'
    compileOnly 'com.google.android.things:androidthings:+'
}

入力データは300X300にリサイズした画像(Bitmapオブジェクト)を1次元のByteByfferに以下のように書き出す。

private static int TF_INTPU_IMAGE_WIDTH = 300;
private static int TF_INTPU_IMAGE_HEIGHT = 300;
private static int DIM_BATCH_SIZE = 1;
private static int DIM_PIXELE_SIZE = 3;

private ByteBuffer convertBitmapToByteBuffer(Bitmap bitmap) {

        int[] intValues = new int[TF_INPUT_IMAGE_WIDTH * TF_INPUT_IMAGE_HEIGHT];
        ByteBuffer imgData = ByteBuffer.allocateDirect(DIM_BATCH_SIZE * TF_INPUT_IMAGE_WIDTH
                * TF_INPUT_IMAGE_HEIGHT * DIM_PIXELE_SIZE);
        imgData.order(ByteOrder.LITTLE_ENDIAN);
        TensorFlowHelper.convertBitmapToByteBuffer(bitmap, intValues, imgData);
        return imgData;
}

出力データ用のアウトプットとして以下のようなデータ構造を作成する。numDetectionは検出させたい物体数の最大値を定義する。

Map<Integer,Object> outputData = new HashMap<>();
float outputLocations = new float[1][numDetection][4];
float outputClasses = new float[1][numDetection];
float outputScores = new float[1][numDetection];
float numDetections = new float[1];
outputData.put(0, outputLocations);
outputData.put(1, outputClasses);
outputData.put(2, outputScores);
outputData.put(3, numDetections);

あらかじめモデルを読み込ませたmTensorFlowLiteのInterpreter#runForMultipleInputsOutputsを実行して画像検出処理を実行する。 認識結果はoutputDataに格納されている。

Object[] inputArray = {imgData};
mTensorFlowLite.runForMultipleInputsOutputs(inputArray, outputData);

実行した結果を以下のように処理する。

private stattic final int LABEL_OFFSET = 1;

final ArrayList<Recognition> recognitions = new ArrayList<>(numDetection);
        for(int i=0; i < outputData.size(); i++){
            final RectF location = new RectF(
                    outputLocations[0][i][1] * TF_INPUT_IMAGE_WIDTH,
                    outputLocations[0][i][0] * TF_INPUT_IMAGE_HEIGHT,
                    outputLocations[0][i][3] * TF_INPUT_IMAGE_WIDTH,
                    outputLocations[0][i][2] * TF_INPUT_IMAGE_HEIGHT
            );
            Recognition recognition =
                    new Recognition(
                            "" + i,
                            label.get((int) outputClasses[0][i] + LABEL_OFFSET),
                            outputScores[0][i],
                            location);
            recognitions.add(recognition);
        }

        return recognitions;

認識した物体ごとに以下の結果が格納されている。

  • outputLocationsは画像上での物体の位置 3次配列で2番目の添字が物体、3番目の添字が物体の位置を表す2点の座標となっている。
  • outputClassesは認識した物体のクラスとなっている。値はラベルファイルの行数-1になっているので、ラベルファイルを行ごとにArrayListか何かに格納し、参照する。
  • outputScoresは信頼度Accuracyを表している。

ちなみに今回作ったRecognitionオブジェクトはこんなかんんじ

public class Recognition {

    private final String id;
    private final String title;
    private final Float confidence;
    private final RectF location;

    public Recognition(
            final String id, final String title, final float confidence, final RectF location) {
        this.id = id;
        this.title = title;
        this.confidence = confidence;
        this.location = location;
    }

    public String getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public Float getConfidence() {
        return confidence == null ? 0f : confidence;
    }

    public RectF getLocation(){return location;}

    @Override
    public String toString() {
        String resultString = "";
        if (id != null) {
            resultString += "[" + id + "] ";
        }

        if (title != null) {
            resultString += title + " ";
        }

        if (confidence != null) {
            resultString += String.format("(%.1f%%) ", confidence * 100.0f);
        }

        return resultString.trim();
    }

}

まとめ

AndroidThingsを使うことで、TensorFlowの環境構築をすっ飛ばしてコードを書くだけで物体検出を動かすことができる。今回作成したサンプルのうち、カメラ部分と物体検出部分をライブラリとしてまとめて、bintrayで公開している。自分のアプリケーションに使ってみたい場合はそれを使うのもあり。性能と品質は保証できないけど。TensorFlow Liteは自分で目的に合わせた認識モデルを作れる様になったらより活用の幅が広がると思う。しかし、そこが活用する上での大きな課題だったりも。

IoT・AIなデバイスを開発するのにAndroid Thingsが控えめに言って最高だった話

この記事について

 この記事ではAndroid Thingsを触ってみた感想をつらつらと記載している。あくまで個人的な感想を記載してあり、異論は多々あるだろう。しかし控えめに言ってAndroid Thingsは最高だった。1ヶ月ほど遊んでみてこれは面白いことができそうという感想しか出てこない。現在、IoTデバイスのトレンドはAIをはじめとするエッジヘビーな処理、デバイス管理、セキュリティなど求められるものが多くなっている。そしてAndroid Thingsはいとも簡単にこれらの要件を叶えてくれる。ちなみにAzure IoT EdgeとかAmazon Free RTOSなんかはこれから触りたい候補に入っているので「それ['Azure IoT Edge' | 'Amazon Free RTOS']でもできるよ」という話は知りたいし、たくさん突っ込んでほしい。

1. なぜAndroid Thingsなのか?

 2018年5月にGAから1.0.0正式リリースになったのを機にAndroid Thigs使ってみるかという機運になった。またGCPのCloud IoT Coreとかその辺りを触っていて、エッジ側のOSとかの使い勝手も知りたくなり手を出してみた。最初は軽い遊びのつもりだったけど本気になってしまった。反省はしていない。

2. Android Thingsプロフィール

まずはAndorid Thingsのプロフィールについて見ていこう。

2.2. Android Things

 大雑把に説明するとAndroid ThingsはAndroid Oから派生して作られている。Android のCore framework APIにI/Oなどを直接コントロールできるようにしたThings APIを追加したものになる。これ以外にAndroidとは以下のポイントが違う。

  1. 設定などを行うシステムアプリがないこと
  2. 1つのアプリケーションしか実行できない
  3. 起動時にアプリケーションが自動的に立ち上がる

こうすることでにAndroid Thingsは組み込みアプリケーションを実行するプラットフォームとして最適化されている。AndroidスマホをIoTデバイスとして使おうとかそういう甘っちょろい考えとはそもそも次元が違うのである。ただし開発環境は普通のAndroid と同じようにAndroidStudioが利用できる(利用せざるおえない)。私はIntteliJ IDEAを使っているけど問題なく使える。

Overview  |  Android Things  |  Android Developers

2.3. Android Thingsで使える。ハードウェア

 Android Thingsが動くハードウェアは決まっている。一番入手しやすいのはRaspberry Pi 3 Bだろう。それ以外でホビー用だと公式入門キットに付属しているNXP Pico i.MX7Dが使えるそうだ。商用ではSnapdragonなんかも動くようだ。自分はおとなしくRaspberry Pi 3 Bを使っている。自分で用意するのであれば一択な気がする。

Supported hardware  |  Android Things  |  Android Developers

2.4. Android Thingsのインストールについて

Android ThingsのインストールはAndroid Things Consoleにユーザ登録するところから始まる。ユーザ登録後、インストールツールがダウンロードできるのでツールを使いSDカードへOSを書き込むことができる。Android Things Consoleはツールのダウンロードだけでなく、カスタムイメージの作成やアプリケーションの配布がきでる。(後述)

3. Android Thingsが最高なポイント

じゃあ、Android Thingsの何が最高なのか、何ができるのかを見ていきたい。

3.1. Peripheralの操作ができて最高

 I/O, I2C, SPI, UART, I2Sなど一通りのペリフェラルを扱うことができる。最近のプロトタイピングボードを使ってやりたいことはそのまま実現できる。しかもこれがAndroidの開発環境から開発できる。Javaさえ書ければ思いのままに扱うことができる。さらにAndroidStudioのデバッグ機能が使えるので、ソフトウェア周りのデバックはこれで十分である。printfデバッグのためにひたすらprint文を埋め込んだりしなくていい。AndroidThingsを始めるにはRainbowHATを買うのがオススメ。2018年7月22日現在スイッチサイエンスでは在庫切れだ。Amazonでは割高で売られている。なんとか在庫復活してほしさある。

www.switch-science.com

 RainbowHATはAndroidThingsのcodelabやチュートリアルで採用されているボードなので、一通りの機能をすぐに触ることができる。

f:id:masato-ka:20180722193802j:plain

しかしRainbowHATだけで遊ぼうと思ってたらいつの間にかディスプレイとカメラを買っていた。ただただ最高かよ。

3.2. ユーザドライバ開発ができて最高

 Androdi ThingsではAndroidデバイスドライバをUser-space driversという形でアプリケーションの一部に実装することができる。例えばPeripheralにGPSや加速度センサを接続してアプリケーションから直接UARTやI2Cを叩いて情報を取ることができる。しかしUser-space-driverとしてこれらの処理をラップすると普通のAndroid端末と同じようにAndroidのframeworkを介してそれぞれの値を取得できるようになる。例えばSPI接続の安いRasPi用ディスプレイはSPIでタッチパネルのデータを受け渡す。これをUser-space-driverを介さずに利用しようとすると、SPIでX,Yの座標を受け取り、UIの座標と当たり判定して。。。と実装する必要がある。しかしHIDのポインティングデバイスドライバとしてSPIをラップして書けば、通常のAndroid端末のタッチパネル操作と何ら変わりなくただViewを実装すればHIDの処理はOS側がイベントとして処理してくれる。SPIでとってきたデータを意識する必要はない。ちなみにこれを1.0.1向けに実装したのものは以下のリポジトリにある。

github.com

動くとこんな感じなる。

User-space-driverはLocation HID Sensor, LoWPANなど4種類サポートされている

 IoTサービスの初期検討ではデバイスがないのでAndroidスマホで実装する。そのフィードバックを元にハードウェア要件を固めAndroidThingsで実装する。スマホで作ったアプリのソフトウェア資産をAndroidThingsに移植することでソフトウェア開発を簡素化できる。こういったIoTのプロジェクトを進める上でとても強力な開発プロセスを提供してくれるのではないだろうか。IoTサービス開発にも役立って最高かよ。

3.3. BLEが使えて最高

 Android ThingsはもちろんBLEも使える。Raspberry Pi 3BのBLEも制御することができるらしい。らしいというのはまだ触っていないのでこの部分については語れる部分がほとんどない。1ヶ月以上遊んでてもまだ試すことが多いの最高かよ。

3.4. カメラが使えて最高

 Android Thingsではカメラを使うことができる。Raspberry Piの公式カメラを利用することができる。ただしUSBカメラを接続して使うのはRaspberry Piでは今の所できないようだ。少々残念なところだけどUSBのカメラのドライバを用意するなどAndroidでは難しい部分もあるのだろうか。もちろん撮影した画像はファイルに保存できるし、画面に表示することもできる。画像が取れることで画像認識など夢が広がりまくって最高かよ。

3.5. デバイスでのAIが簡単すぎて最高

画像認識

 Androidtensorflow-liteFirebase ML Kitといったモバイルデバイス向けディープラーニングフレームワークを使い物体認識などを実装することができる。同じ方法でAndroid Thingsも利用することができる。サンプルも豊富にあって既存モデルを使うだけであればすぐに実行することができる。例えば一般物体認識のサンプルは以下。Raspberry Piでも動く。

GitHub - androidthings/sample-tensorflow-imageclassifier: Classify camera images locally using TensorFlow models

 大きくtensorflow-liteを直接実行する方法とFirebase ML Kitを使う方法があるが後者をおすすめしたい。どちらもtensorflow-liteとそのモデルを利用するみたいだが(と思ってる)Firebase ML Kitでは何種類かのよくありそうな認識モデルを提供してくれる。OCRや顔発見、シーン認識、ランドマーク認識だ。もちろんtensorflow向けに用意したカスタムモデルを圧縮して使うこともできる。ここまで読んでRaspbianでも同じことできると思ってしまう。しかしtensorflow-liteのビルドなど面倒な環境構築作業が必要だ。Android Thingsでは環境構築をすっ飛ばして目的のアプリケーション実装に取り組めるところにアドバンテージがある。さらにFirebaseからモデルファイルをアプリケーションへ配信してデバイスのモデルを更新することができる。こういった管理機能まで含めて利用することができるのだ。そして、Android Things上での実装も数十行で終わる。たとえばFirebase ML Kitだとこうなる。もちろん実際にはカメラで画像をとってくるなど処理はあるが。

private void recongnizeText(FirebaseVisionImage image){
        FirebaseVisionTextDetector detector = FirebaseVision.getInstance().getVisionTextDetector();
        Task<FirebaseVisionText> result = detector.detectInImage(image)
                .addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() {
                    @Override
                    public void onSuccess(FirebaseVisionText firebaseVisionText) {
                        StringBuffer sb = new StringBuffer();
                        sb.append("Result: ");
                        for (FirebaseVisionText.Block block : firebaseVisionText.getBlocks()) {
                            sb.append(block.getText());
                            sb.append(", ");

                            Log.i(LOG_TAG, "Recognize text: " + block.getText());
                        }
                        textView.setText(sb.toString());
                    }
                }).addOnFailureListener(
                        new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Log.e(LOG_TAG, "failed recognize text", e);
                            }
                        }
                );
    }

顔認識をやりたければDetectorの種類を変えるだけだ。さらにクラウドAPI を使う処理にしたい場合もそれ用のDetectorを使えばいいだけだ。リファレンスがなくてもかける気がする。簡単に最新のAIをIoTデバイスに取り込めるの本当に最高かよ。

TPU対応(8月1日追記)

先日行われたGoogle Cloud Nextでは「Edge TPU」と呼ばれるTensorFlow-Liteを実行するための組み込み向けASICが発表された。また開発ボードが秋に発売され、対応OSはDebianとAndroidThingsになるそうだ。また同時に発表されたCloud IoT EdgeではEdge上でのML機能のを実現するランタイムとそれをGCPのプラットフォームをつなげる機能が提供されるようだ。詳細わかり次第また記載をしたい。 また、AndroidIntel Movidiusにも対応しているらしい、AndroidThingsでも使えるのか検証したい。

音声対話アシスタント

今はやりの音声対話アシスタントもAndroid Thingsで作ることができる。こちらはVoice KitのソフトウェアをAndroid Thingsで動かせるようだ。まだ試していないがぜひやってみたい。マイクやスピーカも使えるっぽい。Peripheralにモータとセンサをつなげればコミュニケーションロボットも簡単に作れそうで最高かよ。

3.6. クラウド連携が至れり尽くせりで最高

当然、クラウドとの連携も充実している。

アプリケーションとしてクラウドを使う

Google Cloud IoT Coreとの連携にはクライアントライブラリが公開されている。これを使うと簡単にGoogle Cloud IoT Coreと接続することができた。これでAndroid Thingsで取得したセンサデータや画像認識の結果をGoogle Cloud IoT Coreに投げCloud Dataflowを経由し、BigQueryに投げ込むことができる。後のデータ処理や可視化は思いのままだ。

developers-jp.googleblog.com

Googleクラウドプラットフォームへのコネクティビティが整備されてて最高かよ。

管理方法としてクラウドを使う

クラウドとの連携はアプリケーションだけではなく、デバイスの運用においても力を発揮する。Android Thingsをインストールするときに利用したAndroid Things Consoleを使えばアプリケーションの配信やアップデートができるようになる。また、OSの更新はOTAで実行できるようになる。つまりプロダクトとして実運用に入っても至れり尽くせりになっている。この部分は先ほどのFirebaseのAIモデルの配信も同じだろう。そもそも向こうはスマホアプリを対象としているのでこういう機能がないと実用として使えないのだろう。デバイスの数が増えても最高かよ。

IoT端末のソフトウェアを管理できるツール「Android Things Console」を使ってみました - GIGAZINE

3.7. IoTデバイスとしての取り回しが楽で最高

 AndroidThingsは電源を入れたらOSが立ち上がり、そのままアプリが起動する。電源一発ぽんだ。変なアプリケーション立ち上げ操作やそのための設定は必要ない。また、デバイスの電源はそのままデンプチできる。これでOSは壊れることはない。(一応そういうことになっている。)そのためにOSの設定をする必要はない。まさにIoT向けOSで最高かよ。

4. Android Thingsの弱いところ

ここまでAndroid Thingsの最高なところを見てきた。しかし光あれば影がある。最高じゃない部分だって多々あるのだ。

4.1. LTE接続や3Gサポート

Raspberry PiだとLTEモデムドライバなどサポートがない。QualcommがSnapdragonあたりで使えるようにするみたいなニュースがあるようだがRaspberry Piでもなんとかならんだろうか。今後に期待したいところだ。

Qualcomm to announce LTE chipset for Google’s IoT, Android Things

 またUSBやUARTのLTEモデムを接続し、ATコマンドで無理やりSMS送ってる人はいる。自分でドライバとか書けばなんとかなるんだろうか修羅の道な気もする。 これにSORACOMつなげたいんじゃと思いつつ、SORACOM Kryptonでソラコムのサービスにつなぎ込むんでいくのがいいのかもしれない。

4.2. Javaで開発

 Androidなので開発言語はJavaJavaだと辛い人は辛い。ただしIDEを使えばそこまで辛くはないと個人的には思っている。AndroidStudioはIntteliJ IDEAをベースにしているので開発環境としてもいい方だと思っている。このIDEの使い方を知ればむしろJavaを書くのが楽しくなると思う。どうしてもJavaとか嫌だという人はKotlinを使うことができる。

4.3. Androidの知識

 これまで最高ポイントで「Android開発と同じ知識で」や「Androidと同じソースで」などと書いた。しかし裏を返せばAndroid開発の知識やスキルを強制的に求められるのだ。これはAndroid開発初心者には学習コストが必要になる。しかし、幸いにも世のAndroid 開発者は多い。トラブル発生時のググラビリティは非常に高い。また、Googleのcodelabなど上質なチュートリアルやドキュメントも揃っている。Androidだけなら書籍もあるのでそんなに困らない。事実私はAndroid開発ほぼ初心者だがAndroid Thingsは難なく使えるようになった。もちろんAndroid Things 固有の問題だと辛いけどPeripheral周りとかかな。

4.4. まだ少し不安定

1.0.0とはいえこの安定性はどうなんだという状況がたまに発生する。まず最初に遭遇したのがWiFiの問題だ。家でWiFiを設定すると突然再起動を繰り返すようになった。WiFi設定後だったので電源の問題かと3AのACに変えたが状況が変わらずだった。途方に暮れてバグとして報告をした。

https://issuetracker.google.com/issues/110793391

結果として類似の報告が上がっているらしく、特定の設定のWiFiアクセスポイントが近くにあると起こる問題とのこと。。。家の中で別の部屋に移動するだけで再起動は発生しなくなった。また外に持って作業することもあるが今の所外では発生しない。本当に特異な状況だったのだろう。再起動をかなりの回数繰り返すうちにOSが起動しなくなる事象も確認している。この辺りも電プチが原因なのか、再起動ループが原因なのかは不明だ。今後改善されることを願う。

4.5. 対応ハードウェの選択肢が少ない。

Raspberry Pi 3 Bが使えればそんなに困りはしないが、もう少し選択肢があってもいい気がする。また新しいボードに対応するまでのタイムラグもきになるところだ。ちょっと前まではIntel Edisonなども使えていたようだが奴のことはもう忘れよう。これからシングルボードコンピュータが新規に作られたらぜひAndroid Things対応ボードにしてほしい。

5. まとめ

Android Thignsは最高だった。確かに難はあるしイロモノ感も否めない。しかし、控えめに言って最高かよだった。盛り上がりはイマイチな気がする。もちろん使ってる人もいるにはいるが、よく見るって感じでもない。正式リリースされてまだ日が浅いというのもあるかもしれないが、これから日本でも盛り上がって欲しい。この記事を見てAndroid Thingsに興味を持ってくれたら嬉しい。また、Android Thingsのもくもく会を企画してみたので実際に触って見たくなったら是非参加して欲しい。

connpass.com

このブログでもAndroid Thigsは追っていきたいテーマだ。

SORACOM Discovery 2018に参加した記録

この記事について

この記事では2018年7月4日に開催された株式会社ソラコムさんのイベントSORACOM ディスカバリーに参加した記録と感想・所感について書いています。

SORACOM Discovery 2018について

 SORACOM Discovery 2018は2017年に続き2回目の開催です。キーノートを含めた29のセッションと30を超えるユーザ企業やパートナーの展示、またIoT製品に触って試せるタッチアンドトライコーナーやハンズオンセミナーなど盛りだくさんの内容になっていました。  IoTに関する技術トピックやビジネス動向、実際の応用事例まで一度に見れた貴重な機会でした。これが無料で参加できるとは。。。来年も同様のイベントがあればぜひ参加したいです。

discovery2018.soracom.jp

また夜に行われたSORACOM UG(ユーザグループ)も面白い内容でした。実は今回のUGでは運営のお手伝いをさせていただきました。リストバンドとか作るとこやってました。

UGは9月に大きなイベントを開催予定だということで、そちらもぜひ手伝っていければと思っています。

全体所感

 今回のSORACOM Discovery2018では午前のキーノートセッションで行われた新発表祭りがハイライトだったと思います。特にクラウドへの認証代行を行うKのサービスSORACOM KryptoとSORACOM Harvestに続くLのダッシュボードサービス(SORACOM Lagoon)https://soracom.jp/services/lagoon/の発表が印象深かったです。また、SORACOM LTE-M Buttonの発表も見逃せない内容でした。

  • Lagoon

  • SORACOM LTE-M Buttonを聞いた瞬間の感想

 また、当日セッションを直接聞けなかったのですが懇親会でソラコムのソリューションアーキテクト松本さんご本人から伺ったSORACOM Beamへの認証情報がSIMごとに複数設定できる新機能もF-2SORACOMサービスを利用したIoTアプリケーションのクラウド連携で発表されたようです。個人的には嬉しい内容です。以下資料の37ページ目です。

www.slideshare.net

このブログでも紹介しているSORACOM BeamからGoogle Cloud IoT Coreへ接続する際にそうです。課題感は以下の過去記事に記載があります。今回の機能を使った接続検証の記事は別途記載します。

masato-ka.hatenablog.com

このようにセッション中にもアップデートがあるので、他にも見逃せないものがないか気になるます。本当の意味でのキャッチアップは大変そう。

聴講セッション

聴講したセッションは以下のセッションです。

  1. 《キーノートパネル》Discovery、Digitalization、Democratization 〜つながるデータがもたらす新価値〜
  2. IoTシステムにおけるデバイス管理とセキュリティ
  3. 動態管理 モノ・ヒトの位置情報をビジネスに活かす 〜車両管理・作業管理における実践効果〜
  4. IoT システム 最新アーキテクチャ・リファレンス ~デバイスからクラウドまでの最適解を求めて~

1. Discovery、Digitalization、Democratization 〜つながるデータがもたらす新価値〜

 内容は非公開とのことだったので記載しませんが、ウェザーニュースの石橋さんが印象的でした。ウェザーニュースの流星特番が好きなので、生石橋さんが見れたのは嬉しかったです。

2. IoTシステムにおけるデバイス管理とセキュリティ

 「IoTシステムにおけるデバイス管理とセキュリティ」では当日発表されたSORACOM Kriptonの解説がありました。SIMを認証キーとして利用するというコンセプト自体はソラコムサービスの当初からあった考え方だったと思います。これまでもこのコンセプトを体現するためSORACOM Endorseやメタデータサービスが存在していました。今回のSORACOM Kriptonではこの考え方をさらに進め、SIM認証を中心として、クラウド(現在はAWSの一部サービス)の鍵を作成、デバイスに対して提供する部分をSORACOM Kriptonが担うという形になります。また、認証時にSIMの情報が使えれば LTE/3GでなくてもWiFi・有線で接続するインターネット回線が使えるというのがポイントです。この場合インターネットに全くでずにセキュリティを守るというメリットはなくなりますが、大容量データや非構造化データを取り扱う際にSORACOMのサービスと連携できるのは有利になるのではないでしょうか。最近ではエッジコンピューティングなどでローカル側でデータを処理して送る方法を取ればLTE/3Gでもできなくはないと思います。どう棲みわけ関わりを作るかがポイントとなりそうだと個人的にです。いずれにせよ選択肢が増えることは良いことだと思います。

3. 動態管理 モノ・ヒトの位置情報をビジネスに活かす 〜車両管理・作業管理における実践効果〜

 「動態管理 モノ・ヒトの位置情報をビジネスに活かす 〜車両管理・作業管理における実践効果〜」では物の位置情報や利用履歴などをロギングし可視化する動態管理についてのパネルディスカッションでした。ただ可視化するだけではなく、それを使って業務の改善につなげていくのがポイントというお話でした。データをどのように活用するのか、まずは仮説を立てることが重要ということが語られ、意識はしているけど重要なポイントだと思いました。

4. IoT システム 最新アーキテクチャ・リファレンス ~デバイスからクラウドまでの最適解を求めて~

 SORACOMを使った複数パターンのリファレンスアーキテクチャが公開されていました。資料だけでも大変参考になるので、これからIoTのシステム構築を検討される方は見た方が良いと思います。(近いうちに公開されると思います)デジタルサイネージのシステムなどソラコムのサービスを使わない場合でもそのエッセンスは共通的で参考になります。さらにそれらがソラコムサービスを使うとより簡単に構築できることがわかると思います。

まとめ

 カンファレンス自体は大変楽しめる作りになっており、魅力的なセッションばかりでどれを見るか迷うものが多かったです。ビジネスからテクノロジー、エンジニアリングまで幅広くカバーされている話を1日で聞けるのは非常に貴重な機会なので今後も続けていただきたいと思います。また、ソラコムさんの今後の方向性として通信サービスではなくSIMを中心としたIoTのインフラ提供を行っていくという強い意志みたいなものを感じました。常々ソラコムさんのサービスはIoTデバイスのPaaSサービスみたいなものだと考えています。現場にいかに素早くデバイスを開発してデプロイしていくか。そのためのプラットフォームとしてソラコムのサービスが大変便利だと考えています。(以前のLTでもそんなつもりでしゃべりました。)これからも目が離せないIoTのプレーヤーです。  話は横に逸れますがソラコムの社員さんともお話しする機会があり、みなさん気さくで中が良さそうな人たちでした。雰囲気の良いチームや組織からはやはりそれにあった素晴らしいプロダクトが出るのだなと改めて思いました。自分のチームもそうあるように頑張りたい。

SORACOM BeamにGoogle Cloud IoT Coreへの接続設定をソラコムのAPI経由で設定する。

この記事について

この記事ではSORACOM APIを使って Google Cloud IoT Coreへの接続設定を行う方法を記載します。前回の記事ではSORACOMの管理画面からSORACOM Beamの設定を行い、Cloud IoT Coreへの接続設定を行いましたが今回はソラコムが提供するWEB APIを利用して設定を行ってみます。基本的にAPIを叩くだけですが、SORACOM BeamのCloud IoT Core向け設定をAPIで実効する方法など公式ドキュメント化されていない箇所があるので備忘録的に記載しています。

APIで接続設定する利点

前回の記事にも記載しましたが、SORACOM BeamからCloud IoT Coreへ接続する場合、Cloud IoT Coreに登録したデバイスとSORACOM Beamの設定は一対一の関係にする必要があります。これはCloud IoT Coreではデバイスが個別の証明書(秘密鍵)を持つのに対して、SORACOM Beamの仕様では1設定ごと(=1グループ)に証明書を1つしか設定できないことが理由です。そのため、複数のデバイスを接続するためにはデバイス(=SORACOM Air SIM)ごとにグループを作成し、SORACOM Beamの設定を行う必要があります。

f:id:masato-ka:20180623131229p:plain
GCPのデバイス設定とSORACOM Beam設定は一対一

複数の設定をSORACOM のユーザコンソールから設定するのは煩雑ですが、SORACOM Beamの設定はSORACOM APIから設定することができるため、APIでグループの作成と、SORACOM Beamの設定をすることで煩雑さから解放されます。この方法がわかればCloud IoT Coreの設定と合わせて管理ツールを作ることもできます。

APIからの設定

 ソラコムの提供するサービスは全てAPI経由で設定を行うことができます。当然Beamの設定についてもAPIから設定を行うことができます。今回はAPIのクライアントとしてCURLコマンドを利用します。その他のクライアントを使う場合は適宜よみかえを行ってください。soracom-cliAPI のSwaggerドキュメント、各言語のAPIクライアントライブラリが存在しています。現在のバージョンでは証明書の登録ができませんが、私が開発しているVisual Studio CodeのExtentionも利用できます。

 Cloud IoT Coreの設定やデバイスの登録、証明書の発行については以下の過去記事を参考にしてください。

masato-ka.hatenablog.com

なお以降のサンプルでは「//」をコメントとして扱っています。必要に応じて取り除いてください。

証明書の登録

まずはじめにCloud IoT Coreに接続するための認証情報を登録します。あらかじめ、Cloud IoT Coreにデバイスを登録する際に設定した公開鍵のついとなる秘密鍵を用意しておきます。以下のリクエスト送ることで、credential-device01と言うcredentialIDを持つ認証情報を作成することができます。

curl -X POST --header 'Content-Type: application/json;charset=UTF-8' --header 'Accept: application/json' \
--header 'X-Soracom-API-Key: API KEY' \
--header 'X-Soracom-Token: APIのトークン' \
-d '  {
    "description": "api-registry", //(1)
    "type": "googleIoT-credentials", //(2)
    "credentials": {//(3)
      "projectId": "careful-maxim-150804", 
      "region": "us-central1", 
      "registryId": "my-registry", 
      "deviceId": "newcamer", 
      "algorithm": "RS256", 
      "privateKey":"-----BEGIN RSA PRIVATE KEY-----\n..."(4)
    }
}' 'https://api.soracom.io/v1/credentials/credential-device01' //(5)
  • (1) 認証情報の概要を記載しておきます。
  • (2) type要素にCloud IoT Coreの認証情報であることを指定しておきます。
  • (3) credentials要素内ではCloud IoT Coreへの接続情報を入れます。Userコンソール画面を参考に入力します。先述の過去記事を参考にしてください。
  • (4) privateKeyにはpem形式の秘密鍵を設定します。この際、改行を「\n」に置き換えて1行の文字列として貼り付けてください。
  • (5) 認証情報のIDはAPIのパスバリューとして私ます。上記の例ではURL末尾のcredential-device01がcredentialIDとなります。任意の値を指定してください。デバイスごとに認証情報を使う必要があるため、「credential-デバイスID」など命名規則を決めておくと良いでしょう。

credentialIDは次のSORACOM Beamの設定で利用するため書き留めておきましょう。

SORACOM Beamの設定

SORACOM Beamの設定はSIMグループに対して設定します。また、SORACOM BeamからCloud IoT Coreへ接続する場合は前述の通り、1デバイスにつき、1グループが必要になります。そこで、API/groups エンドポイントに対して以下のリクエストを投げ、SIMグループの作成とSORACOM Beamの設定を行います。リクエストに成功した場合、レスポンスボディにgroupIdが含まれていますので書き留めておきましょう。SIMをグループに追加する際に利用します。

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' \
--header 'X-Soracom-API-Key: APIキー' \
--header 'X-Soracom-Token: APIトークン' \
-d ' {
    "configuration": {
      "SoracomBeam": {
        "mqtt://beam.soracom.io:1883": {
          "enabled": true,
          "name": "IoTCore",// (1)任意の設定名を追加する。
          "addEquipmentHeader": false,
          "addSignature": false,
          "addSubscriberHeader": false,
          "customHeaders": {},
          "skipStatusCode": false,
          "useClientCert": false,
          "useGoogleIoT": true,
          "googleIoTCredential": {
            "$credentialsId": "credential-device01" //(2)証明書の登録で登録した認証情報を指定する。
          },
          "addDeviceIdHeader": false,
          "destination": "mqtts://mqtt.googleapis.com:8883"//(3)Cloud IoT Coreの設定
        }
      }
    },
    "tags": {
      "name": "IoTCore2" //(4) グループ名固有の名前になるよう、デバイス名などを指定しておく。
    }
  }' 'https://api.soracom.io/v1/groups'

グループに対する設定はconfigurationセクションで行われます。また、SORACOM Beamへの設定はその中のSoracomBeamネームスペースに設定を記載します。各設定の要点を以下にまとめています。

  • (1) SORACOM Beamの設定名、任意の名前を指定可能。
  • (2) 「証明書の登録セクションで設定した認証情報を指定する。」
  • (3) Cloud IoT Coreのエンドポイントの設定 固定値になります。
  • (4) グループ名、どのデバイスの設定かわかりやすくするため、デバイス名+Groupなど命名規則を決めておくといいと思います。

なお、SORACOM Technology Camp の際に質問し回答をいただいた範囲ではグループ作成の上限数は決まっていないとのことです。

GroupへSIMを追加する。

以下のリクエストでSIMをグループに追加します。

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' \
--header 'X-Soracom-API-Key: APIキー' \
--header 'X-Soracom-Token: APIトークン' \
-d '{
  "groupId": "グループ作成時に取得した値",
}' 'https://api.soracom.io/v1/subscribers/{imsi}/set_group'

groupIdを記録し忘れた場合は以下のAPIを実効することでグループの情報を再度確認することができます。このリクエストは/v1/groupsのエンドポイントにリクエストパラメータでタグ名とその値のクエリを渡して検索しています。SORACOM Beamの設定でリクエストとして送ったJSON(4)の要素を指定しています。もしグループのタグ情報としてnameを指定していない場合は適宜グループの検索条件を指定してください。また、リクエストパラメータを設定しない場合は全てのグループを取得することが可能です。

https://api.soracom.io/v1/groups?tag_name=name&tag_value=IoTCore&tag_value_match_mode=exact

以上で設定は完了となります。追加したSIMを使いSORACOM BeamのMQTTエンドポイントmqtt://beam.soracom.io:1883へpub-subすることでCloud IoT Coreにメッセージが送れるようになります。

まとめ

 今回はSORACOM Beamの設定のみでしたが、Google Cloud IoT Coreへのデバイス追加を行うGCPAPIと組み合わせればデバイス追加を行うための管理サービスを作ることができます。実際に運用するためには証明書の管理などポイントがあると思いますが、小規模なデバイスを管理するのであればこの方法で十分ではないでしょうか。証明書自身はサーバ側で作り、ファイルに保存することなく、SORACOMとGCPの証明書管理サービスに投げ込めばセキュアに実現できるでしょうか。