整体流程如下图所示
首先,您需要安装node-red-contrib-opcua和node-red-contrib-mssql-plus节点,以便使用OPC UA Client获取OPC变量值,连接SQLServer。
然后,您可以使用Inject节点(OPC采集)作为触发器,用于定期采集OPC变量值。
接下来,通过Function节点进行数据预处理。把需要需要采集的OPC UA变量放到这里,格式如图所示。
根据OPC UA服务器配置OPC UA Client 节点。
把获得的OPC UA 的值传送到 function(数据处理flow)中,把变量和值,成对的存放到flow中的数组变量中。(下边这段代码根据别人的代码,由GPT生成。)
var myvalue = msg.payload; // 获取消息的 payload
var ss = JSON.stringify(msg.topic.nodeId); // 将 msg.topic.nodeId 转换为字符串
// node.warn(msg);
ss = ss.replace(/^"|"$/g, ''); // 移除字符串开头和结尾的双引号
// node.warn(ss);
// 确保替换后的字符串是有效的
var nodearr = ss.split('='); // 以 '=' 分割字符串
// node.warn(nodearr);
// var tagid = nodearr[nodearr.length - 1].slice(0, -1).replace(/#/, '_').replace(/\.+/g, '_'); // 获取最后一个元素,去掉最后一个字符,并替换 '#' 为 '_'
var tagid = nodearr[nodearr.length - 1].replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g, '_').replace(/_+/g, '_'); // // 获取最后一个元素,替换非法字符为下划线,并将连续的下划线替换为单个下划线
// node.warn(tagid);
flow.set(tagid, myvalue); // 将 tagid 和 myvalue 存储在 flow 范围内
var keys = flow.keys(); // 获取所有存储的 keys
// node.warn("num:" + keys.length);
// for (let i = 0; i < keys.length; i++) { // 遍历所有 keys
// var key = keys[i];
// var value = flow.get(key); // 获取每个 key 对应的值
// // 可以在这里添加对 key 和 value 的处理逻辑
// // node.warn("key:" + key + ", value: " + value);
// }
msg.payload = tagid; // 将 msg.payload 设置为 tagid
return msg; // 返回 msg
在上述代码中,我们将获取到的OPC变量值存储到flow中。
下边是把flow中存储的数组发送给SQLServer。
这是一个周期性触发的节点。
使用function节点拼接出SQL语句,这个拼接SQL语句的function是GPT写的,代码如下:
// 初始化 SQL 语句字符串
var sql = "";
// 获取流程上下文中所有的 key
var keys = flow.keys();
// node.warn("num:" + keys.length); // 输出 key 的数量用于调试
node.warn(keys);
// 定义替换非法字符的正则表达式,只保留字母、数字、汉字和下划线
var regex = /[^a-zA-Z0-9_\u4e00-\u9fa5]/g;
// 遍历所有的 key,并输出其对应的 value
for (var i = 0; i < keys.length; i++) {
var key = keys[i]; // 获取当前的 key
var value = flow.get(key); // 获取当前 key 对应的 value
// node.warn("Key:" + key + ", Value: " + value); // 输出 key 和对应的 value 用于调试
// 替换非法字符
var sanitizedKey = key.replace(regex, '_');
// node.warn(sanitizedKey);
// 判断数据类型并选择适当的数据类型
var valueType = typeof value;
var columnType = "";
var valueStr = "";
if (valueType === "string") {
columnType = "NVARCHAR(MAX)";
valueStr = "'" + value + "'";
} else if (valueType === "number") {
if (Number.isInteger(value)) {
columnType = "INT";
} else {
columnType = "FLOAT";
}
valueStr = value;
} else if (valueType === "boolean") {
columnType = "BIT";
valueStr = value ? 1 : 0;
} <