@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
package/dist/hmi/spec.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMI screens: what the model writes. A screen is a grid of tiles; each tile is
|
|
3
|
+
* one widget bound to PLC variables (full instance paths, e.g. "PLC_PRG.fbPump.xRunning").
|
|
4
|
+
* The same description renders as a live HTML/SVG screen in the browser, as a
|
|
5
|
+
* screenshot for the model, and as a native CODESYS visualization.
|
|
6
|
+
*/
|
|
7
|
+
import * as z from "zod/v4";
|
|
8
|
+
import { routeProblems } from "./route.js";
|
|
9
|
+
const v = z.string().min(1).describe("PLC variable, full path, e.g. 'PLC_PRG.fbPump.xRunning' or 'GVL.rLevel'");
|
|
10
|
+
const tone = z.enum(["accent", "ok", "warn", "alarm", "neutral"]);
|
|
11
|
+
const num = z.number();
|
|
12
|
+
/** A colour band for a value: from `from` upwards the value shows in `tone`. */
|
|
13
|
+
const band = z.object({ from: num, tone });
|
|
14
|
+
const at = z
|
|
15
|
+
.tuple([z.number().int().min(1), z.number().int().min(1), z.number().int().min(1), z.number().int().min(1)])
|
|
16
|
+
.describe("[column, row, width, height] in grid cells, 1-based (the grid is 12 columns by 8 rows unless the screen sets grid)");
|
|
17
|
+
const base = { at, title: z.string().optional().describe("Tile title") };
|
|
18
|
+
const id = z.string().optional().describe("Name pipes connect to (default: the label, e.g. 'P-101')");
|
|
19
|
+
const faceplate = z
|
|
20
|
+
.object({
|
|
21
|
+
title: z.string().optional(),
|
|
22
|
+
auto: v.optional().describe("BOOL: automatic mode (a switch)"),
|
|
23
|
+
start: v.optional().describe("BOOL tapped by a Start button"),
|
|
24
|
+
stop: v.optional().describe("BOOL tapped by a Stop button"),
|
|
25
|
+
open: v.optional().describe("BOOL tapped by an Open button (valves)"),
|
|
26
|
+
close: v.optional().describe("BOOL tapped by a Close button (valves)"),
|
|
27
|
+
reset: v.optional().describe("BOOL tapped by a Reset button"),
|
|
28
|
+
values: z.array(z.object({ label: z.string(), value: v, unit: z.string().optional(), decimals: z.number().int().optional() })).max(6).optional(),
|
|
29
|
+
setpoint: z.object({ label: z.string().optional(), variable: v, min: num, max: num, step: num.optional(), unit: z.string().optional() }).optional(),
|
|
30
|
+
})
|
|
31
|
+
.describe("A popup opened by clicking the symbol: mode switch, Start/Stop or Open/Close, Reset, values and a setpoint");
|
|
32
|
+
const end = z
|
|
33
|
+
.union([z.string().regex(/^[^.]+\.[a-z-]+$/), z.tuple([num, num])])
|
|
34
|
+
.describe("A port 'P-101.out' (see the ports of each symbol) or a point [x, y] at the diagram's edge");
|
|
35
|
+
/** Things placed on a process (mimic) diagram, in a 0..100 x 0..100 box scaled to the tile. */
|
|
36
|
+
const processItem = z.discriminatedUnion("type", [
|
|
37
|
+
z.object({ type: z.literal("tank"), id, x: num, y: num, w: num, h: num, level: v, max: num.default(100), unit: z.string().optional(), label: z.string().optional(), bands: z.array(band).optional() }),
|
|
38
|
+
z.object({ type: z.literal("pump"), id, x: num, y: num, size: num.default(12), running: v, fault: v.optional(), label: z.string().optional(), faceplate: faceplate.optional() }),
|
|
39
|
+
z.object({ type: z.literal("fan"), id, x: num, y: num, size: num.default(12), running: v, label: z.string().optional(), faceplate: faceplate.optional() }),
|
|
40
|
+
z.object({ type: z.literal("valve"), id, x: num, y: num, size: num.default(8), open: v, vertical: z.boolean().optional(), label: z.string().optional(), faceplate: faceplate.optional() }),
|
|
41
|
+
z.object({ type: z.literal("junction"), id: z.string(), x: num, y: num }).describe("A tee or bend that several pipes meet at"),
|
|
42
|
+
z
|
|
43
|
+
.object({
|
|
44
|
+
type: z.literal("pipe"),
|
|
45
|
+
from: end.optional(),
|
|
46
|
+
to: end.optional(),
|
|
47
|
+
via: z.array(z.tuple([num, num])).optional().describe("Points the pipe must pass, in order"),
|
|
48
|
+
points: z.array(z.tuple([num, num])).min(2).optional().describe("Raw points instead of from/to (avoid: ends rarely meet the symbols)"),
|
|
49
|
+
flow: v.optional().describe("BOOL: animate flow while TRUE"),
|
|
50
|
+
})
|
|
51
|
+
.refine((p) => (p.from && p.to) || p.points, { message: "a pipe needs from and to (ports or points), or points" }),
|
|
52
|
+
z.object({ type: z.literal("sensor"), x: num, y: num, value: v, unit: z.string().optional(), label: z.string().optional(), decimals: z.number().int().optional() }),
|
|
53
|
+
z.object({ type: z.literal("lamp"), x: num, y: num, on: v, tone: tone.optional(), label: z.string().optional() }),
|
|
54
|
+
z.object({ type: z.literal("label"), x: num, y: num, text: z.string() }),
|
|
55
|
+
]);
|
|
56
|
+
export const widgetSchema = z.discriminatedUnion("type", [
|
|
57
|
+
z.object({ type: z.literal("value"), ...base, value: v, unit: z.string().optional(), decimals: z.number().int().optional(), bands: z.array(band).optional(), trend: z.boolean().optional().describe("Small sparkline under the value") }),
|
|
58
|
+
z.object({ type: z.literal("gauge"), ...base, value: v, min: num.default(0), max: num.default(100), unit: z.string().optional(), decimals: z.number().int().optional(), bands: z.array(band).optional() }),
|
|
59
|
+
z.object({ type: z.literal("bar"), ...base, value: v, min: num.default(0), max: num.default(100), unit: z.string().optional(), vertical: z.boolean().optional(), bands: z.array(band).optional() }),
|
|
60
|
+
z.object({ type: z.literal("status"), ...base, items: z.array(z.object({ label: z.string(), on: v, tone: tone.optional(), invert: z.boolean().optional() })).min(1) }),
|
|
61
|
+
z.object({
|
|
62
|
+
type: z.literal("buttons"),
|
|
63
|
+
...base,
|
|
64
|
+
items: z
|
|
65
|
+
.array(z.object({
|
|
66
|
+
label: z.string(),
|
|
67
|
+
variable: v,
|
|
68
|
+
action: z.enum(["tap", "toggle", "set", "reset"]).default("tap").describe("tap: TRUE while pressed; toggle: flips; set: writes TRUE; reset: writes FALSE"),
|
|
69
|
+
tone: tone.optional(),
|
|
70
|
+
}))
|
|
71
|
+
.min(1),
|
|
72
|
+
}),
|
|
73
|
+
z.object({ type: z.literal("switch"), ...base, variable: v, label: z.string().optional() }),
|
|
74
|
+
z.object({ type: z.literal("setpoint"), ...base, variable: v, min: num, max: num, step: num.optional(), unit: z.string().optional() }),
|
|
75
|
+
z.object({
|
|
76
|
+
type: z.literal("trend"),
|
|
77
|
+
...base,
|
|
78
|
+
series: z.array(z.object({ value: v, label: z.string().optional() })).min(1).max(6),
|
|
79
|
+
min: num.optional(),
|
|
80
|
+
max: num.optional(),
|
|
81
|
+
seconds: z.number().int().min(5).max(3600).default(60),
|
|
82
|
+
}),
|
|
83
|
+
z.object({ type: z.literal("alarms"), ...base, items: z.array(z.object({ active: v, text: z.string(), severity: z.enum(["info", "warning", "alarm"]).default("alarm") })).min(1) }),
|
|
84
|
+
z.object({ type: z.literal("text"), ...base, text: z.string() }),
|
|
85
|
+
z.object({ type: z.literal("process"), ...base, items: z.array(processItem).min(1) }),
|
|
86
|
+
]);
|
|
87
|
+
export const screenSchema = z.object({
|
|
88
|
+
name: z.string().regex(/^[A-Za-z][A-Za-z0-9_]*$/).describe("Screen name, e.g. 'Overview'"),
|
|
89
|
+
title: z.string().describe("Shown in the header"),
|
|
90
|
+
subtitle: z.string().optional(),
|
|
91
|
+
theme: z.enum(["dark", "light"]).default("dark"),
|
|
92
|
+
size: z.enum(["1280x720", "1920x1080", "1024x768", "800x480"]).default("1280x720").describe("Panel resolution; use the same on every page"),
|
|
93
|
+
grid: z.tuple([z.number().int().min(2).max(24), z.number().int().min(2).max(16)]).default([12, 8]).describe("[columns, rows]"),
|
|
94
|
+
widgets: z.array(widgetSchema).min(1),
|
|
95
|
+
});
|
|
96
|
+
/** Every alarm on any screen, for the header's alarm count. */
|
|
97
|
+
export function allAlarms(screens) {
|
|
98
|
+
const seen = new Map();
|
|
99
|
+
for (const s of screens)
|
|
100
|
+
for (const w of s.widgets)
|
|
101
|
+
if (w.type === "alarms")
|
|
102
|
+
for (const a of w.items)
|
|
103
|
+
seen.set(a.active, a);
|
|
104
|
+
return [...seen.values()];
|
|
105
|
+
}
|
|
106
|
+
/** Every PLC variable a screen reads or writes. */
|
|
107
|
+
export function screenVariables(s) {
|
|
108
|
+
const out = new Set();
|
|
109
|
+
const add = (x) => x && out.add(x);
|
|
110
|
+
for (const w of s.widgets) {
|
|
111
|
+
switch (w.type) {
|
|
112
|
+
case "value":
|
|
113
|
+
case "gauge":
|
|
114
|
+
case "bar":
|
|
115
|
+
add(w.value);
|
|
116
|
+
break;
|
|
117
|
+
case "status":
|
|
118
|
+
w.items.forEach((i) => add(i.on));
|
|
119
|
+
break;
|
|
120
|
+
case "buttons":
|
|
121
|
+
w.items.forEach((i) => add(i.variable));
|
|
122
|
+
break;
|
|
123
|
+
case "switch":
|
|
124
|
+
case "setpoint":
|
|
125
|
+
add(w.variable);
|
|
126
|
+
break;
|
|
127
|
+
case "trend":
|
|
128
|
+
w.series.forEach((i) => add(i.value));
|
|
129
|
+
break;
|
|
130
|
+
case "alarms":
|
|
131
|
+
w.items.forEach((i) => add(i.active));
|
|
132
|
+
break;
|
|
133
|
+
case "process":
|
|
134
|
+
for (const p of w.items) {
|
|
135
|
+
if ("faceplate" in p && p.faceplate) {
|
|
136
|
+
const f = p.faceplate;
|
|
137
|
+
[f.auto, f.start, f.stop, f.open, f.close, f.reset, f.setpoint?.variable].forEach(add);
|
|
138
|
+
f.values?.forEach((x) => add(x.value));
|
|
139
|
+
}
|
|
140
|
+
if (p.type === "tank")
|
|
141
|
+
add(p.level);
|
|
142
|
+
else if (p.type === "pump")
|
|
143
|
+
(add(p.running), add(p.fault));
|
|
144
|
+
else if (p.type === "fan")
|
|
145
|
+
add(p.running);
|
|
146
|
+
else if (p.type === "valve")
|
|
147
|
+
add(p.open);
|
|
148
|
+
else if (p.type === "pipe")
|
|
149
|
+
add(p.flow);
|
|
150
|
+
else if (p.type === "sensor")
|
|
151
|
+
add(p.value);
|
|
152
|
+
else if (p.type === "lamp")
|
|
153
|
+
add(p.on);
|
|
154
|
+
}
|
|
155
|
+
break;
|
|
156
|
+
default:
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return [...out];
|
|
161
|
+
}
|
|
162
|
+
/** Overlapping or out-of-grid tiles, as readable problems (empty when the layout is fine). */
|
|
163
|
+
export function layoutProblems(s) {
|
|
164
|
+
const [cols, rows] = s.grid;
|
|
165
|
+
const out = [];
|
|
166
|
+
const cells = new Map();
|
|
167
|
+
s.widgets.forEach((w, i) => {
|
|
168
|
+
const [c, r, wd, ht] = w.at;
|
|
169
|
+
const name = `widget ${i + 1} (${w.type}${w.title ? ` "${w.title}"` : ""})`;
|
|
170
|
+
if (c + wd - 1 > cols || r + ht - 1 > rows)
|
|
171
|
+
out.push(`${name} at [${w.at.join(", ")}] runs past the ${cols}x${rows} grid.`);
|
|
172
|
+
for (let x = c; x < c + wd; x++)
|
|
173
|
+
for (let y = r; y < r + ht; y++) {
|
|
174
|
+
const k = `${x},${y}`;
|
|
175
|
+
const other = cells.get(k);
|
|
176
|
+
if (other !== undefined && other !== i) {
|
|
177
|
+
out.push(`${name} overlaps widget ${other + 1} at cell ${k}.`);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
cells.set(k, i);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
s.widgets.forEach((w, i) => {
|
|
184
|
+
if (w.type === "process")
|
|
185
|
+
for (const msg of routeProblems(w.items))
|
|
186
|
+
out.push(`widget ${i + 1} (process): ${msg}`);
|
|
187
|
+
});
|
|
188
|
+
return out;
|
|
189
|
+
}
|
|
190
|
+
export { plcValue } from "./value.js";
|
|
191
|
+
//# sourceMappingURL=spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/hmi/spec.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,yEAAyE,CAAC,CAAC;AAChH,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;AAClE,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;AAEvB,gFAAgF;AAChF,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AAE3C,MAAM,EAAE,GAAG,CAAC;KACT,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;KAC3G,QAAQ,CAAC,oHAAoH,CAAC,CAAC;AAElI,MAAM,IAAI,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;AAEzE,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0DAA0D,CAAC,CAAC;AACtG,MAAM,SAAS,GAAG,CAAC;KAChB,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;IAC9D,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;IAC7D,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;IAC3D,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;IACrE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;IACtE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;IAC7D,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAChJ,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE;CACpJ,CAAC;KACD,QAAQ,CAAC,4GAA4G,CAAC,CAAC;AAC1H,MAAM,GAAG,GAAG,CAAC;KACV,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;KAClE,QAAQ,CAAC,2FAA2F,CAAC,CAAC;AAEzG,+FAA+F;AAC/F,MAAM,WAAW,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAC/C,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;IACtM,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC;IAChL,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC1J,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC1L,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,0CAA0C,CAAC;IAC9H,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QACvB,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE;QACpB,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE;QAClB,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;QAC5F,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qEAAqE,CAAC;QACtI,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;KAC7D,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,uDAAuD,EAAE,CAAC;IACpH,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC;IACnK,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC;IACjH,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;CACzE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IACvD,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC,EAAE,CAAC;IACzO,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC1M,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;IACnM,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACtK,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;QAC1B,GAAG,IAAI;QACP,KAAK,EAAE,CAAC;aACL,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;YACP,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;YACjB,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,+EAA+E,CAAC;YAC1J,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;SACtB,CAAC,CACH;aACA,GAAG,CAAC,CAAC,CAAC;KACV,CAAC;IACF,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC3F,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC;IACtI,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;QACxB,GAAG,IAAI;QACP,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACnF,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;QACnB,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;QACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;KACvD,CAAC;IACF,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACnL,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;IAChE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;CACtF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,QAAQ,CAAC,8BAA8B,CAAC;IAC1F,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;IACjD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAChD,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;IAC3I,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IAC9H,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CACtC,CAAC,CAAC;AAUH,+DAA+D;AAC/D,MAAM,UAAU,SAAS,CAAC,OAAiB;IACzC,MAAM,IAAI,GAAG,IAAI,GAAG,EAA8D,CAAC;IACnF,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO;YAAE,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;gBAAE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK;oBAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5H,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,eAAe,CAAC,CAAS;IACvC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,MAAM,GAAG,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QAC1B,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,OAAO,CAAC;YACb,KAAK,OAAO,CAAC;YACb,KAAK,KAAK;gBACR,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACb,MAAM;YACR,KAAK,QAAQ;gBACX,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAClC,MAAM;YACR,KAAK,SAAS;gBACZ,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACxC,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,UAAU;gBACb,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBAChB,MAAM;YACR,KAAK,OAAO;gBACV,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACtC,MAAM;YACR,KAAK,QAAQ;gBACX,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBACtC,MAAM;YACR,KAAK,SAAS;gBACZ,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;oBACxB,IAAI,WAAW,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;wBACpC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC;wBACtB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;wBACvF,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;oBACzC,CAAC;oBACD,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;wBAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;yBAC/B,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;wBAAE,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;yBACtD,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK;wBAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;yBACrC,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;wBAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;yBACpC,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;wBAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;yBACnC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;wBAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;yBACtC,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;wBAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACxC,CAAC;gBACD,MAAM;YACR;gBACE,MAAM;QACV,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;AAClB,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,cAAc,CAAC,CAAS;IACtC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IAC5B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACzB,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;QAC5E,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,IAAI,IAAI,IAAI,QAAQ,CAAC,CAAC;QAC5H,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;YAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC3B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;oBACvC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,oBAAoB,KAAK,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;oBAC/D,OAAO;gBACT,CAAC;gBACD,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAClB,CAAC;IACL,CAAC,CAAC,CAAC;IACH,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACzB,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;YAAE,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,eAAe,GAAG,EAAE,CAAC,CAAC;IACpH,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page templates: good layouts the model adapts (titles, variables) instead of
|
|
3
|
+
* starting from an empty grid. Variables are placeholders under 'PRG.'.
|
|
4
|
+
*/
|
|
5
|
+
import type { ScreenInput } from "./spec.js";
|
|
6
|
+
type Template = ScreenInput;
|
|
7
|
+
export declare const TEMPLATES: Record<string, {
|
|
8
|
+
use: string;
|
|
9
|
+
screen: Template;
|
|
10
|
+
}>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export const TEMPLATES = {
|
|
2
|
+
overview: {
|
|
3
|
+
use: "Plant overview: the process diagram large on the left, key values and status on the right, controls and a trend along the bottom.",
|
|
4
|
+
screen: {
|
|
5
|
+
name: "Overview",
|
|
6
|
+
title: "Plant overview",
|
|
7
|
+
subtitle: "Line A",
|
|
8
|
+
widgets: [
|
|
9
|
+
{
|
|
10
|
+
type: "process",
|
|
11
|
+
title: "Process",
|
|
12
|
+
at: [1, 1, 8, 5],
|
|
13
|
+
items: [
|
|
14
|
+
{ type: "tank", x: 20, y: 15, w: 18, h: 70, level: "PRG.rLevel", max: 100, unit: "%", label: "T-101" },
|
|
15
|
+
{ type: "pump", x: 58, y: 74.5, size: 11, running: "PRG.xPumpRunning", label: "P-101", faceplate: { auto: "PRG.xAuto", start: "PRG.xStart", stop: "PRG.xStop" } },
|
|
16
|
+
{ type: "valve", x: 82, y: 45, size: 7, open: "PRG.xValveOpen", vertical: true, label: "V-102" },
|
|
17
|
+
{ type: "pipe", from: [3, 74.5], to: "T-101.left", flow: "PRG.xInflow" },
|
|
18
|
+
{ type: "pipe", from: "T-101.right", to: "P-101.in", flow: "PRG.xPumpRunning" },
|
|
19
|
+
{ type: "pipe", from: "P-101.out", to: "V-102.in", flow: "PRG.xPumpRunning" },
|
|
20
|
+
{ type: "pipe", from: "V-102.out", to: [97, 15], flow: "PRG.xPumpRunning" },
|
|
21
|
+
{ type: "sensor", x: 89, y: 8, value: "PRG.rFlow", unit: "m³/h", label: "FT-103" },
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
{ type: "gauge", title: "Level", at: [9, 1, 4, 3], value: "PRG.rLevel", min: 0, max: 100, unit: "%", bands: [{ from: 0, tone: "accent" }, { from: 85, tone: "warn" }, { from: 95, tone: "alarm" }] },
|
|
25
|
+
{ type: "status", title: "Status", at: [9, 4, 2, 2], items: [{ label: "Pump running", on: "PRG.xPumpRunning" }, { label: "Auto", on: "PRG.xAuto", tone: "accent" }, { label: "Fault", on: "PRG.xFault", tone: "alarm" }] },
|
|
26
|
+
{ type: "value", title: "Flow", at: [11, 4, 2, 2], value: "PRG.rFlow", unit: "m³/h", decimals: 1, trend: true },
|
|
27
|
+
{ type: "trend", title: "Level and flow", at: [1, 6, 5, 3], series: [{ value: "PRG.rLevel", label: "Level %" }, { value: "PRG.rFlow", label: "Flow m³/h" }], seconds: 120 },
|
|
28
|
+
{ type: "buttons", title: "Pump", at: [6, 6, 3, 2], items: [{ label: "Start", variable: "PRG.xStart", tone: "ok" }, { label: "Stop", variable: "PRG.xStop" }] },
|
|
29
|
+
{ type: "switch", title: "Mode", at: [6, 8, 3, 1], variable: "PRG.xAuto", label: "Automatic" },
|
|
30
|
+
{ type: "setpoint", title: "Level setpoint", at: [9, 6, 2, 3], variable: "PRG.rSetpoint", min: 0, max: 100, step: 0.5, unit: "%" },
|
|
31
|
+
{ type: "alarms", title: "Alarms", at: [11, 6, 2, 3], items: [{ active: "PRG.xHighLevel", text: "High level T-101", severity: "warning" }, { active: "PRG.xFault", text: "Pump P-101 fault" }] },
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
unit: {
|
|
36
|
+
use: "One machine or unit in detail: its diagram, every measured value, its controls.",
|
|
37
|
+
screen: {
|
|
38
|
+
name: "Unit",
|
|
39
|
+
title: "Pump P-101",
|
|
40
|
+
widgets: [
|
|
41
|
+
{ type: "process", title: "P-101", at: [1, 1, 6, 6], items: [{ type: "pump", x: 50, y: 50, size: 22, running: "PRG.xPumpRunning", fault: "PRG.xFault", label: "P-101" }, { type: "pipe", from: [3, 50], to: "P-101.in", flow: "PRG.xPumpRunning" }, { type: "pipe", from: "P-101.out", to: [97, 50], flow: "PRG.xPumpRunning" }] },
|
|
42
|
+
{ type: "value", title: "Speed", at: [7, 1, 3, 2], value: "PRG.rSpeed", unit: "rpm", decimals: 0, trend: true },
|
|
43
|
+
{ type: "value", title: "Current", at: [10, 1, 3, 2], value: "PRG.rCurrent", unit: "A", decimals: 1, trend: true },
|
|
44
|
+
{ type: "gauge", title: "Motor temperature", at: [7, 3, 3, 4], value: "PRG.rTemp", min: 0, max: 120, unit: "°C", bands: [{ from: 0, tone: "ok" }, { from: 80, tone: "warn" }, { from: 100, tone: "alarm" }] },
|
|
45
|
+
{ type: "status", title: "Status", at: [10, 3, 3, 4], items: [{ label: "Running", on: "PRG.xPumpRunning" }, { label: "Ready", on: "PRG.xReady" }, { label: "Auto", on: "PRG.xAuto", tone: "accent" }, { label: "Fault", on: "PRG.xFault", tone: "alarm" }] },
|
|
46
|
+
{ type: "buttons", title: "Control", at: [1, 7, 6, 2], items: [{ label: "Start", variable: "PRG.xStart", tone: "ok" }, { label: "Stop", variable: "PRG.xStop" }, { label: "Reset", variable: "PRG.xReset", tone: "warn" }] },
|
|
47
|
+
{ type: "setpoint", title: "Speed setpoint", at: [7, 7, 6, 2], variable: "PRG.rSpeedSet", min: 0, max: 1500, step: 10, unit: "rpm" },
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
alarms: {
|
|
52
|
+
use: "Alarm page: the active alarms large, the signals behind them, and test or reset buttons.",
|
|
53
|
+
screen: {
|
|
54
|
+
name: "Alarms",
|
|
55
|
+
title: "Alarms",
|
|
56
|
+
widgets: [
|
|
57
|
+
{ type: "alarms", title: "Active alarms", at: [1, 1, 8, 8], items: [{ active: "PRG.xHighLevel", text: "High level T-101", severity: "warning" }, { active: "PRG.xFault", text: "Pump P-101 fault" }, { active: "PRG.xLowPressure", text: "Low inlet pressure", severity: "warning" }] },
|
|
58
|
+
{ type: "status", title: "Signals", at: [9, 1, 4, 5], items: [{ label: "High level", on: "PRG.xHighLevel", tone: "warn" }, { label: "Pump fault", on: "PRG.xFault", tone: "alarm" }, { label: "Low pressure", on: "PRG.xLowPressure", tone: "warn" }] },
|
|
59
|
+
{ type: "buttons", title: "Alarms", at: [9, 6, 4, 3], items: [{ label: "Reset", variable: "PRG.xReset", tone: "warn" }] },
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
trends: {
|
|
64
|
+
use: "Trend page: one large chart and the current values beside it.",
|
|
65
|
+
screen: {
|
|
66
|
+
name: "Trends",
|
|
67
|
+
title: "Trends",
|
|
68
|
+
widgets: [
|
|
69
|
+
{ type: "trend", title: "Process values", at: [1, 1, 9, 8], series: [{ value: "PRG.rLevel", label: "Level %" }, { value: "PRG.rFlow", label: "Flow m³/h" }], seconds: 300 },
|
|
70
|
+
{ type: "value", title: "Level", at: [10, 1, 3, 3], value: "PRG.rLevel", unit: "%", decimals: 1, trend: true },
|
|
71
|
+
{ type: "value", title: "Flow", at: [10, 4, 3, 3], value: "PRG.rFlow", unit: "m³/h", decimals: 1, trend: true },
|
|
72
|
+
{ type: "text", title: "Note", at: [10, 7, 3, 2], text: "History starts when the page opens." },
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
settings: {
|
|
77
|
+
use: "Settings page: setpoints, limits and modes the operator may change.",
|
|
78
|
+
screen: {
|
|
79
|
+
name: "Settings",
|
|
80
|
+
title: "Settings",
|
|
81
|
+
widgets: [
|
|
82
|
+
{ type: "setpoint", title: "Level setpoint", at: [1, 1, 4, 3], variable: "PRG.rSetpoint", min: 0, max: 100, step: 0.5, unit: "%" },
|
|
83
|
+
{ type: "setpoint", title: "High level limit", at: [5, 1, 4, 3], variable: "PRG.rHighLimit", min: 50, max: 100, step: 1, unit: "%" },
|
|
84
|
+
{ type: "setpoint", title: "Pump start delay", at: [9, 1, 4, 3], variable: "PRG.rStartDelay", min: 0, max: 60, step: 1, unit: "s" },
|
|
85
|
+
{ type: "switch", title: "Mode", at: [1, 4, 4, 1], variable: "PRG.xAuto", label: "Automatic" },
|
|
86
|
+
{ type: "switch", title: "Alarm horn", at: [5, 4, 4, 1], variable: "PRG.xHornEnabled", label: "Horn enabled" },
|
|
87
|
+
{ type: "text", title: "About", at: [1, 6, 12, 3], text: "Changes take effect at once. Settings that must survive a restart need persistent variables in the program." },
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/hmi/templates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ActionResult, RegisterAction } from "../actions.js";
|
|
2
|
+
import type { AppContext } from "../tools.js";
|
|
3
|
+
import { type HmiService } from "./service.js";
|
|
4
|
+
export declare function registerHmiActions(reg: RegisterAction, ctx: AppContext, hmi: HmiService, run: (fn: () => Promise<string>) => Promise<ActionResult>): void;
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The model's HMI actions: design screens, look at them, open the live page.
|
|
3
|
+
*/
|
|
4
|
+
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import * as z from "zod/v4";
|
|
8
|
+
import { currentCodesysSim } from "../codesys/simulation.js";
|
|
9
|
+
import { findBrowser, hmiScript, previewValues, screenshot, staticPage } from "./service.js";
|
|
10
|
+
import { nativePlan } from "./native.js";
|
|
11
|
+
import { canvasOf, tileBox } from "./render.js";
|
|
12
|
+
import { overlapWarnings } from "./route.js";
|
|
13
|
+
import { TEMPLATES } from "./templates.js";
|
|
14
|
+
import { allAlarms, layoutProblems, screenSchema, screenVariables } from "./spec.js";
|
|
15
|
+
const text = (t, isError = false) => ({ content: [{ type: "text", text: t }], ...(isError ? { isError } : {}) });
|
|
16
|
+
const GUIDE = `A screen is a ${"12x8"} grid of tiles (change with grid). Each widget has at: [column, row, width, height], 1-based, no overlaps.
|
|
17
|
+
Widgets: value (big number, optional sparkline), gauge, bar, status (LED list), buttons (tap/toggle/set/reset), switch, setpoint (+/- and slider), trend (up to 6 series), alarms, text, and process: a mimic diagram whose items sit in a 0..100 x 0..100 box (x across, y down): tank, pump, fan, valve, junction, pipe, sensor, lamp, label.
|
|
18
|
+
Connect pipes to ports, never by guessing points: {type: 'pipe', from: 'T-101.right', to: 'P-101.in', flow: 'PLC_PRG.xRun'}. The toolkit routes it with right angles and it meets the symbols exactly. A symbol's name is its id, or its label. Ports: tank top, bottom, left, right, left-high, right-high; pump and fan in (left), out (right), top, bottom; valve in, out (left/right, or bottom/top when vertical: true); junction c (for tees). A pipe end can also be a point [x, y] at the diagram's edge. via: [[x, y]] makes it pass points. For straight runs give connected symbols the same y (or x); a valve on a vertical pipe is vertical: true.
|
|
19
|
+
Variables are full instance paths: 'PLC_PRG.fbPump.xRunning', 'GVL.rLevel'. bands colour a value by range: [{from: 0, tone: 'accent'}, {from: 90, tone: 'alarm'}]. Tones: accent, ok, warn, alarm, neutral.
|
|
20
|
+
Good screens: the process diagram large on the left (about 8x5), key numbers and status on the right, controls and trends along the bottom; titles short; tag names on symbols (P-101, T-101).`;
|
|
21
|
+
export function registerHmiActions(reg, ctx, hmi, run) {
|
|
22
|
+
reg("hmi_save_screen", {
|
|
23
|
+
description: `Create or replace an HMI screen for the open project (stored next to it as <project>.hmi.json). It shows live in the browser page (open_hmi) and the panel while CODESYS's simulation runs, and buttons, switches and setpoints write to the simulation. After saving, call hmi_screenshot to look at it and fix what looks off.\n${GUIDE}`,
|
|
24
|
+
inputSchema: z.object({ screen: screenSchema }),
|
|
25
|
+
}, async ({ screen }) => {
|
|
26
|
+
if (!ctx.project)
|
|
27
|
+
return text("No project is open: open or create one first; screens are stored next to it.", true);
|
|
28
|
+
const problems = layoutProblems(screen);
|
|
29
|
+
if (problems.length)
|
|
30
|
+
return text(`Not saved: fix the layout first.\n- ${problems.join("\n- ")}`, true);
|
|
31
|
+
const vars = screenVariables(screen);
|
|
32
|
+
const roots = new Set(vars.map((v) => v.split(".")[0].toLowerCase()));
|
|
33
|
+
const unknown = ctx.cache ? [...roots].filter((r) => !ctx.cache.get(r) && !/^(gvl|io|hmi)/i.test(r)) : [];
|
|
34
|
+
const r = hmi.save(screen);
|
|
35
|
+
const looks = screen.widgets.flatMap((w) => {
|
|
36
|
+
if (w.type !== "process")
|
|
37
|
+
return [];
|
|
38
|
+
const b = tileBox(screen, w.at);
|
|
39
|
+
return overlapWarnings(w.items, (b.h - 46) / (b.w - 32));
|
|
40
|
+
});
|
|
41
|
+
const warn0 = looks.length ? `
|
|
42
|
+
Layout: ${looks.join(" ")}` : "";
|
|
43
|
+
const warn = warn0 + (unknown.length ? `\nCheck these: no object named ${unknown.map((u) => `'${u}'`).join(", ")} in the project (the first part of a variable path must be a program or GVL).` : "");
|
|
44
|
+
return text(`${r.replaced ? "Replaced" : "Saved"} screen '${screen.name}' (${screen.widgets.length} widgets, ${vars.length} variables) in ${r.file}.${warn}\nCall hmi_screenshot to see it.`);
|
|
45
|
+
});
|
|
46
|
+
reg("hmi_screenshot", {
|
|
47
|
+
description: "Render an HMI screen to an image you can look at, to check and polish the layout. Uses live values while the simulation runs; otherwise example values (pass values to choose them). Trends show made-up history in a screenshot.",
|
|
48
|
+
inputSchema: z.object({
|
|
49
|
+
screen: z.string().optional().describe("Screen name (default: the first)"),
|
|
50
|
+
values: z.record(z.string(), z.string()).optional().describe("Values to show instead, e.g. { 'PLC_PRG.rLevel': '72.5', 'PLC_PRG.xRun': 'TRUE' }"),
|
|
51
|
+
}),
|
|
52
|
+
}, async ({ screen: name, values }) => {
|
|
53
|
+
const s = hmi.screen(name);
|
|
54
|
+
if (!s)
|
|
55
|
+
return text(name ? `No screen named '${name}'. Screens: ${hmi.screens().map((x) => x.name).join(", ") || "none"}.` : "This project has no HMI screens yet: create one with hmi_save_screen.", true);
|
|
56
|
+
const script = hmiScript();
|
|
57
|
+
if (!script)
|
|
58
|
+
return text("The HMI page isn't built. Run npm run build.", true);
|
|
59
|
+
if (!findBrowser())
|
|
60
|
+
return text("Screenshots need Microsoft Edge or Google Chrome, and neither was found.", true);
|
|
61
|
+
let shown = values ?? {};
|
|
62
|
+
let source = values ? "the values you passed" : "example values (the simulation isn't running)";
|
|
63
|
+
if (!values && currentCodesysSim(ctx)) {
|
|
64
|
+
try {
|
|
65
|
+
shown = (await hmi.values(s)).values;
|
|
66
|
+
source = "live values from the simulation";
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
/* fall back to examples */
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (!values && !Object.keys(shown).length)
|
|
73
|
+
shown = previewValues(s);
|
|
74
|
+
try {
|
|
75
|
+
const png = await screenshot(staticPage(s, shown, hmi.sim(), script, hmi.page()), undefined, canvasOf(s));
|
|
76
|
+
return { content: [{ type: "image", data: png.toString("base64"), mimeType: "image/png" }, { type: "text", text: `Screen '${s.name}' (${s.size}) with ${source}.` }] };
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
return text(`Screenshot failed: ${e.message}`, true);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
reg("hmi_export_codesys", {
|
|
83
|
+
description: "Build the HMI as native CODESYS visualizations in the project, one per page (Visu_<screen>), so it ships with the application: the header links the pages, the first page is the start page of TargetVisu and WebVisu at the panel size, pumps and fans turn while running (8-frame animation), and a symbol with a faceplate opens it as a dialog (Dlg_<screen>_<tag>). Cards with gradients, SVG symbols in an embedded image pool, live values, bars and tank levels, colour states, buttons, switches, setpoints and alarm rows. A generated program PRG_HMI_<screen> per page scales values and turns the impellers; it runs in VISU_TASK. Returns a picture of the first page. Trends are shown as values. Rebuilds what exists.",
|
|
84
|
+
inputSchema: z.object({ screen: z.string().optional().describe("One page only (default: every page)") }),
|
|
85
|
+
}, async ({ screen: name }) => {
|
|
86
|
+
const all = hmi.screens();
|
|
87
|
+
const targets = name ? [hmi.screen(name)].filter((x) => !!x) : all;
|
|
88
|
+
if (!targets.length)
|
|
89
|
+
return text(name ? `No screen named '${name}'.` : "This project has no HMI screens yet: create one with hmi_save_screen.", true);
|
|
90
|
+
const b = ctx.bridge;
|
|
91
|
+
if (!(await b.waitReady(ctx.startWaitMs)))
|
|
92
|
+
return text("CODESYS is still starting; try again shortly.", true);
|
|
93
|
+
const pages = all.map((x) => ({ name: x.name, title: x.title }));
|
|
94
|
+
const dir = mkdtempSync(join(tmpdir(), "cmcp-visu-"));
|
|
95
|
+
try {
|
|
96
|
+
const notes = [];
|
|
97
|
+
const warnings = [];
|
|
98
|
+
const builtNames = [];
|
|
99
|
+
let first;
|
|
100
|
+
// The first page is built last, so a CODESYS window ends up showing the start page.
|
|
101
|
+
for (const s of [...targets].reverse()) {
|
|
102
|
+
const plan = nativePlan(s, pages);
|
|
103
|
+
const images = plan.images.map((img) => {
|
|
104
|
+
const path = join(dir, `${img.id}.svg`);
|
|
105
|
+
writeFileSync(path, img.svg, "utf8");
|
|
106
|
+
return { id: img.id, path };
|
|
107
|
+
});
|
|
108
|
+
// The helper program first: the visualization refers to its variables.
|
|
109
|
+
try {
|
|
110
|
+
await b.call("object.write", { path: plan.helper.name, declaration: plan.helper.declaration, implementation: plan.helper.implementation });
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
await b.call("object.create", { kind: "program", name: plan.helper.name, declaration: plan.helper.declaration, implementation: plan.helper.implementation });
|
|
114
|
+
}
|
|
115
|
+
for (const d of plan.dialogs) {
|
|
116
|
+
const r = await b.call("visu.build", { name: d.name, replace: true, background: d.background, elements: d.elements, size: d.size, dialog: true, save: false }, { timeoutMs: 300_000 });
|
|
117
|
+
warnings.push(...r.warnings.map((w) => `${d.name}: ${w}`));
|
|
118
|
+
builtNames.push(d.name);
|
|
119
|
+
}
|
|
120
|
+
const built = await b.call("visu.build", { name: plan.visu, replace: true, background: plan.background, elements: plan.elements, image_pool: plan.imagePool, images, size: plan.size, save: ctx.autosave }, { timeoutMs: 300_000 });
|
|
121
|
+
warnings.push(...built.warnings.map((w) => `${plan.visu}: ${w}`));
|
|
122
|
+
builtNames.push(`${built.name} (${built.elements} elements)`);
|
|
123
|
+
first = { visu: plan.visu, w: plan.size[0], h: plan.size[1] };
|
|
124
|
+
for (const task of ["VISU_TASK", "MainTask"]) {
|
|
125
|
+
try {
|
|
126
|
+
await b.call("task.configure", { name: task, add_calls: [plan.helper.name], save: false });
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
/* try the next task */
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// The pages' alarms as CODESYS alarms (timestamps, acknowledge and history in the PLC).
|
|
135
|
+
const alarms = allAlarms(all);
|
|
136
|
+
if (alarms.length) {
|
|
137
|
+
try {
|
|
138
|
+
const cls = (sev) => (sev === "info" ? "Info" : sev === "warning" ? "Warning" : "Error");
|
|
139
|
+
const r = await b.call("alarms.configure", { group: "AG_HMI", alarms: alarms.map((a, i) => ({ id: i + 1, kind: "digital", expression: a.active, comparison: "Equal", compare_to: "TRUE", text: a.text, cls: cls(a.severity) })), save: false }, { timeoutMs: 120_000 });
|
|
140
|
+
notes.push(`${r.alarms.length} alarm(s) in CODESYS alarm management (Alarm Configuration / AG_HMI).`);
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
warnings.push(`alarms: ${e.message}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// User groups for the Login button; users and passwords are the engineer's to add.
|
|
147
|
+
try {
|
|
148
|
+
await b.call("visu.users", { groups: ["Operator", "Maintenance", "Admin"], save: false }, { timeoutMs: 120_000 });
|
|
149
|
+
notes.push("User groups Operator, Maintenance and Admin; add users in the Visualization Manager (User Management) for the Login button.");
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
warnings.push(`user groups: ${e.message}`);
|
|
153
|
+
}
|
|
154
|
+
// Start on the first page; the clients use the panel size.
|
|
155
|
+
const startPage = `Visu_${all[0].name}`;
|
|
156
|
+
const cv = canvasOf(all[0]);
|
|
157
|
+
try {
|
|
158
|
+
const m = await b.call("visu.manager", { start: startPage, width: cv.w, height: cv.h, save: ctx.autosave });
|
|
159
|
+
notes.push(`Start page ${startPage} at ${cv.w}x${cv.h} in ${m.updated.join(", ") || "no client"}.`);
|
|
160
|
+
warnings.push(...m.warnings);
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
warnings.push(`visualization manager: ${e.message}`);
|
|
164
|
+
}
|
|
165
|
+
const build = await b.call("build", {}, { timeoutMs: 900_000 });
|
|
166
|
+
const errors = build.messages.filter((m) => /error/i.test(m.severity));
|
|
167
|
+
if (errors.length) {
|
|
168
|
+
const fpu = errors.some((m) => /\bFPU\b|FloatingPointUtils/.test(m.text));
|
|
169
|
+
notes.push(fpu
|
|
170
|
+
? `The build has ${errors.length} errors because this CODESYS's library repository lacks FloatingPointUtils, which the visualization libraries need. Install it with the CODESYS Installer (or Tools > Library Repository), then compile again.`
|
|
171
|
+
: `The build has ${errors.length} errors, for example: ${errors.slice(0, 3).map((m) => `${m.object ?? ""} ${m.text}`.trim()).join("; ")}`);
|
|
172
|
+
}
|
|
173
|
+
else
|
|
174
|
+
notes.push("Compiles with 0 errors. Start the simulation to see it live.");
|
|
175
|
+
if (warnings.length)
|
|
176
|
+
notes.push(`Not applied (${warnings.length}): ${warnings.slice(0, 6).join("; ")}`);
|
|
177
|
+
const png = join(dir, "visu.png");
|
|
178
|
+
let image = [];
|
|
179
|
+
if (first) {
|
|
180
|
+
try {
|
|
181
|
+
await b.call("visu.render", { name: first.visu, path: png, width: first.w, height: first.h }, { timeoutMs: 60_000 });
|
|
182
|
+
image = [{ type: "image", data: readFileSync(png).toString("base64"), mimeType: "image/png" }];
|
|
183
|
+
}
|
|
184
|
+
catch (e) {
|
|
185
|
+
notes.push(`No picture: ${e.message}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return { content: [...image, { type: "text", text: [`Built ${builtNames.join(", ")}.`, ...notes].join("\n") }] };
|
|
189
|
+
}
|
|
190
|
+
catch (e) {
|
|
191
|
+
return text(`${e.code ? `${e.code}: ` : ""}${e.message}`, true);
|
|
192
|
+
}
|
|
193
|
+
finally {
|
|
194
|
+
rmSync(dir, { recursive: true, force: true });
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
reg("hmi_template", {
|
|
198
|
+
description: `Page templates for a complete HMI: ${Object.entries(TEMPLATES).map(([k, t]) => `${k} (${t.use})`).join("; ")}. Returns the template's screen description: adapt titles and replace the 'PRG.' variables with the program's, then save it with hmi_save_screen. Pages of one HMI share the header, which links to every page and counts the alarms of all pages.`,
|
|
199
|
+
inputSchema: z.object({ kind: z.enum(Object.keys(TEMPLATES)) }),
|
|
200
|
+
}, async ({ kind }) => text(`${TEMPLATES[kind].use}\n${JSON.stringify(TEMPLATES[kind].screen, null, 1)}`));
|
|
201
|
+
reg("hmi_list", { description: "List the open project's HMI screens.", inputSchema: z.object({ screen: z.string().optional().describe("Return this screen's full description") }) }, async ({ screen }) => {
|
|
202
|
+
if (screen) {
|
|
203
|
+
const s = hmi.screen(screen);
|
|
204
|
+
return s ? text(JSON.stringify(s, null, 2)) : text(`No screen named '${screen}'.`, true);
|
|
205
|
+
}
|
|
206
|
+
const all = hmi.screens();
|
|
207
|
+
return text(all.length ? all.map((s) => `${s.name}: "${s.title}" (${s.widgets.length} widgets, ${screenVariables(s).length} variables)`).join("\n") : "No HMI screens yet.");
|
|
208
|
+
});
|
|
209
|
+
reg("hmi_delete_screen", { description: "Delete an HMI screen.", inputSchema: z.object({ screen: z.string() }) }, async ({ screen }) => (hmi.remove(screen) ? text(`Deleted screen '${screen}'.`) : text(`No screen named '${screen}'.`, true)));
|
|
210
|
+
reg("open_hmi", {
|
|
211
|
+
description: "Open the live HMI in the user's browser (full screen, live values from the simulation, buttons work). Call this only when the user asks to see or operate the HMI.",
|
|
212
|
+
inputSchema: z.object({ screen: z.string().optional() }),
|
|
213
|
+
}, async ({ screen }) => {
|
|
214
|
+
if (!ctx.viewer)
|
|
215
|
+
return text("The browser page is switched off (--no-viewer).", true);
|
|
216
|
+
const url = ctx.viewer.url.replace("/?t=", "/hmi?t=") + (screen ? `&s=${encodeURIComponent(screen)}` : "");
|
|
217
|
+
ctx.viewer.open(true, url);
|
|
218
|
+
return text(`The live HMI opened in the user's browser: ${url}${currentCodesysSim(ctx) ? "" : "\nThe simulation isn't running: start it (codesys_sim_start, then codesys_sim_control run) so the screen shows live values."}`);
|
|
219
|
+
});
|
|
220
|
+
void run;
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/hmi/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Parsing PLC values; no dependencies, so the browser page can use it too. */
|
|
2
|
+
/** A PLC value as the simulation reports it ("TRUE", "INT#8", "REAL#1.5", "T#1s"), as a number or boolean. */
|
|
3
|
+
export declare function plcValue(raw: string | undefined): number | boolean | string | undefined;
|