Removed unnecessary IPC drc - defaulting to only using the CLI
This commit is contained in:
parent
a95c0a40ba
commit
e5c87df088
@ -152,9 +152,8 @@ The KiCad MCP Server provides several key features, each with detailed documenta
|
||||
- **BOM Management**: Analyze and export Bills of Materials
|
||||
- *Example:* "Generate a BOM for my smart watch project" → Creates a detailed bill of materials
|
||||
|
||||
- **Design Rule Checking**: Run DRC checks and track your progress over time
|
||||
- **Design Rule Checking**: Run DRC checks using the KiCad CLI and track your progress over time
|
||||
- *Example:* "Run DRC on my power supply board and compare to last week" → Shows progress in fixing violations
|
||||
- *KiCad 9.0+ Compatible:* Uses the new KiCad CLI or IPC API automatically
|
||||
|
||||
- **PCB Visualization**: Generate visual representations of your PCB layouts
|
||||
- *Example:* "Show me a thumbnail of my audio amplifier PCB" → Displays a visual render of the board
|
||||
|
@ -11,15 +11,7 @@ The Design Rule Check (DRC) functionality allows you to:
|
||||
3. Track your progress over time as you fix issues
|
||||
4. Compare current results with previous checks
|
||||
|
||||
## KiCad 9.0+ Compatibility
|
||||
|
||||
**Important Update**: With KiCad 9.0+, the DRC functionality has been reimplemented to work with the new KiCad APIs. The server now supports two methods for running DRC:
|
||||
|
||||
1. **KiCad CLI Method** (Recommended) - Uses the `kicad-cli` command-line tool to run DRC checks without requiring a running instance of KiCad.
|
||||
|
||||
2. **IPC API Method** - Connects to a running instance of KiCad through the new IPC API using the `kicad-python` package.
|
||||
|
||||
The server automatically selects the best available method based on your KiCad installation.
|
||||
It does this all by using the `kicad-cli` command-line tool to run DRC checks without requiring a running instance of KiCad.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@ -27,7 +19,6 @@ For optimal DRC functionality with KiCad 9.0+, you should have:
|
||||
|
||||
- KiCad 9.0 or newer installed
|
||||
- `kicad-cli` available in your system PATH (included with KiCad 9.0+)
|
||||
- For IPC API functionality: the `kicad-python` package installed (`pip install kicad-python`)
|
||||
|
||||
## Using DRC Features
|
||||
|
||||
@ -43,7 +34,7 @@ Please run a DRC check on my project at /Users/username/Documents/KiCad/my_proje
|
||||
```
|
||||
|
||||
The tool will:
|
||||
- Automatically select the best available method (CLI or IPC API)
|
||||
- Use the kicad CLI to run the DRC check
|
||||
- Analyze your PCB design for rule violations
|
||||
- Generate a comprehensive report
|
||||
- Save the results to your DRC history
|
||||
@ -141,19 +132,7 @@ If the DRC check fails to run:
|
||||
|
||||
1. Ensure your KiCad project exists at the specified path
|
||||
2. Verify that the project contains a PCB file (.kicad_pcb)
|
||||
3. Check your KiCad installation:
|
||||
- For CLI method: Verify `kicad-cli` is in your PATH or in a standard installation location
|
||||
- For IPC API method: Make sure KiCad is running with the API server enabled in Preferences > Plugins
|
||||
3. Check your KiCad installation: Verify `kicad-cli` is in your PATH or in a standard installation location
|
||||
4. Try using the full absolute path to your project file
|
||||
|
||||
### Method Selection Issues
|
||||
|
||||
If you want to force a specific DRC method:
|
||||
|
||||
1. **CLI Method**: Ensure `kicad-cli` is available in your PATH
|
||||
2. **IPC API Method**:
|
||||
- Install the `kicad-python` package
|
||||
- Launch KiCad before running the DRC check
|
||||
- Enable the API server in KiCad preferences
|
||||
|
||||
If you continue to experience issues, check the server logs for more detailed error information.
|
||||
|
@ -1,160 +0,0 @@
|
||||
"""
|
||||
Design Rule Check (DRC) implementation using the KiCad IPC API.
|
||||
"""
|
||||
import os
|
||||
from typing import Any, Dict
|
||||
|
||||
from mcp.server.fastmcp import Context
|
||||
|
||||
from kicad_mcp.utils.kicad_api_detection import check_ipc_api_environment
|
||||
|
||||
async def run_drc_with_ipc_api(pcb_file: str, ctx: Context) -> Dict[str, Any]:
|
||||
"""Run DRC using the KiCad IPC API (kicad-python).
|
||||
This requires a running instance of KiCad with the IPC API enabled.
|
||||
|
||||
Args:
|
||||
pcb_file: Path to the PCB file (.kicad_pcb)
|
||||
ctx: MCP context for progress reporting
|
||||
|
||||
Returns:
|
||||
Dictionary with DRC results
|
||||
"""
|
||||
try:
|
||||
# Import the kicad-python modules
|
||||
import kipy
|
||||
from kipy.board_types import DrcExclusion, DrcSeverity
|
||||
print("Successfully imported kipy modules")
|
||||
|
||||
# Check if we're running in a KiCad IPC plugin environment
|
||||
is_plugin, socket_path = check_ipc_api_environment()
|
||||
|
||||
# Connect to KiCad
|
||||
await ctx.report_progress(20, 100)
|
||||
ctx.info("Connecting to KiCad...")
|
||||
|
||||
if is_plugin:
|
||||
# When running as a plugin, let kipy use environment variables
|
||||
kicad = kipy.KiCad()
|
||||
else:
|
||||
# When running standalone, try to connect to KiCad
|
||||
if socket_path:
|
||||
kicad = kipy.KiCad(socket_path=socket_path)
|
||||
else:
|
||||
# Try with default socket path
|
||||
kicad = kipy.KiCad()
|
||||
|
||||
# Get the currently open board
|
||||
await ctx.report_progress(30, 100)
|
||||
ctx.info("Getting board...")
|
||||
|
||||
# Check which board to use
|
||||
current_boards = await kicad.get_open_documents("board")
|
||||
|
||||
# If we have an open board, check if it's the one we want
|
||||
use_current_board = False
|
||||
board_doc = None
|
||||
|
||||
if current_boards:
|
||||
for doc in current_boards:
|
||||
if doc.file_path and os.path.normpath(doc.file_path) == os.path.normpath(pcb_file):
|
||||
board_doc = doc
|
||||
use_current_board = True
|
||||
break
|
||||
|
||||
# If the board isn't open, see if we can open it
|
||||
if not use_current_board:
|
||||
ctx.info(f"Opening board file: {pcb_file}")
|
||||
try:
|
||||
# Try to open the board
|
||||
doc = await kicad.open_document(pcb_file)
|
||||
board_doc = doc
|
||||
except Exception as e:
|
||||
print(f"Error opening board: {str(e)}")
|
||||
return {
|
||||
"success": False,
|
||||
"method": "ipc",
|
||||
"error": f"Failed to open board file: {str(e)}"
|
||||
}
|
||||
|
||||
# Get the board
|
||||
board = await kicad.board.get_board(board_doc.uuid)
|
||||
|
||||
# Run DRC
|
||||
await ctx.report_progress(50, 100)
|
||||
ctx.info("Running DRC check...")
|
||||
|
||||
# Define which severities to include
|
||||
severity_filter = DrcSeverity.ERROR | DrcSeverity.WARNING
|
||||
|
||||
# Run DRC on the board
|
||||
drc_report = await kicad.board.run_drc(
|
||||
board.uuid,
|
||||
severity_filter=severity_filter,
|
||||
exclusions=DrcExclusion.NONE # Include all violations
|
||||
)
|
||||
|
||||
# Process results
|
||||
await ctx.report_progress(70, 100)
|
||||
ctx.info("Processing DRC results...")
|
||||
|
||||
# Get all violations
|
||||
violations = drc_report.violations
|
||||
violation_count = len(violations)
|
||||
|
||||
print(f"DRC completed with {violation_count} violations")
|
||||
ctx.info(f"DRC completed with {violation_count} violations")
|
||||
|
||||
# Process the violations
|
||||
drc_errors = []
|
||||
error_types = {}
|
||||
|
||||
for violation in violations:
|
||||
# Get violation details
|
||||
severity = str(violation.severity)
|
||||
message = violation.message
|
||||
|
||||
# Extract location
|
||||
location = {
|
||||
"x": violation.location.x if hasattr(violation, 'location') and violation.location else 0,
|
||||
"y": violation.location.y if hasattr(violation, 'location') and violation.location else 0
|
||||
}
|
||||
|
||||
error_info = {
|
||||
"severity": severity,
|
||||
"message": message,
|
||||
"location": location
|
||||
}
|
||||
|
||||
drc_errors.append(error_info)
|
||||
|
||||
# Count by type
|
||||
if message not in error_types:
|
||||
error_types[message] = 0
|
||||
error_types[message] += 1
|
||||
|
||||
# Create result
|
||||
results = {
|
||||
"success": True,
|
||||
"method": "ipc",
|
||||
"pcb_file": pcb_file,
|
||||
"total_violations": violation_count,
|
||||
"violation_categories": error_types,
|
||||
"violations": drc_errors
|
||||
}
|
||||
|
||||
return results
|
||||
|
||||
except ImportError as e:
|
||||
print(f"Failed to import kipy modules: {str(e)}")
|
||||
return {
|
||||
"success": False,
|
||||
"method": "ipc",
|
||||
"error": f"Failed to import kipy modules: {str(e)}"
|
||||
}
|
||||
except Exception as e:
|
||||
print(f"Error in IPC API DRC: {str(e)}", exc_info=True)
|
||||
return {
|
||||
"success": False,
|
||||
"method": "ipc",
|
||||
"error": f"Error in IPC API DRC: {str(e)}"
|
||||
}
|
@ -8,7 +8,6 @@ from mcp.server.fastmcp import FastMCP, Context
|
||||
|
||||
from kicad_mcp.utils.file_utils import get_project_files
|
||||
from kicad_mcp.utils.drc_history import save_drc_result, get_drc_history, compare_with_previous
|
||||
from kicad_mcp.utils.kicad_api_detection import get_best_api_approach
|
||||
|
||||
# Import implementations
|
||||
from kicad_mcp.tools.drc_impl.cli_drc import run_drc_via_cli
|
||||
|
@ -68,64 +68,3 @@ def check_for_cli_api() -> bool:
|
||||
except Exception as e:
|
||||
print(f"Error checking for KiCad CLI API: {str(e)}")
|
||||
return False
|
||||
|
||||
|
||||
def check_for_ipc_api() -> bool:
|
||||
"""Check if KiCad IPC API (kicad-python) is available.
|
||||
|
||||
Returns:
|
||||
True if KiCad IPC API is available, False otherwise
|
||||
"""
|
||||
try:
|
||||
# Try to import the kipy module
|
||||
import kipy
|
||||
print("KiCad IPC API (kicad-python) is available")
|
||||
return True
|
||||
except ImportError:
|
||||
print("KiCad IPC API (kicad-python) is not available")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Error checking for KiCad IPC API: {str(e)}")
|
||||
return False
|
||||
|
||||
|
||||
def check_ipc_api_environment() -> Tuple[bool, Optional[str]]:
|
||||
"""Check if we're running in a KiCad IPC plugin environment.
|
||||
|
||||
Returns:
|
||||
Tuple of (is_plugin, socket_path)
|
||||
"""
|
||||
# Check for environment variables that would indicate we're a plugin
|
||||
is_plugin = os.environ.get("KICAD_PLUGIN_ENV") is not None
|
||||
|
||||
# Check for socket path in environment
|
||||
socket_path = os.environ.get("KICAD_SOCKET_PATH")
|
||||
|
||||
if is_plugin:
|
||||
print("Running as a KiCad plugin")
|
||||
elif socket_path:
|
||||
print(f"KiCad IPC socket path found: {socket_path}")
|
||||
|
||||
return (is_plugin, socket_path)
|
||||
|
||||
|
||||
def get_best_api_approach() -> Literal["cli", "ipc", "none"]:
|
||||
"""Determine the best available KiCad API approach.
|
||||
|
||||
Returns:
|
||||
String indicating which API approach to use:
|
||||
- "cli": Use KiCad command-line interface
|
||||
- "ipc": Use KiCad IPC API (kicad-python)
|
||||
- "none": No API available
|
||||
"""
|
||||
# Check for IPC API first (preferred if available)
|
||||
if check_for_ipc_api():
|
||||
return "ipc"
|
||||
|
||||
# Check for CLI API next
|
||||
if check_for_cli_api():
|
||||
return "cli"
|
||||
|
||||
# No API available
|
||||
print("No KiCad API available")
|
||||
return "none"
|
||||
|
@ -1,8 +1,5 @@
|
||||
mcp[cli]
|
||||
httpx
|
||||
pytest
|
||||
pandas
|
||||
kicad-python
|
||||
|
||||
# Development/Testing
|
||||
pytest-asyncio
|
||||
pytest
|
Loading…
x
Reference in New Issue
Block a user