2018-12-21 13:56:11 +00:00
process . env . ELECTRON _DISABLE _SECURITY _WARNINGS = '1' ;
2020-08-10 14:27:13 +00:00
process . on ( 'uncaughtException' , function ( err ) {
2023-04-27 18:45:28 +00:00
//showErrorDialog(err, attempts = 2) // make two attempts to show an uncaughtException in a dialog
if ( DEBUG ) {
debug _log ( err )
} else {
console . log ( err ) ;
}
2020-08-10 14:27:13 +00:00
} )
2023-04-27 18:45:28 +00:00
function showErrorDialog ( err , attempts ) {
console . error ( 'Attempting to show an error dialog.' )
if ( ! attempts ) return ;
try {
let options = {
type : 'error' ,
buttons : [ 'OK' ] ,
title : 'Error' ,
message : ` An error occured. ` ,
detail : ` ${ err . message } \r \r \r If you feel this shouldn't be happening, please report it at: \r \r https://github.com/OpenBuilds/OpenBuilds-CONTROL/issues ` ,
} ;
let window = BrowserWindow . getFocusedWindow ( )
dialog . showMessageBoxSync ( window , options )
} catch ( e ) {
console . error ( ` An error occurred trying show an error, ho-boy. ${ e } . We'll try again ${ attempts } more time(s). ` )
setTimeout ( ( ) => {
showErrorDialog ( err , -- attempts )
} , millisecondDelay = 2000 ) ;
}
}
2020-03-06 15:59:58 +00:00
// To see console.log output run with `DEBUGCONTROL=true electron .` or set environment variable for DEBUGCONTROL=true
// debug_log debug overhead
2020-04-19 07:40:14 +00:00
DEBUG = false ;
2020-03-06 15:59:58 +00:00
if ( process . env . DEBUGCONTROL ) {
DEBUG = true ;
console . log ( "Console Debugging Enabled" )
}
function debug _log ( ) {
if ( DEBUG ) {
console . log . apply ( this , arguments ) ;
}
} // end Debug Logger
debug _log ( "Starting OpenBuilds CONTROL v" + require ( './package' ) . version )
2018-06-26 10:33:13 +00:00
2018-07-11 09:02:41 +00:00
var config = { } ;
2023-04-27 18:45:28 +00:00
config . webPorts = [ 3000 , 3020 , 3200 , 3220 ]
config . webPortIdx = 0 ;
config . nextWebPort = function ( ) {
config . webPort = config . webPorts [ config . webPortIdx ]
config . webPortIdx ++
if ( config . webPortIdx == config . webPorts . length ) {
throw new Error ( ` No ports were available to start the http server. \r \r We tried ports ${ config . webPorts . join ( "," ) } . ` ) ;
}
return config . webPort ;
}
config . webPort = process . env . WEB _PORT || config . nextWebPort ( ) ;
2024-04-08 14:36:02 +00:00
config . posDecimals = process . env . DRO _DECIMALS || 3 ;
2022-07-06 20:08:38 +00:00
config . grblWaitTime = 0.5 ;
2018-07-11 09:02:41 +00:00
config . firmwareWaitTime = 4 ;
2018-06-19 08:07:03 +00:00
var express = require ( "express" ) ;
var app = express ( ) ;
var http = require ( "http" ) . Server ( app ) ;
2018-07-11 09:02:41 +00:00
var https = require ( 'https' ) ;
2023-02-16 17:05:26 +00:00
//var ioServer = require('socket.io');
const {
Server : ioServer
} = require ( 'socket.io' ) ;
2021-02-01 21:31:46 +00:00
var io = new ioServer ( ) ;
2018-07-11 09:02:41 +00:00
var fs = require ( 'fs' ) ;
2018-07-11 12:39:24 +00:00
var path = require ( "path" ) ;
const join = require ( 'path' ) . join ;
2023-02-16 17:05:26 +00:00
const {
mkdirp
} = require ( 'mkdirp' )
//const drivelist = require('drivelist'); // removed in 1.0.350 due to Drivelist stability issues
2018-07-11 12:39:24 +00:00
2022-12-20 18:50:36 +00:00
// FluidNC test
var fluidncConfig = "" ;
// FluidNC end test
2022-07-06 20:08:38 +00:00
2018-09-18 14:09:11 +00:00
app . use ( express . static ( path . join ( _ _dirname , "app" ) ) ) ;
2021-01-20 16:23:46 +00:00
//app.use(express.limit('200M'));
2023-02-23 13:24:27 +00:00
app . use ( function setCommonHeaders ( req , res , next ) {
res . set ( "Access-Control-Allow-Private-Network" , "true" ) ;
next ( ) ;
} ) ;
app . all ( '/*' , function ( req , res , next ) {
res . header ( "Access-Control-Allow-Origin" , "*" ) ;
res . header ( "Access-Control-Allow-Headers" , "X-Requested-With" ) ;
res . header ( "Access-Control-Allow-Private-Network" , "true" ) ;
next ( ) ;
} ) ;
2018-09-18 14:09:11 +00:00
2020-11-20 15:50:37 +00:00
// Interface firmware flash
app . post ( '/uploadCustomFirmware' , ( req , res ) => {
// 'firmwareBin' is the name of our file input field in the HTML form
let upload = multer ( {
storage : storage
} ) . single ( 'firmwareBin' ) ;
upload ( req , res , function ( err ) {
// req.file contains information of uploaded file
// req.body contains information of text fields, if there were any
if ( err instanceof multer . MulterError ) {
return res . send ( err ) ;
} else if ( err ) {
return res . send ( err ) ;
}
// Display uploaded image for user validation
firmwareImagePath = req . file . path ;
2022-11-10 21:06:34 +00:00
res . send ( req . file . path ) ;
2020-11-20 15:50:37 +00:00
} ) ;
} ) ;
// end Interface Firmware flash
2020-03-19 14:21:06 +00:00
//Note when renewing Convert zerossl cert first `openssl.exe rsa -in domain-key.key -out domain-key.key`
// fix error: App threw an error during load
// Error: error:06000066:public key routines:OPENSSL_internal:DECODE_ERROR
2018-07-11 09:02:41 +00:00
var httpsOptions = {
2020-06-01 17:15:27 +00:00
key : fs . readFileSync ( path . join ( _ _dirname , 'privkey1.pem' ) ) ,
cert : fs . readFileSync ( path . join ( _ _dirname , 'fullchain1.pem' ) )
2018-07-11 09:02:41 +00:00
} ;
const httpsserver = https . createServer ( httpsOptions , app ) . listen ( 3001 , function ( ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'https: listening on:' + ip . address ( ) + ":3001" ) ;
2018-07-11 09:02:41 +00:00
} ) ;
2023-04-27 18:45:28 +00:00
const httpserver = http . listen ( config . webPort , '0.0.0.0' , httpServerSuccess ) . on ( 'error' , httpServerError ) ;
function httpServerSuccess ( ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'http: listening on:' + ip . address ( ) + ":" + config . webPort ) ;
2023-04-27 18:45:28 +00:00
if ( jogWindow ) {
jogWindow . loadURL ( ` http://localhost: ${ config . webPort } / ` ) ;
}
}
function httpServerError ( error ) {
// If unable to start (port in use) - try next port in array from config.nextWebPort()
console . error ( error . message ) ;
httpserver . listen ( config . nextWebPort ( ) ) ;
}
2018-07-11 09:02:41 +00:00
io . attach ( httpserver ) ;
io . attach ( httpsserver ) ;
const grblStrings = require ( "./grblStrings.js" ) ;
2022-07-06 20:08:38 +00:00
// Serial
2022-11-10 21:06:34 +00:00
const {
SerialPort
} = require ( 'serialport' )
const {
ReadlineParser
2024-04-08 20:55:14 +00:00
} = require ( '@serialport/parser-readline' )
2022-07-06 20:08:38 +00:00
// telnet
const net = require ( 'net' ) ;
2018-06-19 08:07:03 +00:00
var ip = require ( "ip" ) ;
2022-07-06 20:08:38 +00:00
const Evilscan = require ( 'evilscan' ) ;
var md5 = require ( 'md5' ) ;
2018-06-19 20:25:40 +00:00
var _ = require ( 'lodash' ) ;
2018-06-27 14:08:24 +00:00
var formidable = require ( 'formidable' )
var lastsentuploadprogress = 0 ;
2018-07-11 09:02:41 +00:00
// Electron app
const electron = require ( 'electron' ) ;
const electronApp = electron . app ;
2024-04-25 14:27:42 +00:00
electronApp . setAppUserModelId ( "openbuilds.control" )
2022-11-22 16:29:24 +00:00
const {
dialog
} = require ( 'electron' )
electronApp . commandLine . appendSwitch ( 'ignore-gpu-blacklist' )
electronApp . commandLine . appendSwitch ( 'enable-gpu-rasterization' )
electronApp . commandLine . appendSwitch ( 'enable-zero-copy' )
2019-05-21 12:09:53 +00:00
2018-08-23 20:09:27 +00:00
if ( isElectron ( ) ) {
2020-03-06 15:59:58 +00:00
debug _log ( "Local User Data: " + electronApp . getPath ( 'userData' ) )
2018-08-23 20:09:27 +00:00
}
2022-11-22 16:29:24 +00:00
2018-07-11 09:02:41 +00:00
const BrowserWindow = electron . BrowserWindow ;
const Tray = electron . Tray ;
const nativeImage = require ( 'electron' ) . nativeImage
const Menu = require ( 'electron' ) . Menu
2019-01-10 17:42:08 +00:00
var forceQuit
2018-07-16 17:24:09 +00:00
2018-07-11 09:02:41 +00:00
var appIcon = null ,
jogWindow = null ,
mainWindow = null
2018-08-28 16:12:42 +00:00
var autoUpdater
2018-07-11 12:39:24 +00:00
2020-11-23 19:06:28 +00:00
2018-12-27 13:16:39 +00:00
var updateIsDownloading = false ;
2018-08-23 20:09:27 +00:00
if ( isElectron ( ) ) {
2018-08-28 16:12:42 +00:00
autoUpdater = require ( "electron-updater" ) . autoUpdater
2018-08-23 20:09:27 +00:00
var availversion = '0.0.0'
autoUpdater . on ( 'checking-for-update' , ( ) => {
var string = 'Starting update... Please wait' ;
var output = {
'command' : 'autoupdate' ,
'response' : string
}
io . sockets . emit ( 'updatedata' , output ) ;
} )
autoUpdater . on ( 'update-available' , ( ev , info ) => {
2018-12-27 13:16:39 +00:00
updateIsDownloading = true ;
2018-08-23 20:09:27 +00:00
var string = "Starting Download: v" + ev . version ;
availversion = ev . version
var output = {
'command' : 'autoupdate' ,
'response' : string
}
io . sockets . emit ( 'updatedata' , output ) ;
2020-03-06 15:59:58 +00:00
debug _log ( JSON . stringify ( ev ) )
2018-08-23 20:09:27 +00:00
} )
autoUpdater . on ( 'update-not-available' , ( ev , info ) => {
var string = 'Update not available. Installed version: ' + require ( './package' ) . version + " / Available version: " + ev . version + ".\n" ;
if ( require ( './package' ) . version === ev . version ) {
string += "You are already running the latest version!"
}
var output = {
'command' : 'autoupdate' ,
'response' : string
}
io . sockets . emit ( 'updatedata' , output ) ;
2020-03-06 15:59:58 +00:00
debug _log ( JSON . stringify ( ev ) )
2018-08-23 20:09:27 +00:00
} )
autoUpdater . on ( 'error' , ( ev , err ) => {
if ( err ) {
var string = 'Error in auto-updater: \n' + err . split ( 'SyntaxError' ) [ 0 ] ;
} else {
var string = 'Error in auto-updater' ;
}
var output = {
'command' : 'autoupdate' ,
'response' : string
}
io . sockets . emit ( 'updatedata' , output ) ;
} )
autoUpdater . on ( 'download-progress' , ( ev , progressObj ) => {
2018-12-27 13:16:39 +00:00
updateIsDownloading = true ;
2018-08-23 20:09:27 +00:00
var string = 'Download update ... ' + ev . percent . toFixed ( 1 ) + '%' ;
2020-03-06 15:59:58 +00:00
debug _log ( string )
2018-08-23 20:09:27 +00:00
var output = {
'command' : 'autoupdate' ,
'response' : string
}
io . sockets . emit ( 'updatedata' , output ) ;
io . sockets . emit ( 'updateprogress' , ev . percent . toFixed ( 0 ) ) ;
} )
2018-07-11 12:39:24 +00:00
2018-08-23 20:09:27 +00:00
autoUpdater . on ( 'update-downloaded' , ( info ) => {
var string = "New update ready" ;
var output = {
'command' : 'autoupdate' ,
'response' : string
}
io . sockets . emit ( 'updatedata' , output ) ;
2018-08-10 19:42:30 +00:00
io . sockets . emit ( 'updateready' , availversion ) ;
2018-08-23 20:09:27 +00:00
// repeat every minute
setTimeout ( function ( ) {
io . sockets . emit ( 'updateready' , availversion ) ;
2023-04-27 18:45:28 +00:00
} , 1000 * 60 * 60 * 8 ) // 8hrs before alerting again if it was snoozed
2018-12-27 13:16:39 +00:00
updateIsDownloading = false ;
2018-08-23 20:09:27 +00:00
} ) ;
2018-08-28 16:12:42 +00:00
} else {
2020-03-06 15:59:58 +00:00
debug _log ( "Running outside Electron: Disabled AutoUpdater" )
2018-08-23 20:09:27 +00:00
}
2018-07-11 12:39:24 +00:00
2018-08-23 20:09:27 +00:00
if ( isElectron ( ) ) {
var uploadsDir = electronApp . getPath ( 'userData' ) + '/upload/' ;
} else {
var uploadsDir = process . env . APPDATA || ( process . platform == 'darwin' ? process . env . HOME + 'Library/Preferences' : '/var/local' )
}
2020-12-15 17:06:42 +00:00
var jobStartTime = false ;
2020-03-06 15:59:58 +00:00
var jobCompletedMsg = "" ; // message sent when job is done
2018-08-29 08:11:14 +00:00
var uploadedgcode = "" ; // var to store uploaded gcode
2019-04-29 17:26:29 +00:00
var uploadedworkspace = "" ; // var to store uploaded OpenBuildsCAM Workspace
2018-07-11 09:02:41 +00:00
2020-03-19 15:13:52 +00:00
mkdirp ( uploadsDir ) . then ( made =>
debug _log ( 'Created Uploads Temp Directory' ) )
2018-07-03 20:54:15 +00:00
2020-04-20 20:58:03 +00:00
// Check USB Selective Suspend Settings
function checkPowerSettings ( ) {
if ( process . platform == 'win32' ) {
debug _log ( "Checking Power Settings" )
var powerplan = "" ,
usbselectiveAC = false ,
usbselectiveDC = false ;
const {
exec
} = require ( 'child_process' ) ;
const cfg = exec ( 'powercfg /GETACTIVESCHEME' , function ( error , stdout , stderr ) {
if ( error ) {
debug _log ( error . stack ) ;
debug _log ( 'Error code: ' + error . code ) ;
debug _log ( 'Signal received: ' + error . signal ) ;
}
// console.log('Child Process STDOUT: ' + stdout);
// console.log('Child Process STDERR: ' + stderr);
powerplan = stdout . split ( ":" ) [ 1 ] . split ( "()" ) [ 0 ] . trim ( )
} ) ;
cfg . on ( 'exit' , function ( code ) {
debug _log ( 'powercfg /GETACTIVESCHEME exited with exit code ' + code ) ;
if ( code == 0 ) {
const usbsetting = exec ( 'powercfg /q ' + powerplan , function ( error , stdout , stderr ) {
if ( error ) {
debug _log ( error . stack ) ;
debug _log ( 'Error code: ' + error . code ) ;
debug _log ( 'Signal received: ' + error . signal ) ;
}
// console.log('Child Process STDOUT: ' + stdout);
// console.log('Child Process STDERR: ' + stderr);
usbselective = ( stdout . slice ( stdout . search ( "USB selective suspend setting" ) - 1 ) ) . split ( "\n" )
usbselective . length = 7 ;
if ( usbselective [ 5 ] . indexOf ( "0x00000000" ) != - 1 ) {
debug _log ( "USB Selective Suspend DISABLED on AC power " )
status . driver . powersettings . usbselectiveAC = false ;
} else if ( usbselective [ 5 ] . indexOf ( "0x00000001" ) != - 1 ) {
debug _log ( "USB Selective Suspend ENABLED on AC power " )
status . driver . powersettings . usbselectiveAC = true ;
}
if ( usbselective [ 6 ] . indexOf ( "0x00000000" ) != - 1 ) {
debug _log ( "USB Selective Suspend DISABLED on DC power " )
status . driver . powersettings . usbselectiveDC = false ;
} else if ( usbselective [ 6 ] . indexOf ( "0x00000001" ) != - 1 ) {
debug _log ( "USB Selective Suspend ENABLED on DC power " )
status . driver . powersettings . usbselectiveDC = true ;
}
} ) ;
usbsetting . on ( 'exit' , function ( code ) {
debug _log ( 'powercfg /q exited with exit code ' + code ) ;
setTimeout ( function ( ) {
debug _log ( status . driver . powersettings . usbselectiveDC , status . driver . powersettings . usbselectiveAC )
2022-07-06 20:08:38 +00:00
} , 100 ) ;
2020-04-20 20:58:03 +00:00
} )
}
} ) ;
// end USB Selective Suspend
}
}
2022-07-06 20:08:38 +00:00
var oldportslist , oldiplist ;
2019-02-11 19:29:44 +00:00
var oldpinslist ;
2018-06-19 20:25:40 +00:00
const iconPath = path . join ( _ _dirname , 'app/icon.png' ) ;
2018-06-25 17:25:19 +00:00
const iconNoComm = path . join ( _ _dirname , 'app/icon-notconnected.png' ) ;
const iconPlay = path . join ( _ _dirname , 'app/icon-play.png' ) ;
const iconStop = path . join ( _ _dirname , 'app/icon-stop.png' ) ;
const iconPause = path . join ( _ _dirname , 'app/icon-pause.png' ) ;
const iconAlarm = path . join ( _ _dirname , 'app/icon-bell.png' ) ;
2018-06-19 20:25:40 +00:00
2018-06-19 08:07:03 +00:00
var iosocket ;
var lastCommand = false
var gcodeQueue = [ ] ;
var queuePointer = 0 ;
2018-08-07 17:34:04 +00:00
var statusLoop ;
2022-05-02 19:22:15 +00:00
var frontEndUpdateLoop
2018-06-19 08:07:03 +00:00
var queueCounter ;
var listPortsLoop ;
2018-08-09 16:34:51 +00:00
var GRBL _RX _BUFFER _SIZE = 127 ; // 128 characters
2022-04-21 12:26:03 +00:00
var GRBLHAL _RX _BUFFER _SIZE = 1023 ; // 128 characters
2018-08-09 16:34:51 +00:00
var sentBuffer = [ ] ;
2018-06-19 08:07:03 +00:00
var xPos = 0.00 ;
var yPos = 0.00 ;
var zPos = 0.00 ;
var aPos = 0.00 ;
var xOffset = 0.00 ;
var yOffset = 0.00 ;
var zOffset = 0.00 ;
var aOffset = 0.00 ;
2022-11-01 20:21:24 +00:00
2018-06-19 08:07:03 +00:00
var feedOverride = 100 ,
spindleOverride = 100 ;
2019-04-29 17:26:29 +00:00
2018-06-19 08:07:03 +00:00
//regex to identify MD5hash on sdupload later
var re = new RegExp ( "^[a-f0-9]{32}" ) ;
var status = {
2023-03-02 18:30:08 +00:00
login : false ,
2018-06-26 10:33:13 +00:00
driver : {
2018-08-24 19:00:03 +00:00
version : require ( './package' ) . version ,
2018-08-29 08:11:14 +00:00
ipaddress : ip . address ( ) ,
2020-04-20 20:58:03 +00:00
operatingsystem : false ,
powersettings : {
usbselectiveAC : null ,
usbselectiveDC : null
} ,
2018-06-26 10:33:13 +00:00
} ,
2018-06-19 08:07:03 +00:00
machine : {
2018-12-21 13:56:11 +00:00
name : '' ,
2022-11-01 20:21:24 +00:00
has4thAxis : false ,
2018-08-07 10:05:49 +00:00
inputs : [ ] ,
2018-06-19 08:07:03 +00:00
overrides : {
feedOverride : 100 , //
spindleOverride : 100 , //
realFeed : 0 , //
realSpindle : 0 //
} ,
2019-09-03 18:36:09 +00:00
//
tool : {
nexttool : {
number : 0 ,
line : ""
}
} ,
2021-12-01 19:34:45 +00:00
modals : {
2022-03-29 13:53:43 +00:00
//motionmode: "G0", // G0, G1, G2, G3, G38.2, G38.3, G38.4, G38.5, G80
2021-12-01 19:34:45 +00:00
coordinatesys : "G54" , // G54, G55, G56, G57, G58, G59
plane : "G17" , // G17, G18, G19
distancemode : "G90" , // G90, G91
arcdistmode : "G91.1" , // G91.1
feedratemode : "G94" , // G93, G94
unitsmode : "G21" , // G20, G21
radiuscomp : "G40" , // G40
tlomode : "G49" , // G43.1, G49
2022-03-29 13:53:43 +00:00
// programmode: "M0", // M0, M1, M2, M30
2021-12-01 19:34:45 +00:00
spindlestate : "M5" , // M3, M4, M5
2022-04-21 20:04:00 +00:00
coolantstate : "M9" , // M7, M8, M9
homedRecently : false
2022-03-29 13:53:43 +00:00
// tool: "0",
// spindle: "0",
// feedrate: "0"
2021-12-01 19:34:45 +00:00
} ,
2018-12-28 21:28:44 +00:00
probe : {
x : 0.00 ,
y : 0.00 ,
z : 0.00 ,
2020-06-22 21:04:23 +00:00
state : - 1
2018-12-28 21:28:44 +00:00
} ,
2018-06-19 08:07:03 +00:00
position : {
work : {
x : 0 ,
y : 0 ,
z : 0 ,
a : 0 ,
e : 0
} ,
offset : {
x : 0 ,
y : 0 ,
z : 0 ,
a : 0 ,
e : 0
}
} ,
firmware : {
type : "" ,
2022-04-21 12:26:03 +00:00
platform : "" ,
2018-06-19 08:07:03 +00:00
version : "" ,
date : "" ,
2018-08-07 10:05:49 +00:00
buffer : [ ] ,
2019-07-23 19:04:50 +00:00
features : [ ] ,
2023-03-01 18:05:29 +00:00
blockBufferSize : 0 ,
rxBufferSize : 0 ,
2018-06-19 08:07:03 +00:00
} ,
} ,
comms : {
2019-09-13 18:39:59 +00:00
connectionStatus : 0 , //0 = not connected, 1 = opening, 2 = connected, 3 = playing, 4 = paused, 5 = alarm, 6 = firmware upgrade
2018-06-19 08:07:03 +00:00
runStatus : "Pending" , // 0 = init, 1 = idle, 2 = alarm, 3 = stop, 4 = run, etc?
queue : 0 ,
blocked : false ,
paused : false ,
controllerBuffer : 0 , // Seems like you are tracking available buffer? Maybe nice to have in frontend?
interfaces : {
2022-07-06 20:08:38 +00:00
type : "" ,
2018-06-19 08:07:03 +00:00
ports : "" ,
2022-07-06 20:08:38 +00:00
networkDevices : [ ] ,
2018-06-19 08:07:03 +00:00
activePort : "" // or activeIP in the case of wifi/telnet?
} ,
alarm : ""
2020-11-23 19:06:28 +00:00
} ,
interface : {
2023-02-16 17:05:26 +00:00
diskdrive : false ,
2020-11-24 16:30:37 +00:00
firmware : {
availVersion : "" ,
2020-12-15 17:06:42 +00:00
installedVersion : "" ,
2020-12-16 08:20:46 +00:00
} ,
connected : false
2018-06-19 08:07:03 +00:00
}
} ;
2018-12-21 15:44:37 +00:00
2020-03-19 15:13:52 +00:00
async function findPorts ( ) {
const ports = await SerialPort . list ( )
// console.log(ports)
2018-06-19 20:25:40 +00:00
oldportslist = ports ;
2018-06-19 08:07:03 +00:00
status . comms . interfaces . ports = ports ;
2020-03-19 15:13:52 +00:00
}
findPorts ( )
async function findChangedPorts ( ) {
const ports = await SerialPort . list ( )
// console.log(ports)
status . comms . interfaces . ports = ports ;
if ( ! _ . isEqual ( ports , oldportslist ) ) {
var newPorts = _ . differenceWith ( ports , oldportslist , _ . isEqual )
if ( newPorts . length > 0 ) {
debug _log ( "Plugged " + newPorts [ 0 ] . path ) ;
}
var removedPorts = _ . differenceWith ( oldportslist , ports , _ . isEqual )
if ( removedPorts . length > 0 ) {
debug _log ( "Unplugged " + removedPorts [ 0 ] . path ) ;
}
}
oldportslist = ports ;
// throw new Error('No ports found')
2020-11-24 16:30:37 +00:00
findPorts ( )
2020-03-19 15:13:52 +00:00
}
2023-02-16 17:05:26 +00:00
// async function findDisks() {
// const drives = await drivelist.list();
// status.interface.diskdrives = drives;
// } // removed in 1.0.350 due to Drivelist stability issues
2018-06-19 08:07:03 +00:00
var PortCheckinterval = setInterval ( function ( ) {
2018-06-22 19:49:51 +00:00
if ( status . comms . connectionStatus == 0 ) {
2020-03-19 15:13:52 +00:00
findChangedPorts ( ) ;
2018-06-22 19:49:51 +00:00
}
2023-02-16 17:05:26 +00:00
//findDisks(); // removed in 1.0.350 due to Drivelist stability issues
2020-11-24 16:30:37 +00:00
} , 1000 ) ;
2018-06-19 08:07:03 +00:00
2022-07-06 20:08:38 +00:00
// var telnetCheckinterval = setInterval(function() {
// if (status.comms.connectionStatus == 0) {
// scanForTelnetDevices();
// }
// }, 30000);
// scanForTelnetDevices();
2020-04-20 20:58:03 +00:00
checkPowerSettings ( )
2018-06-27 14:08:24 +00:00
// JSON API
app . get ( '/api/version' , ( req , res ) => {
2018-06-29 19:48:34 +00:00
res . header ( "Access-Control-Allow-Origin" , "*" ) ;
res . header ( "Access-Control-Allow-Headers" , "Origin, X-Requested-With, Content-Type, Accept" ) ;
2018-06-27 14:08:24 +00:00
data = {
2018-06-29 19:48:34 +00:00
"application" : "OMD" ,
2018-06-27 14:08:24 +00:00
"version" : require ( './package' ) . version ,
"ipaddress" : ip . address ( ) + ":" + config . webPort
}
res . send ( JSON . stringify ( data ) , null , 2 ) ;
} )
2018-08-08 17:56:11 +00:00
app . get ( '/activate' , ( req , res ) => {
2020-03-06 15:59:58 +00:00
debug _log ( req . hostname )
2018-08-08 17:56:11 +00:00
res . header ( "Access-Control-Allow-Origin" , "*" ) ;
res . header ( "Access-Control-Allow-Headers" , "Origin, X-Requested-With, Content-Type, Accept" ) ;
2018-11-23 16:13:16 +00:00
res . send ( 'Host: ' + req . hostname + ' asked to activate OpenBuilds CONTROL v' + require ( './package' ) . version ) ;
2022-09-22 17:27:29 +00:00
showJogWindow ( )
2018-08-08 17:56:11 +00:00
setTimeout ( function ( ) {
2018-08-09 12:20:42 +00:00
io . sockets . emit ( 'activate' , req . hostname ) ;
2022-07-06 20:08:38 +00:00
} , 500 ) ;
2018-08-08 17:56:11 +00:00
} )
2018-07-03 20:28:02 +00:00
// Upload
2018-06-27 14:08:24 +00:00
app . get ( '/upload' , ( req , res ) => {
2018-06-29 19:48:34 +00:00
res . header ( "Access-Control-Allow-Origin" , "*" ) ;
res . header ( "Access-Control-Allow-Headers" , "Origin, X-Requested-With, Content-Type, Accept" ) ;
2018-06-27 14:08:24 +00:00
res . sendFile ( _ _dirname + '/app/upload.html' ) ;
} )
2018-08-29 08:11:14 +00:00
app . get ( '/gcode' , ( req , res ) => {
2019-01-18 19:01:53 +00:00
if ( uploadedgcode . indexOf ( '$' ) != 0 ) { // Ignore grblSettings jobs
res . header ( "Access-Control-Allow-Origin" , "*" ) ;
res . header ( "Access-Control-Allow-Headers" , "Origin, X-Requested-With, Content-Type, Accept" ) ;
res . send ( uploadedgcode ) ;
}
2019-04-29 17:26:29 +00:00
} )
2019-01-18 19:01:53 +00:00
2019-04-29 17:26:29 +00:00
app . get ( '/workspace' , ( req , res ) => {
res . header ( "Access-Control-Allow-Origin" , "*" ) ;
res . header ( "Access-Control-Allow-Headers" , "Origin, X-Requested-With, Content-Type, Accept" ) ;
res . send ( uploadedworkspace ) ;
2018-08-29 08:11:14 +00:00
} )
2021-01-05 21:23:40 +00:00
// http-post version of runJob
app . post ( '/runjob' , ( req , res ) => {
// 'firmwareBin' is the name of our file input field in the HTML form
let upload = multer ( {
storage : storage
} ) . single ( 'file' ) ;
upload ( req , res , function ( err ) {
// req.file contains information of uploaded file
// req.body contains information of text fields, if there were any
if ( err instanceof multer . MulterError ) {
return res . send ( err ) ;
} else if ( err ) {
return res . send ( err ) ;
}
fs . readFile ( req . file . path , 'utf8' , function ( err , data ) {
if ( err ) {
return console . log ( err ) ;
}
var object = {
isJob : true ,
//completedMsg: "",
data : data ,
}
runJob ( object )
} ) ;
res . send ( ` Running ` + req . file . path ) ;
} ) ;
} ) ;
2018-06-27 14:08:24 +00:00
// File Post
app . post ( '/upload' , function ( req , res ) {
2018-06-29 19:48:34 +00:00
res . header ( "Access-Control-Allow-Origin" , "*" ) ;
res . header ( "Access-Control-Allow-Headers" , "Origin, X-Requested-With, Content-Type, Accept" ) ;
2020-03-06 15:59:58 +00:00
//debug_log(req)
2018-06-27 14:08:24 +00:00
uploadprogress = 0
var form = new formidable . IncomingForm ( ) ;
2021-01-20 16:23:46 +00:00
form . maxFileSize = 300 * 1024 * 1024 ;
2019-05-21 12:09:53 +00:00
form . parse ( req , function ( err , fields , files ) {
2020-03-06 15:59:58 +00:00
// debug_log(files);
2019-05-21 12:09:53 +00:00
} ) ;
2018-06-27 14:08:24 +00:00
2018-07-11 09:02:41 +00:00
form . on ( 'fileBegin' , function ( name , file ) {
2023-02-23 13:24:27 +00:00
debug _log ( JSON . stringify ( name ) ) ;
debug _log ( JSON . stringify ( file ) ) ;
debug _log ( 'Uploading ' + file . filepath ) ;
2018-07-11 09:02:41 +00:00
} ) ;
2018-06-27 14:08:24 +00:00
form . on ( 'progress' , function ( bytesReceived , bytesExpected ) {
uploadprogress = parseInt ( ( ( bytesReceived * 100 ) / bytesExpected ) . toFixed ( 0 ) ) ;
if ( uploadprogress != lastsentuploadprogress ) {
lastsentuploadprogress = uploadprogress ;
}
2021-01-20 16:23:46 +00:00
debug _log ( 'Progress ' + uploadprogress + "% / " + bytesReceived + "b" ) ;
2018-06-27 14:08:24 +00:00
} ) ;
form . on ( 'file' , function ( name , file ) {
2023-02-23 13:24:27 +00:00
debug _log ( 'Uploaded ' + file . filepath ) ;
2022-11-10 21:06:34 +00:00
showJogWindow ( )
2023-02-23 13:24:27 +00:00
readFile ( file . filepath )
2018-06-27 14:08:24 +00:00
} ) ;
form . on ( 'aborted' , function ( ) {
// Emitted when the request was aborted by the user. Right now this can be due to a 'timeout' or 'close' event on the socket. After this event is emitted, an error event will follow. In the future there will be a separate 'timeout' event (needs a change in the node core).
} ) ;
form . on ( 'end' , function ( ) {
//Emitted when the entire request has been received, and all contained files have finished flushing to disk. This is a great place for you to send your response.
2021-01-20 16:23:46 +00:00
res . end ( ) ;
2018-06-27 14:08:24 +00:00
} ) ;
res . sendFile ( _ _dirname + '/app/upload.html' ) ;
} ) ;
2018-06-19 08:07:03 +00:00
app . on ( 'certificate-error' , function ( event , webContents , url , error ,
certificate , callback ) {
event . preventDefault ( ) ;
callback ( true ) ;
} ) ;
io . on ( "connection" , function ( socket ) {
2023-02-03 16:47:44 +00:00
debug _log ( "New IO Connection " ) ;
2018-06-19 08:07:03 +00:00
2023-02-03 16:47:44 +00:00
iosocket = socket ;
2020-03-20 12:32:01 +00:00
2018-06-21 20:02:40 +00:00
if ( status . machine . firmware . type == 'grbl' ) {
2019-02-11 19:29:44 +00:00
2023-02-03 16:47:44 +00:00
debug _log ( "Is Grbl" ) ;
// // handle Grbl RESET external input
// if (status.machine.inputs.length > 0) {
// for (i = 0; i < status.machine.inputs.length; i++) {
// switch (status.machine.inputs[i]) {
// case 'R':
// // debug_log('PIN: SOFTRESET');
// safetosend = true;
// break;
// }
// }
// } else {
// setTimeout(function() {
debug _log ( "Emit Grbl: 1" ) ;
io . sockets . emit ( 'grbl' , status . machine . firmware )
// }, 10000);
// }
//
// if (safetosend != undefined && safetosend == true) {
// setTimeout(function() {
// debug_log("Emit Grbl: 2");
// io.sockets.emit('grbl', status.machine.firmware)
// }, 10000);
// }
2018-06-21 20:02:40 +00:00
}
2022-05-02 19:22:15 +00:00
// Global Update loop
clearInterval ( frontEndUpdateLoop ) ;
frontEndUpdateLoop = setInterval ( function ( ) {
2018-06-19 08:07:03 +00:00
io . sockets . emit ( "status" , status ) ;
2022-05-02 18:04:33 +00:00
} , 100 ) ;
2018-06-19 08:07:03 +00:00
2022-07-06 20:08:38 +00:00
socket . on ( "scannetwork" , function ( data ) {
2022-11-01 20:21:24 +00:00
scanForTelnetDevices ( data )
2022-07-06 20:08:38 +00:00
} )
2022-11-22 16:29:24 +00:00
socket . on ( "openFile" , function ( data ) {
dialog . showOpenDialog ( jogWindow , {
properties : [ 'openFile' ]
} ) . then ( result => {
console . log ( result . canceled )
console . log ( result . filePaths )
var openFilePath = result . filePaths [ 0 ] ;
if ( openFilePath !== "" ) {
debug _log ( "path" + openFilePath ) ;
readFile ( openFilePath ) ;
}
} ) . catch ( err => {
console . log ( err )
} )
} )
2023-02-16 17:05:26 +00:00
socket . on ( "openInterfaceDir" , function ( data ) {
dialog . showOpenDialog ( jogWindow , {
properties : [ 'openDirectory' ] ,
title : "Select the USB Flashdrive you want to use with Interface"
} ) . then ( result => {
console . log ( result . canceled )
console . log ( result . filePaths )
io . sockets . emit ( "interfaceDrive" , result . filePaths [ 0 ] ) ;
status . interface . diskdrive = result . filePaths [ 0 ]
} ) . catch ( err => {
console . log ( err )
} )
} )
2019-01-23 19:07:58 +00:00
socket . on ( "openbuilds" , function ( data ) {
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://www.openbuilds.com' )
} ) ;
2023-02-28 18:40:11 +00:00
socket . on ( "openbuildspartstore" , function ( data ) {
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://www.openbuildspartstore.com' )
} ) ;
2021-03-12 19:19:47 +00:00
socket . on ( "carveco" , function ( data ) {
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://carveco.com/carveco-software-range/?ref=openbuilds' )
} ) ;
socket . on ( "fabber" , function ( data ) {
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://www.getfabber.com/openbuilds?ref=OpenBuilds' )
} ) ;
socket . on ( "lightburn" , function ( data ) {
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://openbuildspartstore.com/lightburn/' )
} ) ;
socket . on ( "vectric" , function ( data ) {
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://openbuildspartstore.com/vectric/' )
} ) ;
2018-07-26 20:22:07 +00:00
socket . on ( "opencam" , function ( data ) {
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://cam.openbuilds.com' )
} ) ;
2021-03-16 19:46:51 +00:00
socket . on ( "opendocs" , function ( data ) {
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://docs.openbuilds.com/' )
} ) ;
2019-03-06 19:26:09 +00:00
socket . on ( "openforum" , function ( data ) {
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://openbuilds.com/threads/openbuilds-control-software.13121/' )
} ) ;
2022-12-20 18:50:36 +00:00
socket . on ( "gpuinfo" , function ( data ) {
// GPU
var gpuInfoWindow = new BrowserWindow ( {
// 1366 * 768 == minimum to cater for
width : 800 ,
height : 800 ,
fullscreen : false ,
center : true ,
resizable : true ,
maximizable : true ,
title : "OpenBuilds CONTROL: Chromium's GPU Report" ,
frame : true ,
autoHideMenuBar : true ,
//icon: '/app/favicon.png',
icon : nativeImage . createFromPath (
path . join ( _ _dirname , "/app/favicon.png" )
) ,
webgl : true ,
experimentalFeatures : true ,
experimentalCanvasFeatures : true ,
offscreen : true ,
backgroundColor : "#fff"
} ) ;
gpuInfoWindow . loadURL ( "chrome://gpu" ) ;
gpuInfoWindow . once ( 'ready-to-show' , ( ) => {
gpuInfoWindow . show ( )
gpuInfoWindow . setAlwaysOnTop ( true ) ;
gpuInfoWindow . focus ( ) ;
gpuInfoWindow . setAlwaysOnTop ( false ) ;
} )
} ) ;
2018-08-07 10:05:49 +00:00
socket . on ( "minimisetotray" , function ( data ) {
2018-06-20 13:00:05 +00:00
jogWindow . hide ( ) ;
} ) ;
2018-08-07 10:05:49 +00:00
socket . on ( "minimize" , function ( data ) {
jogWindow . minimize ( ) ;
} ) ;
2020-04-17 21:07:39 +00:00
socket . on ( "maximize" , function ( data ) {
2022-11-10 21:06:34 +00:00
if ( jogWindow . isFullScreen ( ) ) {
jogWindow . setFullScreen ( false ) ;
}
2021-03-16 19:46:51 +00:00
if ( jogWindow . isMaximized ( ) ) {
2021-03-19 18:24:53 +00:00
jogWindow . unmaximize ( ) ;
2021-03-16 19:46:51 +00:00
} else {
jogWindow . maximize ( ) ;
}
2020-04-17 21:07:39 +00:00
} ) ;
2018-08-07 10:05:49 +00:00
2022-11-10 21:06:34 +00:00
socket . on ( "fullscreen" , function ( data ) {
if ( jogWindow . isFullScreen ( ) ) {
jogWindow . setFullScreen ( false ) ;
} else {
jogWindow . setFullScreen ( true ) ;
}
} ) ;
2018-06-20 13:00:05 +00:00
socket . on ( "quit" , function ( data ) {
2019-01-16 10:18:46 +00:00
if ( appIcon ) {
appIcon . destroy ( ) ;
}
2018-06-20 13:00:05 +00:00
electronApp . exit ( 0 ) ;
} ) ;
2018-07-11 12:39:24 +00:00
socket . on ( "applyUpdate" , function ( data ) {
autoUpdater . quitAndInstall ( ) ;
} )
2018-08-10 19:42:30 +00:00
socket . on ( "downloadUpdate" , function ( data ) {
2018-12-27 13:16:39 +00:00
if ( ! updateIsDownloading ) {
if ( typeof autoUpdater !== 'undefined' ) {
autoUpdater . checkForUpdates ( ) ;
} else {
2020-03-06 15:59:58 +00:00
debug _log ( "autoUpdater not found" )
2018-12-27 13:16:39 +00:00
}
2018-08-28 15:09:20 +00:00
}
2018-07-12 13:06:53 +00:00
} )
2018-12-20 19:22:02 +00:00
socket . on ( "flashGrbl" , function ( data ) {
var port = data . port ;
2022-07-06 20:08:38 +00:00
var firmwareImagePath = data . file ;
2019-03-07 14:38:40 +00:00
var board = data . board
2020-11-20 18:29:52 +00:00
var customImg = data . customImg
2022-08-23 14:19:10 +00:00
console . log ( _ _dirname , file , data . file )
2020-11-20 18:29:52 +00:00
if ( customImg ) {
2022-11-10 21:06:34 +00:00
var firmwarePath = data . file
2020-11-20 18:29:52 +00:00
} else {
2022-08-23 14:19:10 +00:00
var firmwarePath = path . join ( _ _dirname , data . file )
2020-11-20 18:29:52 +00:00
}
2022-11-10 21:06:34 +00:00
console . log ( "-------------------------------------------" )
console . log ( firmwarePath )
console . log ( "-------------------------------------------" )
2018-12-20 19:22:02 +00:00
if ( status . comms . connectionStatus > 0 ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'WARN: Closing Port ' + port ) ;
2018-12-20 19:22:02 +00:00
stopPort ( ) ;
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-12-20 19:22:02 +00:00
}
function flashGrblCallback ( debugString , port ) {
2020-03-06 15:59:58 +00:00
debug _log ( port , debugString ) ;
2018-12-20 19:22:02 +00:00
var data = {
'port' : port ,
'string' : debugString
}
io . sockets . emit ( "progStatus" , data ) ;
}
2024-04-09 07:56:30 +00:00
// setTimeout(function() {
// var avrgirl = new Avrgirl({
// board: board,
// port: port,
// debug: function(debugString) {
// var port = this.connection.options.port;
// flashGrblCallback(debugString, port)
// }
// });
//
// debug_log(JSON.stringify(avrgirl));
//
// status.comms.connectionStatus = 6;
// avrgirl.flash(firmwarePath, function(error) {
// if (error) {
// console.error(error);
// io.sockets.emit("progStatus", 'Flashing FAILED!');
// status.comms.connectionStatus = 0;
// } else {
// console.info('done.');
// io.sockets.emit("progStatus", 'Programmed Succesfully');
// io.sockets.emit("progStatus", 'Please Reconnect');
// status.comms.connectionStatus = 0;
// }
// status.comms.connectionStatus = 0;
// });
// }, 1000)
2018-12-20 19:22:02 +00:00
} )
2022-07-06 20:08:38 +00:00
socket . on ( "flashGrblHal" , function ( data ) {
if ( status . comms . connectionStatus > 0 ) {
debug _log ( 'WARN: Closing Port ' + port ) ;
stopPort ( ) ;
} else {
debug _log ( 'ERROR: Machine connection not open!' ) ;
}
console . log ( JSON . stringify ( data ) , null , 4 ) ;
flashGrblHal ( data )
} )
2020-11-20 15:50:37 +00:00
socket . on ( "flashInterface" , function ( data ) {
if ( status . comms . connectionStatus > 0 ) {
debug _log ( 'WARN: Closing Port ' + port ) ;
stopPort ( ) ;
} else {
debug _log ( 'ERROR: Machine connection not open!' ) ;
}
flashInterface ( data )
} )
2020-11-24 16:30:37 +00:00
socket . on ( "writeInterfaceUsbDrive" , function ( data ) {
2022-11-01 20:21:24 +00:00
2023-02-16 17:05:26 +00:00
debug _log ( data )
2022-11-01 20:21:24 +00:00
//data.drive = mountpoint dest
//data.controller = type of controller
if ( data . controller == "blackbox4x" || data . controller == "genericgrbl" ) {
var probesrc = path . join ( _ _dirname , './app/wizards/interface/PROBE/' ) ;
var profilesrc = path . join ( _ _dirname , './app/wizards/interface/PROFILESGRBL/' ) ;
} else if ( data . controller == "blackboxx32" || data . controller == "genericgrblhal" ) {
var probesrc = path . join ( _ _dirname , './app/wizards/interface/PROBE/' ) ;
var profilesrc = path . join ( _ _dirname , './app/wizards/interface/PROFILESHAL/' ) ;
}
var probedest = path . join ( data . drive , "/PROBE/" ) ;
var profiledest = path . join ( data . drive , "/PROFILES/" ) ;
2020-11-24 16:30:37 +00:00
var ncp = require ( 'ncp' ) . ncp ;
ncp . limit = 16 ;
var output = {
'command' : 'Interface USB Drive' ,
2022-11-01 20:21:24 +00:00
'response' : "Starting to copy data to " + data . drive ,
2020-12-16 08:20:46 +00:00
'type' : 'info'
2020-11-24 16:30:37 +00:00
}
io . sockets . emit ( 'data' , output ) ;
var errorCount = 0 ;
2024-04-18 13:18:21 +00:00
if ( data . ssid && data . psk ) {
const folderPath = path . join ( data . drive , "CONFIG" ) ;
// Create the subfolder if it doesn't exist and then write the file
fs . mkdir ( folderPath , {
recursive : true
} , ( err ) => {
if ( err ) {
var output = {
'command' : 'Interface USB Drive' ,
'response' : ` Failed to create folder ${ folderPath } ! Error: ${ err } ` ,
'type' : 'error'
} ;
io . sockets . emit ( 'data' , output ) ;
} else {
var fileContent = ` ${ data . ssid } \n ${ data . psk } ` ;
fs . writeFile ( path . join ( folderPath , "wifi.cfg" ) , fileContent , ( err ) => {
if ( err ) {
errorCount ++ ;
var output = {
'command' : 'Interface USB Drive' ,
'response' : ` Failed to create Wifi Configuration file in ${ folderPath } ! Error: ${ err } ` ,
'type' : 'error'
} ;
io . sockets . emit ( 'data' , output ) ;
} else {
var output = {
'command' : 'Interface USB Drive' ,
'response' : ` Created Wifi Configuration file in ${ folderPath } successfully! ` ,
'type' : 'success'
} ;
io . sockets . emit ( 'data' , output ) ;
}
} ) ;
}
} ) ;
}
2024-04-17 18:31:08 +00:00
ncp ( probesrc , probedest , function ( err ) {
if ( err ) {
var output = {
'command' : 'Interface USB Drive' ,
'response' : "Failed to copy PROBE macros to " + probedest + ": " + JSON . stringify ( err ) ,
'type' : 'error'
}
io . sockets . emit ( 'data' , output ) ;
errorCount ++
} else {
var output = {
'command' : 'Interface USB Drive' ,
'response' : "Copied PROBE macros to " + probedest + " succesfully!" ,
'type' : 'success'
}
io . sockets . emit ( 'data' , output ) ;
}
} ) ;
2020-11-24 16:30:37 +00:00
2022-11-01 20:21:24 +00:00
2024-04-17 18:31:08 +00:00
ncp ( profilesrc , profiledest , function ( err ) {
if ( err ) {
var output = {
'command' : 'Interface USB Drive' ,
'response' : "Failed to copy MACHINE PROFILES to " + profiledest + ": " + JSON . stringify ( err ) ,
'type' : 'error'
2020-11-24 16:30:37 +00:00
}
2024-04-17 18:31:08 +00:00
io . sockets . emit ( 'data' , output ) ;
errorCount ++
} else {
var output = {
'command' : 'Interface USB Drive' ,
'response' : "Copied MACHINE PROFILES to " + profiledest + " succesfully!" ,
'type' : 'success'
}
io . sockets . emit ( 'data' , output ) ;
}
} ) ;
2020-11-20 15:50:37 +00:00
2020-12-30 19:28:28 +00:00
2020-11-24 16:30:37 +00:00
setTimeout ( function ( ) {
if ( errorCount == 0 ) {
var output = {
'command' : 'Interface USB Drive' ,
2022-11-01 20:21:24 +00:00
'response' : "Finished copying supporting files to Drive " + data . drive ,
2020-12-16 08:20:46 +00:00
'type' : 'success'
2020-11-24 16:30:37 +00:00
}
io . sockets . emit ( 'data' , output ) ;
var output = {
'command' : 'Interface USB Drive' ,
2020-12-16 08:20:46 +00:00
'response' : "Please Eject the drive (Safely Remove) and insert it into your Interface's USB port" ,
'type' : 'info'
2020-11-24 16:30:37 +00:00
}
io . sockets . emit ( 'data' , output ) ;
}
2022-07-06 20:08:38 +00:00
} , 500 ) ;
2020-11-24 16:30:37 +00:00
} ) ;
2018-12-20 19:22:02 +00:00
2018-06-19 08:07:03 +00:00
socket . on ( "connectTo" , function ( data ) { // If a user picks a port to connect to, open a Node SerialPort Instance to it
if ( status . comms . connectionStatus < 1 ) {
2024-04-25 20:12:14 +00:00
2022-07-06 20:08:38 +00:00
if ( data . type == "usb" ) {
console . log ( "connect" , "Connecting to " + data . port + " via " + data . type ) ;
2024-04-25 20:12:14 +00:00
// Fix for autoreset getting stuck on MacOS with Silabs Chip
var allowRtsCts = false
var allowHupcl = false
if ( process . platform == 'darwin' ) {
allowRtsCts = true
allowHupcl = true
}
2022-09-23 06:50:53 +00:00
port = new SerialPort ( {
path : data . port ,
2022-07-06 20:08:38 +00:00
baudRate : parseInt ( data . baud ) ,
2024-04-25 20:12:14 +00:00
rtscts : allowRtsCts ,
hupcl : allowHupcl // Don't set DTR - useful for X32 Reset
2022-07-06 20:08:38 +00:00
} ) ;
} else if ( data . type == "telnet" ) {
console . log ( "connect" , "Connecting to " + data . ip + " via " + data . type ) ;
port = net . connect ( 23 , data . ip ) ;
port . isOpen = true ;
}
2024-04-08 21:09:34 +00:00
const parser = port . pipe ( new ReadlineParser ( {
2019-04-15 17:31:30 +00:00
delimiter : '\r\n'
2024-04-08 21:09:34 +00:00
} ) )
2019-04-15 17:31:30 +00:00
2020-03-19 15:13:52 +00:00
// port.on("data", function(data) {
// console.log(data)
// })
2018-06-19 08:07:03 +00:00
port . on ( "error" , function ( err ) {
2018-12-20 19:22:02 +00:00
if ( err . message != "Port is not open" ) {
2020-03-06 15:59:58 +00:00
debug _log ( "Error: " , err . message ) ;
2018-12-20 19:22:02 +00:00
var output = {
'command' : '' ,
2020-12-16 08:20:46 +00:00
'response' : "PORT ERROR: " + err . message ,
'type' : 'error'
2018-12-20 19:22:02 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2019-02-11 19:29:44 +00:00
2018-12-20 19:22:02 +00:00
if ( status . comms . connectionStatus > 0 ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'WARN: Closing Port ' + port . path ) ;
2019-04-12 15:44:02 +00:00
status . comms . connectionStatus = 0 ;
2018-12-20 19:22:02 +00:00
stopPort ( ) ;
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-12-20 19:22:02 +00:00
}
2018-07-24 12:58:26 +00:00
}
2018-12-20 19:22:02 +00:00
2018-06-19 08:07:03 +00:00
} ) ;
2020-03-19 15:13:52 +00:00
2022-07-06 20:08:38 +00:00
port . on ( "ready" , function ( e ) {
portOpened ( port , data )
} ) ;
port . on ( "open" , function ( e ) {
portOpened ( port , data )
} ) ;
port . on ( "close" , function ( ) { // open errors will be emitted as an error event
debug _log ( "PORT INFO: Port closed" ) ;
var output = {
'command' : 'disconnect' ,
'response' : "PORT INFO: Port closed" ,
'type' : 'info'
}
io . sockets . emit ( 'data' , output ) ;
status . comms . connectionStatus = 0 ;
} ) ; // end port.onclose
function portOpened ( port , data ) {
2020-03-06 15:59:58 +00:00
debug _log ( "PORT INFO: Connected to " + port . path + " at " + port . baudRate ) ;
2018-07-11 18:58:38 +00:00
var output = {
2018-10-10 18:50:55 +00:00
'command' : 'connect' ,
2024-04-09 12:15:44 +00:00
'response' : "PORT INFO: Port is now open: " + port . path + " - Attempting to detect Controller..." ,
2020-12-16 08:20:46 +00:00
'type' : 'info'
2018-07-11 18:58:38 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2018-10-10 18:50:55 +00:00
2018-06-19 08:07:03 +00:00
status . comms . connectionStatus = 1 ;
2018-10-10 18:50:55 +00:00
2022-05-02 18:04:33 +00:00
addQRealtime ( "\n" ) ; // this causes smoothie and grblHAL to send the welcome string
2018-10-10 18:50:55 +00:00
var output = {
'command' : 'connect' ,
2024-04-09 12:15:44 +00:00
'response' : "Attempting to detect Controller (1): (Autoreset)" ,
2020-12-16 08:20:46 +00:00
'type' : 'info'
2018-06-19 08:07:03 +00:00
}
2018-10-10 18:50:55 +00:00
io . sockets . emit ( 'data' , output ) ;
2018-10-10 18:36:56 +00:00
setTimeout ( function ( ) { //wait for controller to be ready
if ( status . machine . firmware . type . length < 1 ) {
2020-03-06 15:59:58 +00:00
debug _log ( "Didnt detect firmware after AutoReset. Lets see if we have Grbl instance with a board that doesnt have AutoReset" ) ;
2018-10-10 18:50:55 +00:00
var output = {
'command' : 'connect' ,
2024-04-09 12:15:44 +00:00
'response' : "Attempting to detect Controller (2): (Ctrl+X)" ,
2020-12-16 08:20:46 +00:00
'type' : 'info'
2018-10-10 18:50:55 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2018-10-10 18:36:56 +00:00
addQRealtime ( String . fromCharCode ( 0x18 ) ) ; // ctrl-x (needed for rx/tx connection)
2020-03-06 15:59:58 +00:00
debug _log ( "Sent: Ctrl+x" ) ;
2018-10-10 18:36:56 +00:00
}
} , config . grblWaitTime * 1000 ) ;
2018-06-19 08:07:03 +00:00
setTimeout ( function ( ) { //wait for controller to be ready
if ( status . machine . firmware . type . length < 1 ) {
2020-03-06 15:59:58 +00:00
debug _log ( "No firmware yet, probably not Grbl then. lets see if we have Smoothie?" ) ;
2018-10-10 18:50:55 +00:00
var output = {
'command' : 'connect' ,
2024-04-09 12:15:44 +00:00
'response' : "Attempting to detect Controller (3): (others)" ,
2020-12-16 08:20:46 +00:00
'type' : 'info'
2018-10-10 18:50:55 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2018-08-09 16:34:51 +00:00
addQRealtime ( "version\n" ) ; // Check if it's Smoothieware?
2020-03-06 15:59:58 +00:00
debug _log ( "Sent: version" ) ;
2018-06-19 08:07:03 +00:00
}
2018-10-10 18:36:56 +00:00
} , config . grblWaitTime * 2000 ) ;
2022-05-02 18:04:33 +00:00
setTimeout ( function ( ) {
2024-04-25 17:06:17 +00:00
2024-04-25 17:51:09 +00:00
if ( status . machine . firmware . type . length > 1 ) {
if ( status . machine . firmware . type === "grbl" ) {
2022-05-02 18:04:33 +00:00
debug _log ( "GRBL detected" ) ;
var output = {
'command' : 'connect' ,
'response' : "Detecting Firmware: Detected Grbl Succesfully" ,
'type' : 'info'
}
2024-04-25 17:06:17 +00:00
2022-05-02 18:04:33 +00:00
setTimeout ( function ( ) {
2022-12-20 18:50:36 +00:00
io . sockets . emit ( 'grbl' , status . machine . firmware )
2022-05-02 18:04:33 +00:00
//v1.0.318 - commented out as a test - too many normal alarms clear prematurely
//io.sockets.emit('errorsCleared', true);
} , 600 )
// Start interval for status queries
clearInterval ( statusLoop ) ;
statusLoop = setInterval ( function ( ) {
if ( status . comms . connectionStatus > 0 ) {
addQRealtime ( "?" ) ;
}
} , 200 ) ;
status . machine . modals . homedRecently = false ;
}
}
} , config . grblWaitTime * 3000 )
2018-06-19 08:07:03 +00:00
if ( config . firmwareWaitTime > 0 ) {
setTimeout ( function ( ) {
// Close port if we don't detect supported firmware after 2s.
if ( status . machine . firmware . type . length < 1 ) {
2020-03-06 15:59:58 +00:00
debug _log ( "No supported firmware detected. Closing port " + port . path ) ;
2020-12-16 08:20:46 +00:00
if ( status . interface . connected ) {
var output = {
'command' : 'connect' ,
'response' : ` ERROR!: Connection established to INTERFACE, but no response from Grbl on the upstream controller. See https://docs.openbuilds.com/interface for more details. Closing port ` + port . path ,
'type' : 'error'
}
} else {
var output = {
'command' : 'connect' ,
2024-04-09 12:15:44 +00:00
'response' : ` ERROR!: No Response from Controller - See https://docs.openbuilds.com/doku.php?id=docs:blackbox:faq-usb-connection-failed for troubleshooting information. Closing port ` + port . path ,
2020-12-16 08:20:46 +00:00
'type' : 'error'
}
2018-10-10 18:50:55 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2018-06-19 08:07:03 +00:00
stopPort ( ) ;
2018-10-10 18:50:55 +00:00
} else {
2022-07-06 20:08:38 +00:00
if ( data . type == "usb" ) {
var output = {
'command' : 'connect' ,
2024-04-09 20:47:04 +00:00
'response' : "Firmware Detected: " + status . machine . firmware . platform + " version " + status . machine . firmware . version + " dated " + status . machine . firmware . date + " on " + port . path ,
2022-07-06 20:08:38 +00:00
'type' : 'success'
}
} else if ( data . type = "telnet" ) {
var output = {
'command' : 'connect' ,
2024-04-09 20:47:04 +00:00
'response' : "Firmware Detected: " + status . machine . firmware . platform + " version " + status . machine . firmware . version + " dated " + status . machine . firmware . date + " on " + data . ip ,
2022-07-06 20:08:38 +00:00
'type' : 'success'
}
2018-10-10 18:50:55 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2018-06-19 08:07:03 +00:00
}
} , config . firmwareWaitTime * 1000 ) ;
}
2018-10-10 18:50:55 +00:00
2018-06-19 08:07:03 +00:00
status . comms . connectionStatus = 2 ;
2022-07-06 20:08:38 +00:00
if ( data . type == "usb" ) {
status . comms . interfaces . activePort = port . path ;
status . comms . interfaces . type = data . type
status . comms . interfaces . activeBaud = port . baudRate ;
} else if ( data . type = "telnet" ) {
status . comms . interfaces . activePort = data . ip ;
status . comms . interfaces . type = data . type
status . comms . interfaces . activeBaud = "net" ;
2018-07-11 18:58:38 +00:00
}
2022-07-06 20:08:38 +00:00
}
2018-06-19 08:07:03 +00:00
2019-04-15 17:31:30 +00:00
parser . on ( "data" , function ( data ) {
2020-12-17 18:27:05 +00:00
//console.log(data)
2018-08-09 16:34:51 +00:00
var command = sentBuffer [ 0 ] ;
2018-06-19 08:07:03 +00:00
2022-12-20 18:50:36 +00:00
if ( command == "$CD" && data != "ok" ) {
fluidncConfig = fluidncConfig += data + "\n"
}
2021-12-01 19:34:45 +00:00
2019-12-30 19:56:20 +00:00
if ( data . indexOf ( "<" ) != 0 ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'data:' , data )
2019-12-30 19:56:20 +00:00
}
2019-01-29 21:29:13 +00:00
2018-12-21 13:56:11 +00:00
// Grbl $I parser
if ( data . indexOf ( "[VER:" ) === 0 ) {
status . machine . name = data . split ( ':' ) [ 2 ] . split ( ']' ) [ 0 ] . toLowerCase ( )
io . sockets . emit ( "status" , status ) ;
2019-01-23 19:07:58 +00:00
io . sockets . emit ( "machinename" , data . split ( ':' ) [ 2 ] . split ( ']' ) [ 0 ] . toLowerCase ( ) ) ;
2023-02-03 16:47:44 +00:00
status . machine . firmware . date = data . split ( ':' ) [ 1 ] . split ( "." ) [ 2 ] ;
2018-12-21 13:56:11 +00:00
}
2019-07-23 19:04:50 +00:00
if ( data . indexOf ( "[OPT:" ) === 0 ) {
var startOpt = data . search ( /opt:/i ) + 4 ;
var grblOpt ;
if ( startOpt > 4 ) {
var grblOptLen = data . substr ( startOpt ) . search ( /]/ ) ;
grblOpts = data . substr ( startOpt , grblOptLen ) . split ( /,/ ) ;
status . machine . firmware . blockBufferSize = grblOpts [ 1 ] ;
status . machine . firmware . rxBufferSize = grblOpts [ 2 ] ;
var features = [ ]
var i = grblOpts [ 0 ] . length ;
while ( i -- ) {
features . push ( grblOpts [ 0 ] . charAt ( i ) )
2019-08-23 17:10:54 +00:00
switch ( grblOpts [ 0 ] . charAt ( i ) ) {
2019-07-23 19:04:50 +00:00
case 'Q' :
2020-03-06 15:59:58 +00:00
debug _log ( 'SPINDLE_IS_SERVO Enabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'V' : // Variable spindle enabled
2020-03-06 15:59:58 +00:00
debug _log ( 'Variable spindle enabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'N' : // Line numbers enabled
2020-03-06 15:59:58 +00:00
debug _log ( 'Line numbers enabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'M' : // Mist coolant enabled
2020-03-06 15:59:58 +00:00
debug _log ( 'Mist coolant enabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'C' : // CoreXY enabled
2020-03-06 15:59:58 +00:00
debug _log ( 'CoreXY enabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'P' : // Parking motion enabled
2020-03-06 15:59:58 +00:00
debug _log ( 'Parking motion enabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'Z' : // Homing force origin enabled
2020-03-06 15:59:58 +00:00
debug _log ( 'Homing force origin enabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'H' : // Homing single axis enabled
2020-03-06 15:59:58 +00:00
debug _log ( 'Homing single axis enabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'T' : // Two limit switches on axis enabled
2020-03-06 15:59:58 +00:00
debug _log ( 'Two limit switches on axis enabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'A' : // Allow feed rate overrides in probe cycles
2020-03-06 15:59:58 +00:00
debug _log ( 'Allow feed rate overrides in probe cycles' )
2019-07-23 19:04:50 +00:00
//
break ;
case '$' : // Restore EEPROM $ settings disabled
2020-03-06 15:59:58 +00:00
debug _log ( 'Restore EEPROM $ settings disabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case '#' : // Restore EEPROM parameter data disabled
2020-03-06 15:59:58 +00:00
debug _log ( 'Restore EEPROM parameter data disabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'I' : // Build info write user string disabled
2020-03-06 15:59:58 +00:00
debug _log ( 'Build info write user string disabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'E' : // Force sync upon EEPROM write disabled
2020-03-06 15:59:58 +00:00
debug _log ( 'Force sync upon EEPROM write disabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'W' : // Force sync upon work coordinate offset change disabled
2020-03-06 15:59:58 +00:00
debug _log ( 'Force sync upon work coordinate offset change disabled' )
2019-07-23 19:04:50 +00:00
//
break ;
case 'L' : // Homing init lock sets Grbl into an alarm state upon power up
2020-03-06 15:59:58 +00:00
debug _log ( 'Homing init lock sets Grbl into an alarm state upon power up' )
2019-07-23 19:04:50 +00:00
//
break ;
}
}
status . machine . firmware . features = features ;
io . sockets . emit ( "features" , features ) ;
}
}
2018-12-28 21:28:44 +00:00
// [PRB:0.000,0.000,0.000:0]
2021-12-01 19:34:45 +00:00
//if (data.indexOf("[PRB:") === 0 && command != "$#" && command != undefined) {
2018-12-28 21:28:44 +00:00
if ( data . indexOf ( "[PRB:" ) === 0 ) {
2020-06-22 21:04:23 +00:00
debug _log ( data )
var prbLen = data . substr ( 5 ) . search ( /\]/ ) ;
var prbData = data . substr ( 5 , prbLen ) . split ( /,/ ) ;
var success = data . split ( ':' ) [ 2 ] . split ( ']' ) [ 0 ] ;
status . machine . probe . x = prbData [ 0 ] ;
status . machine . probe . y = prbData [ 1 ] ;
status . machine . probe . z = prbData [ 2 ] . split ( ':' ) [ 0 ] ;
status . machine . probe . state = success ;
if ( success > 0 ) {
var output = {
'command' : '[ PROBE ]' ,
'response' : "Probe Completed." ,
2020-12-16 08:20:46 +00:00
'type' : 'success'
2018-12-28 21:28:44 +00:00
}
2020-06-22 21:04:23 +00:00
io . sockets . emit ( 'data' , output ) ;
} else {
var output = {
'command' : '[ PROBE ]' ,
'response' : "Probe move ERROR - probe did not make contact within specified distance" ,
2020-12-16 08:20:46 +00:00
'type' : 'error'
2020-06-22 21:04:23 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2018-12-28 21:28:44 +00:00
}
2020-06-22 21:04:23 +00:00
io . sockets . emit ( 'prbResult' , status . machine . probe ) ;
2018-12-28 21:28:44 +00:00
} ;
2018-12-21 13:56:11 +00:00
2021-12-01 19:34:45 +00:00
if ( data . indexOf ( "[GC:" ) === 0 ) {
gotModals ( data )
}
2020-12-15 17:06:42 +00:00
if ( data . indexOf ( "[INTF:" ) === 0 ) {
var output = {
'command' : 'connect' ,
'response' : "Detected an OpenBuilds Interface on port " + port . path ,
2020-12-16 08:20:46 +00:00
'type' : 'success'
2020-12-15 17:06:42 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2020-12-16 08:20:46 +00:00
status . interface . connected = true ;
2020-12-15 17:06:42 +00:00
if ( data . split ( ":" ) [ 1 ] . indexOf ( "ver" ) == 0 ) {
var installedVersion = parseFloat ( data . split ( ":" ) [ 1 ] . split ( "]" ) [ 0 ] . split ( "-" ) [ 1 ] )
status . interface . firmware . installedVersion = installedVersion
var output = {
'command' : 'connect' ,
'response' : "OpenBuilds Interface Firmware Version: v" + installedVersion ,
2020-12-16 08:20:46 +00:00
'type' : 'info'
2020-12-15 17:06:42 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2020-12-16 08:20:46 +00:00
if ( installedVersion < status . interface . firmware . availVersion ) {
2020-12-15 17:06:42 +00:00
var output = {
'command' : 'connect' ,
'response' : "OpenBuilds Interface Firmware OUTDATED: v" + installedVersion + " can be upgraded to v" + status . interface . firmware . availVersion ,
2020-12-16 08:20:46 +00:00
'type' : 'error'
2020-12-15 17:06:42 +00:00
}
io . sockets . emit ( 'data' , output ) ;
io . sockets . emit ( 'interfaceOutdated' , status ) ;
}
}
io . sockets . emit ( "status" , status ) ;
}
2018-06-19 08:07:03 +00:00
// Machine Identification
2024-04-19 12:09:10 +00:00
if ( data . indexOf ( "Grbl" ) === 0 || data . indexOf ( "[FIRMWARE:grblHAL]" ) === 0 ) { // Check if it's Grbl
2020-03-06 15:59:58 +00:00
debug _log ( data )
2018-06-19 08:07:03 +00:00
status . comms . blocked = false ;
2022-04-21 12:26:03 +00:00
if ( data . indexOf ( "GrblHAL" ) === 0 ) {
status . machine . firmware . type = "grbl" ;
status . machine . firmware . platform = "grblHAL"
status . machine . firmware . version = data . substr ( 8 , 4 ) ; // get version
2024-04-19 12:09:10 +00:00
} else if ( data . indexOf ( "[FIRMWARE:grblHAL]" ) === 0 ) {
status . machine . firmware . type = "grbl" ;
status . machine . firmware . platform = "grblHAL"
// Parse version from seperate [VER:...] line not here for this response
2022-12-20 18:50:36 +00:00
} else if ( data . indexOf ( "FluidNC" ) != - 1 ) { // Grbl 3.6 [FluidNC v3.6.5 (wifi) '$' for help]
status . machine . firmware . type = "grbl" ;
status . machine . firmware . platform = "FluidNC"
status . machine . firmware . version = data . substr ( 19 , 5 ) ; // get version
2022-04-21 12:26:03 +00:00
} else {
status . machine . firmware . type = "grbl" ;
status . machine . firmware . platform = "gnea"
status . machine . firmware . version = data . substr ( 5 , 4 ) ; // get version
}
2018-07-24 15:25:35 +00:00
if ( parseFloat ( status . machine . firmware . version ) < 1.1 ) { // If version is too old
2019-02-11 19:29:44 +00:00
if ( status . machine . firmware . version . length < 3 ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'invalid version string, stay connected' )
2018-07-24 15:25:35 +00:00
} else {
2019-02-11 19:29:44 +00:00
if ( status . comms . connectionStatus > 0 ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'WARN: Closing Port ' + port . path + " / v" + parseFloat ( status . machine . firmware . version ) ) ;
2019-02-11 19:29:44 +00:00
// stopPort();
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2019-02-11 19:29:44 +00:00
}
var output = {
'command' : command ,
2020-12-16 08:20:46 +00:00
'response' : "Detected an unsupported version: Grbl " + status . machine . firmware . version + ". This is sadly outdated. Please upgrade to Grbl 1.1 or newer to use this software. Go to http://github.com/gnea/grbl" ,
'type' : 'error'
2019-02-11 19:29:44 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2018-07-24 15:25:35 +00:00
}
}
2018-06-19 08:07:03 +00:00
status . machine . firmware . date = "" ;
2022-05-02 18:04:33 +00:00
// debug_log("GRBL detected");
// setTimeout(function() {
2022-12-20 18:50:36 +00:00
// io.sockets.emit('grbl', status.machine.firmware)
2022-05-02 18:04:33 +00:00
// //v1.0.318 - commented out as a test - too many normal alarms clear prematurely
// //io.sockets.emit('errorsCleared', true);
// }, 600)
// // Start interval for status queries
// clearInterval(statusLoop);
// statusLoop = setInterval(function() {
// if (status.comms.connectionStatus > 0) {
// addQRealtime("?");
// }
// }, 200);
2022-05-02 19:22:15 +00:00
status . machine . modals . homedRecently = false ;
2018-06-19 08:07:03 +00:00
} else if ( data . indexOf ( "LPC176" ) >= 0 ) { // LPC1768 or LPC1769 should be Smoothieware
status . comms . blocked = false ;
2020-03-06 15:59:58 +00:00
debug _log ( "Smoothieware detected" ) ;
2018-06-19 08:07:03 +00:00
status . machine . firmware . type = "smoothie" ;
status . machine . firmware . version = data . substr ( data . search ( /version:/i ) + 9 ) . split ( /,/ ) ;
status . machine . firmware . date = new Date ( data . substr ( data . search ( /Build date:/i ) + 12 ) . split ( /,/ ) ) . toDateString ( ) ;
// Start interval for status queries
2019-07-17 13:29:39 +00:00
// statusLoop = setInterval(function() {
// if (status.comms.connectionStatus > 0) {
// addQRealtime("?");
// }
// }, 200);
var output = {
'command' : "FIRMWARE ERROR" ,
2020-12-16 08:20:46 +00:00
'response' : "Detected an unsupported version: Smoothieware " + status . machine . firmware . version + ". This software no longer support Smoothieware. \nLuckilly there is an alternative firmware you can install on your controller to make it work with this software. Check out Grbl-LPC at https://github.com/cprezzi/grbl-LPC - Grbl-LPC is a Grbl port for controllers using the NXP LPC176x chips, for example Smoothieboards" ,
'type' : 'error'
2019-07-17 13:29:39 +00:00
}
io . sockets . emit ( 'data' , output ) ;
stopPort ( ) ;
2018-06-19 08:07:03 +00:00
} // end of machine identification
2019-07-23 19:04:50 +00:00
// Machine Feedback: Position
2018-08-09 16:34:51 +00:00
if ( data . indexOf ( "<" ) === 0 ) {
2020-03-06 15:59:58 +00:00
// debug_log(' Got statusReport (Grbl & Smoothieware)')
2018-06-19 08:07:03 +00:00
// statusfeedback func
parseFeedback ( data )
2021-02-01 15:59:05 +00:00
if ( command == "?" ) {
var output = {
'command' : command ,
'response' : data ,
'type' : 'info'
}
// debug_log(output.response)
io . sockets . emit ( 'data' , output ) ;
}
2020-03-06 15:59:58 +00:00
// debug_log(data)
2018-06-19 08:07:03 +00:00
} else if ( data . indexOf ( "ok" ) === 0 ) { // Got an OK so we are clear to send
2024-04-09 14:59:13 +00:00
io . sockets . emit ( 'ok' , command ) ; // added per #325
2020-03-06 15:59:58 +00:00
// debug_log("OK FOUND")
2018-06-19 08:07:03 +00:00
if ( status . machine . firmware . type === "grbl" ) {
2020-03-06 15:59:58 +00:00
// debug_log('got OK from ' + command)
2018-08-09 16:34:51 +00:00
command = sentBuffer . shift ( ) ;
2018-06-19 08:07:03 +00:00
}
2022-12-20 18:50:36 +00:00
if ( command == "$CD" ) {
io . sockets . emit ( 'fluidncConfig' , fluidncConfig ) ;
}
2018-06-19 08:07:03 +00:00
status . comms . blocked = false ;
send1Q ( ) ;
} else if ( data . indexOf ( 'ALARM' ) === 0 ) { //} || data.indexOf('HALTED') === 0) {
2020-03-06 15:59:58 +00:00
debug _log ( "ALARM: " + data )
2018-06-19 08:07:03 +00:00
status . comms . connectionStatus = 5 ;
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-08-09 16:34:51 +00:00
// sentBuffer.shift();
2018-06-19 08:07:03 +00:00
var alarmCode = parseInt ( data . split ( ':' ) [ 1 ] ) ;
2020-03-06 15:59:58 +00:00
debug _log ( 'ALARM: ' + alarmCode + ' - ' + grblStrings . alarms ( alarmCode ) ) ;
2018-06-19 08:07:03 +00:00
status . comms . alarm = alarmCode + ' - ' + grblStrings . alarms ( alarmCode )
2018-12-28 21:28:44 +00:00
if ( alarmCode != 5 ) {
2019-04-22 14:52:10 +00:00
io . sockets . emit ( "toastErrorAlarm" , 'ALARM: ' + alarmCode + ' - ' + grblStrings . alarms ( alarmCode ) + " [ " + command + " ]" )
2018-12-28 21:28:44 +00:00
}
2018-10-25 19:25:57 +00:00
var output = {
'command' : '' ,
2020-12-16 08:20:46 +00:00
'response' : 'ALARM: ' + alarmCode + ' - ' + grblStrings . alarms ( alarmCode ) + " [ " + command + " ]" ,
'type' : 'error'
2018-10-25 19:25:57 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2018-06-19 08:07:03 +00:00
break ;
}
status . comms . connectionStatus = 5 ;
} else if ( data . indexOf ( 'WARNING: After HALT you should HOME as position is currently unknown' ) != - 1 ) { //} || data.indexOf('HALTED') === 0) {
status . comms . connectionStatus = 2 ;
2018-08-09 17:29:41 +00:00
} else if ( data . indexOf ( 'Emergency Stop Requested' ) != - 1 ) { //} || data.indexOf('HALTED') === 0) {
2020-03-06 15:59:58 +00:00
debug _log ( "Emergency Stop Requested" )
2018-06-19 08:07:03 +00:00
status . comms . connectionStatus = 5 ;
} else if ( data . indexOf ( 'wait' ) === 0 ) { // Got wait from Repetier -> ignore
// do nothing
} else if ( data . indexOf ( 'error' ) === 0 ) { // Error received -> stay blocked stops queue
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-08-09 16:34:51 +00:00
// sentBuffer.shift();
2018-06-19 08:07:03 +00:00
var errorCode = parseInt ( data . split ( ':' ) [ 1 ] ) ;
2020-12-17 18:27:05 +00:00
var lastAlarm = "" ;
if ( errorCode == 9 && status . comms . connectionStatus == 5 && status . comms . alarm . length > 0 ) {
lastAlarm = "<hr>This error may just be a symptom of an earlier event:<br> ALARM: " + status . comms . alarm
}
2020-03-06 15:59:58 +00:00
debug _log ( 'error: ' + errorCode + ' - ' + grblStrings . errors ( errorCode ) + " [ " + command + " ]" ) ;
2018-07-11 18:58:38 +00:00
var output = {
'command' : '' ,
2020-12-17 18:27:05 +00:00
'response' : 'error: ' + errorCode + ' - ' + grblStrings . errors ( errorCode ) + " [ " + command + " ]" + lastAlarm ,
2020-12-16 08:20:46 +00:00
'type' : 'error'
2018-07-11 18:58:38 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2020-12-17 18:27:05 +00:00
io . sockets . emit ( "toastError" , 'error: ' + errorCode + ' - ' + grblStrings . errors ( errorCode ) + " [ " + command + " ]" + lastAlarm )
2018-06-19 08:07:03 +00:00
break ;
}
2020-03-06 15:59:58 +00:00
debug _log ( "error;" )
2018-10-22 14:54:53 +00:00
sentBuffer . shift ( ) ;
2018-08-07 17:34:04 +00:00
status . comms . connectionStatus = 5 ;
2018-06-19 08:07:03 +00:00
} else if ( data === ' ' ) {
// nothing
} else {
// do nothing with +data
}
2018-08-09 16:34:51 +00:00
2018-09-27 15:00:49 +00:00
if ( data . indexOf ( "[MSG:Reset to continue]" ) === 0 ) {
switch ( status . machine . firmware . type ) {
case 'grbl' :
2020-03-06 15:59:58 +00:00
debug _log ( "[MSG:Reset to continue] -> Sending Reset" )
2018-09-27 15:00:49 +00:00
addQRealtime ( String . fromCharCode ( 0x18 ) ) ; // ctrl-x
break ;
}
}
2019-12-30 19:56:20 +00:00
2018-08-09 16:34:51 +00:00
if ( command ) {
command = command . replace ( /(\r\n|\n|\r)/gm , "" ) ;
2020-03-06 15:59:58 +00:00
// debug_log("CMD: " + command + " / DATA RECV: " + data.replace(/(\r\n|\n|\r)/gm, ""));
2018-08-09 16:34:51 +00:00
2019-01-21 12:46:21 +00:00
if ( command != "?" && command != "M105" && data . length > 0 && data . indexOf ( '<' ) == - 1 ) {
2018-08-09 16:34:51 +00:00
var string = "" ;
if ( status . comms . sduploading ) {
string += "SD: "
}
string += data //+ " [ " + command + " ]"
var output = {
'command' : command ,
2020-12-16 08:20:46 +00:00
'response' : string ,
'type' : 'info'
2018-08-09 16:34:51 +00:00
}
2020-03-06 15:59:58 +00:00
// debug_log(output.response)
2018-08-09 16:34:51 +00:00
io . sockets . emit ( 'data' , output ) ;
}
2018-09-27 15:00:49 +00:00
} else {
if ( data . indexOf ( "<" ) != 0 ) {
var output = {
2018-09-28 15:37:03 +00:00
'command' : "" ,
2020-12-16 08:20:46 +00:00
'response' : data ,
'type' : 'info'
2018-09-27 15:00:49 +00:00
}
io . sockets . emit ( 'data' , output ) ;
}
2018-08-09 16:34:51 +00:00
}
2018-06-19 08:07:03 +00:00
} ) ; // end of parser.on(data)
}
} ) ;
socket . on ( 'saveToSd' , function ( datapack ) {
saveToSd ( datapack ) ;
} ) ;
2019-10-16 13:57:56 +00:00
socket . on ( 'setqueuePointer' , function ( data ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'Setting queuePointer to ' + data )
2019-10-16 13:57:56 +00:00
queuePointer = data
} ) ;
2020-02-06 18:02:06 +00:00
socket . on ( 'runJob' , function ( object ) {
2020-03-06 15:59:58 +00:00
// debug_log(data)
2021-01-05 21:23:40 +00:00
runJob ( object ) ;
2018-06-19 08:07:03 +00:00
} ) ;
socket . on ( 'forceQueue' , function ( data ) {
send1Q ( ) ;
} ) ;
2022-12-07 18:04:33 +00:00
socket . on ( 'serialInject' , function ( data ) {
// Inject a live command into Serial stream in real-time (dev tool) even while a job is running, etc (straight Port.write from machineSend)
machineSend ( data , true ) ;
} ) ;
socket . on ( "dump" , function ( data ) {
console . log ( queuePointer ) ;
console . log ( gcodeQueue ) ;
console . log ( sentBuffer ) ;
} )
2018-06-19 08:07:03 +00:00
socket . on ( 'runCommand' , function ( data ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'Run Command (' + data . replace ( '\n' , '|' ) + ')' ) ;
2018-06-19 08:07:03 +00:00
if ( status . comms . connectionStatus > 0 ) {
if ( data ) {
data = data . split ( '\n' ) ;
for ( var i = 0 ; i < data . length ; i ++ ) {
var line = data [ i ] . split ( ';' ) ; // Remove everything after ; = comment
var tosend = line [ 0 ] . trim ( ) ;
if ( tosend . length > 0 ) {
2018-08-09 16:34:51 +00:00
addQToEnd ( tosend ) ;
2018-06-19 08:07:03 +00:00
}
}
2020-06-23 17:55:56 +00:00
status . comms . runStatus = 'Running'
// debug_log('sending ' + JSON.stringify(gcodeQueue))
send1Q ( ) ;
2018-06-19 08:07:03 +00:00
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
} ) ;
socket . on ( 'jog' , function ( data ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'Jog ' + data ) ;
2018-06-19 08:07:03 +00:00
if ( status . comms . connectionStatus > 0 ) {
data = data . split ( ',' ) ;
var dir = data [ 0 ] ;
var dist = parseFloat ( data [ 1 ] ) ;
var feed ;
if ( data . length > 2 ) {
feed = parseInt ( data [ 2 ] ) ;
if ( feed ) {
feed = 'F' + feed ;
}
}
if ( dir && dist && feed ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'Adding jog commands to queue. Firmw=' + status . machine . firmware . type + ', blocked=' + status . comms . blocked + ', paused=' + status . comms . paused + ', Q=' + gcodeQueue . length ) ;
2018-06-19 08:07:03 +00:00
switch ( status . machine . firmware . type ) {
case 'grbl' :
2019-01-29 21:29:13 +00:00
addQToEnd ( '$J=G91G21' + dir + dist + feed ) ;
2018-06-19 08:07:03 +00:00
send1Q ( ) ;
break ;
default :
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Unknown firmware!' ) ;
2018-06-19 08:07:03 +00:00
break ;
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Invalid params!' ) ;
2018-06-19 08:07:03 +00:00
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
} ) ;
2018-08-24 19:00:03 +00:00
socket . on ( 'jogXY' , function ( data ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'Jog XY' + data ) ;
2018-08-24 19:00:03 +00:00
if ( status . comms . connectionStatus > 0 ) {
// var data = {
// x: xincrement,
// y: yincrement,
// feed: feed
// }
var xincrement = parseFloat ( data . x ) ;
var yincrement = parseFloat ( data . y ) ;
var feed = parseFloat ( data . feed )
if ( feed ) {
feed = 'F' + feed ;
}
if ( xincrement && yincrement && feed ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'Adding jog commands to queue. blocked=' + status . comms . blocked + ', paused=' + status . comms . paused + ', Q=' + gcodeQueue . length ) ;
2018-08-24 19:00:03 +00:00
switch ( status . machine . firmware . type ) {
case 'grbl' :
2019-01-29 21:29:13 +00:00
addQToEnd ( '$J=G91G21X' + xincrement + " Y" + yincrement + " " + feed ) ;
2018-08-24 19:00:03 +00:00
send1Q ( ) ;
break ;
default :
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Unknown firmware!' ) ;
2018-08-24 19:00:03 +00:00
break ;
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Invalid params!' ) ;
2018-08-24 19:00:03 +00:00
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-08-24 19:00:03 +00:00
}
} ) ;
2018-06-19 08:07:03 +00:00
socket . on ( 'jogTo' , function ( data ) { // data = {x:xVal, y:yVal, z:zVal, mode:0(absulute)|1(relative), feed:fVal}
2020-03-06 15:59:58 +00:00
debug _log ( 'JogTo ' + JSON . stringify ( data ) ) ;
2018-06-19 08:07:03 +00:00
if ( status . comms . connectionStatus > 0 ) {
if ( data . x !== undefined || data . y !== undefined || data . z !== undefined ) {
var xVal = ( data . x !== undefined ? 'X' + parseFloat ( data . x ) : '' ) ;
var yVal = ( data . y !== undefined ? 'Y' + parseFloat ( data . y ) : '' ) ;
var zVal = ( data . z !== undefined ? 'Z' + parseFloat ( data . z ) : '' ) ;
var mode = ( ( data . mode == 0 ) ? 0 : 1 ) ;
var feed = ( data . feed !== undefined ? 'F' + parseInt ( data . feed ) : '' ) ;
2020-03-06 15:59:58 +00:00
debug _log ( 'Adding jog commands to queue. blocked=' + status . comms . blocked + ', paused=' + status . comms . paused + ', Q=' + gcodeQueue . length ) ;
2018-06-19 08:07:03 +00:00
switch ( status . machine . firmware . type ) {
case 'grbl' :
2019-01-29 21:29:13 +00:00
addQToEnd ( '$J=G91G21' + mode + xVal + yVal + zVal + feed ) ;
2018-06-19 08:07:03 +00:00
break ;
default :
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Unknown firmware!' ) ;
2018-06-19 08:07:03 +00:00
break ;
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'error Invalid params!' ) ;
2018-06-19 08:07:03 +00:00
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
} ) ;
socket . on ( 'setZero' , function ( data ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'setZero(' + data + ')' ) ;
2018-06-19 08:07:03 +00:00
if ( status . comms . connectionStatus > 0 ) {
switch ( data ) {
case 'x' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G10 L20 P0 X0' ) ;
2018-06-19 08:07:03 +00:00
break ;
case 'y' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G10 L20 P0 Y0' ) ;
2018-06-19 08:07:03 +00:00
break ;
case 'z' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G10 L20 P0 Z0' ) ;
2018-06-19 08:07:03 +00:00
break ;
case 'a' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G10 L20 P0 A0' ) ;
2018-06-19 08:07:03 +00:00
break ;
case 'all' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G10 L20 P0 X0 Y0 Z0' ) ;
2018-06-19 08:07:03 +00:00
break ;
case 'xyza' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G10 L20 P0 X0 Y0 Z0 A0' ) ;
2018-06-19 08:07:03 +00:00
break ;
}
send1Q ( ) ;
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
} ) ;
socket . on ( 'gotoZero' , function ( data ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'gotoZero(' + data + ')' ) ;
2018-06-19 08:07:03 +00:00
if ( status . comms . connectionStatus > 0 ) {
switch ( data ) {
case 'x' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G0 X0' ) ;
2018-06-19 08:07:03 +00:00
break ;
case 'y' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G0 Y0' ) ;
2018-06-19 08:07:03 +00:00
break ;
case 'z' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G0 Z0' ) ;
2018-06-19 08:07:03 +00:00
break ;
case 'a' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G0 A0' ) ;
2018-06-19 08:07:03 +00:00
break ;
case 'all' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G0 X0 Y0 Z0' ) ;
2018-06-19 08:07:03 +00:00
break ;
case 'xyza' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G0 X0 Y0 Z0 A0' ) ;
2018-06-19 08:07:03 +00:00
break ;
}
send1Q ( ) ;
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
} ) ;
socket . on ( 'setPosition' , function ( data ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'setPosition(' + JSON . stringify ( data ) + ')' ) ;
2018-06-19 08:07:03 +00:00
if ( status . comms . connectionStatus > 0 ) {
if ( data . x !== undefined || data . y !== undefined || data . z !== undefined ) {
var xVal = ( data . x !== undefined ? 'X' + parseFloat ( data . x ) + ' ' : '' ) ;
var yVal = ( data . y !== undefined ? 'Y' + parseFloat ( data . y ) + ' ' : '' ) ;
var zVal = ( data . z !== undefined ? 'Z' + parseFloat ( data . z ) + ' ' : '' ) ;
var aVal = ( data . a !== undefined ? 'A' + parseFloat ( data . a ) + ' ' : '' ) ;
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G10 L20 P0 ' + xVal + yVal + zVal + aVal ) ;
2018-06-19 08:07:03 +00:00
send1Q ( ) ;
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
} ) ;
socket . on ( 'probe' , function ( data ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'probe(' + JSON . stringify ( data ) + ')' ) ;
2018-06-19 08:07:03 +00:00
if ( status . comms . connectionStatus > 0 ) {
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G38.2 ' + data . direction + '-5 F1' ) ;
addQToEnd ( 'G92 ' + data . direction + ' ' + data . probeOffset ) ;
send1Q ( ) ;
2018-06-19 08:07:03 +00:00
break ;
default :
//not supported
2020-03-06 15:59:58 +00:00
debug _log ( 'Command not supported by firmware!' ) ;
2018-06-19 08:07:03 +00:00
break ;
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
} ) ;
socket . on ( 'feedOverride' , function ( data ) {
2020-03-06 15:59:58 +00:00
debug _log ( data )
2018-06-19 08:07:03 +00:00
if ( status . comms . connectionStatus > 0 ) {
switch ( status . machine . firmware . type ) {
case 'grbl' :
2020-03-06 15:59:58 +00:00
debug _log ( "current FRO = " + status . machine . overrides . feedOverride )
debug _log ( "requested FRO = " + data )
2018-06-19 08:07:03 +00:00
var curfro = parseInt ( status . machine . overrides . feedOverride )
var reqfro = parseInt ( data )
var delta ;
if ( reqfro == 100 ) {
2019-04-12 13:32:56 +00:00
addQRealtime ( String . fromCharCode ( 0x90 ) ) ;
2018-06-19 08:07:03 +00:00
} else if ( curfro < reqfro ) {
// FRO Increase
delta = reqfro - curfro
2020-03-06 15:59:58 +00:00
debug _log ( "delta = " + delta )
2018-06-19 08:07:03 +00:00
var tens = Math . floor ( delta / 10 )
2020-03-06 15:59:58 +00:00
debug _log ( "need to send " + tens + " x10s increase" )
2019-04-12 13:32:56 +00:00
// for (i = 0; i < tens; i++) {
// addQRealtime(String.fromCharCode(0x91));
// }
for ( let i = 1 ; i < tens + 1 ; i ++ ) {
setTimeout ( function timer ( ) {
addQRealtime ( String . fromCharCode ( 0x91 ) ) ;
addQRealtime ( "?" ) ;
} , i * 50 ) ;
2018-06-19 08:07:03 +00:00
}
var ones = delta - ( 10 * tens ) ;
2020-03-06 15:59:58 +00:00
debug _log ( "need to send " + ones + " x1s increase" )
2019-04-12 13:32:56 +00:00
// for (i = 0; i < ones; i++) {
// addQRealtime(String.fromCharCode(0x93));
// }
for ( let i = 1 ; i < ones + 1 ; i ++ ) {
setTimeout ( function timer ( ) {
addQRealtime ( String . fromCharCode ( 0x93 ) ) ;
addQRealtime ( "?" ) ;
} , i * 50 ) ;
2018-06-19 08:07:03 +00:00
}
} else if ( curfro > reqfro ) {
// FRO Decrease
delta = curfro - reqfro
2020-03-06 15:59:58 +00:00
debug _log ( "delta = " + delta )
2018-06-19 08:07:03 +00:00
var tens = Math . floor ( delta / 10 )
2020-03-06 15:59:58 +00:00
debug _log ( "need to send " + tens + " x10s decrease" )
2019-04-12 13:32:56 +00:00
// for (i = 0; i < tens; i++) {
// addQRealtime(String.fromCharCode(0x92));
// }
for ( let i = 1 ; i < tens + 1 ; i ++ ) {
setTimeout ( function timer ( ) {
addQRealtime ( String . fromCharCode ( 0x92 ) ) ;
addQRealtime ( "?" ) ;
} , i * 50 ) ;
2018-06-19 08:07:03 +00:00
}
2019-04-12 13:32:56 +00:00
2018-06-19 08:07:03 +00:00
var ones = delta - ( 10 * tens ) ;
2020-03-06 15:59:58 +00:00
debug _log ( "need to send " + ones + " x1s decrease" )
2019-04-12 13:32:56 +00:00
// for (i = 0; i < tens; i++) {
// addQRealtime(String.fromCharCode(0x94));
// }
for ( let i = 1 ; i < ones + 1 ; i ++ ) {
setTimeout ( function timer ( ) {
addQRealtime ( String . fromCharCode ( 0x94 ) ) ;
addQRealtime ( "?" ) ;
} , i * 50 ) ;
2018-06-19 08:07:03 +00:00
}
}
2019-04-12 13:32:56 +00:00
addQRealtime ( "?" ) ;
2020-04-17 21:07:39 +00:00
status . machine . overrides . feedOverride = parseInt ( reqfro ) ; // Set now, but will be overriden from feedback from Grbl itself in next queryloop
2018-06-19 08:07:03 +00:00
break ;
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
} ) ;
socket . on ( 'spindleOverride' , function ( data ) {
if ( status . comms . connectionStatus > 0 ) {
switch ( status . machine . firmware . type ) {
case 'grbl' :
2020-03-06 15:59:58 +00:00
debug _log ( "current SRO = " + status . machine . overrides . spindleOverride )
debug _log ( "requested SRO = " + data )
2018-06-19 08:07:03 +00:00
var cursro = parseInt ( status . machine . overrides . spindleOverride )
var reqsro = parseInt ( data )
var delta ;
if ( reqsro == 100 ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 153 ) ) ;
2018-06-19 08:07:03 +00:00
} else if ( cursro < reqsro ) {
// FRO Increase
delta = reqsro - cursro
2020-03-06 15:59:58 +00:00
debug _log ( "delta = " + delta )
2018-06-19 08:07:03 +00:00
var tens = Math . floor ( delta / 10 )
2020-03-06 15:59:58 +00:00
debug _log ( "need to send " + tens + " x10s increase" )
2019-04-12 13:32:56 +00:00
// for (i = 0; i < tens; i++) {
// addQRealtime(String.fromCharCode(154));
// }
for ( let i = 1 ; i < tens + 1 ; i ++ ) {
setTimeout ( function timer ( ) {
addQRealtime ( String . fromCharCode ( 154 ) ) ;
addQRealtime ( "?" ) ;
} , i * 50 ) ;
2018-06-19 08:07:03 +00:00
}
var ones = delta - ( 10 * tens ) ;
2020-03-06 15:59:58 +00:00
debug _log ( "need to send " + ones + " x1s increase" )
2019-04-12 13:32:56 +00:00
// for (i = 0; i < ones; i++) {
// addQRealtime(String.fromCharCode(156));
// }
for ( let i = 1 ; i < ones + 1 ; i ++ ) {
setTimeout ( function timer ( ) {
addQRealtime ( String . fromCharCode ( 156 ) ) ;
addQRealtime ( "?" ) ;
} , i * 50 ) ;
2018-06-19 08:07:03 +00:00
}
} else if ( cursro > reqsro ) {
// FRO Decrease
delta = cursro - reqsro
2020-03-06 15:59:58 +00:00
debug _log ( "delta = " + delta )
2018-06-19 08:07:03 +00:00
var tens = Math . floor ( delta / 10 )
2020-03-06 15:59:58 +00:00
debug _log ( "need to send " + tens + " x10s decrease" )
2019-04-12 13:32:56 +00:00
// for (i = 0; i < tens; i++) {
// addQRealtime(String.fromCharCode(155));
// }
for ( let i = 1 ; i < tens + 1 ; i ++ ) {
setTimeout ( function timer ( ) {
addQRealtime ( String . fromCharCode ( 155 ) ) ;
addQRealtime ( "?" ) ;
} , i * 50 ) ;
2018-06-19 08:07:03 +00:00
}
var ones = delta - ( 10 * tens ) ;
2020-03-06 15:59:58 +00:00
debug _log ( "need to send " + ones + " x1s decrease" )
2019-04-12 13:32:56 +00:00
// for (i = 0; i < tens; i++) {
// addQRealtime(String.fromCharCode(157));
// }
for ( let i = 1 ; i < ones + 1 ; i ++ ) {
setTimeout ( function timer ( ) {
addQRealtime ( String . fromCharCode ( 157 ) ) ;
addQRealtime ( "?" ) ;
} , i * 50 ) ;
2018-06-19 08:07:03 +00:00
}
}
2019-04-12 13:32:56 +00:00
addQRealtime ( "?" ) ;
2020-04-17 21:07:39 +00:00
status . machine . overrides . spindleOverride = parseInt ( reqsro ) ; // Set now, but will be overriden from feedback from Grbl itself in next queryloop
2018-06-19 08:07:03 +00:00
break ;
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
} ) ;
socket . on ( 'laserTest' , function ( data ) { // Laser Test Fire
laserTest ( data ) ;
} ) ;
socket . on ( 'pause' , function ( ) {
2019-01-21 12:46:21 +00:00
pause ( ) ;
2018-06-19 08:07:03 +00:00
} ) ;
socket . on ( 'resume' , function ( ) {
2019-01-21 12:46:21 +00:00
unpause ( ) ;
2018-06-19 08:07:03 +00:00
} ) ;
2019-04-18 14:23:51 +00:00
socket . on ( 'stop' , function ( data ) {
stop ( data ) ;
2018-06-19 08:07:03 +00:00
} ) ;
socket . on ( 'clearAlarm' , function ( data ) { // Clear Alarm
if ( status . comms . connectionStatus > 0 ) {
data = parseInt ( data ) ;
2020-03-06 15:59:58 +00:00
debug _log ( 'Clearing Queue: Method ' + data ) ;
2018-06-19 08:07:03 +00:00
switch ( data ) {
case 1 :
2020-03-06 15:59:58 +00:00
debug _log ( 'Clearing Lockout' ) ;
2018-06-19 08:07:03 +00:00
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-08-09 16:34:51 +00:00
addQRealtime ( '$X\n' ) ;
2020-03-06 15:59:58 +00:00
debug _log ( 'Sent: $X' ) ;
2018-06-19 08:07:03 +00:00
break ;
}
2020-03-06 15:59:58 +00:00
debug _log ( 'Resuming Queue Lockout' ) ;
2024-05-07 17:55:51 +00:00
var output = {
'command' : '[clear alarm]' ,
'response' : "Operator clicked Clear Alarm: Cleared Lockout" ,
'type' : 'info'
}
io . sockets . emit ( 'data' , output ) ;
2018-06-19 08:07:03 +00:00
break ;
case 2 :
2020-03-06 15:59:58 +00:00
debug _log ( 'Emptying Queue' ) ;
2018-09-27 15:00:49 +00:00
status . comms . queue = 0
queuePointer = 0 ;
2018-06-19 08:07:03 +00:00
gcodeQueue . length = 0 ; // Dump the queue
2018-08-09 16:34:51 +00:00
sentBuffer . length = 0 ; // Dump bufferSizes
2018-06-19 08:07:03 +00:00
queuePointer = 0 ;
2020-03-06 15:59:58 +00:00
debug _log ( 'Clearing Lockout' ) ;
2018-06-19 08:07:03 +00:00
switch ( status . machine . firmware . type ) {
case 'grbl' :
2022-04-21 12:26:03 +00:00
clearInterval ( queueCounter ) ;
2024-04-17 13:22:42 +00:00
if ( jogWindow ) {
jogWindow . setProgressBar ( 0 ) ;
}
2018-09-27 15:00:49 +00:00
addQRealtime ( String . fromCharCode ( 0x18 ) ) ; // ctrl-x
2022-04-21 12:26:03 +00:00
setTimeout ( function ( ) {
addQRealtime ( '$X\n' ) ;
debug _log ( 'Sent: $X' ) ;
} , 500 ) ;
2018-06-19 08:07:03 +00:00
status . comms . blocked = false ;
status . comms . paused = false ;
break ;
}
2024-05-07 17:55:51 +00:00
var output = {
'command' : '[clear alarm]' ,
'response' : "Operator clicked Clear Alarm: Cleared Lockout and Emptied Queue" ,
'type' : 'info'
}
io . sockets . emit ( 'data' , output ) ;
2018-06-19 08:07:03 +00:00
break ;
}
status . comms . runStatus = 'Stopped'
status . comms . connectionStatus = 2 ;
2020-12-17 18:27:05 +00:00
status . comms . alarm = "" ;
2020-11-16 17:58:36 +00:00
io . sockets . emit ( 'errorsCleared' , true ) ;
2018-06-19 08:07:03 +00:00
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
} ) ;
socket . on ( 'resetMachine' , function ( ) {
if ( status . comms . connectionStatus > 0 ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'Reset Machine' ) ;
2018-06-19 08:07:03 +00:00
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 0x18 ) ) ; // ctrl-x
2020-03-06 15:59:58 +00:00
debug _log ( 'Sent: Code(0x18)' ) ;
2018-06-19 08:07:03 +00:00
break ;
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
} ) ;
socket . on ( 'closePort' , function ( data ) { // Close machine port and dump queue
if ( status . comms . connectionStatus > 0 ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'WARN: Closing Port ' + port . path ) ;
2018-06-19 08:07:03 +00:00
stopPort ( ) ;
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
} ) ;
2022-11-01 20:21:24 +00:00
2022-07-06 20:08:38 +00:00
2018-06-19 08:07:03 +00:00
} ) ;
2021-04-16 13:41:00 +00:00
function readFile ( filePath ) {
if ( filePath ) {
if ( filePath . length > 1 ) {
var filename = path . parse ( filePath )
filename = filename . name + filename . ext
debug _log ( 'readfile: ' + filePath )
fs . readFile ( filePath , 'utf8' ,
2018-09-04 16:12:14 +00:00
function ( err , data ) {
if ( err ) {
2020-03-06 15:59:58 +00:00
debug _log ( err ) ;
2018-09-04 16:12:14 +00:00
var output = {
'command' : '' ,
'response' : "ERROR: File Upload Failed"
}
uploadedgcode = "" ;
2018-08-29 08:11:14 +00:00
}
2018-09-04 16:12:14 +00:00
if ( data ) {
2021-04-16 13:41:00 +00:00
if ( filePath . endsWith ( '.obc' ) ) { // OpenBuildsCAM Workspace
2019-04-29 17:26:29 +00:00
uploadedworkspace = data ;
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://cam.openbuilds.com' )
} else { // GCODE
2020-03-30 15:26:11 +00:00
var payload = {
gcode : data ,
2021-04-16 13:41:00 +00:00
filename : filename
2020-03-30 15:26:11 +00:00
}
io . sockets . emit ( 'gcodeupload' , payload ) ;
2019-04-29 17:26:29 +00:00
uploadedgcode = data ;
return data
}
2018-09-04 16:12:14 +00:00
}
} ) ;
}
2018-08-29 08:11:14 +00:00
}
}
2020-06-23 17:55:56 +00:00
function machineSend ( gcode , realtime ) {
debug _log ( "SENDING: " + gcode )
2018-06-19 08:07:03 +00:00
if ( port . isOpen ) {
2020-06-23 17:55:56 +00:00
if ( realtime ) {
// realtime commands doesnt count toward the queue, does not generate OK
port . write ( gcode ) ;
} else {
if ( gcode . match ( /T([\d.]+)/i ) ) {
var tool = parseFloat ( RegExp . $1 ) ;
status . machine . tool . nexttool . number = tool
status . machine . tool . nexttool . line = gcode
}
var queueLeft = parseInt ( ( gcodeQueue . length - queuePointer ) )
var queueTotal = parseInt ( gcodeQueue . length )
// debug_log("Q: " + queueLeft)
var data = [ ]
data . push ( queueLeft ) ;
data . push ( queueTotal ) ;
io . sockets . emit ( "queueCount" , data ) ;
// debug_log(gcode)
port . write ( gcode ) ;
2022-12-07 18:04:33 +00:00
debug _log ( "SENT: " + gcode )
2019-09-03 18:36:09 +00:00
}
2018-06-19 08:07:03 +00:00
} else {
2020-03-06 15:59:58 +00:00
debug _log ( "PORT NOT OPEN" )
2018-06-19 08:07:03 +00:00
}
}
2021-01-05 21:23:40 +00:00
function runJob ( object ) {
// object = {
// isJob: true,
// completedMsg: "",
// data: "",
// }
jobStartTime = false ;
var data = object . data
2021-12-02 14:40:12 +00:00
2021-01-05 21:23:40 +00:00
if ( object . isJob ) {
if ( data . length < 20000 ) {
uploadedgcode = data ;
}
jobStartTime = new Date ( ) . getTime ( ) ;
}
if ( object . completedMsg ) {
jobCompletedMsg = object . completedMsg
}
// debug_log('Run Job (' + data.length + ')');
if ( status . comms . connectionStatus > 0 ) {
if ( data ) {
data = data . split ( '\n' ) ;
for ( var i = 0 ; i < data . length ; i ++ ) {
var line = data [ i ] . replace ( "%" , "" ) . split ( ';' ) ; // Remove everything after ; = comment
var tosend = line [ 0 ] . trim ( ) ;
if ( tosend . length > 0 ) {
addQToEnd ( tosend ) ;
}
}
if ( i > 0 ) {
// Start interval for qCount messages to socket clients
queueCounter = setInterval ( function ( ) {
status . comms . queue = gcodeQueue . length - queuePointer
2024-04-17 13:22:42 +00:00
if ( jogWindow ) {
jogWindow . setProgressBar ( queuePointer / gcodeQueue . length )
}
2021-01-05 21:23:40 +00:00
} , 500 ) ;
send1Q ( ) ; // send first line
status . comms . connectionStatus = 3 ;
}
}
} else {
debug _log ( 'ERROR: Machine connection not open!' ) ;
}
}
2018-08-07 17:34:04 +00:00
function stopPort ( ) {
clearInterval ( queueCounter ) ;
2022-07-06 20:08:38 +00:00
clearInterval ( statusLoop ) ;
2024-04-17 13:22:42 +00:00
if ( jogWindow ) {
jogWindow . setProgressBar ( 0 ) ;
}
2018-08-07 17:34:04 +00:00
status . comms . interfaces . activePort = false ;
status . comms . interfaces . activeBaud = false ;
status . comms . connectionStatus = 0 ;
status . machine . firmware . type = "" ;
status . machine . firmware . version = "" ; // get version
status . machine . firmware . date = "" ;
status . machine . firmware . buffer = "" ;
gcodeQueue . length = 0 ;
2018-08-09 16:34:51 +00:00
sentBuffer . length = 0 ; // dump bufferSizes
2022-07-06 20:08:38 +00:00
// port.drain(port.close());
if ( status . comms . interfaces . type == "usb" ) {
port . drain ( port . close ( ) ) ;
} else if ( status . comms . interfaces . type == "telnet" ) {
port . destroy ( ) ;
}
2018-08-07 17:34:04 +00:00
}
2018-06-19 08:07:03 +00:00
function parseFeedback ( data ) {
2022-12-07 18:04:33 +00:00
//debug_log(data)
2018-06-19 08:07:03 +00:00
var state = data . substring ( 1 , data . search ( /(,|\|)/ ) ) ;
status . comms . runStatus = state
2018-06-24 14:14:28 +00:00
if ( state == "Alarm" ) {
2020-03-06 15:59:58 +00:00
// debug_log("ALARM: " + data)
2018-06-24 14:14:28 +00:00
status . comms . connectionStatus = 5 ;
switch ( status . machine . firmware . type ) {
case 'grbl' :
2020-12-17 18:27:05 +00:00
//var alarmCode = parseInt(data.split(':')[1]);
debug _log ( 'ALARM: ' + data ) ;
//status.comms.alarm = alarmCode + ' - ' + grblStrings.alarms(alarmCode)
2018-06-24 14:14:28 +00:00
break ;
}
status . comms . connectionStatus = 5 ;
2020-12-28 15:54:09 +00:00
} else if ( state == "Hold:0" ) {
pause ( ) ;
2018-06-24 14:14:28 +00:00
}
2022-12-07 18:04:33 +00:00
if ( status . machine . firmware . type == "grbl" ) {
2018-09-14 17:35:54 +00:00
// Extract work offset (for Grbl > 1.1 only!)
var startWCO = data . search ( /wco:/i ) + 4 ;
var wco ;
if ( startWCO > 4 ) {
wco = data . replace ( ">" , "" ) . substr ( startWCO ) . split ( /,|\|/ , 4 ) ;
}
if ( Array . isArray ( wco ) ) {
xOffset = parseFloat ( wco [ 0 ] ) . toFixed ( config . posDecimals ) ;
yOffset = parseFloat ( wco [ 1 ] ) . toFixed ( config . posDecimals ) ;
zOffset = parseFloat ( wco [ 2 ] ) . toFixed ( config . posDecimals ) ;
2022-11-01 20:21:24 +00:00
if ( status . machine . has4thAxis ) {
2018-09-14 17:35:54 +00:00
aOffset = parseFloat ( wco [ 3 ] ) . toFixed ( config . posDecimals ) ;
2020-04-17 21:07:39 +00:00
status . machine . position . offset . x = parseFloat ( xOffset ) ;
status . machine . position . offset . y = parseFloat ( yOffset ) ;
status . machine . position . offset . z = parseFloat ( zOffset ) ;
status . machine . position . offset . a = parseFloat ( aOffset ) ;
2018-09-14 17:35:54 +00:00
} else {
2020-04-17 21:07:39 +00:00
status . machine . position . offset . x = parseFloat ( xOffset ) ;
status . machine . position . offset . y = parseFloat ( yOffset ) ;
status . machine . position . offset . z = parseFloat ( zOffset ) ;
2018-09-14 17:35:54 +00:00
}
}
2018-06-19 08:07:03 +00:00
// Extract wPos (for Grbl > 1.1 only!)
var startWPos = data . search ( /wpos:/i ) + 5 ;
var wPos ;
if ( startWPos > 5 ) {
var wPosLen = data . substr ( startWPos ) . search ( />|\|/ ) ;
wPos = data . substr ( startWPos , wPosLen ) . split ( /,/ ) ;
}
2018-09-14 17:35:54 +00:00
var startMPos = data . search ( /mpos:/i ) + 5 ;
var mPos ;
if ( startMPos > 5 ) {
var mPosLen = data . substr ( startMPos ) . search ( />|\|/ ) ;
mPos = data . substr ( startMPos , mPosLen ) . split ( /,/ ) ;
}
// If we got a WPOS
2018-06-19 08:07:03 +00:00
if ( Array . isArray ( wPos ) ) {
2020-03-06 15:59:58 +00:00
// debug_log('wpos')
2018-06-19 08:07:03 +00:00
if ( xPos !== parseFloat ( wPos [ 0 ] ) . toFixed ( config . posDecimals ) ) {
xPos = parseFloat ( wPos [ 0 ] ) . toFixed ( config . posDecimals ) ;
}
if ( yPos !== parseFloat ( wPos [ 1 ] ) . toFixed ( config . posDecimals ) ) {
yPos = parseFloat ( wPos [ 1 ] ) . toFixed ( config . posDecimals ) ;
}
if ( zPos !== parseFloat ( wPos [ 2 ] ) . toFixed ( config . posDecimals ) ) {
zPos = parseFloat ( wPos [ 2 ] ) . toFixed ( config . posDecimals ) ;
}
if ( wPos . length > 3 ) {
if ( aPos !== parseFloat ( wPos [ 3 ] ) . toFixed ( config . posDecimals ) ) {
aPos = parseFloat ( wPos [ 3 ] ) . toFixed ( config . posDecimals ) ;
2022-11-01 20:21:24 +00:00
status . machine . has4thAxis = true ;
2018-06-19 08:07:03 +00:00
}
}
2022-11-01 20:21:24 +00:00
if ( status . machine . has4thAxis ) {
2020-04-17 21:07:39 +00:00
status . machine . position . work . x = parseFloat ( xPos ) ;
status . machine . position . work . y = parseFloat ( yPos ) ;
status . machine . position . work . z = parseFloat ( zPos ) ;
status . machine . position . work . a = parseFloat ( aPos ) ;
2018-06-19 08:07:03 +00:00
} else {
2020-04-17 21:07:39 +00:00
status . machine . position . work . x = parseFloat ( xPos ) ;
status . machine . position . work . y = parseFloat ( yPos ) ;
status . machine . position . work . z = parseFloat ( zPos ) ;
2018-06-19 08:07:03 +00:00
}
2018-09-14 17:35:54 +00:00
// end is WPOS
} else if ( Array . isArray ( mPos ) ) {
2020-03-06 15:59:58 +00:00
// debug_log('mpos', mPos)
2018-09-14 17:35:54 +00:00
if ( xPos !== parseFloat ( mPos [ 0 ] ) . toFixed ( config . posDecimals ) ) {
xPos = parseFloat ( mPos [ 0 ] ) . toFixed ( config . posDecimals ) ;
}
if ( yPos !== parseFloat ( mPos [ 1 ] ) . toFixed ( config . posDecimals ) ) {
yPos = parseFloat ( mPos [ 1 ] ) . toFixed ( config . posDecimals ) ;
}
if ( zPos !== parseFloat ( mPos [ 2 ] ) . toFixed ( config . posDecimals ) ) {
zPos = parseFloat ( mPos [ 2 ] ) . toFixed ( config . posDecimals ) ;
}
if ( mPos . length > 3 ) {
if ( aPos !== parseFloat ( mPos [ 3 ] ) . toFixed ( config . posDecimals ) ) {
aPos = parseFloat ( mPos [ 3 ] ) . toFixed ( config . posDecimals ) ;
2022-11-01 20:21:24 +00:00
status . machine . has4thAxis = true ;
2018-09-14 17:35:54 +00:00
}
}
2022-11-01 20:21:24 +00:00
if ( status . machine . has4thAxis ) {
2020-04-17 21:07:39 +00:00
status . machine . position . work . x = parseFloat ( parseFloat ( xPos - status . machine . position . offset . x ) . toFixed ( config . posDecimals ) ) ;
status . machine . position . work . y = parseFloat ( parseFloat ( yPos - status . machine . position . offset . y ) . toFixed ( config . posDecimals ) ) ;
status . machine . position . work . z = parseFloat ( parseFloat ( zPos - status . machine . position . offset . z ) . toFixed ( config . posDecimals ) ) ;
status . machine . position . work . a = parseFloat ( parseFloat ( aPos - status . machine . position . offset . a ) . toFixed ( config . posDecimals ) ) ;
2018-06-19 08:07:03 +00:00
} else {
2020-04-17 21:07:39 +00:00
status . machine . position . work . x = parseFloat ( parseFloat ( xPos - status . machine . position . offset . x ) . toFixed ( config . posDecimals ) ) ;
status . machine . position . work . y = parseFloat ( parseFloat ( yPos - status . machine . position . offset . y ) . toFixed ( config . posDecimals ) ) ;
status . machine . position . work . z = parseFloat ( parseFloat ( zPos - status . machine . position . offset . z ) . toFixed ( config . posDecimals ) ) ;
2018-06-19 08:07:03 +00:00
}
2018-09-14 17:35:54 +00:00
// end if MPOS
2018-06-19 08:07:03 +00:00
}
2018-09-14 17:35:54 +00:00
2018-06-19 08:07:03 +00:00
}
// Extract override values (for Grbl > v1.1 only!)
var startOv = data . search ( /ov:/i ) + 3 ;
if ( startOv > 3 ) {
var ov = data . replace ( ">" , "" ) . substr ( startOv ) . split ( /,|\|/ , 3 ) ;
if ( Array . isArray ( ov ) ) {
if ( ov [ 0 ] ) {
2020-04-17 21:07:39 +00:00
status . machine . overrides . feedOverride = parseInt ( ov [ 0 ] ) ;
2018-06-19 08:07:03 +00:00
}
if ( ov [ 1 ] ) {
2020-04-17 21:07:39 +00:00
status . machine . overrides . rapidOverride = parseInt ( ov [ 1 ] ) ;
2018-06-19 08:07:03 +00:00
}
if ( ov [ 2 ] ) {
2020-04-17 21:07:39 +00:00
status . machine . overrides . spindleOverride = parseInt ( ov [ 2 ] ) ;
2018-06-19 08:07:03 +00:00
}
}
}
// Extract realtime Feed and Spindle (for Grbl > v1.1 only!)
2021-02-11 18:30:00 +00:00
var startFS = data . search ( /\|FS:/i ) + 4 ;
if ( startFS > 4 ) {
2018-06-19 08:07:03 +00:00
var fs = data . replace ( ">" , "" ) . substr ( startFS ) . split ( /,|\|/ ) ;
if ( Array . isArray ( fs ) ) {
if ( fs [ 0 ] ) {
2020-04-17 21:07:39 +00:00
status . machine . overrides . realFeed = parseInt ( fs [ 0 ] ) ;
2018-06-19 08:07:03 +00:00
}
if ( fs [ 1 ] ) {
2020-04-17 21:07:39 +00:00
status . machine . overrides . realSpindle = parseInt ( fs [ 1 ] ) ;
2018-06-19 08:07:03 +00:00
}
}
}
2021-02-01 15:59:05 +00:00
// extras realtime feed (if variable spindle is disabled)
2021-02-11 18:30:00 +00:00
var startF = data . search ( /\|F:/i ) + 3 ;
if ( startF > 3 ) {
2021-02-01 15:59:05 +00:00
var f = data . replace ( ">" , "" ) . substr ( startF ) . split ( /,|\|/ ) ;
2021-02-11 18:30:00 +00:00
console . log ( JSON . stringify ( f , null , 4 ) )
2021-02-01 15:59:05 +00:00
if ( Array . isArray ( f ) ) {
2021-02-02 19:27:49 +00:00
if ( f [ 0 ] ) {
status . machine . overrides . realFeed = parseInt ( f [ 0 ] ) ;
2021-02-01 15:59:05 +00:00
}
}
}
2018-08-07 10:05:49 +00:00
// Extract Pin Data
var startPin = data . search ( /Pn:/i ) + 3 ;
if ( startPin > 3 ) {
var pinsdata = data . replace ( ">" , "" ) . replace ( "\r" , "" ) . substr ( startPin ) . split ( /,|\|/ , 1 ) ;
var pins = pinsdata [ 0 ] . split ( '' )
status . machine . inputs = pins ;
2019-02-11 19:29:44 +00:00
if ( ! _ . isEqual ( pins , oldpinslist ) ) {
2021-05-11 14:16:04 +00:00
if ( pins . includes ( 'H' ) && ! pins . includes ( 'D' ) ) {
2019-02-11 19:29:44 +00:00
// pause
pause ( ) ;
var output = {
'command' : '[external from hardware]' ,
2020-12-16 08:20:46 +00:00
'response' : "OpenBuilds CONTROL received a FEEDHOLD notification from Grbl: This could be due to someone pressing the HOLD button (if connected)" ,
'type' : 'info'
2019-02-11 19:29:44 +00:00
}
io . sockets . emit ( 'data' , output ) ;
} // end if HOLD
2019-01-21 12:46:21 +00:00
2021-02-11 18:30:00 +00:00
if ( pins . includes ( 'D' ) ) {
// pause
pause ( ) ;
}
2019-02-11 19:29:44 +00:00
if ( pins . includes ( 'R' ) ) {
// abort
2019-04-18 14:23:51 +00:00
stop ( true ) ;
2019-02-11 19:29:44 +00:00
var output = {
'command' : '[external from hardware]' ,
2020-12-16 08:20:46 +00:00
'response' : "OpenBuilds CONTROL received a RESET/ABORT notification from Grbl: This could be due to someone pressing the RESET/ABORT button (if connected)" ,
'type' : 'info'
2019-02-11 19:29:44 +00:00
}
io . sockets . emit ( 'data' , output ) ;
} // end if ABORT
if ( pins . includes ( 'S' ) ) {
// abort
unpause ( ) ;
var output = {
'command' : '[external from hardware]' ,
2020-12-16 08:20:46 +00:00
'response' : "OpenBuilds CONTROL received a CYCLESTART/RESUME notification from Grbl: This could be due to someone pressing the CYCLESTART/RESUME button (if connected)" ,
'type' : 'info'
2019-02-11 19:29:44 +00:00
}
io . sockets . emit ( 'data' , output ) ;
} // end if RESUME/START
}
2018-08-07 10:05:49 +00:00
} else {
status . machine . inputs = [ ] ;
}
2019-02-11 19:29:44 +00:00
oldpinslist = pins ;
2018-08-07 10:05:49 +00:00
// Extract Buffer Data
var startBuf = data . search ( /Bf:/i ) + 3 ;
if ( startBuf > 3 ) {
var buffer = data . replace ( ">" , "" ) . replace ( "\r" , "" ) . substr ( startBuf ) . split ( /,|\|/ , 2 ) ;
2020-03-06 15:59:58 +00:00
// debug_log("BUF: " + JSON.stringify(buffer, null, 2));
2018-08-07 10:05:49 +00:00
status . machine . firmware . buffer = buffer ;
} else {
status . machine . firmware . buffer = [ ] ;
}
2018-06-19 08:07:03 +00:00
// end statusreport
}
2021-12-01 19:34:45 +00:00
function gotModals ( data ) {
// as per https://github.com/gnea/grbl/wiki/Grbl-v1.1-Commands#g---view-gcode-parser-state
// The shown g-code are the current modal states of Grbl's g-code parser.
// This may not correlate to what is executing since there are usually
// several motions queued in the planner buffer.
// [GC:G0 G54 G17 G21 G90 G94 M5 M9 T0 F0.0 S0]
// defaults
data = data . split ( /:|\[|\]/ ) [ 2 ] . split ( " " )
for ( i = 0 ; i < data . length ; i ++ ) {
2022-03-29 13:53:43 +00:00
// if (data[i] == "G0") {
// status.machine.modals.motionmode = "G0";
// }
// if (data[i] == "G1") {
// status.machine.modals.motionmode = "G1";
// }
// if (data[i] == "G2") {
// status.machine.modals.motionmode = "G2";
// }
// if (data[i] == "G3") {
// status.machine.modals.motionmode = "G3";
// }
// if (data[i] == "G38.2") {
// status.machine.modals.motionmode = "G38.2";
// }
// if (data[i] == "G38.3") {
// status.machine.modals.motionmode = "G38.3";
// }
// if (data[i] == "G38.4") {
// status.machine.modals.motionmode = "G38.4";
// }
// if (data[i] == "G38.5") {
// status.machine.modals.motionmode = "G38.5";
// }
// if (data[i] == "G80") {
// status.machine.modals.motionmode = "G80";
// }
2021-12-01 19:34:45 +00:00
// status.machine.modals.coordinatesys = "G54"; // G54, G55, G56, G57, G58, G59
if ( data [ i ] == "G54" ) {
status . machine . modals . coordinatesys = "G54" ;
}
if ( data [ i ] == "G55" ) {
status . machine . modals . coordinatesys = "G55" ;
}
if ( data [ i ] == "G56" ) {
status . machine . modals . coordinatesys = "G56" ;
}
if ( data [ i ] == "G57" ) {
status . machine . modals . coordinatesys = "G57" ;
}
if ( data [ i ] == "G58" ) {
status . machine . modals . coordinatesys = "G58" ;
}
if ( data [ i ] == "G59" ) {
status . machine . modals . coordinatesys = "G59" ;
}
// status.machine.modals.plane = "G17"; // G17, G18, G19
if ( data [ i ] == "G17" ) {
status . machine . modals . plane = "G17" ;
}
if ( data [ i ] == "G18" ) {
status . machine . modals . plane = "G18" ;
}
if ( data [ i ] == "G19" ) {
status . machine . modals . plane = "G19" ;
}
// status.machine.modals.distancemode = "G90"; // G90, G91
if ( data [ i ] == "G90" ) {
status . machine . modals . distancemode = "G90" ;
}
if ( data [ i ] == "G91" ) {
status . machine . modals . distancemode = "G91" ;
}
// status.machine.modals.arcdistmode = "G91.1"; // G91.1
if ( data [ i ] == "G91.1" ) {
status . machine . modals . arcdistmode = "G91.1" ;
}
// status.machine.modals.feedratemode = "G94"; // G93, G94
if ( data [ i ] == "G93" ) {
status . machine . modals . feedratemode = "G93" ;
}
if ( data [ i ] == "G94" ) {
status . machine . modals . feedratemode = "G94" ;
}
// status.machine.modals.unitsmode = "G21"; // G20, G21
if ( data [ i ] == "G20" ) {
status . machine . modals . unitsmode = "G20" ;
}
if ( data [ i ] == "G21" ) {
status . machine . modals . unitsmode = "G21" ;
}
// status.machine.modals.radiuscomp = "G40"; // G40
if ( data [ i ] == "G40" ) {
status . machine . modals . radiuscomp = "G40" ;
}
// status.machine.modals.tlomode = "G49"; // G43.1, G49
if ( data [ i ] == "G49" ) {
status . machine . modals . tlomode = "G49" ;
}
if ( data [ i ] == "G43.1" ) {
status . machine . modals . tlomode = "G43.1" ;
}
// status.machine.modals.programmode = "M0"; // M0, M1, M2, M30
2022-03-29 13:53:43 +00:00
// if (data[i] == "M0") {
// status.machine.modals.programmode = "M0";
// }
// if (data[i] == "M1") {
// status.machine.modals.programmode = "M1";
// }
// if (data[i] == "M2") {
// status.machine.modals.programmode = "M2";
// }
// if (data[i] == "M30") {
// status.machine.modals.programmode = "M30";
// }
2021-12-01 19:34:45 +00:00
// status.machine.modals.spindlestate = "M5"; // M3, M4, M5
if ( data [ i ] == "M3" ) {
status . machine . modals . spindlestate = "M3" ;
}
if ( data [ i ] == "M4" ) {
status . machine . modals . spindlestate = "M4" ;
}
if ( data [ i ] == "M5" ) {
status . machine . modals . spindlestate = "M5" ;
}
// status.machine.modals.coolantstate = "M9"; // M7, M8, M9
if ( data [ i ] == "M7" ) {
status . machine . modals . coolantstate = "M7" ;
}
if ( data [ i ] == "M8" ) {
status . machine . modals . coolantstate = "M8" ;
}
if ( data [ i ] == "M9" ) {
status . machine . modals . coolantstate = "M9" ;
}
2022-03-29 13:53:43 +00:00
// // status.machine.modals.tool = "0",
// if (data[i].indexOf("T") === 0) {
// status.machine.modals.tool = parseFloat(data[i].substr(1))
// }
//
// // status.machine.modals.spindle = "0"
// if (data[i].indexOf("S") === 0) {
// status.machine.modals.spindle = parseFloat(data[i].substr(1))
// }
//
// // status.machine.modals.feedrate = "0"
// if (data[i].indexOf("F") === 0) {
// status.machine.modals.feedrate = parseFloat(data[i].substr(1))
// }
2021-12-01 19:34:45 +00:00
}
} // end gotModals
2018-06-19 08:07:03 +00:00
function laserTest ( data ) {
if ( status . comms . connectionStatus > 0 ) {
data = data . split ( ',' ) ;
var power = parseFloat ( data [ 0 ] ) ;
var duration = parseInt ( data [ 1 ] ) ;
var maxS = parseFloat ( data [ 2 ] ) ;
if ( power > 0 ) {
if ( ! laserTestOn ) {
// laserTest is off
2020-03-06 15:59:58 +00:00
// debug_log('laserTest: ' + 'Power ' + power + ', Duration ' + duration + ', maxS ' + maxS);
2018-06-19 08:07:03 +00:00
if ( duration >= 0 ) {
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G1F1' ) ;
addQToEnd ( 'M3S' + parseInt ( power * maxS / 100 ) ) ;
2018-06-19 08:07:03 +00:00
laserTestOn = true ;
io . sockets . emit ( 'laserTest' , power ) ;
if ( duration > 0 ) {
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G4 P' + duration / 1000 ) ;
addQToEnd ( 'M5S0' ) ;
2018-06-19 08:07:03 +00:00
laserTestOn = false ;
}
send1Q ( ) ;
break ;
}
}
} else {
2020-03-06 15:59:58 +00:00
// debug_log('laserTest: ' + 'Power off');
2018-06-19 08:07:03 +00:00
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'M5S0' ) ;
2018-06-19 08:07:03 +00:00
send1Q ( ) ;
break ;
}
laserTestOn = false ;
io . sockets . emit ( 'laserTest' , 0 ) ;
}
}
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2018-06-19 08:07:03 +00:00
}
}
2018-08-09 16:34:51 +00:00
// queue
function BufferSpace ( firmware ) {
var total = 0 ;
var len = sentBuffer . length ;
for ( var i = 0 ; i < len ; i ++ ) {
total += sentBuffer [ i ] . length ;
}
if ( firmware == "grbl" ) {
2023-03-01 18:05:29 +00:00
if ( status . machine . firmware . rxBufferSize > 0 ) {
return ( status . machine . firmware . rxBufferSize - 1 ) - total ;
2022-04-21 12:26:03 +00:00
} else {
2023-03-01 18:05:29 +00:00
if ( status . machine . firmware . platform == "grblHAL" ) {
return GRBLHAL _RX _BUFFER _SIZE - total ;
} else {
return GRBL _RX _BUFFER _SIZE - total ;
}
2022-04-21 12:26:03 +00:00
}
2023-03-01 18:05:29 +00:00
2018-08-09 16:34:51 +00:00
}
}
function send1Q ( ) {
2019-10-16 13:57:56 +00:00
// console.time('send1Q');
2018-08-09 16:34:51 +00:00
var gcode ;
var gcodeLen = 0 ;
var spaceLeft = 0 ;
if ( status . comms . connectionStatus > 0 ) {
switch ( status . machine . firmware . type ) {
case 'grbl' :
if ( ( gcodeQueue . length - queuePointer ) > 0 && ! status . comms . blocked && ! status . comms . paused ) {
spaceLeft = BufferSpace ( 'grbl' ) ;
2021-12-02 14:40:12 +00:00
// Do we have enough space in the buffer?
2018-08-09 16:34:51 +00:00
if ( gcodeQueue [ queuePointer ] . length < spaceLeft ) {
gcode = gcodeQueue [ queuePointer ] ;
queuePointer ++ ;
sentBuffer . push ( gcode ) ;
2020-06-23 17:55:56 +00:00
machineSend ( gcode + '\n' , false ) ;
2020-03-06 15:59:58 +00:00
// debug_log('Sent: ' + gcode + ' Q: ' + (gcodeQueue.length - queuePointer) + ' Bspace: ' + (spaceLeft - gcode.length - 1));
2018-08-09 16:34:51 +00:00
} else {
status . comms . blocked = true ;
}
}
break ;
}
if ( queuePointer >= gcodeQueue . length ) {
2021-03-30 19:42:35 +00:00
if ( gcodeQueue . length > 1 ) {
var data = {
completed : true ,
failed : false ,
jobCompletedMsg : jobCompletedMsg ,
jobStartTime : jobStartTime ,
jobEndTime : new Date ( ) . getTime ( )
}
io . sockets . emit ( 'jobComplete' , data ) ;
} else {
var data = {
completed : true ,
failed : true ,
jobCompletedMsg : jobCompletedMsg ,
jobStartTime : jobStartTime ,
jobEndTime : new Date ( ) . getTime ( )
}
io . sockets . emit ( 'jobComplete' , data ) ;
}
2019-09-13 18:39:59 +00:00
status . comms . connectionStatus = 2 ; // finished
2018-08-09 16:34:51 +00:00
clearInterval ( queueCounter ) ;
2024-04-17 13:22:42 +00:00
if ( jogWindow ) {
jogWindow . setProgressBar ( 0 ) ;
}
2018-08-09 16:34:51 +00:00
gcodeQueue . length = 0 ; // Dump the Queye
queuePointer = 0 ;
status . comms . connectionStatus = 2 ; // finished
2020-03-06 15:59:58 +00:00
jobCompletedMsg = ""
2020-12-15 17:06:42 +00:00
jobStartTime = false ;
2018-08-09 16:34:51 +00:00
}
2018-09-27 15:00:49 +00:00
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'Not Connected' )
2018-08-09 16:34:51 +00:00
}
2019-10-16 13:57:56 +00:00
// console.timeEnd('send1Q');
2018-08-09 16:34:51 +00:00
}
2022-03-29 13:53:43 +00:00
var modalCommands = [ 'G54' , 'G55' , 'G56' , 'G57' , 'G58' , 'G59' , 'G17' , 'G18' , 'G19' , 'G90' , 'G91' , 'G91.1' , 'G93' , 'G94' , 'G20' , 'G21' , 'G40' , 'G43.1' , 'G49' , 'M0' , 'M1' , 'M2' , 'M30' , 'M3' , 'M4' , 'M5' , 'M7' , 'M8' , 'M9' ]
2024-04-15 13:26:33 +00:00
var modalCommandsRegExp = new RegExp ( modalCommands . join ( "|" ) ) ;
2022-03-29 13:53:43 +00:00
2018-08-09 16:34:51 +00:00
function addQToEnd ( gcode ) {
2020-03-06 15:59:58 +00:00
// debug_log('added ' + gcode)
2018-08-09 16:34:51 +00:00
gcodeQueue . push ( gcode ) ;
2022-03-29 13:53:43 +00:00
// if (gcode.indexOf("G54") != -1 || gcode.indexOf("G55") != -1 || gcode.indexOf("G56") != -1 || gcode.indexOf("G57") != -1 || gcode.indexOf("G58") != -1 || gcode.indexOf("G59") != -1) {
// gcodeQueue.push("$G");
// }
2022-04-21 12:26:03 +00:00
var testGcode = gcode . toUpperCase ( )
2022-04-21 20:04:00 +00:00
if ( testGcode . indexOf ( "$H" ) != - 1 ) {
status . machine . modals . homedRecently = true ;
}
2022-12-20 18:50:36 +00:00
if ( testGcode == "$CD" ) {
fluidncConfig = "" ; // empty string
}
2024-04-15 13:26:33 +00:00
if ( ! gcode . startsWith ( "$J=" ) && modalCommandsRegExp . test ( testGcode ) ) {
2022-03-29 13:53:43 +00:00
gcodeQueue . push ( "$G" ) ;
}
if ( gcode . match ( /T([\d.]+)/i ) ) {
2021-12-02 14:40:12 +00:00
gcodeQueue . push ( "$G" ) ;
}
2022-12-20 18:50:36 +00:00
2018-08-09 16:34:51 +00:00
}
function addQToStart ( gcode ) {
gcodeQueue . unshift ( gcode ) ;
}
function addQRealtime ( gcode ) {
// realtime command skip the send1Q as it doesnt respond with an ok
2020-06-23 17:55:56 +00:00
machineSend ( gcode , true ) ;
2018-08-09 16:34:51 +00:00
}
2022-09-22 17:27:29 +00:00
function showJogWindow ( ) {
if ( jogWindow === null ) {
createJogWindow ( ) ;
}
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
}
2018-08-09 16:34:51 +00:00
// Electron
2018-06-19 08:07:03 +00:00
function isElectron ( ) {
if ( typeof window !== 'undefined' && window . process && window . process . type === 'renderer' ) {
return true ;
}
if ( typeof process !== 'undefined' && process . versions && ! ! process . versions . electron ) {
return true ;
}
return false ;
}
2018-08-23 20:09:27 +00:00
if ( isElectron ( ) ) {
2019-04-15 17:31:30 +00:00
const gotTheLock = electronApp . requestSingleInstanceLock ( )
2019-05-06 14:31:13 +00:00
var lauchGUI = true ;
2019-04-15 17:31:30 +00:00
if ( ! gotTheLock ) {
2020-03-06 15:59:58 +00:00
debug _log ( "Already running! Check the System Tray" )
2018-08-23 20:09:27 +00:00
electronApp . exit ( 0 ) ;
electronApp . quit ( ) ;
2019-04-15 17:31:30 +00:00
} else {
electronApp . on ( 'second-instance' , ( event , commandLine , workingDirectory ) => {
//Someone tried to run a second instance, we should focus our window.
2020-03-06 15:59:58 +00:00
// debug_log('SingleInstance')
2020-03-30 15:26:11 +00:00
function checkFileType ( fileName ) {
var fileNameLC = fileName . toLowerCase ( ) ;
if ( fileNameLC . endsWith ( '.obc' ) || fileName . endsWith ( '.gcode' ) || fileName . endsWith ( '.gc' ) || fileName . endsWith ( '.tap' ) || fileName . endsWith ( '.nc' ) || fileName . endsWith ( '.cnc' ) ) {
return fileName ;
}
}
debug _log ( commandLine )
2019-05-06 14:31:13 +00:00
lauchGUI = true ;
2020-03-30 15:26:11 +00:00
var openFilePath = commandLine . find ( checkFileType ) ;
2019-04-15 17:31:30 +00:00
if ( openFilePath !== "" ) {
readFile ( openFilePath ) ;
2019-05-02 18:51:30 +00:00
if ( openFilePath !== undefined ) {
2019-05-02 17:17:41 +00:00
if ( openFilePath . endsWith ( '.obc' ) ) {
2019-05-06 14:31:13 +00:00
lauchGUI = false ;
2019-04-30 12:13:27 +00:00
} else {
2019-05-06 14:31:13 +00:00
lauchGUI = true ;
2019-04-30 12:13:27 +00:00
}
2019-04-29 17:26:29 +00:00
}
}
2019-05-06 14:31:13 +00:00
if ( lauchGUI ) {
2022-09-22 17:27:29 +00:00
showJogWindow ( )
2019-05-06 14:31:13 +00:00
}
2019-04-15 17:31:30 +00:00
} )
// Create myWindow, load the rest of the app, etc...
2023-03-02 18:30:08 +00:00
electronApp . on ( 'ready' , ( ) => {
2023-02-23 19:25:32 +00:00
if ( process . platform == 'win32' ) {
2023-02-28 18:40:11 +00:00
// Don't show window - sit in Tray
2023-02-23 19:25:32 +00:00
} else {
showJogWindow ( ) // Macos and Linux - launch GUI
}
} )
2018-06-19 20:25:40 +00:00
}
2018-08-23 20:09:27 +00:00
if ( electronApp ) {
// Module to create native browser window.
2018-06-25 17:25:19 +00:00
2018-08-23 20:09:27 +00:00
function createApp ( ) {
createTrayIcon ( ) ;
2019-05-21 12:09:53 +00:00
if ( process . platform == 'darwin' ) {
2020-03-06 15:59:58 +00:00
debug _log ( "Creating MacOS Menu" ) ;
2019-06-06 19:11:48 +00:00
createMenu ( ) ;
status . driver . operatingsystem = 'macos' ;
2019-05-21 12:09:53 +00:00
}
2018-08-29 08:11:14 +00:00
if ( process . platform == 'win32' && process . argv . length >= 2 ) {
var openFilePath = process . argv [ 1 ] ;
if ( openFilePath !== "" ) {
2020-03-06 15:59:58 +00:00
debug _log ( "path" + openFilePath ) ;
2018-08-29 08:11:14 +00:00
readFile ( openFilePath ) ;
}
2019-07-23 19:04:50 +00:00
status . driver . operatingsystem = 'windows' ;
2018-08-29 08:11:14 +00:00
}
if ( process . platform == 'darwin' || uploadedgcode . length > 1 ) {
2022-09-22 17:27:29 +00:00
showJogWindow ( )
2018-08-23 20:09:27 +00:00
}
2018-08-29 08:11:14 +00:00
2018-08-23 20:09:27 +00:00
}
2018-06-25 17:25:19 +00:00
2019-05-21 12:09:53 +00:00
function createMenu ( ) {
var template = [ {
label : "Application" ,
submenu : [ {
label : "Quit" ,
accelerator : "Command+Q" ,
click : function ( ) {
if ( appIcon ) {
appIcon . destroy ( ) ;
}
electronApp . exit ( 0 ) ;
}
} ]
} , {
label : "Edit" ,
submenu : [ {
label : "Cut" ,
accelerator : "CmdOrCtrl+X" ,
selector : "cut:"
} ,
{
label : "Copy" ,
accelerator : "CmdOrCtrl+C" ,
selector : "copy:"
} ,
{
label : "Paste" ,
accelerator : "CmdOrCtrl+V" ,
selector : "paste:"
} ,
{
label : "Select All" ,
accelerator : "CmdOrCtrl+A" ,
selector : "selectAll:"
}
]
2021-03-19 16:02:04 +00:00
} , {
label : "View" ,
submenu : [ {
label : "Reload" ,
accelerator : "F5" ,
click : ( item , focusedWindow ) => {
if ( focusedWindow ) {
// on reload, start fresh and close any old
// open secondary windows
if ( focusedWindow . id === 1 ) {
BrowserWindow . getAllWindows ( ) . forEach ( win => {
if ( win . id > 1 ) win . close ( ) ;
} ) ;
}
focusedWindow . reload ( ) ;
}
}
} ,
{
label : "Toggle Dev Tools" ,
accelerator : "F12" ,
click : ( ) => {
jogWindow . webContents . toggleDevTools ( ) ;
}
}
]
2019-05-21 12:09:53 +00:00
} ] ;
Menu . setApplicationMenu ( Menu . buildFromTemplate ( template ) ) ;
}
2018-08-23 20:09:27 +00:00
function createTrayIcon ( ) {
if ( process . platform !== 'darwin' ) {
appIcon = new Tray (
nativeImage . createFromPath ( iconPath )
)
const contextMenu = Menu . buildFromTemplate ( [ {
2018-11-20 16:08:34 +00:00
label : 'Open User Interface (GUI)' ,
click ( ) {
2020-03-06 15:59:58 +00:00
// debug_log("Clicked Systray")
2022-09-22 17:27:29 +00:00
showJogWindow ( )
2018-11-20 16:08:34 +00:00
}
2018-11-23 16:13:16 +00:00
} , {
label : 'Quit OpenBuilds CONTROL (Disables all integration until started again)' ,
2018-08-23 20:09:27 +00:00
click ( ) {
2019-01-16 10:18:46 +00:00
if ( appIcon ) {
appIcon . destroy ( ) ;
}
2018-08-23 20:09:27 +00:00
electronApp . exit ( 0 ) ;
}
} ] )
2019-01-16 10:18:46 +00:00
if ( appIcon ) {
appIcon . on ( 'click' , function ( ) {
2020-03-06 15:59:58 +00:00
// debug_log("Clicked Systray")
2022-09-22 17:27:29 +00:00
showJogWindow ( )
2019-01-16 10:18:46 +00:00
} )
2019-01-16 10:56:25 +00:00
}
2018-08-16 12:50:11 +00:00
2019-01-16 10:18:46 +00:00
if ( appIcon ) {
appIcon . on ( 'balloon-click' , function ( ) {
2020-03-06 15:59:58 +00:00
// debug_log("Clicked Systray")
2022-09-22 17:27:29 +00:00
showJogWindow ( )
2019-01-16 10:18:46 +00:00
} )
}
2018-06-19 20:25:40 +00:00
2018-08-23 20:09:27 +00:00
// Call this again for Linux because we modified the context menu
2019-01-16 10:18:46 +00:00
if ( appIcon ) {
appIcon . setContextMenu ( contextMenu )
}
2018-08-06 17:19:25 +00:00
2019-01-16 10:18:46 +00:00
if ( appIcon ) {
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "OpenBuilds CONTROL Started" ,
2021-12-27 14:59:14 +00:00
// content: "OpenBuilds CONTROL has started successfully: Active on " + ip.address() + ":" + config.webPort
content : "OpenBuilds CONTROL has started successfully"
2019-01-16 10:18:46 +00:00
} )
}
2018-08-23 20:09:27 +00:00
} else {
const dockMenu = Menu . buildFromTemplate ( [ {
2018-11-23 16:13:16 +00:00
label : 'Quit OpenBuilds CONTROL (Disables all integration until started again)' ,
2018-08-23 20:09:27 +00:00
click ( ) {
// appIcon.destroy();
electronApp . exit ( 0 ) ;
}
} ] )
electronApp . dock . setMenu ( dockMenu )
} ;
2018-06-19 20:25:40 +00:00
2018-08-23 20:09:27 +00:00
}
2018-06-19 20:25:40 +00:00
2018-08-23 20:09:27 +00:00
function createJogWindow ( ) {
// Create the browser window.
jogWindow = new BrowserWindow ( {
2018-09-14 17:35:54 +00:00
// 1366 * 768 == minimum to cater for
2022-11-01 20:21:24 +00:00
width : 1000 ,
2018-09-06 21:08:06 +00:00
height : 850 ,
2018-08-23 20:09:27 +00:00
fullscreen : false ,
center : true ,
resizable : true ,
2021-03-16 19:46:51 +00:00
maximizable : true ,
2018-11-23 16:13:16 +00:00
title : "OpenBuilds CONTROL " ,
2018-08-23 20:09:27 +00:00
frame : false ,
autoHideMenuBar : true ,
2020-08-10 14:27:13 +00:00
//icon: '/app/favicon.png',
icon : nativeImage . createFromPath (
path . join ( _ _dirname , "/app/favicon.png" )
) ,
2018-10-11 17:34:45 +00:00
webgl : true ,
experimentalFeatures : true ,
experimentalCanvasFeatures : true ,
offscreen : true ,
2023-02-22 19:54:49 +00:00
backgroundColor : "#fff" ,
webPreferences : {
nodeIntegration : true ,
contextIsolation : false
}
2018-08-23 20:09:27 +00:00
} ) ;
2018-06-19 20:25:40 +00:00
2018-08-23 20:09:27 +00:00
jogWindow . setOverlayIcon ( nativeImage . createFromPath ( iconPath ) , 'Icon' ) ;
var ipaddr = ip . address ( ) ;
// jogWindow.loadURL(`//` + ipaddr + `:3000/`)
2023-04-27 18:45:28 +00:00
jogWindow . loadURL ( ` http://localhost: ${ config . webPort } / ` ) ;
2020-08-10 16:34:10 +00:00
//jogWindow.webContents.openDevTools()
2018-07-26 20:22:07 +00:00
2018-08-23 20:09:27 +00:00
jogWindow . on ( 'close' , function ( event ) {
2019-01-10 17:42:08 +00:00
if ( ! forceQuit ) {
jogWindow . hide ( ) ;
return false ;
}
2018-08-23 20:09:27 +00:00
} ) ;
2018-06-19 08:07:03 +00:00
2018-08-23 20:09:27 +00:00
// Emitted when the window is closed.
jogWindow . on ( 'closed' , function ( ) {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
jogWindow = null ;
} ) ;
jogWindow . once ( 'ready-to-show' , ( ) => {
2022-09-22 17:27:29 +00:00
showJogWindow ( )
2018-08-23 20:09:27 +00:00
} )
}
2018-06-19 08:07:03 +00:00
2018-08-23 20:09:27 +00:00
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
electronApp . on ( 'ready' , createApp ) ;
2018-06-19 08:07:03 +00:00
2019-01-10 17:42:08 +00:00
electronApp . on ( 'before-quit' , function ( ) {
forceQuit = true ;
} )
2018-08-23 20:09:27 +00:00
electronApp . on ( 'will-quit' , function ( event ) {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
2018-11-05 16:16:17 +00:00
// We don't take that route, we close it completely
2019-01-10 17:45:46 +00:00
if ( appIcon ) {
2019-01-10 17:42:08 +00:00
appIcon . destroy ( ) ;
}
2018-11-05 16:16:17 +00:00
electronApp . exit ( 0 ) ;
2018-08-23 20:09:27 +00:00
} ) ;
2018-07-24 15:25:35 +00:00
2018-08-23 20:09:27 +00:00
// Quit when all windows are closed.
electronApp . on ( 'window-all-closed' , function ( ) {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
2019-01-16 10:18:46 +00:00
if ( appIcon ) {
appIcon . destroy ( ) ;
}
2018-11-05 16:16:17 +00:00
electronApp . exit ( 0 ) ;
2018-08-23 20:09:27 +00:00
} ) ;
2018-06-19 08:07:03 +00:00
2018-08-23 20:09:27 +00:00
electronApp . on ( 'activate' , function ( ) {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if ( mainWindow === null ) {
createApp ( ) ;
}
} ) ;
2018-06-19 20:25:40 +00:00
2018-08-23 20:09:27 +00:00
// Autostart on Login
2023-03-02 18:30:08 +00:00
if ( process . platform == 'win32' ) {
2019-01-10 17:45:46 +00:00
electronApp . setLoginItemSettings ( {
openAtLogin : true ,
args : [ ]
} )
}
2018-08-23 20:09:27 +00:00
}
2021-05-13 13:50:55 +00:00
} else { // if its not running under Electron, lets get Chrome up.
2019-06-06 18:05:30 +00:00
var isPi = require ( 'detect-rpi' ) ;
if ( isPi ( ) ) {
2020-09-01 13:20:57 +00:00
DEBUG = true ;
2020-03-06 15:59:58 +00:00
debug _log ( 'Running on Raspberry Pi!' ) ;
2019-06-06 19:11:48 +00:00
status . driver . operatingsystem = 'rpi'
startChrome ( ) ;
2019-06-06 18:05:30 +00:00
} else {
2020-03-06 15:59:58 +00:00
debug _log ( "Running under NodeJS..." ) ;
2019-06-06 18:05:30 +00:00
}
2018-06-29 13:01:16 +00:00
}
2018-08-29 08:11:14 +00:00
2020-10-12 15:07:38 +00:00
function stop ( data ) {
//data = { stop: false, jog: false, abort: true}
2019-01-21 12:46:21 +00:00
if ( status . comms . connectionStatus > 0 ) {
status . comms . paused = true ;
2020-03-06 15:59:58 +00:00
debug _log ( 'STOP' ) ;
2019-01-21 12:46:21 +00:00
switch ( status . machine . firmware . type ) {
case 'grbl' :
2020-10-12 15:07:38 +00:00
if ( data . jog ) {
2019-04-29 17:26:29 +00:00
addQRealtime ( String . fromCharCode ( 0x85 ) ) ; // canceljog
2020-03-06 15:59:58 +00:00
debug _log ( 'Sent: 0x85 Jog Cancel' ) ;
2020-06-23 17:55:56 +00:00
debug _log ( queuePointer , gcodeQueue )
2020-10-12 15:07:38 +00:00
}
2020-10-21 18:48:18 +00:00
if ( ! data . abort && ! data . jog ) { // pause motion first.
2019-04-29 17:26:29 +00:00
addQRealtime ( '!' ) ; // hold
2020-03-06 15:59:58 +00:00
debug _log ( 'Sent: !' ) ;
2019-04-29 17:26:29 +00:00
}
2020-10-12 15:07:38 +00:00
2019-01-21 12:46:21 +00:00
if ( status . machine . firmware . version === '1.1d' ) {
addQRealtime ( String . fromCharCode ( 0x9E ) ) ; // Stop Spindle/Laser
2020-03-06 15:59:58 +00:00
debug _log ( 'Sent: Code(0x9E)' ) ;
2019-01-21 12:46:21 +00:00
}
2020-10-12 15:07:38 +00:00
2020-03-06 15:59:58 +00:00
debug _log ( 'Cleaning Queue' ) ;
2020-10-12 15:07:38 +00:00
if ( ! data . jog ) {
setTimeout ( function ( ) {
addQRealtime ( String . fromCharCode ( 0x18 ) ) ; // ctrl-x
debug _log ( 'Sent: Code(0x18)' ) ;
} , 200 ) ;
2019-04-18 14:23:51 +00:00
}
2019-01-21 12:46:21 +00:00
status . comms . connectionStatus = 2 ;
break ;
}
clearInterval ( queueCounter ) ;
2024-04-17 13:22:42 +00:00
if ( jogWindow ) {
jogWindow . setProgressBar ( 0 ) ;
}
2019-01-21 12:46:21 +00:00
status . comms . queue = 0
queuePointer = 0 ;
gcodeQueue . length = 0 ; // Dump the queue
sentBuffer . length = 0 ; // Dump the queue
// sentBuffer.length = 0; // Dump bufferSizes
laserTestOn = false ;
status . comms . blocked = false ;
status . comms . paused = false ;
status . comms . runStatus = 'Stopped' ;
2020-04-17 21:07:39 +00:00
status . comms . alarm = "" ;
2019-01-21 12:46:21 +00:00
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2019-01-21 12:46:21 +00:00
}
}
function pause ( ) {
2020-06-23 17:55:56 +00:00
if ( status . comms . connectionStatus == 3 ) {
2019-01-21 12:46:21 +00:00
status . comms . paused = true ;
2020-03-06 15:59:58 +00:00
debug _log ( 'PAUSE' ) ;
2019-01-21 12:46:21 +00:00
switch ( status . machine . firmware . type ) {
case 'grbl' :
addQRealtime ( '!' ) ; // Send hold command
2020-03-06 15:59:58 +00:00
debug _log ( 'Sent: !' ) ;
2019-01-21 12:46:21 +00:00
if ( status . machine . firmware . version === '1.1d' ) {
addQRealtime ( String . fromCharCode ( 0x9E ) ) ; // Stop Spindle/Laser
2020-03-06 15:59:58 +00:00
debug _log ( 'Sent: Code(0x9E)' ) ;
2019-01-21 12:46:21 +00:00
}
break ;
}
status . comms . runStatus = 'Paused' ;
status . comms . connectionStatus = 4 ;
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2019-01-21 12:46:21 +00:00
}
}
function unpause ( ) {
if ( status . comms . connectionStatus > 0 ) {
2020-03-06 15:59:58 +00:00
debug _log ( 'UNPAUSE' ) ;
2019-01-21 12:46:21 +00:00
switch ( status . machine . firmware . type ) {
case 'grbl' :
addQRealtime ( '~' ) ; // Send resume command
2020-03-06 15:59:58 +00:00
debug _log ( 'Sent: ~' ) ;
2019-01-21 12:46:21 +00:00
break ;
}
status . comms . paused = false ;
status . comms . blocked = false ;
setTimeout ( function ( ) {
send1Q ( ) ; // restart queue
} , 200 ) ;
status . comms . runStatus = 'Resuming' ;
status . comms . connectionStatus = 3 ;
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'ERROR: Machine connection not open!' ) ;
2019-01-21 12:46:21 +00:00
}
}
2018-08-29 08:11:14 +00:00
2019-04-29 17:26:29 +00:00
function isJson ( item ) {
item = typeof item !== "string" ?
JSON . stringify ( item ) :
item ;
try {
item = JSON . parse ( item ) ;
} catch ( e ) {
return false ;
}
if ( typeof item === "object" && item !== null ) {
return true ;
}
return false ;
}
2019-06-06 19:19:49 +00:00
function startChrome ( ) {
2019-06-06 19:11:48 +00:00
if ( status . driver . operatingsystem == 'rpi' ) {
2019-06-06 19:21:36 +00:00
const {
spawn
} = require ( 'child_process' ) ;
2023-04-27 18:45:28 +00:00
const chrome = spawn ( 'chromium-browser' , [ ` -app=http://127.0.0.1: ${ config . webPort } ` ] ) ;
2019-06-06 19:25:14 +00:00
chrome . on ( 'close' , ( code ) => {
2020-03-06 15:59:58 +00:00
debug _log ( ` Chromium process exited with code ${ code } ` ) ;
2020-09-01 13:20:57 +00:00
process . exit ( 0 ) ;
2019-06-06 19:25:14 +00:00
} ) ;
2019-06-06 19:16:43 +00:00
} else {
2020-03-06 15:59:58 +00:00
debug _log ( 'Not a Raspberry Pi. Please use Electron Instead' ) ;
2019-06-06 19:11:48 +00:00
}
}
2020-11-20 15:50:37 +00:00
// Interface Programming
2020-11-23 19:06:28 +00:00
// grab latest firmware.bin for Interface on startup
2021-02-01 16:36:07 +00:00
var file = fs . createWriteStream ( path . join ( uploadsDir , "firmware.bin" ) ) ;
2020-11-23 19:06:28 +00:00
https . get ( "https://raw.githubusercontent.com/OpenBuilds/firmware/main/interface/firmware.bin" , function ( response ) {
response . pipe ( file ) ;
file . on ( 'finish' , function ( ) {
file . close ( function ( ) {
const options = {
hostname : 'raw.githubusercontent.com' ,
port : 443 ,
path : '/OpenBuilds/firmware/main/interface/version.txt' ,
method : 'GET'
}
const req = https . request ( options , res => {
console . log ( ` statusCode: ${ res . statusCode } ` )
res . on ( 'data' , d => {
status . interface . firmware . availVersion = parseFloat ( d . toString ( ) )
2020-11-24 16:30:37 +00:00
var output = {
'command' : 'interface firmware update tool' ,
2020-12-16 08:20:46 +00:00
'response' : "Downloaded firmware.bin v" + status . interface . firmware . availVersion ,
'type' : 'info'
2020-11-24 16:30:37 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2024-04-23 18:57:55 +00:00
debug _log ( JSON . stringify ( output ) ) ;
2020-11-24 16:30:37 +00:00
2020-11-23 19:06:28 +00:00
} )
} )
req . on ( 'error' , error => {
2020-11-24 16:30:37 +00:00
var output = {
'command' : 'interface firmware update tool' ,
2020-12-16 08:20:46 +00:00
'response' : "Unable to download latest firmware.bin" ,
'type' : 'error'
2020-11-24 16:30:37 +00:00
}
io . sockets . emit ( 'data' , output ) ;
2020-11-23 19:06:28 +00:00
} )
req . end ( )
2020-11-24 16:30:37 +00:00
2020-11-23 19:06:28 +00:00
} ) ;
} ) ;
} )
2021-02-01 16:36:07 +00:00
var firmwareImagePath = path . join ( uploadsDir , './firmware.bin' ) ;
2020-11-20 15:50:37 +00:00
var spawn = require ( 'child_process' ) . spawn ;
const multer = require ( 'multer' ) ;
const storage = multer . diskStorage ( {
destination : function ( req , file , cb ) {
cb ( null , uploadsDir ) ;
} ,
// By default, multer removes file extensions so let's add them back
filename : function ( req , file , cb ) {
cb ( null , file . fieldname + '-' + new Date ( ) . toJSON ( ) . replace ( new RegExp ( ':' , 'g' ) , '.' ) + path . extname ( file . originalname ) ) ;
}
} ) ;
function flashInterface ( data ) {
status . comms . connectionStatus = 6 ;
var port = data . port ;
var file = data . file ;
var board = data . board
2023-03-08 19:52:55 +00:00
console . log ( "Flashing Interface on " + port + " with file: " + file )
2020-11-20 15:50:37 +00:00
// var data = {
// 'port': port,
// 'string': debugString
// }
// io.sockets.emit("progStatus", data);
//
//for (let i = 0; i < ports.length; i++) {
var data = {
'port' : port ,
'string' : "[Starting...]"
}
io . sockets . emit ( "progStatus" , data ) ;
var esptool _opts = [
'--chip' , 'esp32' ,
'--port' , port ,
'--baud' , '921600' ,
'--before' , 'default_reset' ,
'--after' , 'hard_reset' ,
'write_flash' ,
'-z' ,
'--flash_mode' , 'dio' ,
'--flash_freq' , '80m' ,
'--flash_size' , 'detect' ,
2023-03-08 19:24:54 +00:00
'0xe000' , path . join ( _ _dirname , "./boot_app0.bin" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) ,
'0x1000' , path . join ( _ _dirname , "./bootloader_qio_80m.bin" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) ,
'0x10000' , path . resolve ( firmwareImagePath ) . replace ( 'app.asar' , 'app.asar.unpacked' ) ,
'0x8000' , path . join ( _ _dirname , "./firmware.partitions.bin" ) . replace ( 'app.asar' , 'app.asar.unpacked' )
2020-11-20 15:50:37 +00:00
] ;
2023-03-08 18:48:09 +00:00
if ( process . platform == 'linux' ) {
2023-03-08 18:09:13 +00:00
//path.join(__dirname, "..", "lib", "resources", "vad.onnx"),
fs . chmodSync ( path . join ( _ _dirname , "./esptool.py" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) , 0o755 ) ;
var child = spawn ( path . join ( _ _dirname , "./esptool.py" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) , esptool _opts ) ;
2021-02-26 14:28:44 +00:00
} else if ( process . platform == 'win32' ) {
2023-03-08 18:09:13 +00:00
var child = spawn ( path . join ( _ _dirname , "./esptool.exe" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) , esptool _opts ) ;
2023-03-08 18:48:09 +00:00
} else if ( process . platform == 'darwin' ) {
2023-03-08 19:52:55 +00:00
fs . chmodSync ( path . join ( _ _dirname , "./esptool.py" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) , 0o755 ) ;
var child = spawn ( path . join ( _ _dirname , "./esptool.py" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) , esptool _opts ) ;
2021-02-26 14:28:44 +00:00
}
2020-11-20 15:50:37 +00:00
child . stdout . on ( 'data' , function ( data ) {
var debugString = data . toString ( ) ;
console . log ( debugString )
var data = {
'port' : port ,
'string' : debugString
}
io . sockets . emit ( "progStatus" , data ) ;
status . comms . connectionStatus = 6 ;
} ) ;
child . stderr . on ( 'data' , function ( data ) {
var debugString = data . toString ( ) ;
console . log ( debugString )
var data = {
'port' : port ,
'string' : debugString
}
io . sockets . emit ( "progStatus" , data ) ;
status . comms . connectionStatus = 6 ;
} ) ;
child . on ( 'close' , ( code ) => {
var data = {
'port' : port ,
2021-02-02 19:27:49 +00:00
'string' : ` [exit: ` + code + ` ] ` ,
2020-11-20 15:50:37 +00:00
'code' : code
}
io . sockets . emit ( "progStatus" , data ) ;
status . comms . connectionStatus = 0 ;
} ) ;
}
// end Interface Programming
2022-07-06 20:08:38 +00:00
function flashGrblHal ( data ) {
console . log ( JSON . stringify ( data ) )
status . comms . connectionStatus = 6 ;
var port = data . port ;
var file = data . file ;
var customImg = data . customImg
2022-11-01 20:21:24 +00:00
var erase = data . erase
2022-07-06 20:08:38 +00:00
if ( customImg == true ) {
var firmwarePath = firmwareImagePath
} else {
var firmwarePath = path . join ( _ _dirname , file )
}
2023-03-08 19:52:55 +00:00
console . log ( "Flashing BlackBoxX32 on " + port + " with file: " + path . resolve ( firmwarePath ) . replace ( 'app.asar' , 'app.asar.unpacked' ) )
2022-07-06 20:08:38 +00:00
var data = {
'port' : port ,
'string' : "[Starting...]"
}
io . sockets . emit ( "progStatus" , data ) ;
var esptool _opts = [
'--port' , port ,
'--baud' , '460800' ,
'--before' , 'default_reset' ,
'--after' , 'hard_reset' ,
'--chip' , 'esp32' ,
'write_flash' ,
'--flash_mode' , 'dio' ,
'--flash_size' , 'detect' ,
'--flash_freq' , '40m' ,
2023-03-08 19:24:54 +00:00
'0x1000' , path . join ( _ _dirname , "./grblhal-bootloader.bin" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) ,
'0x8000' , path . join ( _ _dirname , "./grblhal-partition-table.bin" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) ,
'0x10000' , path . resolve ( firmwarePath ) . replace ( 'app.asar' , 'app.asar.unpacked' )
2022-07-06 20:08:38 +00:00
] ;
2022-11-01 20:21:24 +00:00
if ( erase == true ) {
esptool _opts . push ( '--erase-all' ) ;
}
2023-03-08 19:24:54 +00:00
if ( process . platform == 'linux' ) {
fs . chmodSync ( path . join ( _ _dirname , "./esptool.py" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) , 0o755 ) ;
var child = spawn ( path . join ( _ _dirname , "./esptool.py" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) , esptool _opts ) ;
2022-07-06 20:08:38 +00:00
} else if ( process . platform == 'win32' ) {
2023-03-08 19:24:54 +00:00
var child = spawn ( path . join ( _ _dirname , "./esptool.exe" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) , esptool _opts ) ;
} else if ( process . platform == 'darwin' ) {
2024-05-07 17:55:51 +00:00
console . log ( "Running on MacOS" )
2023-03-08 19:52:55 +00:00
fs . chmodSync ( path . join ( _ _dirname , "./esptool.py" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) , 0o755 ) ;
var child = spawn ( path . join ( _ _dirname , "./esptool.py" ) . replace ( 'app.asar' , 'app.asar.unpacked' ) , esptool _opts ) ;
2022-07-06 20:08:38 +00:00
}
2023-03-08 19:24:54 +00:00
2022-07-06 20:08:38 +00:00
child . stdout . on ( 'data' , function ( data ) {
var debugString = data . toString ( ) ;
console . log ( debugString )
var data = {
'port' : port ,
'string' : debugString
}
io . sockets . emit ( "progStatus" , data ) ;
status . comms . connectionStatus = 6 ;
} ) ;
child . stderr . on ( 'data' , function ( data ) {
var debugString = data . toString ( ) ;
console . log ( debugString )
var data = {
'port' : port ,
'string' : debugString
}
io . sockets . emit ( "progStatus" , data ) ;
status . comms . connectionStatus = 6 ;
} ) ;
child . on ( 'close' , ( code ) => {
var data = {
'port' : port ,
'string' : ` [exit: ` + code + ` ] ` ,
'code' : code
}
io . sockets . emit ( "progStatus" , data ) ;
status . comms . connectionStatus = 0 ;
} ) ;
}
// end BlackBoxX32 Programming
// LAN Scanner for BlackBox X32, Interface, SwitchBlox etc //
2022-11-01 20:21:24 +00:00
function scanForTelnetDevices ( range ) {
//var localNetwork = ip.address().split('.');
//var network = localNetwork[0] + '.' + localNetwork[1] + '.' + localNetwork[2];
//var range = network + ".1-" + network + ".254"
2022-07-06 20:08:38 +00:00
var networkDevices = [ ]
oldiplist = status . comms . interfaces . networkDevices ;
2022-11-01 20:21:24 +00:00
const telnetScanOptions = {
2022-07-06 20:08:38 +00:00
target : range ,
port : '23' ,
status : 'TROU' , // Timeout, Refused, Open, Unreachable
banner : true
} ;
2022-11-01 20:21:24 +00:00
var output = {
'command' : 'network' ,
'response' : "Starting network scan for: " + telnetScanOptions . target ,
'type' : 'success'
}
io . sockets . emit ( 'data' , output ) ;
new Evilscan ( telnetScanOptions , ( err , scan ) => {
2022-07-06 20:08:38 +00:00
if ( err ) {
2022-11-01 20:21:24 +00:00
var output = {
'command' : 'network' ,
'response' : "Network Scan error: " + err ,
'type' : 'success'
}
io . sockets . emit ( 'data' , output ) ;
2022-07-06 20:08:38 +00:00
//console.log(err);
return ;
}
scan . on ( 'result' , data => {
// fired when item is matching options
//console.log(data);
if ( data . status == "open" ) {
var type = false ;
if ( data . banner . indexOf ( "GrblHAL" ) != - 1 ) {
type = "grblHAL"
} else if ( data . banner . indexOf ( "Grbl" ) != - 1 ) {
type = "grbl"
}
networkDevices . push ( {
ip : data . ip ,
type : type ,
banner : data . banner
} )
}
} ) ;
scan . on ( 'error' , err => {
//throw new Error(data.toString());
} ) ;
scan . on ( 'done' , ( ) => {
// finished !
networkDevices . sort ( ( a , b ) => {
return a . ip . split ( '.' ) [ 3 ] - b . ip . split ( '.' ) [ 3 ] ;
} ) ;
status . comms . interfaces . networkDevices = networkDevices ;
if ( ! _ . isEqual ( status . comms . interfaces . networkDevices , oldiplist ) ) {
var newTelnetPorts = _ . differenceWith ( status . comms . interfaces . networkDevices , oldiplist , _ . isEqual )
if ( newTelnetPorts . length > 0 ) {
debug _log ( "Detected new device: " + newTelnetPorts [ 0 ] . ip ) ;
}
var removedTelnetPorts = _ . differenceWith ( oldiplist , status . comms . interfaces . networkDevices , _ . isEqual )
if ( removedTelnetPorts . length > 0 ) {
debug _log ( "No longer detecting device: " + removedTelnetPorts [ 0 ] . ip ) ;
}
}
oldiplist = status . comms . interfaces . networkDevices ;
2022-11-01 20:21:24 +00:00
if ( status . comms . interfaces . networkDevices . length > 0 ) {
var output = {
'command' : 'network' ,
'response' : "Network Scan completed. Found " + status . comms . interfaces . networkDevices . length + " devices. Network addresses added to the Port selection dropdown." ,
'type' : 'success'
}
} else {
var output = {
'command' : 'network' ,
'response' : "Network Scan completed. Found " + status . comms . interfaces . networkDevices . length + " devices" ,
'type' : 'error'
}
}
io . sockets . emit ( 'data' , output ) ;
2022-07-06 20:08:38 +00:00
} ) ;
scan . run ( ) ;
} ) ;
}
// end LAN Scanner
2020-11-20 15:50:37 +00:00
2024-04-25 14:27:42 +00:00
2020-03-06 15:59:58 +00:00
process . on ( 'exit' , ( ) => debug _log ( 'exit' ) )