diff --git a/ugs-core/src/com/willwinder/universalgcodesender/GrblUtils.java b/ugs-core/src/com/willwinder/universalgcodesender/GrblUtils.java index f64041e763..6091436d1a 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/GrblUtils.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/GrblUtils.java @@ -364,6 +364,8 @@ public static ControllerStatus getStatusFromStatusStringLegacy(String status, Un */ public static ControllerStatus getStatusFromStatusStringV1(ControllerStatus lastStatus, String status, Units reportingUnits) { String stateString = ""; + String subStateString = ""; + Position MPos = null; Position WPos = null; Position WCO = null; @@ -384,10 +386,12 @@ public static ControllerStatus getStatusFromStatusStringV1(ControllerStatus last for (String part : status.substring(0, status.length()-1).split("\\|")) { if (part.startsWith("<")) { int idx = part.indexOf(':'); - if (idx == -1) + if (idx == -1) { stateString = part.substring(1); - else + } else { stateString = part.substring(1, idx); + subStateString = part.substring(idx + 1); + } } else if (part.startsWith("MPos:")) { MPos = GrblUtils.getPositionFromStatusString(status, machinePattern, reportingUnits); @@ -454,7 +458,7 @@ else if (part.startsWith("A:")) { } ControllerState state = getControllerStateFromStateString(stateString); - return new ControllerStatus(state, MPos, WPos, feedSpeed, reportingUnits, spindleSpeed, overrides, WCO, pins, accessoryStates); + return new ControllerStatus(state, subStateString, MPos, WPos, feedSpeed, reportingUnits, spindleSpeed, overrides, WCO, pins, accessoryStates); } /** diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCController.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCController.java index 362543f2a4..66a1c22907 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCController.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCController.java @@ -26,6 +26,7 @@ This file is part of Universal Gcode Sender (UGS). import com.willwinder.universalgcodesender.IFileService; import com.willwinder.universalgcodesender.StatusPollTimer; import com.willwinder.universalgcodesender.Utils; +import static com.willwinder.universalgcodesender.Utils.formatter; import com.willwinder.universalgcodesender.communicator.GrblCommunicator; import com.willwinder.universalgcodesender.communicator.ICommunicator; import com.willwinder.universalgcodesender.communicator.ICommunicatorListener; @@ -33,6 +34,8 @@ This file is part of Universal Gcode Sender (UGS). import com.willwinder.universalgcodesender.connection.ConnectionException; import com.willwinder.universalgcodesender.firmware.FirmwareSettingsException; import com.willwinder.universalgcodesender.firmware.IFirmwareSettings; +import static com.willwinder.universalgcodesender.firmware.fluidnc.FluidNCUtils.DISABLE_ECHO_COMMAND; +import static com.willwinder.universalgcodesender.firmware.fluidnc.FluidNCUtils.GRBL_COMPABILITY_VERSION; import com.willwinder.universalgcodesender.firmware.fluidnc.commands.FluidNCCommand; import com.willwinder.universalgcodesender.firmware.fluidnc.commands.GetAlarmCodesCommand; import com.willwinder.universalgcodesender.firmware.fluidnc.commands.GetErrorCodesCommand; @@ -56,9 +59,12 @@ This file is part of Universal Gcode Sender (UGS). import com.willwinder.universalgcodesender.model.PartialPosition; import com.willwinder.universalgcodesender.model.Position; import com.willwinder.universalgcodesender.model.UnitUtils; +import static com.willwinder.universalgcodesender.model.UnitUtils.Units.MM; +import static com.willwinder.universalgcodesender.model.UnitUtils.scaleUnits; import com.willwinder.universalgcodesender.services.MessageService; import com.willwinder.universalgcodesender.types.GcodeCommand; import com.willwinder.universalgcodesender.utils.ControllerUtils; +import static com.willwinder.universalgcodesender.utils.ControllerUtils.sendAndWaitForCompletion; import com.willwinder.universalgcodesender.utils.IGcodeStreamReader; import com.willwinder.universalgcodesender.utils.SemanticVersion; import com.willwinder.universalgcodesender.utils.ThreadHelper; @@ -74,12 +80,6 @@ This file is part of Universal Gcode Sender (UGS). import java.util.logging.Level; import java.util.logging.Logger; -import static com.willwinder.universalgcodesender.Utils.formatter; -import static com.willwinder.universalgcodesender.firmware.fluidnc.FluidNCUtils.GRBL_COMPABILITY_VERSION; -import static com.willwinder.universalgcodesender.model.UnitUtils.Units.MM; -import static com.willwinder.universalgcodesender.model.UnitUtils.scaleUnits; -import static com.willwinder.universalgcodesender.utils.ControllerUtils.sendAndWaitForCompletion; - /** * @author Joacim Breiler */ @@ -194,7 +194,10 @@ public void setWorkPosition(PartialPosition axisPosition) throws Exception { @Override public void openDoor() throws Exception { - + if (isCommOpen()) { + pauseStreaming(); + communicator.sendByteImmediately(GrblUtils.GRBL_DOOR_COMMAND); + } } @Override @@ -541,6 +544,7 @@ private void initializeController() { issueSoftReset(); return; } + disableEcho(); queryFirmwareVersion(); queryControllerInformation(); @@ -563,6 +567,10 @@ private void initializeController() { } } + private void disableEcho() throws Exception { + communicator.sendByteImmediately(DISABLE_ECHO_COMMAND); + } + /** * Attempts to get the current version of the controller. If the controller is not a FluidNC or if the version is * too low this will throw an exception. @@ -756,14 +764,7 @@ public void rawResponseListener(String response) { } ThreadHelper.invokeLater(this::initializeController); - } - - if (FluidNCUtils.isProbeMessage(response)) { - Position p = FluidNCUtils.parseProbePosition(response, getFirmwareSettings().getReportingUnits()); - listeners.forEach(l -> l.probeCoordinates(p)); - } - - if (FluidNCUtils.isMessageResponse(response)) { + } else if (FluidNCUtils.isMessageResponse(response)) { MessageType messageType = MessageType.INFO; if (controllerStatus.getState() == ControllerState.CONNECTING) { messageType = MessageType.VERBOSE; @@ -772,6 +773,11 @@ public void rawResponseListener(String response) { } else { messageService.dispatchMessage(MessageType.VERBOSE, "Other: " + response + "\n"); } + + if (FluidNCUtils.isProbeMessage(response)) { + Position p = FluidNCUtils.parseProbePosition(response, getFirmwareSettings().getReportingUnits()); + listeners.forEach(l -> l.probeCoordinates(p)); + } } private void checkStreamFinished() { diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCUtils.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCUtils.java index 80a70331b4..3b4dd82806 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCUtils.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCUtils.java @@ -24,13 +24,13 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import static com.willwinder.universalgcodesender.GrblUtils.getControllerStateFromStateString; import static com.willwinder.universalgcodesender.utils.ControllerUtils.sendAndWaitForCompletion; import static com.willwinder.universalgcodesender.utils.ControllerUtils.sendAndWaitForCompletionWithRetry; public class FluidNCUtils { public static final double GRBL_COMPABILITY_VERSION = 1.1d; public static final SemanticVersion MINIMUM_VERSION = new SemanticVersion(3, 3, 0); + public static final byte DISABLE_ECHO_COMMAND = (byte)0x0c; private static final String MESSAGE_REGEX = "\\[MSG:.*]"; private static final Pattern MESSAGE_PATTERN = Pattern.compile(MESSAGE_REGEX); @@ -86,115 +86,8 @@ public static Optional parseSemanticVersion(String response) { return Optional.empty(); } - public static String getVersionNumber(String response) { - return response; - } - - public static Optional parseFirmwareVariant(String response) { - Matcher matcher = WELCOME_PATTERN.matcher(response); - if (matcher.find()) { - String versionString = matcher.group("fncvariant"); - return Optional.ofNullable(versionString); - } - - return Optional.empty(); - } - public static ControllerStatus getStatusFromStatusResponse(ControllerStatus lastStatus, String status, UnitUtils.Units reportingUnits) { - String stateString = ""; - String subStateString = ""; - Position MPos = null; - Position WPos = null; - Position WCO = null; - - ControllerStatus.OverridePercents overrides = null; - ControllerStatus.EnabledPins pins = null; - ControllerStatus.AccessoryStates accessoryStates = null; - - double feedSpeed = 0; - double spindleSpeed = 0; - if (lastStatus != null) { - feedSpeed = lastStatus.getFeedSpeed(); - spindleSpeed = lastStatus.getSpindleSpeed(); - } - boolean isOverrideReport = false; - - // Parse out the status messages. - for (String part : status.substring(0, status.length() - 1).split("\\|")) { - if (part.startsWith("<")) { - int idx = part.indexOf(':'); - if (idx == -1) { - stateString = part.substring(1); - } else { - stateString = part.substring(1, idx); - subStateString = part.substring(idx + 1); - } - } else if (part.startsWith("MPos:")) { - MPos = GrblUtils.getPositionFromStatusString(status, MACHINE_PATTERN, reportingUnits); - } else if (part.startsWith("WPos:")) { - WPos = GrblUtils.getPositionFromStatusString(status, WORK_PATTERN, reportingUnits); - } else if (part.startsWith("WCO:")) { - WCO = GrblUtils.getPositionFromStatusString(status, WCO_PATTERN, reportingUnits); - } else if (part.startsWith("Ov:")) { - isOverrideReport = true; - String[] overrideParts = part.substring(3).trim().split(","); - if (overrideParts.length == 3) { - overrides = new ControllerStatus.OverridePercents( - Integer.parseInt(overrideParts[0]), - Integer.parseInt(overrideParts[1]), - Integer.parseInt(overrideParts[2])); - } - } else if (part.startsWith("F:")) { - feedSpeed = GrblUtils.parseFeedSpeed(part); - } else if (part.startsWith("FS:")) { - String[] parts = part.substring(3).split(","); - feedSpeed = Double.parseDouble(parts[0]); - spindleSpeed = Double.parseDouble(parts[1]); - } else if (part.startsWith("Pn:")) { - String value = part.substring(part.indexOf(':') + 1); - pins = new ControllerStatus.EnabledPins(value); - } else if (part.startsWith("A:")) { - String value = part.substring(part.indexOf(':') + 1); - accessoryStates = new ControllerStatus.AccessoryStates(value); - } - } - - // Grab WCO from state information if necessary. - if (WCO == null) { - // Grab the work coordinate offset. - if (lastStatus != null && lastStatus.getWorkCoordinateOffset() != null) { - WCO = lastStatus.getWorkCoordinateOffset(); - } else { - WCO = new Position(0, 0, 0, 0, 0, 0, reportingUnits); - } - } - - // Calculate missing coordinate with WCO - if (WPos == null && MPos != null) { - WPos = new Position(MPos.x - WCO.x, MPos.y - WCO.y, MPos.z - WCO.z, MPos.a - WCO.a, MPos.b - WCO.b, MPos.c - WCO.c, reportingUnits); - } else if (MPos == null && WPos != null) { - MPos = new Position(WPos.x + WCO.x, WPos.y + WCO.y, WPos.z + WCO.z, WPos.a + WCO.a, WPos.b + WCO.b, WPos.c + WCO.c, reportingUnits); - } - - if (!isOverrideReport && lastStatus != null) { - overrides = lastStatus.getOverrides(); - pins = lastStatus.getEnabledPins(); - accessoryStates = lastStatus.getAccessoryStates(); - } else if (isOverrideReport) { - // If this is an override report and the 'Pn:' field wasn't sent - // set all pins to a disabled state. - if (pins == null) { - pins = new ControllerStatus.EnabledPins(""); - } - // Likewise for accessory states. - if (accessoryStates == null) { - accessoryStates = new ControllerStatus.AccessoryStates(""); - } - } - - ControllerState state = getControllerStateFromStateString(stateString); - - return new ControllerStatus(state, subStateString, MPos, WPos, feedSpeed, reportingUnits, spindleSpeed, overrides, WCO, pins, accessoryStates); + return GrblUtils.getStatusFromStatusStringV1(lastStatus, status, reportingUnits); } public static GetStatusCommand queryForStatusReport(IController controller, MessageService messageService) throws InterruptedException { @@ -214,6 +107,7 @@ public static void addCapabilities(Capabilities capabilities, SemanticVersion ve capabilities.addCapability(CapabilitiesConstants.HOMING); capabilities.addCapability(CapabilitiesConstants.FIRMWARE_SETTINGS); capabilities.addCapability(CapabilitiesConstants.OVERRIDES); + capabilities.addCapability(CapabilitiesConstants.OPEN_DOOR); try { if (firmwareSettings.isSoftLimitsEnabled()) { diff --git a/ugs-core/test/com/willwinder/universalgcodesender/GrblUtilsTest.java b/ugs-core/test/com/willwinder/universalgcodesender/GrblUtilsTest.java index 38996b7cd5..db910a8d88 100644 --- a/ugs-core/test/com/willwinder/universalgcodesender/GrblUtilsTest.java +++ b/ugs-core/test/com/willwinder/universalgcodesender/GrblUtilsTest.java @@ -396,6 +396,22 @@ public void getStatusFromStatusStringV1ShouldReturnState() { assertEquals(ControllerState.TOOL, controllerStatus.getState()); } + @Test + public void getStatusFromStatusStringV1ShouldReturnSubState() { + Capabilities version = new Capabilities(); + version.addCapability(GrblCapabilitiesConstants.REAL_TIME); + + String status = ""; + ControllerStatus controllerStatus = GrblUtils.getStatusFromStatusStringV1(null, status, MM); + assertEquals(ControllerState.ALARM, controllerStatus.getState()); + assertEquals("1", controllerStatus.getSubState()); + + status = ""; + controllerStatus = GrblUtils.getStatusFromStatusStringV1(null, status, MM); + assertEquals(ControllerState.ALARM, controllerStatus.getState()); + assertEquals("banana", controllerStatus.getSubState()); + } + /** * Test of getWorkPositionFromStatusString method, of class GrblUtils. */ @@ -539,9 +555,8 @@ public void getStatusFromStringVersion1WithoutMachineCoordinateStatusString() { String status = ""; Capabilities version = new Capabilities(); version.addCapability(GrblCapabilitiesConstants.V1_FORMAT); - UnitUtils.Units unit = MM; - ControllerStatus controllerStatus = GrblUtils.getStatusFromStatusString(null, status, version, unit); + ControllerStatus controllerStatus = GrblUtils.getStatusFromStatusString(null, status, version, MM); assertEquals(new Position(11, 13, 15, MM), controllerStatus.getMachineCoord()); assertEquals(new Position(4, 5, 6, MM), controllerStatus.getWorkCoord());