2019-04-15 17:31:30 +00:00
//v1.0.152
2018-12-21 13:56:11 +00:00
process . env . ELECTRON _DISABLE _SECURITY _WARNINGS = '1' ;
2018-11-23 16:13:16 +00:00
console . 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 = { } ;
config . webPort = process . env . WEB _PORT || 3000 ;
config . posDecimals = process . env . DRO _DECIMALS || 2 ;
config . grblWaitTime = 1 ;
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' ) ;
var ioServer = require ( 'socket.io' ) ;
var io = new ioServer ( ) ;
2019-02-15 18:58:11 +00:00
var safetosend ;
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 ;
2018-08-13 17:22:26 +00:00
var mkdirp = require ( 'mkdirp' ) ;
2018-07-11 12:39:24 +00:00
2018-09-18 14:09:11 +00:00
app . use ( express . static ( path . join ( _ _dirname , "app" ) ) ) ;
2018-07-11 09:02:41 +00:00
var httpsOptions = {
2018-07-12 14:56:42 +00:00
key : fs . readFileSync ( path . join ( _ _dirname , 'domain-key.key' ) ) ,
cert : fs . readFileSync ( path . join ( _ _dirname , 'domain-crt.cer' ) )
2018-07-11 09:02:41 +00:00
} ;
const httpsserver = https . createServer ( httpsOptions , app ) . listen ( 3001 , function ( ) {
console . log ( 'https: listening on:' + ip . address ( ) + ":3001" ) ;
} ) ;
const httpserver = http . listen ( config . webPort , '0.0.0.0' , function ( ) {
console . log ( 'http: listening on:' + ip . address ( ) + ":" + config . webPort ) ;
} ) ;
io . attach ( httpserver ) ;
io . attach ( httpsserver ) ;
const grblStrings = require ( "./grblStrings.js" ) ;
2018-06-19 08:07:03 +00:00
const serialport = require ( 'serialport' ) ;
var SerialPort = serialport ;
2019-04-15 17:31:30 +00:00
const Readline = SerialPort . parsers . Readline ;
2018-06-19 08:07:03 +00:00
var md5 = require ( 'md5' ) ;
var ip = require ( "ip" ) ;
2018-06-19 20:25:40 +00:00
var _ = require ( 'lodash' ) ;
2018-06-27 14:08:24 +00:00
var fs = require ( "fs" ) ;
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 ;
2019-05-21 12:09:53 +00:00
2018-08-23 20:09:27 +00:00
if ( isElectron ( ) ) {
console . log ( "Local User Data: " + electronApp . getPath ( 'userData' ) )
2019-05-07 20:10:53 +00:00
electronApp . commandLine . appendSwitch ( 'ignore-gpu-blacklist' , 'true' )
electronApp . commandLine . appendSwitch ( 'enable-gpu-rasterization' , 'true' )
electronApp . commandLine . appendSwitch ( 'enable-zero-copy' , 'true' )
electronApp . commandLine . appendSwitch ( 'disable-software-rasterizer' , 'true' )
electronApp . commandLine . appendSwitch ( 'enable-native-gpu-memory-buffers' , 'true' )
2019-05-21 12:09:53 +00:00
// Removing max-old-space-size switch (Introduced in 1.0.168 and removed in 1.0.169) due it causing High CPU load on some PCs.
2019-05-17 12:10:25 +00:00
//electronApp.commandLine.appendSwitch('js-flags', '--max-old-space-size=8192')
2019-05-07 20:10:53 +00:00
console . log ( 'Command Line Arguments for Electron: Set OK' )
2018-08-23 20:09:27 +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
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 ) ;
console . log ( JSON . stringify ( ev ) )
} )
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 ) ;
console . log ( JSON . stringify ( ev ) )
} )
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 ) + '%' ;
console . log ( string )
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 ) ;
2018-10-29 19:18:59 +00:00
} , 15 * 60 * 1000 ) // 15 mins
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 {
console . 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' )
}
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
2018-08-13 17:22:26 +00:00
mkdirp ( uploadsDir , function ( err ) {
if ( err ) console . error ( err )
else console . log ( 'Created Uploads Temp Directory' )
} ) ;
2018-07-03 20:54:15 +00:00
2018-06-19 20:25:40 +00:00
var oldportslist ;
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 ;
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
var sentBuffer = [ ] ;
2018-06-19 08:07:03 +00:00
var SMOOTHIE _RX _BUFFER _SIZE = 64 ; // max. length of one command line
var smoothie _buffer = false ;
var lastMode ;
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 ;
var has4thAxis = false ;
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 = {
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 ( ) ,
2019-06-06 19:11:48 +00:00
operatingsystem : false
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 : '' ,
2018-08-07 10:05:49 +00:00
inputs : [ ] ,
2018-06-19 08:07:03 +00:00
tools : {
hotend1 : false ,
hotend2 : false ,
heatbed : false ,
laser : false ,
spindle : false
} ,
overrides : {
feedOverride : 100 , //
spindleOverride : 100 , //
realFeed : 0 , //
realSpindle : 0 //
} ,
2018-12-28 21:28:44 +00:00
// status.machine.probe.
probe : {
x : 0.00 ,
y : 0.00 ,
z : 0.00 ,
state : - 1 ,
plate : 0.00 ,
request : { }
} ,
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
}
} ,
temperature : {
setpoint : {
t0 : 0 ,
t1 : 0 ,
b : 0
} ,
actual : {
t0 : 0 ,
t1 : 0 ,
b : 0
}
} ,
firmware : {
type : "" ,
version : "" ,
date : "" ,
2018-08-07 10:05:49 +00:00
buffer : [ ] ,
2018-06-19 08:07:03 +00:00
} ,
drivers : {
x : {
type : "" ,
axis : "" ,
microstep : 0 ,
currentSetting : 0 ,
enabled : 0 ,
stallGuard : {
stallGuardReading : 1023 ,
stallGuardThreshold : 0 ,
stallGuardFilter : 0
} ,
coolStep : {
coolStepEnabled : 0 ,
coolStepCurrent : 0 ,
coolStepLowerThreshold : 0 ,
coolStepUpperThreshold : 0 ,
coolStepNumberOfReadings : 0 ,
coolStepCurrentIncrement : 0 ,
coolStepLowerCurrentLimit : 0
} ,
troubleshooting : {
shortGndA : 0 ,
shortGndB : 0 ,
openLoadA : 0 ,
openLoadB : 0 ,
overTemp : 0
}
} ,
y : {
type : "" ,
axis : "" ,
microstep : 0 ,
currentSetting : 0 ,
enabled : 0 ,
stallGuard : {
stallGuardReading : 1023 ,
stallGuardThreshold : 0 ,
stallGuardFilter : 0
} ,
coolStep : {
coolStepEnabled : 0 ,
coolStepCurrent : 0 ,
coolStepLowerThreshold : 0 ,
coolStepUpperThreshold : 0 ,
coolStepNumberOfReadings : 0 ,
coolStepCurrentIncrement : 0 ,
coolStepLowerCurrentLimit : 0
} ,
troubleshooting : {
shortGndA : 0 ,
shortGndB : 0 ,
openLoadA : 0 ,
openLoadB : 0 ,
overTemp : 0
}
} ,
z : {
type : "" ,
axis : "" ,
microstep : 0 ,
currentSetting : 0 ,
enabled : 0 ,
stallGuard : {
stallGuardReading : 1023 ,
stallGuardThreshold : 0 ,
stallGuardFilter : 0
} ,
coolStep : {
coolStepEnabled : 0 ,
coolStepCurrent : 0 ,
coolStepLowerThreshold : 0 ,
coolStepUpperThreshold : 0 ,
coolStepNumberOfReadings : 0 ,
coolStepCurrentIncrement : 0 ,
coolStepLowerCurrentLimit : 0
} ,
troubleshooting : {
shortGndA : 0 ,
shortGndB : 0 ,
openLoadA : 0 ,
openLoadB : 0 ,
overTemp : 0
}
} ,
a : {
type : "" ,
axis : "" ,
microstep : 0 ,
currentSetting : 0 ,
enabled : 0 ,
stallGuard : {
stallGuardReading : 1023 ,
stallGuardThreshold : 0 ,
stallGuardFilter : 0
} ,
coolStep : {
coolStepEnabled : 0 ,
coolStepCurrent : 0 ,
coolStepLowerThreshold : 0 ,
coolStepUpperThreshold : 0 ,
coolStepNumberOfReadings : 0 ,
coolStepCurrentIncrement : 0 ,
coolStepLowerCurrentLimit : 0
} ,
troubleshooting : {
shortGndA : 0 ,
shortGndB : 0 ,
openLoadA : 0 ,
openLoadB : 0 ,
overTemp : 0
}
} ,
}
} ,
comms : {
connectionStatus : 0 , //0 = not connected, 1 = opening, 2 = connected, 3 = playing, 4 = paused
connectedTo : "none" ,
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 : {
ports : "" ,
activePort : "" // or activeIP in the case of wifi/telnet?
} ,
alarm : ""
}
} ;
2018-12-21 15:44:37 +00:00
2018-06-19 08:07:03 +00:00
SerialPort . list ( function ( err , ports ) {
2018-06-19 20:25:40 +00:00
oldportslist = ports ;
2018-06-19 08:07:03 +00:00
status . comms . interfaces . ports = ports ;
} ) ;
var PortCheckinterval = setInterval ( function ( ) {
2018-06-22 19:49:51 +00:00
if ( status . comms . connectionStatus == 0 ) {
SerialPort . list ( function ( err , ports ) {
status . comms . interfaces . ports = ports ;
if ( ! _ . isEqual ( ports , oldportslist ) ) {
var newPorts = _ . differenceWith ( ports , oldportslist , _ . isEqual )
if ( newPorts . length > 0 ) {
console . log ( "Plugged " + newPorts [ 0 ] . comName ) ;
}
var removedPorts = _ . differenceWith ( oldportslist , ports , _ . isEqual )
if ( removedPorts . length > 0 ) {
console . log ( "Unplugged " + removedPorts [ 0 ] . comName ) ;
}
2018-06-19 20:25:40 +00:00
}
2018-06-22 19:49:51 +00:00
oldportslist = ports ;
} ) ;
}
2018-06-19 08:07:03 +00:00
} , 500 ) ;
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 ) => {
console . log ( req . hostname )
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 ) ;
2018-08-08 17:56:11 +00:00
if ( jogWindow === null ) {
createJogWindow ( ) ;
jogWindow . show ( )
// workaround from https://github.com/electron/electron/issues/2867#issuecomment-261067169 to make window pop over for focus
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
} else {
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
}
setTimeout ( function ( ) {
2018-08-09 12:20:42 +00:00
io . sockets . emit ( 'activate' , req . hostname ) ;
2018-08-08 17:56:11 +00:00
} , 1500 ) ;
} )
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
} )
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" ) ;
2019-05-21 12:09:53 +00:00
//console.log(req)
2018-06-27 14:08:24 +00:00
uploadprogress = 0
var form = new formidable . IncomingForm ( ) ;
2019-05-21 12:09:53 +00:00
form . parse ( req , function ( err , fields , files ) {
// console.log(files);
} ) ;
2018-06-27 14:08:24 +00:00
2018-07-11 09:02:41 +00:00
form . on ( 'fileBegin' , function ( name , file ) {
console . log ( 'Uploading ' + file . name ) ;
file . path = uploadsDir + file . name ;
} ) ;
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 ;
}
} ) ;
form . on ( 'file' , function ( name , file ) {
2018-07-03 20:28:02 +00:00
console . log ( 'Uploaded ' + file . path ) ;
2018-06-29 19:48:34 +00:00
if ( jogWindow === null ) {
createJogWindow ( ) ;
jogWindow . show ( )
2018-07-03 20:28:02 +00:00
// workaround from https://github.com/electron/electron/issues/2867#issuecomment-261067169 to make window pop over for focus
jogWindow . setAlwaysOnTop ( true ) ;
2018-06-29 19:48:34 +00:00
jogWindow . focus ( ) ;
2018-07-03 20:28:02 +00:00
jogWindow . setAlwaysOnTop ( false ) ;
2018-06-29 19:48:34 +00:00
} else {
jogWindow . show ( )
2018-07-03 20:28:02 +00:00
jogWindow . setAlwaysOnTop ( true ) ;
2018-06-29 19:48:34 +00:00
jogWindow . focus ( ) ;
2018-07-03 20:28:02 +00:00
jogWindow . setAlwaysOnTop ( false ) ;
2018-06-29 19:48:34 +00:00
}
2018-08-29 08:11:14 +00:00
readFile ( file . path )
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.
} ) ;
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 ) {
iosocket = socket ;
2018-06-21 20:02:40 +00:00
if ( status . machine . firmware . type == 'grbl' ) {
2019-02-11 19:29:44 +00:00
// 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' :
// console.log('PIN: SOFTRESET');
safetosend = true ;
break ;
}
}
2019-05-08 19:06:34 +00:00
} else {
io . sockets . emit ( 'grbl' )
2019-02-11 19:29:44 +00:00
}
2019-02-15 18:56:37 +00:00
if ( safetosend != undefined && safetosend == true ) {
2019-04-22 14:52:10 +00:00
io . sockets . emit ( 'grbl' )
2019-02-11 19:29:44 +00:00
}
2018-06-21 20:02:40 +00:00
}
2018-06-19 08:07:03 +00:00
var interval = setInterval ( function ( ) {
io . sockets . emit ( "status" , status ) ;
2018-06-25 17:25:19 +00:00
if ( jogWindow ) {
if ( status . comms . connectionStatus == 0 ) {
jogWindow . setOverlayIcon ( nativeImage . createFromPath ( iconNoComm ) , 'Not Connected' ) ;
} else if ( status . comms . connectionStatus == 1 ) {
jogWindow . setOverlayIcon ( nativeImage . createFromPath ( iconStop ) , 'Port Connected' ) ;
} else if ( status . comms . connectionStatus == 2 ) {
jogWindow . setOverlayIcon ( nativeImage . createFromPath ( iconStop ) , 'Connected, and Firmware' ) ;
} else if ( status . comms . connectionStatus == 3 ) {
jogWindow . setOverlayIcon ( nativeImage . createFromPath ( iconPlay ) , 'Playing' ) ;
} else if ( status . comms . connectionStatus == 4 ) {
jogWindow . setOverlayIcon ( nativeImage . createFromPath ( iconPause ) , 'Paused' ) ;
} else if ( status . comms . connectionStatus == 5 ) {
jogWindow . setOverlayIcon ( nativeImage . createFromPath ( iconAlarm ) , 'Alarm' ) ;
}
}
} , 400 ) ;
2018-06-19 08:07:03 +00:00
2019-01-23 19:07:58 +00:00
socket . on ( "openbuilds" , function ( data ) {
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://www.openbuilds.com' )
} ) ;
2018-07-26 20:22:07 +00:00
socket . on ( "opencam" , function ( data ) {
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://cam.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/' )
} ) ;
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 ( ) ;
} ) ;
2018-06-20 13:00:05 +00:00
socket . on ( "maximise" , function ( data ) { } ) ;
2018-08-07 10:05:49 +00:00
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 {
console . log ( "autoUpdater not found" )
}
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 ;
var file = data . file ;
2019-03-07 14:38:40 +00:00
var board = data . board
2018-12-20 19:22:02 +00:00
const Avrgirl = require ( 'avrgirl-arduino' ) ;
if ( status . comms . connectionStatus > 0 ) {
console . log ( 'WARN: Closing Port ' + port ) ;
stopPort ( ) ;
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
function flashGrblCallback ( debugString , port ) {
console . log ( port , debugString ) ;
var data = {
'port' : port ,
'string' : debugString
}
io . sockets . emit ( "progStatus" , data ) ;
}
setTimeout ( function ( ) {
var avrgirl = new Avrgirl ( {
2019-03-07 14:38:40 +00:00
board : board ,
2018-12-20 19:22:02 +00:00
port : port ,
debug : function ( debugString ) {
var port = this . connection . options . port ;
flashGrblCallback ( debugString , port )
}
} ) ;
2019-03-07 14:38:40 +00:00
console . log ( JSON . stringify ( avrgirl ) ) ;
2018-12-20 19:22:02 +00:00
status . comms . connectionStatus = 6 ;
2018-12-20 20:22:09 +00:00
avrgirl . flash ( path . join ( _ _dirname , file ) , function ( error ) {
2018-12-20 19:22:02 +00:00
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-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 ) {
data = data . split ( "," ) ;
console . log ( "Connecting via " + data [ 0 ] + " to " + data [ 1 ] + " at baud " + data [ 2 ] ) ;
port = new SerialPort ( data [ 1 ] , {
baudRate : parseInt ( data [ 2 ] )
} ) ;
2019-04-15 17:31:30 +00:00
parser = port . pipe ( new Readline ( {
delimiter : '\r\n'
} ) ) ;
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" ) {
console . log ( "Error: " , err . message ) ;
var output = {
'command' : '' ,
'response' : "PORT ERROR: " + err . message
}
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 ) {
console . 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 {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
2018-07-24 12:58:26 +00:00
}
2018-12-20 19:22:02 +00:00
2018-06-19 08:07:03 +00:00
} ) ;
port . on ( "open" , function ( ) {
2019-04-15 17:31:30 +00:00
console . 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' ,
'response' : "PORT INFO: Port is now open: " + port . path + " - Attempting to detect Firmware"
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
var output = {
'command' : 'connect' ,
'response' : "Checking for firmware on " + port . path
}
io . sockets . emit ( 'data' , output ) ;
addQRealtime ( "\n" ) ; // this causes smoothie to send the welcome string
var output = {
'command' : 'connect' ,
'response' : "Detecting Firmware: Method 1 (Autoreset)"
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 ) {
2018-10-10 18:50:55 +00:00
console . log ( "Didnt detect firmware after AutoReset. Lets see if we have Grbl instance with a board that doesnt have AutoReset" ) ;
var output = {
'command' : 'connect' ,
'response' : "Detecting Firmware: Method 2 (Ctrl+X)"
}
io . sockets . emit ( 'data' , output ) ;
2018-10-10 18:36:56 +00:00
addQRealtime ( String . fromCharCode ( 0x18 ) ) ; // ctrl-x (needed for rx/tx connection)
console . log ( "Sent: Ctrl+x" ) ;
}
} , 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 ) {
2018-10-10 18:50:55 +00:00
console . log ( "No firmware yet, probably not Grbl then. lets see if we have Smoothie?" ) ;
var output = {
'command' : 'connect' ,
'response' : "Detecting Firmware: Method 3 (Smoothieware)"
}
io . sockets . emit ( 'data' , output ) ;
2018-08-09 16:34:51 +00:00
addQRealtime ( "version\n" ) ; // Check if it's Smoothieware?
2018-06-19 08:07:03 +00:00
console . log ( "Sent: version" ) ;
}
2018-10-10 18:36:56 +00:00
} , config . grblWaitTime * 2000 ) ;
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 ) {
console . log ( "No supported firmware detected. Closing port " + port . path ) ;
2018-10-10 18:50:55 +00:00
var output = {
2019-01-21 12:46:21 +00:00
'command' : 'connect' ,
2018-10-10 18:50:55 +00:00
'response' : "No supported firmware detected. Closing port " + port . path
}
io . sockets . emit ( 'data' , output ) ;
2018-06-19 08:07:03 +00:00
stopPort ( ) ;
2018-10-10 18:50:55 +00:00
} else {
var output = {
'command' : 'connect' ,
'response' : "Firmware Detected: " + status . machine . firmware . type + " version " + status . machine . firmware . version + " on " + port . path
}
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 ;
status . comms . interfaces . activePort = port . path ;
2019-04-15 17:31:30 +00:00
status . comms . interfaces . activeBaud = port . baudRate ;
2018-06-19 08:07:03 +00:00
} ) ; // end port .onopen
port . on ( "close" , function ( ) { // open errors will be emitted as an error event
console . log ( "PORT INFO: Port closed" ) ;
2018-07-11 18:58:38 +00:00
var output = {
2019-01-21 12:46:21 +00:00
'command' : 'disconnect' ,
2018-07-11 18:58:38 +00:00
'response' : "PORT INFO: Port closed"
}
io . sockets . emit ( 'data' , output ) ;
2019-04-12 15:44:02 +00:00
status . comms . connectionStatus = 0 ;
2018-06-19 08:07:03 +00:00
} ) ; // end port.onclose
2019-04-15 17:31:30 +00:00
parser . on ( "data" , function ( data ) {
2018-08-09 16:34:51 +00:00
var command = sentBuffer [ 0 ] ;
2018-06-19 08:07:03 +00:00
2019-01-29 21:29:13 +00:00
// console.log('data:', data)
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 ( ) ) ;
2018-12-21 13:56:11 +00:00
}
2018-12-28 21:28:44 +00:00
// [PRB:0.000,0.000,0.000:0]
if ( data . indexOf ( "[PRB:" ) === 0 ) {
2019-03-06 19:26:09 +00:00
if ( status . machine . probe . request . plate ) {
console . 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 ] ;
status . machine . probe . state = success ;
if ( success > 0 ) {
var output = {
'command' : '[ PROBE ]' ,
'response' : "Probe Completed. Setting Z to " + status . machine . probe . plate + 'mm' ,
}
io . sockets . emit ( 'data' , output ) ;
addQToEnd ( 'G10 P1 L20 Z' + status . machine . probe . plate ) ;
send1Q ( ) ;
} else {
var output = {
'command' : '[ PROBE ]' ,
'response' : "Probe move aborted - probe did not make contact within specified distance" ,
}
io . sockets . emit ( 'data' , output ) ;
2018-12-28 21:28:44 +00:00
}
2019-03-06 19:26:09 +00:00
io . sockets . emit ( 'prbResult' , status ) ;
status . machine . probe . request = "" ;
2018-12-28 21:28:44 +00:00
}
} ;
2018-12-21 13:56:11 +00:00
2018-06-19 08:07:03 +00:00
// Machine Identification
if ( data . indexOf ( "Grbl" ) === 0 ) { // Check if it's Grbl
2019-02-11 19:29:44 +00:00
console . log ( data )
2018-06-19 08:07:03 +00:00
status . comms . blocked = false ;
status . machine . firmware . type = "grbl" ;
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 ) {
console . 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 ) {
console . log ( 'WARN: Closing Port ' + port . path + " / v" + parseFloat ( status . machine . firmware . version ) ) ;
// stopPort();
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
var output = {
'command' : command ,
'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"
}
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 = "" ;
console . log ( "GRBL detected" ) ;
2019-02-11 19:29:44 +00:00
setTimeout ( function ( ) {
2019-04-22 14:52:10 +00:00
io . sockets . emit ( 'grbl' )
2019-02-11 19:29:44 +00:00
} , 600 )
2018-06-19 08:07:03 +00:00
// Start interval for status queries
statusLoop = setInterval ( function ( ) {
if ( status . comms . connectionStatus > 0 ) {
2018-08-09 17:29:41 +00:00
addQRealtime ( "?" ) ;
2018-06-19 08:07:03 +00:00
}
2018-07-24 18:11:56 +00:00
} , 250 ) ;
2018-06-19 08:07:03 +00:00
} else if ( data . indexOf ( "LPC176" ) >= 0 ) { // LPC1768 or LPC1769 should be Smoothieware
status . comms . blocked = false ;
console . log ( "Smoothieware detected" ) ;
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
statusLoop = setInterval ( function ( ) {
if ( status . comms . connectionStatus > 0 ) {
2018-08-09 17:29:41 +00:00
addQRealtime ( "?" ) ;
2018-06-19 08:07:03 +00:00
}
} , 200 ) ;
} // end of machine identification
// Machine Feedback: Temperature and Position
2018-08-09 16:34:51 +00:00
if ( data . indexOf ( "<" ) === 0 ) {
// console.log(' Got statusReport (Grbl & Smoothieware)')
2018-06-19 08:07:03 +00:00
// statusfeedback func
parseFeedback ( data )
2018-08-02 20:17:56 +00:00
// console.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
// console.log("OK FOUND")
if ( status . machine . firmware . type === "grbl" ) {
2018-08-09 16:34:51 +00:00
// console.log('got OK from ' + command)
command = sentBuffer . shift ( ) ;
2018-06-19 08:07:03 +00:00
}
2018-08-09 17:29:41 +00:00
if ( status . machine . firmware . type === "smoothie" ) {
// console.log('got OK from ' + command)
command = sentBuffer . shift ( ) ;
}
2018-06-19 08:07:03 +00:00
status . comms . blocked = false ;
send1Q ( ) ;
} else if ( data . indexOf ( 'ALARM' ) === 0 ) { //} || data.indexOf('HALTED') === 0) {
2019-04-22 14:52:10 +00:00
console . 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 ] ) ;
console . log ( 'ALARM: ' + alarmCode + ' - ' + grblStrings . alarms ( alarmCode ) ) ;
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' : '' ,
'response' : 'ALARM: ' + alarmCode + ' - ' + grblStrings . alarms ( alarmCode ) + " [ " + command + " ]"
}
io . sockets . emit ( 'data' , output ) ;
2018-06-19 08:07:03 +00:00
break ;
case 'smoothie' :
status . comms . alarm = data ;
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) {
2018-08-09 16:34:51 +00:00
console . 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 ] ) ;
2018-06-25 20:13:58 +00:00
console . log ( 'error: ' + errorCode + ' - ' + grblStrings . errors ( errorCode ) + " [ " + command + " ]" ) ;
2018-07-11 18:58:38 +00:00
var output = {
'command' : '' ,
'response' : 'error: ' + errorCode + ' - ' + grblStrings . errors ( errorCode ) + " [ " + command + " ]"
}
io . sockets . emit ( 'data' , output ) ;
2019-04-22 14:52:10 +00:00
io . sockets . emit ( "toastError" , 'error: ' + errorCode + ' - ' + grblStrings . errors ( errorCode ) + " [ " + command + " ]" )
2018-06-19 08:07:03 +00:00
break ;
case 'smoothie' :
2018-07-11 18:58:38 +00:00
var output = {
'command' : '' ,
'response' : data
}
io . sockets . emit ( 'data' , output ) ;
// io.sockets.emit('data', data);
2018-06-19 08:07:03 +00:00
break ;
}
2018-08-09 16:34:51 +00:00
console . 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' :
console . log ( "[MSG:Reset to continue] -> Sending Reset" )
addQRealtime ( String . fromCharCode ( 0x18 ) ) ; // ctrl-x
break ;
// case 'smoothie':
//
// break;
}
}
2018-08-09 16:34:51 +00:00
if ( command ) {
command = command . replace ( /(\r\n|\n|\r)/gm , "" ) ;
// console.log("CMD: " + command + " / DATA RECV: " + data.replace(/(\r\n|\n|\r)/gm, ""));
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 ,
'response' : string
}
// console.log(output.response)
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' : "" ,
2018-09-27 15:00:49 +00:00
'response' : data
}
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 ) ;
} ) ;
socket . on ( 'runJob' , function ( data ) {
2019-01-21 12:46:21 +00:00
// console.log(data)
2018-08-29 08:11:14 +00:00
uploadedgcode = data ;
2019-01-21 12:46:21 +00:00
// console.log('Run Job (' + data.length + ')');
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 ++ ) {
2018-08-07 16:23:58 +00:00
var line = data [ i ] . replace ( "%" , "" ) . split ( ';' ) ; // Remove everything after ; = comment
var tosend = line [ 0 ] . trim ( ) ;
2018-06-19 08:07:03 +00:00
if ( tosend . length > 0 ) {
2018-08-09 16:34:51 +00:00
addQToEnd ( tosend ) ;
2018-06-19 08:07:03 +00:00
}
}
if ( i > 0 ) {
// Start interval for qCount messages to socket clients
queueCounter = setInterval ( function ( ) {
status . comms . queue = gcodeQueue . length - queuePointer
} , 500 ) ;
2018-08-09 16:34:51 +00:00
send1Q ( ) ; // send first line
2018-06-19 08:07:03 +00:00
status . comms . connectionStatus = 3 ;
}
}
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
socket . on ( 'forceQueue' , function ( data ) {
send1Q ( ) ;
} ) ;
socket . on ( 'runCommand' , function ( data ) {
console . log ( 'Run Command (' + data . replace ( '\n' , '|' ) + ')' ) ;
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
}
}
if ( i > 0 ) {
status . comms . runStatus = 'Running'
2018-08-09 16:34:51 +00:00
// console.log('sending ' + JSON.stringify(gcodeQueue))
2018-06-19 08:07:03 +00:00
send1Q ( ) ;
}
}
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
2018-12-28 21:28:44 +00:00
socket . on ( 'zProbe' , function ( data ) {
console . log ( 'Probing ' + data . direction + ' down to ' + data . dist + "mm at " + data . feedrate + "mm/min and then subtracting a plate of " + data . plate + "mm" )
status . machine . probe . request = data ;
status . machine . probe . x = 0.00 ;
status . machine . probe . y = 0.00 ;
status . machine . probe . z = 0.00 ;
status . machine . probe . state = - 1 ;
status . machine . probe . plate = data . plate ;
switch ( status . machine . firmware . type ) {
case 'grbl' :
addQToEnd ( 'G10 P1 L20 Z0' ) ;
addQToEnd ( 'G38.2 Z-' + data . dist + ' F' + data . feedrate ) ;
send1Q ( ) ;
break ;
// case 'smoothie':
// addQToEnd('G91');
// addQToEnd('G0' + feed + dir + dist);
// addQToEnd('G90');
// send1Q();
// break;
2019-01-21 12:46:21 +00:00
console . log ( 'ERROR: Unsupported firmware!' ) ;
break ;
2018-12-28 21:28:44 +00:00
default :
console . log ( 'ERROR: Unsupported firmware!' ) ;
break ;
}
} ) ;
2018-06-19 08:07:03 +00:00
socket . on ( 'jog' , function ( data ) {
console . log ( 'Jog ' + data ) ;
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 ) {
2018-09-27 15:00:49 +00:00
console . 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 ;
case 'smoothie' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G91' ) ;
addQToEnd ( 'G0' + feed + dir + dist ) ;
addQToEnd ( 'G90' ) ;
2018-06-19 08:07:03 +00:00
send1Q ( ) ;
break ;
default :
console . log ( 'ERROR: Unknown firmware!' ) ;
break ;
}
} else {
console . log ( 'ERROR: Invalid params!' ) ;
}
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
2018-08-24 19:00:03 +00:00
socket . on ( 'jogXY' , function ( data ) {
console . log ( 'Jog XY' + data ) ;
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 ) {
console . log ( 'Adding jog commands to queue. blocked=' + status . comms . blocked + ', paused=' + status . comms . paused + ', Q=' + gcodeQueue . length ) ;
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 ;
case 'smoothie' :
addQToEnd ( 'G91' ) ;
addQToEnd ( 'G0 X' + xincrement + " Y" + yincrement + " " + feed ) ;
addQToEnd ( 'G90' ) ;
send1Q ( ) ;
break ;
default :
console . log ( 'ERROR: Unknown firmware!' ) ;
break ;
}
} else {
console . log ( 'ERROR: Invalid params!' ) ;
}
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
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}
console . log ( 'JogTo ' + JSON . stringify ( data ) ) ;
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 ) : '' ) ;
console . log ( 'Adding jog commands to queue. blocked=' + status . comms . blocked + ', paused=' + status . comms . paused + ', Q=' + gcodeQueue . length ) ;
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 ;
case 'smoothie' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G91' + mode ) ;
addQToEnd ( 'G0' + feed + xVal + yVal + zVal ) ;
addQToEnd ( 'G90' ) ;
2018-06-19 08:07:03 +00:00
send1Q ( ) ;
break ;
default :
console . log ( 'ERROR: Unknown firmware!' ) ;
break ;
}
} else {
console . log ( 'error Invalid params!' ) ;
}
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
socket . on ( 'setZero' , function ( data ) {
console . log ( 'setZero(' + data + ')' ) ;
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 {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
socket . on ( 'gotoZero' , function ( data ) {
console . log ( 'gotoZero(' + data + ')' ) ;
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 {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
socket . on ( 'setPosition' , function ( data ) {
console . log ( 'setPosition(' + JSON . stringify ( data ) + ')' ) ;
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 {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
socket . on ( 'probe' , function ( data ) {
console . log ( 'probe(' + JSON . stringify ( data ) + ')' ) ;
if ( status . comms . connectionStatus > 0 ) {
switch ( status . machine . firmware . type ) {
case 'smoothie' :
switch ( data . direction ) {
case 'z' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G30 Z' + data . probeOffset ) ;
2018-06-19 08:07:03 +00:00
break ;
default :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G38.2 ' + data . direction ) ;
2018-06-19 08:07:03 +00:00
break ;
}
2018-08-09 16:34:51 +00:00
send1Q ( ) ;
break ;
2018-06-19 08:07:03 +00:00
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
console . log ( 'Command not supported by firmware!' ) ;
break ;
}
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
socket . on ( 'feedOverride' , function ( data ) {
console . log ( data )
if ( status . comms . connectionStatus > 0 ) {
switch ( status . machine . firmware . type ) {
case 'grbl' :
console . log ( "current FRO = " + status . machine . overrides . feedOverride )
console . log ( "requested FRO = " + data )
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
console . log ( "delta = " + delta )
var tens = Math . floor ( delta / 10 )
console . 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 ) ;
console . 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
console . log ( "delta = " + delta )
var tens = Math . floor ( delta / 10 )
console . 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 ) ;
console . 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 ( "?" ) ;
2018-06-19 08:07:03 +00:00
status . machine . overrides . feedOverride = reqfro // Set now, but will be overriden from feedback from Grbl itself in next queryloop
break ;
case 'smoothie' :
if ( data === 0 ) {
feedOverride = 100 ;
} else {
if ( ( feedOverride + data <= 200 ) && ( feedOverride + data >= 10 ) ) {
// valid range is 10..200, else ignore!
feedOverride += data ;
}
}
2018-08-09 16:34:51 +00:00
addQToStart ( 'M220S' + feedOverride + '\n' ) ;
send1Q ( ) ;
2018-06-19 08:07:03 +00:00
status . machine . overrides . feedOverride = feedOverride
break ;
}
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
socket . on ( 'spindleOverride' , function ( data ) {
if ( status . comms . connectionStatus > 0 ) {
switch ( status . machine . firmware . type ) {
case 'grbl' :
console . log ( "current SRO = " + status . machine . overrides . spindleOverride )
console . log ( "requested SRO = " + data )
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
console . log ( "delta = " + delta )
var tens = Math . floor ( delta / 10 )
console . 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 ) ;
console . 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
console . log ( "delta = " + delta )
var tens = Math . floor ( delta / 10 )
console . 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 ) ;
console . 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 ( "?" ) ;
2018-06-19 08:07:03 +00:00
status . machine . overrides . spindleOverride = reqsro // Set now, but will be overriden from feedback from Grbl itself in next queryloop
break ;
case 'smoothie' :
if ( data === 0 ) {
spindleOverride = 100 ;
} else {
if ( ( spindleOverride + data <= 200 ) && ( spindleOverride + data >= 0 ) ) {
// valid range is 0..200, else ignore!
spindleOverride += data ;
}
}
2018-08-09 16:34:51 +00:00
addQToStart ( 'M221S' + spindleOverride + '\n' ) ;
send1Q ( ) ;
2018-06-19 08:07:03 +00:00
status . machine . overrides . spindleOverride = spindleOverride ;
break ;
}
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
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 ) ;
console . log ( 'Clearing Queue: Method ' + data ) ;
switch ( data ) {
case 1 :
console . log ( 'Clearing Lockout' ) ;
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-08-09 16:34:51 +00:00
addQRealtime ( '$X\n' ) ;
2018-06-19 08:07:03 +00:00
console . log ( 'Sent: $X' ) ;
break ;
case 'smoothie' :
2018-08-09 16:34:51 +00:00
addQRealtime ( '$X\n' ) ;
2018-06-19 08:07:03 +00:00
console . log ( 'Sent: $X' ) ;
break ;
}
console . log ( 'Resuming Queue Lockout' ) ;
break ;
case 2 :
console . 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 ;
console . log ( 'Clearing Lockout' ) ;
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-09-27 15:00:49 +00:00
addQRealtime ( String . fromCharCode ( 0x18 ) ) ; // ctrl-x
2018-08-09 16:34:51 +00:00
addQRealtime ( '$X\n' ) ;
2018-06-19 08:07:03 +00:00
console . log ( 'Sent: $X' ) ;
status . comms . blocked = false ;
status . comms . paused = false ;
break ;
case 'smoothie' :
2018-08-09 16:34:51 +00:00
addQToStart ( 'M999' ) ; //M999
2018-06-19 08:07:03 +00:00
send1Q ( ) ;
2018-08-09 16:34:51 +00:00
console . log ( 'Sent: M999' ) ;
2018-06-19 08:07:03 +00:00
status . comms . blocked = false ;
status . comms . paused = false ;
break ;
}
break ;
}
status . comms . runStatus = 'Stopped'
status . comms . connectionStatus = 2 ;
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
socket . on ( 'resetMachine' , function ( ) {
if ( status . comms . connectionStatus > 0 ) {
console . log ( 'Reset Machine' ) ;
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 0x18 ) ) ; // ctrl-x
2018-06-19 08:07:03 +00:00
console . log ( 'Sent: Code(0x18)' ) ;
break ;
case 'smoothie' :
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 0x18 ) ) ; // ctrl-x
2018-06-19 08:07:03 +00:00
console . log ( 'Sent: Code(0x18)' ) ;
break ;
}
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
socket . on ( 'closePort' , function ( data ) { // Close machine port and dump queue
if ( status . comms . connectionStatus > 0 ) {
console . log ( 'WARN: Closing Port ' + port . path ) ;
stopPort ( ) ;
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
} ) ;
2018-08-29 08:11:14 +00:00
function readFile ( path ) {
2018-09-04 16:12:14 +00:00
if ( path ) {
if ( path . length > 1 ) {
console . log ( 'readfile: ' + path )
fs . readFile ( path , 'utf8' ,
function ( err , data ) {
if ( err ) {
console . log ( err ) ;
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 ) {
2019-04-29 17:26:29 +00:00
if ( path . endsWith ( '.obc' ) ) { // OpenBuildsCAM Workspace
uploadedworkspace = data ;
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://cam.openbuilds.com' )
} else { // GCODE
io . sockets . emit ( 'gcodeupload' , data ) ;
uploadedgcode = data ;
return data
}
2018-09-04 16:12:14 +00:00
}
} ) ;
}
2018-08-29 08:11:14 +00:00
}
}
2018-06-19 08:07:03 +00:00
function machineSend ( gcode ) {
2019-04-18 14:23:51 +00:00
// console.log("SENDING: " + gcode)
2018-06-19 08:07:03 +00:00
if ( port . isOpen ) {
var queueLeft = ( gcodeQueue . length - queuePointer )
var queueTotal = gcodeQueue . length
2018-06-25 20:13:58 +00:00
// console.log("Q: " + queueLeft)
2018-06-19 08:07:03 +00:00
var data = [ ]
data . push ( queueLeft ) ;
data . push ( queueTotal ) ;
io . sockets . emit ( "queueCount" , data ) ;
2018-08-08 12:31:59 +00:00
// console.log(gcode)
2018-06-19 08:07:03 +00:00
port . write ( gcode ) ;
} else {
console . log ( "PORT NOT OPEN" )
}
}
2018-08-07 17:34:04 +00:00
function stopPort ( ) {
clearInterval ( queueCounter ) ;
clearInterval ( statusLoop ) ;
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
2018-08-07 17:34:04 +00:00
port . drain ( port . close ( ) ) ;
}
2018-06-19 08:07:03 +00:00
function parseFeedback ( data ) {
// console.log(data)
var state = data . substring ( 1 , data . search ( /(,|\|)/ ) ) ;
status . comms . runStatus = state
2018-06-24 14:14:28 +00:00
if ( state == "Alarm" ) {
2018-09-27 15:00:49 +00:00
// console.log("ALARM: " + data)
2018-06-24 14:14:28 +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-24 14:14:28 +00:00
var alarmCode = parseInt ( data . split ( ':' ) [ 1 ] ) ;
2018-06-25 20:13:58 +00:00
// console.log('ALARM: ' + alarmCode + ' - ' + grblStrings.alarms(alarmCode));
2018-06-24 14:14:28 +00:00
status . comms . alarm = alarmCode + ' - ' + grblStrings . alarms ( alarmCode )
break ;
case 'smoothie' :
status . comms . alarm = data ;
break ;
}
status . comms . connectionStatus = 5 ;
}
2018-06-19 08:07:03 +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 ) ;
if ( has4thAxis ) {
aOffset = parseFloat ( wco [ 3 ] ) . toFixed ( config . posDecimals ) ;
status . machine . position . offset . x = xOffset ;
status . machine . position . offset . y = yOffset ;
status . machine . position . offset . z = zOffset ;
status . machine . position . offset . a = aOffset ;
} else {
status . machine . position . offset . x = xOffset ;
status . machine . position . offset . y = yOffset ;
status . machine . position . offset . z = zOffset ;
}
}
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 ) ) {
2018-09-14 17:35:54 +00:00
// console.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 ) ;
has4thAxis = true ;
}
}
if ( has4thAxis ) {
status . machine . position . work . x = xPos
status . machine . position . work . y = yPos
status . machine . position . work . z = zPos
status . machine . position . work . a = aPos
} else {
status . machine . position . work . x = xPos
status . machine . position . work . y = yPos
status . machine . position . work . z = zPos
}
2018-09-14 17:35:54 +00:00
// end is WPOS
} else if ( Array . isArray ( mPos ) ) {
// console.log('mpos', mPos)
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 ) ;
has4thAxis = true ;
}
}
2018-06-19 08:07:03 +00:00
if ( has4thAxis ) {
2018-09-14 17:35:54 +00:00
status . machine . position . work . x = parseFloat ( xPos - status . machine . position . offset . x ) . toFixed ( config . posDecimals )
status . machine . position . work . y = parseFloat ( yPos - status . machine . position . offset . y ) . toFixed ( config . posDecimals )
status . machine . position . work . z = parseFloat ( zPos - status . machine . position . offset . z ) . toFixed ( config . posDecimals )
status . machine . position . work . a = parseFloat ( aPos - status . machine . position . offset . a ) . toFixed ( config . posDecimals )
2018-06-19 08:07:03 +00:00
} else {
2018-09-14 17:35:54 +00:00
status . machine . position . work . x = parseFloat ( xPos - status . machine . position . offset . x ) . toFixed ( config . posDecimals )
status . machine . position . work . y = parseFloat ( yPos - status . machine . position . offset . y ) . toFixed ( config . posDecimals )
status . machine . position . work . z = 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
}
if ( status . machine . firmware . type == "smoothie" ) {
// Extract wPos (for Smoothieware only!)
var startWPos = data . search ( /wpos:/i ) + 5 ;
var wPos ;
if ( startWPos > 5 ) {
wPos = data . replace ( '>' , '' ) . substr ( startWPos ) . split ( /,/ , 4 ) ;
}
if ( Array . isArray ( wPos ) ) {
if ( xPos !== wPos [ 0 ] ) {
xPos = wPos [ 0 ] ;
}
if ( yPos !== wPos [ 1 ] ) {
yPos = wPos [ 1 ] ;
}
if ( zPos !== wPos [ 2 ] ) {
zPos = wPos [ 2 ] ;
}
if ( wPos . length > 3 ) {
if ( aPos !== wPos [ 3 ] ) {
aPos = wPos [ 3 ] ;
has4thAxis = true ;
}
}
if ( has4thAxis ) {
2018-06-27 14:08:24 +00:00
status . machine . position . work . x = parseFloat ( xPos ) . toFixed ( config . posDecimals )
status . machine . position . work . y = parseFloat ( yPos ) . toFixed ( config . posDecimals )
status . machine . position . work . z = parseFloat ( zPos ) . toFixed ( config . posDecimals )
status . machine . position . work . a = parseFloat ( aPos ) . toFixed ( config . posDecimals )
2018-06-19 08:07:03 +00:00
} else {
2018-06-27 14:08:24 +00:00
status . machine . position . work . x = parseFloat ( xPos ) . toFixed ( config . posDecimals )
status . machine . position . work . y = parseFloat ( yPos ) . toFixed ( config . posDecimals )
status . machine . position . work . z = parseFloat ( zPos ) . toFixed ( config . posDecimals )
2018-06-19 08:07:03 +00:00
}
}
// Extract mPos (for Smoothieware only!)
var startMPos = data . search ( /mpos:/i ) + 5 ;
var mPos ;
if ( startMPos > 5 ) {
mPos = data . replace ( ">" , "" ) . substr ( startMPos ) . split ( /,|\|/ , 4 ) ;
}
if ( Array . isArray ( mPos ) ) {
if ( xOffset != mPos [ 0 ] - xPos ) {
xOffset = mPos [ 0 ] - xPos ;
}
if ( yOffset != mPos [ 1 ] - yPos ) {
yOffset = mPos [ 1 ] - yPos ;
}
if ( zOffset != mPos [ 2 ] - zPos ) {
zOffset = mPos [ 2 ] - zPos ;
}
if ( has4thAxis ) {
if ( aOffset != mPos [ 3 ] - aPos ) {
aOffset = mPos [ 3 ] - aPos ;
}
}
if ( has4thAxis ) {
status . machine . position . offset . x = parseFloat ( xOffset ) . toFixed ( config . posDecimals ) ;
status . machine . position . offset . y = parseFloat ( yOffset ) . toFixed ( config . posDecimals ) ;
status . machine . position . offset . z = parseFloat ( zOffset ) . toFixed ( config . posDecimals ) ;
status . machine . position . offset . a = parseFloat ( aOffset ) . toFixed ( config . posDecimals ) ;
} else {
status . machine . position . offset . x = parseFloat ( xOffset ) . toFixed ( config . posDecimals ) ;
status . machine . position . offset . y = parseFloat ( yOffset ) . toFixed ( config . posDecimals ) ;
status . machine . position . offset . z = parseFloat ( zOffset ) . toFixed ( config . posDecimals ) ;
}
}
}
// 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 ] ) {
status . machine . overrides . feedOverride = ov [ 0 ] ;
}
if ( ov [ 1 ] ) {
status . machine . overrides . rapidOverride = ov [ 1 ] ;
}
if ( ov [ 2 ] ) {
status . machine . overrides . spindleOverride = ov [ 2 ] ;
}
}
}
// Extract realtime Feed and Spindle (for Grbl > v1.1 only!)
var startFS = data . search ( /FS:/i ) + 3 ;
if ( startFS > 3 ) {
var fs = data . replace ( ">" , "" ) . substr ( startFS ) . split ( /,|\|/ ) ;
if ( Array . isArray ( fs ) ) {
if ( fs [ 0 ] ) {
status . machine . overrides . realFeed = fs [ 0 ] ;
}
if ( fs [ 1 ] ) {
status . machine . overrides . realSpindle = fs [ 1 ] ;
}
}
}
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 ) ) {
if ( pins . includes ( 'H' ) ) {
// pause
pause ( ) ;
var output = {
'command' : '[external from hardware]' ,
'response' : "OpenBuilds CONTROL received a FEEDHOLD notification from Grbl: This could be due to someone pressing the HOLD button (if connected), or DriverMinder on the xPROv4 detected a driver fault"
}
io . sockets . emit ( 'data' , output ) ;
} // end if HOLD
2019-01-21 12:46:21 +00:00
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]' ,
'response' : "OpenBuilds CONTROL received a RESET/ABORT notification from Grbl: This could be due to someone pressing the RESET/ABORT button (if connected), or DriverMinder on the xPROv4 detected a driver fault"
}
io . sockets . emit ( 'data' , output ) ;
} // end if ABORT
if ( pins . includes ( 'S' ) ) {
// abort
unpause ( ) ;
var output = {
'command' : '[external from hardware]' ,
'response' : "OpenBuilds CONTROL received a CYCLESTART/RESUME notification from Grbl: This could be due to someone pressing the CYCLESTART/RESUME button (if connected)"
}
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 ) ;
// console.log("BUF: " + JSON.stringify(buffer, null, 2));
status . machine . firmware . buffer = buffer ;
} else {
status . machine . firmware . buffer = [ ] ;
}
2018-06-19 08:07:03 +00:00
// end statusreport
}
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
// console.log('laserTest: ' + 'Power ' + power + ', Duration ' + duration + ', maxS ' + maxS);
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 ;
case 'smoothie' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'M3\n' ) ;
addQToEnd ( 'fire ' + power + '\n' ) ;
2018-06-19 08:07:03 +00:00
laserTestOn = true ;
io . sockets . emit ( 'laserTest' , power ) ;
if ( duration > 0 ) {
var divider = 1 ;
if ( fDate >= new Date ( '2017-01-02' ) ) {
divider = 1000 ;
}
2018-08-09 16:34:51 +00:00
addQToEnd ( 'G4P' + duration / divider + '\n' ) ;
addQToEnd ( 'fire off\n' ) ;
addQToEnd ( 'M5' ) ;
2018-06-19 08:07:03 +00:00
setTimeout ( function ( ) {
laserTestOn = false ;
io . sockets . emit ( 'laserTest' , 0 ) ;
} , duration ) ;
}
send1Q ( ) ;
break ;
}
}
} else {
// console.log('laserTest: ' + 'Power off');
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 ;
case 'smoothie' :
2018-08-09 16:34:51 +00:00
addQToEnd ( 'fire off\n' ) ;
addQToEnd ( 'M5\n' ) ;
2018-06-19 08:07:03 +00:00
send1Q ( ) ;
break ;
}
laserTestOn = false ;
io . sockets . emit ( 'laserTest' , 0 ) ;
}
}
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
}
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" ) {
return GRBL _RX _BUFFER _SIZE - total ;
} else {
return SMOOTHIE _RX _BUFFER _SIZE - total ;
}
}
function send1Q ( ) {
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' ) ;
if ( gcodeQueue [ queuePointer ] . length < spaceLeft ) {
gcode = gcodeQueue [ queuePointer ] ;
queuePointer ++ ;
sentBuffer . push ( gcode ) ;
machineSend ( gcode + '\n' ) ;
2019-01-21 12:46:21 +00:00
// console.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 ;
case 'smoothie' :
if ( ( gcodeQueue . length - queuePointer ) > 0 && ! status . comms . blocked && ! status . comms . paused ) {
gcode = gcodeQueue [ queuePointer ] ;
queuePointer ++ ;
status . comms . blocked = true ;
2018-08-09 17:29:41 +00:00
sentBuffer . push ( gcode ) ;
2018-08-09 16:34:51 +00:00
machineSend ( gcode + '\n' ) ;
// console.log('Sent: ' + gcode + ' Q: ' + (gcodeQueue.length - queuePointer));
}
break ;
}
if ( queuePointer >= gcodeQueue . length ) {
if ( ! status . comms . connectionStatus == 5 ) {
status . comms . connectionStatus = 2 ; // finished
}
clearInterval ( queueCounter ) ;
gcodeQueue . length = 0 ; // Dump the Queye
queuePointer = 0 ;
status . comms . connectionStatus = 2 ; // finished
}
2018-09-27 15:00:49 +00:00
} else {
console . log ( 'Not Connected' )
2018-08-09 16:34:51 +00:00
}
}
function addQToEnd ( gcode ) {
// console.log('added ' + gcode)
gcodeQueue . push ( gcode ) ;
}
function addQToStart ( gcode ) {
gcodeQueue . unshift ( gcode ) ;
}
function addQRealtime ( gcode ) {
// realtime command skip the send1Q as it doesnt respond with an ok
machineSend ( gcode ) ;
}
// 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 ) {
2018-08-23 20:09:27 +00:00
console . log ( "Already running! Check the System Tray" )
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.
// console.log('SingleInstance')
// console.log(commandLine)
2019-05-06 14:31:13 +00:00
lauchGUI = true ;
2019-04-15 17:31:30 +00:00
var openFilePath = commandLine [ 1 ] ;
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 ) {
if ( jogWindow === null ) {
createJogWindow ( ) ;
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
} else {
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
}
}
2019-04-15 17:31:30 +00:00
} )
// Create myWindow, load the rest of the app, etc...
app . on ( 'ready' , ( ) => { } )
2018-06-19 20:25:40 +00:00
}
2019-04-15 17:31:30 +00:00
// Someone tried to run a second instance, we should focus our window.
// if (jogWindow === null) {
// createJogWindow();
// jogWindow.show()
// jogWindow.setAlwaysOnTop(true);
// jogWindow.focus();
// jogWindow.setAlwaysOnTop(false);
// } else {
// jogWindow.show()
// jogWindow.setAlwaysOnTop(true);
// jogWindow.focus();
// jogWindow.setAlwaysOnTop(false);
// }
// // console.log('SingleInstance')
// // console.log(commandLine)
// var openFilePath = commandLine[1];
// if (openFilePath !== "") {
// // console.log(openFilePath);
// readFile(openFilePath);
// }
// if (shouldQuit) {
// console.log("Already running! Check the System Tray")
// electronApp.exit(0);
// electronApp.quit();
// }
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' ) {
2019-06-06 19:11:48 +00:00
console . log ( "Creating MacOS Menu" ) ;
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 !== "" ) {
console . log ( "path" + openFilePath ) ;
readFile ( openFilePath ) ;
}
}
if ( process . platform == 'darwin' || uploadedgcode . length > 1 ) {
2018-08-16 12:50:11 +00:00
if ( jogWindow === null ) {
createJogWindow ( ) ;
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
} else {
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
}
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:"
}
]
} ] ;
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 ( ) {
2018-11-23 16:13:16 +00:00
// console.log("Clicked Systray")
if ( jogWindow === null ) {
createJogWindow ( ) ;
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
} else {
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
}
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 ( ) {
2019-01-16 10:56:25 +00:00
// console.log("Clicked Systray")
if ( jogWindow === null ) {
createJogWindow ( ) ;
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
} else {
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
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 ( ) {
// console.log("Clicked Systray")
if ( jogWindow === null ) {
createJogWindow ( ) ;
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
} else {
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
}
} )
}
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" ,
content : "OpenBuilds CONTROL has started successfully: Active on " + ip . address ( ) + ":" + config . webPort
} )
}
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
2019-04-24 17:47:21 +00:00
width : 870 ,
2018-09-06 21:08:06 +00:00
height : 850 ,
2018-08-23 20:09:27 +00:00
fullscreen : false ,
center : true ,
resizable : true ,
2018-11-23 16:13:16 +00:00
title : "OpenBuilds CONTROL " ,
2018-08-23 20:09:27 +00:00
frame : false ,
autoHideMenuBar : true ,
2018-10-11 17:34:45 +00:00
icon : '/app/favicon.png' ,
webgl : true ,
experimentalFeatures : true ,
experimentalCanvasFeatures : true ,
offscreen : true ,
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/`)
jogWindow . loadURL ( "http://localhost:3000/" ) ;
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 ) {
event . preventDefault ( ) ;
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' , ( ) => {
jogWindow . show ( )
jogWindow . setAlwaysOnTop ( true ) ;
jogWindow . focus ( ) ;
jogWindow . setAlwaysOnTop ( false ) ;
} )
}
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
2019-01-10 17:45:46 +00:00
if ( ! process . platform == 'darwin' ) {
electronApp . setLoginItemSettings ( {
openAtLogin : true ,
args : [ ]
} )
}
2018-08-23 20:09:27 +00:00
}
2019-06-06 18:05:30 +00:00
} else {
var isPi = require ( 'detect-rpi' ) ;
if ( isPi ( ) ) {
console . 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 {
console . log ( "Running under NodeJS..." ) ;
}
2018-06-29 13:01:16 +00:00
}
2018-08-29 08:11:14 +00:00
2019-04-29 17:26:29 +00:00
function stop ( jog ) {
2019-01-21 12:46:21 +00:00
if ( status . comms . connectionStatus > 0 ) {
status . comms . paused = true ;
console . log ( 'STOP' ) ;
switch ( status . machine . firmware . type ) {
case 'grbl' :
2019-04-29 17:26:29 +00:00
if ( jog ) {
addQRealtime ( String . fromCharCode ( 0x85 ) ) ; // canceljog
console . log ( 'Sent: 0x85 Jog Cancel' ) ;
} else {
addQRealtime ( '!' ) ; // hold
console . log ( 'Sent: !' ) ;
}
2019-01-21 12:46:21 +00:00
if ( status . machine . firmware . version === '1.1d' ) {
addQRealtime ( String . fromCharCode ( 0x9E ) ) ; // Stop Spindle/Laser
console . log ( 'Sent: Code(0x9E)' ) ;
}
console . log ( 'Cleaning Queue' ) ;
2019-04-29 17:26:29 +00:00
if ( ! jog ) {
2019-04-18 14:23:51 +00:00
addQRealtime ( String . fromCharCode ( 0x18 ) ) ; // ctrl-x
console . log ( 'Sent: Code(0x18)' ) ;
}
2019-01-21 12:46:21 +00:00
status . comms . connectionStatus = 2 ;
break ;
case 'smoothie' :
status . comms . paused = true ;
addQRealtime ( 'M112' ) ; // ctrl-x
setTimeout ( function ( ) {
addQToEnd ( "?" ) ;
send1Q ( ) ;
} , 1000 ) ;
status . comms . connectionStatus = 5 ;
console . log ( 'Sent: M112' ) ;
break ;
}
clearInterval ( queueCounter ) ;
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' ;
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
}
function pause ( ) {
if ( status . comms . connectionStatus > 0 ) {
status . comms . paused = true ;
console . log ( 'PAUSE' ) ;
switch ( status . machine . firmware . type ) {
case 'grbl' :
addQRealtime ( '!' ) ; // Send hold command
console . log ( 'Sent: !' ) ;
if ( status . machine . firmware . version === '1.1d' ) {
addQRealtime ( String . fromCharCode ( 0x9E ) ) ; // Stop Spindle/Laser
console . log ( 'Sent: Code(0x9E)' ) ;
}
break ;
case 'smoothie' :
addQToStart ( 'M600' ) ; // Laser will be turned off by smoothie (in default config!)
send1Q ( ) ;
console . log ( 'Sent: M600' ) ;
break ;
}
status . comms . runStatus = 'Paused' ;
status . comms . connectionStatus = 4 ;
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
}
function unpause ( ) {
if ( status . comms . connectionStatus > 0 ) {
console . log ( 'UNPAUSE' ) ;
switch ( status . machine . firmware . type ) {
case 'grbl' :
addQRealtime ( '~' ) ; // Send resume command
console . log ( 'Sent: ~' ) ;
break ;
case 'smoothie' :
addQToStart ( 'M601' ) ; // Send resume command
send1Q ( ) ;
console . log ( 'Sent: M601' ) ;
break ;
}
status . comms . paused = false ;
status . comms . blocked = false ;
setTimeout ( function ( ) {
send1Q ( ) ; // restart queue
} , 200 ) ;
status . comms . runStatus = 'Resuming' ;
status . comms . connectionStatus = 3 ;
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
}
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' ) ;
const chrome = spawn ( 'chromium-browser' , [ '-app=http://127.0.0.1:3000' ] ) ;
2019-06-06 19:25:14 +00:00
chrome . on ( 'close' , ( code ) => {
console . log ( ` Chromium process exited with code ${ code } ` ) ;
console . log ( ` If you want to continue using OpenBuildsCONTROL, please open Chromium Browser to http:// ` + ip . address ( ) + ` :3000 ` ) ;
} ) ;
2019-06-06 19:16:43 +00:00
} else {
2019-06-06 19:21:36 +00:00
console . log ( 'Not a Raspberry Pi. Please use Electron Instead' ) ;
2019-06-06 19:11:48 +00:00
}
}
2019-01-10 17:45:46 +00:00
process . on ( 'exit' , ( ) => console . log ( 'exit' ) )