0
0
Fork 0
Commit graph

4 commits

Author SHA1 Message Date
Karstein Phobic Nyvold Kvistad
ef259c8ee3 fix(online tools): auto-login + non-CONSTANT version GVL
Two related v5-sweep fixes for the online/runtime tool family:

1. Auto-login helper for headless mode

   In headless mode each MCP call spawns a fresh CODESYS --noUI process,
   so the login state established by connect_to_device dies before the
   next call. Pre-fix, only connect_to_device and download_to_device did
   their own login(); the other four (start_stop_application,
   read_variable, write_variable, read_running_version_online) silently
   failed in headless with 'Application not logged in.' (start/stop) or
   'Invalid expression' (read/write). They worked in persistent mode
   only because the login carried across calls.

   Added ensure_logged_in(online_app, login_wait_seconds=30) to
   ensure_online_connection.py. Idempotent: short-circuits via
   online_app.is_logged_in (persistent mode is a no-op, no extra login
   roundtrip). When not logged in, runs the same enum-probe + call-shape
   probe + STABLE_STATES settle-wait pattern as connect_to_device.py.
   Added to start_stop_application.py, read_variable.py,
   write_variable.py, read_running_version_online.py.

2. _MCP_PROJECT_VERSION GVL emitted as plain VAR_GLOBAL, not CONSTANT

   CODESYS inlines VAR_GLOBAL CONSTANT scalars at compile time and
   strips them from the online symbol table. The whole point of
   _MCP_PROJECT_VERSION.sVersion is to be readable live from the
   running PLC, so CONSTANT was the wrong storage class.
   read_running_version_online failed against EVERY project bumped via
   the old template -- 'Invalid expression' on the runtime read.

   Dropped CONSTANT from VERSION_GVL_DECLARATION_TEMPLATE in
   bump_project_version.py. Existing projects auto-migrate on the next
   bump because maintain_version_gvl()'s existing-GVL branch overwrites
   textual_declaration with the (now non-CONSTANT) template. The string
   is still effectively read-only at runtime -- only the bump tool
   updates it.

   read_running_version_online.py also got a more precise error message
   that explicitly fingerprints the 'Invalid expression' failure mode
   and points at the CONSTANT root cause. Useful for any user landing
   on a project that pre-dates this fix.

Verified end-to-end against local CODESYS Control Win V3 (PLATEA, port
11740) on MCPTest2 v1.3.4.0:
- connect_to_device, get_application_state, download_to_device,
  start_stop_application (both directions), read_variable
  (PLC_PRG.watchdog1 = 225 ticking), write_variable (200 -> 204 in 4s
  proves write took), disconnect_from_device: all 7 PASS.
- read_running_version_online failure reproduced (CONSTANT inlined),
  fix landed -- next bump on MCPTest2 will validate.

37/37 unit/integration tests green. TEST_OVERVIEW.md updated with the
v5 device sweep, with the headless-mode deep-dive, and with the
broken-by-design notes on read_running_version_online.
2026-04-26 19:54:13 +02:00
Karstein Phobic Nyvold Kvistad
64906c4ab5 fix(write_variable): use SP22 prepare-then-write API as primary path
After 010811b's diagnostic dump revealed the actual online_app surface on
SP22 Patch 1:

  ['Dispose', 'application', 'application_state', 'create_boot_application',
   'force_prepared_values', 'get_forced_expressions', 'get_online_device',
   'get_prepared_expressions', 'get_prepared_value', 'is_logged_in', 'login',
   'logout', 'operation_state', 'read_value', 'read_values', 'reset',
   'set_prepared_value', 'set_unforce_value', 'source_download', 'start',
   'stop', 'timeout', 'unforce_all_values', 'write_prepared_values']

There is no direct write_value / write / set_value method. The supported
pattern is two-step:

    online_app.set_prepared_value(path, value)   # stage
    online_app.write_prepared_values()           # commit

Asymmetric to read_value() (which is direct), but it's what the SP21+/SP22
scriptengine surface exposes.

This commit:
  - Makes the prepare-then-write path the primary code path.
  - Keeps the direct write_value / set_value / write / set fallbacks for
    older SPs that still expose them (probe order: prepare-first, then
    direct).
  - Falls back to dumping dir(online_app) on total failure, same diagnostic
    pattern that revealed this API in the first place.

Note for future reference: 'force_prepared_values()' is the alternate
commit method when you want to FORCE a value (override what the program
will write next cycle), versus 'write_prepared_values()' which is a normal
one-shot write.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 18:37:38 +02:00
Karstein Phobic Nyvold Kvistad
010811b342 fix(write_variable): probe write methods + diagnostic dump on miss
Mirror of the connect_to_device probe pattern (e862846). The fork's
prior write_variable.py hard-coded write_value() then write() and
errored if neither existed; on SP22 Patch 1 neither is exposed on
online_app, even though the read counterpart (read_value()) works.

Now tries six method names in priority order:
  - Single-write: write_value, set_value, write, set
  - Batch-write:  write_values, set_values   (passes [(name, value)])

On total miss, dumps sorted dir(online_app) so the next debug session
sees exactly what the live online application object exposes -- the
same diagnostic technique that found 'librarymanager' in the earlier
install_library_file probe.

read_variable already works (uses read_value()) so the asymmetry is
specifically on the write side. Verifying by re-running write_variable
after the MCP restart will reveal which method actually exists, and
we can pin it explicitly in a follow-up if useful.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 18:32:57 +02:00
Luke
aad246576c Add 17 new MCP tools for v0.4.0: compiler diagnostics, project authoring, runtime monitoring, library management
- Phase 1: Structured compiler diagnostics — compile_project now returns parsed errors/warnings with object name and line number; new get_compile_messages tool reads last build messages without recompiling
- Phase 2: Project authoring — create_dut, create_gvl, create_folder, delete_object, rename_object, get_all_pou_code
- Phase 3: Online/runtime — connect_to_device, disconnect_from_device, get_application_state, read_variable, write_variable, download_to_device, start_stop_application (with ensure_online_connection helper)
- Phase 4: Library management — list_project_libraries, add_library
- Bump version to 0.4.0, update README with full tool reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 21:05:12 +10:00