node-red轻应用
node-red-contrib-home-assistant-websocket #连接到 home assistant
node-red-contrib-cheerio-function (html解析jquery)
node-red-contrib-moment (时间计算)
node-red-node-pi-gpio (树莓派)
node-red-node-serialport (串口)
node-red-contrib-modbus
node-red-contrib-ui-led
node-red-node-arduino (firmata 通信)
node-red-contrib-socketcan
EMQX (mqtt服务端)(当了kv存储)
建议
-
涉及串口-需要延迟模块
- (限速6/s 涉及回路+10sm延迟)
- 485有严重的,数据同时发送的问题(不如can)
-
开机启动,最好有自检通过再运行。
- 输入输出线 先启动会出现怪问题
firmata 协议 (全双工控制) web测试
http
http://192.168.0.123:1880/tget?a=1
http://192.168.0.123:1880/send-by-phone?msg=123 #发送消息
(http in)->(http response) 直接连接
发送消息
curl --location --request POST 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?access_token=G-Jeb3W990OXhh9VDt48zUEJDpNZQkArPnAinGcC6wMusLEEJzzaOwOB0LUvZYC3qjVJh629FnUE53WKsFj-rExQpVXu-NM_ZqcFINuiRjvLuqLw6xR5pDS7ZCoQUlGefCmmXgJgyr1Onb4e6Mi8xKr6UaSGW6wt5mrQL5YGmvf1Xl-nG1HzIhK3MGkyBObag54_pkzfg995hR1zF3RhMA' \
--header 'Content-Type: application/json' \
--data-raw '{
"corpid": "ww9c0c7927b70a1368",
"corpsecret": "liSANMa-e1atIqLlKSIQKpsB1YaZ0HbLBiaHGednV_A"
}'
msg.url="https://qyapi.weixin.qq.com/cgi-bin/gettoken?access_token=G-Jeb3W990OXhh9VDt48zUEJDpNZQkArPnAinGcC6wMusLEEJzzaOwOB0LUvZYC3qjVJh629FnUE53WKsFj-rExQpVXu-NM_ZqcFINuiRjvLuqLw6xR5pDS7ZCoQUlGefCmmXgJgyr1Onb4e6Mi8xKr6UaSGW6wt5mrQL5YGmvf1Xl-nG1HzIhK3MGkyBObag54_pkzfg995hR1zF3RhMA"
msg.payload={
"corpid": "ww9c0c7927b70a1368",
"corpsecret": "liSANMa-e1atIqLlKSIQKpsB1YaZ0HbLBiaHGednV_A"
}
return msg;
模块时间戳问题
npm search moment
npm install moment
功能.函数设置.导入模块
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const result = moment( Date.now(); )
//.add(8, 'hours')
.format('HH:mm:ss');
输入消息 = result +'\n'+ timeZone
变量
全局变量
保存: flow.set('authToken', new_token);
读取: let token = flow.get('authToken');
非函数中使用
$flowContext("在家与否")
$globalContext("authToken")
parseInt($flowContext("温度") )
payload == 主逻辑
myload == 自有逻辑
代码编程
时间
new Date().toLocaleString('zh-CN')
用 moment库
moment().format('YYYYMMDD HH:mm:ss')
Switch (开关)
Function (功能) 支持多输出 代替Switch分支
Change (修改变量) payload中没有获取到值就会卡住
消息推送
// in msg变量 out msg变量 处理完后 赋值给msg.payload
let 输入消息 = msg.payload
if (msg.topic){
输入消息 = msg.topic +'\n' +输入消息
}
msg.payload= {
"msgtype": "text",
"text": {
"content": 输入消息
}
}
return msg;
远程执行命令
依赖模块 ssh-exec
msg.payload = `cat <<EOF > /mnt/sp-ip.list
${msg.payload}
EOF\n`
return msg;
注意: 最后需要换行回车
http解析
cheerio节点
// 收集所有链接到数组中
let links = [];
$("a").each(function () {
links.push($(this).text());
});
links = Array.from(new Set(links)).sort();
// 将数组赋值给msg.payload
msg.payload = links.join('\n')
return msg;
收集命令行
iftop -P -n -N -t -s 10 -L 20 | \
curl -X POST -H "Content-Type: text/plain" --data-binary @- \
http://192.168.14.144:1880/wrt/iftop
处理命令输出
function extractIPs(text) {
//匹配ip
const ipPattern = /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/g;
return text.match(ipPattern) || [];
}
// 使用示例
const text = msg.payload
const ips = extractIPs(text);
let publicIPs = [];
// 筛选
ips.forEach(ip => {
// 跳过 192.168 开头的 IP
if (ip.startsWith("192.168")) {
return; // 相当于 continue
}
// 处理其他 IP
publicIPs.push(ip);
});
//--返回
msg.payload = publicIPs.join('\n')
return msg;
hass连接
用户 ->标签:安全->长期访问令牌
(url最后不能有/斜杠,协议+IP+端口)
打包模块
可以通过打包 废弃一部分初始数据
join模块 可以统一一次性更新
api
可以访问几乎所有的东西
gpiod
gpiodetect
gpioinfo gpiochip0
/dev/ch343_iodev
安装CA证书
apk update && apk add ca-certificates