製造業IoTのためのNode-REDカスタムノード開発 #noderedjp #nodered / Developing Industrial IoT Node-RED custom node

製造業IoTのためのNode-REDカスタムノード開発 #noderedjp #nodered / Developing Industrial IoT Node-RED custom node

#noderedjp #nodered
Node-RED Con Tokyo 2020 Track B 登壇資料です。
----------------------------------------
産業オートメーションフォーラムが推進する製造現場向けクラウドサービス「ia-cloud」の活動に利用される、製造業の製造現場で使用されるセンサーと計測制御機器をつなぐカスタムノードの開発をご紹介します。
中小企業の生産現場でITに詳しい人が常にいるわけではありません。このような状況の中、実際の生産現場に携わる人々がNode-REDを利用することで、コードなしで製造業のIoTアプリケーションを作れるというコンセプトのワークショップも開催しています。そこで使用されるフィールドのセンサーノードとダッシュボードノードを開発するためのいくつかのアイデアを紹介します。

D4b3dfc68675b3564c58e75cef7c9689?s=128

Ryoichi Obara

October 10, 2020
Tweet

Transcript

  1. 製造業IoTのための Node-REDカスタムノード開発 2020/10/10 Node-RED Con Tokyo 2020 ◆ 小原 亮一

    @ryoichi_obara ◇ 株式会社エス・ジー 成岡 雅 2020/10/10 © ia-cloudプロジェクト
  2. 製造業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
  3. • MSTC(製造科学技術センター) が運営する IAF (産業オートメーションフォーラム) 内の WG(ワーキンググループ) のひとつ • 主に中小製造業向けの安価で簡単なクラウド

    • 概要はTrack A 14:35~14:55 でした ia-cloudとは 2020/10/10 © ia-cloudプロジェクト 3
  4. • Automation Junkie • 中小SIer (製造業向け) の IoT / クラウド

    • 好きなNode-REDノード: • クラフトビール消費量: 600+ [杯/年] @ryoichi_obara 2020/10/10 © ia-cloudプロジェクト 4
  5. Cookbook翻訳してたりもしました 2020/10/10 © ia-cloudプロジェクト 5

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

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

  8. • simple (単純)の反対は、complex (複雑) • easy (簡単) の反対は、difficult (難しい) シンプルとイージーは違う

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

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

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

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

  13. • Node-RED上でやりたいことが高度になってきたと きに、どうシンプルを保つか? • サブフロー? • 汎用的な部分を切り出してカスタムノード化? • かたや、製造業の現場の方々に実際に使ってもらう には、フローエディター上でもロジカルな要素をな

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

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

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

  17. 1. パレットノードの日本語対応 2. パレットカテゴリの並び順 3. ステータスの積極利用 4. タブの積極利用 5. ヘルプテキストの充実

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

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

  20. • HTML RED.nodes.registerType(‘your-custom-node’, { paletteLabel() { // 言語に応じたパレットラベルを取得して返す return this._(‘editor.paletteLabel’);

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

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

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

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

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

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

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

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

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

  30. • 株式会社エス・ジー • 港区芝にあるソフトウェア開発企業 • ソフトウェア開発事業部に所属 • 製造業IoT/クラウド関連業務に従事 • 好きなノード:

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

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

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

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

    © ia-cloudプロジェクト 34
  35. • 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)
  36. • addWidget(option) optionの中身(JavaScriptオブジェクト) ウィジェット定義用API 2020/10/1 © ia-cloudプロジェクト 36 オプション名 説明

    convert 値をフロントエンドに変換するためのコール バック beforeEmit メッセージを準備するためのコールバック convertBack 送信されたメッセージを変換するためのコール バック beforeSend メッセージを準備するためのコールバック initController コントローラで初期化するコールバック
  37. メイン処理はinitControllerに記入する クライアント側で実行されるコールバック →関数スコープ外の変数の参照は不可 実装する上での注意点 2020/10/1 © ia-cloudプロジェクト 37 : initController:

    function($scope, events) { $scope.value = false; $scope.click = function (val) { $scope.send({payload: val}); }; } : <記入例> AngularJSの $scopeと同じ
  38. グラフライブラリを使用したウィジェットを 作りたい →ライブラリを読み込むことができない・・・ 実装していて困ったこと 2020/10/1 © ia-cloudプロジェクト 38

  39. 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",
  40. 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もある
  41. 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", 有名なグラフ 描画用ライブラリ
  42. 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", その他ウィジェット作成 に使用できるモジュール
  43. • dashboardモジュール内にロードされていない モジュール・ライブラリのロード&利用 • ノードのステータス表示 →initController内で関数スコープ外の変数の参照が 不可のため実装が難しい まだ実装中にハマることは多い! 2020/10/1 ©

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

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

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