
1. 项目概述当工业设备遇上“乐高式”图形化最近在折腾一个工业数据可视化的项目客户现场有几十台不同型号的PLC、传感器和机械臂数据源五花八门协议也各不相同。传统的组态软件要么太“重”部署麻烦要么太“死”定制化开发周期长得让人头疼。就在这个当口我接触到了reComputer R1000和FIN这套组合尝试用它来快速创建设备图形界面结果有点出乎意料——它把这件事变得像搭乐高积木一样直观。简单来说reComputer R1000是一台基于NVIDIA Jetson平台的边缘AI计算机性能强劲且接口丰富天生就是为工厂车间这种环境设计的耐高温、抗震动可以直接挂在产线旁边。而FIN则是一个开源的、基于Web的工业物联网IIoT平台和可视化工具。它的核心组件之一Graphics Builder允许你通过拖拽的方式为物理设备创建动态的、数据驱动的图形化界面。这个项目的核心价值在于它解决了工业现场两个最实际的痛点一是快速交付面对客户“明天就要看效果”的需求用FIN的图形化编辑器从零搭建一个包含实时数据、历史曲线和报警面板的设备总览图可能只需要几个小时而不是几天或几周。二是降低门槛让熟悉设备工艺但不一定精通JavaScript或复杂图形库的工程师也能参与到人机界面HMI的开发中来实现“所见即所得”的配置。如果你是一名工业自动化工程师、系统集成商或者正在寻找一种轻量、灵活且强大的方式来可视化你的物联网设备数据那么这套基于reComputer R1000和FIN的方案绝对值得你花时间深入了解。接下来我将从设计思路到实操细节完整拆解这个过程。2. 整体方案设计与核心组件解析在决定采用 reComputer R1000 和 FIN 之前我们评估过几种常见的方案。比如传统的桌面组态软件如WinCC、iFix等它们功能强大但授权费用高且客户端沉重也考虑过用纯Web技术栈如Vue.js ECharts Node.js自研虽然灵活但开发周期长需要前端、后端、运维多方协作对小型项目或快速原型不友好。2.1 为什么是 reComputer R1000 FIN最终选择这个组合是基于以下几个关键考量边缘计算与显示的融合reComputer R1000 不仅是一个数据采集和计算节点它本身就是一个完整的计算机可以直接连接显示器作为HMI终端。这意味着我们无需额外的工控机或服务器实现了“采集-计算-显示”一体化部署简化了硬件架构降低了成本和故障点。FIN 的开源与开放性FIN 是开源的这避免了昂贵的软件许可费用。更重要的是其架构是模块化和微服务化的我们可以按需部署所需的服务如数据采集、流处理、可视化而不用启动一个庞大的单体应用。它的数据模型和API设计也足够开放能轻松接入各种协议如 OPC UA, MQTT, Modbus的数据。Graphics Builder 的革命性体验这是打动我的最关键因素。它不是一个简单的图表配置工具而是一个功能完整的矢量图形编辑器。你可以绘制或导入SVG图形然后将图形中的元素如一个矩形、一条管道、一个文本标签与后台的实时数据点进行“绑定”。数据变化时图形的颜色、大小、位置、可见性等属性会随之动态变化。这几乎是把Adobe Illustrator和实时数据库连接在了一起创意和实现之间没有了隔阂。2.2 核心组件分工与数据流理解整个系统如何协同工作至关重要。下图清晰地展示了从物理设备到最终屏幕显示的数据流转路径和各个核心组件的职责flowchart TD A[物理设备brPLC/传感器/CNC等] --|Modbus/OPC UA/MQTT等协议| B[边缘网关brreComputer R1000] B -- C[数据采集与处理brFIN Core 服务] C -- D[实时数据存储brFIN 时序数据库] D -- E{数据消费端} E -- F[图形化界面brFIN Graphics Builder] E -- G[报警与事件管理] E -- H[历史数据分析] F -- I[可视化渲染brWeb浏览器/本地显示] subgraph R1000 [reComputer R1000 边缘节点] B C D F end数据流解读数据上行物理设备通过工业协议将数据发送至 reComputer R1000 上运行的 FIN 数据采集服务如fin-ua处理 OPC UAfin-modbus处理 Modbus。数据处理与存储采集到的数据经过简单的清洗、转换在 FIN 流处理模块中可配置后被写入 FIN 内置的高性能时序数据库。数据消费与展示Graphics Builder 创建的图形界面通过 WebSocket 或 REST API 从时序数据库中订阅实时数据。当数据更新时图形界面无需刷新页面即可动态更新。最终呈现用户可以通过车间内的任意一台电脑或平板电脑的浏览器访问 R1000 的 IP 地址来查看界面也可以直接将 R1000 连接到大屏幕或触摸屏作为固定监控终端。这个架构的优势在于低延迟和高可用性。所有数据处理和展示都在边缘侧完成不依赖于云端网络即使外网中断车间内的监控和操作也不受影响。同时FIN 的微服务架构保证了单个服务的故障不会导致整个系统崩溃。3. 环境搭建与基础配置实操理论讲完了我们动手把环境跑起来。假设你手上已经有一台 reComputer R1000我用的型号是 J4012搭载 Jetson Orin Nano并且已经按照官方指南刷好了 JetPack 系统Ubuntu 20.04/22.04 LTS。3.1 在 reComputer R1000 上部署 FIN 套件FIN 官方推荐使用 Docker 进行部署这对于资源有限的边缘设备来说是非常好的方式能保证环境隔离和依赖管理。以下是在 R1000 上的步骤安装 Docker 和 Docker Compose# 更新软件包列表 sudo apt-get update # 安装 Docker 必要依赖 sudo apt-get install -y ca-certificates curl software-properties-common # 添加 Docker 官方 GPG 密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 设置稳定版仓库 echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 安装 Docker Engine sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io # 安装 Docker Compose Plugin (v2) sudo apt-get install -y docker-compose-plugin # 将当前用户加入 docker 组避免每次用 sudo sudo usermod -aG docker $USER # 提示需要重新登录或重启使组生效 newgrp docker获取 FIN 的 Docker Compose 配置文件 FIN 的核心服务都定义在一个docker-compose.yml文件中。我们创建一个工作目录并下载它。mkdir ~/fin-stack cd ~/fin-stack # 从 FIN 的 GitHub 仓库获取最新的 compose 文件示例 wget https://raw.githubusercontent.com/final-iot/fin/main/docker-compose.yml # 查看一下内容里面定义了 fin-core, fin-db, fin-ui 等多个服务 cat docker-compose.yml | head -30启动 FIN 服务 这是最简单的一步一条命令启动所有服务。docker compose up -d使用docker compose ps查看所有服务状态当所有容器都显示为running时说明启动成功。首次启动会从 Docker Hub 拉取镜像可能需要几分钟取决于网络速度。访问 FIN 管理界面 在 reComputer R1000 本机的浏览器中打开http://localhost:8080如果从同一网络的其他电脑访问则使用http://R1000的IP地址:8080。你应该能看到 FIN 的登录界面。默认用户名是admin密码是admin。首次登录后请务必立即修改密码实操心得一资源优化reComputer R1000 的 Jetson Orin Nano 虽然性能不错但内存通常8GB或16GB相对有限。在docker-compose.yml中可以为关键服务如fin-db时序数据库配置内存限制避免某个服务异常占用所有资源导致系统卡死。例如在fin-db服务下添加deploy: resources: limits: memory: 2G根据你的设备总内存和容器数量合理分配。3.2 配置第一个数据源以模拟数据为例在开始画图之前我们需要先有数据。FIN 支持多种数据接入方式。为了快速演示我们先创建一个模拟数据源。登录 FIN UI进入主界面。创建“节点”在左侧导航栏找到“节点浏览器”或类似菜单。节点是 FIN 中数据的基本组织单位可以理解为文件夹或标签。右键点击根节点创建一名为DemoPlant的新节点。创建历史数据点在DemoPlant节点下右键创建新的“历史点”。我们创建一个名为Tank1_Level的点用来模拟一个水箱的液位。在配置中设置其工程单位EU为%量程EGU为0到100。最关键的一步在“数据源”选项卡中选择“仿真”数据源并设置一个变化规则比如正弦波幅度50周期60秒。这样这个点就会自动生成模拟的液位数据。验证数据创建完成后你可以在“点详情”页面看到该点的实时值在动态变化。也可以在“趋势”功能中拖入这个点看到它生成的正弦波形曲线。至此我们的数据基础就准备好了。接下来进入最核心的部分——用 Graphics Builder 为这个“虚拟水箱”创建一个图形界面。4. Graphics Builder 核心功能与设备图形创建Graphics Builder 是 FIN 的图形化编辑界面通常可以通过http://R1000_IP:8080/graphics/builder直接访问。它的界面类似于简化版的 Figma 或 Inkscape但核心功能是数据绑定。4.1 界面初识与基本图形绘制打开 Graphics Builder你会看到一个画布和左侧的工具面板。工具面板主要包含选择工具选择和移动对象。基本形状矩形、圆形、多边形、线条等。文本工具添加静态或动态文本。图表组件趋势图、仪表盘、按钮等更复杂的控件。图层与对象树管理画布上所有元素的层级关系。让我们为Tank1_Level创建一个简单的水箱图形绘制水箱外壳使用矩形工具画一个细长的矩形作为水箱主体。在右侧的“属性”面板中可以设置其填充颜色如浅蓝色、边框粗细和颜色。绘制动态液位再画一个矩形放在水箱主体内部底部对齐。这个矩形将代表实际的液位。我们暂时将其填充为深蓝色。绘制标尺和文本使用线条工具在水箱旁边画几条刻度线。使用文本工具添加一个“%”符号和“液位”标签。现在你有了一个静态的水箱示意图。关键的一步来了如何让里面的深蓝色矩形随着Tank1_Level的数据点实时变化其高度4.2 数据绑定让图形“活”起来这是 Graphics Builder 的灵魂功能。我们选中代表液位的那个深蓝色矩形在右侧属性面板中找到“高度”属性。通常属性输入框旁边会有一个小图标如数据库或链接符号点击它。打开数据绑定对话框点击后会弹出一个窗口让你选择要绑定的数据点。通过节点浏览器找到我们之前创建的DemoPlant/Tank1_Level点。配置绑定规则绑定不仅仅是简单的“值等于高度”。我们需要一个转换规则。液位点的值是 0-100 的百分比而矩形的高度是像素值。因此需要设置一个线性映射。输入范围源数据点的值范围这里输入0和100。输出范围目标属性矩形高度的范围。假设我们希望液位从0%到100%对应矩形高度从0像素到200像素这里就输入0和200。绑定模式选择“值”表示矩形的“高度”属性直接由数据点的值经过上述映射后驱动。应用并预览点击确定。回到画布你可能立即就看到那个矩形的高度发生了变化因为它已经订阅了Tank1_Level的实时值。你可以打开另一个浏览器标签页去修改仿真数据点的参数比如把幅度调大然后切回 Graphics Builder 页面会发现液位矩形的高度在动态变化无需刷新页面实操心得二绑定与表达式数据绑定不仅支持简单的线性映射还支持使用JavaScript 表达式。例如你可以绑定矩形的“填充颜色”属性。规则可以写成value 80 ? #ff0000 : (value 50 ? #ffff00 : #00ff00)。这样当液位超过80%时显示红色报警50%-80%显示黄色预警低于50%显示绿色正常。这种灵活性使得创建复杂的、状态驱动的界面变得非常简单。4.3 创建交互式控件一个完整的设备图形不仅用于显示还应能进行控制。我们为水箱添加一个简单的“泵”开关并模拟其状态。创建控制数据点在 FIN 中为DemoPlant节点下再创建一个点名为Pump1_RunCmd数据类型可以是布尔型Boolean表示泵的启动/停止命令。绘制泵的图形在 Graphics Builder 中可以用两个圆形和一个三角形组合画一个简单的泵图标。将泵的“填充颜色”属性绑定到另一个新的数据点Pump1_Status布尔型仿真其运行状态。绑定规则value true ? #00ff00 : #cccccc运行是绿色停止是灰色。添加按钮控件从组件库拖一个“按钮”到画布上放在泵旁边。双击按钮编辑文本如“启动/停止”。为按钮添加点击动作选中按钮在属性面板找到“事件”或“动作”选项卡。添加一个“点击”事件。在动作配置中选择“写数据点”。目标点选择我们创建的Pump1_RunCmd。写入值这里我们可以玩点花样。不直接写true或false而是写一个翻转逻辑。由于 FIN 的表达式支持我们可以写入!{Pump1_RunCmd}。这个表达式的意思是向Pump1_RunCmd写入它当前值的非值即取反。这样每次点击按钮命令就会在true和false之间切换实现一个乒乓开关。模拟状态反馈为了让Pump1_Status能响应Pump1_RunCmd我们需要一点简单的逻辑。这可以在 FIN 的“流处理”模块中完成创建一个简单的流监听Pump1_RunCmd的变化然后延迟1秒模拟泵的启动时间后将同样的值写入Pump1_Status。这样点击按钮后泵的图标颜色会稍后改变模拟真实设备的响应。现在你就拥有了一个带实时数据展示和简单控制功能的设备图形。液位动态变化点击按钮可以“控制”泵的启停并且泵的图标状态会随之改变。5. 高级技巧与复杂图形构建掌握了基础操作后我们可以构建更贴近真实工业场景的复杂图形。5.1 使用SVG导入与分层设计对于复杂的设备如一台数控机床或一个反应釜用基本形状手绘效率太低。Graphics Builder 支持导入SVG可缩放矢量图形文件。准备SVG使用专业的矢量绘图软件如 Inkscape、Adobe Illustrator绘制设备示意图或者从设备厂商提供的资料中获取。确保图形是分层的、逻辑清晰的例如外壳、内部组件、管道、仪表盘分别在不同图层。导入与解组在 Graphics Builder 中通过“文件”-“导入”SVG。导入后整个SVG通常是一个组合。右键点击它选择“解组”或“进入组”你就可以访问到其中各个独立的路径和形状了。分层绑定将解组后的各个部分分别绑定到对应的数据点。例如将电机的外壳绑定到设备温度颜色映射将旋转的叶片绑定到电机转速旋转角度绑定将压力表指针绑定到压力值旋转角度绑定并设置不同的输入输出范围。注意事项SVG 文件优化直接从设计软件导出的 SVG 可能包含大量元数据、无关图层和复杂的路径这会导致 Graphics Builder 渲染变慢尤其是在资源有限的 R1000 上。导入前建议使用工具如 SVGOMG进行优化删除无用信息简化路径。同时在 Graphics Builder 中将不常变化的静态背景层“锁定”或合并可以减少运行时需要处理的动态元素数量显著提升性能。5.2 创建可复用的图形模板与符号库在同一个项目中往往有多个同类型的设备如多个相同的水泵。为每个设备重复绘制和绑定是低效的。Graphics Builder 支持创建符号。创建符号绘制并绑定好一个完整的水泵图形后全选所有相关图形元素右键选择“创建符号”或“制作组件”。定义属性在创建符号时可以定义其“属性”。例如为水泵符号定义一个属性叫MotorSpeedTag类型是“数据点引用”。使用与配置符号将创建好的符号从库中拖到画布上。选中这个符号实例在属性面板中你会看到之前定义的MotorSpeedTag属性。在这里你可以为这个特定的水泵实例指定具体的数据点比如PlantA/Pump1_Speed。批量更新如果需要修改所有水泵的图形样式比如把颜色主题从蓝色改成绿色只需要修改符号库中的原始符号所有使用了该符号的实例都会自动更新但每个实例绑定的具体数据点保持不变。这个功能极大地提升了大型项目界面的开发效率和维护性。5.3 集成趋势图与报警面板设备图形旁边通常需要辅以趋势图和报警列表以提供更全面的信息。内嵌趋势图组件Graphics Builder 提供了趋势图组件。将其拖到画布上调整大小。在组件属性中添加需要显示的趋势笔。例如将Tank1_Level和Tank1_InletFlow假设有都添加进去并设置各自的颜色和线型。这个趋势图组件会自动从 FIN 的历史数据库中查询和绘制数据。创建报警摘要报警信息通常由 FIN 的报警服务管理。我们可以创建一个动态表格或列表组件将其数据源绑定到 FIN 的报警查询 API通过 REST 数据源绑定方式过滤显示当前活动报警或特定优先级以上的报警。当有新报警产生或确认时列表会自动更新。布局与导航对于拥有多台设备或多个工艺段的大型界面可以使用“页面”或“视图”功能。创建多个图形页面然后使用按钮或菜单栏组件为按钮设置“导航到页面”的动作实现类似网页的跳转效果让整个 HMI 系统结构清晰。6. 部署、优化与常见问题排查图形创建完成后我们需要将其部署为可独立访问的运行时界面并确保其在 reComputer R1000 上稳定、高效地运行。6.1 发布与独立访问在 Graphics Builder 中完成的图形默认是在编辑模式下。我们需要将其“发布”。发布图形在 Graphics Builder 中点击“发布”或“导出”按钮。这会将图形及其所有绑定配置打包成一个独立的运行时文件通常是一个 JSON 描述文件。创建视图在 FIN 的主 UI 管理界面找到“视图”或“仪表板”管理。创建一个新视图并选择刚才发布的图形文件作为其内容。生成访问链接保存视图后FIN 会为其生成一个唯一的 URL例如http://R1000_IP:8080/view/abc123。你可以将这个链接发送给操作人员他们无需登录 FIN 管理后台直接在浏览器中打开这个链接就能看到纯净的设备监控界面没有编辑工具栏等多余元素。全屏与Kiosk模式为了达到最佳监控效果可以在显示终端连接 R1000 的屏幕的浏览器中将此 URL 添加到书签并设置为启动页。同时可以使用浏览器自带的“全屏”模式F11或者使用专门的 Kiosk 模式浏览器应用实现开机自启动、全屏显示且禁止用户退出的工业终端效果。6.2 在 reComputer R1000 上的性能优化边缘设备的资源需要精打细算。以下是一些针对 R1000 的优化建议图形复杂度控制减少动态元素只将必须随数据变化的元素进行数据绑定。静态背景、边框等大量元素应合并或栅格化为背景图。简化 SVG 路径如前所述优化导入的 SVG 文件。慎用高频率动画避免使用基于时间的、与数据无关的连续动画如闪烁这会持续消耗 GPU 资源。FIN 服务配置优化调整数据采样与存储间隔不是所有数据点都需要毫秒级记录。对于变化缓慢的工艺参数如温度、液位可以适当降低历史数据的存储频率如每5秒存一次大幅减轻fin-db的负担。限制并发连接数在 FIN 的网关或前端服务配置中可以设置最大 WebSocket 连接数防止意外的大量客户端连接拖垮服务。系统层面优化启用 ZRAM在内存有限的 Jetson 设备上启用 ZRAM内存压缩交换可以有效防止在内存压力大时系统直接卡死。可以通过安装zram-config包并启用。关闭不必要的系统服务如果 R1000 专用于运行 FIN HMI可以关闭图形桌面使用纯命令行模式并通过 Docker 运行 FIN。或者关闭不需要的 snapd、蓝牙等服务。6.3 常见问题与排查实录在实际部署中我遇到过一些典型问题这里分享排查思路问题一Graphics Builder 中图形更新延迟高或卡顿。排查首先打开浏览器的开发者工具F12切换到“网络”标签页查看 WebSocket 连接是否稳定数据推送频率是否正常。在“性能”标签页录制一段时间查看是 JavaScript 执行耗时过长还是渲染Painting耗时过长。解决如果是数据推送慢检查 FIN Core 服务和数据库容器的 CPU/内存使用率docker stats可能是后端处理瓶颈。如果是渲染慢一定是前端图形太复杂。回到“5.2”章节的优化建议简化图形。特别是检查是否有隐藏的、未绑定但非常复杂的 SVG 路径。尝试将浏览器硬件加速设置为“使用硬件加速如果可用”。问题二在远程电脑浏览器访问界面图片或字体加载失败。排查这通常是跨域资源共享CORS问题。FIN 的某些服务如提供静态资源的服务可能没有正确配置 CORS 头。解决修改 FIN 前端服务如fin-ui的 Docker 配置在环境变量或默认配置中添加 CORS 允许的源。或者更简单的方法是通过一个反向代理如 Nginx来统一代理所有 FIN 服务并在 Nginx 层面统一配置 CORS 头。问题三数据点绑定失效图形显示“NaN”或不变。排查在 Graphics Builder 编辑器中选中出问题的图形元素检查其数据绑定配置确认数据点路径是否正确。在 FIN 的点浏览器中确认该数据点是否有实时数据流入值是否在变化。检查绑定规则中的输入输出范围设置是否正确特别是当数据点值为字符串或布尔值时线性映射可能不适用。解决重新选择数据点进行绑定。对于非数值型数据使用“表达式”绑定模式直接返回处理后的值例如value ? 运行 : 停止。确保数据点的“启用历史记录”选项被勾选否则可能无法通过历史/实时接口读取。问题四Docker 容器频繁重启或退出。排查使用docker logs 容器名查看容器退出前的日志通常会有错误信息。常见原因与解决内存不足OOM Killer这是 R1000 上最常见的原因。通过docker stats监控容器内存使用并按照“6.2”章节为容器设置内存限制。存储空间不足时序数据库会持续写入数据。使用df -h检查磁盘空间定期清理旧数据或配置数据保留策略。端口冲突确保docker-compose.yml中映射的宿主机端口如8080, 4840等没有被其他程序占用。这套基于 reComputer R1000 和 FIN 的设备图形创建方案从我的实际项目经验来看它最大的优势在于极大地缩短了从数据到价值的路径。以往需要前后端开发紧密配合才能完成的复杂HMI现在工艺工程师自己就能主导完成大部分可视化工作。而 R1000 提供的稳定边缘算力确保了这套系统在严苛工业环境下的可靠运行。当然它并非万能对于需要极其复杂动画或游戏级渲染的场景仍需要定制开发。但对于90%以上的工业监控与数据可视化需求它无疑是一个高效、优雅且成本可控的解决方案。