Spaces:
Sleeping
Sleeping
File size: 4,850 Bytes
a715790 0fae916 6cb9bde 0fae916 4d0cfc5 9b3f017 4d0cfc5 7ebeb3b 8e9c148 e2a4d50 7ebeb3b b26efca 6cb9bde 7ebeb3b 0fae916 f6f763c 0fae916 a715790 0fae916 9b3f017 0fae916 a715790 4d0cfc5 6cb9bde 0fae916 a715790 0fae916 a715790 0fae916 a715790 5db575c a715790 0fae916 a715790 0fae916 a715790 0fae916 a715790 6cb9bde 9b3f017 6cb9bde 0fae916 9b3f017 0fae916 9b3f017 0fae916 a715790 5db575c 0fae916 a715790 0fae916 a715790 0fae916 a715790 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
import gradio as gr
from skidl import *
import tempfile
import os
import time
import sys
import logging
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Check for required dependencies
try:
import gradio
import skidl
except ImportError as e:
print(f"Missing dependency: {e}")
print("Please install requirements: pip install gradio skidl")
sys.exit(1)
def check_device_lib():
"""Check if device.lib exists in the current directory."""
current_dir = os.getcwd()
device_lib_path = os.path.join(current_dir, 'device.lib')
if os.path.exists(device_lib_path):
logger.info(f"Found device.lib in current directory: {device_lib_path}")
return True
logger.warning(f"device.lib not found in current directory: {current_dir}")
return False
def configure_skidl_libs():
"""Configure SKiDL to use device.lib from the current directory."""
current_dir = os.getcwd()
# Clear existing library search paths
lib_search_paths.clear()
# Assume lib_search_paths is a dict (newer SKiDL)
lib_key = getattr(skidl, 'LIB_SPICE', 'spice')
lib_search_paths[lib_key] = [current_dir]
logger.info(f"Using dict-based lib_search_paths with key '{lib_key}' and {current_dir}")
# Conditionally set default library if set_default_lib exists
try:
set_default_lib('Device')
logger.info("Set default library to Device using set_default_lib")
except NameError:
logger.info("set_default_lib not available; relying on lib_search_paths for Device library")
# Suppress KiCad warnings by setting dummy environment variables
os.environ['KICAD_SYMBOL_DIR'] = current_dir
os.environ['KICAD6_SYMBOL_DIR'] = current_dir
os.environ['KICAD7_SYMBOL_DIR'] = current_dir
os.environ['KICAD8_SYMBOL_DIR'] = current_dir
logger.info("Set dummy KiCad environment variables to suppress warnings")
def cleanup_old_files():
"""Clean up temporary files older than 1 hour."""
temp_dir = tempfile.gettempdir()
for f in os.listdir(temp_dir):
if f.endswith('.net') and os.path.getmtime(os.path.join(temp_dir, f)) < time.time() - 3600:
try:
os.remove(os.path.join(temp_dir, f))
except OSError:
pass
def generate_circuit(skidl_code):
"""Generate circuit netlist from SKiDL code."""
if not skidl_code.strip():
return "Error: Empty code provided", None
reset()
tmp_path = None
try:
configure_skidl_libs()
if not check_device_lib():
return "Error: device.lib not found in the current directory. Please ensure it exists.", None
try:
compile(skidl_code, '<string>', 'exec')
except SyntaxError as e:
return f"Syntax Error: {e}", None
with tempfile.NamedTemporaryFile(delete=False, suffix='.py') as tmp:
tmp.write(skidl_code.encode('utf-8'))
tmp_path = tmp.name
namespace = {}
exec(open(tmp_path).read(), namespace)
netlist_str = generate_netlist()
if not netlist_str.strip():
return "Error: No netlist generated", None
with tempfile.NamedTemporaryFile(delete=False, suffix='.net', mode='w') as out_file:
out_file.write(netlist_str)
netlist_file_path = out_file.name
return "Netlist generated successfully!", netlist_file_path
except SyntaxError as e:
return f"Syntax Error: {e}", None
except Exception as e:
return f"Error: {str(e)}", None
finally:
if tmp_path and os.path.exists(tmp_path):
try:
os.remove(tmp_path)
except OSError:
pass
# Gradio UI
with gr.Blocks() as demo:
gr.Markdown(
"""
# SKiDL Circuit Builder (No KiCad Needed)
**Note**: Ensure `device.lib` is in the same directory as this script to resolve components like resistors, LEDs, etc.
"""
)
# Example code: 5 LEDs with resistors
example_code = """
from skidl import *
vcc = Vcc()
gnd = Gnd()
leds = [Part('Device', 'LED', value='LED') for _ in range(5)]
resistors = [Part('Device', 'R', value='220') for _ in range(5)]
for r, led in zip(resistors, leds):
vcc & r & led & gnd
"""
skidl_input = gr.Textbox(
label="Enter SKiDL Code Here",
lines=20,
placeholder=example_code
)
output_message = gr.Textbox(label="Status / Error", interactive=False)
download_btn = gr.File(label="Download Netlist (.net)")
run_button = gr.Button("Build Circuit")
run_button.click(
fn=generate_circuit,
inputs=[skidl_input],
outputs=[output_message, download_btn]
)
if __name__ == "__main__":
cleanup_old_files()
demo.launch() |