主题
11.1 命令行批量操作多台 PLC
尊敬的电气工程师:当现场有十几台甚至几十台 LPPLC 设备需要统一改名、写入相同寄存器、或下发同一份程序时,一台一台点界面会非常耗时。本文介绍一种无需编程、无需编写 JSON 的批量操作方式——用一份纯文本指令文件,让工具按顺序自动把同样的操作施加到每一台设备上。
它适合:批量改名、批量写寄存器、批量下发 Lua 程序、批量更新 DTU 配置、批量重启等"对多台设备做同样的事"的场景。
除了改名,还能批量写这些
改名只是最简单的一种。同一套批量机制,配合不同的指令,可以对一批设备写入程序类内容:
- 11.2 批量写 Lua 程序 —— 用
LUA PUSH把同一份 Lua 烧入多台 - 11.3 批量写 DTU 配置 —— 用
DTU SET统一通讯配置 - 11.4 批量写梯形图 —— 用一行 JSON 调
ladder_download刷梯形图 - 11.5 批量写 DDC 程序 —— 用一行 JSON 调
write_ddc_program刷 DDC
下面每节都给了可直接照抄的示例文件 + 批处理,并附了在软 PLC 模拟器上的实测结果。
它是怎么工作的
工具提供两种运行模式,先「搜索并选中一台设备」,再「对它下指令」,做完退出换下一台。整个过程就是一行一条指令、从上往下顺序执行。
一个关键顺序
OPT(选中设备)只在工具模式有效。所以"做完一台、切下一台"必须先 BYE 退出当前设备,再 OPT 下一台——与"退出这台、再选那台"的实际操作顺序完全一致,无需记忆其他规则。
一行命令完成单台操作(子命令形式)
除了上面"先 SCAN、再 OPT、再下指令"的 REPL 批量方式,工具还提供子命令形式:一条命令直接完成一台设备的某一项操作,不用进入交互模式、也不用写 @@CMDS@@。适合"就一台、就一次"的场合,也适合写进批处理或自动化脚本。
text
lpplc-manager.exe dev scan
lpplc-manager.exe dev info --device 10000001
lpplc-manager.exe lua push --device 10000001 --file user.lua --verify --yes
lpplc-manager.exe plc read --device 10000001 --type D --start 500 --count 4
lpplc-manager.exe plc write --device 10000001 --type D --start 500 --values 1,2,3 --yes
lpplc-manager.exe dtu set --device 10000001 --file cfg.json --yes
lpplc-manager.exe api --method read_plc_registers --param register_type=D --param start_addr=500子命令全集:dev scan|list|info|restart、lua push|pull、ladder pull|push、dtu get|set、plc read|write、net probe、sim start|stop|status、self test、api。每一条都会先自动搜索一次设备;只有一台设备时 --device 可省略(程序会自动选中那一台)。
dev list是给脚本和 AI 用的:一条命令直接给出设备清单(纯数组,可存成devices.json),不用去解析扫描过程、也不用担心"换一次调用设备就找不到了"。ladder pull|push是 2026-09-29 起新增的:ladder pull把梯形图读回本地,ladder push把梯形图写进设备(底层方法名ladder_upload/ladder_download是按设备视角取的,容易写反,所以封装成 pull/push)。想让 AI 或自动化脚本一次性写对、不用反复试错,直接看 11.7 给 AI 与脚本的调用模板——那里有一段复制即用的代码和一份注意事项清单。
ladder pull|push是 2026-09-29 起新增的:ladder pull把设备上的梯形图读回本地(存成指令表文本),ladder push把指令表写进设备。之所以单独封装,是因为底层方法名ladder_upload/ladder_download是按设备视角取的(upload=设备上传给电脑,即"读"),容易写反;用pull/push方向和lua pull|push一致,一眼就懂。批量导出程序见 11.6。
写操作需要 --yes 确认
lua push / dtu set / plc write / dev restart 会真写设备,必须加 --yes 才会执行;不加只会报"需要确认"并退出。这是防止脚本/自动化误改设备的一道闸。只想先看"会发什么请求"、不真写,加 --dry-run(只回显请求、不连设备)。
上述
--yes/--dry-run/--human/--commands等命令行增强,随 2026-09-24 的命令行重构一同发布;使用较早版本请先升级到最新版。旧版本子命令形式同样可用,只是没有这些安全与可读开关。
给脚本与自动化(含 AI 驱动)的提示
- 拿能力清单:
lpplc-manager.exe --commands会输出一份机器可读的 JSON,列出全部命令、每个命令的参数、哪些是写操作、以及错误码与退出码——写自动化前先读它,不用猜参数名。 - 参数里带引号/中文不用怕:用
--param k=v(可重复)或--params @参数文件.json传参,命令行里一个引号都不用写;PowerShell 吞引号的问题用这两种写法彻底绕开。 - 输出是机器可读的:每条结果在 stdout 占一行 JSON(
type=resp|event|cli|cli_result);退出码0全好 /1命令行错误 /2请求失败 /3断言失败 /4用法错误。想看直观文字版,加--human。
三步走:怎么用
第 1 步:准备好这两个文件
需要两个文件放在同一个文件夹里:一个主程序 lpplc-manager.exe,一个指令模板 批量改名.bat。
① 主程序就在您安装的上位机里,不用另外下载。在桌面「LPPLC 管理工具」图标上右键 →「打开文件所在的位置」,看到的就是 lpplc-manager.exe(安装位置见 1.2 安装与首次启动)。
② 指令模板用记事本自己存一个:新建文本文档 → 把下面整段启动器原样粘进去(这半段一个字都不要改)→ 另存为时把文件名填 批量改名.bat、编码选 UTF-8 → 保存。
bat
@echo off
chcp 65001 >nul
setlocal
cd /d "%~dp0"
set "LPL=%TEMP%\lp_result.txt"
set "LPH=%TEMP%\lp_summary.txt"
if exist "%LPH%" del "%LPH%" >nul 2>nul
if not exist "lpplc-manager.exe" (
echo.
echo ERROR: lpplc-manager.exe NOT FOUND in this folder.
echo Put this file and lpplc-manager.exe in the SAME folder.
echo.
pause
exit /b 1
)
lpplc-manager.exe --repl --script "%~f0" --log "%LPL%" --summary "%LPH%" --quiet >nul 2>nul
echo --------------------------------------------
if exist "%LPH%" (
type "%LPH%"
) else (
echo ERROR: no result. Check device power / network, then retry.
echo Log file: %LPL%
)
echo --------------------------------------------
echo 每条指令的实际结果("errno":0 是成功;有 "error" / 非 0 的就是失败原因):
if exist "%LPL%" findstr /c:"errno" /c:"error" "%LPL%"
echo.
pause
exit /b 0粘完这一大段先别保存,接着做第 2 步把指令写在它下面,最后再一起保存成 批量改名.bat。
请从上面代码框里整段复制,不要自己敲
最后那两行 findstr 会把每条指令的实际结果(errno:0、写进去又读回来的值)也打印到窗口里。漏了这两行,改名以外的指令在窗口里看不到任何回执(见下面「结果确认」)。另外这个文件必须用**回车换行(Windows 格式)**保存——用记事本保存天然是这种格式;用其他编辑器请确认行尾是 CRLF,否则批处理会执行失败。
那个 exit /b 0 是全篇最要紧的一行
上面这段是启动器,最后一行 exit /b 0 让批处理在这里就结束了。您的指令写在它下面,只交给上位机读取执行,cmd 自己不碰。 删掉或漏写这行,cmd 会把您写的指令当成 Windows 命令去执行:屏幕上立刻冒出一串 'SCAN' is not recognized as an internal or external command.;rename … 那几行更会被 cmd 拿去做文件重命名,报 系统找不到指定的路径。——看着像程序坏了,其实只是少了这一行。
把文件放到 ① 那个文件夹里(和 lpplc-manager.exe 同级)。同时确保设备已上电、联网,电脑与设备在同一网段(参考 搜索设备的五种方式)。
第 2 步:用记事本改指令
右键 批量改名.bat → 「打开方式」→「记事本」。上半部分启动器不要动,只在末尾补上 @@CMDS@@ 标记和指令,一行一条。@@CMDS@@ 全文只出现一次——程序从这一行往下执行,多写一个它会被当成一条指令报错。
text
@@CMDS@@
# 以下为实际执行指令,一行一条,自上而下执行
SCAN
OPT 1
rename lpplc11101
BYE
OPT 2
rename lpplc11102
BYESCAN:搜索当前网络内全部设备并输出清单。OPT 1:选中清单里的第 1 台(数字 1、2、3 为搜索结果中的顺序号)。rename 新名字:给这台设备改名。BYE:退出当前设备,准备操作下一台。
要做更多台,复制 OPT / rename / BYE 三行并改名字即可。 保存时编码选 UTF-8(记事本默认即是;若用其他编辑器,请选"UTF-8"而不要选"UTF-8 与 BOM"——带 BOM 会让批处理第一行失效,屏幕上多出一堆回显和报错)。用简体中文 Windows 的记事本存成了 ANSI 也能正常执行,程序会自动识别编码。
第 3 步:双击运行
回到文件夹,双击 批量改名.bat,会弹出一个黑色命令行窗口。窗口里按序显示:搜索到的设备清单、每台的操作结果,最后停在
text
Press any key to continue . . .这一行是正常收尾(表示跑完了),按一下任意键窗口就关闭。
别用 PowerShell 直接敲命令
注意事项里的 lpplc-manager.exe --repl --script ... 这种写法请在黑色命令行窗口(cmd)里执行,或者干脆双击 .bat。 在 PowerShell 里直接敲这一句会看到"没反应":主程序是界面程序,PowerShell 敲完立刻回到提示符,后面的结果才慢慢冒出来,和下一条命令混在一起,看起来像出错、其实只是错序。双击 .bat 不受这个问题影响。 如果您是用脚本 / AI 调用,请用 11.7 给 AI 与脚本的调用模板 里的 Run-Cli 封装(Start-Process -Wait 包装),PowerShell 下也能正常阻塞等待、拿到结果。
只想试指令、不想改动设备
把 @@CMDS@@ 之后先只写这两行跑一次,它只搜索、不改动任何设备:
text
@@CMDS@@
SCAN
BYE看清清单里第几台是哪台之后,再补 OPT / rename。
指令全集
指令不区分大小写(rename 与 RENAME 等效)。# 开头的行是注释,不会被执行,可放心写说明(窗口里会把这一行原样回显出来,后面不跟结果,属正常)。
现在 rename / INFO / READ / WRITE / LUA / DTU 这六类指令,执行完都会在指令下面附一句直观文字提示(例如「已写入 D500 = 1,2,3」「读回 D500..D502 = 1,2,3」「Lua 程序已写入」);写成一行 JSON 的逃生舱不说话,成功与否看窗口最下面「每条指令的实际结果」那一段(见本页「结果确认」一节)。
工具模式(未选中设备时)
| 指令 | 作用 | 示例 |
|---|---|---|
SCAN [毫秒] | 搜索设备并输出清单 | SCAN 或 SCAN 5000 |
OPT <序号|序列号|IP> | 选中一台,进入设备模式 | OPT 1、OPT 10000001、OPT 192.168.1.10 |
HELP | 显示当前模式可用指令 | |
MODE | 显示当前所处模式 | |
BYE | 退出工具 |
OPT 用 IP 也行,但它不是"直接连这个 IP"
OPT 192.168.1.10 只在本次 SCAN 清单的 IP 列里找这台设备,找不到就报 未找到设备:…。所以:先 SCAN,看清单第 4 列显示的 IP 是什么,再照抄那个 IP。个别设备(例如软 PLC 模拟器)清单里 IP 显示为 0.0.0.0,这种就只能用序号或序列号选。
设备模式(已选中某台后)
| 指令 | 作用 | 示例 |
|---|---|---|
INFO | 查看该设备信息(含硬件 / 软件版本) | INFO |
RENAME <新名称> | 改名 | rename 车间A一号 |
READ <类型> <起始> [个数] | 读寄存器 | read D 500 4(读 D500 起 4 个) |
WRITE <类型> <起始> <值1,值2,...> | 写寄存器 | write D 500 1,2,3 |
LUA PUSH <文件> [VERIFY] | 下发 Lua 程序(加 VERIFY 回读校验) | lua push user.lua VERIFY |
LUA PULL [文件] | 读取设备上的 Lua 程序 | lua pull user.lua |
DTU GET [文件] | 读取 DTU 配置 | dtu get cfg.json |
DTU SET <文件> | 写入 DTU 配置 | dtu set cfg.json |
RESTART | 重启该设备 | restart |
SCAN | 重新搜索设备清单 | |
BYE | 退出该设备,回到工具模式(继续下一台) |
实战示例
照抄示例,只改下面这几处,就是您自己现场的批处理——启动器那一整段、@@CMDS@@ 这个标记、以及每台设备必须有 OPT … / 指令 / BYE 这个三段结构,这三样都不用动:
| 您想做什么 | 改哪里 | 改成什么样 |
|---|---|---|
| 改台数(几台就写几组) | 复制 OPT / 指令 / BYE 三行 | OPT 后面的序号或序列号换成清单里那台的 |
| 改设备名 | rename 后面 | rename 车间A一号(中文可以直接写,实测能写进去也能正常显示) |
| 写寄存器 | write 后的类型、起始地址、值 | write D 500 1,2,3 = D500=1、D501=2、D502=3;值用英文逗号分隔,个数决定写几个 |
| 读寄存器核对 | read 后的类型、起始、个数 | read D 500 3,读回的值在窗口最下面那段的 values 里 |
| 同一台做几件事 | 在它的 OPT 与 BYE 之间多写几行 | 先 rename 再 write,按从上往下的顺序执行 |
| 下发 Lua / DTU 配置 / 梯形图 / DDC | 换成对应那节的指令或 JSON 行 | 见 11.2、11.3、11.4、11.5,文件名换成您自己的 |
示例 1:为 10 台设备按序改名
text
@@CMDS@@
SCAN
OPT 1
rename 车间A一号
BYE
OPT 2
rename 车间A二号
BYE
OPT 3
rename 车间A三号
BYE
# …… 依此复制至第十台
OPT 10
rename 车间A十号
BYE示例 2:向一批设备写入相同寄存器值
例如为每台写入 D500=1, D501=2, D502=3:
text
@@CMDS@@
SCAN
OPT 1
write D 500 1,2,3
BYE
OPT 2
write D 500 1,2,3
BYE一台设备如需连续做多件事,都写在
OPT与BYE之间即可,例如先改名再写寄存器:OPT 1→rename 一号→write D 500 1,2,3→BYE。寄存器操作也可在上位机界面里进行,见 寄存器操作与设备日志。
示例 3:向一批设备下发同一份 Lua 程序
假设程序文件 user.lua 与 lpplc-manager.exe 同目录:
text
@@CMDS@@
SCAN
OPT 1
lua push user.lua VERIFY
BYE
OPT 2
lua push user.lua VERIFY
BYE注意事项
先 SCAN 看清再 OPT
OPT 1 / 2 / 3 里的数字是搜索清单中的顺序号,每次搜索顺序可能不同。正式操作前建议先单独跑一次只含 SCAN 的脚本,核对清单中第几台对应哪台设备。
为确保准确,推荐直接用设备真实序列号选择,例如 OPT 10000001(序列号见 SCAN 清单第一列)。这能避免用序号误选到不该动的设备。
.bat与lpplc-manager.exe须置于同一目录,否则窗口里会出现英文提示ERROR: lpplc-manager.exe NOT FOUND in this folder.,按第 1 步 ① 找到主程序所在目录再放一次。- 一台设备操作完毕须
BYE方可选择下一台;最后一台BYE后脚本自动结束。 - 操作会真实写入设备:改名、写寄存器、下发程序均为真实改动,执行前请确认所选设备正确。建议先用 软 PLC 模拟器 练习,确认指令无误后再对真机批量执行。
用模拟器练习时:一次只测一台
已知现象(模拟器版本 2026.9.16):在模拟器上做过读写寄存器或下发程序之后,模拟器进程可能自行退出(上位机所在目录出现崩溃转储文件 crash_dump_日期_时间.dmp),于是脚本里第二台开始会报 扫描完成,找到 0 台设备: 和 未找到设备:2。 这不代表指令写错了,也不代表刚才没写进去——已写入的内容(设备名、寄存器值、Lua 程序、DTU 配置、DDC 程序)重启模拟器后都还在。练习时请:一台一跑,跑完在上位机里重新点一次「🖥 启动软PLC」再测下一台。这一现象目前只在模拟器上见到;真机若也出现"第一台好、第二台搜不到",请联系技术支持并提供 %TEMP%\lp_result.txt。
- 自定义脚本文件名:除改这个
.bat外,也可新建任意xxx.txt只写指令,然后在**黑色命令行窗口(cmd)**里、cd到lpplc-manager.exe所在目录执行lpplc-manager.exe --repl --script xxx.txt,指令写法与@@CMDS@@之后完全一致(不要用 PowerShell 执行,见上面第 3 步的提醒)。
结果确认:怎么知道每条真的成功了
下面是 软 PLC 模拟器 上实测的完整窗口内容,指令为「改名 + 写 D500~D502 + 读回来核对」:
text
=== LPPLC 交互式命令行 (REPL) ===
输入 HELP 查看当前模式的指令;BYE 退出(设备模式下 BYE 回到工具模式)。
也可以直接输入一行 JSON 请求(以 { 开头)走底层引擎。
[工具模式] > SCAN
扫描完成,找到 1 台设备:
序号 序列号 名字 IP 硬件版本 软件版本
[1] 10000001 plc 0.0.0.0 6.6.6.6 2026.9.16
[工具模式] > OPT 1
已进入设备模式:10000001
[设备 10000001] > rename 车间A一号
已改名:10000001 -> 车间A一号
[设备 10000001] > write D 500 1,2,3
已写入 D500 = 1,2,3
[设备 10000001] > read D 500 3
D500..D502 = 1,2,3
[设备 10000001] > BYE
已退出设备模式,回到工具模式。
再见。
--------------------------------------------
每条指令的实际结果("errno":0 是成功;有 "error" / 非 0 的就是失败原因):
{"errmsg":"","errno":0,"method":"write_device_name","result":"设备名称已写入","seq":5,"type":"resp"}
{"errmsg":"","errno":0,"method":"write_plc_registers","result":"寄存器写入成功","seq":6,"type":"resp"}
{"errmsg":"","errno":0,"method":"read_plc_registers","result":{"count":3,"data_type":1,"register_type":"D","start_addr":500,"values":[1,2,3]},"seq":7,"type":"resp"}
--------------------------------------------
Press any key to continue . . .每条指令下面现在都有一句直观文字回执:rename 打「已改名:…」、write 打「已写入 D500 = 1,2,3」、read 打「读回 D500..D502 = 1,2,3」、INFO 打设备序列号/名字/IP/版本、LUA/DTU 打已写入/已读出。如果某条下面只回了「已执行」或「完成」,那是它本就没有要回显的值——成功与否一律以窗口最下面那段「每条指令的实际结果」里的 errno 为准。
看那一段只需要认这几个字段:
| 看到的 | 含义 |
|---|---|
"errno":0 | 这条成功了 |
"errno": 后面不是 0,且有 "errmsg":"…" | 这条失败了,errmsg 就是原因,直接发给技术支持 |
"level":"error" 一行,例如 参数展开失败: 打开文件失败: user.lua | 指令里写的文件没读到(文件名写错 / 没和 .bat 放在同一目录),这条根本没发出去 |
| 一条指令在下面完全没有对应的一行 | 这条没发到设备(常见于前面 OPT 就失败了,或这条写在 BYE 之后、已经回到工具模式) |
上面 read 那行的 "values":[1,2,3]、"start_addr":500 就是设备真实回读的结果——写进去的值原样读回来了,这是最硬的确认。想更稳妥,可以在每台设备上把「写 + 读」成对写,读回来的值不对就是没写进去。
INFO 的详细结果在哪儿看
INFO 现在会在窗口直接打一行「序列号 / 名字 / IP / 硬件版本 / 软件版本」。更完整的设备信息(含 {"cli":"dev info",…} 原始 JSON)仍写进机器可读日志 %TEMP%\lp_result.txt,需要时打开那一文件发给技术支持即可。
跑不出结果时对照这几句
窗口里的提示都是原话,逐条对照即可:
| 屏幕上看到的 | 是什么意思 | 怎么接着做 |
|---|---|---|
ERROR: lpplc-manager.exe NOT FOUND in this folder. | .bat 没和主程序放在同一目录 | 按第 1 步 ① 找到 lpplc-manager.exe,把 .bat 放进那个目录 |
'SCAN' is not recognized as an internal or external command. 或 系统找不到指定的路径。 | 启动器最后的 exit /b 0 被删了,cmd 自己去执行了指令行(rename 还会被当成文件重命名命令) | 把 exit /b 0 补回 @@CMDS@@ 的上一行 |
扫描完成,找到 0 台设备: 后面跟着 (无设备,请确认设备已上电 / 联网) | 没搜到设备 | 查设备电源与网线;确认电脑和设备在同一网段;确认防火墙放行了 lpplc-manager.exe(见 1.2) |
未找到设备:xxx(可先 SCAN,再用列表里的序号或序列号) | OPT 后面写的序号 / 序列号在本次清单里没有 | 用这份清单里的序号或第一列的序列号重写 |
未知指令:rename(输入 HELP 查看可用指令) | 忘了先 OPT,还在工具模式就下了设备指令 | 每台设备的操作都必须夹在 OPT … 和 BYE 之间 |
一行 JSON 报 找到 1 台设备,请用 --device 指定序列号或 IP | 同样忘了 OPT:一行 JSON 也要在设备模式下执行(它会提示"找到 N 台设备"让您挑) | 在这行 JSON 前面补 OPT <序号或序列号>,后面补 BYE |
某条指令下面只有一行 [设备 …] > write …,紧接着就是下一条指令 | 不是错误。write / read / LUA / DTU / INFO / 一行 JSON 都不打印直观文字回执 | 看窗口最下面「每条指令的实际结果」那一段,有对应的 "errno":0 就是成功了 |
窗口最下面那一段里找不到某条指令对应的 errno 行 | 这条没发到设备:多半是它前面的 OPT 就失败了(那台没选中),或它写在 BYE 之后已经回到工具模式 | 往上翻该台设备的 OPT 有没有「已进入设备模式」;设备指令必须写在 OPT 与 BYE 之间 |
ERROR: no result. Check device power / network, then retry. | 主程序没能写出结果文件 | 确认设备已上电联网、防火墙没拦,再双击一次 |
Press any key to continue . . . | 不是错误,整批已跑完 | 按任意键关窗口 |
想写成批的日志
上面这些直观文字结果同时被存进了 %TEMP%\lp_summary.txt(窗口里显示的就是它);机器可读的逐条 JSON 记录在 %TEMP%\lp_result.txt。找技术支持排障时把这两个文件发过去最省事。
进阶用法
除了上面的简写指令,@@CMDS@@ 之后每一行也可以直接写一行 JSON 请求走底层引擎(以 { 开头即可)。批量下发程序、配置有专门的写法:
- 11.2 批量写 Lua 程序 ——
LUA PUSH把同一份 Lua 烧入多台 - 11.3 批量写 DTU 配置 ——
DTU SET统一通讯配置 - 11.4 批量写梯形图 —— 一行 JSON 调
ladder_download - 11.5 批量写 DDC 程序 —— 一行 JSON 调
write_ddc_program