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.
- iflow_mcp_wegitor_logic_analyzer_mcp-0.1.0.dist-info/METADATA +12 -0
- iflow_mcp_wegitor_logic_analyzer_mcp-0.1.0.dist-info/RECORD +15 -0
- iflow_mcp_wegitor_logic_analyzer_mcp-0.1.0.dist-info/WHEEL +5 -0
- iflow_mcp_wegitor_logic_analyzer_mcp-0.1.0.dist-info/entry_points.txt +2 -0
- iflow_mcp_wegitor_logic_analyzer_mcp-0.1.0.dist-info/top_level.txt +1 -0
- logic_analyzer_mcp/__init__.py +7 -0
- logic_analyzer_mcp/__main__.py +4 -0
- logic_analyzer_mcp/controllers/__init__.py +14 -0
- logic_analyzer_mcp/controllers/logic2_automation_controller.py +139 -0
- logic_analyzer_mcp/controllers/saleae_controller.py +929 -0
- logic_analyzer_mcp/controllers/saleae_parser_controller.py +548 -0
- logic_analyzer_mcp/logic_analyzer_mcp.py +62 -0
- logic_analyzer_mcp/mcp_tools.py +310 -0
- logic_analyzer_mcp/mcp_tools_experimental.py +636 -0
- logic_analyzer_mcp/saleae_manager.py +98 -0
|
@@ -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
|