A move (deg)
-
+
{
+const TabArea = ({ tabs, currentTab, onTabChange, mountAllTabs = false }) => {
return (
{
{
tabs.map((tab, index) => {
const active = index === currentTab;
+
+ if (mountAllTabs) {
+ return (
+
+ {tab.component}
+
+ );
+ }
+
return (
{active && tab.component}
diff --git a/src/app/widgets/Rotary/StockTurning/index.js b/src/app/widgets/Rotary/StockTurning/index.js
index da7f7987d..3e9e16b6e 100644
--- a/src/app/widgets/Rotary/StockTurning/index.js
+++ b/src/app/widgets/Rotary/StockTurning/index.js
@@ -77,7 +77,14 @@ const StockTurning = () => {
const serializedFile = new File([stockTurningGenerator.gcode], 'rotary_surfacing.gcode');
- pubsub.publish('visualizer:load', stockTurningGenerator.gcode, serializedFile.size, serializedFile.originalname, VISUALIZER_SECONDARY);
+ const payload = {
+ content: stockTurningGenerator.gcode,
+ size: serializedFile.size,
+ name: serializedFile.name,
+ visualizer: VISUALIZER_SECONDARY
+ };
+
+ pubsub.publish('visualizer:load', payload);
};
const loadGcode = () => {
@@ -125,6 +132,7 @@ const StockTurning = () => {
tabs={tabs}
currentTab={activeTab}
onTabChange={(index) => dispatch({ type: SET_ACTIVE_STOCK_TURNING_TAB, payload: index })}
+ mountAllTabs
/>
diff --git a/src/app/widgets/Visualizer/ClientRecentFiles.js b/src/app/widgets/Visualizer/ClientRecentFiles.js
index 64deb0506..90871869b 100644
--- a/src/app/widgets/Visualizer/ClientRecentFiles.js
+++ b/src/app/widgets/Visualizer/ClientRecentFiles.js
@@ -104,7 +104,6 @@ export const sortRecentFiles = (recentFiles = []) => {
};
export const loadRecentFile = (filePath) => {
- //window.api.loadRecentFile({ filePath: filePath });
window.ipcRenderer.send('load-recent-file', { filePath: filePath });
return true;
};
diff --git a/src/app/widgets/Visualizer/Visualizer.jsx b/src/app/widgets/Visualizer/Visualizer.jsx
index 252796665..a196ed518 100644
--- a/src/app/widgets/Visualizer/Visualizer.jsx
+++ b/src/app/widgets/Visualizer/Visualizer.jsx
@@ -1564,13 +1564,13 @@ class Visualizer extends Component {
}
// Use y-axis in grbl, a-axis in grblHal
- const axis = isInRotaryMode && isUsingGRBL && isRotaryFile ? 'y' : 'a';
+ const axis = isInRotaryMode && isRotaryFile ? 'y' : 'a';
const prevValue = prevPos[axis];
const currValue = currPos[axis];
const grblCondition = isUsingGRBL && valueHasChanged && isInRotaryMode;
- const grblHalCondition = isUsingGRBLHal && valueHasChanged;
+ const grblHalCondition = isUsingGRBLHal && valueHasChanged || isUsingGRBLHal && isInRotaryMode;
/**
* GRBL Condition
diff --git a/src/app/widgets/Visualizer/WorkflowControl.jsx b/src/app/widgets/Visualizer/WorkflowControl.jsx
index 14888f31a..3d20c7956 100644
--- a/src/app/widgets/Visualizer/WorkflowControl.jsx
+++ b/src/app/widgets/Visualizer/WorkflowControl.jsx
@@ -40,8 +40,8 @@ import pubsub from 'pubsub-js';
import i18n from 'app/lib/i18n';
import Modal from 'app/components/Modal';
import Input from 'app/containers/Preferences/components/Input';
-import WorkerOutline from '../../workers/Outline.worker';
+import WorkerOutline from '../../workers/Outline.worker';
import CameraDisplay from './CameraDisplay/CameraDisplay';
import FunctionButton from '../../components/FunctionButton/FunctionButton';
import {
@@ -69,7 +69,7 @@ import {
} from '../../constants';
import styles from './workflow-control.styl';
import RecentFileButton from './RecentFileButton';
-import { addRecentFile, createRecentFile, createRecentFileFromRawPath } from './ClientRecentFiles';
+import { addRecentFile, createRecentFileFromRawPath } from './ClientRecentFiles';
import { UPDATE_FILE_INFO } from '../../actions/fileInfoActions';
import { outlineResponse } from '../../workers/Outline.response';
import { shouldVisualizeSVG } from '../../workers/Visualize.response';
@@ -285,12 +285,22 @@ class WorkflowControl extends PureComponent {
componentDidMount() {
if (isElectron()) {
- window.ipcRenderer.on('loaded-recent-file', (msg, fileMetaData) => {
+ window.ipcRenderer.on('loaded-recent-file', (_, fileMetaData) => {
+ if (!fileMetaData) {
+ Toaster.pop({
+ msg: 'Error loading recent file, it may have been deleted or moved to a different folder.',
+ type: TOASTER_DANGER,
+ duration: 5000
+ });
+
+ return;
+ }
+
this.loadRecentFile(fileMetaData);
- const recentFile = createRecentFile(fileMetaData);
- addRecentFile(recentFile);
+ // const recentFile = createRecentFile(fileMetaData);
+ // addRecentFile(recentFile);
});
- window.ipcRenderer.on('returned-upload-dialog-data', (msg, file) => {
+ window.ipcRenderer.on('returned-upload-dialog-data', (_, file) => {
this.handleElectronFileUpload(file);
});
}
diff --git a/src/electron-app/RecentFiles.js b/src/electron-app/RecentFiles.js
index 13f692ce3..ded4a33b3 100644
--- a/src/electron-app/RecentFiles.js
+++ b/src/electron-app/RecentFiles.js
@@ -47,6 +47,7 @@ export const parseAndReturnGCode = async ({ filePath }) => {
try {
const fileExists = await fileExistsAtPath(filePath);
+
if (!fileExists) {
return null; // TODO: Handle null as FILENOTFOUND error
}
@@ -55,6 +56,7 @@ export const parseAndReturnGCode = async ({ filePath }) => {
const { size } = stats;
const data = await fs.readFile(filePath, 'utf-8');
+
return {
result: data,
size: size,
diff --git a/src/electron-app/WindowManager.js b/src/electron-app/WindowManager.js
index b2aefae07..3c087d20e 100644
--- a/src/electron-app/WindowManager.js
+++ b/src/electron-app/WindowManager.js
@@ -101,7 +101,7 @@ class WindowManager {
const webContents = window.webContents;
// Enable remote API
remoteMain.enable(window.webContents);
- //window.removeMenu();
+ window.removeMenu();
window.webContents.once('did-finish-load', () => {
window.setTitle(options.title);
});
diff --git a/src/main.js b/src/main.js
index 70ccfff9f..e65c7a4a0 100644
--- a/src/main.js
+++ b/src/main.js
@@ -45,7 +45,7 @@ let grblLog = log.create('grbl');
let logPath;
if (process.env.NODE_ENV === 'production') {
- Sentry.init({ dsn: 'https://c09ff263997c4a47ba22b3c948f19734@o558751.ingest.sentry.io/5692684' });
+ Sentry.init({ dsn: 'https://c09ff263997c4a47ba22b3c948f19734@o558751.ingest.sentry.io/5692684', release: pkg.version });
}
const main = () => {
@@ -182,7 +182,9 @@ const main = () => {
});
autoUpdater.on('update-available', (info) => {
- window.webContents.send('update_available', info);
+ setTimeout(() => {
+ window.webContents.send('update_available', info);
+ }, 5000);
});
autoUpdater.on('error', (err) => {
@@ -344,7 +346,7 @@ const main = () => {
}
autoUpdater.autoDownload = false; // We don't want to force update but will prompt until it is updated
// There may be situations where something is blocking the update check outside of internet connectivity
- // This sets a 5 second timeout on the await.
+ // This sets a 4 second timeout on the await.
asyncCallWithTimeout(autoUpdater.checkForUpdates(), 4000);
}
});
diff --git a/src/package.json b/src/package.json
index 40dac902b..f90158b75 100644
--- a/src/package.json
+++ b/src/package.json
@@ -1,6 +1,6 @@
{
- "name": "gSender-Edge",
- "version": "1.3.10-EDGE",
+ "name": "gSender",
+ "version": "1.4.1",
"productName": "gSender",
"description": "CNC Milling Controller",
"author": {
diff --git a/src/server/controllers/Grbl/GrblController.js b/src/server/controllers/Grbl/GrblController.js
index d6f89d5dc..f0dfda1a3 100644
--- a/src/server/controllers/Grbl/GrblController.js
+++ b/src/server/controllers/Grbl/GrblController.js
@@ -248,7 +248,7 @@ class GrblController {
}
}
}
- return data;
+ return data.replace(/\([^\)]*\)/gm, '');
}
});
@@ -270,7 +270,6 @@ class GrblController {
const commentString = (comment && comment[0].length > 0) ? comment[0].trim()
.replace(';', '') : '';
line = line.replace(commentMatcher, '')
- .replace('/uFEFF', '')
.trim();
context = this.populateContext(context);
@@ -420,7 +419,7 @@ class GrblController {
line = line.replace(bracketCommentLine, '').trim();
let comment = line.match(commentMatcher);
let commentString = (comment && comment[0].length > 0) ? comment[0].trim().replace(';', '') : '';
- line = line.replace(commentMatcher, '').replace('/uFEFF', '').trim();
+ line = line.replace(commentMatcher, '').trim();
context = this.populateContext(context);
const { sent, received } = this.sender.state;
@@ -751,7 +750,7 @@ class GrblController {
this.emit('error', {
type: ERROR,
code: `${code}`,
- description: error.description,
+ description: _.get(error, 'description', ''),
line: line,
lineNumber: isFileError ? received + 1 : '',
origin: errorOrigin,
@@ -1938,7 +1937,7 @@ class GrblController {
//axes.Z = calculateAxisValue({ direction: Math.sign(axes.Z), position: mpos.z, maxTravel: (-1 * $132) });
}
} else {
- jogFeedrate = 1250;
+ jogFeedrate = 10000;
Object.keys(axes).forEach((axis) => {
axes[axis] *= jogFeedrate;
});
diff --git a/src/server/controllers/Grblhal/GrblHalController.js b/src/server/controllers/Grblhal/GrblHalController.js
index 69d57d6ca..9f79c4c0a 100644
--- a/src/server/controllers/Grblhal/GrblHalController.js
+++ b/src/server/controllers/Grblhal/GrblHalController.js
@@ -46,9 +46,11 @@ import monitor from '../../services/monitor';
import taskRunner from '../../services/taskrunner';
import store from '../../store';
import {
+ A_AXIS_COMMANDS,
GLOBAL_OBJECTS as globalObjects,
WRITE_SOURCE_CLIENT,
- WRITE_SOURCE_FEEDER
+ WRITE_SOURCE_FEEDER,
+ Y_AXIS_COMMANDS
} from '../constants';
import GrblHalRunner from './GrblHalRunner';
import {
@@ -82,6 +84,7 @@ import { determineMachineZeroFlagSet, determineMaxMovement, getAxisMaximumLocati
import { calcOverrides } from '../runOverride';
import ToolChanger from '../../lib/ToolChanger';
import { GRBL_ACTIVE_STATE_CHECK } from 'server/controllers/Grbl/constants';
+import { GCODE_TRANSLATION_TYPE, translateGcode } from '../../lib/gcode-translation';
// % commands
const WAIT = '%wait';
const PREHOOK_COMPLETE = '%pre_complete';
@@ -196,6 +199,9 @@ class GrblHalController {
// Toolchange
toolChanger = null;
+ // Rotary
+ isInRotaryMode = false;
+
constructor(engine, options) {
if (!engine) {
throw new Error('engine must be specified');
@@ -336,6 +342,23 @@ class GrblHalController {
line = line.replace('M6', '(M6)');
}
+ if (this.isInRotaryMode) {
+ const containsACommand = A_AXIS_COMMANDS.test(line);
+ const containsYCommand = Y_AXIS_COMMANDS.test(line);
+
+ if (containsACommand && !containsYCommand) {
+ const isUsingImperialUnits = context.modal.units === 'G20';
+
+ line = translateGcode({
+ gcode: line,
+ from: 'A',
+ to: 'Y',
+ regex: A_AXIS_COMMANDS,
+ type: isUsingImperialUnits ? GCODE_TRANSLATION_TYPE.TO_IMPERIAL : GCODE_TRANSLATION_TYPE.DEFAULT
+ });
+ }
+ }
+
return line;
}
});
@@ -479,6 +502,30 @@ class GrblHalController {
line = line.replace(`${tool?.[0]}`, `(${tool?.[0]})`);
}
+ /**
+ * Rotary Logic
+ * Need to change the A-axis movements to Y-movements to emulate the rotary axis on grbl
+ */
+ if (this.isInRotaryMode) {
+ const containsACommand = A_AXIS_COMMANDS.test(line);
+ const containsYCommand = Y_AXIS_COMMANDS.test(line);
+
+ if (containsACommand && !containsYCommand) {
+ const isUsingImperialUnits = context.modal.units === 'G20';
+
+ line = translateGcode({
+ gcode: line,
+ from: 'A',
+ to: 'Y',
+ regex: A_AXIS_COMMANDS,
+ type: isUsingImperialUnits ? GCODE_TRANSLATION_TYPE.TO_IMPERIAL : GCODE_TRANSLATION_TYPE.DEFAULT
+ });
+ }
+ }
+ /**
+ * End of Rotary Logic
+ */
+
return line;
}
});
@@ -688,7 +735,7 @@ class GrblHalController {
this.emit('error', {
type: ERROR,
code: `${code}`,
- description: error.description || '',
+ description: error?.description || '',
line: line,
lineNumber: isFileError ? received + 1 : '',
origin: errorOrigin,
@@ -1898,7 +1945,7 @@ class GrblHalController {
axes.Z = calculateAxisValue({ direction: Math.sign(axes.Z), position: Math.abs(mpos.z), maxTravel: $132 });
}
} else {
- jogFeedrate = 1250;
+ jogFeedrate = 10000;
Object.keys(axes).forEach((axis) => {
axes[axis] *= jogFeedrate;
});
@@ -2031,6 +2078,10 @@ class GrblHalController {
const [estimateData] = args;
this.sender.setEstimateData(estimateData.estimates);
this.sender.setEstimatedTime(estimateData.estimatedTime);
+ },
+ 'updateRotaryMode': () => {
+ const [isInRotaryMode] = args;
+ this.isInRotaryMode = isInRotaryMode;
}
}[cmd];
diff --git a/src/server/services/cncengine/CNCEngine.js b/src/server/services/cncengine/CNCEngine.js
index 27a779cf6..5fdaf72cc 100644
--- a/src/server/services/cncengine/CNCEngine.js
+++ b/src/server/services/cncengine/CNCEngine.js
@@ -271,7 +271,7 @@ class CNCEngine {
});
// Filter ports by productId to avoid non-arduino devices from appearing
- const validProductIDs = ['6015', '6001', '606D', '003D', '0042', '0043', '2341', '7523', 'EA60', '2303', '2145', '0AD8', '08D8', '5740'];
+ const validProductIDs = ['6015', '6001', '606D', '003D', '0042', '0043', '2341', '7523', 'EA60', '2303', '2145', '0AD8', '08D8', '5740', '0FA7'];
const validVendorIDs = ['1D50', '0403', '2341', '0042', '1A86', '10C4', '067B', '03EB', '16D0', '0483'];
let [recognizedPorts, unrecognizedPorts] = partition(ports, (port) => {
return validProductIDs.includes(port.productId) && validVendorIDs.includes(port.vendorId);
@@ -332,7 +332,7 @@ class CNCEngine {
});
// Open serial port
- socket.on('open', (port, controllerType, options, callback = noop) => {
+ socket.on('open', (port, controllerType = GRBL, options, callback = noop) => {
//const numClients = this.io.sockets.adapter.rooms.get(port)?.size || 0;
if (typeof callback !== 'function') {
callback = noop;