masato-ka's diary

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

if-up 2019に参加した話。

この記事について

この記事ではソラコムさん主催のif-up 2019へ参加した感想について記載しています。if-upは2017年に開催されたソラコムさん主催のイベントです。その後同名のイベントはなかったのですが、今回パワーアップした形で帰ってきました。

if-up 2019の概要について

前述の通り、if-upは2017年に同名イベントが開催されましたが、今回は少し毛色が違ったイベントになったと感じました。詳細は以下のイベントページにを確認いただければと思います。

if-up2019.soracom.jp

毛色が違った大きな点としてはこれまでのイベントではIoTにおける課題解決をソラコムサービスでどうやって解決するかという内容が主体となっていたのですが、今回のイベントではその部分は少しトーンダウンしています。日本のものづくり、サービス開発は今どうなっているのか、みんな何を課題に取り組んでいるのか?そんなトーンのイベントとなっていました。 イベント冒頭のキーノートセッションでは「プロダクトの裏にはパッションをもった人とチームがいる!」、「プロダクトづくりの前提が変わった」、「日本からもっと良いプロダクトが出てもいいはず」という問いかけから始まり、大変興味深い内容のイベントとなりました。イベント全体を通して特に印象に残ったポイントについて紹介していきます。

if-upで印象に残ったポイント

世の中にないものを生み出すということ

 午前のキーノートでの主題的なテーマだと感じたことです。新しいプロダクトを作る際に、そのコンセプトが果たして正しいのか、それは便利なのかは誰にも分かり得ないことです。良いプロダクトを作るためにまた、作る側のパッションを保つためにもこういった不安を払拭していく必要があると思います。  そんな中でGroovXさんとソラコムさんのプロダクト開発で共通しているなと思ったことが、MVPを作り、ユーザへの提示を素早く行っていくことが一つの会になるのだなと思いました。Agile的な取り組みでは当たり前の解決策ではなるのですが、論より証拠というのはパワポ100ページよりも説得力がある非常にためになるお話でした。  GroovXさんのLOVOTの開発に関するお話の中でLOVOTはロボットではあるけども「便利ではなく心のケアを中心にプロダクトを作った」けれどもまだ形も無いもので投資家の理解も得られなければ、身内からも不安になる。そこで、MVPを作って仮説検証を繰り返し自分たちの目指す方向を正しく見定めたとのことでした。またソラコムさんのお話でもBeamからFunnelそしてHarvestとプロダクトが進化した経緯をベースに同様のことをおっしゃられていたと思います。

日本のプロダクトが売れないのはなぜか?

日本のプロダクトが売れないのは良いプロダクトが作れないのではなく、良いプロダクトの定義が変わったという話が興味深かったです。つまり日本のプロダクトは昔から同じもので過去の基準からすればいいもののはずだけど、そもそも世の中が考える良いプロダクトの基準が変わったため売れなくなってしまったという話です。じゃあ、そもそも「新しい良いプロダクトとはなんなのか?」について明確な定義は出ていなかったと思いますが、パネラーの方達から語られたのは

  • 良いプロダクトの定義が変わったよりはトレンドに振り回されず芯を通したプロダクト開発が必要である。
  • 自分たちが何をやっているのかしっかりをパッションを持つ。
  • 自分たちが何者なのかをはっきりさせる。

ということでした。プロダクトの機能を提供するのではなく、その機能が与える価値をはっきりとさせる、自分たちがユーザへ与える価値か解決する課題をしっかりと定義すること。これが良いプロダクトを作る秘訣なのかなと思ったり。少し前に流行ったコトづくりと似通ったところはありますが、プロダクトの価値としては本質的なんだろうなと思いました。

まとめ

 良いプロダクトをいかに作り出していくのかというのは非常に難しいテーマだと常日頃思います。今日のif-up2019参加してまだまだ振り返りきれていないところもあるのですが、やはり自分たちがテクノロジーを使い、いったい何に取り組むのかを明確化し定義する、それを素早く形にしていき検証を行っていくのが必要なのかなとも思います。それは大変難しいことでもあるのですが。。。

grpc-spring-boot-starterでSpringBootへgRPCを導入する。

# この記事について この記事ではgrpc-spring-boot-starterを使ってSpringBootでgRPCを利用する方法について記載します。主に自分向けの備忘録的記事となります。

プロジェクトの設定

ビルドツールはMavenを利用します。SpringBootのライブラリ作成後、pomのdependenciesに以下を追加して依存関係にgrpc-spring-boot-starterを追加します。 grpc-spring-boot-starterはgRPCをSpringBootで利用できるようにするAutoConfigurationを実行します。

<dependencies>
        <dependency>
            <groupId>io.github.lognet</groupId>
            <artifactId>grpc-spring-boot-starter</artifactId>
            <version>3.1.0</version>
        </dependency>
 </dependencies>

ビルドを実行するプラットフォームを特定するためにプラグイン拡張を追加します。プロトコルバッファをビルドするためのprotocコマンドダウンロードに利用します。

<build>
...
<extensions>
      <extension>
           <groupId>kr.motd.maven</groupId>
           <artifactId>os-maven-plugin</artifactId>
           <version>1.5.0.Final</version>
      </extension>
</extensions>
...
</build>

さらにpurotobuf-maven-pluginを追加することで、Mavenのビルドプロセスの中でプロトコルバッファをコンパイルできるようにします。

<build>
...
<plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.6.0:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.18.0:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
...
</plugins>
</build>

上記でgRPC導入の設定は完了です。

gRPCのインタフェース定義

gRPCではprotoファイルと呼ばれるファイルでRPCの定義を記述します。記述されたprotoファイルからprotobuf-manve-plugin(実際にはprotocコマンド)がgRPCのサーバ側の抽象クラスとクライアントコードを自動生成します。

protoファイルの作成

以下のようなprotoファイルで定義します。 先頭の「option java_package」で生成後のコードのパッケージを定義します。プロジェクトのパッケージに合わせて適宜変更します。

syntax = "proto3";

option java_multiple_files = true;
option java_package = "ka.masato.grpc.demo.grpcmavendemo";
option java_outer_classname = "GreetClass";

package greet;

service Greet{
    rpc greeting (GreetRequest) returns (GreetResponse);
}


message GreetRequest{
    string value = 1;
}

message GreetResponse{
    string value = 1;
}

protoファイルの文法については以下を参照ください。

developers.google.com

protoファイルのビルド

protoファイルのビルドは前述のようにMavenのビルドプロセスの中で実行れます。以下のようにビルドを実行します。

$ mvnw clean package install

実行後、target/generated-souces/protobuf配下に生成されたコードが格納されています。IntelliJ IDEAで実行した際にはclassパスにも追加されているはずのなので、そのまま、srcフォルダ配下のパッケージから参照することができます。

gRPCの実装

生成されたコードをベースにサーバとクライアントを実装します。

サーバ側の実装

生成されたコードに含まれるGreetGrpc.GreetImplBaseを継承したクラスを作成します。この抽象クラスにはprotoファイルで定義したサービスがメソッドとして定義されており、これをオーバライドすることでAPIを実装します。また、継承クラスにはgrpc-spring-boot-starterで定義されている@GRpcServiceアノテーションをつけることで、gRPCのサーバとして登録されます。

@GRpcService
public class endpoint extends GreetGrpc.GreetImplBase{

    @Override
    public void greeting(GreetRequest request, StreamObserver<GreetResponse> responseObserver) {

        String value = request.getValue();
        GreetResponse greetResponse = GreetResponse.newBuilder().setValue("Greeting!"+ value).build();
         responseObserver.onNext(greetResponse);
         responseObserver.onCompleted();

    }
}

クライアントの実装

クライアント側ではスタブを作成し、スタブ経由でサービス側のメソッドを呼び出します。正確かはわかりませんがManagedChannelはgrpc-spring-boot-starterでbean定義されていると思います。

public class GreetClient {

    private final GreetGrpc.GreetBlockingStub stub;


    public GreetClient(ManagedChannel managedChannel) {
        this.stub = GreetGrpc.newBlockingStub(managedChannel);
    }

    public String getHello(){
        GreetRequest greetRequest = GreetRequest.newBuilder().setValue("Hello").build();
        GreetResponse greetResponse = this.stub.greeting(greetRequest);
        return greetResponse.getValue();

    }

}

まとめ

grpc-spring-boot-starterを使うとSpringBootで簡単にgRPCを実装することができました。また、proto-buf-mavenプラグインを利用することで、Mavenのビルドプロセスの中でプロトコルバッファのファイルからgRPCのコードを自動生成することができました。gRPCはprotoファイルで定義した内容からサービスの実装インタフェースと対応するクライアントコードを自動生成でき、サービス間通信のインターフェースを実装と定義を紐付ける良い方法だと思います。実際の開発にはprotoファイルの管理やなど実装以外に工夫が必要そうです。

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が控えめに言って最高だった話

更新

2019年2月12日付けで以下のアナウンスがありました。内容としてはAndroidThingsはスマートディスプレイ向けに再フォーカスするとの内容です。一応当面はRaspberry Pi3Bは利用できるとのことでしたが、非商用での利用です。 2019年以降はCloud IoT CoreやCloud IoT Edgeを利用してくださいとのことです。

https://android-developers.googleblog.com/2019/02/an-update-on-android-things.html?m=1

この記事について

 この記事では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は追っていきたいテーマだ。