@aryacode/dsh-engineering 0.0.0-stage → 0.4.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 +128 -0
- package/LICENSE +21 -0
- package/README.md +230 -2
- package/cordis.patch.yml +123 -0
- package/lib/client.js +3448 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +9 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +94 -3
- package/vendor/ftview/README.md +55 -0
- package/vendor/ftview/SKILL.md +74 -0
- package/vendor/ftview/lib/checks.d.ts +27 -0
- package/vendor/ftview/lib/checks.js +39 -0
- package/vendor/ftview/lib/core.d.ts +208 -0
- package/vendor/ftview/lib/core.js +160 -0
- package/vendor/ftview/lib/edit/drafts.d.ts +49 -0
- package/vendor/ftview/lib/edit/drafts.js +84 -0
- package/vendor/ftview/lib/edit/operations.d.ts +62 -0
- package/vendor/ftview/lib/edit/operations.js +126 -0
- package/vendor/ftview/lib/edit/prepare.d.ts +38 -0
- package/vendor/ftview/lib/edit/prepare.js +133 -0
- package/vendor/ftview/lib/edit/tools.d.ts +25 -0
- package/vendor/ftview/lib/edit/tools.js +198 -0
- package/vendor/ftview/lib/edit.d.ts +30 -0
- package/vendor/ftview/lib/edit.js +38 -0
- package/vendor/ftview/lib/index.d.ts +31 -0
- package/vendor/ftview/lib/index.js +36 -0
- package/vendor/ftview/lib/model.d.ts +80 -0
- package/vendor/ftview/lib/model.js +267 -0
- package/vendor/ftview/lib/session.d.ts +48 -0
- package/vendor/ftview/lib/session.js +98 -0
- package/vendor/ftview/lib/skill.d.ts +29 -0
- package/vendor/ftview/lib/skill.js +43 -0
- package/vendor/ftview/lib/studio/discover.d.ts +36 -0
- package/vendor/ftview/lib/studio/discover.js +87 -0
- package/vendor/ftview/lib/studio/preflight.d.ts +51 -0
- package/vendor/ftview/lib/studio/preflight.js +64 -0
- package/vendor/ftview/lib/studio/tools.d.ts +15 -0
- package/vendor/ftview/lib/studio/tools.js +83 -0
- package/vendor/ftview/lib/studio.d.ts +30 -0
- package/vendor/ftview/lib/studio.js +37 -0
- package/vendor/ftview/lib/tools.d.ts +14 -0
- package/vendor/ftview/lib/tools.js +202 -0
- package/vendor/l5x/README.md +62 -0
- package/vendor/l5x/SKILL.md +81 -0
- package/vendor/l5x/lib/approvals.d.ts +50 -0
- package/vendor/l5x/lib/approvals.js +93 -0
- package/vendor/l5x/lib/client.js +412 -0
- package/vendor/l5x/lib/client.js.map +1 -0
- package/vendor/l5x/lib/core/errors.d.ts +38 -0
- package/vendor/l5x/lib/core/errors.js +48 -0
- package/vendor/l5x/lib/core/params.d.ts +49 -0
- package/vendor/l5x/lib/core/params.js +39 -0
- package/vendor/l5x/lib/core/result.d.ts +46 -0
- package/vendor/l5x/lib/core/result.js +21 -0
- package/vendor/l5x/lib/core/tool.d.ts +102 -0
- package/vendor/l5x/lib/core/tool.js +19 -0
- package/vendor/l5x/lib/drafts.d.ts +66 -0
- package/vendor/l5x/lib/drafts.js +98 -0
- package/vendor/l5x/lib/editing.d.ts +30 -0
- package/vendor/l5x/lib/editing.js +42 -0
- package/vendor/l5x/lib/engine/acd-edit.d.ts +13 -0
- package/vendor/l5x/lib/engine/acd-edit.js +115 -0
- package/vendor/l5x/lib/engine/analysis.d.ts +22 -0
- package/vendor/l5x/lib/engine/analysis.js +258 -0
- package/vendor/l5x/lib/engine/capabilities.d.ts +9 -0
- package/vendor/l5x/lib/engine/capabilities.js +40 -0
- package/vendor/l5x/lib/engine/change-set.d.ts +122 -0
- package/vendor/l5x/lib/engine/change-set.js +446 -0
- package/vendor/l5x/lib/engine/configuration.d.ts +21 -0
- package/vendor/l5x/lib/engine/configuration.js +42 -0
- package/vendor/l5x/lib/engine/details.d.ts +47 -0
- package/vendor/l5x/lib/engine/details.js +173 -0
- package/vendor/l5x/lib/engine/direct-polling.d.ts +91 -0
- package/vendor/l5x/lib/engine/direct-polling.js +193 -0
- package/vendor/l5x/lib/engine/download-review.d.ts +15 -0
- package/vendor/l5x/lib/engine/download-review.js +63 -0
- package/vendor/l5x/lib/engine/logic-syntax.d.ts +60 -0
- package/vendor/l5x/lib/engine/logic-syntax.js +237 -0
- package/vendor/l5x/lib/engine/observations.d.ts +41 -0
- package/vendor/l5x/lib/engine/observations.js +67 -0
- package/vendor/l5x/lib/engine/project-analysis.d.ts +131 -0
- package/vendor/l5x/lib/engine/project-analysis.js +314 -0
- package/vendor/l5x/lib/engine/review-evidence.d.ts +8 -0
- package/vendor/l5x/lib/engine/review-evidence.js +49 -0
- package/vendor/l5x/lib/engine/review.d.ts +18 -0
- package/vendor/l5x/lib/engine/review.js +123 -0
- package/vendor/l5x/lib/engine/studio-sdk.d.ts +101 -0
- package/vendor/l5x/lib/engine/studio-sdk.js +571 -0
- package/vendor/l5x/lib/engine/tag-resolution.d.ts +20 -0
- package/vendor/l5x/lib/engine/tag-resolution.js +169 -0
- package/vendor/l5x/lib/engine/usage.d.ts +16 -0
- package/vendor/l5x/lib/engine/usage.js +92 -0
- package/vendor/l5x/lib/engine/xml-regions.d.ts +23 -0
- package/vendor/l5x/lib/engine/xml-regions.js +77 -0
- package/vendor/l5x/lib/fs.d.ts +17 -0
- package/vendor/l5x/lib/fs.js +36 -0
- package/vendor/l5x/lib/index.d.ts +36 -0
- package/vendor/l5x/lib/index.js +42 -0
- package/vendor/l5x/lib/live.d.ts +48 -0
- package/vendor/l5x/lib/live.js +48 -0
- package/vendor/l5x/lib/model/aois.d.ts +39 -0
- package/vendor/l5x/lib/model/aois.js +112 -0
- package/vendor/l5x/lib/model/errors.d.ts +15 -0
- package/vendor/l5x/lib/model/errors.js +18 -0
- package/vendor/l5x/lib/model/index.d.ts +20 -0
- package/vendor/l5x/lib/model/index.js +19 -0
- package/vendor/l5x/lib/model/module.d.ts +37 -0
- package/vendor/l5x/lib/model/module.js +54 -0
- package/vendor/l5x/lib/model/modules.d.ts +24 -0
- package/vendor/l5x/lib/model/modules.js +55 -0
- package/vendor/l5x/lib/model/parse.d.ts +32 -0
- package/vendor/l5x/lib/model/parse.js +116 -0
- package/vendor/l5x/lib/model/project.d.ts +15 -0
- package/vendor/l5x/lib/model/project.js +31 -0
- package/vendor/l5x/lib/model/routines.d.ts +71 -0
- package/vendor/l5x/lib/model/routines.js +183 -0
- package/vendor/l5x/lib/model/tags.d.ts +51 -0
- package/vendor/l5x/lib/model/tags.js +119 -0
- package/vendor/l5x/lib/model/types.d.ts +304 -0
- package/vendor/l5x/lib/model/types.js +12 -0
- package/vendor/l5x/lib/model/udts.d.ts +34 -0
- package/vendor/l5x/lib/model/udts.js +81 -0
- package/vendor/l5x/lib/model/xml.d.ts +139 -0
- package/vendor/l5x/lib/model/xml.js +291 -0
- package/vendor/l5x/lib/model/xref.d.ts +28 -0
- package/vendor/l5x/lib/model/xref.js +154 -0
- package/vendor/l5x/lib/session.d.ts +119 -0
- package/vendor/l5x/lib/session.js +236 -0
- package/vendor/l5x/lib/skill.d.ts +30 -0
- package/vendor/l5x/lib/skill.js +44 -0
- package/vendor/l5x/lib/studio-state.d.ts +77 -0
- package/vendor/l5x/lib/studio-state.js +79 -0
- package/vendor/l5x/lib/studio.d.ts +29 -0
- package/vendor/l5x/lib/studio.js +40 -0
- package/vendor/l5x/lib/tools/checks.d.ts +19 -0
- package/vendor/l5x/lib/tools/checks.js +140 -0
- package/vendor/l5x/lib/tools/common.d.ts +41 -0
- package/vendor/l5x/lib/tools/common.js +84 -0
- package/vendor/l5x/lib/tools/controller.d.ts +21 -0
- package/vendor/l5x/lib/tools/controller.js +170 -0
- package/vendor/l5x/lib/tools/drafts.d.ts +23 -0
- package/vendor/l5x/lib/tools/drafts.js +270 -0
- package/vendor/l5x/lib/tools/live.d.ts +21 -0
- package/vendor/l5x/lib/tools/live.js +175 -0
- package/vendor/l5x/lib/tools/read.d.ts +19 -0
- package/vendor/l5x/lib/tools/read.js +245 -0
- package/vendor/l5x/lib/tools/references.d.ts +20 -0
- package/vendor/l5x/lib/tools/references.js +269 -0
- package/vendor/l5x/lib/tools/studio.d.ts +21 -0
- package/vendor/l5x/lib/tools/studio.js +193 -0
- package/vendor/l5x/poll-worker.mjs +77 -0
- package/vendor/l5x/studio-bridge/NuGet.Config +1 -0
- package/vendor/l5x/studio-bridge/Program.cs +304 -0
- package/vendor/l5x/studio-bridge/StudioBridge.csproj +11 -0
- package/vendor/mwi/README.md +60 -0
- package/vendor/mwi/SKILL.md +87 -0
- package/vendor/mwi/bridge/README.md +8 -0
- package/vendor/mwi/bridge/mw_bridge.ps1 +2763 -0
- package/vendor/mwi/bridge/sdk-interop-importer.cs +30 -0
- package/vendor/mwi/bridge/sdk-variable-reader.cs +22 -0
- package/vendor/mwi/bridge/start_bridge.cmd +21 -0
- package/vendor/mwi/bridge/watch_dialogs.cmd +13 -0
- package/vendor/mwi/bridge/watch_dialogs.ps1 +153 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__init__.py +14 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/__init__.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/block_interfaces.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/cfb.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/datatypes.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/declarations.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/errors.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/graphical_listing.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/grid.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/knowledge.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/mwt_bind.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/navigation.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/program_checks.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/project.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/staging.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/structure.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/task_bindings.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/tasks.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/tree.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/validation.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/variable_edit.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/variables.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/workflow.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/block_interfaces.py +275 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/build.py +339 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/capture.py +448 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/cfb.py +765 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/com.py +268 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/datatypes.py +204 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/declarations.py +399 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/descriptions.py +30 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/eip.py +292 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/errors.py +36 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/graphical_listing.py +208 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/grid.py +227 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/ide.py +317 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/iec.py +317 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/installed_help.py +151 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/knowledge.py +218 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/libraries.py +250 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/manuals.py +520 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/mwt_bind.py +133 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/navigation.py +44 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/pou_writer.py +1547 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/program_checks.py +360 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/project.py +704 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/reference_data/catalog.json +672 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/reference_data/patterns.json +86 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/restore.py +208 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/server.py +1913 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/snapshot.py +138 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/st_comments.py +25 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/staging.py +179 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/stlint.py +676 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/structure.py +98 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/task_bindings.py +68 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/tasks.py +162 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/transaction.py +157 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/tree.py +563 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/tree_writer.py +790 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/uia.py +465 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/validation.py +41 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/variable_edit.py +183 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/variables.py +472 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/workflow.py +130 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/writer.py +666 -0
- package/vendor/mwi/code/mw_code.py +1258 -0
- package/vendor/mwi/legacy/edit-session.js +50 -0
- package/vendor/mwi/legacy/fb-insertion.js +74 -0
- package/vendor/mwi/legacy/native-code.js +83 -0
- package/vendor/mwi/legacy/native-groups.js +75 -0
- package/vendor/mwi/legacy/native-structure.js +143 -0
- package/vendor/mwi/legacy/native-variables.js +77 -0
- package/vendor/mwi/legacy/pou-conversion.js +47 -0
- package/vendor/mwi/legacy/pou-package.js +66 -0
- package/vendor/mwi/lib/core/bridge.d.ts +71 -0
- package/vendor/mwi/lib/core/bridge.js +53 -0
- package/vendor/mwi/lib/core/code-engine.d.ts +47 -0
- package/vendor/mwi/lib/core/code-engine.js +109 -0
- package/vendor/mwi/lib/core/errors.d.ts +37 -0
- package/vendor/mwi/lib/core/errors.js +47 -0
- package/vendor/mwi/lib/core/params.d.ts +52 -0
- package/vendor/mwi/lib/core/params.js +46 -0
- package/vendor/mwi/lib/core/ps-bridge.d.ts +62 -0
- package/vendor/mwi/lib/core/ps-bridge.js +127 -0
- package/vendor/mwi/lib/core/result.d.ts +45 -0
- package/vendor/mwi/lib/core/result.js +20 -0
- package/vendor/mwi/lib/core/tool.d.ts +80 -0
- package/vendor/mwi/lib/core/tool.js +55 -0
- package/vendor/mwi/lib/edit/compare.d.ts +33 -0
- package/vendor/mwi/lib/edit/compare.js +70 -0
- package/vendor/mwi/lib/edit.d.ts +20 -0
- package/vendor/mwi/lib/edit.js +32 -0
- package/vendor/mwi/lib/index.d.ts +21 -0
- package/vendor/mwi/lib/index.js +33 -0
- package/vendor/mwi/lib/read/service.d.ts +117 -0
- package/vendor/mwi/lib/read/service.js +229 -0
- package/vendor/mwi/lib/read.d.ts +21 -0
- package/vendor/mwi/lib/read.js +33 -0
- package/vendor/mwi/lib/session/project.d.ts +34 -0
- package/vendor/mwi/lib/session/project.js +54 -0
- package/vendor/mwi/lib/session/service.d.ts +167 -0
- package/vendor/mwi/lib/session/service.js +566 -0
- package/vendor/mwi/lib/session/stage.d.ts +84 -0
- package/vendor/mwi/lib/session/stage.js +187 -0
- package/vendor/mwi/lib/session/workspace.d.ts +52 -0
- package/vendor/mwi/lib/session/workspace.js +90 -0
- package/vendor/mwi/lib/skill.d.ts +36 -0
- package/vendor/mwi/lib/skill.js +56 -0
- package/vendor/mwi/lib/tools/edit.d.ts +20 -0
- package/vendor/mwi/lib/tools/edit.js +286 -0
- package/vendor/mwi/lib/tools/read.d.ts +19 -0
- package/vendor/mwi/lib/tools/read.js +161 -0
- package/vendor/mwi/lib/tools/session.d.ts +20 -0
- package/vendor/mwi/lib/tools/session.js +166 -0
- package/vendor/mwi/lib/tools/verify.d.ts +19 -0
- package/vendor/mwi/lib/tools/verify.js +85 -0
- package/vendor/mwi/lib/verify.d.ts +17 -0
- package/vendor/mwi/lib/verify.js +29 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routine reader — ladder as NeutralText with rung comments, Structured Text
|
|
3
|
+
* as its lines.
|
|
4
|
+
*
|
|
5
|
+
* A ladder rung is returned as the compact NeutralText the export already
|
|
6
|
+
* stores, e.g. `XIC(Motor_Start)XIO(Motor_Fault)OTE(Motor_Run);`, which is what
|
|
7
|
+
* makes one rung a single readable line instead of its graphical XML. Any other
|
|
8
|
+
* routine language is reported by name rather than decomposed.
|
|
9
|
+
*/
|
|
10
|
+
import { descriptionOf, programElements } from "./module.js";
|
|
11
|
+
import { attribute, elementChildren, firstChild, nodeText, optionalAttribute } from "./xml.js";
|
|
12
|
+
/** The language code a ladder routine carries. */
|
|
13
|
+
const LADDER = 'RLL';
|
|
14
|
+
/** The language code a Structured Text routine carries. */
|
|
15
|
+
const STRUCTURED_TEXT = 'ST';
|
|
16
|
+
/**
|
|
17
|
+
* List routines with the size of each body.
|
|
18
|
+
*
|
|
19
|
+
* The listing names the program, so a caller can pass the name back to
|
|
20
|
+
* {@link getRoutine}. Only the count for the routine's own language is
|
|
21
|
+
* reported, which is why at most one count is ever present.
|
|
22
|
+
*
|
|
23
|
+
* @param document - The parsed project.
|
|
24
|
+
* @param program - Program name to restrict to; empty or omitted keeps every program.
|
|
25
|
+
* @returns One entry per routine, in written order.
|
|
26
|
+
*/
|
|
27
|
+
export function listRoutines(document, program = '') {
|
|
28
|
+
const routines = program === '' ? document.routines : document.routines.filter(routine => routine.program === program);
|
|
29
|
+
return routines.map(routineInfoOf);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Read one routine's body.
|
|
33
|
+
*
|
|
34
|
+
* @param document - The parsed project.
|
|
35
|
+
* @param program - Program holding the routine.
|
|
36
|
+
* @param routineName - Routine name.
|
|
37
|
+
* @returns The routine, or undefined when that program has no such routine.
|
|
38
|
+
*/
|
|
39
|
+
export function getRoutine(document, program, routineName) {
|
|
40
|
+
return document.routines.find(routine => routine.program === program && routine.name === routineName);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Read every program's routines of a controller.
|
|
44
|
+
*
|
|
45
|
+
* @param controller - The controller element.
|
|
46
|
+
* @returns The routines, in program then written order.
|
|
47
|
+
*/
|
|
48
|
+
export function buildRoutines(controller) {
|
|
49
|
+
const routines = [];
|
|
50
|
+
for (const program of programElements(controller)) {
|
|
51
|
+
const programName = optionalAttribute(program, 'Name', '');
|
|
52
|
+
const elements = firstChild(program, 'Routines');
|
|
53
|
+
if (elements === undefined)
|
|
54
|
+
continue;
|
|
55
|
+
for (const routine of elementChildren(elements, 'Routine'))
|
|
56
|
+
routines.push(routineBody(programName, routine));
|
|
57
|
+
}
|
|
58
|
+
return routines;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Decode one routine element's body.
|
|
62
|
+
*
|
|
63
|
+
* Add-on instructions read their internal routines through this, so an AOI's
|
|
64
|
+
* ladder and Structured Text are decoded exactly as a program's are.
|
|
65
|
+
*
|
|
66
|
+
* @param owner - Program or add-on instruction the routine belongs to.
|
|
67
|
+
* @param routine - The `<Routine>` element.
|
|
68
|
+
* @returns The routine with its body decoded.
|
|
69
|
+
*/
|
|
70
|
+
export function routineBody(owner, routine) {
|
|
71
|
+
const type = optionalAttribute(routine, 'Type', '');
|
|
72
|
+
return {
|
|
73
|
+
program: owner,
|
|
74
|
+
name: optionalAttribute(routine, 'Name', ''),
|
|
75
|
+
type,
|
|
76
|
+
description: descriptionOf(routine),
|
|
77
|
+
body: decodeBody(type, routine),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/** A listing entry for one routine already read. */
|
|
81
|
+
function routineInfoOf(routine) {
|
|
82
|
+
const entry = {
|
|
83
|
+
program: routine.program,
|
|
84
|
+
name: routine.name,
|
|
85
|
+
type: routine.type,
|
|
86
|
+
description: routine.description,
|
|
87
|
+
};
|
|
88
|
+
if (routine.body.type === LADDER)
|
|
89
|
+
return { ...entry, rungCount: routine.body.rungs.length };
|
|
90
|
+
if (routine.body.type === STRUCTURED_TEXT)
|
|
91
|
+
return { ...entry, lineCount: splitLines(routine.body.code).length };
|
|
92
|
+
return entry;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The numbered lines of a Structured Text body.
|
|
96
|
+
*
|
|
97
|
+
* An empty body has no lines: the reader joins the export's lines with `\n`, so
|
|
98
|
+
* a body of no lines and a body of one empty line both read as `''`, and the
|
|
99
|
+
* export's own line count is what a listing reports.
|
|
100
|
+
*
|
|
101
|
+
* @param code - A Structured Text body.
|
|
102
|
+
* @returns One entry per line, numbered from zero in body order.
|
|
103
|
+
*/
|
|
104
|
+
export function splitLines(code) {
|
|
105
|
+
if (code === '')
|
|
106
|
+
return [];
|
|
107
|
+
return code.split('\n').map((text, number) => ({ number, text }));
|
|
108
|
+
}
|
|
109
|
+
/** The body of a routine, by its declared language. */
|
|
110
|
+
function decodeBody(type, routine) {
|
|
111
|
+
if (type === LADDER)
|
|
112
|
+
return { type: LADDER, rungs: decodeRungs(routine) };
|
|
113
|
+
if (type === STRUCTURED_TEXT)
|
|
114
|
+
return { type: STRUCTURED_TEXT, code: decodeLines(routine).join('\n') };
|
|
115
|
+
if ((type === 'FBD' && firstChild(routine, 'FBDContent') !== undefined) || (type === 'SFC' && firstChild(routine, 'SFCContent') !== undefined)) {
|
|
116
|
+
return { type, nodes: decodeDiagram(routine, type === 'FBD' ? 'FBDContent' : 'SFCContent') };
|
|
117
|
+
}
|
|
118
|
+
return { type: 'other', note: `${type} detailed parsing not yet supported` };
|
|
119
|
+
}
|
|
120
|
+
function decodeDiagram(routine, contentName) {
|
|
121
|
+
const content = firstChild(routine, contentName);
|
|
122
|
+
if (content === undefined)
|
|
123
|
+
return [];
|
|
124
|
+
const nodes = [];
|
|
125
|
+
for (const sheet of elementChildren(content, 'Sheet')) {
|
|
126
|
+
const number = Number.parseInt(sheet.attrs['Number'] ?? '0', 10);
|
|
127
|
+
const visit = (child) => {
|
|
128
|
+
const text = nodeText(child);
|
|
129
|
+
if (Object.keys(child.attrs).length > 0 || text !== undefined) {
|
|
130
|
+
const node = {
|
|
131
|
+
kind: child.name, sheet: number,
|
|
132
|
+
...(child.attrs['ID'] === undefined ? {} : { id: child.attrs['ID'] }),
|
|
133
|
+
...(child.attrs['Operand'] === undefined ? {} : { operand: child.attrs['Operand'] }),
|
|
134
|
+
...(child.attrs['FromID'] === undefined ? {} : { fromId: child.attrs['FromID'] }),
|
|
135
|
+
...(child.attrs['ToID'] === undefined ? {} : { toId: child.attrs['ToID'] }),
|
|
136
|
+
...(text === undefined ? {} : { text }),
|
|
137
|
+
};
|
|
138
|
+
nodes.push(node);
|
|
139
|
+
}
|
|
140
|
+
for (const nested of child.children)
|
|
141
|
+
if ('attrs' in nested)
|
|
142
|
+
visit(nested);
|
|
143
|
+
};
|
|
144
|
+
for (const child of sheet.children)
|
|
145
|
+
if ('attrs' in child)
|
|
146
|
+
visit(child);
|
|
147
|
+
}
|
|
148
|
+
return nodes;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* One ladder routine's rungs, as NeutralText with their comments.
|
|
152
|
+
*
|
|
153
|
+
* @param routine - The `<Routine>` element of a ladder routine.
|
|
154
|
+
* @returns One entry per rung, in written order.
|
|
155
|
+
*/
|
|
156
|
+
export function decodeRungs(routine) {
|
|
157
|
+
const content = firstChild(routine, 'RLLContent');
|
|
158
|
+
if (content === undefined)
|
|
159
|
+
return [];
|
|
160
|
+
return elementChildren(content, 'Rung').map(decodeRung);
|
|
161
|
+
}
|
|
162
|
+
/** A Structured Text routine's source lines, verbatim and in written order. */
|
|
163
|
+
function decodeLines(routine) {
|
|
164
|
+
const content = firstChild(routine, 'STContent');
|
|
165
|
+
if (content === undefined)
|
|
166
|
+
return [];
|
|
167
|
+
return elementChildren(content, 'Line').map(line => nodeText(line) ?? '');
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* One rung as NeutralText, with its comment when the export carries one.
|
|
171
|
+
*
|
|
172
|
+
* @param rung - The `<Rung>` element.
|
|
173
|
+
* @returns The rung, with empty text when the export wrote none.
|
|
174
|
+
*/
|
|
175
|
+
function decodeRung(rung) {
|
|
176
|
+
const textElement = firstChild(rung, 'Text');
|
|
177
|
+
const text = textElement === undefined ? '' : (nodeText(textElement) ?? '').trim();
|
|
178
|
+
const comment = optionalAttribute(rung, 'Comment', '');
|
|
179
|
+
const number = Number.parseInt(attribute(rung, 'Number'), 10);
|
|
180
|
+
if (comment === '')
|
|
181
|
+
return { number, text };
|
|
182
|
+
return { number, comment, text };
|
|
183
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tag reader — controller-scoped and program-scoped tags, with the scope and
|
|
3
|
+
* data-type filters the tool schema declares.
|
|
4
|
+
*
|
|
5
|
+
* Scope is carried on every entry rather than implied by grouping, because one
|
|
6
|
+
* flat list answers both "what does the controller own" and "what does this
|
|
7
|
+
* program own" without the caller re-nesting it.
|
|
8
|
+
*/
|
|
9
|
+
import type { L5xDocument, L5xTag } from './types.ts';
|
|
10
|
+
import { type XmlElement } from './xml.ts';
|
|
11
|
+
/**
|
|
12
|
+
* List tags, filtered by scope and data type.
|
|
13
|
+
*
|
|
14
|
+
* A scope of `controller` selects only the controller's tags; any other
|
|
15
|
+
* non-empty scope selects only that program's; an empty scope selects both, with
|
|
16
|
+
* the controller's first. The scope match is exact and case-sensitive except for
|
|
17
|
+
* the literal `controller`, which is matched case-insensitively so `Controller`
|
|
18
|
+
* from a caller still selects the controller's tags.
|
|
19
|
+
*
|
|
20
|
+
* @param document - The parsed project.
|
|
21
|
+
* @param scope - `controller`, a program name, or empty for all.
|
|
22
|
+
* @param dataType - Data type to restrict to; empty keeps every type.
|
|
23
|
+
* @returns Matching tags, in written order.
|
|
24
|
+
*/
|
|
25
|
+
export declare function listTags(document: L5xDocument, scope?: string, dataType?: string): readonly L5xTag[];
|
|
26
|
+
/**
|
|
27
|
+
* Find one tag by name, searching controller scope first and then each program.
|
|
28
|
+
*
|
|
29
|
+
* @param document - The parsed project.
|
|
30
|
+
* @param tagName - Tag name to find.
|
|
31
|
+
* @returns The tag, or undefined when no scope declares it.
|
|
32
|
+
*/
|
|
33
|
+
export declare function findTag(document: L5xDocument, tagName: string): L5xTag | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Read every tag of a controller's scopes.
|
|
36
|
+
*
|
|
37
|
+
* @param controller - The controller element.
|
|
38
|
+
* @returns The controller's tags first, then each program's, in written order.
|
|
39
|
+
*/
|
|
40
|
+
export declare function buildTags(controller: XmlElement): readonly L5xTag[];
|
|
41
|
+
/**
|
|
42
|
+
* One tag entry.
|
|
43
|
+
*
|
|
44
|
+
* Only the fields the export actually declares are emitted, so a caller can
|
|
45
|
+
* tell "declared as false" (`constant` absent) from "declared true".
|
|
46
|
+
*
|
|
47
|
+
* @param tag - The `<Tag>` element.
|
|
48
|
+
* @param scope - The owning scope's name.
|
|
49
|
+
* @returns The tag entry.
|
|
50
|
+
*/
|
|
51
|
+
export declare function parseTag(tag: XmlElement, scope: string): L5xTag;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tag reader — controller-scoped and program-scoped tags, with the scope and
|
|
3
|
+
* data-type filters the tool schema declares.
|
|
4
|
+
*
|
|
5
|
+
* Scope is carried on every entry rather than implied by grouping, because one
|
|
6
|
+
* flat list answers both "what does the controller own" and "what does this
|
|
7
|
+
* program own" without the caller re-nesting it.
|
|
8
|
+
*/
|
|
9
|
+
import { controllerElementOf } from "./parse.js";
|
|
10
|
+
import { descriptionOf, programElements } from "./module.js";
|
|
11
|
+
import { elementChildren, firstChild, optionalAttribute, presentAttribute } from "./xml.js";
|
|
12
|
+
/** The scope name the controller's own tags report. */
|
|
13
|
+
const CONTROLLER_SCOPE = 'controller';
|
|
14
|
+
/**
|
|
15
|
+
* List tags, filtered by scope and data type.
|
|
16
|
+
*
|
|
17
|
+
* A scope of `controller` selects only the controller's tags; any other
|
|
18
|
+
* non-empty scope selects only that program's; an empty scope selects both, with
|
|
19
|
+
* the controller's first. The scope match is exact and case-sensitive except for
|
|
20
|
+
* the literal `controller`, which is matched case-insensitively so `Controller`
|
|
21
|
+
* from a caller still selects the controller's tags.
|
|
22
|
+
*
|
|
23
|
+
* @param document - The parsed project.
|
|
24
|
+
* @param scope - `controller`, a program name, or empty for all.
|
|
25
|
+
* @param dataType - Data type to restrict to; empty keeps every type.
|
|
26
|
+
* @returns Matching tags, in written order.
|
|
27
|
+
*/
|
|
28
|
+
export function listTags(document, scope = '', dataType = '') {
|
|
29
|
+
const tags = selectScope(buildTags(controllerElementOf(document)), scope);
|
|
30
|
+
if (dataType === '')
|
|
31
|
+
return tags;
|
|
32
|
+
return tags.filter(tag => tag.dataType === dataType);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The tags one scope selects.
|
|
36
|
+
*
|
|
37
|
+
* A scope of `controller` selects only the controller's tags; any other
|
|
38
|
+
* non-empty scope selects only that program's; an empty scope selects both. The
|
|
39
|
+
* scope match is exact and case-sensitive except for the literal `controller`,
|
|
40
|
+
* which is matched case-insensitively so `Controller` from a caller still
|
|
41
|
+
* selects the controller's tags.
|
|
42
|
+
*
|
|
43
|
+
* @param tags - Every tag of the project.
|
|
44
|
+
* @param scope - `controller`, a program name, or empty for all.
|
|
45
|
+
* @returns The matching tags, in their original order.
|
|
46
|
+
*/
|
|
47
|
+
function selectScope(tags, scope) {
|
|
48
|
+
if (scope === '')
|
|
49
|
+
return tags;
|
|
50
|
+
if (scope.toLowerCase() === CONTROLLER_SCOPE)
|
|
51
|
+
return tags.filter(tag => tag.scope === CONTROLLER_SCOPE);
|
|
52
|
+
return tags.filter(tag => tag.scope === scope);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Find one tag by name, searching controller scope first and then each program.
|
|
56
|
+
*
|
|
57
|
+
* @param document - The parsed project.
|
|
58
|
+
* @param tagName - Tag name to find.
|
|
59
|
+
* @returns The tag, or undefined when no scope declares it.
|
|
60
|
+
*/
|
|
61
|
+
export function findTag(document, tagName) {
|
|
62
|
+
return buildTags(controllerElementOf(document)).find(tag => tag.name === tagName);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Read every tag of a controller's scopes.
|
|
66
|
+
*
|
|
67
|
+
* @param controller - The controller element.
|
|
68
|
+
* @returns The controller's tags first, then each program's, in written order.
|
|
69
|
+
*/
|
|
70
|
+
export function buildTags(controller) {
|
|
71
|
+
const results = [];
|
|
72
|
+
for (const tag of controllerTags(controller))
|
|
73
|
+
results.push(parseTag(tag, CONTROLLER_SCOPE));
|
|
74
|
+
for (const program of programElements(controller)) {
|
|
75
|
+
const programName = optionalAttribute(program, 'Name', '');
|
|
76
|
+
for (const tag of programTags(program))
|
|
77
|
+
results.push(parseTag(tag, programName));
|
|
78
|
+
}
|
|
79
|
+
return results;
|
|
80
|
+
}
|
|
81
|
+
/** The controller's `<Tag>` elements, in written order. */
|
|
82
|
+
function controllerTags(controller) {
|
|
83
|
+
const tags = firstChild(controller, 'Tags');
|
|
84
|
+
return tags === undefined ? [] : elementChildren(tags, 'Tag');
|
|
85
|
+
}
|
|
86
|
+
/** One program's `<Tag>` elements, in written order. */
|
|
87
|
+
function programTags(program) {
|
|
88
|
+
const tags = firstChild(program, 'Tags');
|
|
89
|
+
return tags === undefined ? [] : elementChildren(tags, 'Tag');
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* One tag entry.
|
|
93
|
+
*
|
|
94
|
+
* Only the fields the export actually declares are emitted, so a caller can
|
|
95
|
+
* tell "declared as false" (`constant` absent) from "declared true".
|
|
96
|
+
*
|
|
97
|
+
* @param tag - The `<Tag>` element.
|
|
98
|
+
* @param scope - The owning scope's name.
|
|
99
|
+
* @returns The tag entry.
|
|
100
|
+
*/
|
|
101
|
+
export function parseTag(tag, scope) {
|
|
102
|
+
const entry = {
|
|
103
|
+
name: optionalAttribute(tag, 'Name', ''),
|
|
104
|
+
dataType: optionalAttribute(tag, 'DataType', ''),
|
|
105
|
+
scope,
|
|
106
|
+
};
|
|
107
|
+
const description = descriptionOf(tag);
|
|
108
|
+
if (description !== '')
|
|
109
|
+
entry.description = description;
|
|
110
|
+
const radix = presentAttribute(tag, 'Radix');
|
|
111
|
+
if (radix !== undefined)
|
|
112
|
+
entry.radix = radix;
|
|
113
|
+
if (tag.attrs['Constant'] === 'true')
|
|
114
|
+
entry.constant = true;
|
|
115
|
+
const externalAccess = presentAttribute(tag, 'ExternalAccess');
|
|
116
|
+
if (externalAccess !== undefined)
|
|
117
|
+
entry.externalAccess = externalAccess;
|
|
118
|
+
return entry;
|
|
119
|
+
}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The parsed-document seam: what a Studio 5000 `.l5x` export becomes once it is
|
|
3
|
+
* parsed, and what reading it yields.
|
|
4
|
+
*
|
|
5
|
+
* Types only — parsing, the read functions, and their errors live beside this
|
|
6
|
+
* file. A document is lossless JSON with no XML nodes in it: an SDK caller, a
|
|
7
|
+
* Remote caller, and an in-process reader all see the same vocabulary, and no
|
|
8
|
+
* payload carries raw XML. Absent means absent: an entry omits a field the
|
|
9
|
+
* export did not supply rather than filling it with a placeholder, because the
|
|
10
|
+
* reference server's JSON omits it too.
|
|
11
|
+
*/
|
|
12
|
+
/** One controller-scoped or program-scoped tag. */
|
|
13
|
+
export interface L5xTag {
|
|
14
|
+
/** Tag name as declared. */
|
|
15
|
+
readonly name: string;
|
|
16
|
+
/** Declared data type, e.g. `BOOL`, `DINT`, `Motor_UDT`. */
|
|
17
|
+
readonly dataType: string;
|
|
18
|
+
/** Owning scope: the literal `controller`, or the declaring program's name. */
|
|
19
|
+
readonly scope: string;
|
|
20
|
+
/** Description, from the `Description` attribute or the child element. */
|
|
21
|
+
readonly description?: string;
|
|
22
|
+
/** Radix the export declares, when it declares one. */
|
|
23
|
+
readonly radix?: string;
|
|
24
|
+
/** Present and true only when the export marks the tag `Constant="true"`. */
|
|
25
|
+
readonly constant?: boolean;
|
|
26
|
+
/** External-access setting, when the export declares one. */
|
|
27
|
+
readonly externalAccess?: string;
|
|
28
|
+
}
|
|
29
|
+
/** One member of a user-defined type. */
|
|
30
|
+
export interface L5xUdtMember {
|
|
31
|
+
/** Member name. */
|
|
32
|
+
readonly name: string;
|
|
33
|
+
/** Declared data type. */
|
|
34
|
+
readonly dataType: string;
|
|
35
|
+
/** Array length, present only when the member declares a non-zero dimension. */
|
|
36
|
+
readonly dimension?: number;
|
|
37
|
+
/** Description, when the member has one. */
|
|
38
|
+
readonly description?: string;
|
|
39
|
+
/** Radix the export declares, when it declares one. */
|
|
40
|
+
readonly radix?: string;
|
|
41
|
+
/** Backing member a BIT member addresses, when the export declares one. */
|
|
42
|
+
readonly target?: string;
|
|
43
|
+
/** Bit position inside the backing member, when the export declares one. */
|
|
44
|
+
readonly bitNumber?: number;
|
|
45
|
+
}
|
|
46
|
+
/** One user-defined type, with the members that are not hidden. */
|
|
47
|
+
export interface L5xUdt {
|
|
48
|
+
/** Type name. */
|
|
49
|
+
readonly name: string;
|
|
50
|
+
/** Description, empty string when the type has none. */
|
|
51
|
+
readonly description: string;
|
|
52
|
+
/** Visible members in declaration order. */
|
|
53
|
+
readonly members: readonly L5xUdtMember[];
|
|
54
|
+
}
|
|
55
|
+
/** One parameter of an add-on instruction. */
|
|
56
|
+
export interface L5xAoiParameter {
|
|
57
|
+
/** Parameter name. */
|
|
58
|
+
readonly name: string;
|
|
59
|
+
/** Declared data type. */
|
|
60
|
+
readonly dataType: string;
|
|
61
|
+
/** `Input`, `Output`, `InOut`, or whatever usage the export declares. */
|
|
62
|
+
readonly usage: string;
|
|
63
|
+
/** Description, when the parameter has one. */
|
|
64
|
+
readonly description?: string;
|
|
65
|
+
/** Present and true only when the export marks the parameter `Required="true"`. */
|
|
66
|
+
readonly required?: boolean;
|
|
67
|
+
/** Present and false only when the export marks the parameter `Visible="false"`. */
|
|
68
|
+
readonly visible?: boolean;
|
|
69
|
+
}
|
|
70
|
+
/** One local tag declared inside an add-on instruction. */
|
|
71
|
+
export interface L5xAoiLocalTag {
|
|
72
|
+
/** Local tag name. */
|
|
73
|
+
readonly name: string;
|
|
74
|
+
/** Declared data type. */
|
|
75
|
+
readonly dataType: string;
|
|
76
|
+
/** Description, when the local tag has one. */
|
|
77
|
+
readonly description?: string;
|
|
78
|
+
}
|
|
79
|
+
/** One ladder rung. */
|
|
80
|
+
export interface L5xRung {
|
|
81
|
+
/** Rung number as the export's `Number` attribute states it. */
|
|
82
|
+
readonly number: number;
|
|
83
|
+
/** Rung comment, when the export carries one. */
|
|
84
|
+
readonly comment?: string;
|
|
85
|
+
/** The rung as compact NeutralText, e.g. `XIC(Motor_Start)OTE(Motor_Run);`. */
|
|
86
|
+
readonly text: string;
|
|
87
|
+
}
|
|
88
|
+
/** Routine body: language-specific, and the discriminant is the routine's `type`. */
|
|
89
|
+
export type L5xRoutineBody =
|
|
90
|
+
/** Ladder body: one entry per rung, in the export's order. */
|
|
91
|
+
{
|
|
92
|
+
readonly type: 'RLL';
|
|
93
|
+
readonly rungs: readonly L5xRung[];
|
|
94
|
+
}
|
|
95
|
+
/** Structured Text body, exactly the routine's lines joined with `\n`. */
|
|
96
|
+
| {
|
|
97
|
+
readonly type: 'ST';
|
|
98
|
+
readonly code: string;
|
|
99
|
+
}
|
|
100
|
+
/** Function Block diagram nodes and connections; execution semantics remain partial. */
|
|
101
|
+
| {
|
|
102
|
+
readonly type: 'FBD';
|
|
103
|
+
readonly nodes: readonly L5xDiagramNode[];
|
|
104
|
+
}
|
|
105
|
+
/** Sequential Function Chart elements and connections; execution semantics remain partial. */
|
|
106
|
+
| {
|
|
107
|
+
readonly type: 'SFC';
|
|
108
|
+
readonly nodes: readonly L5xDiagramNode[];
|
|
109
|
+
}
|
|
110
|
+
/** Any other language the port does not decompose; the note names it. */
|
|
111
|
+
| {
|
|
112
|
+
readonly type: 'other';
|
|
113
|
+
readonly note: string;
|
|
114
|
+
};
|
|
115
|
+
export interface L5xDiagramNode {
|
|
116
|
+
readonly kind: string;
|
|
117
|
+
readonly sheet: number;
|
|
118
|
+
readonly id?: string;
|
|
119
|
+
readonly operand?: string;
|
|
120
|
+
readonly fromId?: string;
|
|
121
|
+
readonly toId?: string;
|
|
122
|
+
readonly text?: string;
|
|
123
|
+
}
|
|
124
|
+
/** One routine as a listing entry: enough to choose it, not its logic. */
|
|
125
|
+
export interface L5xRoutineInfo {
|
|
126
|
+
/** Program the routine belongs to. */
|
|
127
|
+
readonly program: string;
|
|
128
|
+
/** Routine name. */
|
|
129
|
+
readonly name: string;
|
|
130
|
+
/** Language code as written, e.g. `RLL`, `ST`, `FBD`. */
|
|
131
|
+
readonly type: string;
|
|
132
|
+
/** Description, empty string when the routine has none. */
|
|
133
|
+
readonly description: string;
|
|
134
|
+
/** Ladder rungs in the routine; present only for `RLL`. */
|
|
135
|
+
readonly rungCount?: number;
|
|
136
|
+
/** Structured Text lines in the routine; present only for `ST`. */
|
|
137
|
+
readonly lineCount?: number;
|
|
138
|
+
}
|
|
139
|
+
/** One routine with its body. */
|
|
140
|
+
export interface L5xRoutine {
|
|
141
|
+
/** Program the routine belongs to. */
|
|
142
|
+
readonly program: string;
|
|
143
|
+
/** Routine name. */
|
|
144
|
+
readonly name: string;
|
|
145
|
+
/** Language code as written. */
|
|
146
|
+
readonly type: string;
|
|
147
|
+
/** Description, empty string when the routine has none. */
|
|
148
|
+
readonly description: string;
|
|
149
|
+
/** The decoded body. */
|
|
150
|
+
readonly body: L5xRoutineBody;
|
|
151
|
+
}
|
|
152
|
+
/** One add-on instruction as a listing entry. */
|
|
153
|
+
export interface L5xAoiInfo {
|
|
154
|
+
/** Instruction name. */
|
|
155
|
+
readonly name: string;
|
|
156
|
+
/** Description, empty string when it has none. */
|
|
157
|
+
readonly description: string;
|
|
158
|
+
/** Revision the export declares, empty string when it declares none. */
|
|
159
|
+
readonly revision: string;
|
|
160
|
+
}
|
|
161
|
+
/** One add-on instruction with its interface and internal logic. */
|
|
162
|
+
export interface L5xAoiDefinition extends L5xAoiInfo {
|
|
163
|
+
/** Vendor the export declares, empty string when it declares none. */
|
|
164
|
+
readonly vendor: string;
|
|
165
|
+
/** Parameters in declaration order. */
|
|
166
|
+
readonly parameters: readonly L5xAoiParameter[];
|
|
167
|
+
/** Local tags in declaration order. */
|
|
168
|
+
readonly localTags: readonly L5xAoiLocalTag[];
|
|
169
|
+
/** Internal routines in declaration order. */
|
|
170
|
+
readonly routines: readonly L5xRoutine[];
|
|
171
|
+
}
|
|
172
|
+
/** One program's summary. */
|
|
173
|
+
export interface L5xProgram {
|
|
174
|
+
/** Program name. */
|
|
175
|
+
readonly name: string;
|
|
176
|
+
/** Name of the program's main routine, empty string when the export omits it. */
|
|
177
|
+
readonly mainRoutine: string;
|
|
178
|
+
/** Description, empty string when the program has none. */
|
|
179
|
+
readonly description: string;
|
|
180
|
+
}
|
|
181
|
+
/** One task's scheduling summary. */
|
|
182
|
+
export interface L5xTask {
|
|
183
|
+
/** Task name. */
|
|
184
|
+
readonly name: string;
|
|
185
|
+
/** Task type as written, e.g. `CONTINUOUS`, `PERIODIC`, `EVENT`. */
|
|
186
|
+
readonly type: string;
|
|
187
|
+
/** Period, empty string when the export declares none. */
|
|
188
|
+
readonly rate: string;
|
|
189
|
+
/** Priority as written, empty string when the export declares none. */
|
|
190
|
+
readonly priority: string;
|
|
191
|
+
/** Description, empty string when the task has none. */
|
|
192
|
+
readonly description: string;
|
|
193
|
+
/** Names of the programs the task schedules, in the export's order. */
|
|
194
|
+
readonly programs: readonly string[];
|
|
195
|
+
}
|
|
196
|
+
/** One I/O module. */
|
|
197
|
+
export interface L5xModule {
|
|
198
|
+
/** Module name. */
|
|
199
|
+
readonly name: string;
|
|
200
|
+
/** Catalog number, empty string when the export declares none. */
|
|
201
|
+
readonly catalogNumber: string;
|
|
202
|
+
/** Parent module name, empty string for a module the controller owns directly. */
|
|
203
|
+
readonly parentModule: string;
|
|
204
|
+
/** Description, when the module has one. */
|
|
205
|
+
readonly description?: string;
|
|
206
|
+
/** First port's `Address`, which is the slot for a chassis module. */
|
|
207
|
+
readonly slot?: string;
|
|
208
|
+
/** Present and true only when the export marks the module `Inhibited="true"`. */
|
|
209
|
+
readonly inhibited?: boolean;
|
|
210
|
+
}
|
|
211
|
+
/** Alarm metadata found in an export; trigger semantics are not inferred. */
|
|
212
|
+
export interface L5xAlarm {
|
|
213
|
+
readonly name: string;
|
|
214
|
+
readonly kind: string;
|
|
215
|
+
readonly description: string;
|
|
216
|
+
}
|
|
217
|
+
/** The controller-level summary a project listing reports. */
|
|
218
|
+
export interface L5xControllerSummary {
|
|
219
|
+
/** Controller name as the export declares it. */
|
|
220
|
+
readonly name: string;
|
|
221
|
+
/** Processor type as the export declares it, e.g. `1756-L83E`. */
|
|
222
|
+
readonly processorType: string;
|
|
223
|
+
/** Description, empty string when the controller has none. */
|
|
224
|
+
readonly description: string;
|
|
225
|
+
/** Major revision as written, empty string when the export omits it. */
|
|
226
|
+
readonly majorRev: string;
|
|
227
|
+
/** Minor revision as written, empty string when the export omits it. */
|
|
228
|
+
readonly minorRev: string;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* A parsed `.l5x` document.
|
|
232
|
+
*
|
|
233
|
+
* Reading it is pure: the same text always yields the same entries, so a caller
|
|
234
|
+
* may parse once and run every read against the result.
|
|
235
|
+
*/
|
|
236
|
+
export interface L5xDocument {
|
|
237
|
+
/** Controller metadata. */
|
|
238
|
+
readonly controller: L5xControllerSummary;
|
|
239
|
+
/** Programs in the export's order. */
|
|
240
|
+
readonly programs: readonly L5xProgram[];
|
|
241
|
+
/** Tasks in the export's order. */
|
|
242
|
+
readonly tasks: readonly L5xTask[];
|
|
243
|
+
/** Ladder and Structured Text routines of every program, in export order. */
|
|
244
|
+
readonly routines: readonly L5xRoutine[];
|
|
245
|
+
/** Controller-scoped tags first, then each program's, in export order. */
|
|
246
|
+
readonly tags: readonly L5xTag[];
|
|
247
|
+
/** User-defined types in the export's order. */
|
|
248
|
+
readonly udts: readonly L5xUdt[];
|
|
249
|
+
/** Add-on instruction definitions in the export's order. */
|
|
250
|
+
readonly aois: readonly L5xAoiDefinition[];
|
|
251
|
+
/** I/O modules in the export's order. */
|
|
252
|
+
readonly modules: readonly L5xModule[];
|
|
253
|
+
/** Alarm declarations recognized structurally in the export. */
|
|
254
|
+
readonly alarms: readonly L5xAlarm[];
|
|
255
|
+
}
|
|
256
|
+
/** One place a symbol appears. */
|
|
257
|
+
export interface L5xSymbolReference {
|
|
258
|
+
/** Program holding the reference; absent when the reference is inside an AOI. */
|
|
259
|
+
readonly program?: string;
|
|
260
|
+
/** Add-on instruction holding the reference; absent for a program routine. */
|
|
261
|
+
readonly aoi?: string;
|
|
262
|
+
/** Routine holding the reference. */
|
|
263
|
+
readonly routine: string;
|
|
264
|
+
/** Rung number, for a ladder reference. */
|
|
265
|
+
readonly rung?: number;
|
|
266
|
+
/** Line number, for a Structured Text reference. */
|
|
267
|
+
readonly line?: number;
|
|
268
|
+
/** The rung text or source line the symbol was found in. */
|
|
269
|
+
readonly context: string;
|
|
270
|
+
}
|
|
271
|
+
/** One symbol and every place it appears. */
|
|
272
|
+
export interface L5xSymbolUsage {
|
|
273
|
+
/** The symbol as it was written, including any dotted member path. */
|
|
274
|
+
readonly symbol: string;
|
|
275
|
+
/** The references, in the order the routines were scanned. */
|
|
276
|
+
readonly references: readonly L5xSymbolReference[];
|
|
277
|
+
}
|
|
278
|
+
/** What a project listing reports. */
|
|
279
|
+
export interface L5xProjectSummary {
|
|
280
|
+
/** Controller name. */
|
|
281
|
+
readonly controller: string;
|
|
282
|
+
/** Processor type, e.g. `1756-L83E`. */
|
|
283
|
+
readonly processorType: string;
|
|
284
|
+
/** Description, empty string when the controller has none. */
|
|
285
|
+
readonly description: string;
|
|
286
|
+
/** Firmware as `major.minor`, empty when the export declares no revision. */
|
|
287
|
+
readonly firmware: string;
|
|
288
|
+
/** Programs, in written order. */
|
|
289
|
+
readonly programs: readonly L5xProgram[];
|
|
290
|
+
/** Tasks, in written order. */
|
|
291
|
+
readonly tasks: readonly L5xTask[];
|
|
292
|
+
/** How many user-defined types the project defines. */
|
|
293
|
+
readonly udtCount: number;
|
|
294
|
+
/** Those type names, in written order. */
|
|
295
|
+
readonly udts: readonly string[];
|
|
296
|
+
/** How many add-on instructions the project defines. */
|
|
297
|
+
readonly aoiCount: number;
|
|
298
|
+
/** Those instruction names, in written order. */
|
|
299
|
+
readonly aois: readonly string[];
|
|
300
|
+
/** How many I/O modules the controller owns. */
|
|
301
|
+
readonly moduleCount: number;
|
|
302
|
+
/** How many tags exist across every scope. */
|
|
303
|
+
readonly tagCount: number;
|
|
304
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The parsed-document seam: what a Studio 5000 `.l5x` export becomes once it is
|
|
3
|
+
* parsed, and what reading it yields.
|
|
4
|
+
*
|
|
5
|
+
* Types only — parsing, the read functions, and their errors live beside this
|
|
6
|
+
* file. A document is lossless JSON with no XML nodes in it: an SDK caller, a
|
|
7
|
+
* Remote caller, and an in-process reader all see the same vocabulary, and no
|
|
8
|
+
* payload carries raw XML. Absent means absent: an entry omits a field the
|
|
9
|
+
* export did not supply rather than filling it with a placeholder, because the
|
|
10
|
+
* reference server's JSON omits it too.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|