Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"plugins": [
{
"name": "plc-programming",
"description": "Design, write, convert, review and debug PLC programs: IEC 61131-3 (ST, LD, FBD, SFC, IL), PLCopen XML / IEC 61131-10, Siemens TIA (SCL, SimaticML, SIMATIC SD), Schneider (Machine Expert, Control Expert), CODESYS, TwinCAT, ABB Freelance, Rockwell L5X/L5K, IEC 61499, AutomationML, DEXPI, PackML/ISA-88, OPC UA; with a stdlib-only structural validator and an edit-time validation hook.",
"description": "Design, write, convert, review and debug PLC programs: IEC 61131-3 (ST, LD, FBD, SFC, IL), PLCopen XML / IEC 61131-10, Siemens TIA (SCL, SimaticML, SIMATIC SD), Schneider (Machine Expert, Control Expert), CODESYS, TwinCAT, ABB Freelance, Rockwell L5X/L5K, IEC 61499, AutomationML, DEXPI, PackML/ISA-88, OPC UA; with a stdlib-only structural validator, an edit-time validation hook, and an offline reader for CODESYS / Machine Expert .project files.",
"source": "./"
}
]
Expand Down
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
"name": "plc-programming",
"version": "0.1.0",
"version": "0.2.0",
"description": "PLC programming across IEC 61131-3 (ST, LD, FBD, SFC, IL), PLCopen XML / IEC 61131-10, Siemens TIA (SCL, SimaticML, SIMATIC SD), Schneider (Machine Expert, Control Expert), CODESYS, TwinCAT, ABB Freelance, Rockwell L5X/L5K, IEC 61499, AutomationML, DEXPI, PackML/ISA-88 and OPC UA: design, write, convert, review and debug programs, with a stdlib-only structural validator.",
"author": {
"name": "SmailG",
Expand Down
9 changes: 6 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ privately, as described in [SECURITY.md](SECURITY.md). Pull requests use the tem
| `agents/plc-reviewer.md` | Read-only reviewer used by `/plc-programming:review` |
| `hooks/hooks.json` | PostToolUse hook that runs the validator on every file Claude writes or edits |
| `scripts/plc_validate.py` | Validator CLI and hook entry point |
| `scripts/codesys_project.py` | Offline reader for CODESYS 3.5 / Machine Expert `.project` files (`list`, `st`, `dump-st`, `graph`, `info`, `diff`, `xref`); `scripts/codesysproj/` holds `binary.py` (varint, string table), `project.py` (objects, kinds, text), `graph.py` (LD/FBD records) and `graphview.py` (their text and JSON), `export.py` (`dump-st`), `buildinfo.py` (`info`), `diff.py` (`diff`), `xref.py` and `stscan.py` (`xref`) |
| `scripts/plccheck/` | One module per format (`st.py`, `plcopen.py`, `simaticml.py`, `twincat.py`, `logix.py`, `schneider.py`, `iec61499.py`, `aml.py`, `dexpi.py`, `tabular.py`); `findings.py` holds the finding type, `xmlutil.py` the line-numbered XML parser |
| `tests/` | `test_st.py`, `test_formats.py` (validator rules), `test_skills.py` (frontmatter, templates, every `iecst` block lints clean) |
| `tests/` | `test_st.py`, `test_formats.py` (validator rules), `test_codesys_project.py` and `test_codesys_tools.py` (the `.project` reader and its `info`, `diff` and `xref`, on synthetic projects only), `test_skills.py` (frontmatter, templates, every `iecst` block lints clean) |
| `evals/` | `claude plugin eval` cases comparing the plugin against a no-plugin baseline |

## Rules

- **The validator uses only the Python standard library** and must run on Python 3.9 (CI runs
3.9 and 3.12). Optional tools such as `xmllint` or `lxml` are allowed only behind `--xsd`.
- **The validator and the `.project` reader use only the Python standard library** and must
run on Python 3.9 (CI runs 3.9 and 3.12). Optional tools such as `xmllint` or `lxml` are allowed only behind `--xsd`.
- **Every validator rule needs two tests:** an input it must catch and a valid control it must
accept. A rule tested only on bad input cannot show it is not firing on everything.
- **Every fact in a reference file is sourced or marked unverified.** Name the manual, standard
Expand All @@ -30,6 +31,8 @@ privately, as described in [SECURITY.md](SECURITY.md). Pull requests use the tem
- **Bump the version** in `.claude-plugin/plugin.json` on every change; `claude plugin update`
does nothing while it is unchanged.
- Do not bundle vendor schemas or manuals whose licence does not clearly permit redistribution.
- **Test fixtures for the `.project` reader are synthetic.** Never commit a real `.project`,
or names, text or guids taken from one: it is someone's program.

## Tests

Expand Down
30 changes: 28 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ git clone https://github.com/SmailG/plc-programming.git .agents/plugins/plc-prog
| `schneider` skill | automatic | Machine Expert (M241/M251/M262), Control Expert (M340/M580), Automation Expert, Modbus, EtherNet/IP, OPC UA |
| `iec-61131-3` skill | automatic | Ed.2–Ed.4, the five languages, POUs, OOP, data types, the standard library, PLCopen guidelines, Motion and Safety |
| `exchange-formats` skill | automatic | PLCopen XML (TC6 v2.0/v2.01), IEC 61131-10, AutomationML (IEC 62714), DEXPI / ISO 15926 |
| `other-platforms` skill | automatic | Beckhoff TwinCAT, CODESYS, ABB Freelance (PRT/CSV) / AC500 / 800xA, Rockwell L5X/L5K |
| `other-platforms` skill | automatic | Beckhoff TwinCAT, CODESYS (incl. reading a binary `.project` offline: ST, build identity, version diff, cross-reference), ABB Freelance (PRT/CSV) / AC500 / 800xA, Rockwell L5X/L5K |
| `iec-61499` skill | automatic | event-driven FBs, ECC, 4diac file formats |
| `packml-isa88-opcua` skill | automatic | PackML states and PackTags, ISA-88 / IEC 61512, OPC UA (OPC 30000/30001/30050) |
| `/plc-programming:new-pou` | user only | scaffold a POU for a chosen platform and format |
Expand Down Expand Up @@ -78,6 +78,31 @@ The official XSDs (PLCopen TC6, IEC 61131-10) are **not bundled** because their
do not clearly permit redistribution. Download them from
<https://www.plcopen.org/downloads/> and pass `--xsd`.

## The CODESYS `.project` reader

```bash
python3 scripts/codesys_project.py list project.project
python3 scripts/codesys_project.py st project.project <name|guid>
python3 scripts/codesys_project.py dump-st project.project out/
python3 scripts/codesys_project.py graph project.project <name|guid> [--json]
python3 scripts/codesys_project.py info project.project
python3 scripts/codesys_project.py diff old.project new.project [<name|guid>]
python3 scripts/codesys_project.py xref project.project <name>
```

Reads a CODESYS 3.5 / EcoStruxure Machine Expert `.project` without the IDE (standard
library only, Python 3.9+). **The format is undocumented**: the reader is reverse-engineered
and was checked on Machine Expert V2.x files only. ST text and the object inventory are
decoded (`dump-st` writes every ST POU and every GVL and DUT declaration); graphical (LD/FBD)
records are listed with every interpretation marked as a heuristic, and the wiring is not
decoded. `info` prints each application's CodeId / DataId (a lead to which saved project the
controller runs; the IDE's comparison decides) and the last save time; `diff` compares two
versions of a POU or of the whole project with ids and offsets left out; `xref` lists every use
of a name, by name only (heuristic). Damaged, encrypted or oversized zip entries are reported,
not crashed on. Prefer a PLCopen XML export from the IDE when you
can get one, and verify graphical logic in the IDE. Details:
[codesys-project-files.md](skills/other-platforms/references/codesys-project-files.md).

## Tests and evals

```bash
Expand All @@ -86,7 +111,8 @@ claude plugin eval . --trust-plugin --allow-tools Write Edit "Bash(python3 *)" -
```

- **Unit tests:** every validator rule is exercised by an input it must catch and by a
valid control it must pass. Every shipped template and every `iecst` code block in the
valid control it must pass. The `.project` reader is tested on synthetic projects built in
the test, never on a real program. Every shipped template and every `iecst` code block in the
skills must lint clean.
- **Evals:** they compare the plugin against a no-plugin baseline on edition facts, SFC
semantics, a classic scan-cycle bug, PLCopen XML generation, SimaticML namespaces,
Expand Down
2 changes: 1 addition & 1 deletion plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "plc-programming",
"displayName": "PLC Programming",
"version": "0.1.0",
"version": "0.2.0",
"description": "PLC programming across IEC 61131-3 (ST, LD, FBD, SFC, IL), PLCopen XML / IEC 61131-10, Siemens TIA, Schneider, CODESYS, TwinCAT, ABB Freelance, Rockwell L5X/L5K, IEC 61499, AutomationML, DEXPI, PackML/ISA-88 and OPC UA with a stdlib-only structural validator.",
"author": {
"name": "SmailG",
Expand Down
Loading