カスタムウィジェットの作り方 2

投稿日 / 投稿者名

2018.8.1 / 正木 菜津美

はじめに

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

  • ver.8.15.8(backend/UI)

難易度 ★★★


概要

本レポートでは、ウィジェット開発でのデータ実装方法についてご紹介します。
ウィジェットプラグインは、Things Cloud内のデータとのリアルタイムなやり取りを可能にします。

ウィジェット開発に関する紹介は、1〜3のページで構成され、各ページの手順を実行することで次の内容が実現できます。

  1. カスタムウィジェットの作り方 1:ウィジェット編集画面で設定したメッセージ文が表示される「Hello Widget」の開発
  2. カスタムウィジェットの作り方 2:1で作成したウィジェットに「デバイスから取得したデータを表示」する機能を追加(★このページ)
  3. カスタムウィジェットの作り方 3:2で作成したウィジェットに「画像データを表示」する機能を追加(近日公開)

また、全て通して読むことで、設定UIのデータの流れについても理解することができます。

前提条件

所要時間(目安)

この手順に沿って、「Hello Widget」にデバイスから取得したデータを表示する機能を追加する場合の所要時間。

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

つくるもの

カスタムウィジェットの作り方 1で作成した「Hello Widget」に、デバイスから取得したデータを表示する機能を追加します。

【完成イメージ】

image
「Hello Widget」ウィジェットの編集画面では、操作アカウントに紐付いたデバイスを選択することができます。
image
ダッシュボードでは、このようにデバイスから取得したデータが CurrentDeviceValue として表示されるようになります。

なお、本レポートで使用している、hellowidgetプロジェクト以下のファイル一式は こちら からダウンロードできます。

1. 設定ファイルの変更

ウィジェット設定ファイルは以下の通り設定します。

hellowidget.config.js

(function () {
    'use strict';

    angular
        .module('myapp.hellowidget')
        .config(configure);

    /* @ngInject */
    function configure(
        c8yComponentsProvider,
        gettext
    ) {
        c8yComponentsProvider.add({
            name: 'hellowidget',
            nameDisplay: gettext('HelloWidget'),
            description: gettext('HelloWidget'),
            templateUrl: ':::PLUGIN_PATH:::/views/hellowidget.main.html',
            configTemplateUrl: ':::PLUGIN_PATH:::/views/hellowidget.setting.html',
            options: {
                groupsSelectable: true,  // 加える
                noDeviceTarget: false  // falseにするか削除する
            }
        });
    }
}());

この設定ファイルにおける、ウィジェット開発1からの変更箇所は次の2点です。

  • optionsgroupsSelectable: true を 追加し、デバイス選択UIを表示させる
  • noDeviceTarget は false にするか削除する

2. ウィジェット表示コントローラの更新

ウィジェット表示コントローラは以下の通り設定します。

hellowidget.controller.js

(function () {
    'use strict';

    angular
        .module('myapp.hellowidget')
        .controller('hellowidgetController', hellowidgetController);

    /* @ngInject */
    function hellowidgetController(
        $scope,
        $q,
        c8yInventory,
        c8yBinary,
        c8yMeasurements
    ) {

        function init() {
            console.log("init");

            // リアルタイム監視用のフィルタ設定
            var filter = {
                device: $scope.child.config.device.id,
                fragment: "c8y_Temperature",
                series: "T"
            };

            // latestMeasurementという値でデータバインディングする
            var realtime = true;
            c8yMeasurements.latest(filter, realtime)
                .then(function (measurement) {
                    // measurement に最新のセンサーデータがJSON構造で出力されている
                    $scope.currentValue = function(){
                        return measurement[filter.fragment][filter.series].value;  // センサー値
                    };
                    $scope.currentUnit = function(){
                        return measurement[filter.fragment][filter.series].unit;  // センサー単位
                    };
                });
        }

        // デバイス選択UIでの変更の監視
        $scope.$watch('child.config.device', function (newVal, oldVal) {
            if(newVal && !_.isEqual(newVal, oldVal)) {
                // デバイス対象が更新されるたびに初期化する
                init();
            }
        }, true);

        // 値変更の監視
        $scope.$watch('child.config.helloMessage', function (newVal, oldVal) {
            if(newVal && !_.isEqual(newVal, oldVal)) {
                console.log("DataChange");
                init();
            }
        }, true);

        // ウィジェット破棄イベント
        function onDestroy() {
            console.log( 'onDestroy');
        }

        // 初期化
        init();
        // ウィジェット破棄イベント関連付け
        $scope.$on('$destroy', onDestroy);
    }
}());


コントローラでの設定内容を解説します。

センサーデータを監視するには c8yMeasurements API を使います。コントローラで使用できるようにngInjectc8yMeasurement を追加します。

     :
     :
    function hellowidgetController(
        $scope,
        $q,
        c8yInventory,
        c8yBinary,
        c8yMeasurements
    ) {
     :
     :



また、ウィジェット表示した際にすぐに監視できるように初期化の処理を拡張しています。 c8yMeasurements API をもとにc8yMeasurements.latestで最新データを取得する処理を記述しています。

  • fragment は本レポートでは c8y_Temperature を設定していますが、お使いのデバイスに対応するフラグメントを設定してください。
  • series は本レポートでは T を設定していますが、お使いのデバイスに対応するシリーズを設定してください。
  • $scope.currentValue はセンサー値を格納しています。
  • $scope.currentUnit はセンサーの単位(今回は ℃ )を格納しています。
 :
 :
function init() {
    console.log("init");

    // リアルタイム監視用のフィルタ設定
    var filter = {
        device: $scope.child.config.device.id,
        fragment: "c8y_Temperature",
        series: "T"
    };

    // latestMeasurementという値でデータバインディングする
    var realtime = true;
    c8yMeasurements.latest(filter, realtime)
        .then(function (measurement) {
            // measurement に最新のセンサーデータがJSON構造で出力されている
            $scope.currentValue = measurement[filter.fragment][filter.series].value;  // センサー値
            $scope.currentUnit = measurement[filter.fragment][filter.series].unit;  // センサー単位
        });
}
 :
 :



デバイス対象が更新されるたびに初期化する必要があるため、デバイス選択UIでの変更の監視処理をしています。具体的には さきほどの init(初期化処理) を実行しています。

 :
 :
// デバイス選択UIでの変更の監視
$scope.$watch('child.config.device', function (newVal, oldVal) {
    if(newVal && !_.isEqual(newVal, oldVal)) {
        // デバイス対象が更新されるたびに初期化する
        init();
    }
}, true);

// 値変更の監視
$scope.$watch('child.config.helloMessage', function (newVal, oldVal) {
    if(newVal && !_.isEqual(newVal, oldVal)) {
        console.log("DataChange");
        init();
    }
}, true);
 :
 :


3. ウィジェット表示HTMLの更新

ウィジェット表示HTMLは以下の通り設定します。

views/hellowidget.main.html

<div ng-controller="hellowidgetController">
    <h5>CurrentDeviceValue : </h5><h3>{{currentValue()}}{{currentUnit()}}</h3><br />
    <h5>HelloMessage : </h5><h3>{{child.config.helloMessage}}</h3>
</div>

ウィジェットではセンサー値と単位が CurrentDeviceValue の項目でデータバインディングされていて、currentValuecurrentUnitは c8yMeasurements API で更新されるたびに反映されていきます。

image

プラグインの設定は以上で完了です。

4. ビルドする

本レポートでは、作成したウィジェットが含まれたcockpitアプリを作成し、アップロードする方法を紹介します。
c8yコマンド(c8y build:target myapplication)を実行し、cockpit.zipを作成します。
作成したzipファイルは、ファイル名を任意の値に編集後(デフォルトのコックピットアプリと重複しないよう、必ずファイル名を変えてください)、対象テナントの Administrationアプリ > 所有アプリケーション > アプリケーションを追加 からアップロードします。

カスタムウィジェットの作り方 2 についての紹介は以上です。