物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)

NODE-RED配置与逻辑

这个部分中,我们将:

  1. 在树莓派上安装NODE-RED。
  2. 用NODE-RED生成简单的灯带控制网页。
  3. 在NODE-RED中发送HTTP请求获得本地日落时间,在日落时将灯带从日间颜色渐变成夜间颜色。

NODE-RED介绍及安装

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"进入网页编辑器了。
物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第1张图片

NODE-RED生成灯带控制网页

首先请安装node-red-dashboard节点。进入菜单中的节点管理:物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第2张图片
然后在”安装“中搜索node-red-dashboard并安装。物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第3张图片
在安装完成后,在左侧节点列表中会出现新的dashboard(仪表盘)组。物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第4张图片

NODE-RED生成的网页地址为”NODE-RED服务器/UI"(比如http://192.168.3.101:1880/ui)。

在右上角的dashboard标签-Layout里,添加Tab 1标签页,在Tab 1中添加UI group并重命名为LED。

物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第5张图片
接下来,加入两个调色板节点和一个开关节点。物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第6张图片

双击节点打开编辑页面。
Group:节点所属的UI组,将其设为刚才创建的[Tab 1]LED。
SIZE:节点在UI网格中的大小。group默认为6个单位宽,每个单位48像素,可以在group编辑界面和dashboard-site中修改上述默认值。
Lable:UI中的标签。
Name:编辑器中的标签。

在选色器节点中,将节点输出格式设置为rgb(因为与灯条控制值相同),勾选 Always show picker 始终显色色轮。
在开关节点中,将输出格式设置为文字列。物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第7张图片
用浏览器访问编辑器网址/UI(比如http://192.168.3.101:1880/ui)就能看到刚刚添加的UI了。

物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第8张图片

通过webservice获得当地日出与日落时间

接下来,我们将用https://sunrise-sunset.org/api的api获取日出与日落时间。
物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第9张图片

蓝色的注入节点在每天2:00执行。由于它仅仅用于触发HTTP请求,因此设置内容为空:物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第10张图片
接下来是一个http request节点用来发送HTTP请求。
物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第11张图片
发送的请求的URL格式请参考API网站的范例。(设置url参数formatted=0以便用返回的字符串直接初始化Date对象)

接下来是一个路由节点。路由节点将符合条件的消息路由至对应的输出口。
物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第12张图片
这里,它将以返回的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对象。物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第13张图片

接下来,添加三个function节点将输出格式化为上一章程序中ESP32能接受的格式,并将转化后的javascript对象保存至流程的全局变量。(flow.X为单个流程中的全局变量,global.X为所有流程中的全局变量)。
物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第14张图片
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;

物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第15张图片
上面的函数返回后将会触发一个决定颜色的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;
}

上面的函数节点功能:

  1. 在(日落-transitionTime)到日落 这个时间段内将灯带颜色由白天颜色过渡到夜间颜色。
  2. 当开关(on)为false时,关闭灯带输出。
  3. 当 现在时间>日落 或 现在时间<日出 时,输出白天颜色。
  4. 其他时间输出夜间颜色。

物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第16张图片
在上面的函数节点后,json节点将msg.payload对象转化为json字符串。
物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第17张图片
MQTT输出节点把json字符串作为MQTT消息负载,在指定的TOPIC上发送消息。
物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED)_第18张图片

总结

现在我们有了一个web界面控制的灯带,它能在日夜间自动切换颜色。除了上面示例简单功能外,NODE-RED还有许多节点可以使用,包括访问TCP,SQL数据库,本地文件,树莓派的硬件接口等等,而它的网页UI部分可以直接添加html/angular语句。
希望这部分内容对大家有所帮助。

链接:第一部分,第二部分

你可能感兴趣的:(物联网控制的智能LED灯带(3):NODE-RED(1)(WS2812/2811,ESP32,MQTT,NODE-RED))