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,12 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: iflow-mcp_wegitor-logic_analyzer_mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Saleae Logic capture file parser using MCP
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Requires-Dist: logic2-automation>=1.0.7
|
|
7
|
+
Requires-Dist: saleae>=0.12.0
|
|
8
|
+
Requires-Dist: grpcio>=1.71.0
|
|
9
|
+
Requires-Dist: grpcio-tools>=1.71.0
|
|
10
|
+
Requires-Dist: protobuf>=6.30.2
|
|
11
|
+
Requires-Dist: mcp[cli]
|
|
12
|
+
Requires-Dist: pytest
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
logic_analyzer_mcp/__init__.py,sha256=U44CCB3TJ4OSd5z45YtlcmicXND4-EDgAL1tCDa93jA,247
|
|
2
|
+
logic_analyzer_mcp/__main__.py,sha256=XjXiFUarQWkI2dT-aZJLGN4KHfc3PRRUxBB_pwKJbW4,76
|
|
3
|
+
logic_analyzer_mcp/logic_analyzer_mcp.py,sha256=9Hag4NsuVcgQWRHq9S4L5FNQowPfMl_annHo8KvrAEM,2215
|
|
4
|
+
logic_analyzer_mcp/mcp_tools.py,sha256=lIXSTBafo4vEjrP5Le5P0NSodI6ttoByagxD2QGZbm0,14920
|
|
5
|
+
logic_analyzer_mcp/mcp_tools_experimental.py,sha256=qho1lQME6ImZNEfcyLOWrLJo9-0v9oAxBVMZUNSHiZk,27954
|
|
6
|
+
logic_analyzer_mcp/saleae_manager.py,sha256=Lm7M-dJ5GKlHEEv0c_4dew6Yhtzdo86lZzhVMD0BDyo,3131
|
|
7
|
+
logic_analyzer_mcp/controllers/__init__.py,sha256=qHQG1AxXEzvi8e7Ol_kNA8RpG4mWq9dAoBv6RF6NsbY,638
|
|
8
|
+
logic_analyzer_mcp/controllers/logic2_automation_controller.py,sha256=RHPLHrY8I0I7Sphw4aTegYaBDkfFPZIdrY9a_TdXHlc,5484
|
|
9
|
+
logic_analyzer_mcp/controllers/saleae_controller.py,sha256=FhLz9YySu2H6x_T4BPjjTXkLBNMDRSZpk67Aa7q6jMg,39479
|
|
10
|
+
logic_analyzer_mcp/controllers/saleae_parser_controller.py,sha256=YI06t6tx0ejoii61w27no3dT00MXPPw4O6VBnk2g5lE,21530
|
|
11
|
+
iflow_mcp_wegitor_logic_analyzer_mcp-0.1.0.dist-info/METADATA,sha256=5xV1gI66BWxshSueI57TBSuawpAMr0_biP3WQ2TWjZ8,370
|
|
12
|
+
iflow_mcp_wegitor_logic_analyzer_mcp-0.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
13
|
+
iflow_mcp_wegitor_logic_analyzer_mcp-0.1.0.dist-info/entry_points.txt,sha256=D-H3T7U-s3cM-r5BEyr0iURmzWSkGsFAWGkoNecTTrE,63
|
|
14
|
+
iflow_mcp_wegitor_logic_analyzer_mcp-0.1.0.dist-info/top_level.txt,sha256=DsOp3oM_ZWDrO51uyiAZ4XtvRFinYFhzs2IP_rsnmuc,19
|
|
15
|
+
iflow_mcp_wegitor_logic_analyzer_mcp-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
logic_analyzer_mcp
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Controllers package for Saleae Logic Usage.
|
|
3
|
+
|
|
4
|
+
This package contains the Logic2AutomationController for Logic 2 device and capture management:
|
|
5
|
+
- Logic2AutomationController: Device configuration, capture management, and device discovery
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# Import controllers so they can be imported from the controllers package
|
|
9
|
+
from .logic2_automation_controller import Logic2AutomationController
|
|
10
|
+
from .saleae_controller import SaleaeController
|
|
11
|
+
from .saleae_parser_controller import SaleaeParserController
|
|
12
|
+
# Note: The TemplateController class has been moved to template_controller.py to avoid import issues
|
|
13
|
+
|
|
14
|
+
__all__ = ['Logic2AutomationController']
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
from typing import List, Optional, Dict
|
|
2
|
+
from saleae.automation import Manager, LogicDeviceConfiguration, CaptureConfiguration, TimedCaptureMode, DeviceType
|
|
3
|
+
|
|
4
|
+
class Logic2AutomationController:
|
|
5
|
+
"""Controller for managing Logic 2 automation device configurations and captures."""
|
|
6
|
+
|
|
7
|
+
def __init__(self, manager: Manager):
|
|
8
|
+
"""
|
|
9
|
+
Initialize the Logic 2 automation controller.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
manager (Manager): Logic 2 automation manager instance
|
|
13
|
+
"""
|
|
14
|
+
self.manager = manager
|
|
15
|
+
self._device_configs: Dict[str, LogicDeviceConfiguration] = {}
|
|
16
|
+
self._capture_configs: Dict[str, CaptureConfiguration] = {}
|
|
17
|
+
|
|
18
|
+
def create_device_config(self,
|
|
19
|
+
name: str,
|
|
20
|
+
digital_channels: List[int],
|
|
21
|
+
digital_sample_rate: int,
|
|
22
|
+
analog_channels: Optional[List[int]] = None,
|
|
23
|
+
analog_sample_rate: Optional[int] = None,
|
|
24
|
+
digital_threshold_volts: Optional[float] = None) -> str:
|
|
25
|
+
"""
|
|
26
|
+
Create a new device configuration.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
name (str): Name for the configuration
|
|
30
|
+
digital_channels (List[int]): List of digital channels to enable
|
|
31
|
+
digital_sample_rate (int): Digital sample rate in Hz
|
|
32
|
+
analog_channels (List[int], optional): List of analog channels to enable
|
|
33
|
+
analog_sample_rate (int, optional): Analog sample rate in Hz
|
|
34
|
+
digital_threshold_volts (float, optional): Digital threshold voltage
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
str: Configuration name
|
|
38
|
+
"""
|
|
39
|
+
config = LogicDeviceConfiguration(
|
|
40
|
+
enabled_digital_channels=digital_channels,
|
|
41
|
+
digital_sample_rate=digital_sample_rate,
|
|
42
|
+
enabled_analog_channels=analog_channels or [],
|
|
43
|
+
analog_sample_rate=analog_sample_rate,
|
|
44
|
+
digital_threshold_volts=digital_threshold_volts
|
|
45
|
+
)
|
|
46
|
+
self._device_configs[name] = config
|
|
47
|
+
return name
|
|
48
|
+
|
|
49
|
+
def create_capture_config(self,
|
|
50
|
+
name: str,
|
|
51
|
+
duration_seconds: float,
|
|
52
|
+
buffer_size_megabytes: Optional[int] = None) -> str:
|
|
53
|
+
"""
|
|
54
|
+
Create a new capture configuration.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
name (str): Name for the configuration
|
|
58
|
+
duration_seconds (float): Capture duration in seconds
|
|
59
|
+
buffer_size_megabytes (int, optional): Buffer size in MB
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
str: Configuration name
|
|
63
|
+
"""
|
|
64
|
+
config = CaptureConfiguration(
|
|
65
|
+
capture_mode=TimedCaptureMode(duration_seconds=duration_seconds),
|
|
66
|
+
buffer_size_megabytes=buffer_size_megabytes
|
|
67
|
+
)
|
|
68
|
+
self._capture_configs[name] = config
|
|
69
|
+
return name
|
|
70
|
+
|
|
71
|
+
def get_device_config(self, name: str) -> Optional[LogicDeviceConfiguration]:
|
|
72
|
+
"""Get a device configuration by name."""
|
|
73
|
+
return self._device_configs.get(name)
|
|
74
|
+
|
|
75
|
+
def get_capture_config(self, name: str) -> Optional[CaptureConfiguration]:
|
|
76
|
+
"""Get a capture configuration by name."""
|
|
77
|
+
return self._capture_configs.get(name)
|
|
78
|
+
|
|
79
|
+
def list_device_configs(self) -> List[str]:
|
|
80
|
+
"""List all available device configurations."""
|
|
81
|
+
return list(self._device_configs.keys())
|
|
82
|
+
|
|
83
|
+
def list_capture_configs(self) -> List[str]:
|
|
84
|
+
"""List all available capture configurations."""
|
|
85
|
+
return list(self._capture_configs.keys())
|
|
86
|
+
|
|
87
|
+
def remove_device_config(self, name: str) -> bool:
|
|
88
|
+
"""Remove a device configuration."""
|
|
89
|
+
if name in self._device_configs:
|
|
90
|
+
del self._device_configs[name]
|
|
91
|
+
return True
|
|
92
|
+
return False
|
|
93
|
+
|
|
94
|
+
def remove_capture_config(self, name: str) -> bool:
|
|
95
|
+
"""Remove a capture configuration."""
|
|
96
|
+
if name in self._capture_configs:
|
|
97
|
+
del self._capture_configs[name]
|
|
98
|
+
return True
|
|
99
|
+
return False
|
|
100
|
+
|
|
101
|
+
def get_available_devices(self) -> List[Dict]:
|
|
102
|
+
"""
|
|
103
|
+
Get list of available Logic devices.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
List[Dict]: List of device information dictionaries with masked device IDs
|
|
107
|
+
"""
|
|
108
|
+
devices = self.manager.get_devices()
|
|
109
|
+
return [
|
|
110
|
+
{
|
|
111
|
+
'id': f"{device.device_id[:4]}...{device.device_id[-4:]}" if len(device.device_id) > 8 else "****",
|
|
112
|
+
'type': device.device_type,
|
|
113
|
+
'is_simulation': device.is_simulation
|
|
114
|
+
}
|
|
115
|
+
for device in devices
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
def find_device_by_type(self, device_type: DeviceType) -> Optional[Dict]:
|
|
119
|
+
"""
|
|
120
|
+
Find a device by its type.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
device_type (DeviceType): Type of device to find
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
Optional[Dict]: Device information if found, None otherwise
|
|
127
|
+
|
|
128
|
+
Raises:
|
|
129
|
+
ValueError: If the device type is not supported
|
|
130
|
+
"""
|
|
131
|
+
# Check if device type is supported
|
|
132
|
+
if device_type in [DeviceType.LOGIC, DeviceType.LOGIC_4, DeviceType.LOGIC_16]:
|
|
133
|
+
raise ValueError(f"Device type {device_type.name} is not supported by Logic 2 software")
|
|
134
|
+
|
|
135
|
+
devices = self.get_available_devices()
|
|
136
|
+
for device in devices:
|
|
137
|
+
if device['type'] == device_type:
|
|
138
|
+
return device
|
|
139
|
+
return None
|