@codesys/mcp-toolkit 2.2.0 → 2.3.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 +85 -0
- package/README.md +109 -9
- package/README.zh-CN.md +72 -9
- package/dist/actions.d.ts +9 -4
- package/dist/actions.js +1 -1
- package/dist/actions.js.map +1 -1
- package/dist/codesys/debug.d.ts +5 -0
- package/dist/codesys/debug.js +89 -0
- package/dist/codesys/debug.js.map +1 -0
- package/dist/codesys/device-tools.d.ts +3 -0
- package/dist/codesys/device-tools.js +38 -0
- package/dist/codesys/device-tools.js.map +1 -0
- package/dist/codesys/graphical.d.ts +76 -0
- package/dist/codesys/graphical.js +226 -0
- package/dist/codesys/graphical.js.map +1 -0
- package/dist/codesys/lang.d.ts +39 -0
- package/dist/codesys/lang.js +177 -0
- package/dist/codesys/lang.js.map +1 -0
- package/dist/codesys/simtest.d.ts +48 -0
- package/dist/codesys/simtest.js +103 -0
- package/dist/codesys/simtest.js.map +1 -0
- package/dist/codesys/st.d.ts +1 -1
- package/dist/codesys/st.js.map +1 -1
- package/dist/codesys/trace.d.ts +19 -0
- package/dist/codesys/trace.js +139 -0
- package/dist/codesys/trace.js.map +1 -0
- package/dist/hmi/native.d.ts +89 -0
- package/dist/hmi/native.js +447 -0
- package/dist/hmi/native.js.map +1 -0
- package/dist/hmi/render.d.ts +90 -0
- package/dist/hmi/render.js +307 -0
- package/dist/hmi/render.js.map +1 -0
- package/dist/hmi/route.d.ts +32 -0
- package/dist/hmi/route.js +184 -0
- package/dist/hmi/route.js.map +1 -0
- package/dist/hmi/service.d.ts +45 -0
- package/dist/hmi/service.js +182 -0
- package/dist/hmi/service.js.map +1 -0
- package/dist/hmi/spec.d.ts +821 -0
- package/dist/hmi/spec.js +191 -0
- package/dist/hmi/spec.js.map +1 -0
- package/dist/hmi/templates.d.ts +11 -0
- package/dist/hmi/templates.js +92 -0
- package/dist/hmi/templates.js.map +1 -0
- package/dist/hmi/tools.d.ts +4 -0
- package/dist/hmi/tools.js +222 -0
- package/dist/hmi/tools.js.map +1 -0
- package/dist/hmi/value.d.ts +3 -0
- package/dist/hmi/value.js +26 -0
- package/dist/hmi/value.js.map +1 -0
- package/dist/panel/hmi.js +138 -0
- package/dist/panel.d.ts +3 -0
- package/dist/panel.js +17 -0
- package/dist/panel.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +7 -2
- package/dist/server.js.map +1 -1
- package/dist/tools.d.ts +5 -1
- package/dist/tools.js +18 -2
- package/dist/tools.js.map +1 -1
- package/dist/viewer.d.ts +1 -1
- package/dist/viewer.js +13 -2
- package/dist/viewer.js.map +1 -1
- package/package.json +1 -1
- package/watcher/mcp_alarms.py +134 -0
- package/watcher/mcp_debug.py +161 -0
- package/watcher/mcp_devices.py +83 -0
- package/watcher/mcp_lang.py +179 -0
- package/watcher/mcp_ops.py +3 -1
- package/watcher/mcp_trace.py +90 -0
- package/watcher/mcp_ui.py +54 -0
- package/watcher/mcp_visu.py +422 -0
- package/watcher/watcher.py +35 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ladder, FBD and SFC from a structured description, as PLCopenXML that
|
|
3
|
+
* CODESYS imports (the rules were learned live: a connection lists every
|
|
4
|
+
* source; SFC actions need relPosition before reference; every localId is
|
|
5
|
+
* unique; transition conditions are connected inVariables; step outputs use
|
|
6
|
+
* formalParameter "sfc"). The declaration is written as ST after the import.
|
|
7
|
+
*/
|
|
8
|
+
import * as z from "zod/v4";
|
|
9
|
+
import type { ActionResult, RegisterAction } from "../actions.js";
|
|
10
|
+
import type { AppContext } from "../tools.js";
|
|
11
|
+
/** A boolean expression for ladder: a variable ("xStart", "NOT xStop") or and/or of others. */
|
|
12
|
+
export type Logic = string | {
|
|
13
|
+
and: Logic[];
|
|
14
|
+
} | {
|
|
15
|
+
or: Logic[];
|
|
16
|
+
};
|
|
17
|
+
/** An FBD expression: a variable or literal, a function block, or a function such as AND, ADD, GT. */
|
|
18
|
+
export type Fbd = string | {
|
|
19
|
+
fn: string;
|
|
20
|
+
args: Fbd[];
|
|
21
|
+
} | {
|
|
22
|
+
fb: string;
|
|
23
|
+
instance: string;
|
|
24
|
+
inputs?: Record<string, Fbd>;
|
|
25
|
+
output?: string;
|
|
26
|
+
};
|
|
27
|
+
export declare const ladderSchema: z.ZodObject<{
|
|
28
|
+
rungs: z.ZodArray<z.ZodObject<{
|
|
29
|
+
when: z.ZodType<Logic, unknown, z.core.$ZodTypeInternals<Logic, unknown>>;
|
|
30
|
+
then: z.ZodArray<z.ZodObject<{
|
|
31
|
+
coil: z.ZodString;
|
|
32
|
+
kind: z.ZodDefault<z.ZodEnum<{
|
|
33
|
+
coil: "coil";
|
|
34
|
+
negated: "negated";
|
|
35
|
+
reset: "reset";
|
|
36
|
+
set: "set";
|
|
37
|
+
}>>;
|
|
38
|
+
}, z.core.$strip>>;
|
|
39
|
+
}, z.core.$strip>>;
|
|
40
|
+
}, z.core.$strip>;
|
|
41
|
+
export declare const fbdSchema: z.ZodObject<{
|
|
42
|
+
networks: z.ZodArray<z.ZodObject<{
|
|
43
|
+
assign: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
44
|
+
to: z.ZodOptional<z.ZodString>;
|
|
45
|
+
expr: z.ZodType<Fbd, unknown, z.core.$ZodTypeInternals<Fbd, unknown>>;
|
|
46
|
+
}, z.core.$strip>>;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
export declare const sfcSchema: z.ZodObject<{
|
|
49
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
50
|
+
name: z.ZodString;
|
|
51
|
+
initial: z.ZodOptional<z.ZodBoolean>;
|
|
52
|
+
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
53
|
+
name: z.ZodString;
|
|
54
|
+
qualifier: z.ZodDefault<z.ZodEnum<{
|
|
55
|
+
N: "N";
|
|
56
|
+
P: "P";
|
|
57
|
+
P0: "P0";
|
|
58
|
+
P1: "P1";
|
|
59
|
+
R: "R";
|
|
60
|
+
S: "S";
|
|
61
|
+
}>>;
|
|
62
|
+
st: z.ZodString;
|
|
63
|
+
}, z.core.$strip>>>;
|
|
64
|
+
next: z.ZodString;
|
|
65
|
+
when: z.ZodString;
|
|
66
|
+
}, z.core.$strip>>;
|
|
67
|
+
}, z.core.$strip>;
|
|
68
|
+
export declare function ladderXml(name: string, pouType: "program" | "functionBlock", spec: z.infer<typeof ladderSchema>): string;
|
|
69
|
+
export declare function fbdXml(name: string, pouType: "program" | "functionBlock", spec: z.infer<typeof fbdSchema>): string;
|
|
70
|
+
export declare function sfcXml(name: string, pouType: "program" | "functionBlock", spec: z.infer<typeof sfcSchema>): string;
|
|
71
|
+
/**
|
|
72
|
+
* The SFCs this generator makes are one sequence: each step goes to the next one
|
|
73
|
+
* listed, and the last step jumps back (to any step). Branches aren't supported yet.
|
|
74
|
+
*/
|
|
75
|
+
export declare function sfcProblems(spec: z.infer<typeof sfcSchema>): string[];
|
|
76
|
+
export declare function registerGraphicalActions(reg: RegisterAction, ctx: AppContext, run: (fn: () => Promise<string>) => Promise<ActionResult>): void;
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ladder, FBD and SFC from a structured description, as PLCopenXML that
|
|
3
|
+
* CODESYS imports (the rules were learned live: a connection lists every
|
|
4
|
+
* source; SFC actions need relPosition before reference; every localId is
|
|
5
|
+
* unique; transition conditions are connected inVariables; step outputs use
|
|
6
|
+
* formalParameter "sfc"). The declaration is written as ST after the import.
|
|
7
|
+
*/
|
|
8
|
+
import * as z from "zod/v4";
|
|
9
|
+
const logic = z.lazy(() => z.union([z.string().min(1), z.object({ and: z.array(logic).min(1) }), z.object({ or: z.array(logic).min(1) })]));
|
|
10
|
+
const fbd = z.lazy(() => z.union([
|
|
11
|
+
z.string().min(1),
|
|
12
|
+
z.object({ fn: z.string().min(1), args: z.array(fbd).min(1) }),
|
|
13
|
+
z.object({ fb: z.string().min(1), instance: z.string().min(1), inputs: z.record(z.string(), fbd).optional(), output: z.string().optional() }),
|
|
14
|
+
]));
|
|
15
|
+
export const ladderSchema = z.object({
|
|
16
|
+
rungs: z
|
|
17
|
+
.array(z.object({
|
|
18
|
+
when: logic.describe("Contacts: 'xStart', 'NOT xStop', {and: [...]} in series, {or: [...]} in parallel"),
|
|
19
|
+
then: z.array(z.object({ coil: z.string(), kind: z.enum(["coil", "set", "reset", "negated"]).default("coil") })).min(1),
|
|
20
|
+
}))
|
|
21
|
+
.min(1),
|
|
22
|
+
});
|
|
23
|
+
export const fbdSchema = z.object({
|
|
24
|
+
networks: z
|
|
25
|
+
.array(z.object({
|
|
26
|
+
assign: z.record(z.string(), z.string()).optional().describe("For a function block: its outputs to variables, e.g. {Q: 'xLamp', ET: 'tElapsed'}"),
|
|
27
|
+
to: z.string().optional().describe("Variable the expression's result is written to"),
|
|
28
|
+
expr: fbd.describe("e.g. {fn: 'AND', args: ['xA', 'xB']} or {fb: 'TON', instance: 'tonDelay', inputs: {IN: 'xIn', PT: 'T#2S'}, output: 'Q'}"),
|
|
29
|
+
}))
|
|
30
|
+
.min(1),
|
|
31
|
+
});
|
|
32
|
+
export const sfcSchema = z.object({
|
|
33
|
+
steps: z
|
|
34
|
+
.array(z.object({
|
|
35
|
+
name: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/),
|
|
36
|
+
initial: z.boolean().optional(),
|
|
37
|
+
actions: z.array(z.object({ name: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/), qualifier: z.enum(["N", "S", "R", "P", "P0", "P1"]).default("N"), st: z.string() })).optional(),
|
|
38
|
+
next: z.string().describe("Step this one goes to"),
|
|
39
|
+
when: z.string().describe("Transition condition in ST, e.g. 'xStart AND NOT xFault'"),
|
|
40
|
+
}))
|
|
41
|
+
.min(2),
|
|
42
|
+
});
|
|
43
|
+
const esc = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
44
|
+
function wrap(name, pouType, body, actions = "", addData = "") {
|
|
45
|
+
return `<?xml version="1.0" encoding="utf-8"?>
|
|
46
|
+
<project xmlns="http://www.plcopen.org/xml/tc6_0200">
|
|
47
|
+
<fileHeader companyName="codesys-mcp-toolkit" productName="codesys-mcp-toolkit" productVersion="2" creationDateTime="2026-01-01T00:00:00" />
|
|
48
|
+
<contentHeader name="${esc(name)}"><coordinateInfo><fbd><scaling x="1" y="1" /></fbd><ld><scaling x="1" y="1" /></ld><sfc><scaling x="1" y="1" /></sfc></coordinateInfo></contentHeader>
|
|
49
|
+
<types><dataTypes /><pous>
|
|
50
|
+
<pou name="${esc(name)}" pouType="${pouType}">
|
|
51
|
+
<interface />
|
|
52
|
+
${actions}<body>${body}</body>${addData}
|
|
53
|
+
</pou>
|
|
54
|
+
</pous></types>
|
|
55
|
+
<instances><configurations /></instances>
|
|
56
|
+
</project>`;
|
|
57
|
+
}
|
|
58
|
+
export function ladderXml(name, pouType, spec) {
|
|
59
|
+
let id = 0;
|
|
60
|
+
const parts = [];
|
|
61
|
+
spec.rungs.forEach((rung, n) => {
|
|
62
|
+
const y = n * 100;
|
|
63
|
+
const rail = ++id;
|
|
64
|
+
parts.push(`<leftPowerRail localId="${rail}"><position x="0" y="${y}" /><connectionPointOut formalParameter="none" /></leftPowerRail>`);
|
|
65
|
+
const build = (e, inputs) => {
|
|
66
|
+
if (typeof e === "string") {
|
|
67
|
+
const neg = /^\s*NOT\s+/i.test(e);
|
|
68
|
+
const v = e.replace(/^\s*NOT\s+/i, "").trim();
|
|
69
|
+
const c = ++id;
|
|
70
|
+
parts.push(`<contact localId="${c}" negated="${neg}"><position x="0" y="${y}" /><connectionPointIn>${inputs.map((i) => `<connection refLocalId="${i}" />`).join("")}</connectionPointIn><connectionPointOut /><variable>${esc(v)}</variable></contact>`);
|
|
71
|
+
return [c];
|
|
72
|
+
}
|
|
73
|
+
if ("and" in e)
|
|
74
|
+
return e.and.reduce((cur, x) => build(x, cur), inputs);
|
|
75
|
+
return e.or.flatMap((x) => build(x, inputs));
|
|
76
|
+
};
|
|
77
|
+
const outs = build(rung.when, [rail]);
|
|
78
|
+
const coils = rung.then.map((t) => {
|
|
79
|
+
const c = ++id;
|
|
80
|
+
const storage = t.kind === "set" ? ' storage="set"' : t.kind === "reset" ? ' storage="reset"' : "";
|
|
81
|
+
parts.push(`<coil localId="${c}" negated="${t.kind === "negated"}"${storage}><position x="0" y="${y}" /><connectionPointIn>${outs.map((i) => `<connection refLocalId="${i}" />`).join("")}</connectionPointIn><connectionPointOut /><variable>${esc(t.coil)}</variable></coil>`);
|
|
82
|
+
return c;
|
|
83
|
+
});
|
|
84
|
+
parts.push(`<rightPowerRail localId="${++id}"><position x="0" y="${y}" /><connectionPointIn>${coils.map((i) => `<connection refLocalId="${i}" />`).join("")}</connectionPointIn></rightPowerRail>`);
|
|
85
|
+
});
|
|
86
|
+
return wrap(name, pouType, `<LD>${parts.join("\n")}</LD>`);
|
|
87
|
+
}
|
|
88
|
+
export function fbdXml(name, pouType, spec) {
|
|
89
|
+
let id = 0;
|
|
90
|
+
const parts = [];
|
|
91
|
+
spec.networks.forEach((net, n) => {
|
|
92
|
+
const y = n * 200;
|
|
93
|
+
let x = 0;
|
|
94
|
+
/** Emits the expression; returns its output connection. */
|
|
95
|
+
const build = (e) => {
|
|
96
|
+
if (typeof e === "string") {
|
|
97
|
+
const v = ++id;
|
|
98
|
+
parts.push(`<inVariable localId="${v}"><position x="${x}" y="${y}" /><connectionPointOut /><expression>${esc(e)}</expression></inVariable>`);
|
|
99
|
+
return { id: v };
|
|
100
|
+
}
|
|
101
|
+
if ("fn" in e) {
|
|
102
|
+
const ins = e.args.map(build);
|
|
103
|
+
const b = ++id;
|
|
104
|
+
x += 100;
|
|
105
|
+
const fn = e.fn.toUpperCase();
|
|
106
|
+
parts.push(`<block localId="${b}" typeName="${esc(fn)}"><position x="${x}" y="${y}" /><inputVariables>${ins.map((i, k) => `<variable formalParameter="In${k + 1}"><connectionPointIn><connection refLocalId="${i.id}"${i.param ? ` formalParameter="${esc(i.param)}"` : ""} /></connectionPointIn></variable>`).join("")}</inputVariables><inOutVariables /><outputVariables><variable formalParameter="Out1"><connectionPointOut /></variable></outputVariables></block>`);
|
|
107
|
+
return { id: b, param: "Out1" };
|
|
108
|
+
}
|
|
109
|
+
const ins = Object.entries(e.inputs ?? {}).map(([k, v]) => [k, build(v)]);
|
|
110
|
+
const b = ++id;
|
|
111
|
+
x += 100;
|
|
112
|
+
const outs = [...new Set([e.output ?? "Q", ...Object.keys(net.assign ?? {})])];
|
|
113
|
+
parts.push(`<block localId="${b}" typeName="${esc(e.fb)}" instanceName="${esc(e.instance)}"><position x="${x}" y="${y}" /><inputVariables>${ins.map(([k, i]) => `<variable formalParameter="${esc(k)}"><connectionPointIn><connection refLocalId="${i.id}"${i.param ? ` formalParameter="${esc(i.param)}"` : ""} /></connectionPointIn></variable>`).join("")}</inputVariables><inOutVariables /><outputVariables>${outs.map((o) => `<variable formalParameter="${esc(o)}"><connectionPointOut /></variable>`).join("")}</outputVariables></block>`);
|
|
114
|
+
return { id: b, param: e.output ?? "Q" };
|
|
115
|
+
};
|
|
116
|
+
const out = build(net.expr);
|
|
117
|
+
const targets = [];
|
|
118
|
+
if (net.to)
|
|
119
|
+
targets.push([out.param, net.to]);
|
|
120
|
+
for (const [param, v] of Object.entries(net.assign ?? {}))
|
|
121
|
+
targets.push([param, v]);
|
|
122
|
+
for (const [param, v] of targets) {
|
|
123
|
+
x += 100;
|
|
124
|
+
parts.push(`<outVariable localId="${++id}"><position x="${x}" y="${y}" /><connectionPointIn><connection refLocalId="${out.id}"${param ? ` formalParameter="${esc(param)}"` : ""} /></connectionPointIn><expression>${esc(v)}</expression></outVariable>`);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
return wrap(name, pouType, `<FBD>${parts.join("\n")}</FBD>`);
|
|
128
|
+
}
|
|
129
|
+
export function sfcXml(name, pouType, spec) {
|
|
130
|
+
const steps = spec.steps;
|
|
131
|
+
const names = new Set(steps.map((s) => s.name));
|
|
132
|
+
for (const s of steps)
|
|
133
|
+
if (!names.has(s.next))
|
|
134
|
+
throw new Error(`step ${s.name} goes to '${s.next}', which isn't a step`);
|
|
135
|
+
if (!steps.some((s) => s.initial))
|
|
136
|
+
steps[0].initial = true;
|
|
137
|
+
let id = 0;
|
|
138
|
+
const parts = [];
|
|
139
|
+
const actionDefs = [];
|
|
140
|
+
let y = 0;
|
|
141
|
+
let prev;
|
|
142
|
+
steps.forEach((s, k) => {
|
|
143
|
+
const st = ++id;
|
|
144
|
+
parts.push(`<step localId="${st}"${s.initial ? ' initialStep="true"' : ""} name="${esc(s.name)}"><position x="0" y="${y}" /><connectionPointIn>${prev ? `<connection refLocalId="${prev}" />` : ""}</connectionPointIn><connectionPointOut formalParameter="sfc" /></step>`);
|
|
145
|
+
if (s.actions?.length) {
|
|
146
|
+
const blk = ++id;
|
|
147
|
+
const acts = s.actions.map((a) => {
|
|
148
|
+
actionDefs.push(`<action name="${esc(a.name)}"><body><ST><xhtml xmlns="http://www.w3.org/1999/xhtml">${esc(a.st)}</xhtml></ST></body></action>`);
|
|
149
|
+
return `<action localId="${++id}" qualifier="${a.qualifier}"><relPosition x="0" y="0" /><reference name="${esc(a.name)}" /><connectionPointOut /></action>`;
|
|
150
|
+
});
|
|
151
|
+
parts.push(`<actionBlock localId="${blk}"><position x="150" y="${y}" /><connectionPointIn><connection refLocalId="${st}" /></connectionPointIn>${acts.join("")}</actionBlock>`);
|
|
152
|
+
}
|
|
153
|
+
y += 40;
|
|
154
|
+
const cond = ++id;
|
|
155
|
+
parts.push(`<inVariable localId="${cond}"><position x="0" y="${y}" /><connectionPointOut /><expression>${esc(s.when)}</expression></inVariable>`);
|
|
156
|
+
const tr = ++id;
|
|
157
|
+
parts.push(`<transition localId="${tr}"><position x="0" y="${y}" /><connectionPointIn><connection refLocalId="${st}" formalParameter="sfc" /></connectionPointIn><connectionPointOut /><condition><connectionPointIn><connection refLocalId="${cond}" /></connectionPointIn></condition></transition>`);
|
|
158
|
+
y += 40;
|
|
159
|
+
const following = steps[k + 1];
|
|
160
|
+
if (following && following.name === s.next)
|
|
161
|
+
prev = tr;
|
|
162
|
+
else {
|
|
163
|
+
parts.push(`<jumpStep localId="${++id}" targetName="${esc(s.next)}"><position x="0" y="${y}" /><connectionPointIn><connection refLocalId="${tr}" /></connectionPointIn></jumpStep>`);
|
|
164
|
+
y += 40;
|
|
165
|
+
prev = undefined;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
const sfcSettings = `<addData><data name="http://www.3s-software.com/plcopenxml/sfcsettings" handleUnknown="implementation"><SFCSettings><LibTitle>IecSfc</LibTitle><LibCompany>System</LibCompany><LibVersion>4.4.0.0</LibVersion><LibNamespace>IecSfc</LibNamespace><CalcActiveTransOnly>false</CalcActiveTransOnly><UseDefaults>false</UseDefaults></SFCSettings></data></addData>`;
|
|
169
|
+
return wrap(name, pouType, `<SFC>${parts.join("\n")}</SFC>`, actionDefs.length ? `<actions>${actionDefs.join("")}</actions>\n ` : "", sfcSettings);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* The SFCs this generator makes are one sequence: each step goes to the next one
|
|
173
|
+
* listed, and the last step jumps back (to any step). Branches aren't supported yet.
|
|
174
|
+
*/
|
|
175
|
+
export function sfcProblems(spec) {
|
|
176
|
+
const out = [];
|
|
177
|
+
const names = new Set(spec.steps.map((s) => s.name));
|
|
178
|
+
if (names.size !== spec.steps.length)
|
|
179
|
+
out.push("step names must be unique");
|
|
180
|
+
spec.steps.forEach((s, k) => {
|
|
181
|
+
const following = spec.steps[k + 1];
|
|
182
|
+
if (!names.has(s.next))
|
|
183
|
+
out.push(`step ${s.name} goes to '${s.next}', which isn't a step`);
|
|
184
|
+
else if (following && s.next !== following.name)
|
|
185
|
+
out.push(`step ${s.name} must go to the next step listed (${following.name}); only the last step can jump back. Branches aren't supported yet: write the sequence in ST instead.`);
|
|
186
|
+
});
|
|
187
|
+
return out;
|
|
188
|
+
}
|
|
189
|
+
export function registerGraphicalActions(reg, ctx, run) {
|
|
190
|
+
reg("create_graphical", {
|
|
191
|
+
description: "Create a ladder (LD), function block diagram (FBD) or sequential function chart (SFC) program or function block from a structured description; CODESYS draws it. " +
|
|
192
|
+
"ladder: {rungs: [{when: 'xStart' | 'NOT xStop' | {and: [...]} (series) | {or: [...]} (parallel), then: [{coil: 'xMotor', kind: 'coil'|'set'|'reset'|'negated'}]}]}. " +
|
|
193
|
+
"fbd: {networks: [{expr: 'xA' | {fn: 'AND', args: [...]} | {fb: 'TON', instance: 'tonDelay', inputs: {IN: ..., PT: 'T#2S'}, output: 'Q'}, to: 'xOut', assign: {ET: 'tEt'}}]}. " +
|
|
194
|
+
"sfc: {steps: [{name, initial?, actions?: [{name, qualifier: 'N'|'S'|'R'|'P', st: 'ST code'}], next: 'NextStep', when: 'ST condition'}]}, one sequence: each step goes to the next listed, the last jumps back. " +
|
|
195
|
+
"declaration is the POU's ST declaration (PROGRAM or FUNCTION_BLOCK with its variables, FB instances included). Compile afterwards.",
|
|
196
|
+
inputSchema: z.object({
|
|
197
|
+
name: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/),
|
|
198
|
+
declaration: z.string().describe("e.g. 'PROGRAM LD_Motor\nVAR\n xStart, xStop, xMotor : BOOL;\nEND_VAR'"),
|
|
199
|
+
ladder: ladderSchema.optional(),
|
|
200
|
+
fbd: fbdSchema.optional(),
|
|
201
|
+
sfc: sfcSchema.optional(),
|
|
202
|
+
parent: z.string().optional().describe("Folder or object to create it under (default: the application)"),
|
|
203
|
+
}),
|
|
204
|
+
}, async (a) => run(async () => {
|
|
205
|
+
const kinds = [a.ladder && "ladder", a.fbd && "fbd", a.sfc && "sfc"].filter(Boolean);
|
|
206
|
+
if (kinds.length !== 1)
|
|
207
|
+
throw new Error("Give exactly one of ladder, fbd or sfc.");
|
|
208
|
+
const head = /^\s*(?:\{[^}]*\}\s*)*(PROGRAM|FUNCTION_BLOCK)\s+([A-Za-z_][A-Za-z0-9_]*)/i.exec(a.declaration);
|
|
209
|
+
if (!head)
|
|
210
|
+
throw new Error("The declaration must start with PROGRAM or FUNCTION_BLOCK and the name.");
|
|
211
|
+
if (head[2].toLowerCase() !== a.name.toLowerCase())
|
|
212
|
+
throw new Error(`The declaration names ${head[2]}, not ${a.name}.`);
|
|
213
|
+
const pouType = head[1].toUpperCase() === "PROGRAM" ? "program" : "functionBlock";
|
|
214
|
+
if (a.sfc) {
|
|
215
|
+
const p = sfcProblems(a.sfc);
|
|
216
|
+
if (p.length)
|
|
217
|
+
throw new Error(p.join("\n"));
|
|
218
|
+
}
|
|
219
|
+
const xml = a.ladder ? ladderXml(a.name, pouType, a.ladder) : a.fbd ? fbdXml(a.name, pouType, a.fbd) : sfcXml(a.name, pouType, a.sfc);
|
|
220
|
+
const r = await ctx.bridge.call("object.import_xml", { parent: a.parent, xml, save: false }, { timeoutMs: 120_000 });
|
|
221
|
+
const path = r.added[0];
|
|
222
|
+
await ctx.bridge.call("object.write", { path, declaration: a.declaration, save: ctx.autosave });
|
|
223
|
+
return `Created ${path} in ${kinds[0] === "ladder" ? "ladder (LD)" : kinds[0] === "fbd" ? "FBD" : "SFC"}${a.sfc ? ` with ${a.sfc.steps.length} steps` : ""}. Compile to check it, and call it from a task (configure_task) or another POU.`;
|
|
224
|
+
}));
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=graphical.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphical.js","sourceRoot":"","sources":["../../src/codesys/graphical.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ActionResult, RegisterAction } from "../actions.js";
|
|
2
|
+
import type { AppContext } from "../tools.js";
|
|
3
|
+
interface Var {
|
|
4
|
+
name: string;
|
|
5
|
+
type: string;
|
|
6
|
+
section: "input" | "output" | "other";
|
|
7
|
+
comment?: string;
|
|
8
|
+
hidden?: boolean;
|
|
9
|
+
init?: string;
|
|
10
|
+
}
|
|
11
|
+
interface Sig {
|
|
12
|
+
name: string;
|
|
13
|
+
kind?: string;
|
|
14
|
+
library?: string;
|
|
15
|
+
comment?: string;
|
|
16
|
+
variables?: Var[];
|
|
17
|
+
members?: string[];
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
20
|
+
/** A library doc comment without its reStructuredText blocks (examples, ranges, images). */
|
|
21
|
+
export declare function plainComment(c?: string): string;
|
|
22
|
+
export declare function formatSignature(s: Sig): string;
|
|
23
|
+
export declare function registerLangActions(reg: RegisterAction, ctx: AppContext, run: (fn: () => Promise<string>) => Promise<ActionResult>): void;
|
|
24
|
+
/** "Line 3, Column 22 (Impl)" -> where the reference is. */
|
|
25
|
+
export declare function parseLocation(loc: string): {
|
|
26
|
+
line: number;
|
|
27
|
+
col?: number;
|
|
28
|
+
part: "declaration" | "implementation";
|
|
29
|
+
} | undefined;
|
|
30
|
+
/** Replaces the identifier at (or after) each location; locations on one line go right to left. */
|
|
31
|
+
export declare function renameAt(text: string, spots: {
|
|
32
|
+
line: number;
|
|
33
|
+
col?: number;
|
|
34
|
+
}[], oldName: string, newName: string): {
|
|
35
|
+
text: string;
|
|
36
|
+
done: number;
|
|
37
|
+
};
|
|
38
|
+
export declare function registerRenameAction(reg: RegisterAction, ctx: AppContext, run: (fn: () => Promise<string>) => Promise<ActionResult>): void;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What CODESYS's compiler knows about names: the interface of any POU or type,
|
|
3
|
+
* including FBs in compiled libraries (TON, MC_MoveAbsolute, SysFileOpen...),
|
|
4
|
+
* and where a name is read, written or called. See watcher/mcp_lang.py.
|
|
5
|
+
*/
|
|
6
|
+
import * as z from "zod/v4";
|
|
7
|
+
/** A library doc comment without its reStructuredText blocks (examples, ranges, images). */
|
|
8
|
+
export function plainComment(c) {
|
|
9
|
+
return (c ?? "").split(/\s\.\.\s|^\.\.\s/)[0].trim();
|
|
10
|
+
}
|
|
11
|
+
export function formatSignature(s) {
|
|
12
|
+
if (s.error)
|
|
13
|
+
return `${s.name}: ${s.error}`;
|
|
14
|
+
const head = `${s.name} (${s.kind ?? "?"}${s.library ? `, ${s.library}` : ", this project"})${plainComment(s.comment) ? `: ${plainComment(s.comment)}` : ""}`;
|
|
15
|
+
const shown = (s.variables ?? []).filter((v) => !v.hidden);
|
|
16
|
+
const line = (v) => ` ${v.name} : ${v.type}${v.init ? ` := ${v.init}` : ""}${v.comment ? ` // ${v.comment}` : ""}`;
|
|
17
|
+
const parts = [head];
|
|
18
|
+
const ins = shown.filter((v) => v.section === "input");
|
|
19
|
+
const outs = shown.filter((v) => v.section === "output");
|
|
20
|
+
const other = shown.filter((v) => v.section === "other");
|
|
21
|
+
if (ins.length)
|
|
22
|
+
parts.push("VAR_INPUT", ...ins.map(line));
|
|
23
|
+
if (outs.length)
|
|
24
|
+
parts.push("VAR_OUTPUT", ...outs.map(line));
|
|
25
|
+
if (other.length)
|
|
26
|
+
parts.push("Other variables (in/out, locals)", ...other.map(line));
|
|
27
|
+
const hidden = (s.variables ?? []).filter((v) => v.hidden).map((v) => v.name);
|
|
28
|
+
if (hidden.length)
|
|
29
|
+
parts.push(`Hidden (internal): ${hidden.join(", ")}`);
|
|
30
|
+
if (s.members?.length)
|
|
31
|
+
parts.push(`Methods, properties and actions: ${s.members.join(", ")}`);
|
|
32
|
+
return parts.join("\n");
|
|
33
|
+
}
|
|
34
|
+
export function registerLangActions(reg, ctx, run) {
|
|
35
|
+
const b = ctx.bridge;
|
|
36
|
+
reg("get_signature", {
|
|
37
|
+
description: "The real interface of POUs and types as CODESYS's compiler sees them: inputs, outputs, other variables with types, initial values and doc comments, and methods/properties. Works for the project's own code and for FBs in any referenced library, compiled ones included (TON, CTU, R_TRIG, MC_MoveAbsolute, SysFileOpen...). Use it before calling a library FB instead of guessing its parameters. Builds the application first if the names aren't known yet.",
|
|
38
|
+
inputSchema: z.object({ names: z.array(z.string()).min(1).max(20).describe("POU or type names, e.g. ['TON', 'FB_Pump']") }),
|
|
39
|
+
}, async ({ names }) => run(async () => {
|
|
40
|
+
const r = await b.call("lang.signature", { names }, { timeoutMs: 300_000 });
|
|
41
|
+
return r.signatures.map(formatSignature).join("\n\n");
|
|
42
|
+
}));
|
|
43
|
+
reg("find_references", {
|
|
44
|
+
description: "Where a variable, POU or type is used in the application: each read, write and call with the POU, line and column, from CODESYS's cross-reference list. Builds first. Use it before renaming or changing an interface.",
|
|
45
|
+
inputSchema: z.object({
|
|
46
|
+
name: z.string().describe("e.g. 'xRunning', 'fbPump', 'FB_Pump'"),
|
|
47
|
+
kind: z.enum(["variable", "pou", "type"]).default("variable"),
|
|
48
|
+
}),
|
|
49
|
+
}, async ({ name, kind }) => run(async () => {
|
|
50
|
+
const r = await b.call("lang.xref", { name, kind }, { timeoutMs: 300_000 });
|
|
51
|
+
if (!r.references.length)
|
|
52
|
+
return `No references to ${name} (as a ${kind}).`;
|
|
53
|
+
return [`${r.references.length} reference${r.references.length === 1 ? "" : "s"} to ${name}:`, ...r.references.map((x) => ` ${x.access.padEnd(11)} ${x.pou} ${x.location} ${x.text}`)].join("\n");
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
/** "Line 3, Column 22 (Impl)" -> where the reference is. */
|
|
57
|
+
export function parseLocation(loc) {
|
|
58
|
+
const m = /Line\s+(\d+)(?:,\s*Column\s+(\d+))?\s*\((Decl|Impl)\)/i.exec(loc);
|
|
59
|
+
if (!m)
|
|
60
|
+
return undefined;
|
|
61
|
+
return { line: Number(m[1]), ...(m[2] ? { col: Number(m[2]) } : {}), part: /^decl/i.test(m[3]) ? "declaration" : "implementation" };
|
|
62
|
+
}
|
|
63
|
+
const word = (name) => new RegExp(`(?<![A-Za-z0-9_])${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![A-Za-z0-9_])`, "gi");
|
|
64
|
+
/** Replaces the identifier at (or after) each location; locations on one line go right to left. */
|
|
65
|
+
export function renameAt(text, spots, oldName, newName) {
|
|
66
|
+
const eol = text.includes("\r\n") ? "\r\n" : "\n";
|
|
67
|
+
const lines = text.split(/\r?\n/);
|
|
68
|
+
let done = 0;
|
|
69
|
+
const sorted = [...spots].sort((a, b) => b.line - a.line || (b.col ?? 0) - (a.col ?? 0));
|
|
70
|
+
const seen = new Set();
|
|
71
|
+
for (const s of sorted) {
|
|
72
|
+
const key = `${s.line}:${s.col ?? 0}`;
|
|
73
|
+
if (seen.has(key))
|
|
74
|
+
continue;
|
|
75
|
+
seen.add(key);
|
|
76
|
+
const l = lines[s.line - 1];
|
|
77
|
+
if (l === undefined)
|
|
78
|
+
continue;
|
|
79
|
+
const re = word(oldName);
|
|
80
|
+
re.lastIndex = Math.max(0, (s.col ?? 1) - 1);
|
|
81
|
+
const m = re.exec(l);
|
|
82
|
+
if (!m)
|
|
83
|
+
continue;
|
|
84
|
+
lines[s.line - 1] = l.slice(0, m.index) + newName + l.slice(m.index + m[0].length);
|
|
85
|
+
done++;
|
|
86
|
+
}
|
|
87
|
+
return { text: lines.join(eol), done };
|
|
88
|
+
}
|
|
89
|
+
export function registerRenameAction(reg, ctx, run) {
|
|
90
|
+
reg("rename_symbol", {
|
|
91
|
+
description: "Rename a variable or a POU everywhere it is used, from CODESYS's cross-references: the declaration, every read, write and call, and instance declarations of a renamed FB. kind 'variable': name is the variable, owner the POU or GVL that declares it (refused when several objects declare the same name). kind 'pou': owner is the POU to rename. Compile afterwards. Graphical bodies that need changes are reported, not changed.",
|
|
92
|
+
inputSchema: z.object({
|
|
93
|
+
kind: z.enum(["variable", "pou"]),
|
|
94
|
+
owner: z.string().describe("POU or GVL that declares the variable, or the POU to rename, e.g. 'FB_Pump'"),
|
|
95
|
+
name: z.string().optional().describe("The variable's current name (kind 'variable')"),
|
|
96
|
+
newName: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/),
|
|
97
|
+
}),
|
|
98
|
+
}, async ({ kind, owner, name, newName }) => run(async () => {
|
|
99
|
+
if (kind === "variable" && !name)
|
|
100
|
+
throw new Error("Give the variable's name.");
|
|
101
|
+
const b = ctx.bridge;
|
|
102
|
+
const oldName = kind === "pou" ? owner.split("/").pop() : name;
|
|
103
|
+
const r = await b.call("lang.xref", { name: oldName, kind: kind === "pou" ? "pou" : "variable" }, { timeoutMs: 300_000 });
|
|
104
|
+
let refs = r.references;
|
|
105
|
+
if (kind === "variable") {
|
|
106
|
+
const decls = refs.filter((x) => /^declaration$/i.test(x.access));
|
|
107
|
+
const owners = [...new Set(decls.map((x) => x.pou.toLowerCase()))];
|
|
108
|
+
if (owners.length > 1)
|
|
109
|
+
throw new Error(`Several objects declare ${oldName} (${owners.join(", ")}); renaming would be ambiguous. Rename it in ${owner} by hand with write_object, or rename the others first.`);
|
|
110
|
+
if (owners.length === 1 && owners[0] !== owner.split("/").pop().toLowerCase())
|
|
111
|
+
throw new Error(`${oldName} is declared in ${decls[0].pou}, not in ${owner}.`);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// Only the type name's own uses: declarations of instances (Type) and calls of functions or programs.
|
|
115
|
+
refs = refs.filter((x) => x.text.toLowerCase().startsWith(oldName.toLowerCase()));
|
|
116
|
+
}
|
|
117
|
+
const byObj = new Map();
|
|
118
|
+
for (const x of refs) {
|
|
119
|
+
const loc = parseLocation(x.location);
|
|
120
|
+
if (!loc)
|
|
121
|
+
continue;
|
|
122
|
+
const path = x.pou.replace(/\./g, "/");
|
|
123
|
+
const e = byObj.get(path) ?? { declaration: [], implementation: [] };
|
|
124
|
+
e[loc.part].push({ line: loc.line, ...(loc.col ? { col: loc.col } : {}) });
|
|
125
|
+
byObj.set(path, e);
|
|
126
|
+
}
|
|
127
|
+
if (kind === "pou") {
|
|
128
|
+
const e = byObj.get(owner) ?? { declaration: [], implementation: [] };
|
|
129
|
+
e.declaration.push({ line: 1 });
|
|
130
|
+
byObj.set(owner, e);
|
|
131
|
+
}
|
|
132
|
+
if (!byObj.size)
|
|
133
|
+
return `Nothing to rename: ${oldName} isn't used.`;
|
|
134
|
+
const objs = (await b.call("objects.read", { paths: [...byObj.keys()] })).objects;
|
|
135
|
+
const changed = [];
|
|
136
|
+
const skipped = [];
|
|
137
|
+
let count = 0;
|
|
138
|
+
for (const o of objs) {
|
|
139
|
+
const spots = byObj.get(o.path) ?? byObj.get([...byObj.keys()].find((k) => k.toLowerCase() === o.path.toLowerCase()) ?? "");
|
|
140
|
+
if (!spots || o.error) {
|
|
141
|
+
skipped.push(`${o.path}${o.error ? ` (${o.error})` : ""}`);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const args = { path: o.path };
|
|
145
|
+
if (spots.declaration.length && o.declaration !== undefined) {
|
|
146
|
+
const d = renameAt(o.declaration, spots.declaration, oldName, newName);
|
|
147
|
+
if (d.done)
|
|
148
|
+
(args.declaration = d.text), (count += d.done);
|
|
149
|
+
}
|
|
150
|
+
if (spots.implementation.length) {
|
|
151
|
+
if (o.implementation === undefined) {
|
|
152
|
+
skipped.push(`${o.path} (graphical body)`);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const im = renameAt(o.implementation, spots.implementation, oldName, newName);
|
|
156
|
+
if (im.done)
|
|
157
|
+
(args.implementation = im.text), (count += im.done);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (args.declaration || args.implementation) {
|
|
161
|
+
await b.call("object.write", { ...args, save: false });
|
|
162
|
+
changed.push(o.path);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (kind === "pou")
|
|
166
|
+
await b.call("object.rename", { path: owner, new_name: newName, save: false });
|
|
167
|
+
await b.call("project.save", {}).catch(() => undefined);
|
|
168
|
+
return [
|
|
169
|
+
`Renamed ${kind === "pou" ? owner : `${owner}.${oldName}`} to ${newName}: ${count} occurrence(s) in ${changed.length} object(s) (${changed.join(", ")}).`,
|
|
170
|
+
skipped.length ? `Not changed (do these by hand): ${skipped.join(", ")}.` : "",
|
|
171
|
+
"Compile to check.",
|
|
172
|
+
]
|
|
173
|
+
.filter(Boolean)
|
|
174
|
+
.join("\n");
|
|
175
|
+
}));
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lang.js","sourceRoot":"","sources":["../../src/codesys/lang.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAsB5B,4FAA4F;AAC5F,MAAM,UAAU,YAAY,CAAC,CAAU;IACrC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,CAAM;IACpC,IAAI,CAAC,CAAC,KAAK;QAAE,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAC5C,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,gBAAgB,IAAI,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC9J,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,CAAC,CAAM,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC1H,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;IACrB,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;IACzD,IAAI,GAAG,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,IAAI,IAAI,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7D,IAAI,KAAK,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,kCAAkC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9E,IAAI,MAAM,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,sBAAsB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzE,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9F,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,GAAmB,EAAE,GAAe,EAAE,GAAyD;IACjI,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IACrB,GAAG,CACD,eAAe,EACf;QACE,WAAW,EACT,ocAAoc;QACtc,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,4CAA4C,CAAC,EAAE,CAAC;KAC5H,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAClB,GAAG,CAAC,KAAK,IAAI,EAAE;QACb,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAwB,gBAAgB,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QACnG,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxD,CAAC,CAAC,CACL,CAAC;IACF,GAAG,CACD,iBAAiB,EACjB;QACE,WAAW,EAAE,wNAAwN;QACrO,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;YACjE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;SAC9D,CAAC;KACH,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CACvB,GAAG,CAAC,KAAK,IAAI,EAAE;QACb,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAoF,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/J,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM;YAAE,OAAO,oBAAoB,IAAI,UAAU,IAAI,IAAI,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,aAAa,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvM,CAAC,CAAC,CACL,CAAC;AACJ,CAAC;AASD,4DAA4D;AAC5D,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,CAAC,GAAG,wDAAwD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7E,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC;AACvI,CAAC;AAED,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,oBAAoB,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;AAEnI,mGAAmG;AACnG,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAuC,EAAE,OAAe,EAAE,OAAe;IAC9G,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACzF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,KAAK,SAAS;YAAE,SAAS;QAC9B,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACnF,IAAI,EAAE,CAAC;IACT,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAmB,EAAE,GAAe,EAAE,GAAyD;IAClI,GAAG,CACD,eAAe,EACf;QACE,WAAW,EACT,yaAAya;QAC3a,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACjC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6EAA6E,CAAC;YACzG,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;YACrF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,0BAA0B,CAAC;SACtD,CAAC;KACH,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CACvC,GAAG,CAAC,KAAK,IAAI,EAAE;QACb,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/E,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;QACrB,MAAM,OAAO,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC,CAAC,CAAC,IAAK,CAAC;QACjE,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAwB,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QACjJ,IAAI,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC;QACxB,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YAClE,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;YACnE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,OAAO,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,gDAAgD,KAAK,yDAAyD,CAAC,CAAC;YAC/M,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC,WAAW,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,mBAAmB,KAAK,CAAC,CAAC,CAAE,CAAC,GAAG,YAAY,KAAK,GAAG,CAAC,CAAC;QAClK,CAAC;aAAM,CAAC;YACN,sGAAsG;YACtG,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,GAAG,EAA+G,CAAC;QACrI,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACtC,IAAI,CAAC,GAAG;gBAAE,SAAS;YACnB,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACvC,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;YACrE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAC3E,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACrB,CAAC;QACD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnB,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;YACtE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;YAChC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI;YAAE,OAAO,sBAAsB,OAAO,cAAc,CAAC;QACpE,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAiG,cAAc,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAClL,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5H,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC3D,SAAS;YACX,CAAC;YACD,MAAM,IAAI,GAA2B,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACtD,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC5D,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;gBACvE,IAAI,CAAC,CAAC,IAAI;oBAAE,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;gBAChC,IAAI,CAAC,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;oBACnC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,mBAAmB,CAAC,CAAC;gBAC7C,CAAC;qBAAM,CAAC;oBACN,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;oBAC9E,IAAI,EAAE,CAAC,IAAI;wBAAE,CAAC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;gBACnE,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC5C,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;gBACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QACD,IAAI,IAAI,KAAK,KAAK;YAAE,MAAM,CAAC,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACnG,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACxD,OAAO;YACL,WAAW,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,OAAO,EAAE,OAAO,OAAO,KAAK,KAAK,qBAAqB,OAAO,CAAC,MAAM,eAAe,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACzJ,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,mCAAmC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAC9E,mBAAmB;SACpB;aACE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests in CODESYS's simulation: test cases of steps (write or force
|
|
3
|
+
* inputs, run cycles or wait, check values), run in order, reported as a table.
|
|
4
|
+
*/
|
|
5
|
+
import * as z from "zod/v4";
|
|
6
|
+
import type { ActionResult, RegisterAction } from "../actions.js";
|
|
7
|
+
import type { AppContext } from "../tools.js";
|
|
8
|
+
declare const expectation: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
9
|
+
op: z.ZodEnum<{
|
|
10
|
+
"<": "<";
|
|
11
|
+
"<=": "<=";
|
|
12
|
+
"<>": "<>";
|
|
13
|
+
"=": "=";
|
|
14
|
+
">": ">";
|
|
15
|
+
">=": ">=";
|
|
16
|
+
}>;
|
|
17
|
+
value: z.ZodNumber;
|
|
18
|
+
tolerance: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
}, z.core.$strip>]>;
|
|
20
|
+
export declare const testSchema: z.ZodObject<{
|
|
21
|
+
cases: z.ZodArray<z.ZodObject<{
|
|
22
|
+
name: z.ZodString;
|
|
23
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
24
|
+
write: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
25
|
+
force: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
26
|
+
unforce: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
27
|
+
cycles: z.ZodOptional<z.ZodNumber>;
|
|
28
|
+
waitMs: z.ZodOptional<z.ZodNumber>;
|
|
29
|
+
expect: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
30
|
+
op: z.ZodEnum<{
|
|
31
|
+
"<": "<";
|
|
32
|
+
"<=": "<=";
|
|
33
|
+
"<>": "<>";
|
|
34
|
+
"=": "=";
|
|
35
|
+
">": ">";
|
|
36
|
+
">=": ">=";
|
|
37
|
+
}>;
|
|
38
|
+
value: z.ZodNumber;
|
|
39
|
+
tolerance: z.ZodOptional<z.ZodNumber>;
|
|
40
|
+
}, z.core.$strip>]>>>;
|
|
41
|
+
}, z.core.$strip>>;
|
|
42
|
+
}, z.core.$strip>>;
|
|
43
|
+
}, z.core.$strip>;
|
|
44
|
+
type Expectation = z.infer<typeof expectation>;
|
|
45
|
+
/** Whether a read value meets an expectation; booleans and numbers compare by value. */
|
|
46
|
+
export declare function check(raw: string | undefined, exp: Expectation): boolean;
|
|
47
|
+
export declare function registerSimTestAction(reg: RegisterAction, ctx: AppContext, run: (fn: () => Promise<string>) => Promise<ActionResult>): void;
|
|
48
|
+
export {};
|