ドイツでIoTについて考えた

モバイルファースト室、@kaaです。

現在開催されているIFA 2014のため、ドイツのベルリンへ行ってきました。 IFAとはアメリカのCES,スペインのMWCと並んで世界3大家電見本市と言われる ものの一つで、その中でも白物家電中心のイベントです。

f:id:futura24pt:20140906062655j:plain

ここに今回クックパッドはソニーのSmart EyeGlassの出展に合わせアプリ開発を行い展示をしております。 今回はeyeglass上にレシピの手順が表示され、スマホにはレシピの詳細が表示されるものです。 利用シーンとしてはまずスマホ上でレシピを選び、料理中はeyeglassでレシピの手順を見ていただいて、 詳細はスマホで、という利用方法になります。

f:id:futura24pt:20140910103500j:plain f:id:futura24pt:20140910103531j:plain

参考:[IFA 2014]ソニーが「Xperia Z3」「Smart EyeGlass」など発表、各種APIも公開

その際に、家電のIT化、ウェアラブルデバイスを中心に他の展示を 見てきたのでまとめてみようかと思います。

各展示の状況

国内ですとネットに繋がる家電、スマート家電というとpanasonicさんが 先駆けていた面があるのでご存知の方も多いかと思います。 他にも海外のメーカーを見ると、

LG

f:id:futura24pt:20140906062741j:plain

f:id:futura24pt:20140906062815j:plain

大きくスペースを取って展開しています。 これはオーブン。スマホ連携ですね LGはテレビで曲面ディスプレイを大きく展示していましたが、白物家電も多く展示していました。

f:id:futura24pt:20140906062848j:plain

LGはウェアラブルも。 reddotはドイツのデザイン賞なので推しているのでしょうか

Grundig

ドイツの家電メーカーGrundig。

f:id:futura24pt:20140906062959j:plain

f:id:futura24pt:20140906063002j:plain

日本で知名度は低いですがかなり大きなブースでした。 デザインが統一されている印象。写真はガスコンロですがメニューが左右、下と移動できます。

BOSCH

f:id:futura24pt:20140906063105j:plain

f:id:futura24pt:20140906063122j:plain

こちらもドイツ。BOSCH。日本では工具メーカーとして有名ですが洗濯機なども出しています。 静かな洗濯機の広告をよく見ました。

haier

f:id:futura24pt:20140906063152j:plain

ハイアール。こちらは白物家電中心です。 日本でもここ数年見るようになりましたね。白物家電中心に大きなブースで展開しています。

Miele

f:id:futura24pt:20140906063254j:plain

ミーレ。高級家電メーカーですね。 食洗機や洗濯機、調理家電が多いです。

こういったように大手白物家電メーカーだとだいたいネット連携家電のコーナーがあります。 日本との違いとしてはコーヒーマシンを各社展示していることや掃除機が重視されている。 あと組み込み家電が多いので洗濯機のサイズが規格化されているようです。上面は平らだし。

f:id:futura24pt:20140910165640p:plain

写真はドイツの家電量販店での洗濯機売り場。洗濯機をキッチンに食洗機のように組み込みにすることも多いそう。 このように売る商品自体にも市場による差があります。

ネット家電のできること

調理家電でしたらレシピをダウンロードするとか、機能面のアップデート、 洗濯機などなら携帯から操作、エアコンなら外から操作できたり。

IoTというと、みんながインターネットにつながるように聞こえますが 実際は家のWIFIに繋がってコントロール、というものも多くあります。 それぞれはwifi内での接続でいて、ゲートウェイになるもの、例えば STBだったりPS4だったりメディアサーバー(NAS)だったりが外との接続の 役目を持つのではないでしょうか。

現在各社それぞれがネットワーク化を進めているようにみえますが、 もちろん共通化の動きもあるようで、例えばQIVICON。 これはスマートフォンからの家電操作の共通化を図っており、主導は T-mobile(日本でいうドコモのようなドイツの大手キャリア)です。 参画企業にはサムスン、ケルヒャー、フィリップスなど30社以上あります。

まだどこも探っている状況といった感じはありますが、大手メーカーは かなり取り組んでおり機能を使う使わないに限らずいつの間にか 当たり前になっている可能性もあると思いました。 家電は製品寿命が長い上に、家電ごとに買い替えのタイミングが バラバラ(新生活を始めるなどは別)なので、同じメーカー限定での 家電の連携は難しい点があると思います。(同時に揃える人が少ない) ネットワークで出来る事自体はある程度共通化されていくものなのかもしれません。

Android Publisherによるストア管理の自動化

技術部開発基盤グループの id:gfx と申します。

Google I/O 2014で発表されたGoogle Play Developer API (Android Publisher)を調べてみました。

Android PublisherはPlayのアプリケーション情報やAPKバイナリの操作を行うAPIで、これがあればリリースエンジニアリングの自動化(Release Engineering as Code)や、アプリの説明文や更新情報のgit管理などができるようになります。リリースエンジニアリングは属人化しがちなので、その作業をコードに落としこむという点で大きな意味を持つAPIだと言えるでしょう。AndroidアプリケーションにおけるRelease Engineering as Codeの実現に一歩近づくことができます。

本エントリでは、Android Publisher API(以下、単に「API」といいます)について簡単に紹介します。

APIでできること

  • APKのアップロードやアプリの説明文、更新情報などを取得・更新ができる
  • IABの設定を行える(このエントリでは未検証)
  • APIリクエストの限界は 200,000 queries per day

サンプルコードについて

詳細はこのエントリでは省きますが、このエントリのコードはGradle+Groovyプロジェクトで試しました。依存ライブラリは以下のとおりです。

dependencies {
    compile 'com.google.apis:google-api-services-androidpublisher:v2-rev2-1.19.0'
    compile 'com.google.api-client:google-api-client:1.19.0'
    compile 'com.google.api-client:google-api-client-gson:1.19.0'
}

APIを使う準備

AndroidPublisher service clientの生成

認証方法は「OAuth2」と「service account」の二種類あります。今回はservice accountで認証しましょう。以下の「Getting Started」に従って、Developer Consoleでservice accountを作ってAPIの設定をしてください。

認証の流れとしては、認証情報を設定したGoogleCredentialを生成し、それをもとにAndroidPublisherを生成します。

認証情報としては、Google API Developer Consoleで生成した Google Play Android Developer-xxxx.json のなかの client_email と、 Google Play Android Developer-xxxx.p12 ファイルが必要です。

// Google Play Android Developer-xxx.json
public static class Account {

    public String private_key_id

    public String private_key

    public String client_email

    public String client_id

    public String type
}

// ...

// create AndroidPublisher instance
def account = new Gson().fromJson(credentialFile(jsonName).text, Account);
assert account.client_id;

def httpTransport = GoogleNetHttpTransport.newTrustedTransport()
def jsonFactory = JacksonFactory.getDefaultInstance()

def credential = new GoogleCredential.Builder()
        .setTransport(httpTransport)
        .setJsonFactory(jsonFactory)
        .setServiceAccountId(account.client_email)
        .setServiceAccountScopes(AndroidPublisherScopes.all())
        .setServiceAccountPrivateKeyFromP12File(credentialFile(p12Name))
        .build()

def publisher = new AndroidPublisher.Builder(httpTransport, jsonFactory,
        credential)
        .build()

このpublisherオブジェクトに対してリクエストを生成することで、Playのアプリケーション情報を操作します。この部分はメソッドにして分離しておくといいですね。

なお、認証情報などのクライアント生成のための情報が足りないとIllegalArgumentExceptionをただ投げるだけなので、これに悩まされたら思い切ってソースを読みましょう。

編集の準備を行う

AndroidPublisherを生成したら、APIを呼ぶために、リクエストのための準備をします。これはどのリクエストでも共通です。

// 操作は特定のpackage名(application ID)に対して行う
def packageName = "com.example.android.app"


// 編集操作の集合であるeditsを作る
// 最終的に `edits.commit()` することで
// editsにリクエストされた操作がコミットされる
def edits = publisher.edits()
def editRequest = edits.insert(packageName, null)
def appEdit = editRequest.execute()

// `appEdit.getId()` を使ってeditsに対して操作する
// ...

これでようやくAPIを呼ぶ準備が整いました。次に、実際にAPIを見てみましょう。

Android Publisher API

Edits.apks

APKを操作します。list()とupload()メソッドを持っています。

まずlist()で情報を取得してみます。取得できるのはversionCodeとapk binaryのSHA1値です:

// list
Apk apk = edits.apks()
        .list(packageName, appEdit.getId())
        .execute()
        .getApks()
        .first()
println("versionCode: ${apk.getVersionCode()}, SHA1: ${apk.getBinary().getSha1()}")

次にupload()ですが、これはpackage名とapkファイルがあればできます。最後にcommitするまで実際の更新は適用されません。なお、不正なファイルをアップロードするとエラーになります:

def mimeType = "application/vnd.android.package-archive"
def apkFile = new FileContent(mimeType,
        new File('./app/build/outputs/apk/app-release.apk'))

Apk apk = edits.apks(
        .upload(packageName, appEdit.getId(), apkFile)
        .execute()

println("uploaded: versionCode: ${apk.getVersionCode()}, sha1: ${apk.getBinary().getSha1()}")

edits.commit(packageName, appEdit.getId())
    .execute()

Edits.apklistings

その他のAPIについても同様に操作できます。たとえば、Edits.apklistingsは言語(ロケール)ごとの更新情報を取得・更新できます。操作にはバージョンコードが必要なので、必要に応じて Edits.apks から入手するとよいでしょう。

edits.apklistings()
        .list(packageName, appEdit.getId(), apk.getVersionCode())
        .execute()
        .getListings()
        .each { ApkListing listing ->
    println("recent changes: ${listing.getRecentChanges()} (${listing.getLanguage()})")
}

同様に、 管理者の連絡先用の Edits.details 、公開状態を操作する Edits.tracks 、タイトルや説明文を操作する Edits.listings などがあります。

さてここまでの前提知識があればオフィシャルのREST APIリファレンスとAndroidPublisherのjavadocを元にAPIを使えるようになると思います。

おまけ:API使用の注意点

API Usage Instructions に書いてあることのまとめです。

  • productionはもちろんのこと、alpha/betaリリースであっても、必要のない限り1日1度以上リリースすべきではない。頻繁なリリースはユーザーに負担をかける。
  • 外注先などの協力会社にアプリの作成や公開・配付を行わせてはいけない。それはGoogle Play Developer API Terms of Serviceに違反している
  • 協力会社にアプリの開発を任せる場合は、開発用アカウントを共有してはいけない。パーミッションを制限したアカウントを作ってそれを使わせること
  • 協力会社には作成したサービスアカウントを与えないことを奨励する