fix: gateway auto-register (env-driven), add_library backout, remove_library exact verify
Three fixes found while running an NVL-over-UDP benchmark on Linux-SL (x64) and
WAGO 750-8216 PFC200 (ARM) targets:
- _find_gateway (scan/rebind/verify): when the device gateway GUID is absent from
scriptengine.online.gateways (fresh/headless profile), auto-register one under that
GUID from env vars (CODESYS_GATEWAY_ADDR / _PORT / _NAME, default port 1217). No
hard-coded IPs; unchanged behaviour when the env var is unset.
- add_library: gate the post-add hollow-check backout on `resolved_lib is None` so a
genuine managed add (whose effective_resolution only fills after reopen) is not
discarded as unresolvable ("Project NOT saved").
- remove_library: verify removal by EXACT name, not prefix match, so a same-base-name
sibling (e.g. "X" vs "X, * (System)") no longer triggers a false "still present".
Also docs/NVL_BENCH_FINDINGS.md: the fixes, proposed tools (reload_library,
swap_device, close_project, set_task_interval, bootstrap_device_user) and SysSocket
SP21 signatures captured during the bench.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
d29ebfcb8f
commit
f43ecff100
5 changed files with 68 additions and 4 deletions
|
|
@ -541,8 +541,11 @@ try:
|
||||||
print("SCRIPT_ERROR: %s" % msg)
|
print("SCRIPT_ERROR: %s" % msg)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not _is_resolved(new_ref):
|
if not _is_resolved(new_ref) and resolved_lib is None:
|
||||||
# Unresolvable placeholder. Remove it before save() and report.
|
# Unresolvable placeholder. Remove it before save() and report.
|
||||||
|
# Only back out when we did NOT pre-resolve to a real installed ManagedLib;
|
||||||
|
# a genuine managed add fills in effective_resolution only after reopen, so the
|
||||||
|
# hollow-check is a false negative there and must not discard it. (NVL-bench fix)
|
||||||
eff = getattr(new_ref, 'effective_resolution', None)
|
eff = getattr(new_ref, 'effective_resolution', None)
|
||||||
is_ph = getattr(new_ref, 'is_placeholder', None)
|
is_ph = getattr(new_ref, 'is_placeholder', None)
|
||||||
removed_ok, rem_err = _try_remove(lib_manager, LIBRARY_NAME)
|
removed_ok, rem_err = _try_remove(lib_manager, LIBRARY_NAME)
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,23 @@ def _find_gateway(target_device):
|
||||||
return gw
|
return gw
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
# NVL-bench fix: when the device gateway GUID is not configured in this IDE profile
|
||||||
|
# (fresh/headless profile), auto-register one under that GUID from env vars so online
|
||||||
|
# tools work without manually picking a gateway in the IDE dropdown. Address/port are
|
||||||
|
# NOT hard-coded -- set CODESYS_GATEWAY_ADDR (and optionally _PORT/_NAME).
|
||||||
|
try:
|
||||||
|
import os as _os
|
||||||
|
_addr = _os.environ.get("CODESYS_GATEWAY_ADDR")
|
||||||
|
if _addr:
|
||||||
|
import System as _Sys
|
||||||
|
_port = int(_os.environ.get("CODESYS_GATEWAY_PORT", "1217"))
|
||||||
|
_gw = online.gateways.add_new_gateway(
|
||||||
|
_os.environ.get("CODESYS_GATEWAY_NAME", "mcp-gateway"),
|
||||||
|
{0: _addr, 1: _port}, None, _Sys.Guid(target_guid))
|
||||||
|
print("DEBUG: auto-registered gateway %s:%d under guid %s" % (_addr, _port, target_guid))
|
||||||
|
return _gw
|
||||||
|
except Exception as _e:
|
||||||
|
print("DEBUG: gateway auto-registration failed: %s" % _e)
|
||||||
raise RuntimeError("Device's gateway Guid %s is not in scriptengine.online.gateways." % target_guid)
|
raise RuntimeError("Device's gateway Guid %s is not in scriptengine.online.gateways." % target_guid)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,9 +135,19 @@ try:
|
||||||
lib_manager.remove_library(existing_name)
|
lib_manager.remove_library(existing_name)
|
||||||
print("DEBUG: remove_library('%s') returned without exception." % existing_name)
|
print("DEBUG: remove_library('%s') returned without exception." % existing_name)
|
||||||
|
|
||||||
# Verify removal succeeded by re-checking lm.references.
|
# Verify removal succeeded by re-checking lm.references. Use EXACT-name equality
|
||||||
still_present = _find_reference(lib_manager, LIBRARY_NAME)
|
# against the specific removed ref, not prefix-matching _find_reference -- otherwise a
|
||||||
if still_present is not None:
|
# same-base-name sibling (e.g. 'X' vs 'X, * (System)') causes a false 'still present'
|
||||||
|
# failure and refuses to save a successful removal. (NVL-bench fix)
|
||||||
|
def _exact_present(lm, name):
|
||||||
|
try: refs = lm.references
|
||||||
|
except Exception: return False
|
||||||
|
for r in (refs or []):
|
||||||
|
try:
|
||||||
|
if getattr(r, 'name', None) == name: return True
|
||||||
|
except Exception: pass
|
||||||
|
return False
|
||||||
|
if _exact_present(lib_manager, existing_name):
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"remove_library('%s') returned without error but the reference "
|
"remove_library('%s') returned without error but the reference "
|
||||||
"is still present in lm.references. Project NOT saved." % existing_name)
|
"is still present in lm.references. Project NOT saved." % existing_name)
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,23 @@ def _find_gateway(target_device):
|
||||||
return gw
|
return gw
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
# NVL-bench fix: when the device gateway GUID is not configured in this IDE profile
|
||||||
|
# (fresh/headless profile), auto-register one under that GUID from env vars so online
|
||||||
|
# tools work without manually picking a gateway in the IDE dropdown. Address/port are
|
||||||
|
# NOT hard-coded -- set CODESYS_GATEWAY_ADDR (and optionally _PORT/_NAME).
|
||||||
|
try:
|
||||||
|
import os as _os
|
||||||
|
_addr = _os.environ.get("CODESYS_GATEWAY_ADDR")
|
||||||
|
if _addr:
|
||||||
|
import System as _Sys
|
||||||
|
_port = int(_os.environ.get("CODESYS_GATEWAY_PORT", "1217"))
|
||||||
|
_gw = online.gateways.add_new_gateway(
|
||||||
|
_os.environ.get("CODESYS_GATEWAY_NAME", "mcp-gateway"),
|
||||||
|
{0: _addr, 1: _port}, None, _Sys.Guid(target_guid))
|
||||||
|
print("DEBUG: auto-registered gateway %s:%d under guid %s" % (_addr, _port, target_guid))
|
||||||
|
return _gw
|
||||||
|
except Exception as _e:
|
||||||
|
print("DEBUG: gateway auto-registration failed: %s" % _e)
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"Device's configured gateway (Guid %s) is not in scriptengine.online.gateways. "
|
"Device's configured gateway (Guid %s) is not in scriptengine.online.gateways. "
|
||||||
"Open the IDE Gateway dropdown and pick a configured gateway." % target_guid
|
"Open the IDE Gateway dropdown and pick a configured gateway." % target_guid
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,23 @@ def _find_gateway(target_device):
|
||||||
return gw
|
return gw
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
# NVL-bench fix: when the device gateway GUID is not configured in this IDE profile
|
||||||
|
# (fresh/headless profile), auto-register one under that GUID from env vars so online
|
||||||
|
# tools work without manually picking a gateway in the IDE dropdown. Address/port are
|
||||||
|
# NOT hard-coded -- set CODESYS_GATEWAY_ADDR (and optionally _PORT/_NAME).
|
||||||
|
try:
|
||||||
|
import os as _os
|
||||||
|
_addr = _os.environ.get("CODESYS_GATEWAY_ADDR")
|
||||||
|
if _addr:
|
||||||
|
import System as _Sys
|
||||||
|
_port = int(_os.environ.get("CODESYS_GATEWAY_PORT", "1217"))
|
||||||
|
_gw = online.gateways.add_new_gateway(
|
||||||
|
_os.environ.get("CODESYS_GATEWAY_NAME", "mcp-gateway"),
|
||||||
|
{0: _addr, 1: _port}, None, _Sys.Guid(target_guid))
|
||||||
|
print("DEBUG: auto-registered gateway %s:%d under guid %s" % (_addr, _port, target_guid))
|
||||||
|
return _gw
|
||||||
|
except Exception as _e:
|
||||||
|
print("DEBUG: gateway auto-registration failed: %s" % _e)
|
||||||
raise RuntimeError("Device's gateway Guid %s is not in scriptengine.online.gateways." % target_guid)
|
raise RuntimeError("Device's gateway Guid %s is not in scriptengine.online.gateways." % target_guid)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue