Stale device addresses (cached in the project's Communication Settings)
are the #1 cause of download_to_device hanging silently: the gateway is
up, but the PLC has moved to a new router address after a reboot/DHCP
event, so login() waits forever on a UI dialog the agent can't see.
Adds three new tools:
- scan_network_devices: drives gateway.perform_network_scan() and emits
the list of discovered targets (device_name, type_name, vendor_name,
address, device_id). Supports useCache=true to read the gateway's
last cached scan result instead.
- verify_device_reachable: scans the gateway and reports whether the
project's cached device address matches a live target. Returns
reachable=true/false plus the candidate list.
- rebind_device_to_scan_result: matches a scan result (by name, by
device_id, by forced address, or single-candidate) and calls
device.set_gateway_and_address() + saves the project so the new
binding persists across CODESYS restarts.
And wires download_to_device to run verify_device_reachable BEFORE
login(). If unreachable, the tool fails fast with a clear hint to call
rebind_device_to_scan_result, instead of dropping into the IDE dialog.
Pass skipReachabilityCheck=true to force-bypass if the gateway/cache
lookup itself is broken on a given SP.
Helper find_target_device.py is shared across the three new scripts.