mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 09:12:09 +10:00
analyzer added
This commit is contained in:
@@ -43,6 +43,20 @@ public interface IChatbotAPI {
|
|||||||
@ParamName("machineId") String machineId, @ParamName("project") String project,
|
@ParamName("machineId") String machineId, @ParamName("project") String project,
|
||||||
@ParamName("netlist") File netlist, @ParamName("prompt") String prompt);
|
@ParamName("netlist") File netlist, @ParamName("prompt") String prompt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyzes the provided circuit
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* @param token
|
||||||
|
* @param machineId
|
||||||
|
* @param project
|
||||||
|
* @param netlist
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String analyzeCircuit(@ParamName("username") String username, @ParamName("token") String token,
|
||||||
|
@ParamName("machineId") String machineId, @ParamName("project") String project,
|
||||||
|
@ParamName("netlist") File netlist);
|
||||||
|
|
||||||
SubscriptionEntity getSubscriptionInfo(@ParamName("username") String username, @ParamName("token") String token,
|
SubscriptionEntity getSubscriptionInfo(@ParamName("username") String username, @ParamName("token") String token,
|
||||||
@ParamName("machineId") String machineId);
|
@ParamName("machineId") String machineId);
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -5,6 +5,7 @@ import java.awt.geom.Point2D;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
@@ -34,7 +35,8 @@ public class AiProjectBuilder {
|
|||||||
sets.stream().map(s -> s.stream()
|
sets.stream().map(s -> s.stream()
|
||||||
.map(AiProjectBuilder::mapTerminal)
|
.map(AiProjectBuilder::mapTerminal)
|
||||||
.collect(Collectors.toSet()))
|
.collect(Collectors.toSet()))
|
||||||
.collect(Collectors.toMap(x -> "N" + counter.incrementAndGet(), x -> x));
|
.collect(Collectors.toMap(x -> "N" + String.format("%03d", counter.incrementAndGet()),
|
||||||
|
Function.identity()));
|
||||||
|
|
||||||
List<AiSwitch> switches =
|
List<AiSwitch> switches =
|
||||||
project.getComponents().stream()
|
project.getComponents().stream()
|
||||||
|
|||||||
+55
-18
@@ -123,9 +123,57 @@ public class ChatbotService {
|
|||||||
String currentFile = plugInPort.getCurrentFileName();
|
String currentFile = plugInPort.getCurrentFileName();
|
||||||
String fileName = extractFileName(currentFile);
|
String fileName = extractFileName(currentFile);
|
||||||
|
|
||||||
File aiProjectFile = null;
|
File aiProjectFile = getAiProjectFile();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return getService().promptChatbot(
|
||||||
|
plugInPort.getCloudService().getCurrentUsername(),
|
||||||
|
plugInPort.getCloudService().getCurrentToken(),
|
||||||
|
plugInPort.getCloudService().getMachineId(),
|
||||||
|
fileName,
|
||||||
|
aiProjectFile,
|
||||||
|
prompt);
|
||||||
|
} finally {
|
||||||
|
// Clean up the temp file immediately after use
|
||||||
|
if (aiProjectFile != null && aiProjectFile.exists()) {
|
||||||
|
aiProjectFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String analyzeCircuit() throws NotLoggedInException {
|
||||||
|
if (!plugInPort.getCloudService().isLoggedIn())
|
||||||
|
throw new NotLoggedInException();
|
||||||
|
|
||||||
|
LOG.info("Analyzing circuit...");
|
||||||
|
|
||||||
|
String currentFile = plugInPort.getCurrentFileName();
|
||||||
|
String fileName = extractFileName(currentFile);
|
||||||
|
|
||||||
|
File aiProjectFile = getAiProjectFile();
|
||||||
|
|
||||||
|
try {
|
||||||
|
String jsonResult = getService().analyzeCircuit(plugInPort.getCloudService().getCurrentUsername(),
|
||||||
|
plugInPort.getCloudService().getCurrentToken(),
|
||||||
|
plugInPort.getCloudService().getMachineId(), fileName, aiProjectFile);
|
||||||
|
return JsonToHtmlConverter.convertToHtml(jsonResult);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
// Clean up the temp file immediately after use
|
||||||
|
if (aiProjectFile != null && aiProjectFile.exists()) {
|
||||||
|
aiProjectFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getAiProjectFile() {
|
||||||
|
File aiProjectFile = null;
|
||||||
|
AiProject aiProject = extractAiProject();
|
||||||
|
if (aiProject == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
AiProject aiProject = extractAiProject();
|
|
||||||
String aiProjectStr = null;
|
String aiProjectStr = null;
|
||||||
try {
|
try {
|
||||||
aiProjectStr = MAPPER.writeValueAsString(aiProject);
|
aiProjectStr = MAPPER.writeValueAsString(aiProject);
|
||||||
@@ -181,24 +229,13 @@ public class ChatbotService {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Error extracting or saving netlist", e);
|
LOG.error("Error extracting or saving netlist", e);
|
||||||
}
|
}
|
||||||
|
return aiProjectFile;
|
||||||
try {
|
|
||||||
return getService().promptChatbot(
|
|
||||||
plugInPort.getCloudService().getCurrentUsername(),
|
|
||||||
plugInPort.getCloudService().getCurrentToken(),
|
|
||||||
plugInPort.getCloudService().getMachineId(),
|
|
||||||
fileName,
|
|
||||||
aiProjectFile,
|
|
||||||
prompt);
|
|
||||||
} finally {
|
|
||||||
// Clean up the temp file immediately after use
|
|
||||||
if (aiProjectFile != null && aiProjectFile.exists()) {
|
|
||||||
aiProjectFile.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AiProject extractAiProject() throws NetlistException {
|
private AiProject extractAiProject() {
|
||||||
|
if (plugInPort.getCurrentProject().getComponents().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
List<ContinuityArea> continuityAreas = plugInPort.getDrawingManager().getContinuityAreas();
|
List<ContinuityArea> continuityAreas = plugInPort.getDrawingManager().getContinuityAreas();
|
||||||
return AiProjectBuilder.build(plugInPort.getCurrentProject(), continuityAreas);
|
return AiProjectBuilder.build(plugInPort.getCurrentProject(), continuityAreas);
|
||||||
}
|
}
|
||||||
|
|||||||
+92
@@ -0,0 +1,92 @@
|
|||||||
|
package org.diylc.plugins.chatbot.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class JsonToHtmlConverter {
|
||||||
|
|
||||||
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the given JSON string into HTML.
|
||||||
|
*
|
||||||
|
* @param json the input JSON
|
||||||
|
* @return an HTML document as a String
|
||||||
|
* @throws IOException if JSON parsing fails
|
||||||
|
*/
|
||||||
|
public static String convertToHtml(String json) throws IOException {
|
||||||
|
JsonNode root = MAPPER.readTree(json);
|
||||||
|
StringBuilder html = new StringBuilder();
|
||||||
|
|
||||||
|
html.append("<!DOCTYPE html>\n<html>\n<head>\n")
|
||||||
|
.append(" <meta charset=\"UTF-8\">\n")
|
||||||
|
.append(" <title>Validation Report</title>\n")
|
||||||
|
.append(" <style>\n")
|
||||||
|
.append(" body { font-family: Arial, sans-serif; }\n")
|
||||||
|
.append(" h2 { color: #444; }\n")
|
||||||
|
.append(" ul { list-style: disc; margin-left: 20px; }\n")
|
||||||
|
.append(" li { margin-bottom: 5px; }\n")
|
||||||
|
.append(" </style>\n")
|
||||||
|
.append("</head>\n<body>\n");
|
||||||
|
|
||||||
|
// Process each section
|
||||||
|
processSection(root, "critical", html, "#c00");
|
||||||
|
processSection(root, "warnings", html, "#e65c00");
|
||||||
|
processSection(root, "optimizations", html, "#0066c0");
|
||||||
|
|
||||||
|
html.append("</body>\n</html>");
|
||||||
|
return html.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processSection(JsonNode root, String field, StringBuilder html, String color) {
|
||||||
|
JsonNode array = root.path(field);
|
||||||
|
if (array.isArray() && array.size() > 0) {
|
||||||
|
html.append(String.format("<h2 style=\"color:%s;\">%s</h2>\n", color, capitalize(field)));
|
||||||
|
html.append("<ul>\n");
|
||||||
|
for (JsonNode item : array) {
|
||||||
|
String message = escapeHtml(item.path("message").asText(""));
|
||||||
|
if (item.hasNonNull("componentId") && !item.path("componentId").asText().isEmpty()) {
|
||||||
|
String id = escapeHtml(item.path("componentId").asText());
|
||||||
|
html.append(" <li><strong>")
|
||||||
|
.append(id)
|
||||||
|
.append("</strong>: ")
|
||||||
|
.append(message)
|
||||||
|
.append("</li>\n");
|
||||||
|
} else {
|
||||||
|
html.append(" <li>")
|
||||||
|
.append(message)
|
||||||
|
.append("</li>\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
html.append("</ul>\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String capitalize(String text) {
|
||||||
|
if (text == null || text.isEmpty()) return text;
|
||||||
|
return Character.toUpperCase(text.charAt(0)) + text.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Very basic HTML escapement; for more robust use Apache Commons StringEscapeUtils.escapeHtml4().
|
||||||
|
*/
|
||||||
|
private static String escapeHtml(String s) {
|
||||||
|
return s.replace("&", "&")
|
||||||
|
.replace("<", "<")
|
||||||
|
.replace(">", ">")
|
||||||
|
.replace("\"", """);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example usage:
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
String json = "{\n" +
|
||||||
|
" \"critical\": [{\"message\":\"Value too low\"}],\n" +
|
||||||
|
" \"warnings\": [{\"componentId\":\"C3\",\"message\":\"Consider higher tolerance\"}],\n" +
|
||||||
|
" \"optimizations\": [{\"componentId\":\"L2\",\"message\":\"Could use 0805 package\"}]\n" +
|
||||||
|
"}";
|
||||||
|
String html = convertToHtml(json);
|
||||||
|
System.out.println(html);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import java.awt.datatransfer.Clipboard;
|
|||||||
import java.awt.datatransfer.ClipboardOwner;
|
import java.awt.datatransfer.ClipboardOwner;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
import org.diylc.swing.actions.analyze.AiAnalyzeAction;
|
||||||
import org.diylc.swing.actions.analyze.HighlightConnectedAreasAction;
|
import org.diylc.swing.actions.analyze.HighlightConnectedAreasAction;
|
||||||
import org.diylc.swingframework.IDrawingProvider;
|
import org.diylc.swingframework.IDrawingProvider;
|
||||||
|
|
||||||
@@ -275,6 +276,10 @@ public class ActionFactory {
|
|||||||
return new GenerateNetlistAction(plugInPort, swingUI, includeSwitches);
|
return new GenerateNetlistAction(plugInPort, swingUI, includeSwitches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AiAnalyzeAction createAiAnalyzeAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||||
|
return new AiAnalyzeAction(plugInPort, swingUI);
|
||||||
|
}
|
||||||
|
|
||||||
public SummarizeNetlistAction createSummarizeNetlistAction(IPlugInPort plugInPort,
|
public SummarizeNetlistAction createSummarizeNetlistAction(IPlugInPort plugInPort,
|
||||||
ISwingUI swingUI, INetlistAnalyzer summarizer, boolean includeSwitches) {
|
ISwingUI swingUI, INetlistAnalyzer summarizer, boolean includeSwitches) {
|
||||||
return new SummarizeNetlistAction(plugInPort, swingUI, summarizer, includeSwitches);
|
return new SummarizeNetlistAction(plugInPort, swingUI, summarizer, includeSwitches);
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package org.diylc.swing.actions.analyze;
|
||||||
|
|
||||||
|
import org.diylc.common.INetlistAnalyzer;
|
||||||
|
import org.diylc.common.IPlugInPort;
|
||||||
|
import org.diylc.common.ITask;
|
||||||
|
import org.diylc.netlist.Netlist;
|
||||||
|
import org.diylc.netlist.Summary;
|
||||||
|
import org.diylc.swing.ISwingUI;
|
||||||
|
import org.diylc.swingframework.TextDialog;
|
||||||
|
import org.diylc.utils.IconLoader;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AiAnalyzeAction extends AbstractAction {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private IPlugInPort plugInPort;
|
||||||
|
private ISwingUI swingUI;
|
||||||
|
|
||||||
|
public AiAnalyzeAction(IPlugInPort plugInPort, ISwingUI swingUI) {
|
||||||
|
super();
|
||||||
|
this.plugInPort = plugInPort;
|
||||||
|
this.swingUI = swingUI;
|
||||||
|
putValue(AbstractAction.NAME, "AI Circuit Analyzer");
|
||||||
|
// putValue(AbstractAction.SMALL_ICON,
|
||||||
|
// Enum.valueOf(IconLoader.class, summarizer.getIconName()).getIcon());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
||||||
|
swingUI.executeBackgroundTask(new ITask<String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String doInBackground() throws Exception {
|
||||||
|
return plugInPort.getChatbotService().analyzeCircuit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed(Exception e) {
|
||||||
|
swingUI.showMessage(e.getMessage(), "AI Circuit Analyzer", ISwingUI.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void complete(String res) {
|
||||||
|
if (res == null || res.isEmpty()) {
|
||||||
|
swingUI.showMessage("The generated analysis is empty, nothing to show.",
|
||||||
|
"AI Circuit Analyzer", ISwingUI.INFORMATION_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
new TextDialog(swingUI.getOwnerFrame().getRootPane(), res, "AI Circuit Analyzer",
|
||||||
|
new Dimension(800, 600)).setVisible(true);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,6 +66,7 @@ public class AnalyzeMenuPlugin implements IPlugIn {
|
|||||||
List<Action> menuActions = new ArrayList<>();
|
List<Action> menuActions = new ArrayList<>();
|
||||||
|
|
||||||
// Add all menu actions to the list
|
// Add all menu actions to the list
|
||||||
|
menuActions.add(actionFactory.createAiAnalyzeAction(plugInPort, swingUI));
|
||||||
menuActions.add(actionFactory.createCheckProximityAction(plugInPort, swingUI));
|
menuActions.add(actionFactory.createCheckProximityAction(plugInPort, swingUI));
|
||||||
menuActions.add(actionFactory.createBomAction(plugInPort));
|
menuActions.add(actionFactory.createBomAction(plugInPort));
|
||||||
menuActions.add(actionFactory.createGenerateNetlistAction(plugInPort, swingUI, false));
|
menuActions.add(actionFactory.createGenerateNetlistAction(plugInPort, swingUI, false));
|
||||||
|
|||||||
Reference in New Issue
Block a user