Web SDK for Angular を利用したカスタムアプリケーションの作り方

投稿日/投稿者名

2019.10.7 / 高橋桃花



はじめに

本レポートは、Things Cloud の利用例をより知っていただくための実利用レポートとして作成したものです。Things Cloud は極力後方互換性を持つよう開発されていますが、今後のリリースにより、一部画面やコマンド、手順などが変更となったり、利用できない可能性があることをあらかじめご了承ください。 なお、作成にあたり、以下バージョンを用いています。

また、本レポートで使用している 「Web SDK for Angular」 は、「AngularJS のための Web SDK」とは異なります。以下の2点が大きな違いです。



難易度 ★★★


概要



前提条件

なお、本レポートでは手軽に扱える位置情報シミュレータを利用します。


【参考】シミュレータを利用する方法
シミュレータを利用する方法は、以下をご覧ください。(プリセットで位置情報の更新イベントを選択)
シミュレータは通常のデバイスと同様課金対象となりますのでご了承ください。本レポート実施後、不要なシミュレータは削除してください。

シミュレータの利用には、シミュレータを操作する権限が必要になります。権限追加操作には admins 権限が必要なため、権限が無い場合は Things Cloud のシステム管理者に依頼してください。

権限の追加方法は以下のとおりです。

image

image



所要時間(目安)



つくるもの

Web SDK for Angular を利用して、アプリメニューに追加できるカスタムアプリケーションを作成します。このカスタムアプリケーションへ、 Things Cloud API から ManagedObject の一覧情報を取得し、デバイス一覧と各デバイスの位置情報を表示する機能を追加します。

【完成イメージ】

アプリメニューで作成したアプリケーションを選択できるようになります。

image

アプリケーションの画面では、テナントから取得したデバイス一覧と、デバイスの現在値が表示されます。これらの値はリアルタイムに更新されます。

image

なお、本レポート完了時にできあがる成果物は こちら からダウンロードできます。
node_modules/ は上記のファイル一式に含まれていないため、npm install コマンドでインストールする必要があります。



開発の流れ

  1. アプリケーション用ディレクトリ作成
  2. コンポーネントファイルの編集
  3. app.module.ts の編集
  4. ビューファイルの編集
  5. ローカル開発環境での動作確認
  6. Things Cloud へのデプロイ
  7. 位置情報シミュレータを作成して動作を確認してみましょう



1. アプリケーション開発の準備

# CLI をインストール
$ npm install -g @c8y/cli

# アプリケーションディレクトリの作成
$ c8ycli new my-app
Application created. Go into the folder "my-app" and run npm install

$ cd my-app
$ npm install

package.json に記載されているデフォルトの UI バージョンは 1000.6.14 (本レポート執筆当時) です。UI と backend のバージョンが異なるため、コンソール画面には「You are running version 1004.6.14 of the UI and version 9.16.16 of backend!」という文字列が表示されますが、本レポートで作成するアプリケーションの動作の範囲内であれば問題ありません。



2. コンポーネントの作成・編集

my-app/
└── devices/
    ├── devices.component.html
    └── devices.component.ts

【参考】本レポート記載のアプリケーションを開発する際に必要となるファイル一覧

my-app/
├── app.module.ts
├── devices/
│   ├── devices.component.html
│   └── devices.component.ts
├── node_modules/
├── index.ts
├── package-lock.json
├── package.json
├── polyfills.ts
└── tsconfig.json
import { Component } from '@angular/core';
import { InventoryService, IManagedObject, IObservableOptions } from '@c8y/client';

@Component({
  selector: 'app-device',
  templateUrl: 'devices.component.html'
})

export class DevicesComponent {
  devices: IManagedObject;

  // 初回 GET リクエスト時のページングとリストのフィルタ設定
  private filter: object = {
    fragmentType: 'c8y_IsDevice',
    pageSize: 2000
  }

  // Observable 型データのオプション設定
  private options: IObservableOptions = {
    realtime: true
  }

  // コンストラクタで InventoryService を依存性注入(Dependency Injection)
  constructor(private inventory: InventoryService) {
    this.loadDevices();
  }

  // デバイス一覧情報を取得
  loadDevices() {
    const list$ = this.inventory.list$(this.filter, this.options);
    list$.subscribe((data) => {
      this.devices = data;
    });
  }
}

devices.component.ts の内容を順に説明していきます。

:
:
// 初回 GET リクエスト時のページングとリストのフィルタ設定
private filter: object = {
  fragmentType: 'c8y_IsDevice', // c8y_IsDevice フラグメントを指定
  pageSize: 2000                // クエリ結果のページングを 2000 に設定
}
:
:

初回 GET リクエスト時のページングとリストのフィルタを設定します。list$ メソッドにより Observable 型のデータを取得するとき、初回は GET /inventory/managedObjects によりデータを取得します。その後は、リアルタイム通知 の仕組みを用いて ManagedObject の変更が通知されます。

import { InventoryService, IManagedObject, IObservableOptions } from '@c8y/client';
:
:
// Observable 型データのオプション設定
private options: IObservableOptions = {
  realtime: true
}
:
:

Observable 型のデータにはオプションを設定できます。ここでは、realtimetrue に設定し、ManagedObject の変更を検知できるようにします。

import { InventoryService, IManagedObject, IObservableOptions } from '@c8y/client';
:
:
// コンストラクタで InventoryService を依存性注入(Dependency Injection)
constructor(private inventory: InventoryService) {
  this.loadDevices();
}
:
:

Things Cloud API からデータを取得するには、@cli/client ライブラリを使用します。 ここでは、ManagedObject の一覧情報を取得したいため client ライブラリから InventoryService をインポートし、依存性注入します。

:
devices: IManagedObject;
:
// デバイス一覧情報を取得
loadDevices() {
  const list$ = this.inventory.list$(this.filter, this.options);
  list$.subscribe((data) => {
    this.devices = data;
  });
}
:
:

次に、API からデータを取得します。Inventory のデータを取得する例として、以下の2つのメソッドがあります。

メソッド 内容 パラメータ 返却型
client.<endpoint>.list$(filter, options) 対象となるエンドポイントの一覧情報を取得 filter: object (オプショナル)
クエリ結果のページングとリストのフィルタの設定
options: IObservableOptions (オプショナル)
Observable 型データの設定オプション
ObservableList<TData>: サブスクライブできる Observable 型のリスト
client.<endpoint>.detail$(entityOrId, options) 対象 id を持つ ManagedObject の詳細情報を取得 entityOrId : string
options: IObservableOptions (オプショナル)
Observable 型データの設定オプション
number

上記のメソッドは Observable 型のデータを返します。Promise 型を返したい場合は、list()detail() のように末尾の $ を削除してください。

ここでは、一覧情報を取得するため、list$ メソッドを利用して ManagedObject のリストを取得します。先程定義したフィルタとオプションをパラメータとしてメソッドに渡します。list$ をサブスクライブし、データの変更を監視します。

3. app.module.ts の編集

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { CoreModule, BootstrapComponent, CommonModule } from '@c8y/ngx-components';

import { DevicesComponent } from './devices/devices.component'; // DevicesComponent をインポート

@NgModule({
  imports: [
    BrowserModule,
    RouterModule.forRoot([{ path: '', component: DevicesComponent }], // アプリケーションのルートモジュールに DevicesComponent を指定
    { enableTracing: false, useHash: true }),
    // c8y- プレフィックスが付くコンポーネントを使用するためのモジュール
    CoreModule,
    // データアクセスと翻訳のためのモジュール、@c8y/client の使用に必要
    CommonModule
  ],
  declarations: [DevicesComponent], // DevicesComponent を追加
  bootstrap: [BootstrapComponent]
})
export class AppModule {}

app.module.ts に以下の3つを追加・編集します。



4. ビューの作成・編集

次に、devices.component.html を以下のように編集します。

<c8y-title>デバイス一覧</c8y-title>
<table class="table">
  <tr>
    <th>ID</th>
    <th>名前</th>
    <th>現在位置</th>
  </tr>
  <tr *ngFor="let device of devices">
    <td *ngIf="device.c8y_IsDevice !== undefined">{{device.id}}</td>
    <td *ngIf="device.c8y_IsDevice !== undefined">{{device.name}}</td>
    <td *ngIf="device.c8y_Position !== undefined">lat: {{device.c8y_Position.lat}}, lng: {{device.c8y_Position.lng}}, alt: {{device.c8y_Position.alt}}</td>
  </tr>
</table>

Interpolation記法 {{}} により、データバインディングを実現します。コンポーネント側で devices データの変更があった場合には、ビュー側も変更されます。 表の .table クラスは CUMULOCITY IoT UI Style Guide を使用しています。



5. ローカル開発環境での動作確認

以下のコマンドにより、ローカルホストでの動作確認ができます。以下では、ローカルホストへのリクエストを -u オプションで指定した URL へプロキシしています。

$ c8ycli server -u https://<テナント名>.je1.thingscloud.ntt.com

もしくは、package.json"scripts""start" の項目の c8ycli server 以降に -u https://<テナント名>.je1.thingscloud.ntt.com を追加することでリクエストを指定 URL へプロキシできるようになります。(この場合は、npm start コマンドを使用します。)

{
  "name": "my-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "c8ycli server -u https://<テナント名>.je1.thingscloud.ntt.com",
    "build": "c8ycli build",
    "deploy": "c8ycli deploy",
    "locale-extract": "c8ycli locale-extract"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@angular/animations": "7.2.2",
    "@angular/common": "7.2.2",
    "@angular/compiler": "7.2.2",
    "@angular/core": "7.2.2",
    "@angular/forms": "7.2.2",
    "@angular/http": "7.2.2",
    "@angular/platform-browser": "7.2.2",
    "@angular/platform-browser-dynamic": "7.2.2",
    "@angular/router": "7.2.2",
    "@angular/upgrade": "7.2.2",
    "@c8y/ngx-components": "1004.6.14",
    "core-js": "^2.6.2",
    "rxjs": "~6.3.3",
    "zone.js": "~0.8.28",
    "@c8y/style": "1004.6.14"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.10.4",
    "@angular/compiler-cli": "7.2.2",
    "@angular/language-service": "7.2.2",
    "typescript": "3.1.6",
    "@c8y/cli": "1004.6.14"
  },
  "c8y": {
    "application": {
      "name": "my-app",
      "contextPath": "my-app",
      "key": "my-app-application-key"
    },
    "cli": {}
  }
}

c8ycli server -u https://<テナント名>.je1.thingscloud.ntt.com もしくは、npm start を実行した後、Webブラウザに以下のURL ( http://localhost:9000/apps/my-app/ ) を入力し、アクセスします。アクセス後、テナント名・ユーザ名・パスワードの入力が求められるためこれらを入力し、リクエストをプロキシしているテナントへログインします。ログイン後、アプリケーションの動作確認ができるようになります。



6. Things Cloud へのデプロイ

ローカル開発環境での動作が正常であることを確認したら、Things Cloud へデプロイします。アプリケーションのルートディレクトリ (my-app/ 直下) に移動し、以下のコマンドを実行します。

$ c8ycli build
$ c8ycli deploy
prompt: Instance URL:  (http://demos.cumulocity.com) テナントのURLを入力 (例: https://<テナント名>.je1.thingscloud.ntt.com)
prompt: Username:  (admin) ユーザ名を入力
prompt: Password: パスワードを入力

c8ycli build コマンドを実行し、アプリケーションをビルドします。ビルド後、アプリケーションのディレクトリに dist/ ディレクトリが作成されます。このディレクトリがが作成されたことを確認したら、c8ycli deploy コマンドで Things Cloud へアプリケーションをデプロイします。デプロイコマンド実行時に、アプリケーションのデプロイ先 URL とユーザ情報の入力が必要になります。



7. 位置情報シミュレータを作成して動作を確認してみましょう

位置情報シミュレータを作成して、デプロイしたアプリケーションの動作を確認してみましょう。

image

以上により、Web SDK for Angular を利用したカスタムアプリケーションの作成は完了です。

【参考】 以下に Web SDK for Angular を利用する上で参考となる Web サイトを記載しています。
※ 以下はソフトウェア・エー・ジー株式会社の Web サイトです。