☰
凯恩帝KND数控机床REST API实战:状态读取与数据采集接口详解
2026/10/15 4:36:33 网站建设 项目流程

简介:北京凯恩帝KND系列CNC系统REST API参考文档,面向数控系统集成商、第三方开发者及设备维护人员,用于对CNC设备进行远程状态读取、坐标管理、PLC数据采集与程序执行监控,可无缝融入工厂自动化与生产数据采集场景。资源为单个PDF文档,压缩包仅485KB,内容按接口模块化编排,涵盖系统信息、系统配置、轴配置、软限位、参考点、主轴进给控制及错误处理等细节,并给出v1.3与v1.2版本基地址及JSON请求示例,便于快速上手。已有198人学习下载,适合具备基础HTTP与JSON知识、希望调用KND开放接口的开发者阅读;建议结合实际机床操作手册,优先从系统状态与配置接口入手,再逐步深入到坐标与PLC相关功能。

1. 别再把数控机床当黑匣子:凯恩帝 CNC REST API 能直接读出系统状态

做过车间数据采集的人都有体会:最难的往往不是 MES 逻辑怎么写,而是设备数据根本拿不到。老一点的车床只有串口,新一点的又是各家私有协议,想读个坐标都要跟现场 PLC 工程师磨半天。而凯恩帝(KND)部分 CNC 系统上直接内置了一个 REST API 服务器,跑在标准 80 端口上,用 HTTP 就能读到系统状态、坐标、倍率、宏变量甚至 PLC 寄存器。这对系统集成商、第三方开发者和维护人员来说,相当于厂家给了一扇正门,不用再靠旁路硬件去猜数据。本文要拆的这份《KND REST API 参考文档》覆盖 v1.3 与 v1.2 两个版本,接口范围从基础配置、运行状态、坐标管理一路延伸到 PLC 虚拟机和加工程序访问,适合把这套接口当作车间数据底座的人仔细读一遍。

2. 接口地基:版本、基地址、Content-Type 和错误对象,先把这四个约定吃透

2.1 版本选择:v1.3 优先,v1.2 仅作兼容

文档里写得很明确:当前最新版本是 v1.3,建议直接用 v1.3,请求基地址是/api/v1.3;同时兼容 v1.2,基地址为/api/v1.2。除了程序列表这个接口在 v1.2 里只返回程序号、v1.3 里才会附带程序名之外,绝大多数接口在两个版本下行为一致。我通常的做法是:统一按 v1.3 开发,代码里把 base 路径做成可配置项,这样现场如果遇到只能用 v1.2 的老系统,改一个变量就能切过去,不用动业务逻辑。

这里有一个容易被忽略的细节:基地址是从/api/v1.3开始的,后面的接口路径才是/status、/coors这种相对路径。假设 CNC 的 IP 是 192.168.1.101,那么完整的状态接口地址就是http://192.168.1.101/api/v1.3/status。第一次调试时很多人习惯性写成http://192.168.1.101/status,结果 404,这不是接口不存在,而是把版本前缀漏掉了。

2.2 请求约束:只收 application/json,编码必须是 UTF-8

所有接口只接收Content-Type: application/json的 HTTP 数据,除了部分文件相关接口外,大部分接口返回的也是 JSON。数据编码统一 UTF-8。这意味着你用 curl、Postman 或者 Python requests 都能直接调,但要注意两点:第一,不要用application/x-www-form-urlencoded去 POST;第二,如果是从 Windows 的 cmd 里手敲 curl,中文注释或者特殊字符很容易被系统默认编码搞乱,建议脚本文件统一存成 UTF-8 无 BOM。

另一个隐含约束是:除特殊说明外,HTTP 方法默认是 GET。但也有一批接口支持 PUT(设置)和 DELETE(清零),比如坐标清零、宏变量写入、刀补设置、工件坐标系写入、加工计数清零。设计程序轮询时,一定要区分“读接口”和“写接口”,不要把写操作放进高频读循环里,后面会具体讲哪些接口有写入副作用。

2.3 错误对象:HTTP 200 也可能带着 error,别只盯状态码

错误处理这块值得单独拎出来说。文档给出的错误返回格式如下:

{ "error": -1, "error-message": "未知错误" }

error是错误码,error-message是错误描述。关键点在于:返回错误时 HTTP 状态码一般是 400、500,但也可能是 200。也就是说,不能只看 HTTP 状态码判断请求是否成功,必须解析响应体里有没有error字段。我在做数据采集框架时,统一封装了一个响应校验函数,先检查状态码,再检查 JSON 里是否含error键,两者都通过才算成功。

还需要注意:当操作成功且没有数据需要返回时,服务端只返回 2xx 状态码,不返回任何数据体。所以 DELETE 清零坐标、PUT 设置目标件数这类操作,成功后的响应体可能是空的,解析的时候要容忍空响应。

3. 系统状态与配置:从机器配置到实时状态,这一组接口就是“体检报告”

3.1 /config/basic:先看机床基础配置再谈采集

采集程序真正跑起来之前,我建议先调一次/config/basic,把机床的基础参数捞一遍。这个接口返回插补周期、PLC 周期、直线轴个数、旋转轴个数、主轴个数、通道个数、本地数字输入输出点数、模拟轴输出接口个数、手轮接口个数,以及远程 IO 模块的分布情况。

curl -s http://192.168.1.101/api/v1.3/config/basic | python3 -m json.tool

返回里的interpolation-period单位是微秒,典型值是 2000,也就是 2ms 的插补周期;plc-period单位也是微秒,常见 16000。这两个值决定了你能以多快的频率去读动态数据——插补周期 2ms 意味着坐标值本身是 2ms 量级在刷新,但 REST API 走 HTTP 协议,实际轮询做到 100ms 级别已经算高频了,再快意义不大,反而可能占用系统资源。

io-modules是一个数组,每个元素含di-count和do-count,对应远程 IO 模块的点数。如果你的设备上有扩展 IO 模块,这个字段能帮你确定 PLC 地址映射范围,后续读 X/Y 区时心里有数。

3.2 /status:运行状态、工作模式与未就绪原因掩码

/status是监控页面最核心的接口,返回运行状态、当前工作模式、是否准备就绪、未就绪原因、报警类型列表,以及机床锁、辅助锁、空运行、单段、跳段、选择停这些开关状态。

curl -s http://192.168.1.101/api/v1.3/status | python3 -m json.tool

run-status有三个取值:0 停止、1 暂停(进给保持)、2 运行。opr-mode是工作模式,枚举值很细:0 录入、1 自动、3 编辑、4 单步、5 手动、6 手动编辑(示教)、7 手轮编辑(示教)、8 手轮、9 机械回零、10 程序回零。做设备状态大屏时,我一般把这两个字段组合成业务状态:自动模式下 run-status 为 2 就是“自动运行中”;手动模式下 run-status 为 0 就是“手动待机”;回零模式单独显示“正在回零”。

ready是布尔值,表示机床是否准备就绪。如果为 false,not-ready-reason是掩码值:0x1 急停信号有效、0x2 伺服准备未绪、0x4 IO 准备未绪(远程 IO 设备等)。注意这是按位或的组合,判断时要用位运算,不能直接做等值比较。

reason = status_json.get("not-ready-reason", 0) if reason & 0x1: print("急停信号有效") if reason & 0x2: print("伺服准备未绪") if reason & 0x4: print("IO准备未绪")

alarms字段是当前报警类型的列表,比如["ps", "prm-switch"]。注意它只给类型名称,具体报警文本要去/alarms/接口查。还有machine-lock、dry-run、single-block这些辅助开关状态,做远程监控时也建议一并展示,因为机床锁和空运行状态下,坐标在动但实际并没有切削,直接统计运行时长会误导生产报表。

3.3 /alarms:报警类型与单类型查询

/alarms/返回系统中所有当前报警,属性名是报警类型,属性值是文本描述。文档里列出的类型相当全:prm-switch(参数开关报警)、reboot(开关机报警)、plc(PLC 报警或提示)、ps(PS 报警,操作错)、over-travel(超程)、over-heat(过热)、mem(存储器)、servo(伺服驱动)、servo-bus(伺服总线)、over-workarea(超出工作区)、io-bus、io-module、manufacture(机床厂报警)、forbid-move(不允许移动的轴发生移动)。

curl -s http://192.168.1.101/api/v1.3/alarms/ps

每种报警类型也可以单独访问,比如/alarms/ps。如果当前没有该类型报警,返回空对象{}。这里有个实用技巧:我只关注ps、servo、over-travel、plc这四类就能覆盖车间九成以上的停机原因,轮询时可以只轮这四个子接口,减少数据量。

3.4 /config/axes 与 /config/spindles:轴和主轴的“身份证”

轴配置接口/config/axes/<axisNameOrNo>既可以按轴号也可以按轴名访问,比如/config/axes/X和/config/axes/1都行。返回字段里有type(linear/rotary)、soft-limit软限位数组、ref-pos参考点数组、screw-pitch螺距、gear-ratio齿轮比、closed-loop-type(半闭环/全闭环)、backlash间隙补偿值,以及伺服、电机、编码器的配置参数。

文档里特别提醒:轴配置信息客户端应至少读两次,以确保数据完整有效。原因是伺服、电机、编码器这些字段在总线驱动器未连接时可能为 null,而且配置数据存在更新窗口,单次读取可能拿到半新半旧的数据。我做设备台账初始化时,会让程序连续拉两次/config/axes,对比一致后再入库,不一致就重试。

主轴配置/config/spindles/<spindleNameOrNo>的返回结构里,axis字段如果为 null 表示模拟主轴,否则返回对应数字轴的完整配置。批量接口/config/axes/和/config/spindles/返回所有轴和主轴的配置数组,适合做一次性全量采集。

3.5 PLC 虚拟机(/plc/vm):远程读 PLC 寄存器的关键路径

如果要采集 PLC 侧的传感器信号、气缸到位、夹具状态这类数据,就要用到/plc/vm/这一组接口。先调/plc/vm/获取运行环境信息,返回 PLC 版本号和各区域大小:

{ "version": "4.1", "region-size": { "X": 1000, "Y": 1000, "F": 20000, "G": 20000, "R": 20000, "S": 20, "K": 256, "D": 20000, "TL": 2000, "T": 1000, "C": 1000 } }

X/Y/F/G/R/S/K/D/TL 区的读取方式是/plc/vm/<region><offset>?type=<type>&count=<count>。offset可以是字节偏移,也可以是字节内位偏移(如10.0),指定位时只支持访问 1 位且不能指定其他查询参数。type默认为u8,可选s8/u16/s16/u32/s32;count不指定时默认 1,最大 128。注意TL区只支持u8类型,且type与offset必须有对齐关系——u32类型要求 offset 按 4 字节对齐,u16要求 2 字节对齐,否则请求直接报错。

curl -s "http://192.168.1.101/api/v1.3/plc/vm/X0?type=u16&count=3"

这条命令读的是 X0、X1 组成一个 u16,X2、X3 组成一个 u16,X4、X5 组成一个 u16,返回[1, 2, 4]这样的列表。如果count不写,返回单个对象{"val": 100};如果写了 count,即使值为 1,也返回列表,这是为了避免代码里对“返回的是对象还是数组”做特殊判断。

T/C 区(定时器/计数器)的读取格式稍有不同,/plc/vm/T0返回的是{"conf": 1000, "cur": 100},conf是设置值,cur是当前值。带count参数时返回对象列表,最大支持 128 个。

4. 坐标管理与数据操作:读坐标、清坐标、写工件坐标系、宏变量和刀补

4.1 /coors:四类坐标读取与清零的两个红灯

坐标是这个 API 里最常用的数据。/coors/一次性返回四组坐标:absolute绝对坐标、machine机床坐标、relative相对坐标、dist-to-go余移动量。

import requests resp = requests.get("http://192.168.1.101/api/v1.3/coors/", timeout=3) coors = resp.json() print("绝对坐标:", coors["absolute"]) print("机床坐标:", coors["machine"]) print("相对坐标:", coors["relative"]) print("余移动量:", coors["dist-to-go"])

四组坐标也可以单独访问:/coors/absolute、/coors/machine、/coors/relative、/coors/dist-to-go,返回格式是{"X": 10.0, "Z": 10.0, "Y": 20.0},轴名列表与系统配置里的axes对应。

清零操作有两个红灯:

  1. DELETE /coors/machine清零机床坐标,DELETE /coors/relative清零相对坐标,加工时清零会返回错误。
  2. 清零机床坐标有风险,文档原话是“应仅用于测试、教学、无机床零点或不使用机床零点的机床”。我自己的习惯是:生产系统里绝对不开放这个接口给操作工,只保留相对坐标清零,而且清零前必须确认 run-status 为 0。

4.2 /workcoors:工件坐标系的读与写

/workcoors/返回所有工件坐标系 G54-G59 的当前值。单个坐标系可以 GET,也可以用 PUT 修改:

curl -s -X PUT http://192.168.1.101/api/v1.3/workcoors/g55 \ -H "Content-Type: application/json" \ -d '{"X": 10.0, "Z": 2.0, "Y": 0}'

PUT 支持只设置部分轴,比如只写 X 轴。这个接口做远程对刀、批量工件坐标系下发时很有用,但要注意:坐标系修改是在系统运行参数上直接动刀,写入前一定要确认机床处于非运行状态,并且最好用/workcoors/cur先看当前用的是哪个坐标系,别把正在用的坐标系改了。

4.3 /vars:宏变量的读写与并发风险

单个宏变量接口是/vars/<varNo>,GET 读取,PUT 写入:

curl -s -X PUT http://192.168.1.101/api/v1.3/vars/100 \ -H "Content-Type: application/json" \ -d '{"val": 10.0}'

<varNo>既可以是宏变量号,也可以是宏名称(如/vars/TEST)。批量接口/vars/?name=<varNo1>,<varNo2>,...,<varNo3-varNo4>,...,<varNox>最多一次性读取 64 个宏变量的值,name为必选参数,逗号分隔,可以使用区间。区间是左闭右开,比如300-302等价于300,301,不包含 302。

这里有两个明确警告:第一,宏变量接口支持访问系统宏变量,包括刀补、模态和坐标值等,运行时修改可能对加工产生重大影响;第二,如果加工程序和 REST API 同时修改同一个宏变量,结果未知。我在做刀具寿命管理时,刀具计数宏变量的写入会严格限定在循环启动前和循环结束后这两个窗口,避免和加工程序撞车。

4.4 /ofs:刀补读写的“部分成功”大坑

刀补接口/ofs/count获取系统支持的刀补个数,/ofs/geoms/<ofsNo>和/ofs/wears/<ofsNo>分别读写形状值和磨损值。形状值包含每轴一项、R半径形状值、T刀尖方向(仅车床,0~9);磨损值包含每轴一项和R半径磨损值。

批量接口支持?start=<start>&count=<count>,start 默认 1,count 默认 32,最大 32。PUT 批量设置时传对象数组:

payload = [ {"no": 1, "val": {"X": 1.0, "Y": 0.5, "R": 0.1, "T": 0}}, {"no": 2, "val": {"X": 1.0, "Y": 0.5, "R": 0.1, "T": 0}}, ] resp = requests.put( "http://192.168.1.101/api/v1.3/ofs/geoms/", json=payload, timeout=3 )

文档里有一句非常关键的警告:设置即使返回失败,也可以部分成功,客户端应处理这种情况,读回确认全部成功。也就是说,批量写刀补之后,不能只看响应码,必须再批量 GET 一次,逐一比对写入值。这是这个接口最典型的边界,后面避坑章还会展开。

5. 常见问题排查:六个容易翻车的边界场景

5.1 现象:HTTP 200 但业务失败

第一次对接时,明明返回了 200,程序却一直拿不到数据。后来把响应体打出来才发现是{"error": -1, "error-message": "未知错误"}。

原因:这套 API 的错误处理里,HTTP 状态码不保证与业务成功一致,200 也可能带 error 对象。调用方只校验 HTTP 状态码就会漏掉业务错误。

解决:统一封装响应解析函数,先判断 HTTP 状态码,再解析 JSON,最后检查是否有error键。我把这个确认逻辑固化成了采集框架的公共方法,后续所有接口都走同一套校验。

5.2 现象:读 PLC 的 u32 数据一直报错

原因:/plc/vm/接口要求type与offset有对齐关系,u32的 offset 必须是 4 字节对齐,u16必须是 2 字节对齐。直接把 offset 写成 1 再去读 u32,服务端认为是非法请求。

解决:先算好 offset 是否满足对齐条件。我一般会写一个对齐检查,offset 对类型字节数取模为 0 才发请求;读连续数据时,count个 u32 占count * 4字节,下一个读取起点要加count * 4,而不是加 1。

5.3 现象:清零机床坐标时报错,加工时清零相对坐标也失败

原因:接口设计上做了保护,加工状态(run-status 为 2)下不允许清零坐标。清零操作会直接破坏加工基准,系统拒绝执行。

解决:清零前先 GET/status,确认run-status为 0 再发 DELETE。同时在业务逻辑里区分场景:相对坐标清零可以开放给操作工在待机时使用;机床坐标清零仅保留给调试模式或教学场景,生产环境不开放这个按钮。

5.4 现象:宏变量写入后,加工程序行为异常,且偶发写不进去

原因:加工程序和 REST API 同时修改同一个宏变量时,结果未知,文档明确警告过。宏变量里有很多是系统宏变量,包含刀补、模态、坐标值,运行时改这些变量等于在加工中途篡改系统数据。

解决:把宏变量的读写窗口严格限定在机床停止状态,并且通过/gmodals/确认当前不在自动运行中的 G 代码模态下。若必须读写刀具寿命类变量,我会把变量号集中在用户宏变量区(如 #500 以后),躲开系统占用区间。

5.5 现象:批量写刀补返回失败,但读回发现部分刀补已经生效

原因:刀补写入不是原子操作。文档明确说“设置即使返回失败,也可以部分成功”,服务端在执行批量写入时,可能写入前几项后遇到错误中断,但前面已写入的数据不会回滚。

解决:批量设置之后强制读回。我一般修改完刀补会立即调用/ofs/geoms/?start=<start>&count=<count>读回,逐项核对写入值,发现不一致就重新写入该序号。刀补数据直接影响加工精度,这个读回校验绝对不能省。

5.6 现象:程序列表读出来只有程序号,找不到程序名

原因:v1.2 和 v1.3 的程序列表返回结构不同。v1.2 中/progs/仅返回程序号,没有程序号的程序不会出现在列表中;v1.3 才返回程序名、程序号、大小、etag 和最后修改时间。

解决:程序管理功能一律按 v1.3 开发。如果遇到现场系统只支持 v1.2,程序列表里拿不到名称,只能靠程序号匹配业务数据。另注意程序访问要求 CNC 处于编辑模式或自动模式,修改/删除程序时程序开关还必须处于打开状态,否则返回错误。

6. 用一小段脚本把接口串起来:状态巡检与坐标采集的落地起点

接口看完了,最终还是要落到能跑的代码上。这里给一个最小的巡检脚本骨架,它把状态、坐标、报警、加工时间四类数据串起来,每秒轮询一次,写入本地 JSON 文件。这个脚本可以直接跑在车间工控机上,也可以改造成数据推送服务的一部分。

import requests import json import time BASE = "http://192.168.1.101/api/v1.3" def get(path): resp = requests.get(BASE + path, timeout=3) data = resp.json() if resp.text else {} if "error" in data: raise RuntimeError(data["error-message"]) return data def poll_once(): status = get("/status") coors = get("/coors/absolute") alarms = get("/alarms/") cycle = get("/cycletime") return { "run-status": status["run-status"], "opr-mode": status["opr-mode"], "ready": status["ready"], "position": coors, "alarms": alarms, "cycle": cycle, } while True: try: snapshot = poll_once() with open("cnc_snapshot.json", "w", encoding="utf-8") as f: json.dump(snapshot, f, ensure_ascii=False, indent=2) print("snapshot ok:", snapshot["position"]) except Exception as e: print("poll error:", e) time.sleep(1)

这个脚本里get()函数做了两层校验:空响应体和 error 字段。轮询循环里把异常兜住,防止网络抖动导致采集线程退出。实际项目里,我还会在此基础上增加写入保护:只有run-status == 0时才允许执行 PUT/DELETE 类操作,坐标采集永远只读绝对坐标,机床坐标只在初始化时读一次用于对零校验。至于倍率、目标件数、工件计数这类数据,建议放到低频采集(5 秒以上间隔),没必要每秒刷。

第一次把脚本接到真机上时,我因为没处理“HTTP 200 但带 error”的情况,整整查了一个下午,最后打印响应体才恍然大悟。从那以后我每次对接新接口,都强制先把原始响应打印出来看一遍,再写业务解析。这套 API 的文档已经算写得清楚,但边界条件仍然不少,希望这份拆解能帮你少踩几个坑,让数控机床的数据底座少一点玄学,多一点可控。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询