本文章基于我前两篇和Node-Red有关的文章。

《Node-Red读写西门子PLC并上传至云服务器》

《将PLC数据上传至物联网平台进行可视化显示》

安装MySQL数据库:参考该文章 mysql数据库安装(详细)

我一开始使用的是图形化安装,但安装完后一直无法正常启动数据库,于是卸载后重新通过压缩包安装。

数据库安装完成后通过 Navicat 软件新建一个名为 nodered 的数据库并新建如下表,表名 plc。

img

通过Node-Red修改数据库中表的内容:

启动Node-Red并进入Node-Red网页,在节点管理处安装 node-red-node-mysql 节点。

img

在上一篇文章中的 数据封装节点(templete)后加入 function 节点,函数内容如下:

var temperature = msg.payload.params.Int // 创建全局变量temperature并赋值为上一个templete节点的输出信息
msg.topic ="UPDATE plc SET temperature="+temperature+" WHERE id=1;" // 将MySQL的查询语句赋给topic
return msg;
img

在界面左侧的储存区找到新添加的 mysql节点 并拖出,双击该节点,在Database处选择添加新的MySQLdatabase,写入之前创建的数据库信息。

img

点击完成并选择刚才添加的 Database ,创建完成后按照如下方式连接各节点。

img

根据上一篇文章编写PLC程序并部署 Node-Red,新建监控表并修改相关数据即可看到数据库中的数据随监控表处的数据变动而变动。(如未变动请右键手动刷新数据库)

img
img
img
img

通过 Node-Red 读取数据库中表的内容并利用 WebSocket 对接HTML网页端进行显示:

在Node-Red左侧共通区拖出inject节点,双击编辑,在重复处选择周期性执行,间隔时间可自定义,点击完成编辑。

img

拖出功能区的function节点,写入如下查询语句。

msg.topic ="SELECT temperature from plc WHERE id=1;" // 查询表plc中id为1的temperature数据
return msg
img

再次拖出mysql节点,以及网络区的 websocket out 节点 ,mysql节点依然选择刚才创建的 Database。在 websocket节点 的路径处选择添加新的 websocket-listener 节点,并点击后面的笔编辑。发送/接受 选择有效载荷,路径处填写:

/ws/request
img
img

点击完成完成编辑,并将上述节点按如下方式连接后点击右上角部署按钮。

img

创建HTML文件:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>数据可视化</title>

<!-- 按钮样式 -->
<style>
#login_click{ margin-top:40px; height:40px;margin-left:200px;}
#login_click a 
{
text-decoration:none;
background:#67e0e3;
color:#fd666d;

padding: 10px 30px 10px 30px;
font-size:16px;
font-family: 微软雅黑,宋体,Arial,Helvetica,Verdana,sans-serif;
font-weight:bold;
border-radius:30px;

-webkit-transition:all linear 0.30s;
-moz-transition:all linear 0.30s;
transition:all linear 0.30s;

}
#login_click a:hover { background:#37a2da; }
</style> 

<script src="https://cdn.jsdelivr.net/npm/echarts@5.3.2/dist/echarts.js"></script>

<script type="text/javascript"> 
// WebSocket通信代码
var temperature = 0; //定义温度全局变量
function WebSocketTest()
{
if ("WebSocket" in window)
{
// 浏览器支持 WebSocket
alert("调用成功!");

// 连接WebSocket
var ws = new WebSocket("ws://localhost:1880/ws/request");

// // 发送数据
// ws.onopen = function()
// {
// ws.send("发送数据");
// alert("数据发送中...");
// };

// 接收数据
ws.onmessage = function (evt) 
{
// alert("数据已接收...");
var data = JSON.parse(evt.data);
temperature = data[0].temperature;
// console.log(temperature);
};

// // 关闭连接
// ws.onclose = function()
// { 
// alert("连接已关闭..."); 
// };
} 
else
{
// 浏览器不支持 WebSocket
alert("您的浏览器不支持 WebSocket!");
}
}
</script>
</head>

<body>
<!-- 仪表盘代码 -->
<div id="main" style="width: 600px;height:400px;"></div>
<script>
var mycharts = echarts.init(document.getElementById("main")); 
var option = {
series: [
{
type: 'gauge', // 图表类型,这里表示仪表盘
axisLine: { 
lineStyle: {
width: 30, // 仪表盘外圈的宽度为30px
color: [
[0.3, '#67e0e3'], // 到30%的颜色
[0.7, '#37a2da'], // 到70%的颜色
[1, '#fd666d'] // 到100%的颜色
]
}
},
pointer: { // 仪表盘指针设置
itemStyle: {
color: 'auto' // 指针颜色,此处是自动,根据指向的范围变相应的颜色
}
},
axisTick: { // 设置仪表盘上的刻度短线
distance: -30, // 刻度短线的位置 
length: 8, // 刻度短线的长度 
lineStyle: {
color: '#fff', //刻度短线的颜色
width: 2 //刻度短线的宽度
}
},
splitLine: { // 分割线设置,如: 0-10和10-20之间的分割线
distance: -30, //分割线位置
length: 30, // 分割线长度
lineStyle: {
color: '#fff', // 分割线颜色
width: 4 // 分割线宽度
}
}, axisLabel: { // 仪表盘里圈数字设置
color: 'auto', // 设置颜色,此处是:自动
distance: 40, // 里圈数字的位置
fontSize: 10 // 里圈数字的大小
},
detail: {
valueAnimation: true, // 仪表盘显示的值是否有动画效果
formatter: '{value} ℃', // 仪表盘显示的值和单位
color: 'auto' // 仪表盘显示的值数字的颜色
},
data: [
{
value: temperature // 当前仪表盘数值,实际开发中,这里的值是动态变化的。比如从传感器采集而来
}
]
}
]
};
mycharts.setOption(option);

// 每一秒刷新一次表盘
setInterval(function () {
mycharts.setOption({
series: [
{
data: [
{
value: temperature
}
]
}
]
});
}, 1000);
</script> 

<!-- 连接按钮 --> 
<div id="login_click">
<a href="javascript:WebSocketTest()">连接 WebSocket</a>
</div>

</body>
</html>

使用浏览器打开编写好的HTML文件即可看到如下画面,点击 连接WebSocket 按钮进行连接,若配置正确,则一秒后显示数据库的最新信息。

img

此处放上利用function节点向表中插入新数据的代码,连接方式和上面一样,在后面加上mysql节点。 

msg.payload = ['1','Int','30']
msg.topic ="INSERT INTO plc (id,name,temperature) VALUES (?,?,?);"
return msg;

这是我整个项目的配置:

img