iflow-mcp_wegitor-logic_analyzer_mcp 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,98 @@
1
+ import os
2
+ import time
3
+ import logging
4
+ from typing import Optional
5
+ try:
6
+ from saleae import Saleae
7
+ except Exception:
8
+ Saleae = None # allow import to succeed even if saleae package unavailable
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ _saleae_instance: Optional[Saleae] = None
13
+
14
+ def create_saleae_instance(max_retries=3, retry_delay=2) -> Optional[Saleae]:
15
+ """
16
+ Create a Saleae instance with automatic launch and retry mechanism.
17
+ """
18
+ # Define all possible paths where Logic.exe might be installed
19
+ common_paths = [
20
+ os.path.expandvars(r"%ProgramFiles%\Saleae\Logic\Logic.exe"),
21
+ os.path.expandvars(r"%ProgramFiles%\Logic\Logic.exe"),
22
+ os.path.expandvars(r"%ProgramFiles(x86)%\Saleae\Logic\Logic.exe"),
23
+ os.path.expanduser(r"~\AppData\Local\Programs\Saleae\Logic\Logic.exe")
24
+ ]
25
+
26
+ # First, check if any of the paths exist
27
+ saleae_path = None
28
+ for path in common_paths:
29
+ logger.info(f"Checking path: {path}")
30
+ if os.path.exists(path):
31
+ saleae_path = path
32
+ logger.info(f"Found Saleae Logic at: {path}")
33
+ # Check file permissions
34
+ try:
35
+ if os.access(path, os.R_OK):
36
+ logger.info(f"File is readable: {path}")
37
+ else:
38
+ logger.warning(f"File exists but is not readable: {path}")
39
+ if os.access(path, os.X_OK):
40
+ logger.info(f"File is executable: {path}")
41
+ else:
42
+ logger.warning(f"File exists but is not executable: {path}")
43
+ except Exception as e:
44
+ logger.warning(f"Error checking file permissions: {str(e)}")
45
+ break
46
+ else:
47
+ logger.info(f"Path does not exist: {path}")
48
+
49
+ if saleae_path is None:
50
+ logger.error("Saleae Logic software not found in common locations.")
51
+ return None
52
+
53
+ if Saleae is None:
54
+ logger.error("python-saleae package not available (Saleae import failed).")
55
+ return None
56
+
57
+ for attempt in range(max_retries):
58
+ try:
59
+ # Try to create a new instance
60
+ saleae = Saleae()
61
+ # Test the connection
62
+ saleae.get_connected_devices()
63
+ return saleae
64
+ except Exception as e:
65
+ logger.warning(f"Attempt {attempt + 1}/{max_retries} failed: {str(e)}")
66
+
67
+ if attempt < max_retries - 1:
68
+ try:
69
+ # Try to launch the software using the found path
70
+ logger.info(f"Attempting to launch Saleae Logic from: {saleae_path}")
71
+ # Try to launch using subprocess first
72
+ try:
73
+ import subprocess
74
+ logger.info("Attempting to launch using subprocess...")
75
+ subprocess.Popen([saleae_path])
76
+ time.sleep(retry_delay)
77
+ except Exception as subprocess_error:
78
+ logger.warning(f"Subprocess launch failed: {str(subprocess_error)}")
79
+ # Fall back to Saleae API launch
80
+ saleae = Saleae()
81
+ saleae.launch()
82
+
83
+ # Wait for the software to start
84
+ time.sleep(retry_delay)
85
+ except Exception as launch_error:
86
+ logger.error(f"Failed to launch Saleae Logic: {launch_error}")
87
+ time.sleep(retry_delay)
88
+ continue
89
+
90
+ logger.error("Failed to connect to Saleae Logic after all attempts.")
91
+ return None
92
+
93
+ def get_saleae() -> Optional[Saleae]:
94
+ """Return a cached Saleae instance, creating one if necessary."""
95
+ global _saleae_instance
96
+ if _saleae_instance is None:
97
+ _saleae_instance = create_saleae_instance()
98
+ return _saleae_instance