cambiate le dimensioni della finestra, settato porte di debug per essere le stesse del programma, cambiato reset target verso server
This commit is contained in:
parent
ab22246f54
commit
a0652998ab
@ -2,7 +2,7 @@
|
|||||||
"general": {
|
"general": {
|
||||||
"scan_limit": 60,
|
"scan_limit": 60,
|
||||||
"max_range": 100,
|
"max_range": 100,
|
||||||
"geometry": "1599x1089+587+179",
|
"geometry": "1599x1075+587+179",
|
||||||
"last_selected_scenario": "scenario_dritto",
|
"last_selected_scenario": "scenario_dritto",
|
||||||
"connection": {
|
"connection": {
|
||||||
"target": {
|
"target": {
|
||||||
|
|||||||
@ -6,10 +6,10 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
# --- Version Data (Generated) ---
|
# --- Version Data (Generated) ---
|
||||||
__version__ = "v.0.0.0.62-0-g00ffcb5-dirty"
|
__version__ = "v.0.0.0.67-0-gc8c1bb0-dirty"
|
||||||
GIT_COMMIT_HASH = "00ffcb54a320df4b682bb77920dbb758e10fbca0"
|
GIT_COMMIT_HASH = "c8c1bb0f372c8217a86fbdb82e4922888594d2ba"
|
||||||
GIT_BRANCH = "master"
|
GIT_BRANCH = "master"
|
||||||
BUILD_TIMESTAMP = "2025-10-31T11:56:55.656151+00:00"
|
BUILD_TIMESTAMP = "2025-11-03T11:17:11.985027+00:00"
|
||||||
IS_GIT_REPO = True
|
IS_GIT_REPO = True
|
||||||
|
|
||||||
# --- Default Values (for comparison or fallback) ---
|
# --- Default Values (for comparison or fallback) ---
|
||||||
@ -17,7 +17,6 @@ DEFAULT_VERSION = "0.0.0+unknown"
|
|||||||
DEFAULT_COMMIT = "Unknown"
|
DEFAULT_COMMIT = "Unknown"
|
||||||
DEFAULT_BRANCH = "Unknown"
|
DEFAULT_BRANCH = "Unknown"
|
||||||
|
|
||||||
|
|
||||||
# --- Helper Function ---
|
# --- Helper Function ---
|
||||||
def get_version_string(format_string=None):
|
def get_version_string(format_string=None):
|
||||||
"""
|
"""
|
||||||
@ -45,38 +44,28 @@ def get_version_string(format_string=None):
|
|||||||
|
|
||||||
replacements = {}
|
replacements = {}
|
||||||
try:
|
try:
|
||||||
replacements["version"] = __version__ if __version__ else DEFAULT_VERSION
|
replacements['version'] = __version__ if __version__ else DEFAULT_VERSION
|
||||||
replacements["commit"] = GIT_COMMIT_HASH if GIT_COMMIT_HASH else DEFAULT_COMMIT
|
replacements['commit'] = GIT_COMMIT_HASH if GIT_COMMIT_HASH else DEFAULT_COMMIT
|
||||||
replacements["commit_short"] = (
|
replacements['commit_short'] = GIT_COMMIT_HASH[:7] if GIT_COMMIT_HASH and len(GIT_COMMIT_HASH) >= 7 else DEFAULT_COMMIT
|
||||||
GIT_COMMIT_HASH[:7]
|
replacements['branch'] = GIT_BRANCH if GIT_BRANCH else DEFAULT_BRANCH
|
||||||
if GIT_COMMIT_HASH and len(GIT_COMMIT_HASH) >= 7
|
replacements['timestamp'] = BUILD_TIMESTAMP if BUILD_TIMESTAMP else "Unknown"
|
||||||
else DEFAULT_COMMIT
|
replacements['timestamp_short'] = BUILD_TIMESTAMP.split('T')[0] if BUILD_TIMESTAMP and 'T' in BUILD_TIMESTAMP else "Unknown"
|
||||||
)
|
replacements['is_git'] = "Git" if IS_GIT_REPO else "Unknown"
|
||||||
replacements["branch"] = GIT_BRANCH if GIT_BRANCH else DEFAULT_BRANCH
|
replacements['dirty'] = "-dirty" if __version__ and __version__.endswith('-dirty') else ""
|
||||||
replacements["timestamp"] = BUILD_TIMESTAMP if BUILD_TIMESTAMP else "Unknown"
|
|
||||||
replacements["timestamp_short"] = (
|
|
||||||
BUILD_TIMESTAMP.split("T")[0]
|
|
||||||
if BUILD_TIMESTAMP and "T" in BUILD_TIMESTAMP
|
|
||||||
else "Unknown"
|
|
||||||
)
|
|
||||||
replacements["is_git"] = "Git" if IS_GIT_REPO else "Unknown"
|
|
||||||
replacements["dirty"] = (
|
|
||||||
"-dirty" if __version__ and __version__.endswith("-dirty") else ""
|
|
||||||
)
|
|
||||||
|
|
||||||
tag = DEFAULT_VERSION
|
tag = DEFAULT_VERSION
|
||||||
if __version__ and IS_GIT_REPO:
|
if __version__ and IS_GIT_REPO:
|
||||||
match = re.match(r"^(v?([0-9]+(?:\.[0-9]+)*))", __version__)
|
match = re.match(r'^(v?([0-9]+(?:\.[0-9]+)*))', __version__)
|
||||||
if match:
|
if match:
|
||||||
tag = match.group(1)
|
tag = match.group(1)
|
||||||
replacements["tag"] = tag
|
replacements['tag'] = tag
|
||||||
|
|
||||||
output_string = format_string
|
output_string = format_string
|
||||||
for placeholder, value in replacements.items():
|
for placeholder, value in replacements.items():
|
||||||
pattern = re.compile(r"{{\s*" + re.escape(placeholder) + r"\s*}}")
|
pattern = re.compile(r'{{\s*' + re.escape(placeholder) + r'\s*}}')
|
||||||
output_string = pattern.sub(str(value), output_string)
|
output_string = pattern.sub(str(value), output_string)
|
||||||
|
|
||||||
if re.search(r"{\s*\w+\s*}", output_string):
|
if re.search(r'{\s*\w+\s*}', output_string):
|
||||||
pass # Or log a warning: print(f"Warning: Unreplaced placeholders found: {output_string}")
|
pass # Or log a warning: print(f"Warning: Unreplaced placeholders found: {output_string}")
|
||||||
|
|
||||||
return output_string
|
return output_string
|
||||||
|
|||||||
@ -37,6 +37,26 @@ from target_simulator.gui.analysis_window import AnalysisWindow
|
|||||||
from target_simulator.core import command_builder
|
from target_simulator.core import command_builder
|
||||||
from target_simulator.analysis.simulation_archive import SimulationArchive
|
from target_simulator.analysis.simulation_archive import SimulationArchive
|
||||||
|
|
||||||
|
# --- Import Version Info FOR THE WRAPPER ITSELF ---
|
||||||
|
try:
|
||||||
|
# Use absolute import based on package name
|
||||||
|
from target_simulator import _version as wrapper_version
|
||||||
|
|
||||||
|
WRAPPER_APP_VERSION_STRING = f"{wrapper_version.__version__} ({wrapper_version.GIT_BRANCH}/{wrapper_version.GIT_COMMIT_HASH[:7]})"
|
||||||
|
WRAPPER_BUILD_INFO = f"Wrapper Built: {wrapper_version.BUILD_TIMESTAMP}"
|
||||||
|
except ImportError:
|
||||||
|
# This might happen if you run the wrapper directly from source
|
||||||
|
# without generating its _version.py first (if you use that approach for the wrapper itself)
|
||||||
|
WRAPPER_APP_VERSION_STRING = "(Dev Wrapper)"
|
||||||
|
WRAPPER_BUILD_INFO = "Wrapper build time unknown"
|
||||||
|
# --- End Import Version Info ---
|
||||||
|
|
||||||
|
# --- Constants for Version Generation ---
|
||||||
|
DEFAULT_VERSION = "0.0.0+unknown"
|
||||||
|
DEFAULT_COMMIT = "Unknown"
|
||||||
|
DEFAULT_BRANCH = "Unknown"
|
||||||
|
# --- End Constants ---
|
||||||
|
|
||||||
|
|
||||||
GUI_QUEUE_POLL_INTERVAL_MS = 100
|
GUI_QUEUE_POLL_INTERVAL_MS = 100
|
||||||
GUI_REFRESH_RATE_MS = 40
|
GUI_REFRESH_RATE_MS = 40
|
||||||
@ -85,8 +105,8 @@ class MainView(tk.Tk):
|
|||||||
self._slider_is_dragging = False
|
self._slider_is_dragging = False
|
||||||
|
|
||||||
# --- Window and UI Setup ---
|
# --- Window and UI Setup ---
|
||||||
self.title("Radar Target Simulator")
|
self.title(f"Radar Target Simulator")
|
||||||
self.geometry(settings.get("geometry", "1200x1024"))
|
self.geometry(settings.get("geometry", "1200x900"))
|
||||||
self.minsize(1024, 768)
|
self.minsize(1024, 768)
|
||||||
|
|
||||||
self._create_menubar()
|
self._create_menubar()
|
||||||
@ -525,6 +545,10 @@ class MainView(tk.Tk):
|
|||||||
ttk.Button(
|
ttk.Button(
|
||||||
btn_frame, text="Refresh List", command=self._refresh_analysis_list
|
btn_frame, text="Refresh List", command=self._refresh_analysis_list
|
||||||
).pack(side=tk.LEFT)
|
).pack(side=tk.LEFT)
|
||||||
|
# Button to open the archive folder in the system file explorer
|
||||||
|
ttk.Button(
|
||||||
|
btn_frame, text="Open Archive Folder", command=self._open_archive_folder
|
||||||
|
).pack(side=tk.LEFT, padx=(6, 0))
|
||||||
ttk.Button(
|
ttk.Button(
|
||||||
btn_frame, text="Analyze Selected", command=self._on_analyze_run
|
btn_frame, text="Analyze Selected", command=self._on_analyze_run
|
||||||
).pack(side=tk.RIGHT)
|
).pack(side=tk.RIGHT)
|
||||||
@ -617,7 +641,7 @@ class MainView(tk.Tk):
|
|||||||
|
|
||||||
def _update_window_title(self):
|
def _update_window_title(self):
|
||||||
"""Updates the window title based on the current scenario."""
|
"""Updates the window title based on the current scenario."""
|
||||||
base_title = "Radar Target Simulator"
|
base_title = (f"Radar Target Simulator- {WRAPPER_APP_VERSION_STRING}")
|
||||||
if self.current_scenario_name:
|
if self.current_scenario_name:
|
||||||
self.title(f"{base_title} - {self.current_scenario_name}")
|
self.title(f"{base_title} - {self.current_scenario_name}")
|
||||||
else:
|
else:
|
||||||
@ -830,120 +854,117 @@ class MainView(tk.Tk):
|
|||||||
True if the reset commands were sent successfully, False otherwise.
|
True if the reset commands were sent successfully, False otherwise.
|
||||||
"""
|
"""
|
||||||
if not self.target_communicator or not self.target_communicator.is_open:
|
if not self.target_communicator or not self.target_communicator.is_open:
|
||||||
self.logger.error(
|
self.logger.error("Cannot reset radar state: communicator is not connected.")
|
||||||
"Cannot reset radar state: communicator is not connected."
|
messagebox.showerror("Connection Error", "Cannot reset radar: Not Connected.")
|
||||||
)
|
|
||||||
messagebox.showerror(
|
|
||||||
"Connection Error", "Cannot reset radar: Not Connected."
|
|
||||||
)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.logger.info("Sending reset commands to deactivate all radar targets...")
|
self.logger.info("Attempting to reset radar state (legacy vs JSON-aware logic)")
|
||||||
|
|
||||||
# Build the atomic reset command.
|
|
||||||
try:
|
try:
|
||||||
reset_command = "tgtset /-s"
|
use_json = bool(getattr(self.target_communicator, "_use_json_protocol", False))
|
||||||
except Exception:
|
|
||||||
self.logger.exception(
|
|
||||||
"Error while building atomic reset command; falling back to raw string."
|
|
||||||
)
|
|
||||||
reset_command = "tgtset /-s"
|
|
||||||
|
|
||||||
# Some radar servers require adjusting internal parameters for legacy mode.
|
|
||||||
# Use the non-$ textual commands and ensure newline termination per the
|
|
||||||
# user's request: send exactly "mex.t_rows=80\n" and "tgtset /-s\n".
|
|
||||||
prep_command = "mex.t_rows=80\n"
|
|
||||||
|
|
||||||
# If the communicator was configured to use the JSON protocol, send
|
|
||||||
# the JSON reset command expected by the server. Otherwise, fall back
|
|
||||||
# to the legacy prep + atomic reset command sequence.
|
|
||||||
try:
|
|
||||||
use_json = bool(
|
|
||||||
getattr(self.target_communicator, "_use_json_protocol", False)
|
|
||||||
)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
use_json = False
|
use_json = False
|
||||||
|
|
||||||
if use_json:
|
# Helper: wait until hub reports no active real targets (bounded)
|
||||||
# Send both the per-target zeroing payloads (if available) followed
|
def _wait_for_clear(timeout_s: float = 3.0, poll_interval: float = 0.2) -> bool:
|
||||||
# by a minimal {'CMD':'reset'} line. The per-target payloads clear
|
|
||||||
# active flags on individual IDs; the simple reset is a noop on
|
|
||||||
# servers that don't implement it but is harmless when supported.
|
|
||||||
try:
|
|
||||||
json_payloads = command_builder.build_json_reset_ids()
|
|
||||||
# Ensure all payloads are newline-terminated and then append
|
|
||||||
# the simple reset as a final step so servers that process
|
|
||||||
# the reset command can react accordingly.
|
|
||||||
final_reset = '{"CMD":"reset"}\n'
|
|
||||||
commands_to_send = [
|
|
||||||
p if p.endswith("\n") else p + "\n" for p in json_payloads
|
|
||||||
] + [final_reset]
|
|
||||||
self.logger.info(
|
|
||||||
"Using JSON Reset IDs payloads for radar reset (parts=%d + reset).",
|
|
||||||
len(json_payloads),
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
self.logger.exception(
|
|
||||||
"Failed to build Reset IDs JSON payloads; falling back to simple JSON reset."
|
|
||||||
)
|
|
||||||
commands_to_send = ['{"CMD":"reset"}\n']
|
|
||||||
else:
|
|
||||||
# Legacy textual reset sequence (no leading $; newline-terminated strings)
|
|
||||||
commands_to_send = [prep_command, reset_command + "\n"]
|
|
||||||
|
|
||||||
# When using JSON protocol, send each payload part individually.
|
|
||||||
if use_json:
|
|
||||||
all_ok = True
|
|
||||||
for payload in commands_to_send:
|
|
||||||
try:
|
|
||||||
ok = self.target_communicator.send_commands([payload])
|
|
||||||
except Exception:
|
|
||||||
self.logger.exception("Exception while sending JSON reset payload")
|
|
||||||
ok = False
|
|
||||||
if not ok:
|
|
||||||
all_ok = False
|
|
||||||
self.logger.error("Failed to send JSON reset payload part.")
|
|
||||||
break
|
|
||||||
if not all_ok:
|
|
||||||
messagebox.showerror(
|
|
||||||
"Reset Error", "Failed to send reset payload(s) to the radar."
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
if not self.target_communicator.send_commands(commands_to_send):
|
|
||||||
self.logger.error(
|
|
||||||
"Failed to send preparatory/reset commands to the radar."
|
|
||||||
)
|
|
||||||
messagebox.showerror(
|
|
||||||
"Reset Error", "Failed to send reset command to the radar."
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
self.logger.info(
|
|
||||||
"Successfully sent preparatory and atomic reset commands: %s",
|
|
||||||
commands_to_send,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Poll the simulation hub to confirm the server processed the reset.
|
|
||||||
# The success condition is that there are no more active REAL targets being reported.
|
|
||||||
timeout_s = 3.0
|
|
||||||
poll_interval = 0.2
|
|
||||||
waited = 0.0
|
waited = 0.0
|
||||||
while waited < timeout_s:
|
while waited < timeout_s:
|
||||||
# MODIFICATION: Use the new, correct check.
|
try:
|
||||||
if not self.simulation_hub.has_active_real_targets():
|
if not self.simulation_hub.has_active_real_targets():
|
||||||
self.logger.info("Radar reported zero active real targets after reset.")
|
|
||||||
return True
|
return True
|
||||||
|
except Exception:
|
||||||
|
# If hub query fails, treat as not cleared and keep waiting
|
||||||
|
self.logger.debug("Error while querying simulation_hub during reset wait", exc_info=True)
|
||||||
time.sleep(poll_interval)
|
time.sleep(poll_interval)
|
||||||
waited += poll_interval
|
waited += poll_interval
|
||||||
|
return False
|
||||||
|
|
||||||
# If we reach here, the hub still reports active real targets — treat as failure
|
# 1) Legacy textual command path
|
||||||
self.logger.error(
|
if not use_json:
|
||||||
"Radar did not clear real targets after reset within timeout."
|
cmd = "tgtset /-s\n"
|
||||||
)
|
self.logger.info("Sending legacy reset command: %s", cmd.strip())
|
||||||
|
try:
|
||||||
|
ok = self.target_communicator.send_commands([cmd])
|
||||||
|
except Exception:
|
||||||
|
self.logger.exception("Failed to send legacy reset command")
|
||||||
|
ok = False
|
||||||
|
|
||||||
|
if not ok:
|
||||||
|
messagebox.showerror("Reset Error", "Failed to send reset command to the radar.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Wait briefly for the server to apply the reset and for hub to reflect it
|
||||||
|
cleared = _wait_for_clear()
|
||||||
|
if cleared:
|
||||||
|
self.logger.info("Legacy reset acknowledged: no active real targets remain.")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.logger.error("Legacy reset sent but server did not clear active targets in time.")
|
||||||
messagebox.showerror("Reset Error", "Radar did not clear targets after reset.")
|
messagebox.showerror("Reset Error", "Radar did not clear targets after reset.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# 2) JSON-capable communicator path
|
||||||
|
# First attempt: send a single simple JSON reset command
|
||||||
|
try:
|
||||||
|
json_reset = '{"CMD":"reset"}\n'
|
||||||
|
self.logger.info("Sending JSON reset command: %s", json_reset.strip())
|
||||||
|
try:
|
||||||
|
ok = self.target_communicator.send_commands([json_reset])
|
||||||
|
except Exception:
|
||||||
|
self.logger.exception("Failed to send JSON reset command")
|
||||||
|
ok = False
|
||||||
|
|
||||||
|
# Wait to see if server cleared active flags
|
||||||
|
if ok:
|
||||||
|
cleared = _wait_for_clear()
|
||||||
|
if cleared:
|
||||||
|
self.logger.info("JSON reset acknowledged: server cleared active flags.")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.logger.info("JSON reset sent but server did not clear active flags; will attempt per-target JSON zeroing.")
|
||||||
|
else:
|
||||||
|
self.logger.warning("JSON reset command failed to send; will attempt per-target JSON zeroing.")
|
||||||
|
except Exception:
|
||||||
|
self.logger.exception("Unexpected error while attempting JSON reset")
|
||||||
|
|
||||||
|
# 3) Build and send per-target JSON payloads that explicitly clear active flag
|
||||||
|
try:
|
||||||
|
self.logger.info("Building per-target JSON reset payloads to clear active flags on all targets.")
|
||||||
|
json_payloads = command_builder.build_json_reset_ids()
|
||||||
|
except Exception:
|
||||||
|
self.logger.exception("Failed to build per-target JSON reset payloads")
|
||||||
|
messagebox.showerror("Reset Error", "Failed to build JSON reset payloads.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Send each payload and check hub state after sending
|
||||||
|
all_sent_ok = True
|
||||||
|
for i, payload in enumerate(json_payloads):
|
||||||
|
p = payload if payload.endswith("\n") else payload + "\n"
|
||||||
|
self.logger.info("Sending JSON reset payload part %d/%d", i + 1, len(json_payloads))
|
||||||
|
try:
|
||||||
|
ok = self.target_communicator.send_commands([p])
|
||||||
|
except Exception:
|
||||||
|
self.logger.exception("Exception while sending JSON reset payload part %d", i + 1)
|
||||||
|
ok = False
|
||||||
|
if not ok:
|
||||||
|
all_sent_ok = False
|
||||||
|
self.logger.error("Failed to send JSON reset payload part %d", i + 1)
|
||||||
|
break
|
||||||
|
|
||||||
|
if not all_sent_ok:
|
||||||
|
messagebox.showerror("Reset Error", "Failed to send one or more JSON reset payloads to the radar.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# After sending all per-target payloads, wait for hub to show targets cleared
|
||||||
|
cleared = _wait_for_clear()
|
||||||
|
if cleared:
|
||||||
|
self.logger.info("Per-target JSON reset succeeded: all active flags cleared.")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.logger.error("Per-target JSON reset did not clear active flags within timeout.")
|
||||||
|
messagebox.showerror("Reset Error", "Radar did not clear targets after per-target reset.")
|
||||||
|
return False
|
||||||
|
|
||||||
def _on_start_simulation(self):
|
def _on_start_simulation(self):
|
||||||
if self.is_simulation_running.get():
|
if self.is_simulation_running.get():
|
||||||
self.logger.info("Simulation is already running.")
|
self.logger.info("Simulation is already running.")
|
||||||
@ -1997,6 +2018,41 @@ class MainView(tk.Tk):
|
|||||||
iid=run["filepath"],
|
iid=run["filepath"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _open_archive_folder(self):
|
||||||
|
"""Open the simulation archive folder in the system file explorer."""
|
||||||
|
archive_folder = SimulationArchive.ARCHIVE_FOLDER
|
||||||
|
try:
|
||||||
|
# Ensure the folder exists
|
||||||
|
os.makedirs(archive_folder, exist_ok=True)
|
||||||
|
# On Windows, os.startfile opens the folder in Explorer
|
||||||
|
try:
|
||||||
|
os.startfile(archive_folder)
|
||||||
|
return
|
||||||
|
except Exception:
|
||||||
|
# Fallback to using explorer.exe via subprocess
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.run(["explorer", os.path.abspath(archive_folder)])
|
||||||
|
return
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.exception("Failed to open archive folder: %s", e)
|
||||||
|
|
||||||
|
# If we get here, show an error to the user
|
||||||
|
try:
|
||||||
|
messagebox.showerror(
|
||||||
|
"Error",
|
||||||
|
f"Could not open archive folder: {archive_folder}\nSee logs for details.",
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
# If even showing a messagebox fails, log and continue
|
||||||
|
try:
|
||||||
|
self.logger.error("Could not open archive folder: %s", archive_folder)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
def _on_analyze_run(self):
|
def _on_analyze_run(self):
|
||||||
selected_item = self.analysis_tree.focus()
|
selected_item = self.analysis_tree.focus()
|
||||||
if not selected_item:
|
if not selected_item:
|
||||||
|
|||||||
@ -124,6 +124,34 @@ class SfpDebugWindow(tk.Toplevel):
|
|||||||
|
|
||||||
self._create_widgets()
|
self._create_widgets()
|
||||||
|
|
||||||
|
# Initialize connection fields from the central connection settings
|
||||||
|
try:
|
||||||
|
cfg = None
|
||||||
|
# Prefer the master's runtime connection_config if available
|
||||||
|
if hasattr(self.master, "connection_config") and self.master.connection_config:
|
||||||
|
cfg = self.master.connection_config.get("target", {})
|
||||||
|
else:
|
||||||
|
# Fallback to ConfigManager if present on master
|
||||||
|
gm = getattr(self.master, "config_manager", None)
|
||||||
|
if gm:
|
||||||
|
cfg = gm.get_connection_settings().get("target", {})
|
||||||
|
|
||||||
|
if cfg is not None:
|
||||||
|
sfp_cfg = cfg.get("sfp", {})
|
||||||
|
if sfp_cfg:
|
||||||
|
ip = sfp_cfg.get("ip") or sfp_cfg.get("host")
|
||||||
|
if ip:
|
||||||
|
self.ip_var.set(str(ip))
|
||||||
|
port = sfp_cfg.get("port")
|
||||||
|
if port is not None:
|
||||||
|
self.server_port_var.set(str(port))
|
||||||
|
local = sfp_cfg.get("local_port")
|
||||||
|
if local is not None:
|
||||||
|
self.local_port_var.set(str(local))
|
||||||
|
except Exception:
|
||||||
|
# Do not prevent window from opening on any config read error
|
||||||
|
self.logger.debug("Could not initialise SFP debug connection fields from central config", exc_info=True)
|
||||||
|
|
||||||
if self.shared_communicator:
|
if self.shared_communicator:
|
||||||
self._update_toggle_state(self.shared_communicator.is_open)
|
self._update_toggle_state(self.shared_communicator.is_open)
|
||||||
# Schedule the legacy polling loop used by tests and older UI code
|
# Schedule the legacy polling loop used by tests and older UI code
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user