
车间里最常听到的一句话是“这台机今天到底开了多久”而最常看到的画面是班组长拿着本子挨台抄状态灯。设备本身明明已经把运行、待机、报警、程序号这些信息挂在面板上了但要把它们自动变成一张稼动率报表往往就卡在“采集”这一步。马扎克MazakSmart、Smooth 系列 CNC 数据采集这几年被问得特别多核心诉求就两个字省钱——能不能不走厂商的付费监控套件、不加装昂贵的网关盒子直接从机床自己的网口里把数据抠出来。这篇文章聊的就是这件事我会把 Smart 和 Smooth 两个平台的内置接口形态、协议边界、端口探测、XML 解析、入库建模以及接口走不通时的硬件兜底方案一次讲透。适合三类人看负责车间数字化的设备工程师、做 MES/IoT 集成的实施人员以及手上管着几台马扎克想先做个小组件试试水的技术负责人。不需要你懂 Mazatrol 编程但需要你会用浏览器打开一个网页、会用 Python 跑一段脚本。1. 整体思路拆解免的到底是什么能免到什么程度1.1 先把“授权”这个词拆开看很多人一提“免授权”就想到破解这个方向从一开始就走偏了而且风险极高——改固件、动许可文件轻则失去厂商保修重则整机参数紊乱。我讲的“免授权”是另一回事不去采购厂商的增值监控软件包比如上位机监控套件、车间级 MES 模块、专用数据网关盒子而是直接使用机床控制器里已经内置的标准化数据服务。这个区别非常关键前者是绕开收费后者是绕开收费的产品层但没有绕开任何协议与安全机制。马扎克的 Smart 和 Smooth 两代控制器出厂时就内置了基于 MTConnect 标准的数据服务端。MTConnect 是一个开放的、基于 HTTP 和 XML 的只读协议由行业联盟维护任何厂商都可以实现任何客户端也都可以读取。它跟付费授权的关系是协议本身免费开放但“启用这个功能”在某些控制器版本上被做成了一个需要激活的选项。所以现场会遇到三种情况直接能通、需要在维护菜单里勾一下才通、以及确实没有这个选项需要走别的路。判断清楚自己落在哪一档比盲目折腾端口重要得多。我一般会把授权边界分成三层来理解。第一层是协议层也就是 MTConnect、OPC UA 这类开放标准本身。这一层永远是免费且公开的你可以自己写客户端也可以用开源库没人会来收钱。第二层是功能启用层即控制器固件里那个“是否允许外部读取”的开关。有些批次的 Smart 和 Smooth 出厂就是开着的有些默认关闭但可以在维护参数里打开还有些在特定销售区域的固件里根本没编进去。这一层是现场最大的不确定性来源也是“免授权”三个字能不能成立的分水岭。第三层是应用层就是厂商卖的那些看板、报表、OEE 分析、刀具寿命管理软件。这一层是纯粹的商业产品你完全可以自己用 Grafana 加时序数据库搭一套功能上未必差成本几乎为零。绝大多数中小车间的需求其实只到“能拿到数据”这一层后面的看板自己拼就行。把这三层想清楚你就不会在“为什么别人说能采我却采不到”这种问题上纠结了——大家说的往往不是同一层。1.2 为什么偏偏盯上 Smart 和 Smooth 这两代马扎克的控制器代际跨度很大早期的 Mazatrol 系统基本只有串口和 DNC 传程序的能力想拿状态数据非常费劲。到了 Matrix 时代开始有了以太网但数据服务还不成体系。真正让数据采集变得“可做”的是 Smart 和 Smooth 这两代。Smart 系列大概是过渡期产品它第一次把网络化数据服务做成了标配能力的一部分。Smooth 系列则是全面铺开的一代SmoothAi、SmoothC、SmoothG、SmoothX 这些型号覆盖了铣削、车削、磨削和小型机它们内部的数据服务成熟度高得多不仅能吐状态还能吐程序名、刀具号、坐标、负载、报警文本。我做过的几个项目里Smooth 系列的probe返回的设备模型动辄上千行可采的点位非常丰富基本能满足一个正经的 OEE 建模需要。这两代机器的另一个好处是网口是标配。以前为了联网还得加一块网卡或者串口服务器现在机床背面直接一个 RJ45插上就能通。这在实施成本上省了一大截也让“先用一台试试水”这种低风险试点成为可能。不过要注意Smart 和 Smooth 之间的差异不小不能拿一套参数表硬套两台机器。我在下面讲协议细节时会特别标注两者的不同之处你在现场一定要以实际读到的模型为准。1.3 四条技术路线的取舍逻辑现场能走的路其实有四条我按推荐优先级排一下。第一条直连内置数据服务。用 HTTP 请求机床的数据端点拿 XML自己解析。优点是不增加任何硬件成本、数据最全、实时性最好缺点是对固件版本和选项开关有依赖不是每台都能通。这是首选能通就别折腾别的。第二条OPC UA。Smooth 系列的部分版本内置了 OPC UA 服务端端口一般是 4840。它的好处是有成熟的客户端库、有浏览节点的能力、结构化程度比 XML 高。缺点是同样受功能开关限制而且 OPC UA 的节点浏览在不熟悉的机型上要花时间摸索。我通常把它作为第一条的备选。第三条硬件信号采集。直接从机床的三色灯、循环启动继电器、报警输出端子取干接点信号或者用霍尔电流互感器卡在主轴上测负载。这条路完全不受控制器软件选项的限制任何年代任何型号的机床都能做。缺点是只能拿到“开/关/报警”这种粗粒度状态拿不到程序号和坐标。如果你的需求只是算稼动率这条路其实够用而且最稳。第四条宏变量与外部程序交互。部分机型支持通过宏变量或者外部 I/O 触发写入数据。这条路门槛最高、可移植性最差除非前三条都走不通否则我不建议碰。实际项目中我经常是第一条为主、第三条兜底同一车间里有 Smooth 也有老机器Smooth 直连老机器挂信号采集模块数据统一进同一个数据库上层看板不区分来源。这种混合架构比追求“全车间统一方案”要现实得多。2. 协议层核心细节数据到底长什么样2.1 内置数据服务的形态与访问路径马扎克 Smart 和 Smooth 内置的这套服务本质上是控制器里的一个轻量 HTTP 服务端它遵循 MTConnect 的 REST 风格约定。你不需要装任何客户端用浏览器就能访问。默认端口通常是 5000但这个不是绝对的不同固件、不同配置下可能被改过所以现场第一件事永远是确认端口。标准的访问路径有三个作用完全不同千万别混。/probe是“探针”它返回的是这台机床的设备模型也就是一份自我描述文档。里面用层级结构列出了这台机器有几个轴、主轴参数是什么、有哪些事件Events、哪些采样量Samples、哪些报警条件Condition。这份文档相当于机床的名片你要什么数据先来这里找它的“字段名”。/current返回的是当前时刻的完整快照。所有设备、所有组件、所有数据项的当前值一次性给你。做实时监控和状态判断用这个最方便。它的数据量比想象中大一台复合机返回几十 KB 是常事所以轮询频率要控制。/sample是历史区间查询可以带from、count、interval这类参数按序列返回一段时间内的数据。理论上它是最优雅的方案但实测下来机床侧的缓冲区通常很小长时间的历史数据拉不到而且参数支持程度因固件而异。我的经验是自己在外围做轮询和存储别指望机床帮你存历史。有一个细节值得单独说/probe返回的模型是带序列号sequence的。MTConnect 用nextSequence、lastSequence这类字段标识数据流的位置。如果你用/sample做增量拉取一定要维护好这个序列号否则会漏数据或者重复。很多人第一次做的时候直接用/current轮询反而避开了这个坑对新手来说更友好。2.2 设备模型里最该盯的几类数据项模型文档很长但真正决定项目成败的其实就几类。我把常用的整理成表注意字段名以实际 probe 返回为准下表是基于常见配置的经验归纳。数据类别典型组件路径常见取值用途说明运行状态设备层 executionACTIVE / READY / STOPPED / INTERRUPTED稼动率计算的核心区分“真在干活”和“开着机待着”程序信息控制器层 program程序名或 O 号区分换活、统计单件工时主轴转速主轴组件的 Sspeed数值单位 rpm判断是否真实切削、辅助时间识别进给速度轴组件的 Xfrt数值单位 mm/min配合主轴转速判断空行程坐标位置轴组件的 Xabs / Zabs数值单位 mm刀具轨迹粗判、防碰撞参考报警条件类型的 alarm报警号 文本故障分类、MTBF 统计刀具号刀库或主轴组件的 toolT 号刀具寿命管理、换刀次数统计负载主轴组件的 load 或电流换算百分比防止过载、工艺优化工件计数部分机型的 counter整数产量核对看这张表你可能已经发现判断“机床在不在干活”从来不能只看 execution。我踩过的坑是这样的机床处于ACTIVE状态主轴在转、进给在动但那是在做空行程或者对刀并不产生价值。后来我改成三个条件同时满足才算有效加工——execution ACTIVE并且Sspeed 阈值并且Xfrt 在合理区间。这个复合判断把稼动率从虚高的 85% 压到了真实的 62%老板一开始不信后来对着产量一核对服了。阈值怎么定别拍脑袋。我的做法是连续采一周数据把主轴转速画成直方图你会发现明显有两个峰一个是零附近的待机峰一个是切削转速区间的主峰。阈值取两峰之间的低谷位置比任何经验值都靠谱。2.3 端口探测与网络打通的实际做法在机房或车间交换机上机床通常配一个固定 IP。如果你不知道 IP有两个办法一是看机床开机时的网络设置界面二是在交换机上查 ARP 表或者用扫描工具扫网段。拿到 IP 之后先做最基本的连通性测试。这里给几个常用命令Linux 或者 Windows 的 WSL 都能跑。# 先确认能通 ping -c 3 192.168.10.51 # 探测常见数据服务端口是否开放 for p in 5000 4840 80 8080; do timeout 2 bash -c echo /dev/tcp/192.168.10.51/$p 2/dev/null \ echo port $p OPEN || echo port $p closed done # 直接拉取设备模型看前 50 行 curl -s --max-time 5 http://192.168.10.51:5000/probe | head -50如果 5000 端口开着curl能返回一大段 XML恭喜你这条路基本通了。如果 5000 关闭但 4840 开着那说明走的是 OPC UA 路线得换个工具验证。如果两个都关先别急着下结论去机床的维护参数页面找一找“网络服务”“外部通信”“MTConnect 有效”之类的开关很多机器的默认值是关闭的。注意修改机床的网络或通信参数属于对设备运行环境的变更务必在停机窗口内进行改之前把原参数拍照或抄录下来。生产机床上任何一次参数误改代价都可能是半天的停机排查。还有一个容易被忽略的点子网掩码和网关。有些车间的机床 IP 配的是老网段跟新部署的采集服务器不在一个网段中间又有路由策略表现就是 ping 得通但 HTTP 拉不到。这种情况我遇到过两次都是网络层的问题而不是机床的问题排查顺序一定要从网络往上走。2.4 那些看起来能采、实际采不到的东西做这类项目最怕的不是采不到而是以为能采到。有几个数据点在 MTConnect 标准里是有的但马扎克某些机型上返回的是空值或者固定值你得提前有心理准备。报警文本是最典型的。报警号一般能拿到但报警的中文描述经常是空字符串因为控制器里的报警字典没有通过这个接口暴露出来。解决办法是自己维护一张报警号到描述的映射表从机床手册或者实际发生时人工记录积累用个 Excel 就能管起来。刀具寿命也是类似情况。标准里有刀具组件但剩余寿命这种业务属性很多机型不在数据服务里吐。能耗数据基本别指望除非机床本身配了电能表并接入了数据服务否则只能外加表计。加工计数在不同机型上差异极大有的直接给有的要你从程序结束信号自己数。我的建议是先跑一段时间的 probe 加 current 落盘把每个字段的实际取值分布统计一遍看哪些是常量、哪些是空值、哪些真的在变。这比看任何文档都快两三天就能摸清一台机器的真实可采能力。3. 实操过程从零到跑通一条数据链3.1 前置勘察三分钟判断一台机器值不值得投入在正式写代码之前我有个固定的勘察清单现场十分钟内能跑完能避免后面大量的无效劳动。第一步确认控制器型号和固件版本。这个信息在机床开机界面的系统信息里拍照记下来。型号决定了它属于 Smart 还是 Smooth版本号决定了它的接口能力边界。第二步确认网口是否已启用、IP 是多少。有些机床有双网口一个接内部总线一个对外别插错了。第三步探测端口。用上面那段 bash 脚本跑一遍记录哪些端口开着。第四步如果 5000 开着拉一次/probe保存成文件回办公室慢慢看。这份文件是后续所有开发的依据。第五步也是最有价值的一步问车间老师傅这台机器的实际使用习惯。比如“这台机经常一开机就是一天中间换活很频繁”“这台只做粗加工主轴负载常年 60% 以上”。这些信息直接决定了你的采集阈值怎么定、状态机怎么设计。纯看数据是看不出来的。勘察结果一般分三类直接可采、需开开关、只能硬件兜底。第一类立刻可以做第二类约个停机窗口改参数第三类先挂着用信号采集模块过渡。3.2 把 XML 变成可用数据的解析写法拿到/current的返回之后第一个问题是怎么解析。XML 结构是 DeviceStream 下面挂着若干 ComponentStream每个 ComponentStream 里有 Events、Samples、Condition 三类节点每个节点用dataItemId或name标识。最省事的写法是用标准库的 ElementTree不用装第三方依赖。下面这段是我常用的最小可用版本跑通了再加日志和异常处理。import time import requests import xml.etree.ElementTree as ET ENDPOINT http://192.168.10.51:5000/current # 想拿的数据项键是业务名值是 MTConnect 的 dataItemId WANTED { execution: execution, program: program, sspeed: sspeed, feedrate: Xfrt, alarm: alarm, } def fetch_once(): r requests.get(ENDPOINT, timeout5) r.raise_for_status() root ET.fromstring(r.text) result {} for cs in root.iter(ComponentStream): for node in cs: for item in node: key item.get(dataItemId) if key in WANTED.values(): result[key] item.text return result if __name__ __main__: while True: try: data fetch_once() print(data) except Exception as e: print(采集异常:, e) time.sleep(2)这段代码有几个地方值得说道。root.iter(ComponentStream)用的是迭代查找不关心层级深度因为不同机型的嵌套层数不一样硬写路径很容易挂。item.get(dataItemId)拿的是协议里的唯一标识比用name稳因为name是可以本地化的。WANTED这个映射表是给业务层用的。千万不要在代码里到处硬编码sspeed这种字符串一定要集中到一处因为不同机型的字段名可能不一样将来换机器只改这张表就行。我在第二个项目上就是因为到处硬编码换机型的时候改了一整天。异常处理必须包在最外层。机床重启、网络抖动、数据服务偶尔卡顿都会让请求失败如果不 catch脚本一晚上就挂了第二天看数据是断的。这种问题在试点阶段特别容易被忽略。3.3 状态机建模从裸数据到可解释的业务状态拿到数据只是第一步真正有价值的是把裸数据翻译成业务语言。我给每台机床定义一个五态模型加工中、待机、报警、停机、离线。判断逻辑大致如下。加工中execution ACTIVE且主轴转速大于阈值。这是唯一产生价值的时段。待机execution READY或者ACTIVE但主轴转速低于阈值持续超过 30 秒。注意后半个条件这是识别“程序在跑但没切削”的关键。报警alarm项存在非空值。报警要单独建一张表记录开始时间、结束时间、报警号这样才能算 MTTR。停机execution STOPPED且无报警。可能是换活、保养、下班没关电。离线超过一定时间比如 5 分钟没收到任何数据。这个状态必须单独定义否则离线时间会被错误地算进停机稼动率就失真了。这里有个我反复强调的原则状态判断要带迟滞不能一有变化就切。比如主轴转速在程序段之间会瞬间掉到零如果立刻判定为待机一天下来会切出成千上万个碎片状态看板上密密麻麻。我的做法是设一个 30 到 60 秒的确认窗口状态持续超过窗口才真正切换。这个窗口值跟加工节拍有关粗加工可以短一点精加工长一点。还有个细节程序号变化往往意味着换活这是一个很有价值的信号。我把程序号变化单独记一条事件配合产量数据能反推出每个程序对应多少件、耗时多少。这比让工人手工记录准确得多。3.4 数据落库与看板的最小可用组合数据量算一下就知道该选什么库。假设一台机床 2 秒采一次一天 43200 条单条 200 字节一天不到 10 MB。十台机床一年也就三十多个 G。这个量级SQLite 完全扛得住TimescaleDB 或者 TDengine 会舒服一些但没必要一上来就上重型方案。我的建议是分两层存原始层用宽表存每次采集的原始字段保留 30 天用于回溯和重新建模聚合层用分钟级和小时级的聚合表长期保留用于看板。这样既不会因为原始数据膨胀拖慢查询也不会因为只存聚合而失去分析弹性。-- 原始层按天分区思路简化成一个表 CREATE TABLE cnc_raw ( ts INTEGER NOT NULL, -- 时间戳秒 machine_id TEXT NOT NULL, state TEXT, -- 业务状态 program TEXT, sspeed REAL, feedrate REAL, alarm_no TEXT ); CREATE INDEX idx_raw_ts ON cnc_raw(machine_id, ts); -- 分钟聚合层 CREATE TABLE cnc_min ( ts_min INTEGER NOT NULL, machine_id TEXT NOT NULL, active_sec INTEGER DEFAULT 0, idle_sec INTEGER DEFAULT 0, alarm_sec INTEGER DEFAULT 0, stop_sec INTEGER DEFAULT 0 );看板这块Grafana 直接接数据库就行状态时序用状态时间线图稼动率用小时柱状图报警 Top10 用条形图。三张图就能让车间主任看懂别一开始堆十几张图没人看。提示采集端的时间戳一定要用机床返回的时间或者采集服务器的时间统一到一个时钟源。我见过因为时钟不同步导致报警时间对不上原始记录排查了两天才发现是某台机器的系统时间差了三小时。3.5 接口走不通时的硬件兜底信号采集的落地细节有些机器确实走不通软件路线比如早期 Smart 或者某些定制固件。这时候硬件方案能救场而且它的稳定性往往比软件方案还好。最基础的方案是取三色灯信号。机床的三色灯模块内部是继电器或光耦输出红黄绿三路接一个 8 路光耦隔离板再进一个带网口的采集模块比如支持 Modbus TCP 的远程 I/O采集服务器按 1 秒轮询读三路状态。成本几百块接线两小时稳定运行几年。稍微进阶一点是加循环启动信号。有些机床的电气柜里有循环启动的辅助触点或者可以并一个中间继电器这样能区分“程序在跑”和“灯亮着”。这个信号比灯准确得多但需要看电气图纸动电柜必须找有资质的人做。再进一层是主轴电流采集。用开合式霍尔电流互感器卡在主轴电机的一相线上输出 4-20mA 或者 0-5V进模拟量采集模块。电流曲线能反映真实的切削负载甚至能做刀具磨损预警。这个方案的特点是精度高、成本中等、不受任何软件限制。硬件方案的坑主要在电气安全和信号抖动。电柜内的接线必须断电操作、必须由持证人员完成信号抖动则靠软件滤波解决比如连续 3 次采样都是高电平才算真的启动避免继电器吸合瞬间的抖动造成误计数。4. 常见问题与排查技巧实录4.1 故障速查表从症状直接定位这张表是我这几年攒下来的按症状查命中率很高。症状表现可能原因排查与处理ping 通但 HTTP 请求超时端口未开放 / 服务未启动先探端口再进维护菜单确认数据服务开关/current返回空 Streams机床处于特殊模式或正在初始化等机床完全启动后再试避开开机阶段返回 XML 但字段值是空的该机型不支持此数据项以/probe为准剔除不支持项采集脚本跑几小时就停未捕获异常导致进程退出加 try/except 进程守护记录失败日志数据间隔忽大忽小网络拥塞或机床内部任务繁忙降低频率到 1~2 秒避开换刀与程序切换瞬间状态频繁跳变无迟滞判断加 30~60 秒确认窗口稼动率明显虚高只用了 execution 判断加主轴转速与进给量的复合条件多台机器时间对不上时钟源不统一统一 NTP 或者以采集服务器时间为准报警号能拿到但无文本报警字典未暴露自建报警号映射表换刀或换程序时数据跳零正常现象在状态机里将换刀时段单独标记不计入待机这张表里最想强调第一条和第七条。第一条是所有新项目的必经之路别慌按顺序排查就行。第七条是业务层面的坑技术上是通的但算出来的数字是错的这种问题最隐蔽往往要等到老板质疑报表才会发现。4.2 采集频率的选择不是越快越好新手普遍有个执念觉得采得越频繁越“实时”。实际上在 CNC 场景里1 秒和 100 毫秒对稼动率计算没有任何区别但系统负载差别是 100 倍。我的经验值是这样状态类数据 1 到 2 秒一次足够因为人的反应时间、班组的关注粒度都是分钟级的。主轴转速和负载这类模拟量2 秒一次也够画趋势图足够顺滑。报警事件必须实时捕获但报警不是靠高频轮询拿的而是靠Condition节点的变化判断或者干脆用/sample的序列号增量拉取这样既不漏事件又不浪费带宽。还有一个现实约束机床的数据服务是跑在控制器上的它跟加工程序共享 CPU 资源。轮询太频繁极端情况下会影响机床的响应速度这在精加工工序上是不能接受的。我一般会在机床侧做限流同时把采集客户端部署在一个独立的边缘盒子上避免采集服务器和机床之间隔着整个厂区网络。4.3 长期运行的经验稳定性比功能重要试点跑通很容易跑三个月不出问题很难。下面几条是我踩坑换来的。第一采集进程必须有守护。用 systemd 或者 supervisor 都行崩溃自动拉起日志按天切分。我遇到过一次机床侧服务在半夜重启采集脚本报错退出第二天发现整晚数据空白而那天正好有夜班在赶货。第二必须有“数据新鲜度”监控。就是给每台机器记录最后一次成功采到数据的时间超过阈值就在看板上标红。这个功能救过我好几次因为很多故障是静默的——脚本还活着但一直在报错重试没有新鲜度监控你根本不知道。第三配置一定要外置。机床 IP、端口、字段映射、阈值全部放在配置文件或者数据库里不要写在代码里。车间里加一台机器改配置就行不用改代码重新部署。第四先小范围跑再全车间铺。我一般先选一台使用最规律、网络条件最好的机器做试点跑两周看数据质量确认稳定了再扩到五台最后才全铺。一次铺二十台然后集体出问题排查起来是灾难。第五把原始数据留一份。不管上层怎么聚合原始采集记录至少留一个月。因为你永远不知道自己什么时候会想换个算法重新算一遍没有原始数据就只能等下次。4.4 几个容易被忽略的实施心得关于**“可免授权”这件事的表述方式**我建议在项目文档里写清楚边界本方案使用机床内置的开放协议接口和外部硬件信号采集不涉及任何固件修改、许可文件改动或逆向工程。这样写既是合规要求也能避免后续被误解。如果现场发现某台机器的接口确实未开放正确做法是走硬件方案或者按正规流程采购相应选件而不是想办法“打开”它。这一点上我不建议有任何侥幸心理工业设备的稳定性和可维护性比省下的那点钱重要得多。关于跨部门协作数据采集项目最容易卡在“没人愿意配合”。设备部门怕影响生产IT 部门怕网络不安全生产部门怕被考核。我的做法是先做一台机器、只对班组长开放、只看稼动率一个指标让他自己发现“原来下午那两小时真的是在等料”。用数据说话比开十次会都管用。关于数据的解释权一定要在项目初期就跟使用方对齐每个状态的定义。什么叫“待机”换活算不算待机计划保养算不算停机这些定义不统一最后做出来的报表每个人都能挑出毛病。我现在的做法是画一张状态流转图让车间主任签字确认后面再有人质疑就拿出来对。最后说一个实际感受这类项目真正的价值不在技术难度而在持续运营。采集跑通了只是起点能不能坚持每天看数据、每周复盘、每月优化口径才是决定它有没有用的关键。我见过太多项目第一周轰轰烈烈第三个月就没人登录了。技术上再优雅没人用就是零。所以如果你正准备动手先想清楚一件事——数据采上来之后第一个会看它的人是谁他想解决什么问题。这个问题答不上来后面所有的端口探测和 XML 解析都是白费功夫。