这个部分中,我们将:
NODE-RED用一种有趣的可视化方式将各类硬件设备,API和服务连接起来。它的配置在WEB编辑器中进行,内置的各个调色板(palette)以连线完成逻辑连接。基于Node.js之上,流程能够在运行时一键部署(更新)。
NODE-RED现有包括用户贡献的超过上千个调色板(palette),支持
这个项目中NODE-RED将运行在一个树莓派上,树莓派上安装NODE-RED可以用下面的命令:bash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)
。
NODE-RED也可以在Windows下运行,在安装Node.js之后,使用npm install -g --unsafe-perm node-red
安装NODE-RED。
默认情况下所有人都可以访问NODE-RED编辑器和NODE-RED生成的控制网页,如果需要用户访问控制,请参见文档。
当安装完成后,用node-red-pi --max-old-space-size=256
(windows下使用node-red
)启动NODE-RED(关于使用SystemD自动启动NODE-RED)。 现在,我们可以用“服务器地址:1880"进入网页编辑器了。
首先请安装node-red-dashboard节点。进入菜单中的节点管理:
然后在”安装“中搜索node-red-dashboard并安装。
在安装完成后,在左侧节点列表中会出现新的dashboard(仪表盘)组。
NODE-RED生成的网页地址为”NODE-RED服务器/UI"(比如http://192.168.3.101:1880/ui)。
在右上角的dashboard标签-Layout里,添加Tab 1标签页,在Tab 1中添加UI group并重命名为LED。
双击节点打开编辑页面。
Group:节点所属的UI组,将其设为刚才创建的[Tab 1]LED。
SIZE:节点在UI网格中的大小。group默认为6个单位宽,每个单位48像素,可以在group编辑界面和dashboard-site中修改上述默认值。
Lable:UI中的标签。
Name:编辑器中的标签。
在选色器节点中,将节点输出格式设置为rgb(因为与灯条控制值相同),勾选 Always show picker 始终显色色轮。
在开关节点中,将输出格式设置为文字列。
用浏览器访问编辑器网址/UI(比如http://192.168.3.101:1880/ui)就能看到刚刚添加的UI了。
接下来,我们将用https://sunrise-sunset.org/api的api获取日出与日落时间。
蓝色的注入节点在每天2:00执行。由于它仅仅用于触发HTTP请求,因此设置内容为空:
接下来是一个http request节点用来发送HTTP请求。
发送的请求的URL格式请参考API网站的范例。(设置url参数formatted=0以便用返回的字符串直接初始化Date对象)
接下来是一个路由节点。路由节点将符合条件的消息路由至对应的输出口。
这里,它将以返回的JSON中的status值等于”OK"为条件。当status不等于OK时,消息被路由到延迟节点,在延迟10秒钟后,重新触发http请求。status值为OK时,消息被路由到函数节点中进行保存。
函数节点将日落日出时间保存为全局变量:
var sunrise=new Date(msg.payload.results.sunrise);
flow.set("sunriseTime",sunrise);
var sunset=new Date(msg.payload.results.sunset);
flow.set("sunsetTime",sunset);
通过添加debug(调试)节点到UI的输出。我们可以看选色器UI输出的msg.payload为{r:164,g:255,b:149,a:1}格式的javascript对象。
接下来,添加三个function节点将输出格式化为上一章程序中ESP32能接受的格式,并将转化后的javascript对象保存至流程的全局变量。(flow.X为单个流程中的全局变量,global.X为所有流程中的全局变量)。
function节点为一段javascript函数,接收来自前面节点的名为msg的参数,数据载荷存储在msg.payload。function节点可以返回对象,将数据继续向后传递。如果想要触发后面的节点,function不能不返回或返回NULL。
var day={red:msg.payload.r,green:msg.payload.g,blue:msg.payload.b};
flow.set("DayColor",day);
return msg;
上面的函数返回后将会触发一个决定颜色的function节点。除了操作UI更改外,每隔20秒触发的注入(inject)节点以及MQTT输入节点(当ESP32上线时会往bedroom/light/status/switch这个TOPIC发送消息)也会触发决定颜色的function节点。
var transitionTime=3600000;
function map( x, in_min, in_max, out_min, out_max){
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
var ni=flow.get("NightColor");
var nightColor=new Array(ni.red,ni.green,ni.blue);
var da =flow.get("DayColor");
var dayColor= new Array(da.red,da.green,da.blue);
var now=new Date();
var sunrise=flow.get("sunriseTime");
var sunset=flow.get("sunsetTime");
if(flow.get("on")=="false"){
var colorobj={ red:0, green:0, blue:0};
var newMsg = { payload: colorobj };
return newMsg;
}
else if(parseInt(sunset-now)<transitionTime&&now<sunset){
var outputcolor=new Array(3);
for(var i=0;i!=3;++i)
outputcolor[i]=Math.round(map(parseInt(sunset-now),0,transitionTime,nightColor[i],dayColor[i]));
var colorobj={ red:outputcolor[0], green:outputcolor[1], blue:outputcolor[2]};
var newMsg = { payload: colorobj };
return newMsg;
}
else if(now>=sunset||now<=sunrise){
var newMsg = { payload: ni };
return newMsg;
}
else {
var newMsg = { payload: da };
return newMsg;
}
上面的函数节点功能:
在上面的函数节点后,json节点将msg.payload对象转化为json字符串。
MQTT输出节点把json字符串作为MQTT消息负载,在指定的TOPIC上发送消息。
现在我们有了一个web界面控制的灯带,它能在日夜间自动切换颜色。除了上面示例简单功能外,NODE-RED还有许多节点可以使用,包括访问TCP,SQL数据库,本地文件,树莓派的硬件接口等等,而它的网页UI部分可以直接添加html/angular语句。
希望这部分内容对大家有所帮助。
链接:第一部分,第二部分