Node-REDを使用した視覚的なプログラミング:モノのインターネットを簡単に配線する

公開: 2022-03-11

プログラミングを通じて、単純な命令のシーケンスに従うことにより、マシンに複雑な動作を模倣させます。 アセンブリ、C、Python、JavaScriptなどのテキストプログラミング言語を使用することは、これを行うための主要な方法の1つです。 これらのプログラミング言語の設計者は、表現力豊かな構文、堅牢なプログラミング構造、および強力なツールチェーンを通じて、プログラムの作成を可能な限り簡単にするために数え切れないほどの時間を費やしてきました。 ただし、これらのプログラミング言語はすべて、テキストソースコードという共通の特徴を共有しています。

テキストでプログラムを書くことはうまくいきます、そしてほとんどの場合それはうまくいきます。 ただし、プログラムを視覚的に表現する機能が望ましい場合がよくあります。 多くの場合、大規模なシステムのさまざまなコンポーネントを介した情報の流れを設計できることが、必要なすべてです。 ビジュアルプログラミングツールは、プログラミングに不慣れで、変数、ポインタ、信号、スコープなどのさまざまな概念を処理するのに苦労している人にも寛容です。

Node-REDを使用してハードウェアデバイスをAPIに接続する

Node-REDは、視覚的にプログラミングするためのツールです。 関係と機能を視覚的に表示し、ユーザーが言語を入力しなくてもプログラミングできるようにします。 Node-REDはブラウザベースのフローエディタであり、ノードを追加または削除し、ノードを相互に通信させるためにそれらを相互に接続できます。

Node-REDでは、すべてのノードは次の2つのタイプのいずれかです:注入ノードまたは関数ノード。 インジェクトノードは、入力を必要とせずにメッセージを生成し、それに接続されている次のノードにメッセージをプッシュします。 一方、関数ノードは入力を受け取り、それに対していくつかの作業を実行します。 Node-REDは、これらのノードを多数選択できるため、ハードウェアデバイス、API、およびオンラインサービスをこれまでになく簡単に接続できます。

Node-RED入門

Node-REDはNode.js上に構築されています。 Node-REDをインストールするには、Node.jsとNPMの両方をインストールする必要があります。 NPMを使用すると、Node-REDのインストールが非常に簡単になります。

 npm install -g node-red

Node-REDのフローエディタは、Webブラウザベースのアプリケーションです。 これを使用できるようにするには、Node-REDを実行します。

 node-red

&hellipを実行し、http:// localhost:1880に移動します。

こんにちは世界!

「Hello、world」と言うことを学ばなくても、どの初心者向けプログラミングチュートリアルが完了しますか? それを正確に試すことから始めましょう:

  1. フローエディタに注入ノードをドラッグアンドドロップします。 次に、ダブルクリックしてペイロードを文字列として設定し、「Helloworld」と記述します。
  2. インジェクトノードで行ったのと同じ方法で、デバッグノードをドラッグアンドドロップします。
  3. それらを一緒に配線します。
  4. 右隅の「展開」ボタンをクリックします。
  5. インジェクトノードのすぐ左にある青いボタンをクリックします。

それを試してみてください。 次のようなものが表示されます。

JavaScriptだけ

Node-REDを使用すると、単純なノードと機能だけに限定されません。 Node-REDはNode.js上に構築されているため、すべてJavaScriptを利用しています。 実際、ノードはNode.jsモジュールです。 それらはhttp://flows.nodered.org/にあるので、左側のパネルに追加するには、「npminstall」するだけです。 実際、独自のフローを開発して、フローリポジトリにアップロードすることができます。 Node-REDが提供するコードエディタ内の関数ノードにJavaScriptを入力できるため、アプリケーションは必要に応じて複雑にすることができます。

プラットフォームはNode.jsに基づいているため、同じイベント駆動型の非ブロッキングモデルを利用します。 そのため、Node-REDで構築されたアプリケーションは、クラウドだけでなく、RaspberryPiなどの低コストのハードウェアでも実行できます。

Let's Go Pro:ホームオートメーションの時間

Node-REDがモノのインターネットの領域にどのように適合するかを示すために、スマート電球の色を変更するアプリケーションを作成しましょう。 誰もが同じスマート照明システムを自由に使えるわけではありませんが、公式のフローリポジトリから適切なNode-REDモジュールを見つけることができるので、心配する必要はありません。 ただし、物事をさらに簡単にするために、よりスマートなものを探しましょう。

Netbeastに会いましょう。 これは、モノのインターネットアプライアンスおよびデバイス用のアプリケーションを開発するためのオープンソースプラットフォームであり、ワイヤレスプロトコル、ブランドの互換性などの詳細を気にする必要はなく、特定の各APIの処理方法を知る必要もありません。 これにより、実際のデバイスとして機能する仮想デバイスを使用できます。 したがって、スマート電球がなくても、仮想電球を利用できます。

Netbeast for Node-RED npmパッケージは、次のようにグローバルにインストールできます。

 npm install -g node-red-contrib-netbeast

netbeast-redノードはNetbeastダッシュボードを表し、そのAPIプリミティブを自宅にあるすべてのスマートデバイスに変換します。 幸い、モジュールとしても利用できます!

Netbeastを起動します。

 npm install -g netbeast-cli netbeast start

これにより、ダッシュボードがポート8000​​で使用可能になり、SSLが8443で使用可能になります。次にブラウザを開いてhttp:// localhost:8000に移動し、[探索]に移動します。 そこでは、たくさんのアプリやプラグインを見つけることができます。 スマート電球のブランド(Philips Hue、LIFX、WeMo)を探すか、持っていない場合は、電球プラグインをダウンロードしてみてください。 ダッシュボードプラグインにこれ​​らのいずれかが含まれていることを確認してください。

黄色のバッジは、プラグインが実行されているが、デバイスが見つからないことを示します。 電球プラグインをクリックして、仮想電球を作成します。 検出された他のデバイスはすべて、ネットワークの下に表示されます。

すべてが整ったら、仕事に戻りましょう。 簡単なフローを作成します。

  1. インジェクトノードをドラッグアンドドロップします。
  2. Netbeastノードをドラッグアンドドロップします。
  3. デバッグノードをドラッグアンドドロップします。
  4. 以下に示すように、すべてを配線します。

それでは、ダッシュボードにHTTPリクエストを送信しましょう。 Netbeast APIを使用して、電球でトリガーする値を含むJSONを注入ノードを介して送信する必要があります。

ボタンを押すと、すべてのスマート電球に色と電力が注入されます。

各トピックは、異なる種類のデバイスを表します。 つまり、照明だけでなく、音楽、暖房、ビデオに関するトピックもあります。 湿度、存在、温度のセンサーだけでなく、リストは続きます。 彼らのドキュメントには、あらゆる種類のデバイスに変換されるトピックのリストと推奨される構造が記載されています。 このIoTエンジンは未成熟ですが、強力です。 開発者が情報を再利用して、真に接続されたシナリオを作成できるようにするオープンソース。

もっと深く行きましょう

次に、別のプラグインである周囲ノイズ検出器を使用して2番目のフローを作成し、それをトリガーとして使用して、電球の色をノイズセマフォとして変更します。 このチュートリアルでは仮想のものを使用するため、新しいハードウェアを購入する必要はありません。 Node-REDエディターの「プラス」ボタンをクリックすることから始めましょう。

ダッシュボードhttp:// localhost:8000 / exploreで[Explore]セクションに再度移動し、Volume-Pluginを探します。 これは、ブラウザー内のgetUserMedia()を利用して、単純なHTMLアプリからメディアをキャプチャする非常に初歩的なWebアプリです。 したがって、おそらく最新のブラウザでのみ機能します。

仮想電球と同様に、それをクリックして開きます。 マイクから録音する許可を求められます。 次に、メッセージをNetbeastのMQTTブローカーに送信します。これは、すべてのダッシュボードで共有されるため、サブスクライブできるようになります。 このようなことを行うには、 netbeast-triggerノードをnode-redのエディターにドラッグアンドドロップするだけで済みます。 次に、トリガーとNetbeastノードの間に関数を挿入して、音量が大きすぎるかどうかを判断します。 また、いくつかのデバッグノードを使用して、すべてが正常かどうかを確認する必要があります。 スキームは次のようになります。

それでは、tooLoud関数ノードにコードを入力してみましょう。 はい、コーディングしなくてもプログラムできると約束したことは知っていますが、すでにできることを示しました。 また、使用可能なさまざまな要素またはレジストリの他のノードを組み合わせて、次のことを実行できます。

 var volume = msg.payload.volume node.log(volume) if (volume < 50) { return { topic: 'lights', payload: { power: 1, color: '#00CC00'}} } else if (volume < 75) { return { topic: 'lights', payload: { power: 1, color: '#CCCC00'}} } else { return { topic: 'lights', payload: { power: 1, color: '#FF0000'}} }

このかなり単純なコードスニペットは、前のノードによって報告された音量レベルに応じて、特定のカラーコードを持つ次のノードの3つのペイロードの1つを返します。

これで準備が整いました。 もう一度[デプロイ]ボタンを押して、音を立てましょう。 電球がある色から別の色にすぐに変わる様子を見てみましょう!

使用しているマイクとウェブブラウザは異なる場合がありますので、機能値としきい値を自由に調整し、色の値を試して球根がどのように変化するかを確認してください。

独自のプラグインを作成する

純粋なCSSのこの電球は、このcssdeckに触発されました。

お気づきかもしれませんが、以前の仮想電球は非常に初歩的なものなので、微調整することをお勧めします。 またはさらに良いことに、独自のスマートホームコントローラーを作成できます。 そこで、Netbeastの仮想プラグインを作成するプロセスを実行します。これにより、スマートデバイス用の独自のコントローラーを作成できるようになります。

netbeast-cliパッケージを使用して、コードを自動的に生成できます。 netbeast create myplugin --pluginを実行すると、次のような基本的なプロジェクトになります。

 myplugin ├── README.md ├── index.js ├── package.json └── test.js

フロントエンド

それでは、フロントエンドで電球の模倣を始めましょう。 通常、デバイスコントローラーには1つがないため、scaffoldコマンドにパブリックフォルダーはまだ含まれていません。 プロジェクト内にpublicディレクトリを作成し、そこに次のHTML、CSS、およびJSファイルを配置しましょう。

index.html

 <head> <title>Netbeast Bulb Plugin</title> <link rel="stylesheet" href="bulb.css" media="screen" charset="utf-8"> </head> <body> <div class="top-decoration"></div> <div> </div> <div class="bulb-container small"> <div class="bulb light"> <div> <div class="bulb top"></div> <div class="bulb middle-1"></div> <div class="bulb middle-2"></div> <div class="bulb middle-3"></div> <div class="bulb bottom"></div> </div> <div> <div class="screw-top"></div> <div class="screw a"></div> <div class="screw b"></div> <div class="screw a"></div> <div class="screw b"></div> <div class="screw a"></div> <div class="screw b"></div> <div class="screw c"></div> <div class="screw d"></div> </div> </div> </div> <div class="code-container"> <pre><i class="txt-red">beast</i>(<i class="txt-green">'lights'</i>).<i class="txt-blue">set</i>({ <i class="txt-green">color</i>: <i class="txt-green">"<input type="text" class="color" name="color" value="00fea5">"</i>, <i class="txt-green">power</i>: <i class="txt-green">"<input type="text" class="power" name="power" value="on">"</i> })</pre> <button> RUN </button> </div><!-- wrapper --> <!-- declares bulb features and methods --> <script type="text/javascript" src="bulb.js"></script> <!-- real time comms library --> <script type="text/javascript" src="socketio.js"></script> <!-- simulates hardware communication --> <script type="text/javascript" src="hw-api.js"></script> </body>

電球.css

 section { float: left; padding: 20px 50px 20px 50px; } .bulb-light { border: 0; background: transparent; margin: 0 auto !important; padding: 0 !important; display: block; z-index: 1; } #bulb { opacity: 1; z-index: 3; display: block;} .bulb.top { border: 0; width: 300px; height: 300px; margin: 0 auto; padding: 0; border-radius: 999px; background: #E7E7E7; } .bulb.middle-1 { margin: -75px auto 0 auto; width: 190px; border-left: 35px solid transparent; border-right: 35px solid transparent; border-top: 55px solid #E7E7E7; } .bulb.middle-2 { margin: -22px auto 0 auto; width: 178px; border-left: 19px solid transparent; border-right: 19px solid transparent; border-top: 50px solid #E7E7E7; } .bulb.middle-3 { margin: -20px auto 0 auto; width: 182px; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 30px solid #E7E7E7; } .bulb.bottom { width: 184px; height: 65px; margin: -8px auto 0 auto; padding: 0; border-radius: 0 0 999px 999px; background: #E7E7E7; } #base { position:relative; z-index: 2; } .screw { transform: rotate(-3deg); -ms-transform: rotate(-3deg); -webkit-transform: rotate(-3deg); padding: 0; } .screw-top { margin: -18px auto -4px auto; padding: 0; width: 132px; height: 0; border-left: 15px solid transparent; border-right: 15px solid transparent; border-top: 21px solid #D3D3D3; border-radius: 999px; } .screw.a { background: #DDD; width: 150px; height: 15px; border-radius: 999px; margin: -1px auto 0px; } .screw.b { background: #D9D9D9; width: 135px; height: 15px; margin: -1px auto 0px; } .screw.c { margin: -1px auto 0px; width: 78px; height: 0; border-left: 30px solid transparent; border-right: 30px solid transparent; border-top: 20px solid #DDD; border-radius: 8px; } .screw.d { margin: 0 auto; width: 15px; height: 0; border-left: 30px solid transparent; border-right: 30px solid transparent; border-top: 15px solid #444; } .on #light { -moz-opacity: 1; -khtml-opacity: 1; opacity: 1; } .bulb.top, .bulb.bottom { transition: all 0.5s ease-in-out; } .bulb.middle-1, .bulb.middle-2, .bulb.middle-3 { transition: all 0.5s ease-in-out; }

これらのHTMLファイルとCSSファイルを使用すると、ブラウザで電球の形をすでに確認できるはずです。 先に進み、HTMLファイルを開いてライブで確認してください。 動作していますか? では、いくつかの機能を追加しましょう。

電球.js

このファイルは、クリックしてクリックするだけで電球の動作を模倣し、Netbeastを介して色を変更するために少し使用されるいくつかの関数を設定します。

 var color = document.getElementById('color') var power = document.getElementById('power') var bulb = document.getElementById('bulb') var button = document.getElementById('run-btn') var light = document.getElementById('light') button.onclick = function toggleBulbState () { changeBulbParams({ color: color.value, power: power.value }) } function setBulbParams (params) { if (params.power === 'off') { params = { color: 'E7E7E7' } } console.log('set params', params) var bulb_parts = ['.bulb.middle-1', '.bulb.middle-2', '.bulb.middle-3'] document.querySelector('.bulb.top').style.boxShadow = '0px 0px 98px #' + params.color document.querySelector('.bulb.top').style.backgroundColor = params.color document.querySelector('.bulb.bottom').style.backgroundColor = params.color bulb_parts.forEach(function (className) { document.querySelector(className).style.borderTopColor = params.color }) } function changeBulbParams (params) { console.log('change params', params) /* Overwrite html fields if necessary */ color.value = params.color || color.value power.value = params.power || power.value setBulbParams({color: color.value, power: power.value}) }

この後、フィールドと実行ボタンはすべて意味をなすはずです。 真新しい仮想電球でさまざまな色を試してみることができます。 しかし、私たちがこのようにやってきた理由は、それをモノのインターネットエコシステムの別のデバイスにするためでした。

hw-api.js

自作のフロントエンドJSの最後。 WiFiまたはBluetooth電球が電話、サーバー、ハブなどのリモートコントローラーで行うように、サーバーとのワイヤレス接続を模倣します。 これは、実際のプラグインコードがそれを制御するために使用するインターフェースです!

 var socket = io.connect() socket.on('connect', function () { console.log('ws:// bulb is online') }) socket.on('disconnect', function () { console.log('ws:// connection with bulb lost') }) socket.on('set', function (params) { changeBulbParams(params) // uses functions from bulb.js! }) socket.on('get', function () { const params = { power: power.value, color: color.value } socket.emit('params', params) })

最後に、WebSocketライブラリをHTMLから含める必要があるため、フロントエンドの準備が整います。 https://raw.githubusercontent.com/netbeast/bulb-plugin/master/public/socketio.jsからソースをコピーして、 socketio.jsというファイルに貼り付けることができます。 curlまたはwgetを使用するターミナルから、これを簡単に行うことができます。

 curl https://raw.githubusercontent.com/netbeast/bulb-plugin/master/public/socketio.js > public/socketio.js

これで、次のようなファイル構造になります。

 myplugin ├── README.md ├── index.js ├── package.json ├── public │ ├── bulb.css │ ├── bulb.js │ ├── hw-api.js │ ├── index.html │ └── socketio.js └── test.js

バックエンド

次に、デバイスとのインターフェイスを実装し、Netbeastエンジンに登録します。 WebSocketをリッスンして、電球がネットワークにインストールされていることを検出し、Dashboard APIにPOSTを実行して、新しいリソースを利用できるようにします。

そのために、以前に生成したファイルを見てみましょう。

package.json

このファイルには、アプリの実行に必要なすべての依存関係と情報が含まれています。 Netbeastは、通常のpackage.jsonを使用して、名前やタイプなどの情報を取得します。 このパッケージがプラグインであることを指定することが重要です。

 { "name": "myplugin", "version": "0.0.0", "description": "Netbeast plugin for... <your description>", "main": "index.js", "netbeast": { "bootOnLoad": true, "type": "plugin" }, "dependencies": { "bluebird": "^3.3.5", "body-parser": "^1.15.0", "express": "^4.13.4", "minimist": "^1.2.0", "mocha": "^2.3.2", "morgan": "^1.6.1", "netbeast": "^1.0.6", "socket.io": "^1.4.5", "superagent": "^1.8.3" }, "devDependencies": {}, "scripts": { "test": "node test.js", "start": "node index.js" }, "repository": { "type": "git", "url": "GITHUB_REPOSITORY" }, "keywords": [ "iot", "netbeast", "plugin" ], "author": "YOUR_EMAIL", "license": "GPL 3", "bugs": { "url": "ISSUES_CHANNEL" }, "homepage": "HOMEPAGE" }

index.js

これは、プラグインを起動するためにNetbeastダッシュボードから呼び出されるコードです。 着信要求を受け入れる場所を知るには、コマンドライン引数でポートを受け入れる必要があります。 node myplugin.js --port <a free port number>と入力したかのように起動されます。 冒頭のシバンにもご注意ください! #!/usr/bin/env node

 #!/usr/bin/env node var io = require('socket.io')() var express = require('express') var bodyParser = require('body-parser') var app = express() // Netbeast apps need to accept the port to be launched by parameters var argv = require('minimist')(process.argv.slice(2)) app.use(express.static('public')) // will serve our app in an HTTP server app.use(bodyParser.json()) // will parse JSON API calls app.use('/api', require('./plugin')(io)) var server = app.listen(argv.port || 31416, function () { console.log('Bulb plugin listening at http://%s:%s', server.address().address, server.address().port) }) // we need websockets to push updates to browser view io.listen(server)

ご覧のとおり、実際にsocket.ioコントローラーを実装するファイルを起動するためのファイルがありませんでした。 何も派手ではありません!

plugin.js

 var express = require('express') var netbeast = require('netbeast') var router = express.Router() var bulbParams // auxiliar variable, nasty way to transmit changes, but works module.exports = function (io) { io = io // Create resource that works on lights topic and listens on /api route netbeast('lights').create({ app: 'myplugin', hook: '/api' }) io.on('connection', function () { console.log('ws:// bulb has connected to plugin') }) io.on('disconnection', function () { console.log('ws:// bulb has disconnected from plugin') }) io.on('connect_failure', function (err) { console.trace(err) }) router.post('/', function (req, res) { io.emit('set', { power: req.body.power, color: req.body.color, }) res.status(200).json(req.body) }) router.get('/', function (req, res) { io.emit('get') var timerReference = setTimeout(function () { if (bulbParams) { res.json(bulbParams) } else { res.status(200).json({ error: 'No bulb available' }) } }, 3000) }) return router }

アプリを起動する

次に、アプリをテストします。 これを行うには、 tar.gz形式でパッケージ化し、ダッシュボードのドラッグアンドドロップセクションhttp:// localhost:8000/installにアップロードします。

 beast package # Compresses your app when ran in myplugin dir

出来上がり! これで、プラグインに移動してテストできます。 ネットワークセクション(http:// localhost:8000 / devices)に移動して、実行されていることを確認し、そこから色を変更します。

何か問題が発生した場合、または詳細を見逃したと思われる場合は、 node index.jsを使用してローカルで実行してみてください。そうすれば、 netbeast startログ内よりもデバッグが簡単になります。

あなたの作品を公開する

アプリをNetbeastダッシュボードの[探索]セクションに表示する場合は、説明とREADME.mdの両方に含まれているNetbeastアプリまたはNetbeastプラグインを使用してGitHubにリポジトリを作成する必要があります。

アプリを見つけるために、GitHubの検索APIを利用します。 https://api.github.com/search/repositories?q=netbeast+language:javascriptにGETリクエストを送信したときに表示されるのと同じ結果が表示されます。

アプリが表示されると、アプリが表示されることがわかります。

次は何ですか?

どちらのプロジェクトもオープンソースであり、実際にコミュニティが関与しています。 Node-REDへの独自のフローまたはノードの作成を開始する場合は、それらの公式ドキュメントをご覧ください。 そこに記載されている手順に従うと、すぐに独自のノードまたはフローを公開できるようになります。

一方、Netbeastの内部に飛び込みたい場合は、それらのドキュメントに従うか、ダッシュボードリポジトリを確認することができます。 Netbeast APIを使用すると、個々のデバイス、ブランド、またはテクノロジーに集中する必要がなくなるので、試してみてください。 ここで詳細を学ぶか、Slackチャネルに参加して、Node-RED、IoT、またはNode.jsについて話し合うことができます。

このようなものをRaspberryPi、Beagle Bone、または古いサーバーにインストールする場合は、コードなしでハッキング可能なスマートハブに変えることができます。 両方のサイトにそれらの既成のビルドがあります。

ハッピーハッキング。

関連:安全でないモノのインターネット(IoT)を作成していますか?