Node-RED Dashboardのコンポーネントにイベントを追加する


動機:ボタンを押したらスマホを振動させたい

この前Node-RED Dashboardでスマートリモコンを作ってみたのですが、スマホ上でボタンをクリックした時に「ボタン押した感」が欲しいなぁと何となく感じました1

JavaScriptにはVibration APIというハードウェアのバイブレーションにアクセスできるAPIがあるので、これを使ってボタンをクリックした時にちょっと振動させてやればよさそうです。

ただ、Node-RED Dashboardのボタンはクリックイベントを設定するプロパティ等はないので、少し工夫が必要でした。
少し試した結果、ボタン以外のコンポーネントにも汎用的にイベントを設定できそうな方法があったのでメモしておきます。

環境

  • Node-RED 1.0.2
  • Node-RED Dashboard 2.19.0
  • スマホ: Google Pixel 3 (Chrome)
    • 上記のVibration APIが現状Android ChromeとFirefox Mobileくらいしか対応していないようなので、iPhoneの場合は使えないかもしれません

結論

  1. ui_templateノードを使う
  2. コード種別は<head>セクションへ追加にする
  3. jQueryでdocumentに対してセレクタ付きのイベントを設定する(下記画像参照)

ui_templateノード

この子です。Dashboardのカスタムコンポーネントを作ることができます。

コード種別で

  • グループ内のWidget
  • <head>セクションへ追加

の2つが選択できますが、今回は<head>セクションへ追加を使います。
これを使うことで<head>タグ内にHTMLコードを追加できるので、<script>タグを使って任意のJavaScriptコードを埋め込むことができます。

jQueryでセレクタ付きのイベントを設定

Node-RED DashboardはAngularJSとjQueryを利用して作られています。
なので、クリックイベントを追加する際はjQueryの.on('click')で簡単に追加できます。
例えばボタンは<button class="md-raised md-button md-ink-ripple" type="button" ...のように出力されているので2button.md-raised.md-button等と指定すればボタンを選択できます(※この辺は結構雑です)。

ただし、Dashboardのコンポーネントは動的に生成されるので、以下のように指定しても動きません。

正しく動かない
<script>
$('button.md-raised.md-button').on('click', function() {
  window.navigator.vibrate(10)
})
</script>

動的に生成された項目に対してもクリックイベントを追加するには、以下のようにdocumentに対してセレクタ付きでイベントを設定します。

正しく動く
<script>
$(document).on('click', 'button.md-raised.md-button', function() {
  window.navigator.vibrate(10)
})
</script>

これを応用すれば、Dashboardのコンポーネントに対して汎用的にイベントを追加して機能拡張できます。

まとめ

  • Node-RED Dashboardのコンポーネントじゃ少し物足りない
  • コンポーネントに少しだけ機能追加したい

といった時にはui_templateノードを活用できます。
<head>セクションへ追加を使うことで任意のJavaScriptコードを<head>内に埋め込めるため、コンポーネントに対してjQueryで各種イベントを設定できます。
Dashboardはデフォルトでコンポーネントが揃っているので簡単に使える + 拡張性も高い、という構成になっているので良いですね。


  1. こういうフィードバックを与える技術をハプティクスというらしいです。 

  2. DashboardのコンポーネントはおそらくAngularJS Materialを使用しているので、これのクラスを使用できます。