Documentation
plccheck CLI
Use npx plccheck for Siemens PLC diagnostics, tests, coverage, transpilation, and automation.
plccheck CLI
plccheck is the command-line tool for checking, testing, and exporting Siemens PLC projects from a terminal or automation workflow.
Use it with npx:
npx plccheck check ./my-plc-project
The CLI is useful when you want the same PLC feedback outside the VS Code UI: local terminal checks, CI jobs, scripted validation, or LLM/agent workflows that need a reliable command to inspect a Siemens project.
Project Layout
plccheck works best when each PLC project has a .plc.json file at its root. The PLC root defines the symbol and type scope for files below it.
{
"name": "PackingLine PLC",
"libraries": [
"../shared_types"
]
}
Supported project files include SCL / Structured Text source, S7DCL exports, S7RES resources, data blocks, UDTs, AWL files, PLC tag-table XML, and .scltest test files.
TIA exports preserve project-library instances in the same shape as TIA VCI exports: library-owned PLC objects become .liblink placeholders in the PLC folder, while the shared library definition is written once under a sibling Types folder with .libinfo and .libint sidecars. The generated .plc.json points at ../Types, so plccheck resolves those placeholders without duplicating library code in every PLC.
Quick Commands
| Task | Command |
|---|---|
| Check a PLC project | npx plccheck check ./my-plc-project |
| Run PLC tests | npx plccheck test ./my-plc-project |
| Run one test subset | npx plccheck test ./my-plc-project --filter motor |
| Write coverage artifacts | npx plccheck test ./my-plc-project --coverage-json coverage.json --coverage-lcov lcov.info |
| Stream machine-readable test events | npx plccheck test ./my-plc-project --events-json |
| Transpile S7DCL FBD/LAD to SCL | npx plccheck transpile --to scl ./Program.s7dcl |
| Build a PLC runtime executable | npx plccheck compile --out plc-run.exe ./my-plc-project |
| Build and run a PLC runtime | npx plccheck run ./my-plc-project -- --opcua-port 4849 |
| Export blocks from TIA Portal | npx plccheck tia export --project Demo.ap21 --out exported --plc PLC_1 |
| Start an LSP server | npx plccheck serve |
Check PLC Source
Use check to parse and type-check a file, folder, or PLC root.
npx plccheck check ./my-plc-project
The command exits non-zero when it finds errors. This makes it suitable for CI and for agent workflows where a tool needs a clear success/failure signal.
Useful flags:
| Flag | Description |
|---|---|
--jobs N | Controls parallel checking. Defaults to the available Go runtime parallelism. |
--show-warnings | Prints warning diagnostics as well as errors. |
Example:
npx plccheck check --show-warnings --jobs 4 ./my-plc-project
Run PLC Tests
Use test to run .scltest suites for a PLC root.
npx plccheck test ./my-plc-project
The test runtime is designed for fast iteration. It generates a runtime for the PLC project, runs selected test cases, and resets generated runtime state quickly between tests.
Useful flags:
| Flag | Description |
|---|---|
--filter <text> | Runs only test cases whose names contain the filter text. |
--list-cases | Prints selected test cases before running. |
--parallel N | Controls parallel execution of generated test cases. |
--events-json | Streams machine-readable test events to stdout. |
--entry-ob <name> | Sets the whole-program entry OB when the default OB1 is not correct. |
Examples:
npx plccheck test ./my-plc-project --filter startup
npx plccheck test ./my-plc-project --events-json
npx plccheck test ./my-plc-project --entry-ob Main
Generate Coverage
Use coverage flags with test to write reports.
npx plccheck test ./my-plc-project --coverage-json coverage.json --coverage-lcov lcov.info
Coverage artifacts include statement, function, and branch data where runtime data is available.
| Artifact | Use |
|---|---|
--coverage-json <file> | Structured coverage data for custom tools, CI summaries, and LLM/agent analysis. |
--coverage-lcov <file> | LCOV tracefile for coverage viewers such as Coverage Gutters. |
If you use Coverage Gutters, lcov.info is a convenient default filename:
npx plccheck test ./my-plc-project --coverage-json coverage.json --coverage-lcov lcov.info
Compile and Run PLC Runtime
Use compile to generate a temporary Go runtime and build a standalone executable:
npx plccheck compile --out plc-run.exe ./my-plc-project
Use run to build and launch the runtime in one step. Runtime arguments go after --:
npx plccheck run ./my-plc-project -- --opcua-port 4849 --scan-period 24h
Transpile S7DCL to SCL
Use transpile to inspect generated SCL for TIA Portal exports.
npx plccheck transpile --to scl ./Program.s7dcl
For ambiguous inputs, provide the source form explicitly:
npx plccheck transpile --from s7dcl-fbd --to scl ./Program.s7dcl
npx plccheck transpile --from s7dcl-lad --to scl ./Program.s7dcl
This is useful when reviewing graphical FBD/LAD exports in text-based workflows or when an agent needs to reason about the equivalent SCL.
Emit Source Summaries
Use emit when you need a derived representation of a source file.
npx plccheck emit --target scl-summary ./Program.scl
Use this for inspection and automation tasks where a compact summary is easier to consume than the original export.
LSP Server Mode
serve starts the language server over stdio:
npx plccheck serve
Most users do not need to call this directly. It is intended for editor integrations or tools that can speak the Language Server Protocol.
TIA Portal Openness
On Windows x64 machines with TIA Portal Openness V21 or newer, tia commands attach to a running TIA project or open an explicit .ap21/.zap21 path. For an already open project, --project can be the exact project name shown by tia list --json instead of the full project path.
npx plccheck tia list --json
npx plccheck tia compile --project "Demo Project" --plc PLC_1 --json
npx plccheck tia export --project Demo.ap21 --out exported --plc PLC_1 --delete-stale
npx plccheck tia import --project Demo.ap21 --root exported "exported/PLC_1/Program blocks/Main.scl" --create
npx plccheck tia import --project Demo.ap21 --root exported --skip-library-instances "exported/PLC_1"
npx plccheck tia import --project Demo.ap21 --root exported "exported/PLC_1/Program blocks"
npx plccheck tia repair-library-dependencies --project Demo.ap21 --plc PLC_1 --owner CA
npx plccheck tia compile --project Demo.ap21 --plc PLC_1 --json
npx plccheck tia online --project Demo.ap21 --plc PLC_1
npx plccheck tia online --project Demo.ap21 --plc PLC_1 --online-auth-type ProjectUser --online-user engineer --online-password-env TIA_PROJECT_PASSWORD
npx plccheck tia offline --project Demo.ap21 --plc PLC_1
npx plccheck tia snapshot --project Demo.ap21 --plc PLC_1 --json
npx plccheck tia download --project Demo.ap21 --plc PLC_1 --json
Without --json, project-scoped tia list prints a PLC summary table with block/type counts and example commands using the listed PLC names. Human tia export output prints each exported block and data type path relative to the export directory with its real file extension, then finishes with exported/failed block counts instead of dumping the structured file list. Use --json when scripts need the full structured result.
export writes each PLC under its own PLC-name root with a .plc.json file and preserves Program blocks / PLC data types folders. SCL blocks are emitted through TIA external-source generation as .scl; PLC types, DBs, FBD, and LAD blocks are emitted through TIA document export first so the main editable output is .s7dcl. The export job runs inside one TIA exclusive-access scope across all selected PLCs, and the scope text is updated for each block or type with item progress, percentage, and ETA so long document exports show continuous TIA progress. Each item is staged in a clean temporary folder before replacing that item's previous files, so re-exporting into the same output directory does not require deleting it first. import accepts one or more source files or folders, expands folders recursively, infers the target PLC from paths under Program blocks / PLC data types, and requires --create before creating missing TIA folders or blocks. Supported direct import sources are .scl, .s7dcl, .db, .udt, .xml, .awl, .lad, and .fbd; pass the owning source file instead of .s7res resource sidecars or .meta.json metadata sidecars. When an import would overwrite an existing project-library type instance or one of its project-library dependencies, it fails by default because plain document/source import detaches that object from its library type; pass --skip-library-instances to leave those library-owned targets unchanged and continue importing the rest, or pass --allow-library-instance-overwrite only for an intentional mutation run. repair-library-dependencies is the safe repair path for that failure class: it recreates the named library instance's project-local dependency objects from the project library. compile, online, offline, snapshot, and download operate on all PLCs unless --plc narrows the scope; snapshot skips safety DBs and DBs without retained members while reporting skip/error data. download compiles first, uses the target configured in the TIA project, reports the selected target in JSON, and falls back to software-only changes when Siemens Openness rejects a full load because of fail-safe data.
Device actions automatically accept non-secret TLS/online authentication modes when TIA exposes them, such as trusted TLS, anonymous user, single sign-on, or no user. If the PLC requires explicit credentials, pass --online-auth-type ProjectUser|GlobalUser|PasswordOnly, --online-user <name> where applicable, and --online-password-env <env> so the password comes from an environment variable instead of the process command line. The bridge also reads PLCCHECK_TIA_ONLINE_USER_TYPE or PLCCHECK_TIA_ONLINE_AUTH_TYPE, PLCCHECK_TIA_ONLINE_USER, and PLCCHECK_TIA_ONLINE_PASSWORD when flags are omitted.
Use npx plccheck tia trust --json to inspect the Siemens Openness AllowList entry for the packaged bridge. The result includes installed, the required entry, registryFile, and existingEntry when a stale registry entry already exists for the bridge. Use --install to install the required entry and avoid repeated TIA Openness firewall prompts for the same bridge executable; if the current shell is not elevated, Windows will ask for administrator approval through UAC. If that relaunch path is blocked, save registryFile as a .reg file and import it from an already elevated shell.
Agent-Friendly Usage
For LLM coding agents and search tools, these are the most useful commands:
npx plccheck check ./my-plc-project
npx plccheck test ./my-plc-project
npx plccheck test ./my-plc-project --coverage-json coverage.json --coverage-lcov lcov.info
npx plccheck transpile --to scl ./Program.s7dcl
npx plccheck tia export --project Demo.ap21 --out exported --json
Recommended agent workflow:
- Locate the PLC root containing
.plc.json. - Run
npx plccheck check <plc-root>before changing behavior. - Add or update
.scltestfiles for the target block. - Run
npx plccheck test <plc-root>. - Use
--coverage-jsonwhen coverage or branch visibility matters. - Use
transpile --to sclwhen reviewing S7DCL FBD/LAD exports.
The CLI returns process exit codes that automation can trust: successful checks/tests exit with 0; diagnostics, failing tests, invalid paths, or invalid options exit non-zero.