Web SDK for Angular を利用したカスタムウィジェットの作り方2

投稿日/更新日/投稿者名

2020.7.31 / 2020.10.27 / 川戸美輝

2025.1.30 / 吉冨寿一郎

はじめに

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

  • ver 1018.0.259 (frontend)
  • ver 1018.0.405 (backend)

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

  • 使用フレームワークのバージョンが AngularJS v1.x から Angular へアップデート
  • CLI (コマンドラインインタフェース) が c8y (cumulocity-tools) から c8ycli (@c8y/cli) へ変更

Web SDK for Angular を利用する上では、以下のWebサイトが参考になります。 ※ Cumulocity社の Web サイトが含まれます。



難易度 ★★★


概要

Web SDK for Angular を利用して、デフォルトで提供しているウィジェット以外に自らウィジェットを開発する手法について、サンプルとして開発した「View Widget」を用いて説明します。本レポートでは、デバイスから取得するデータとして位置情報を利用します。

Web SDK for Angular を利用したアプリケーション開発における基本的な部分は、カスタムアプリケーションの作り方と重複した内容もございますので、こちらも合わせて読む事で一層理解が深まると考えられます。

本レポートで紹介するカスタムウィジェットの作り方は2つのページから構成されており、それぞれの内容は下記の通りです。

  • 本レポートの紹介内容
    • Angular版 カスタムウィジェットの作り方1 :静的な情報のみを表示するウィジェット「View Widget」の開発
    • Angular版 カスタムウィジェットの作り方2 :1で作成したウィジェットに「デバイスから取得したデータを表示」する機能を追加(本ページ)

  • 本ページで学べること
    • Web SDK for Angular を使ったカスタムウィジェットの開発方法
    • @c8y/client ライブラリを用いて Things Cloud API からリアルタイムにデータを取得する方法
    • ローカル開発環境での動作確認の仕方、Things Cloud へのデプロイ方法



前提条件

  • 次の言語/フレームワークを扱えること
    • HTML5
    • CSS
    • TypeScript
    • Angular v14.0.0以上推奨
  • 開発環境に以下をインストールしていること
    • Node.js v18推奨
    • npm (Node.js と一緒にインストールされます)
    • @c8y/cli パッケージ (c8ycli コマンドの使用に必要です)
  • 位置情報を取得するため、以下のどちらかを満たしていること
    • Things Cloud に接続済みの位置情報が取得できるデバイスがある
    • Things Cloud で位置情報シミュレータを利用している

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



所要時間(目安)

  • 約30分(本レポートに記載されたコードをそのまま利用する場合)



つくるもの

カスタムウィジェットの作り方1で作成したウィジェット「View Widget」に対して機能を追加する事で、カスタムウィジェット開発の基礎を学びます。 今回は、デバイスから取得したデータをリアルタイムで表示する機能を追加します。ここで、デバイスから取得するデータとして位置情報を選択します。



【完成イメージ】

image
ウィジェット作成画面に「View Widget」が表示されます。

image
「View Widget」を選択し、位置情報を送信するデバイスを設定、さらに表示するメッセージを入力します。

image
このようにウィジェットとして表示されます。デバイスの位置情報はリアルタイムに更新されていきます。

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



ウィジェット開発の準備

カスタムウィジェットの作り方1を実施していただいている場合、開発用ディレクトリは以下のような構成となっているはずです。 これらのファイルを必要に応じて編集・追加する事で、ウィジェットに機能を追加することができます。 本レポートで追加する「デバイスの情報をリアルタイムに表示する」機能であれば、view-widget.component.tsを編集するだけで良いでしょう。

<<root folder>>
	|
	└── my-cockpit
            ├── app.module.spec.ts
            ├── app.module.ts
            ├── dist //Things Cloudにデプロイする際に生成される
            ├── i18n.ts
            ├── index.ts
            ├── jest.config.js
            ├── ng1.ts
            ├── node_modules
            ├── package-lock.json
            ├── package.json
            ├── polyfills.ts
            ├── setup-jest.js
            ├── tsconfig.json
            ├── tsconfig.spec.json
            ├── view-widget-config.component.ts
            └── view-widget.component.ts	



デバイス選択画面の追加

本レポートで作成するウィジェットは、ウィジェット作成時に選択したデバイスからの情報を取得するため、 前回のレポートにて、デバイス選択画面の非表示オプションを有効にしていた場合、 これを無効に変更する必要があります。

具体的には、app.module.ts中のproviders:を以下の様に編集します。 これにより、ダッシュボード上にウィジェットを作成する際、対象となるデバイスを選択する項目が追加されます。

  providers: [
    hookComponent({
      id: 'hoge.view.widget', //一意なIDを設定
      label: 'View Widget',
      description: 'Can display a demo',
      component: WidgetDemo, //コンポーネントを関連付け
      configComponent: WidgetConfigDemo
      /*  ここに記述されていたデバイス選択画面に関するオプションを削除  */
    })
	]



デバイスから取得したデータのリアルタイム表示

続いて対象となるデバイスから取得したデータをリアルタイムに表示する機能を追加していきます。 ここまでの作業で既に2つのコンポーネントを作成しているため、これらを編集して機能を実装します。


今回の場合、view-widget.component.ts を以下のように編集します。

// 必要なライブラリをimport
import { Component, Input, OnInit } from '@angular/core';
import { InventoryService, IManagedObject, FetchClient, Realtime } from '@c8y/client';

// ウィジェットに表示する内容を定義
@Component({
	selector: 'c8y_custum-widget',
	template: `<h1>{{config?.text || 'No text'}}</h1>
			<h2>name:{{config?.device.name}}</h2>
			<p>position(lng):{{positions?.lng}}</p>
			<p>position(lat):{{positions?.lat}}</p>
	`,
	styles: [`h1{ color: red }`]
})

export class WidgetDemo implements OnInit {
    @Input() config; // 親コンポーネントから受け取る設定オブジェクト
    positions: any; // デバイスから取得した位置情報を格納するオブジェクト
    devID: number; // デバイスIDを格納する変数

    private inventoryService: InventoryService; // InventoryServiceのインスタンス
    private realtime: Realtime; // Realtimeのインスタンス

    // コンストラクタで FetchClient を使って InventoryService と Realtime を初期化
    constructor(private fetchClient: FetchClient) {
        this.realtime = new Realtime(fetchClient);
        this.inventoryService = new InventoryService(fetchClient);
    }

    // コンポーネントの初期化時に呼ばれるメソッド
    ngOnInit() {
        this.devID = this.config.device.id; // 設定オブジェクトからデバイスIDを取得
        this.loadRealtimePositions(); // 位置情報をリアルタイムで取得するメソッドを呼び出す
    }

    // 位置情報をリアルタイムで取得するメソッド
    loadRealtimePositions() {
        // ページロード時にデバイスの位置情報を非同期で取得し、初期表示  
        (async () => {
            // デバイスのManagedObjectを取得
            const {data, res} = await this.inventoryService.detail(this.devID);
            console.log(data); // デバッグ用に取得したデータをコンソールに表示
            // 位置情報データを更新
            this.positions = data.c8y_Position;
        })();

        // デバイスのManagedObjectのデータ変更をリアルタイムに監視して、位置情報を更新
        this.realtime.subscribe(`/managedobjects/${this.devID}`, (notifiedData) => {
            console.log(notifiedData); // デバッグ用に通知されたデータをコンソールに表示
            // 位置情報データを更新
            this.positions = notifiedData.data.data.c8y_Position;
        });
    }
}

view-widget.component.ts に追加した loadRealtimePositions() では、realtime.subscribe() を利用することで対応するデバイスの情報をリアルタイムに講読しています。



シミュレータの準備

作成したアプリケーションの動作確認を行う前に、ウィジェットに表示するデバイスとして位置情報シミュレータを作成します。 手順は以下の通りです。

  • デバイス管理アプリケーションからデバイスタブを開く
  • シミュレータ ⇒ シミュレータを追加 を選択
  • 位置情報シミュレータを新たに作成
  • シミュレータのスイッチを ON にしてステータスを実行中へ変更

さらに、新しいグループを用意し、作成した位置情報シミュレータを割り当てておきましょう。 このグループのダッシュボードにカスタムウィジェットを設置します。



ローカル環境での動作確認

これ以降に行う動作確認とThings Cloudへのデプロイにおける基本的な操作はAngular版 カスタムウィジェットの作り方1で説明したものと同様です。


以下のコマンドにより、ローカルホストでの動作確認ができます。以下では、ローカルホストへのリクエストを -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 コマンドを使用します。)

ローカルで動作確認を行う場合、前回のレポートにてアップロードしたui-assetsへアクセスできないため、 ブランドロゴ等は表示されないことに注意してください。 ここでは、作成したウィジェットが正常に動作することのみを確認します。

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

ここで、テナントIDとはt<number>の形で定義される固有の識別子を指します。テナントIDの確認方法は、基本的には以下の3種類です。

  • テナントへログインし、右上のユーザアイコンをクリックして、プラットフォーム情報から確認する
  • APIを使用してテナント情報を取得する(参考ページ
  • 親テナントの管理アプリケーションにログインし、サブテナントメニューから確認する

image

画面左のメニューから先ほど作成したグループを選択し、ダッシュボードを追加します。 追加されたダッシュボードにウィジェットを追加し、View Widgetを選択します。 表示したいメッセージを入力して保存することで、ダッシュボード上に作成したウィジェットが表示されます。 さらに、関連付けるデバイスとして先ほど作成した位置情報シミュレータを選択すると、シミュレータの位置情報がリアルタイムに表示されます。


【動作例】

image

ダッシュボードを追加メニューが表示されない場合、次の手順に従って一度Things Cloudにデプロイすることで、ローカル環境でも正常に動作する場合があります。



Things Cloud へのデプロイ

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

$ 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 とユーザ情報の入力が必要になります。

最後に、デプロイしたアプリケーションにアクセスし、ブランドロゴ等が正常に表示されている事を確認します。

image



さいごに

本レポートでは、Things Cloud の既存コックピットとは異なるコックピット (my-cockpit) を作成し、my-cockpit上にカスタムウィジェットをデプロイしました。そのため、既存のコックピットからは今回作成したカスタムウィジェットの動作は確認できません。実際に既存のコックピットで動作するカスタムウィジェットを開発する場合は、既存のコックピットに対してデプロイを行ってください。 ただし、既存のコックピットに対してデプロイを行う場合、別途開発者が設定しない限り、Branding UI のバージョンも同時に変更されますのでご注意ください。


Web SDK for Angular を利用する上では、以下のWebサイトが参考になります。 ※ Cumulocity社のWebサイトが含まれます。