Slide 1

Slide 1 text

製造業IoTのための Node-REDカスタムノード開発 2020/10/10 Node-RED Con Tokyo 2020 ◆ 小原 亮一 @ryoichi_obara ◇ 株式会社エス・ジー 成岡 雅 2020/10/10 © ia-cloudプロジェクト

Slide 2

Slide 2 text

製造業IoTを実現させるために開発している “ia-cloud” のカスタムノード群 設計や開発の知見の話。 ここで話すこと 2020/10/10 © ia-cloudプロジェクト 2 https://github.com/ia-cloud/node-red-contrib-ia-cloud-fds https://github.com/ia-cloud/node-red-contrib-ia-cloud-dashboard

Slide 3

Slide 3 text

• MSTC(製造科学技術センター) が運営する IAF (産業オートメーションフォーラム) 内の WG(ワーキンググループ) のひとつ • 主に中小製造業向けの安価で簡単なクラウド • 概要はTrack A 14:35~14:55 でした ia-cloudとは 2020/10/10 © ia-cloudプロジェクト 3

Slide 4

Slide 4 text

• Automation Junkie • 中小SIer (製造業向け) の IoT / クラウド • 好きなNode-REDノード: • クラフトビール消費量: 600+ [杯/年] @ryoichi_obara 2020/10/10 © ia-cloudプロジェクト 4

Slide 5

Slide 5 text

Cookbook翻訳してたりもしました 2020/10/10 © ia-cloudプロジェクト 5

Slide 6

Slide 6 text

1-1. カスタムノードのあり方の話 1-2. カスタムノード開発のTips 2. Node-REDのダッシュボード開発の話 目次 2020/10/10 © ia-cloudプロジェクト 6

Slide 7

Slide 7 text

シンプルとイージーは違う 2020/10/10 © ia-cloudプロジェクト 7 Ref https://www.infoq.com/presentations/Simple-Made-Easy/

Slide 8

Slide 8 text

• simple (単純)の反対は、complex (複雑) • easy (簡単) の反対は、difficult (難しい) シンプルとイージーは違う 2020/10/10 © ia-cloudプロジェクト 8

Slide 9

Slide 9 text

• それなりの高度さを実現したソフトウェアは、 中の構造はシンプルだとしても イージーかどうかは利用者の視点にも依存する。 • たくさんの”シンプル”を組み合わせて 高度なことを実現させようとすると、 その組み合わせが多岐に渡れば渡るほど、 イージーでなくなることがある。 • 組み合わせ方にも気をつけなければならない! シンプルとイージーは違う 2020/10/10 © ia-cloudプロジェクト 9

Slide 10

Slide 10 text

• Node-REDはノーコード/ローコードでイージー。 利用者はシンプルなノードを組み合わせて さまざまなことを実現できる。 • ただし、作成されるフローについては ノードがカバーする機能の範囲や、 利用者の技量に左右されて、 シンプルでなくなったりしてしまうこともある。 Node-REDではどうか? 2020/10/10 © ia-cloudプロジェクト 10

Slide 11

Slide 11 text

• ia-cloudで開発・提供しているカスタムノードを 製造業の現場に使ってもらう立場 • ある程度のDIY(※) をユーザーに求める ※ エンドユーザーコンピューティングを、わかりやすく理解してもらうた めに、ia-cloud内ではDIYという言葉をよく使っています。 ia-cloudの視点は 2020/10/10 © ia-cloudプロジェクト 11

Slide 12

Slide 12 text

少しでも工夫しようとすると… 2020/10/10 © ia-cloudプロジェクト 12 例です。これはまだマシな方ですよね

Slide 13

Slide 13 text

• Node-RED上でやりたいことが高度になってきたと きに、どうシンプルを保つか? • サブフロー? • 汎用的な部分を切り出してカスタムノード化? • かたや、製造業の現場の方々に実際に使ってもらう には、フローエディター上でもロジカルな要素をな るべく取り除かないと、シンプルが保てない。 課題になりがちな点 2020/10/10 © ia-cloudプロジェクト 13

Slide 14

Slide 14 text

• エンジニア視点で見れば ある程度の複雑度は許容できるし リファクタリングも安全に効く • 利用者が製造業の現場の方という視点では 「シンプルな提供物の組み合わせにより 複雑さが組み上がる」ことを避けるのもひとつの手 =「なんでもできる」がデメリットになるケースも 利用者に複雑さを提供しない 2020/10/10 © ia-cloudプロジェクト 14

Slide 15

Slide 15 text

そんな思想に基づいて実装しています 2020/10/10 © ia-cloudプロジェクト 15

Slide 16

Slide 16 text

他にも細かいTipsを実践しています 2020/10/10 © ia-cloudプロジェクト 16

Slide 17

Slide 17 text

1. パレットノードの日本語対応 2. パレットカテゴリの並び順 3. ステータスの積極利用 4. タブの積極利用 5. ヘルプテキストの充実 他にもTipsを実践 2020/10/10 © ia-cloudプロジェクト 17

Slide 18

Slide 18 text

1. パレットラベルの日本語化 2020/10/10 © ia-cloudプロジェクト 18 日本語化できるようになった

Slide 19

Slide 19 text

1. パレットラベルの日本語化 2020/10/10 © ia-cloudプロジェクト 19

Slide 20

Slide 20 text

• HTML RED.nodes.registerType(‘your-custom-node’, { paletteLabel() { // 言語に応じたパレットラベルを取得して返す return this._(‘editor.paletteLabel’); }, }); 1. パレットラベルの日本語化 2020/10/10 © ia-cloudプロジェクト 20

Slide 21

Slide 21 text

1. パレットラベルの日本語化 2020/10/10 © ia-cloudプロジェクト 21 https://nodered.jp/docs/creating-nodes/node-html#ノードの定義

Slide 22

Slide 22 text

2. パレットカテゴリの並び順 2020/10/10 © ia-cloudプロジェクト 22 並び順が指定できる

Slide 23

Slide 23 text

2. パレットカテゴリの並び順 2020/10/10 © ia-cloudプロジェクト 23 ラズパイだと .node-red/settings.js

Slide 24

Slide 24 text

2. パレットカテゴリの並び順 2020/10/10 © ia-cloudプロジェクト 24 https://nodered.jp/docs/user-guide/runtime/configuration#フローエディタの設定

Slide 25

Slide 25 text

3. ステータスの積極利用 2020/10/10 © ia-cloudプロジェクト 25

Slide 26

Slide 26 text

4. タブの積極利用 2020/10/10 © ia-cloudプロジェクト 26

Slide 27

Slide 27 text

5. ヘルプテキストの充実 2020/10/10 © ia-cloudプロジェクト 27

Slide 28

Slide 28 text

Node-REDのバージョンアップと共に成長するia-cloud 気になった方はコンタクトしてください 2020/10/10 © ia-cloudプロジェクト 28 github.com/ia-cloud twitter.com/ryoichi_obara

Slide 29

Slide 29 text

続いて成岡さんお願いします https://unsplash.com/photos/HgwY_YQ1m0w

Slide 30

Slide 30 text

• 株式会社エス・ジー • 港区芝にあるソフトウェア開発企業 • ソフトウェア開発事業部に所属 • 製造業IoT/クラウド関連業務に従事 • 好きなノード: 成岡(なるおか)です! 2020/10/1 © ia-cloudプロジェクト 30

Slide 31

Slide 31 text

皆さんご存知、ダッシュボード 私からお話しすること 2020/10/1 © ia-cloudプロジェクト 31 ダッシュボードに 配置するパーツ →ウィジェット

Slide 32

Slide 32 text

node-red-dashboard GitHub wiki内に記載あり ダッシュボードウィジェットは自作ができる! 2020/10/1 © ia-cloudプロジェクト 32 https://github.com/node-red/node-red-dashboard/wiki/Creating-New-Dashboard-Widgets

Slide 33

Slide 33 text

以下のようなダッシュボードウィジェットを作成 ia-cloudダッシュボードウィジェットノードの一例 2020/10/1 © ia-cloudプロジェクト 33 https://github.com/ia-cloud/node-red-contrib-ia-cloud-dashboard ランプノード 日時指定ノード 稼働状況ノード バーゲージノード

Slide 34

Slide 34 text

• 基本的な構成は通常のノード定義と同じ • 名前は「node-red-contrib-ui-{widget-name}」 • ウィジェット定義用APIを使用して実装する • node-red-dashboardモジュールをJS内でロードする 基本構成はノードと同じ 2020/10/1 © ia-cloudプロジェクト 34

Slide 35

Slide 35 text

• addWidget(option) optionの中身(JavaScriptオブジェクト) ウィジェット定義用API 2020/10/1 © ia-cloudプロジェクト 35 オプション名 説明 node 制御ノード format ウィジェットのHTMLコード *テンプレートウィジェットと同じHTMLを受け入れる group ウィジェットが属するグループノードオブジェクト width ウィジェットの幅 heigth ウィジェットの高さ order グループのorder templateScope ウィジェットのスコープ(global/local) EmmitOnlyNewValues 変更された場合はメッセージを送信する(true/false) forwardInputMessages 入力メッセージを出力に転送する(true/false) storeFrontEndInputAsState 受信したメッセージを保存する(true/false)

Slide 36

Slide 36 text

• addWidget(option) optionの中身(JavaScriptオブジェクト) ウィジェット定義用API 2020/10/1 © ia-cloudプロジェクト 36 オプション名 説明 convert 値をフロントエンドに変換するためのコール バック beforeEmit メッセージを準備するためのコールバック convertBack 送信されたメッセージを変換するためのコール バック beforeSend メッセージを準備するためのコールバック initController コントローラで初期化するコールバック

Slide 37

Slide 37 text

メイン処理はinitControllerに記入する クライアント側で実行されるコールバック →関数スコープ外の変数の参照は不可 実装する上での注意点 2020/10/1 © ia-cloudプロジェクト 37 : initController: function($scope, events) { $scope.value = false; $scope.click = function (val) { $scope.send({payload: val}); }; } : <記入例> AngularJSの $scopeと同じ

Slide 38

Slide 38 text

グラフライブラリを使用したウィジェットを 作りたい →ライブラリを読み込むことができない・・・ 実装していて困ったこと 2020/10/1 © ia-cloudプロジェクト 38

Slide 39

Slide 39 text

package.jsonを見ると・・・ 2020/10/1 © ia-cloudプロジェクト 39 "chart.js": "~2.3.0", "d3": "^3.5.17", "font-awesome": "^4.7.0", "jquery": "~3.5.1", : "jshint": "~2.12.0", "justgage": "~1.4.0", "less": "~3.9.0", "material-design-icons-iconfont": "~6.1.0", "moment": "~2.27.0", "sprintf-js": "^1.1.2", "streamqueue": "~1.1.2", "svg-morpheus": "^0.3.0", "tinycolor2": "^1.4.1", "weather-icons-lite": "^1.3.1“ } : : "dependencies": { "compression": "^1.7.4", "gridstack": "^0.6.4", "serve-static": "^1.14.1", "socket.io": "^2.3.0" }, "devDependencies": { "angular": "~1.8.0", "angular-animate": "~1.8.0", "angular-aria": "~1.8.0", "angular-chart.js": "^1.1.1", "angular-material": "~1.1.26", "angular-material-icons": "^0.7.1", "angular-messages": "~1.8.0", "angular-mocks": "~1.8.0", "angular-route": "~1.8.0", "angular-sanitize": "~1.8.0", "angular-touch": "~1.8.0", "angularjs-color-picker": "^3.4.8",

Slide 40

Slide 40 text

package.jsonを見ると・・・ 2020/10/1 © ia-cloudプロジェクト 40 "chart.js": "~2.3.0", "d3": "^3.5.17", "font-awesome": "^4.7.0", "jquery": "~3.5.1", : "jshint": "~2.12.0", "justgage": "~1.4.0", "less": "~3.9.0", "material-design-icons-iconfont": "~6.1.0", "moment": "~2.27.0", "sprintf-js": "^1.1.2", "streamqueue": "~1.1.2", "svg-morpheus": "^0.3.0", "tinycolor2": "^1.4.1", "weather-icons-lite": "^1.3.1“ } : : "dependencies": { "compression": "^1.7.4", "gridstack": "^0.6.4", "serve-static": "^1.14.1", "socket.io": "^2.3.0" }, "devDependencies": { "angular": "~1.8.0", "angular-animate": "~1.8.0", "angular-aria": "~1.8.0", "angular-chart.js": "^1.1.1", "angular-material": "~1.1.26", "angular-material-icons": "^0.7.1", "angular-messages": "~1.8.0", "angular-mocks": "~1.8.0", "angular-route": "~1.8.0", "angular-sanitize": "~1.8.0", "angular-touch": "~1.8.0", "angularjs-color-picker": "^3.4.8", AngularJSベースで 組まれている JQueryもある

Slide 41

Slide 41 text

package.jsonを見ると・・・ 2020/10/1 © ia-cloudプロジェクト 41 "chart.js": "~2.3.0", "d3": "^3.5.17", "font-awesome": "^4.7.0", "jquery": "~3.5.1", : "jshint": "~2.12.0", "justgage": "~1.4.0", "less": "~3.9.0", "material-design-icons-iconfont": "~6.1.0", "moment": "~2.27.0", "sprintf-js": "^1.1.2", "streamqueue": "~1.1.2", "svg-morpheus": "^0.3.0", "tinycolor2": "^1.4.1", "weather-icons-lite": "^1.3.1“ } : : "dependencies": { "compression": "^1.7.4", "gridstack": "^0.6.4", "serve-static": "^1.14.1", "socket.io": "^2.3.0" }, "devDependencies": { "angular": "~1.8.0", "angular-animate": "~1.8.0", "angular-aria": "~1.8.0", "angular-chart.js": "^1.1.1", "angular-material": "~1.1.26", "angular-material-icons": "^0.7.1", "angular-messages": "~1.8.0", "angular-mocks": "~1.8.0", "angular-route": "~1.8.0", "angular-sanitize": "~1.8.0", "angular-touch": "~1.8.0", "angularjs-color-picker": "^3.4.8", 有名なグラフ 描画用ライブラリ

Slide 42

Slide 42 text

package.jsonを見ると・・・ 2020/10/1 © ia-cloudプロジェクト 42 "chart.js": "~2.3.0", "d3": "^3.5.17", "font-awesome": "^4.7.0", "jquery": "~3.5.1", : "jshint": "~2.12.0", "justgage": "~1.4.0", "less": "~3.9.0", "material-design-icons-iconfont": "~6.1.0", "moment": "~2.27.0", "sprintf-js": "^1.1.2", "streamqueue": "~1.1.2", "svg-morpheus": "^0.3.0", "tinycolor2": "^1.4.1", "weather-icons-lite": "^1.3.1“ } : : "dependencies": { "compression": "^1.7.4", "gridstack": "^0.6.4", "serve-static": "^1.14.1", "socket.io": "^2.3.0" }, "devDependencies": { "angular": "~1.8.0", "angular-animate": "~1.8.0", "angular-aria": "~1.8.0", "angular-chart.js": "^1.1.1", "angular-material": "~1.1.26", "angular-material-icons": "^0.7.1", "angular-messages": "~1.8.0", "angular-mocks": "~1.8.0", "angular-route": "~1.8.0", "angular-sanitize": "~1.8.0", "angular-touch": "~1.8.0", "angularjs-color-picker": "^3.4.8", その他ウィジェット作成 に使用できるモジュール

Slide 43

Slide 43 text

• dashboardモジュール内にロードされていない モジュール・ライブラリのロード&利用 • ノードのステータス表示 →initController内で関数スコープ外の変数の参照が 不可のため実装が難しい まだ実装中にハマることは多い! 2020/10/1 © ia-cloudプロジェクト 43

Slide 44

Slide 44 text

• カスタムノードのあり方・設計や考え方 • node-red-dasnboardを拡張するための開発の話 “ia-cloud”カスタムノード群 設計・開発する上での話をご紹介しました まとめ 2020/10/1 © ia-cloudプロジェクト 44

Slide 45

Slide 45 text

ご存知の方はぜひ教えてください! ia-cloudへの参加もお待ちしております! 2020/10/1 © ia-cloudプロジェクト 45

Slide 46

Slide 46 text

中小製造業の未来を、一緒に拓きましょう。 ご清聴ありがとうございました。 2019/10/0 ia-cloud プロジェクト 46