@codesys/mcp-toolkit 2.3.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -0
- package/README.md +63 -7
- package/README.zh-CN.md +43 -5
- package/dist/actions.js +7 -2
- package/dist/actions.js.map +1 -1
- package/dist/codesys/alarm-tools.d.ts +28 -0
- package/dist/codesys/alarm-tools.js +126 -0
- package/dist/codesys/alarm-tools.js.map +1 -0
- package/dist/codesys/graphical-read.d.ts +63 -0
- package/dist/codesys/graphical-read.js +214 -0
- package/dist/codesys/graphical-read.js.map +1 -0
- package/dist/codesys/graphical.js +13 -1
- package/dist/codesys/graphical.js.map +1 -1
- package/dist/codesys/report.d.ts +51 -0
- package/dist/codesys/report.js +100 -0
- package/dist/codesys/report.js.map +1 -0
- package/dist/hmi/native.d.ts +2 -1
- package/dist/hmi/native.js +42 -4
- package/dist/hmi/native.js.map +1 -1
- package/dist/hmi/render.d.ts +5 -0
- package/dist/hmi/render.js +33 -7
- package/dist/hmi/render.js.map +1 -1
- package/dist/hmi/route.d.ts +7 -7
- package/dist/hmi/route.js +36 -12
- package/dist/hmi/route.js.map +1 -1
- package/dist/hmi/service.d.ts +26 -1
- package/dist/hmi/service.js +113 -21
- package/dist/hmi/service.js.map +1 -1
- package/dist/hmi/spec.d.ts +104 -1
- package/dist/hmi/spec.js +20 -2
- package/dist/hmi/spec.js.map +1 -1
- package/dist/hmi/symbols.d.ts +89 -0
- package/dist/hmi/symbols.js +210 -0
- package/dist/hmi/symbols.js.map +1 -0
- package/dist/hmi/tools.d.ts +2 -0
- package/dist/hmi/tools.js +87 -10
- package/dist/hmi/tools.js.map +1 -1
- package/dist/panel/hmi.js +121 -27
- package/dist/panel.js +2 -1
- package/dist/panel.js.map +1 -1
- package/dist/progress.d.ts +17 -0
- package/dist/progress.js +36 -0
- package/dist/progress.js.map +1 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +4 -3
- package/dist/server.js.map +1 -1
- package/dist/tools.js +126 -5
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
- package/watcher/mcp_alarms.py +58 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,61 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.5.0] - 2026-11-14
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Ladder, FBD and SFC POUs read back as `create_graphical`'s description:
|
|
14
|
+
`read_objects` turns CODESYS's PLCopenXML into rungs (contacts in series
|
|
15
|
+
and parallel, coils, set/reset), networks (functions, function blocks with
|
|
16
|
+
their inputs and outputs, outputs written on the block) or steps (actions,
|
|
17
|
+
conditions, the jump back). To change one, Claude edits the description and
|
|
18
|
+
calls `create_graphical` with `replace: true`. What the description can't
|
|
19
|
+
hold (function boxes in a rung, SFC branches) is named, with the XML.
|
|
20
|
+
Checked against CODESYS SP22's own export: read, add a rung, replace,
|
|
21
|
+
compile with 0 errors, read back.
|
|
22
|
+
|
|
23
|
+
## [2.4.0] - 2026-11-14
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- Process-diagram symbols: a `symbol` item with a library of standard
|
|
27
|
+
symbols (motor, conveyor, heat exchanger, mixer, filter, compressor,
|
|
28
|
+
cylinder, level switch, pressure switch, check valve, control valve), each
|
|
29
|
+
with off, on and fault colours, named ports for pipes and rotation in 90°
|
|
30
|
+
steps. In CODESYS each state is its own picture in the image pool, chosen by
|
|
31
|
+
the on and fault variables. Checked live on SP21.
|
|
32
|
+
- Your own symbols: `hmi_save_symbol` adds an SVG symbol to the project, drawn
|
|
33
|
+
by Claude or imported from an SVG file (Inkscape, Illustrator), and returns
|
|
34
|
+
a picture of it in every state with its ports marked. `hmi_symbols` shows
|
|
35
|
+
the library, `hmi_delete_symbol` removes one. The SVG is checked against a
|
|
36
|
+
short list of elements and attributes; scripts, styles, links and external
|
|
37
|
+
images are refused.
|
|
38
|
+
- CODESYS alarms in the simulation: `alarm_list` (groups, alarms, classes,
|
|
39
|
+
messages and conditions of the Alarm Configuration), `alarm_status` (each
|
|
40
|
+
alarm's state from CODESYS's alarm manager: normal, pending, active, active
|
|
41
|
+
acknowledged, cleared and waiting for confirmation or acknowledgement) and
|
|
42
|
+
`alarm_acknowledge`. Lets Claude test alarms: raise the condition, check
|
|
43
|
+
it's active, clear it, acknowledge, check it's normal. Checked live on SP21.
|
|
44
|
+
- The browser HMI's alarm rows follow CODESYS's alarm states once the HMI is
|
|
45
|
+
exported: a cleared alarm stays in the list until it's acknowledged, with an
|
|
46
|
+
ACK button that acknowledges it in CODESYS's alarm manager (simulation
|
|
47
|
+
only); the header counts these too.
|
|
48
|
+
- `project_report`: a Markdown handover report next to the project (summary,
|
|
49
|
+
tasks, I/O list, device-tree mappings, CODESYS alarms, HMI pages,
|
|
50
|
+
libraries, devices, program structure) ending with a commissioning
|
|
51
|
+
checklist built from the project: each task, I/O point, mapped channel,
|
|
52
|
+
alarm, HMI page and persistent variable list to verify on the machine.
|
|
53
|
+
- `export_sources`: the project as plain text for git and review, one `.st`
|
|
54
|
+
file per object in folders like the project tree, ladder/FBD/SFC bodies as
|
|
55
|
+
PLCopenXML, `project.txt` (tasks, libraries, devices, alarms) and the HMI
|
|
56
|
+
screens. Exporting again only rewrites changed files and removes files of
|
|
57
|
+
deleted objects (only files an earlier export wrote).
|
|
58
|
+
- MCP progress: long actions send progress notifications (the steps of an HMI
|
|
59
|
+
export, the steps of a batch, and a heartbeat every 10 s), so clients that
|
|
60
|
+
reset their timeout on progress don't give up on a long export.
|
|
61
|
+
- `hmi_export_codesys` checks for the FloatingPointUtils library first and
|
|
62
|
+
says how to install it, instead of building for minutes and failing at the
|
|
63
|
+
compile.
|
|
64
|
+
|
|
10
65
|
## [2.3.0] - 2026-11-14
|
|
11
66
|
|
|
12
67
|
Several of the new actions use CODESYS's own services inside the IDE, beyond
|
package/README.md
CHANGED
|
@@ -35,8 +35,12 @@ can watch the code change as it happens.
|
|
|
35
35
|
- **Shows its work.** A live panel with the project tree, the code as it is
|
|
36
36
|
written, compile results, and Accept or Revert for each change.
|
|
37
37
|
- **Designs operator screens.** Claude builds a live HMI for your program,
|
|
38
|
-
with tanks, pumps, valves,
|
|
39
|
-
polishes it. You operate it in
|
|
38
|
+
with tanks, pumps, valves, a library of process symbols (or your own SVG),
|
|
39
|
+
gauges, trends and alarms, looks at it, and polishes it. You operate it in
|
|
40
|
+
the browser against the simulation, and it exports as a native CODESYS
|
|
41
|
+
visualization with real CODESYS alarms.
|
|
42
|
+
- **Ready for handover.** A project report with a commissioning checklist
|
|
43
|
+
built from the project, and a plain-text export of every object for git.
|
|
40
44
|
- **Never touches a real controller.** The only online connection is to
|
|
41
45
|
CODESYS's own simulation, and every online call checks for it first.
|
|
42
46
|
|
|
@@ -118,7 +122,9 @@ operation. [The reference](docs/reference.md) describes each one.
|
|
|
118
122
|
| **Simulation** | `codesys_sim_start` `codesys_sim_stop` `codesys_sim_status` `codesys_sim_control` `codesys_sim_cycle` `codesys_sim_read` `codesys_sim_write` `codesys_sim_force` `codesys_sim_unforce` `codesys_sim_test` |
|
|
119
123
|
| **Trace** | `trace_setup` `trace_record` |
|
|
120
124
|
| **Debug** | `breakpoint_set` `breakpoint_clear` `debug_status` `debug_step` `debug_continue` |
|
|
121
|
-
| **HMI screens** | `hmi_save_screen` `hmi_template` `hmi_screenshot` `hmi_export_codesys` `hmi_list` `hmi_delete_screen` `open_hmi` |
|
|
125
|
+
| **HMI screens** | `hmi_save_screen` `hmi_template` `hmi_screenshot` `hmi_export_codesys` `hmi_list` `hmi_delete_screen` `open_hmi` `hmi_save_symbol` `hmi_symbols` `hmi_delete_symbol` |
|
|
126
|
+
| **Alarms** | `alarm_list` `alarm_status` `alarm_acknowledge` |
|
|
127
|
+
| **Handover** | `project_report` `export_sources` |
|
|
122
128
|
| **Helpers** | `batch` `wait` `help` `open_workspace` |
|
|
123
129
|
|
|
124
130
|
`batch` runs up to 50 actions in one call, which is much faster than separate
|
|
@@ -127,15 +133,18 @@ calls.
|
|
|
127
133
|
Some actions go beyond what CODESYS's scripting API documents and use CODESYS's
|
|
128
134
|
own services inside the IDE: `get_signature`, `find_references`,
|
|
129
135
|
`rename_symbol`, `trace_setup`, `trace_record`, the debug actions,
|
|
130
|
-
`hmi_export_codesys` (with its alarms and user groups) and
|
|
136
|
+
`hmi_export_codesys` (with its alarms and user groups), the alarm actions and
|
|
137
|
+
`--show-window`.
|
|
131
138
|
They are **experimental**: checked on CODESYS V3.5 SP21 and SP22 as noted in
|
|
132
139
|
the [changelog](CHANGELOG.md). On another version they may report that the
|
|
133
140
|
feature isn't available, or not work.
|
|
134
141
|
|
|
135
142
|
Claude writes Structured Text, and creates ladder (LD), FBD and SFC programs
|
|
136
143
|
and function blocks with `create_graphical` from a simple description of rungs,
|
|
137
|
-
networks or steps; CODESYS draws them.
|
|
138
|
-
|
|
144
|
+
networks or steps; CODESYS draws them. Reading an LD, FBD or SFC POU gives the
|
|
145
|
+
same description, so Claude can change existing graphical code too: it edits the
|
|
146
|
+
description and sends it back with `replace: true`. CFC isn't supported, and
|
|
147
|
+
stays read-only as PLCopenXML.
|
|
139
148
|
|
|
140
149
|
## Live panel
|
|
141
150
|
|
|
@@ -178,6 +187,14 @@ bound to your PLC variables.
|
|
|
178
187
|
connects, and the toolkit routes it with right angles to meet each symbol
|
|
179
188
|
exactly, in the browser and in CODESYS alike. Unknown symbols or ports are
|
|
180
189
|
refused with the list of valid ones.
|
|
190
|
+
- **A symbol library, and your own symbols.** Besides tanks, pumps, fans and
|
|
191
|
+
valves: motor, conveyor, heat exchanger, mixer, filter, compressor,
|
|
192
|
+
cylinder, level and pressure switches, check valve and control valve, each
|
|
193
|
+
grey when off, green when on and red on a fault, with ports for pipes and
|
|
194
|
+
rotation. Claude can draw a symbol you need as SVG, or import yours from an
|
|
195
|
+
SVG file (`hmi_save_symbol`), and gets back a picture of it in every state
|
|
196
|
+
to check. Custom SVG is checked against a short list of elements and
|
|
197
|
+
attributes: scripts, styles, links and external images are refused.
|
|
181
198
|
- **Claude checks its own work.** `hmi_screenshot` returns the screen as an
|
|
182
199
|
image, so Claude can see overlaps, empty space or unclear labels and fix
|
|
183
200
|
them before you look.
|
|
@@ -190,6 +207,10 @@ bound to your PLC variables.
|
|
|
190
207
|
`<project>.hmi.json`, so they travel with it and can go into version control.
|
|
191
208
|
- **Dark and light themes,** on a 1280x720 canvas that scales to any window.
|
|
192
209
|
|
|
210
|
+

|
|
211
|
+
|
|
212
|
+

|
|
213
|
+
|
|
193
214
|
The HMI writes only into CODESYS's own simulation, like the rest of the
|
|
194
215
|
toolkit. Screenshots use Microsoft Edge or Google Chrome, whichever is
|
|
195
216
|
installed.
|
|
@@ -223,12 +244,47 @@ Error-class alarm should.
|
|
|
223
244
|
|
|
224
245
|

|
|
225
246
|
|
|
247
|
+
Claude can test them in the simulation: `alarm_status` reads each alarm's
|
|
248
|
+
state from CODESYS's alarm manager (normal, active, active acknowledged,
|
|
249
|
+
cleared but waiting for confirmation or acknowledgement), and
|
|
250
|
+
`alarm_acknowledge` acknowledges as an operator would. In the browser HMI, a
|
|
251
|
+
cleared alarm stays in the list until someone presses its ACK button, which
|
|
252
|
+
acknowledges it in CODESYS.
|
|
253
|
+
|
|
254
|
+

|
|
255
|
+
|
|
256
|
+
The symbols come along too: each state is its own picture in the image pool,
|
|
257
|
+
and the symbol's on and fault variables choose which one CODESYS shows.
|
|
258
|
+
|
|
259
|
+

|
|
260
|
+
|
|
226
261
|
CODESYS's scripting can't create trend, meter or alarm-table elements, so
|
|
227
262
|
trends show their current values, gauges show a bar, and the alarm page shows a
|
|
228
263
|
row per alarm while it is active (acknowledge it in CODESYS's own alarm table,
|
|
229
264
|
which you can add from the toolbox). Checked on CODESYS V3.5 SP21 in the
|
|
230
265
|
simulation. A visualization needs the `FloatingPointUtils` library in CODESYS's
|
|
231
|
-
library repository; if it's missing, the export says so
|
|
266
|
+
library repository; if it's missing, the export says so before it builds
|
|
267
|
+
anything. A long export reports its progress (each page, the alarms, the
|
|
268
|
+
compile) to clients that show MCP progress.
|
|
269
|
+
|
|
270
|
+
## Handover and version control
|
|
271
|
+
|
|
272
|
+
`project_report` writes a Markdown report next to the project for whoever
|
|
273
|
+
commissions or takes over the machine: a summary, the tasks, the I/O list and
|
|
274
|
+
device-tree mappings, the CODESYS alarms, the HMI pages, libraries, devices and
|
|
275
|
+
the program structure. It ends with a commissioning checklist built from the
|
|
276
|
+
project itself: every task's cycle time, every input and output, every mapped
|
|
277
|
+
channel, every alarm, every HMI page and the persistent variables to check on
|
|
278
|
+
the real machine, plus the safety and archiving items no checklist should
|
|
279
|
+
skip. Everything Claude did was tested in CODESYS's simulation only, and the
|
|
280
|
+
report says so.
|
|
281
|
+
|
|
282
|
+
`export_sources` writes the project as plain text for git: one `.st` file per
|
|
283
|
+
POU, method, property, action, DUT, GVL and interface, in folders like the
|
|
284
|
+
project tree, ladder/FBD/SFC bodies as PLCopenXML, a `project.txt` with tasks,
|
|
285
|
+
libraries, devices and alarms, and the HMI screens. A `.project` file is
|
|
286
|
+
binary; this folder is what makes a change reviewable as a diff. Exporting
|
|
287
|
+
again rewrites only what changed and removes the files of deleted objects.
|
|
232
288
|
|
|
233
289
|
## Other clients and models
|
|
234
290
|
|
package/README.zh-CN.md
CHANGED
|
@@ -32,6 +32,9 @@ CODESYS 会话,让 AI 助手直接操作你的真实项目:用真正的 CODE
|
|
|
32
32
|
无需安装其他软件,也不需要 PLC 硬件。
|
|
33
33
|
- **理解整个项目。** 提供项目大纲、I/O 列表、设备树和库接口,无需逐个读取对象。
|
|
34
34
|
- **过程可见。** 实时面板显示项目树、正在编写的代码和编译结果,每个改动都可以接受或还原。
|
|
35
|
+
- **设计操作画面。** Claude 为你的程序设计实时 HMI:储罐、泵、阀门、工艺符号库(或你自己的 SVG
|
|
36
|
+
符号)、仪表、趋势和报警,并能导出为带有 CODESYS 原生报警的 CODESYS 可视化。
|
|
37
|
+
- **便于交接。** 生成项目报告和基于项目内容的调试检查清单,并可把每个对象导出为纯文本以便用 git 管理。
|
|
35
38
|
- **绝不连接真实控制器。** 唯一的在线连接是 CODESYS 自带的仿真,每次在线操作前都会先检查。
|
|
36
39
|
|
|
37
40
|
## 快速开始
|
|
@@ -155,6 +158,11 @@ Cline、Trae、通义灵码、Cursor、Claude Desktop 等使用 `mcpServers` 配
|
|
|
155
158
|
面板尺寸:1280x720、1920x1080、1024x768 或 800x480。
|
|
156
159
|
- **操作面板(faceplate)。** 点击泵、风机或阀门会弹出面板:模式开关、启动/停止或开/关、复位、
|
|
157
160
|
实时数值和设定值。
|
|
161
|
+
- **符号库,以及你自己的符号。** 除储罐、泵、风机和阀门外,还有电机、输送带、换热器、搅拌器、
|
|
162
|
+
过滤器、压缩机、气缸、液位开关、压力开关、止回阀和调节阀;每个符号关闭时为灰色、运行时为绿色、
|
|
163
|
+
故障时为红色,带有管道接口并可旋转。Claude 可以把你需要的符号画成 SVG,或从 SVG 文件导入
|
|
164
|
+
(`hmi_save_symbol`),并返回该符号各状态的图片供检查。自定义 SVG 只允许少量元素和属性,
|
|
165
|
+
脚本、样式、链接和外部图片都会被拒绝。
|
|
158
166
|
- **Claude 会检查自己的设计。** `hmi_screenshot` 把画面作为图片返回给 Claude,它能发现重叠、
|
|
159
167
|
空白或不清楚的标签并自行修正。
|
|
160
168
|
- **在浏览器中实时运行。** 让 Claude 打开 HMI(`open_hmi`)。页面由工具包在 127.0.0.1 上提供,
|
|
@@ -164,6 +172,10 @@ Cline、Trae、通义灵码、Cursor、Claude Desktop 等使用 `mcpServers` 配
|
|
|
164
172
|
工具包会以直角自动布线,在浏览器和 CODESYS 中都能精确对接。
|
|
165
173
|
- **与项目一起保存。** 画面保存在项目文件旁边的 `<项目名>.hmi.json` 中。
|
|
166
174
|
|
|
175
|
+

|
|
176
|
+
|
|
177
|
+

|
|
178
|
+
|
|
167
179
|
HMI 只写入 CODESYS 自带的仿真,不会连接真实控制器。
|
|
168
180
|
|
|
169
181
|
`hmi_export_codesys` 还能把同一个画面生成为项目中的原生 CODESYS 可视化(不用 CODESYS 自带的灯和按钮样式):
|
|
@@ -183,9 +195,33 @@ HMI 只写入 CODESYS 自带的仿真,不会连接真实控制器。
|
|
|
183
195
|
|
|
184
196
|

|
|
185
197
|
|
|
198
|
+
Claude 可以在仿真中测试这些报警:`alarm_status` 从 CODESYS 报警管理器读取每个报警的状态(正常、
|
|
199
|
+
活动、活动已确认、已消失但等待确认),`alarm_acknowledge` 像操作员一样确认报警。在浏览器 HMI 中,
|
|
200
|
+
已消失的报警会一直留在列表中,直到有人按下它的 ACK 按钮,在 CODESYS 中确认它。
|
|
201
|
+
|
|
202
|
+

|
|
203
|
+
|
|
204
|
+
符号也会一起导出:每个状态是图片池中的一张图片,由符号的运行和故障变量决定 CODESYS 显示哪一张。
|
|
205
|
+
|
|
206
|
+

|
|
207
|
+
|
|
186
208
|
CODESYS 的脚本无法创建趋势、仪表或报警表元素,所以趋势显示当前值,仪表显示为棒图,报警页在
|
|
187
209
|
报警活动时显示一行(可在 CODESYS 自带的报警表中确认报警,报警表可从工具箱添加)。已在 CODESYS
|
|
188
|
-
V3.5 SP21 的仿真中验证。可视化需要 CODESYS 库存储库中有 `FloatingPointUtils`
|
|
210
|
+
V3.5 SP21 的仿真中验证。可视化需要 CODESYS 库存储库中有 `FloatingPointUtils` 库;如果缺少,导出会在
|
|
211
|
+
开始构建之前提示。
|
|
212
|
+
|
|
213
|
+
## 交接与版本管理
|
|
214
|
+
|
|
215
|
+
`project_report` 在项目旁边生成一份 Markdown 报告,供调试或接手设备的人使用:摘要、任务、I/O 列表和
|
|
216
|
+
设备树映射、CODESYS 报警、HMI 页面、库、设备和程序结构。报告最后是一份根据项目本身生成的调试检查
|
|
217
|
+
清单:每个任务的周期、每个输入输出、每个映射通道、每个报警、每个 HMI 页面以及保持型变量,都列为需要
|
|
218
|
+
在真实设备上检查的项目,另外还有安全和归档事项。Claude 所做的一切都只在 CODESYS 仿真中测试过,报告中
|
|
219
|
+
也会说明这一点。
|
|
220
|
+
|
|
221
|
+
`export_sources` 把项目导出为纯文本以便用 git 管理:每个 POU、方法、属性、动作、DUT、GVL 和接口一个
|
|
222
|
+
`.st` 文件,按项目树的结构放在文件夹中;梯形图、FBD 和 SFC 以 PLCopenXML 保存;`project.txt` 包含任务、
|
|
223
|
+
库、设备和报警;以及 HMI 画面。`.project` 文件是二进制的,这个文件夹让每次改动都能以差异的形式审阅。
|
|
224
|
+
再次导出时只重写有变化的文件,并删除已删除对象的文件。
|
|
189
225
|
|
|
190
226
|
## 可用操作
|
|
191
227
|
|
|
@@ -205,19 +241,21 @@ V3.5 SP21 的仿真中验证。可视化需要 CODESYS 库存储库中有 `Float
|
|
|
205
241
|
| **仿真** | `codesys_sim_start` `codesys_sim_stop` `codesys_sim_status` `codesys_sim_control` `codesys_sim_cycle` `codesys_sim_read` `codesys_sim_write` `codesys_sim_force` `codesys_sim_unforce` `codesys_sim_test` |
|
|
206
242
|
| **跟踪(Trace)** | `trace_setup` `trace_record` |
|
|
207
243
|
| **调试** | `breakpoint_set` `breakpoint_clear` `debug_status` `debug_step` `debug_continue` |
|
|
208
|
-
|
|
|
244
|
+
| **报警** | `alarm_list` `alarm_status` `alarm_acknowledge` |
|
|
245
|
+
| **交接** | `project_report` `export_sources` |
|
|
246
|
+
| **HMI 画面** | `hmi_save_screen` `hmi_template` `hmi_screenshot` `hmi_export_codesys` `hmi_list` `hmi_delete_screen` `open_hmi` `hmi_save_symbol` `hmi_symbols` `hmi_delete_symbol` |
|
|
209
247
|
| **辅助** | `batch` `wait` `help` `open_workspace` |
|
|
210
248
|
|
|
211
249
|
`batch` 可以在一次调用中执行最多 50 个操作,比逐个调用快得多。
|
|
212
250
|
|
|
213
251
|
有些操作超出了 CODESYS 脚本 API 文档的范围,使用 IDE 内部的 CODESYS 服务:`get_signature`、
|
|
214
252
|
`find_references`、`rename_symbol`、`trace_setup`、`trace_record`、调试操作、`hmi_export_codesys`
|
|
215
|
-
|
|
253
|
+
(包括报警和用户组)、报警操作以及 `--show-window`。它们属于**实验性功能**:已在 CODESYS V3.5 SP21 和 SP22 上
|
|
216
254
|
验证(见[更新日志](CHANGELOG.md)),在其他版本上可能提示功能不可用,或无法正常工作。
|
|
217
255
|
|
|
218
256
|
Claude 编写结构化文本,并可用 `create_graphical` 根据梯级、网络或步骤的简单描述创建梯形图(LD)、
|
|
219
|
-
FBD 和 SFC 程序及功能块,由 CODESYS
|
|
220
|
-
|
|
257
|
+
FBD 和 SFC 程序及功能块,由 CODESYS 绘制。读取 LD、FBD 或 SFC POU 时会得到同样的描述,因此 Claude
|
|
258
|
+
也能修改已有的图形化代码:修改描述后用 `replace: true` 发回即可。不支持 CFC,CFC 仍以 PLCopenXML 只读显示。
|
|
221
259
|
|
|
222
260
|
## 安全
|
|
223
261
|
|
package/dist/actions.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as z from "zod/v4";
|
|
2
|
+
import { reportProgress, withProgress } from "./progress.js";
|
|
2
3
|
export const TOOL_NAME = "codesys";
|
|
3
4
|
const fields = (s) => {
|
|
4
5
|
const required = new Set(s.required ?? []);
|
|
@@ -56,6 +57,8 @@ function batchAction(actions) {
|
|
|
56
57
|
const out = [];
|
|
57
58
|
let failed = false;
|
|
58
59
|
for (const [i, s] of steps.entries()) {
|
|
60
|
+
if (steps.length > 1)
|
|
61
|
+
reportProgress(`step ${i + 1}/${steps.length}: ${s.name}`);
|
|
59
62
|
const r = await s.action.run(s.args);
|
|
60
63
|
out.push(`[${i + 1}/${steps.length}] ${s.name}${r.isError ? " FAILED" : ""}:\n${r.content.map((c) => (c.type === "text" ? c.text : "(an image: call this action on its own to see it)")).join("\n")}`);
|
|
61
64
|
failed ||= !!r.isError;
|
|
@@ -80,7 +83,7 @@ export function registerActionTool(server, actions) {
|
|
|
80
83
|
args: z.record(z.string(), z.unknown()).optional().describe("The action's arguments, as listed for it in this tool's description"),
|
|
81
84
|
}),
|
|
82
85
|
annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false },
|
|
83
|
-
}, async ({ action, args }) => {
|
|
86
|
+
}, async ({ action, args }, ctx) => {
|
|
84
87
|
if (action === "help") {
|
|
85
88
|
if (args?.action === undefined)
|
|
86
89
|
return reply(catalog);
|
|
@@ -92,7 +95,9 @@ export function registerActionTool(server, actions) {
|
|
|
92
95
|
const parsed = checkArgs(a, args);
|
|
93
96
|
if (!parsed.success)
|
|
94
97
|
return reply(`Invalid arguments for ${action}:\n${z.prettifyError(parsed.error)}\n\n${usage(action, a)}`, true);
|
|
95
|
-
|
|
98
|
+
const token = ctx?.mcpReq?._meta?.progressToken;
|
|
99
|
+
const req = token === undefined ? undefined : { progressToken: token, notify: (n) => ctx.mcpReq.notify(n) };
|
|
100
|
+
return withProgress(req, action, () => a.run(parsed.data));
|
|
96
101
|
});
|
|
97
102
|
}
|
|
98
103
|
//# sourceMappingURL=actions.js.map
|
package/dist/actions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ActionResult, RegisterAction } from "../actions.js";
|
|
2
|
+
import type { AppContext } from "../tools.js";
|
|
3
|
+
export interface AlarmDef {
|
|
4
|
+
id: string;
|
|
5
|
+
kind: string;
|
|
6
|
+
expression: string;
|
|
7
|
+
comparison: string;
|
|
8
|
+
compare_to: string;
|
|
9
|
+
cls: string;
|
|
10
|
+
text: string;
|
|
11
|
+
}
|
|
12
|
+
export interface AlarmGroupDef {
|
|
13
|
+
name: string;
|
|
14
|
+
alarms: AlarmDef[];
|
|
15
|
+
}
|
|
16
|
+
/** The PLC variable of the k-th alarm of a group. */
|
|
17
|
+
export declare const alarmPath: (group: string, k: number) => string;
|
|
18
|
+
export type AlarmStateName = "normal" | "pending" | "active" | "waiting" | "acknowledged" | "unacknowledged" | "unknown";
|
|
19
|
+
/** AlarmState as read from the simulation ('AlarmState.Active', or the number). */
|
|
20
|
+
export declare function alarmState(raw: string | undefined): AlarmStateName;
|
|
21
|
+
export declare const STATE_TEXT: Record<AlarmStateName, string>;
|
|
22
|
+
export declare const condition: (a: AlarmDef) => string;
|
|
23
|
+
export declare function listAlarms(ctx: AppContext): Promise<AlarmGroupDef[]>;
|
|
24
|
+
/** Each alarm's state from the running simulation. */
|
|
25
|
+
export declare function readAlarmStates(ctx: AppContext, groups: AlarmGroupDef[]): Promise<Map<string, AlarmStateName>>;
|
|
26
|
+
/** Acknowledge (or confirm) alarms in the simulation; returns the keys written. */
|
|
27
|
+
export declare function acknowledgeAlarms(ctx: AppContext, groups: AlarmGroupDef[], keys: Set<string>): Promise<string[]>;
|
|
28
|
+
export declare function registerAlarmActions(reg: RegisterAction, ctx: AppContext, run: (fn: () => Promise<string>) => Promise<ActionResult>): void;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CODESYS alarm management, read and operated in the simulation: the Alarm
|
|
3
|
+
* Configuration's groups and alarms (watcher op alarms.list), each alarm's
|
|
4
|
+
* state from CODESYS's alarm manager, and acknowledging.
|
|
5
|
+
*
|
|
6
|
+
* The code CODESYS generates for an Alarm Configuration holds one instance per
|
|
7
|
+
* group, __Alm__GVL.g_inst.gen_Inst_<group>_AlarmGroup, whose gen_ArrAllAlarms[k]
|
|
8
|
+
* is the k-th alarm of the group (checked on SP21: m_uiId = k). m_eState is its
|
|
9
|
+
* AlarmState; writing TRUE to m_xToAcknowledge acknowledges or confirms it in
|
|
10
|
+
* the next cycle, as an alarm table's Acknowledge button does. Writes go only
|
|
11
|
+
* to CODESYS's own simulation.
|
|
12
|
+
*/
|
|
13
|
+
import * as z from "zod/v4";
|
|
14
|
+
import { currentCodesysSim } from "./simulation.js";
|
|
15
|
+
/** The PLC variable of the k-th alarm of a group. */
|
|
16
|
+
export const alarmPath = (group, k) => `__Alm__GVL.g_inst.gen_Inst_${group}_AlarmGroup.gen_ArrAllAlarms[${k}]`;
|
|
17
|
+
/** AlarmState as read from the simulation ('AlarmState.Active', or the number). */
|
|
18
|
+
export function alarmState(raw) {
|
|
19
|
+
const v = (raw ?? "").replace(/^AlarmState\./, "").replace(/^[A-Z_]+#/, "").trim();
|
|
20
|
+
const by = { Normal: "normal", "0": "normal", Pending: "pending", "1": "pending", Active: "active", "2": "active", WaitingForConfirmation: "waiting", "3": "waiting", ActiveAcknowledged: "acknowledged", "4": "acknowledged", InactiveUnacknowledged: "unacknowledged", "5": "unacknowledged" };
|
|
21
|
+
return by[v] ?? "unknown";
|
|
22
|
+
}
|
|
23
|
+
export const STATE_TEXT = {
|
|
24
|
+
normal: "normal",
|
|
25
|
+
pending: "pending (on-delay running)",
|
|
26
|
+
active: "ACTIVE",
|
|
27
|
+
waiting: "cleared, waiting for confirmation",
|
|
28
|
+
acknowledged: "ACTIVE, acknowledged",
|
|
29
|
+
unacknowledged: "cleared, not acknowledged",
|
|
30
|
+
unknown: "unknown",
|
|
31
|
+
};
|
|
32
|
+
const OPS = { Equal: "=", NotEqual: "<>", Greater: ">", GreaterOrEqual: ">=", Less: "<", LessOrEqual: "<=" };
|
|
33
|
+
export const condition = (a) => `${a.expression} ${OPS[a.comparison] ?? a.comparison} ${a.compare_to}`;
|
|
34
|
+
export async function listAlarms(ctx) {
|
|
35
|
+
return (await ctx.bridge.call("alarms.list", {}, { timeoutMs: 60_000 })).groups;
|
|
36
|
+
}
|
|
37
|
+
/** Each alarm's state from the running simulation. */
|
|
38
|
+
export async function readAlarmStates(ctx, groups) {
|
|
39
|
+
const names = groups.flatMap((g) => g.alarms.map((_, k) => `${alarmPath(g.name, k)}.m_eState`));
|
|
40
|
+
const out = new Map();
|
|
41
|
+
if (!names.length)
|
|
42
|
+
return out;
|
|
43
|
+
const r = await ctx.bridge.call("sim.read", { names }, { timeoutMs: 10_000 });
|
|
44
|
+
for (const g of groups)
|
|
45
|
+
g.alarms.forEach((a, k) => out.set(`${g.name}/${a.id}`, alarmState(r.values?.[`${alarmPath(g.name, k)}.m_eState`])));
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
/** Acknowledge (or confirm) alarms in the simulation; returns the keys written. */
|
|
49
|
+
export async function acknowledgeAlarms(ctx, groups, keys) {
|
|
50
|
+
const values = {};
|
|
51
|
+
const done = [];
|
|
52
|
+
for (const g of groups)
|
|
53
|
+
g.alarms.forEach((a, k) => {
|
|
54
|
+
const key = `${g.name}/${a.id}`;
|
|
55
|
+
if (keys.has(key))
|
|
56
|
+
(values[`${alarmPath(g.name, k)}.m_xToAcknowledge`] = "TRUE"), done.push(key);
|
|
57
|
+
});
|
|
58
|
+
if (done.length)
|
|
59
|
+
await ctx.bridge.call("sim.write", { values }, { timeoutMs: 10_000 });
|
|
60
|
+
return done;
|
|
61
|
+
}
|
|
62
|
+
export function registerAlarmActions(reg, ctx, run) {
|
|
63
|
+
const pick = (groups, group) => (group ? groups.filter((g) => g.name.toLowerCase() === group.toLowerCase()) : groups);
|
|
64
|
+
const needSim = () => {
|
|
65
|
+
if (!currentCodesysSim(ctx))
|
|
66
|
+
throw new Error("The simulation isn't running: start it with codesys_sim_start and codesys_sim_control (run).");
|
|
67
|
+
};
|
|
68
|
+
reg("alarm_list", {
|
|
69
|
+
description: "The project's CODESYS alarm management (Alarm Configuration): each alarm group with its alarms' IDs, conditions, classes and messages. hmi_export_codesys puts an HMI's alarms in group AG_HMI.",
|
|
70
|
+
inputSchema: z.object({}),
|
|
71
|
+
}, async () => run(async () => {
|
|
72
|
+
const groups = await listAlarms(ctx);
|
|
73
|
+
if (!groups.length)
|
|
74
|
+
return "This project has no Alarm Configuration (or no alarm groups in it).";
|
|
75
|
+
return groups.map((g) => [`${g.name} (${g.alarms.length} alarms):`, ...g.alarms.map((a) => ` ${a.id} [${a.cls || "?"}] ${a.text || "(no message)"} when ${condition(a)}`)].join("\n")).join("\n");
|
|
76
|
+
}));
|
|
77
|
+
reg("alarm_status", {
|
|
78
|
+
description: "The state of every CODESYS alarm in the running simulation, from CODESYS's own alarm manager: normal, pending, ACTIVE, ACTIVE acknowledged, or cleared but not yet acknowledged/confirmed. Use it to test alarms: force the condition, run, check it's ACTIVE, clear it, acknowledge, check it's normal. The state variables are listed for codesys_sim_test (expect 'AlarmState.Active' etc.).",
|
|
79
|
+
inputSchema: z.object({ group: z.string().optional().describe("One alarm group (default: all)") }),
|
|
80
|
+
}, async ({ group }) => run(async () => {
|
|
81
|
+
needSim();
|
|
82
|
+
const groups = pick(await listAlarms(ctx), group);
|
|
83
|
+
if (!groups.length)
|
|
84
|
+
return group ? `No alarm group named '${group}'.` : "This project has no CODESYS alarms.";
|
|
85
|
+
const states = await readAlarmStates(ctx, groups);
|
|
86
|
+
const lines = [];
|
|
87
|
+
let open = 0;
|
|
88
|
+
for (const g of groups) {
|
|
89
|
+
lines.push(`${g.name}:`);
|
|
90
|
+
g.alarms.forEach((a) => {
|
|
91
|
+
const s = states.get(`${g.name}/${a.id}`) ?? "unknown";
|
|
92
|
+
if (s !== "normal")
|
|
93
|
+
open++;
|
|
94
|
+
lines.push(` ${a.id.padEnd(4)} ${STATE_TEXT[s].padEnd(34)} [${a.cls || "?"}] ${a.text || "(no message)"} (${condition(a)})`);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
lines.push(open ? `${open} alarm(s) not normal. alarm_acknowledge acknowledges them (an alarm whose condition is still true stays active).` : "All alarms normal.");
|
|
98
|
+
lines.push(`State variables: ${alarmPath(groups[0].name, 0)}.m_eState and so on (index = position in the group, from 0).`);
|
|
99
|
+
return lines.join("\n");
|
|
100
|
+
}));
|
|
101
|
+
reg("alarm_acknowledge", {
|
|
102
|
+
description: "Acknowledge (or confirm) CODESYS alarms in the simulation, as an operator would at the alarm table: by default every alarm that isn't normal. Returns each alarm's state before and after. Only CODESYS's own simulation is written.",
|
|
103
|
+
inputSchema: z.object({
|
|
104
|
+
group: z.string().optional(),
|
|
105
|
+
ids: z.array(z.string()).optional().describe("Alarm IDs in the group (default: all that aren't normal)"),
|
|
106
|
+
}),
|
|
107
|
+
}, async ({ group, ids }) => run(async () => {
|
|
108
|
+
needSim();
|
|
109
|
+
const groups = pick(await listAlarms(ctx), group);
|
|
110
|
+
if (!groups.length)
|
|
111
|
+
return group ? `No alarm group named '${group}'.` : "This project has no CODESYS alarms.";
|
|
112
|
+
const before = await readAlarmStates(ctx, groups);
|
|
113
|
+
const wanted = new Set();
|
|
114
|
+
for (const g of groups)
|
|
115
|
+
for (const a of g.alarms)
|
|
116
|
+
if (ids ? ids.includes(a.id) : before.get(`${g.name}/${a.id}`) !== "normal")
|
|
117
|
+
wanted.add(`${g.name}/${a.id}`);
|
|
118
|
+
if (!wanted.size)
|
|
119
|
+
return "Nothing to acknowledge: every alarm is normal.";
|
|
120
|
+
const done = await acknowledgeAlarms(ctx, groups, wanted);
|
|
121
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
122
|
+
const after = await readAlarmStates(ctx, groups);
|
|
123
|
+
return [`Acknowledged ${done.length} alarm(s):`, ...done.map((k) => ` ${k}: ${STATE_TEXT[before.get(k) ?? "unknown"]} -> ${STATE_TEXT[after.get(k) ?? "unknown"]}`)].join("\n");
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=alarm-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alarm-tools.js","sourceRoot":"","sources":["../../src/codesys/alarm-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAG5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAgBpD,qDAAqD;AACrD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAa,EAAE,CAAS,EAAE,EAAE,CAAC,8BAA8B,KAAK,gCAAgC,CAAC,GAAG,CAAC;AAI/H,mFAAmF;AACnF,MAAM,UAAU,UAAU,CAAC,GAAuB;IAChD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACnF,MAAM,EAAE,GAAmC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,sBAAsB,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,kBAAkB,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC;IACjU,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAmC;IACxD,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,4BAA4B;IACrC,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,mCAAmC;IAC5C,YAAY,EAAE,sBAAsB;IACpC,cAAc,EAAE,2BAA2B;IAC3C,OAAO,EAAE,SAAS;CACnB,CAAC;AAEF,MAAM,GAAG,GAA2B,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AACrI,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAW,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;AAEjH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAe;IAC9C,OAAO,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAA8B,aAAa,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/G,CAAC;AAED,sDAAsD;AACtD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAe,EAAE,MAAuB;IAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IAChG,MAAM,GAAG,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC9C,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,GAAG,CAAC;IAC9B,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAiD,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9H,KAAK,MAAM,CAAC,IAAI,MAAM;QAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7I,OAAO,GAAG,CAAC;AACb,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAe,EAAE,MAAuB,EAAE,IAAiB;IACjG,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,MAAM;QACpB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACxB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;YAChC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,mBAAmB,CAAC,GAAG,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnG,CAAC,CAAC,CAAC;IACL,IAAI,IAAI,CAAC,MAAM;QAAE,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IACvF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAmB,EAAE,GAAe,EAAE,GAAyD;IAClI,MAAM,IAAI,GAAG,CAAC,MAAuB,EAAE,KAAc,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAChJ,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8FAA8F,CAAC,CAAC;IAC/I,CAAC,CAAC;IAEF,GAAG,CACD,YAAY,EACZ;QACE,WAAW,EAAE,iMAAiM;QAC9M,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;KAC1B,EACD,KAAK,IAAI,EAAE,CACT,GAAG,CAAC,KAAK,IAAI,EAAE;QACb,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,qEAAqE,CAAC;QACjG,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,WAAW,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,IAAI,cAAc,UAAU,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvM,CAAC,CAAC,CACL,CAAC;IAEF,GAAG,CACD,cAAc,EACd;QACE,WAAW,EACT,iYAAiY;QACnY,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC,EAAE,CAAC;KACnG,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAClB,GAAG,CAAC,KAAK,IAAI,EAAE;QACb,OAAO,EAAE,CAAC;QACV,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC,CAAC,CAAC,yBAAyB,KAAK,IAAI,CAAC,CAAC,CAAC,qCAAqC,CAAC;QAC9G,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAClD,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;YACzB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBACrB,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC;gBACvD,IAAI,CAAC,KAAK,QAAQ;oBAAE,IAAI,EAAE,CAAC;gBAC3B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,IAAI,cAAc,MAAM,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACjI,CAAC,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,kHAAkH,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;QACpK,KAAK,CAAC,IAAI,CAAC,oBAAoB,SAAS,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC,CAAC,8DAA8D,CAAC,CAAC;QAC5H,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CACL,CAAC;IAEF,GAAG,CACD,mBAAmB,EACnB;QACE,WAAW,EAAE,sOAAsO;QACnP,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC5B,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0DAA0D,CAAC;SACzG,CAAC;KACH,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,CACvB,GAAG,CAAC,KAAK,IAAI,EAAE;QACb,OAAO,EAAE,CAAC;QACV,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC,CAAC,CAAC,yBAAyB,KAAK,IAAI,CAAC,CAAC,CAAC,qCAAqC,CAAC;QAC9G,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;QACjC,KAAK,MAAM,CAAC,IAAI,MAAM;YAAE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM;gBAAE,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,QAAQ;oBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/J,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,OAAO,gDAAgD,CAAC;QAC1E,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1D,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjD,OAAO,CAAC,gBAAgB,IAAI,CAAC,MAAM,YAAY,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,OAAO,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnL,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ladder, FBD and SFC bodies read back as the description create_graphical
|
|
3
|
+
* takes, so the model can understand a graphical POU and edit it (change the
|
|
4
|
+
* description, create it again with replace). Works on the PLCopenXML CODESYS
|
|
5
|
+
* exports (checked against SP22's own export) and on create_graphical's.
|
|
6
|
+
*
|
|
7
|
+
* LD: every coil's power flow is followed back to the rail: contacts in series
|
|
8
|
+
* become {and}, parallel paths {or}. FBD: each output variable (or output
|
|
9
|
+
* written straight on a block) is followed back through blocks to the inputs.
|
|
10
|
+
* SFC: steps, their actions and the transition to the next step. What has no
|
|
11
|
+
* place in the description (function boxes in LD, SFC branches) is reported.
|
|
12
|
+
*/
|
|
13
|
+
import type { Fbd, Logic } from "./graphical.js";
|
|
14
|
+
interface El {
|
|
15
|
+
name: string;
|
|
16
|
+
attrs: Record<string, string>;
|
|
17
|
+
children: El[];
|
|
18
|
+
text: string;
|
|
19
|
+
}
|
|
20
|
+
/** A small XML reader for well-formed PLCopenXML: elements, attributes, text, CDATA. */
|
|
21
|
+
export declare function parseXml(xml: string): El;
|
|
22
|
+
export type GraphicalDescription = {
|
|
23
|
+
kind: "ladder";
|
|
24
|
+
spec: {
|
|
25
|
+
rungs: {
|
|
26
|
+
when: Logic;
|
|
27
|
+
then: {
|
|
28
|
+
coil: string;
|
|
29
|
+
kind: "coil" | "set" | "reset" | "negated";
|
|
30
|
+
}[];
|
|
31
|
+
}[];
|
|
32
|
+
};
|
|
33
|
+
notes: string[];
|
|
34
|
+
} | {
|
|
35
|
+
kind: "fbd";
|
|
36
|
+
spec: {
|
|
37
|
+
networks: {
|
|
38
|
+
expr: Fbd;
|
|
39
|
+
to?: string;
|
|
40
|
+
assign?: Record<string, string>;
|
|
41
|
+
}[];
|
|
42
|
+
};
|
|
43
|
+
notes: string[];
|
|
44
|
+
} | {
|
|
45
|
+
kind: "sfc";
|
|
46
|
+
spec: {
|
|
47
|
+
steps: {
|
|
48
|
+
name: string;
|
|
49
|
+
initial?: boolean;
|
|
50
|
+
actions?: {
|
|
51
|
+
name: string;
|
|
52
|
+
qualifier: string;
|
|
53
|
+
st: string;
|
|
54
|
+
}[];
|
|
55
|
+
next: string;
|
|
56
|
+
when: string;
|
|
57
|
+
}[];
|
|
58
|
+
};
|
|
59
|
+
notes: string[];
|
|
60
|
+
};
|
|
61
|
+
/** A graphical POU's PLCopenXML as create_graphical's description; undefined when the body isn't LD, FBD or SFC. */
|
|
62
|
+
export declare function describeGraphical(xml: string): GraphicalDescription | undefined;
|
|
63
|
+
export {};
|