前言
Node-Red
环境配置好之后,我去看了一些入门类的文章,基本上都是从各种节点组件开始讲起,要不就是一个最简单的 打印输出
的示例就完了。
但这么简单的入门教程其实跟不写一样,对于想要入门的新手来说,一点帮助都没有。
于是,我打算从一个需求点出发,通过实现该需求一步步的了解 Node-Red
的使用方法。
偶然间刷头条App时,看到顶部菜单项 北京
页面上面显示的天气,突然来了兴趣,干脆我就从实现一个天气预报的推送通知开始入门 Node-Red
吧。
获取天气接口
那么问题来了,天气接口从哪来呢?
看了看头条App上的天气页面,感觉基本的天气信息都有了。不过对头条App抓包不太好操作。于是打算看看头条PC版首页是不是好获取。
没想到天气接口直接就能拿到。那就开始吧!
打开浏览器的调试窗口。这里有一个技巧:如果第一次加载页面,无法记录到和天气相关的数据请求。
可以先 清除历史请求记录
,然后选择 筛选
所有的api请求。点击顶部的 天气城市切换
,可以看到下面已经显示出来切换后城市的天气请求数据了。
对获取到的天气接口做精简,得到如下:
1 | https://www.toutiao.com/stream/widget/local_weather/data/?city=上海 |
也就是说,我们只需要提供一个 城市名称
即可。
提取天气数据
在 Node-Red
页面中添加一个 inject节点
作为流程的触发起点。
上面我们得到了天气api接口,我们要做的第一步就是请求接口,得到天气数据。那么就需要从 网络
组中找一个能够发起http请求的节点。这里我们选择 http request节点
。
注意,URL一栏填入的接口中,为了防止报错要将城市中文名称进行URL编码处理(说明:直接从浏览器地址栏中拷贝过来就是被URL编码后的)。
再添加一个 debug节点
用来查看请求返回的结果。点击 部署
,触发流程。
结构如下:
可以看到正确请求了接口并返回了该城市天气数据。
返回的天气数据直接是一个 json对象
,那么我们可以直接拿到想要的信息。如上图所示,我们需要的参数都在 weather
对象下。那首先,我们要先拿到这个 weather
对象。
这里选择用 function节点
来处理。根据返回的json结构,加入如下代码:
1 | var data = msg.payload.data.weather; |
再次点击右上角 部署
,执行流程:
可以看到,右侧的输出中打印出了 weather对象
包含的所有属性。
构造天气信息
天气数据获取到了,下面要来考虑下如何输出这些信息。
获取指定参数
天气信息中,除了包含当前天气情况,今天天气情况和明天天气情况以外,还有未来两周天气和未来24小时天气情况。某些城市还包含特殊天气提醒。
这里为了简单,我只获取当时、今日和明日天气。其他的后续再考虑扩展。
继续在 function节点
中对数据做二次处理。
部署
后查看输出:
正确得到了我们想要的指定参数。
文案组装
获取到了所需的天气属性参数,对这些信息进行拼装,整理成了如下的天气播报文案:
1 | [上海]当前天气:[阴],气温[21]℃,空气质量[优]。今日天气:[中雨]转[小雨],气温[14]℃~[22]℃。明日天气:[小雨],[5]℃~[17]℃。 |
其中,中括号 []
中的内容为需要的天气属性参数值。
那这里又遇到一个问题,要如何将这些天气属性参数拼接成上面的文案呢?
Node-Red
中提供了一个 template节点
,我们可以用该节点实现文案拼接。
拖放一个 template节点
,先来研究一下如何使用。
将其中模板内容改为如下:
然后 部署
、执行。查看输出:
那么,从上一个节点中传递过来的 payload
参数,就表示上面经过二次处理后的 完整数据
,需要哪个参数,直接通过
1 | {{payload.xxx}} |
的形式就能获取到。
所以,模板中的内容对应于上面的文案,修改为:
1 | {{payload.city}}当前天气:{{payload.cur_con}},气温{{payload.cur_tp}}℃,空气质量{{payload.qua_level}}。今日天气:{{payload.day_con}}转{{payload.night_con}},气温{{payload.low_tp}}℃~{{payload.high_tp}}℃。明日天气:{{payload.tom_con}},{{payload.tom_low_tp}}℃~{{payload.tom_hight_tp}}℃。 |
注意,下面的 输出为
类型要选为 纯文本
。
部署
后执行,查看输出内容。
貌似输出的内容中有一些错误。
排查问题
最终输出的结果中出现了问题,那么要如何来调试找出问题所在呢?
这里就不得不再提一下 debug节点
。
前面我们在执行完成每一个步骤之后,都会加一个 debug节点
来查看该步骤的输出内容。这样的话,就便于我们判断该步骤是否执行成功。
经过查看,原来是在 提取天气数据
阶段出了问题
将其改正后,再次部署查看。
此时,输出的天气文案就是我们想要的了。
发送通知
天气信息有了,下一步就要考虑如何接收通知了。
选择通知方案
便于实现的消息通知方式,除了企业微信、钉钉机器人、飞书机器人之外,对于iPhone用户来说,还可以选择像 Bark
这种开源方案。
这里我选择的是一款名为 PushDeer
的开源App推送方案,效果类似于 Bark
。
参考 PushDeer 官方文档 使用官方在线版 - PushDeer·推送说明 的说明,在安装好App后,获取相应的 key
就可以通过如下的请求方式发送消息了:
1 | https://api2.pushdeer.com/message/push?pushkey=key&text=要发送的内容 |
实现通知请求
在 Node-Red
中,发送通知请求还是继续使用 http request节点
来实现。
拖放一个 http request节点
,由于此时的请求链接是带有 可变化
参数的,并不是像上面获取天气的链接那样直接指定后就不再改变。所以,这里在内容下拉框中要选择 Append to query-string parameters
项,表示将前面步骤传递过来的 msg.payload
作为url请求参数来使用。
但我们知道,上一个步骤 构造天气信息
中,输出的是我们拼装后的天气文案。
那也就是说,我们要在这两个节点之间对数据再做一次转换,将上一步的 天气文案
经过处理后作为下一个步骤的url请求参数使用。
构造请求参数
在上面 PushDeer
的请求链接中,我们需要的是两个url请求参数: pushkey
和 text
。其中,pushkey
在我们安装完App后已经得到;而 text
就是上一个步骤中的天气文案。
但要怎么将这两个参数作为url请求参数呢?
在使用工具时遇到了问题,最简单的方法就是去看官方文档。
查询 Node-Red
的官方文档,我找到了这篇文章 Handle query parameters passed to an HTTP endpoint : Node-RED
参照其中的说明,我们可以将参数构造成如下的键值对结构:
1 | { |
这样作为url的请求参数后的形式就是 /hello-query?name=Nick&colour=blue
。
这不正是我们所需要的嘛。
于是,为了实现中间的处理操作,我们可以通过拖放一个 function节点
来实现。将函数的处理逻辑改成如下:
同时,修改 http request节点
发送的URL为去除参数的形式:
发送通知
将以上流程组合,点击 部署
后手动触发。会发现 debug节点
打印了每一步的输出结果:
同时,我的手机上也收到了相应的通知提醒:
至此,天气预报通知手动触发操作算是实现了。
定时触发
不过为了接收天气预报,我们总不能每次都要打开电脑去点一下来进行操作吧。
最基本的,我想要实现的是每天早晨7:30起床后,手机上收到一条天气播报,了解一下当天的天气情况,这样临出门前也能应对当天可能出现的恶劣天气;每天晚上20:30临睡觉前,收到一条天气播报,了解一下明天的整体天气情况,是降温还是偏热,可以提前考虑一下明天的穿衣情况。
但是在 Node-Red
中想要实现定时触发,我却找不到符合这种条件的节点。虽说 inject节点
可以实现简单的 重复触发
操作,但功能比较简单,想要实现定时功能要做的处理比较复杂。
其实,Node-Red
的节点本质上就是一些 Nodejs
的模块实现的功能,内部执行的就是 Nodejs
脚本。
那么,我们可以通过安装第三方的模块来实现更多更复杂的功能。
安装定时模块
为了实现定时任务,比较灵活的方式就是通过 cron表达式
来实现。
在 Node-Red
中比较有名的支持 cron表达式
的模块叫 node-red-contrib-cron-plus
。
要在 Node-Red
中安装模块,依次选择:右上角 菜单
– 节点管理
– 左侧 控制板
– 右侧 安装
– 在 搜索模块
中输入名称
找到相应模块后点击 安装
,等待其安装即可。
npm加速
在等待了大约2分钟左右,我发现该模块还没有安装成功,一直处于下面的 安装中
界面:
又继续等待一段时间后,直接弹出了错误信息。查看日志后发现,果然又遇到了 特殊网络
问题。
上面日志中也描述的很清楚 npm install
安装时,网络请求失败。
对于
npm install
的问题,可以直接通过替换国内镜像源
的方式来解决。
登录 树莓派
,进入之前安装的 node-red
容器中:
1 | docker-compose -f docker-compose-node-red.yml exec hass-nodered bash |
直接执行如下命令来为 npm
设置国内镜像源:
1 | npm config set registry https://registry.npmmirror.com |
然后再回到 Node-Red
节点管理设置界面,再次安装模块,会发现该模块几秒钟就安装成功了:
定时模块配置
模块安装好后,在左侧的节点栏中可以看到新增了一个 cronplus
节点
拖放该节点并双击打开配置界面,在 Schedules
区域添加我们想要的定时cron表达式。
配置完点击 部署
后,可以发现该节点下方直接显示出了下一次执行的时间:
之后,将定时组件加入流程中。为了方便处理,我保留了手动和自动两种触发方式。同时也为了便于调试,我又将整体的流程布局做了调整,最终的效果如下:
流程分享
为了方便流程的分享,Node-Red
支持导入导出功能。
直接在右上角 菜单
中选择即可。
总结
至此,一个 Node-Red
入门流程 – 天气预报通知
的功能就实现了。
俗话说,授人以鱼不如授人以渔。
这里主要就是想通过如何实现一个小功能来入门 Node-Red
,关键还是要理清思路,一步一步来,遇到了问题不要慌,通过错误日志一点点分析,最终得到想要的结果。