使用ogamma Visual Logger for OPC和InfluxDB存储、处理和可视化数据
作者:社区 / 产品, 用例, 开发者
2020年10月2日
导航到
本文由One-Way Automation软件架构师Ravil Nugmanov撰写,One-Way Automation是一家位于加拿大埃德蒙顿的初创公司。
本文描述了一个端到端解决方案,该方案使用开源组件InfluxDB和Grafana以及ogamma Visual Logger for OPC,以收集工业过程控制数据,以流式模式分析数据,并在仪表板上进行可视化。
问题
对于此演示,我们使用一个假设的工业泵,该泵通过OPC UA服务器发布以下值
- 输入压力
- 输出压力
- 温度
- 电源状态
在仪表板上,我们希望可视化以下信息
- 这些变量的当前值
- 图表中的历史值
- 计算输入和输出压力平均值的差异,并在仪表板上显示结果
- 定期检查从上述数据中计算出的压力差异,如果超出期望范围,则生成通知,并在仪表板上显示。
解决方案
以下是此问题的解决方案图
以下章节将详细说明所用组件及其交互方式。
OPC UA 数据源
作为为监测的泵提供值的数据库,我们使用了Prosys OPC UA 模拟服务器。与其他可用的模拟服务器不同,您可以根据特定需求构建自定义的 OPC UA 地址空间,并且可以根据选定的模式(如随机、正弦、锯齿等)自动生成变量的值。
时间序列数据库和流分析引擎
作为时间序列数据库,InfluxDB 被选择是因为它可以以高度有效的方式存储数据,并且支持实时流分析。您可以使用满足您要求的Flux 脚本分析数据,并即时提供结果。
将 OPC UA 服务器中的数据移动到 InfluxDB
为了从 OPC UA 服务器收集数据并将其推送到InfluxDB 时间序列数据库,我们使用了 ogamma Visual Logger for OPC。它可以部署在 Windows、Linux 或 Docker 上,具有基于 Web 的配置图形用户界面,性能高,并且不占用太多硬件资源(用 C++ 编写)。
仪表板中信息的可视化
对于这个演示,使用了另一个开源项目 Grafana。或者,您也可以在 InfluxDB 中构建仪表板。
最终结果:仪表板截图。
最终结果:屏幕录制。
技术细节
配置 Prosys OPC UA 模拟服务器
在 Windows 虚拟机上安装了 Prosys OPC UA 模拟服务器的一个实例。在“对象”文件夹下创建了对象和变量
从 OPC UA 客户端的角度来看,地址空间看起来是这样的
变量配置设置截图如下
配置 ogamma Visual Logger for OPC 以安全模式连接到服务器
首先,应在地址空间面板中创建一个新的 OPC UA 服务器节点。注意,安全模式设置为签名并加密。在服务器端配置信任将需要一些额外的步骤。
添加 OPC UA 服务器节点后,初始尝试连接将会失败。在服务器端,ogamma Visual Logger 的 OPC UA 应用程序实例证书将被保存在被拒绝的证书文件夹中。从 Prosys OPC UA 模拟服务器 GUI 中,需要将其标记为受信任。这可以在切换到 专家模式(菜单 选项 / 切换到专家模式)后通过 证书 标签页完成
仅仅信任 ogamma Visual Logger 实例证书是不够的。您还需要
- 下载其 CA 证书(通过菜单设置 / 下载证书 / CA 证书)并将其保存在服务器端的文件夹 C:\Users\Administrator\.prosysopc\prosys-opc-ua-simulation-server\PKI\CA\certs 中,
- 下载 CRL(通过菜单设置 / 下载证书 / CA CRL)并将其保存在服务器端的文件夹 C:\Users\Administrator\.prosysopc\prosys-opc-ua-simulation-server\PKI\CA\crl 中。
注意:证书实际所在的文件夹在不同的安装中可能会有所不同。因此,请使用Prosys OPC UA模拟服务器GUI打开文件夹,通过菜单证书/ 在文件资源管理器中打开。
当证书信任配置正确时,ogamma Visual Logger for OPC应该能够连接到服务器。要验证这一点,请尝试通过在地址空间面板中展开节点来浏览它。
配置ogamma Visual Logger for OPC以记录所需的变量
从地址空间面板选择节点,通过单击日志按钮将它们添加到日志变量表中。如果一切正常,状态列中应显示带勾选标记的图标。
配置ogamma Visual Logger for OPC以连接到InfluxDB实例
首先,在时间序列数据库列表中添加一条新记录(菜单 设置/时间序列数据库)。将字段 类型 的值设置为 InfluxDB 2.0,并修改字段主机、端口、使用安全模式和JSON。在最后一个字段(JSON)中,将“测量”选项设置为“[TN]”,并确保选项 组织、桶、令牌 设置正确。
通过单击 测试连接 按钮验证连接设置是否正确。现在实时数据值将被导入InfluxDB数据库。
以流模式分析变量值并生成通知
对于流分析,使用InfluxDB任务功能。创建此功能通过编写Flux脚本来计算每5秒输入压力和输出压力及其差的平均值。然后根据此差的值生成通知消息。如果差值低于指定的阈值,则消息级别设置为关键,否则设置为警告、信息或正常,具体取决于值。然后通知写入特殊系统桶 _monitoring
,其中 _measurement
设置为statuses。
以下是完整的Flux脚本代码
import "influxdata/influxdb/monitor"
option task = {name: "Check Pump Pressure", every: 5s, offset: 1s}
currentTime = now()
join(tables: {ip: from(bucket: "ogamma")
|> range(start: -task.every)
|> filter(fn: (r) =>
(r._measurement == "InputPressure" and r.unit == "Pump" and r._field == "v"))
|> drop(columns: ["_source_timestamp"])
|> mean(column: "_value")
|> map(fn: (r) =>
({
_time: currentTime,
_value: r._value,
unit: r.unit,
_measurement: "OutputPressure",
})), op: from(bucket: "ogamma")
|> range(start: -task.every)
|> filter(fn: (r) =>
(r._measurement == "OutputPressure" and r.unit == "Pump" and r._field == "v"))
|> drop(columns: ["_source_timestamp"])
|> mean(column: "_value")
|> map(fn: (r) =>
({
_time: currentTime,
_value: r._value,
unit: r.unit,
_measurement: "OutputPressure",
}))}, on: ["_time", "_measurement"])
|> map(fn: (r) =>
({
_time: r._time,
_pd: r._value_op - r._value_ip,
unit: r.unit_op,
_measurement: "OutputPressure",
}))
|> monitor.check(
crit: (r) =>
(r._pd < 10.0),
warn: (r) =>
(r._pd < 15.0),
info: (r) =>
(r._pd < 25.0),
ok: (r) =>
(r._pd >= 25.0),
messageFn: (r) =>
(if r._pd < 10.0 then "Critical alert!! error: Pressure difference is too low: ${string(v: r._pd)}!" else if r._pd < 15.0 then "Warning! Pressure difference is low: ${string(v: r._pd)}!" else if r._pd < 25.0 then "Pressure difference is: ${string(v: r._pd)}!" else "ok"),
data: {
_check_name: "Pressure difference check",
_check_id: "pres_diff",
_type: "threshold",
tags: {unit: "Pump"},
_measurement: "statuses",
},
)
在Grafana中可视化实时和流处理数据
Grafana附带一个功能丰富的InfluxDB数据源插件。该插件包括自定义查询编辑器和支持注释和查询模板。要将InfluxDB添加到Grafana中的数据源
- 通过单击顶部标题中的Grafana图标打开侧菜单
- 在侧菜单下的仪表板链接下,您应该找到一个名为数据源的超链接
- 单击顶部标题中的 + 添加数据源按钮
- 从下拉菜单中选择InfluxDB
- 确保您从查询语言列表中选择Flux
每个面板使用Flux脚本从InfluxDB查询数据。以下是每个面板及其相应的Flux脚本代码的描述。
状态
此面板显示泵的当前状态,基于布尔类型变量Power的值。
from(bucket: "ogamma")
|> range(start: v.timeRangeStart, stop:v.timeRangeStop)
|> filter(fn: (r) =>
r._measurement == "Power" and
r._field == "v"
)
|> last()
>
输入压力
在此面板中,显示输入压力变量的当前值。
from(bucket: "ogamma")
|> range(start: v.timeRangeStart, stop:v.timeRangeStop)
|> filter(fn: (r) =>
r._measurement == "InputPressure" and
r._field == "v"
)
输出压力
在此面板中,显示输出压力变量的当前值。
from(bucket: "ogamma")
|> range(start: v.timeRangeStart, stop:v.timeRangeStop)
|> filter(fn: (r) =>
r._measurement == "OutputPressure" and
r._field == "v"
)
相对压力
在此面板中,显示计算输出和输入压力之间的差的当前值。请注意,对于每个输入和输出压力变量,首先计算平均值,因此差值不等于当前值之间的差。
from(bucket: "_monitoring")
|> range(start: -10s, stop:now())
|> filter(fn: (r) =>
r._measurement == "statuses" and
r.unit == "Pump"
)
|> drop (columns:["_source_timestamp", "_check_id", "_check_name", "_start", "_stop"])
泵:输入和输出压力
在此面板中,显示最新显示间隔内压力变量的历史值。
from(bucket: "ogamma")
|> range(start: v.timeRangeStart, stop:v.timeRangeStop)
|> filter(fn: (r) =>
r._measurement == "InputPressure" and
r._field == "v"
)
泵通知
在本面板中,显示由流值处理生成的通知。
from(bucket: "_monitoring")
|> range(start: v.timeRangeStart, stop:v.timeRangeStop)
|> filter(fn: (r) =>
r._measurement == "statuses" and
r.unit == "Pump"
)
|> drop(columns: ["_source_timestamp"])
温度
在本面板中,显示温度变量的历史值。
from(bucket: "ogamma")
|> range(start: v.timeRangeStart, stop:v.timeRangeStop)
|> filter(fn: (r) =>
r._measurement == "Temperature" and
r._field == "v"
)
最终结果
最后,我们在Grafana中得到了这个运行的仪表板!