本文概述
- Node-RED入门
- 现在, 让我们去Pro:家庭自动化的时机
- 让我们更深入
- 创建自己的插件
- 下一步是什么?
用文本编写程序很有效, 并且在大多数情况下效果很好。但是, 通常需要视觉上表达程序的能力。通常, 仅需要能够通过大型系统的各个组件设计信息流。可视化编程工具还对那些不熟悉编程并且努力处理各种概念(例如变量, 指针, 信号, 范围等)的人宽容。
文章图片
Node-RED是用于可视化编程的工具。它以可视方式显示关系和功能, 并允许用户进行编程而无需键入语言。 Node-RED是一个基于浏览器的流编辑器, 你可以在其中添加或删除节点并将它们连接在一起, 以使它们彼此通信。
在Node-RED中, 每个节点都是以下两种类型之一:注入节点或功能节点。注入节点无需任何输入即可生成消息, 并将消息推送到与其连接的下一个节点。另一方面, 功能节点接受输入并对其执行一些工作。有了这些节点的众多选择, 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” 的情况下, 什么完整的初学者编程教程呢?让我们首先尝试一下:
- 在流程编辑器上拖放一个注入节点。然后双击并将有效负载设置为字符串, 然后输入” Hello world” 。
- 拖放调试节点, 方法与注入节点相同。
- 将它们连接在一起。
- 单击右上角的” 部署” 按钮。
- 单击注入节点左侧的蓝色按钮。
文章图片
只是JavaScript
使用Node-RED, 你不仅会局限于简单的节点和功能。由于Node-RED是基于Node.js构建的, 因此全部由JavaScript驱动。节点确实是Node.js模块。可以在http://flows.nodered.org/中找到它们, 因此要将它们添加到左侧面板中, 只需” npm install” 它们即可。实际上, 你可以开发自己的流程并将其上传到流程存储库。应用程序可以随心所欲, 因为你可以在Node-RED提供的代码编辑器内的函数节点中键入JavaScript。
由于该平台基于Node.js, 因此它利用了相同的事件驱动的非阻塞模型。因此, 基于Node-RED构建的应用程序可以在诸如Raspberry Pi的低成本硬件上以及在云中运行。
现在, 让我们去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上可用, 而在8443上的SSL上可用。接下来, 将浏览器打开到http:// localhost:8000, 然后导航到Explore。在那里, 我们将能够找到许多应用程序和插件。寻找智慧型灯泡的品牌(Philips Hue, LIFX, WeMo), 或者如果没有品牌, 请尝试下载灯泡外挂程式。检查你的仪表板插件是否包含其中之一!
文章图片
黄色标志表示插件正在运行, 但是找不到任何设备。单击灯泡插件以创建虚拟灯泡。发现的任何其他设备应出现在” 网络” 下。
一切准备就绪后, 让我们重新开始工作。我们将做一个简单的流程:
- 拖放一个注入节点。
- 拖放Netbeast节点。
- 拖放调试节点。
- 如下图所示将它们全部连接起来:
文章图片
现在, 我们将HTTP请求发送到仪表板。使用Netbeast API, 我们将必须通过注入节点发送一个JSON, 其中包含我们要在灯泡上触发的值。
文章图片
按下按钮, 为所有智能灯泡注入颜色和电源!
文章图片
每个主题代表一种不同的设备。因此, 这里有灯光的主题, 还有音乐, 暖气和视频的主题。以及湿度, 存在, 温度和传感器列表, 此列表仍在继续。你可以在他们的文档中找到主题列表及其建议的结构, 以将其翻译为各种设备。此物联网引擎不成熟, 但功能强大。开源, 允许开发人员重用信息以创建真正连接的场景, 从而变得聪明。
让我们更深入 接下来, 我们将使用另一个插件(环境噪声检测器)创建第二个流程, 以将其用作触发器来将灯泡的颜色更改为噪声信号量。在本教程中, 我们将使用虚拟的, 因此无需购买新硬件。首先, 点击Node-RED编辑器中的” 加号” 按钮。
在Dashboard上再次转到http:// localhost:8000 / explore到Explore部分, 然后查找Volume-Plugin。这是一个非常基本的Web应用程序, 它利用浏览器中的getUserMedia()来捕获来自简单HTML应用程序的媒体。因此, 它可能仅适用于现代浏览器!
单击它可以打开, 就像虚拟灯泡一样。它将请求你的麦克风录音许可。然后, 它将消息发送到Netbeast的MQTT代理, 该代理将在所有仪表板之间共享, 因此我们可以进行订阅。为此, 我们只需要将netbeast-trigger节点拖放到node-red的编辑器中即可。然后, 我们将在触发器和Netbeast节点之间插入一个函数, 以便确定它何时太大声或不大声。另外, 我们应该使用一些调试节点来检查一切是否正常。现在, 该方案将如下所示:
文章图片
现在, 让我们向tooLoud函数节点中输入一些代码。是的, 我知道我答应过你无需编写代码就可以编程, 但是我已经证明了你可以!而且, 你可以尝试组合注册表中可用的不同元素或其他节点来完成以下任务。
var volume = msg.payload.volumenode.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'}}
}
这个相当简单的代码片段将根据下一个节点报告的音量级别, 为下一个节点返回具有特定颜色代码的三个有效负载之一。
现在我们准备出发了!让我们再次按下” 部署” 按钮并发出声音。让我们看看灯泡如何立即从一种颜色变为另一种颜色!
由于你使用的麦克风和网络浏览器可能有所不同, 请随时调整功能值和阈值, 并同时使用颜色值以查看其如何改变灯泡。
创建自己的插件
文章图片
纯CSS中的灯泡是受此cssdeck启发的。
你可能已经注意到, 以前的虚拟灯泡非常初级, 因此你可能需要对其进行调整。甚至更好的是, 你可以创建自己的智能家居控制器。因此, 我们将经历为Netbeast创建虚拟插件的过程, 这将使你能够为智能设备创建自己的控制器。
你可以使用netbeast-cli软件包自动生成一些代码。通过运行netbeast创建myplugin – plugin, 我们将得到一个基本项目, 如下所示:
myplugin
├── README.md
├── index.js
├── package.json
└── test.js
前端
现在, 让我们开始使用前端模拟灯泡。设备控制器通常没有一个, 因此脚手架命令中还没有公用文件夹。让我们在项目内部创建一个公共目录, 然后在其中放置以下HTML, CSS和JS文件。
index.html
<
head>
<
title>
Netbeast Bulb Plugin<
/title>
<
link rel="stylesheet" href="http://www.srcmini.com/bulb.css" media="screen" charset="utf-8">
<
/head>
<
body>
<
div class="top-decoration">
<
/div>
<
div id="plugin front-end">
<
/div>
<
div class="bulb-container small">
<
div class="bulb light">
<
div id="bulb">
<
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 id="base">
<
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 id="color" type="text" class="color" name="color" value="http://www.srcmini.com/00fea5">
"<
/i>
, <
i class="txt-green">
power<
/i>
: <
i class="txt-green">
"<
input id="power" type="text" class="power" name="power" value="http://www.srcmini.com/on">
"<
/i>
})<
/pre>
<
button id="run-btn">
RUN
<
/button>
<
/div>
<
!-- wrapper -->
<
!-- declares bulb features and methods -->
<
script type="text/javascript" src="http://www.srcmini.com/bulb.js">
<
/script>
<
!-- real time comms library -->
<
script type="text/javascript" src="http://www.srcmini.com/socketio.js">
<
/script>
<
!-- simulates hardware communication -->
<
script type="text/javascript" src="http://www.srcmini.com/hw-api.js">
<
/script>
<
/body>
bulb.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文件以实时观看!工作正常吗?太好了, 现在让我们提供一些功能。
bulb.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.colordocument.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 = http://www.srcmini.com/params.color || color.value
power.value = params.power || power.value
setBulbParams({color: color.value, power: power.value})
}
此后, 字段和运行按钮都应该有意义。你可以开始尝试使用全新的虚拟灯泡上的不同颜色。但是, 我们之所以走这条路, 是为了使其成为我们物联网生态系统的另一种设备。
hw-api.js 我们自制的前端JS的最后一个。它模拟了与服务器的无线连接, 就像WiFi或蓝牙灯泡将与其遥控器(例如电话, 服务器或集线器)一样。这是实际插件代码将用来控制它的接口!
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)
})
最后, 我们需要从HTML中包含WebSocket库, 因此前端已准备就绪。你可以从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, 以检测网络上是否已安装灯泡, 然后对仪表板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仪表板调用以启动插件的代码!它需要通过命令行参数接受端口, 以知道在何处接受传入的请求。就像我们键入节点myplugin.js – port < 自由端口号> 一样启动它。请同时注意开头的哈希! #!/ usr / bin / env节点。
#!/usr/bin/env nodevar 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 worksmodule.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)以查看其运行并从此处更改其颜色。
文章图片
如果出现问题或你认为你可能错过了一个细节, 请尝试使用节点index.js在本地运行它, 也许比在netbeast启动日志中更容易调试。
发布作品
【使用Node-RED进行可视化编程(轻松连接物联网)】如果要将你的应用程序显示在Netbeast仪表板” 浏览” 部分, 则必须在GitHub中使用Netbeast应用程序或Netbeast插件创建存储库, 这两个描述均包含在README.md中。
要查找应用程序, 我们使用GitHub的搜索API。我们向你发出GET请求时会看到相同的结果:https://api.github.com/search/repositories?q=netbeast+language:javascript
你会知道, 如果你的应用程序出现在其中, 就会显示出来!
下一步是什么? 这两个项目都是开源的, 并且确实涉及社区。如果要开始创建自己的Node-RED流或节点, 请查看其官方文档。按照此处描述的步骤进行操作, 你应该能够立即发布自己的节点或流程。
另一方面, 如果你想潜入Netbeast, 也可以遵循他们的文档, 或查看Dashboard存储库。使用Netbeast API, 你不必再专注于单个设备, 品牌或技术, 因此请尝试一下。你可以在此处了解更多信息, 或加入其Slack频道并讨论Node-RED, IoT或Node.js。
如果要将这些东西安装在Raspberry Pi, Beagle Bone或旧服务器上, 则可以将它们变成可黑客入侵的Smart Hub, 而无需代码!在这两个站点中都有针对它们的预制版本。
骇客入侵。
相关:我们是否正在创建不安全的物联网(IoT)?
推荐阅读
- 转到Python 3并再次转回来(是否值得进行切换())
- 并发编程简介(入门指南)
- Express,Koa,Meteor,Sails.js(启示的四个框架)
- 扩展Scala(如何使用Kubernetes进行Docker化)
- 如何通过缓存提高Web Farm中的ASP.NET App性能
- 如何修复Chrome不断崩溃(解决办法分步教程)
- 如何修复Windows 10中的DISM错误87(解决办法教程)
- 如何修复USB不断断开和重新连接(解决办法分步指南)
- 如何修复io.netty.channel.AbstractChannel$AnnotatedConnectException错误(解决办法)