2018-06-26 10:33:13 +00:00
console . log ( "Starting OpenBuilds Machine Driver v" + require ( './package' ) . version )
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 ( ) ;
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-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 ;
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 ;
2018-08-23 20:09:27 +00:00
if ( isElectron ( ) ) {
console . log ( "Local User Data: " + electronApp . getPath ( 'userData' ) )
}
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
2018-07-16 17:24:09 +00:00
2018-07-11 09:02:41 +00:00
var appIcon = null ,
jogWindow = null ,
mainWindow = null
2018-07-11 12:39:24 +00:00
2018-08-23 20:09:27 +00:00
if ( isElectron ( ) ) {
const autoUpdater = require ( "electron-updater" ) . autoUpdater
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 ) ;
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "OpenBuilds Machine Driver" ,
content : string
} )
}
2018-08-23 20:09:27 +00:00
} )
autoUpdater . on ( 'update-available' , ( ev , info ) => {
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 ) )
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "OpenBuilds Machine Driver" ,
content : string
} )
}
} )
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 ) )
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "OpenBuilds Machine Driver" ,
content : string
} )
}
} )
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 ) ;
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "OpenBuilds Machine Driver" ,
content : string
} )
}
} )
autoUpdater . on ( 'download-progress' , ( ev , progressObj ) => {
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 ) ) ;
if ( ev . percent % 10 === 0 ) {
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "OpenBuilds Machine Driver" ,
content : string
} )
}
}
} )
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 ) ;
} , 15 * 60 * 1000 ) // 5 mins
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "OpenBuilds Machine Driver" ,
content : string
} )
}
} ) ;
}
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-07-11 09:02:41 +00:00
2018-08-13 17:22:26 +00:00
// fs.existsSync(uploadsDir) || fs.mkdirSync(uploadsDir)
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 ;
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 ;
//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 ,
ipaddress : ip . address ( )
2018-06-26 10:33:13 +00:00
} ,
2018-06-19 08:07:03 +00:00
machine : {
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 //
} ,
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 : ""
}
} ;
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 ) ;
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "Driver Detected a new Port" ,
content : "OpenBuilds Machine Driver detected a new port: " + newPorts [ 0 ] . comName
} )
}
2018-06-22 19:49:51 +00:00
}
var removedPorts = _ . differenceWith ( oldportslist , ports , _ . isEqual )
if ( removedPorts . length > 0 ) {
console . log ( "Unplugged " + removedPorts [ 0 ] . comName ) ;
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "Driver Detected a disconnected Port" ,
content : "OpenBuilds Machine Driver detected that port: " + removedPorts [ 0 ] . comName + " was removed"
} )
}
2018-06-22 19:49:51 +00:00
}
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
// Static Webserver
2018-06-19 08:07:03 +00:00
app . use ( express . static ( path . join ( _ _dirname , "app" ) ) ) ;
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" ) ;
res . send ( 'Host: ' + req . hostname + ' asked to activate OpenBuildsMachineDriver v' + require ( './package' ) . version ) ;
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' ) ;
} )
// 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" ) ;
2018-06-27 14:08:24 +00:00
// console.log(req)
uploadprogress = 0
var form = new formidable . IncomingForm ( ) ;
2018-08-07 17:34:04 +00:00
form . parse ( req , function ( err , fields , 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
}
setTimeout ( function ( ) {
2018-07-11 09:02:41 +00:00
2018-06-29 19:48:34 +00:00
fs . readFile ( file . path , 'utf8' ,
function ( err , data ) {
if ( err ) {
console . log ( err ) ;
2018-07-11 18:58:38 +00:00
var output = {
'command' : '' ,
'response' : "ERROR: File Upload Failed"
}
io . sockets . emit ( 'data' , output ) ;
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "ERROR: File Upload Failed" ,
content : "OpenBuilds Machine Driver ERROR: File Upload Failed"
} )
}
2018-06-29 19:48:34 +00:00
}
2018-07-11 09:02:41 +00:00
if ( data ) {
io . sockets . emit ( 'gcodeupload' , data ) ;
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "GCODE Received" ,
content : "OpenBuilds Machine Driver received new GCODE"
} )
}
2018-07-11 09:02:41 +00:00
}
2018-06-29 19:48:34 +00:00
} ) ;
2018-07-03 20:28:02 +00:00
} , 1500 ) ;
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' ) {
socket . emit ( 'grbl' )
}
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
2018-07-26 20:22:07 +00:00
socket . on ( "opencam" , function ( data ) {
const {
shell
} = require ( 'electron' )
shell . openExternal ( 'https://cam.openbuilds.com' )
} ) ;
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 ) {
appIcon . destroy ( ) ;
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-07-12 13:06:53 +00:00
autoUpdater . checkForUpdates ( ) ;
} )
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 ] , {
parser : serialport . parsers . readline ( '\n' ) ,
baudRate : parseInt ( data [ 2 ] )
} ) ;
port . on ( "error" , function ( err ) {
console . log ( "Error: " , err . message ) ;
2018-07-24 12:58:26 +00:00
var output = {
'command' : '' ,
'response' : "PORT ERROR: " + err . message
}
io . sockets . emit ( 'data' , output ) ;
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "Driver encountered a Port error" ,
content : "OpenBuilds Machine Driver received the following error: " + err . message
} )
}
2018-07-24 12:58:26 +00:00
if ( status . comms . connectionStatus > 0 ) {
console . log ( 'WARN: Closing Port ' + port . path ) ;
stopPort ( ) ;
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
2018-06-19 08:07:03 +00:00
} ) ;
port . on ( "open" , function ( ) {
2018-07-11 18:58:38 +00:00
var output = {
'command' : '' ,
'response' : "PORT INFO: Opening USB Port"
}
io . sockets . emit ( 'data' , output ) ;
2018-06-19 08:07:03 +00:00
status . comms . connectionStatus = 1 ;
if ( config . resetOnConnect == 1 ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 0x18 ) ) ; // ctrl-x (needed for rx/tx connection)
2018-06-19 08:07:03 +00:00
console . log ( "Sent: ctrl-x" ) ;
} else {
2018-08-09 16:34:51 +00:00
addQRealtime ( "\n" ) ; // this causes smoothie to send the welcome string
2018-06-19 08:07:03 +00:00
}
setTimeout ( function ( ) { //wait for controller to be ready
if ( status . machine . firmware . type . length < 1 ) {
console . log ( "No GRBL, lets see if we have Smoothie?" ) ;
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" ) ;
}
} , config . grblWaitTime * 1000 ) ;
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 ) ;
stopPort ( ) ;
}
} , config . firmwareWaitTime * 1000 ) ;
}
console . log ( "PORT INFO: Connected to " + port . path + " at " + port . options . baudRate ) ;
2018-07-11 18:58:38 +00:00
var output = {
'command' : '' ,
'response' : "PORT INFO: Port is now open: " + port . path + " - Attempting to detect Firmware"
}
io . sockets . emit ( 'data' , output ) ;
2018-06-19 08:07:03 +00:00
status . comms . connectionStatus = 2 ;
status . comms . interfaces . activePort = port . path ;
status . comms . interfaces . activeBaud = port . options . baudRate ;
} ) ; // 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 = {
'command' : '' ,
'response' : "PORT INFO: Port closed"
}
io . sockets . emit ( 'data' , output ) ;
2018-06-19 08:07:03 +00:00
} ) ; // end port.onclose
port . on ( "data" , function ( data ) {
2018-08-09 16:34:51 +00:00
var command = sentBuffer [ 0 ] ;
2018-06-19 08:07:03 +00:00
// Machine Identification
if ( data . indexOf ( "Grbl" ) === 0 ) { // Check if it's Grbl
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
if ( status . comms . connectionStatus > 0 ) {
console . log ( 'WARN: Closing Port ' + port . path ) ;
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-06-19 08:07:03 +00:00
status . machine . firmware . date = "" ;
console . log ( "GRBL detected" ) ;
2018-06-21 20:02:40 +00:00
socket . emit ( 'grbl' )
2018-08-09 16:34:51 +00:00
addQRealtime ( "$10=2\n" ) ; // force Status Report to WPOS
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "Driver has established a Connection" ,
content : "OpenBuilds Machine Driver is now connected to " + status . comms . interfaces . activePort + " running " + status . machine . firmware . type + " " + status . machine . firmware . version
} )
}
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" ) ;
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "Driver has established a Connection" ,
content : "OpenBuilds Machine Driver is now connected to " + status . comms . interfaces . activePort + " running " + status . machine . firmware . type + " " + status . machine . firmware . version
} )
}
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
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) {
console . log ( "ALARM: " + data )
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 )
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 ) ;
2018-06-25 20:13:58 +00:00
socket . 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-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
if ( command ) {
command = command . replace ( /(\r\n|\n|\r)/gm , "" ) ;
// console.log("CMD: " + command + " / DATA RECV: " + data.replace(/(\r\n|\n|\r)/gm, ""));
if ( command != "?" && command != "M105" && data . length > 0 ) {
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-06-19 08:07:03 +00:00
} ) ; // end of parser.on(data)
}
} ) ;
socket . on ( 'saveToSd' , function ( datapack ) {
saveToSd ( datapack ) ;
} ) ;
socket . on ( 'runJob' , function ( data ) {
2018-08-08 12:31:59 +00:00
// console.log(data)
2018-06-19 08:07:03 +00:00
console . log ( 'Run Job (' + data . length + ')' ) ;
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 ;
}
}
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "Driver: Job Started" ,
content : "OpenBuilds Machine Driver started a job: Job Size: " + data . length + " lines of GCODE"
} )
}
2018-06-19 08:07:03 +00:00
} 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!' ) ;
}
} ) ;
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 ) {
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' :
2018-08-09 16:34:51 +00:00
addQToEnd ( '$J=G91' + 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' :
addQToEnd ( '$J=G91 X' + xincrement + " Y" + yincrement + " " + feed ) ;
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' :
2018-08-09 16:34:51 +00:00
addQToEnd ( '$J=G91' + 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 ( ) ;
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "Driver: Work Coordinate System Reset" ,
content : "OpenBuilds Machine Driver has reset the WCS on the " + data + " axes."
} )
}
2018-06-19 08:07:03 +00:00
} 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 ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 144 ) ) ;
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" )
for ( i = 0 ; i < tens ; i ++ ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 145 ) ) ;
2018-06-19 08:07:03 +00:00
}
var ones = delta - ( 10 * tens ) ;
console . log ( "need to send " + ones + " x1s increase" )
for ( i = 0 ; i < ones ; i ++ ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 147 ) ) ;
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" )
for ( i = 0 ; i < tens ; i ++ ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 146 ) ) ;
2018-06-19 08:07:03 +00:00
}
var ones = delta - ( 10 * tens ) ;
console . log ( "need to send " + ones + " x1s decrease" )
for ( i = 0 ; i < tens ; i ++ ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 148 ) ) ;
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" )
for ( i = 0 ; i < tens ; i ++ ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 154 ) ) ;
2018-06-19 08:07:03 +00:00
}
var ones = delta - ( 10 * tens ) ;
console . log ( "need to send " + ones + " x1s increase" )
for ( i = 0 ; i < ones ; i ++ ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 156 ) ) ;
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" )
for ( i = 0 ; i < tens ; i ++ ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 155 ) ) ;
2018-06-19 08:07:03 +00:00
}
var ones = delta - ( 10 * tens ) ;
console . log ( "need to send " + ones + " x1s decrease" )
for ( i = 0 ; i < tens ; i ++ ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 157 ) ) ;
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 ( ) {
if ( status . comms . connectionStatus > 0 ) {
status . comms . paused = true ;
console . log ( 'PAUSE' ) ;
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-08-09 16:34:51 +00:00
addQRealtime ( '!' ) ; // Send hold command
2018-06-19 08:07:03 +00:00
console . log ( 'Sent: !' ) ;
2018-06-22 19:49:51 +00:00
if ( status . machine . firmware . version === '1.1d' ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 0x9E ) ) ; // Stop Spindle/Laser
2018-06-19 08:07:03 +00:00
console . log ( 'Sent: Code(0x9E)' ) ;
}
break ;
case 'smoothie' :
2018-08-09 16:34:51 +00:00
addQToStart ( 'M600' ) ; // Laser will be turned off by smoothie (in default config!)
send1Q ( ) ;
2018-06-19 08:07:03 +00:00
console . log ( 'Sent: M600' ) ;
break ;
}
status . comms . runStatus = 'Paused' ;
status . comms . connectionStatus = 4 ;
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "Driver: Job Paused" ,
content : "OpenBuilds Machine Driver paused the job"
} )
}
2018-06-19 08:07:03 +00:00
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
socket . on ( 'resume' , function ( ) {
if ( status . comms . connectionStatus > 0 ) {
console . log ( 'UNPAUSE' ) ;
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-08-09 16:34:51 +00:00
addQRealtime ( '~' ) ; // Send resume command
2018-06-19 08:07:03 +00:00
console . log ( 'Sent: ~' ) ;
break ;
case 'smoothie' :
2018-08-09 16:34:51 +00:00
addQToStart ( 'M601' ) ; // Send resume command
send1Q ( ) ;
2018-06-19 08:07:03 +00:00
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 ;
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "Driver: Job Resumed" ,
content : "OpenBuilds Machine Driver resumed the job"
} )
}
2018-06-19 08:07:03 +00:00
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
socket . on ( 'stop' , function ( ) {
if ( status . comms . connectionStatus > 0 ) {
status . comms . paused = true ;
console . log ( 'STOP' ) ;
switch ( status . machine . firmware . type ) {
case 'grbl' :
2018-08-09 16:34:51 +00:00
addQRealtime ( '!' ) ; // hold
2018-06-19 08:07:03 +00:00
console . log ( 'Sent: !' ) ;
2018-06-21 20:02:40 +00:00
if ( status . machine . firmware . version === '1.1d' ) {
2018-08-09 16:34:51 +00:00
addQRealtime ( String . fromCharCode ( 0x9E ) ) ; // Stop Spindle/Laser
2018-06-19 08:07:03 +00:00
console . log ( 'Sent: Code(0x9E)' ) ;
}
console . log ( 'Cleaning Queue' ) ;
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)' ) ;
2018-08-09 17:29:41 +00:00
status . comms . connectionStatus = 2 ;
2018-06-19 08:07:03 +00:00
break ;
case 'smoothie' :
status . comms . paused = true ;
2018-08-09 16:34:51 +00:00
addQRealtime ( 'M112' ) ; // ctrl-x
2018-08-09 17:29:41 +00:00
setTimeout ( function ( ) {
addQToEnd ( "?" ) ;
send1Q ( ) ;
} , 1000 ) ;
status . comms . connectionStatus = 5 ;
2018-06-19 08:07:03 +00:00
console . log ( 'Sent: M112' ) ;
break ;
}
clearInterval ( queueCounter ) ;
status . comms . queue = 0
queuePointer = 0 ;
gcodeQueue . length = 0 ; // Dump the queue
2018-08-09 17:29:41 +00:00
sentBuffer . 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
laserTestOn = false ;
status . comms . blocked = false ;
status . comms . paused = false ;
status . comms . runStatus = 'Stopped' ;
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "Driver: Job Aborted" ,
content : "OpenBuilds Machine Driver was asked to abort the running job."
} )
}
2018-06-19 08:07:03 +00:00
// status.comms.connectionStatus = 2;
} else {
console . log ( 'ERROR: Machine connection not open!' ) ;
}
} ) ;
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' ) ;
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-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 ;
2018-08-07 10:05:49 +00:00
if ( jogWindow && ! jogWindow . isFocused ( ) ) {
2018-08-06 17:19:25 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "Driver: Alarm Cleared" ,
content : "OpenBuilds Machine Driver has cleared the Alarm Condition, you may continue"
} )
}
2018-06-19 08:07:03 +00:00
} 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!' ) ;
}
} ) ;
} ) ;
function machineSend ( gcode ) {
2018-06-25 17:25:19 +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-08-09 16:34:51 +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" ) {
// 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 ( /,/ ) ;
}
if ( Array . isArray ( wPos ) ) {
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
}
} // END IS WPOS
// 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 ;
}
}
}
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 ( '' )
// console.log("PINS: " + JSON.stringify(pins, null, 2));
status . machine . inputs = pins ;
} else {
status . machine . inputs = [ ] ;
}
// 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' ) ;
// console.log('Sent: ' + gcode + ' Q: ' + (gcodeQueue.length - queuePointer) + ' Bspace: ' + (spaceLeft - gcode.length - 1));
} 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 ) ;
2018-08-24 19:00:03 +00:00
// if (jogWindow && !jogWindow.isFocused()) {
// appIcon.displayBalloon({
// icon: nativeImage.createFromPath(iconPath),
// title: "Driver: Job Completed!",
// content: "OpenBuilds Machine Driver completed a Job"
// })
// }
2018-08-09 16:34:51 +00:00
gcodeQueue . length = 0 ; // Dump the Queye
// sentBuffer.length = 0; // Dump bufferSizes
queuePointer = 0 ;
status . comms . connectionStatus = 2 ; // finished
// status.comms.runStatus = "Finished"
}
}
}
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 ( ) ) {
const shouldQuit = electronApp . makeSingleInstance ( ( commandLine , workingDirectory ) => {
// 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 ) ;
2018-08-14 18:16:49 +00:00
}
2018-08-23 20:09:27 +00:00
} ) ;
if ( shouldQuit ) {
console . log ( "Already running! Check the System Tray" )
electronApp . exit ( 0 ) ;
electronApp . quit ( ) ;
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 ( ) ;
if ( process . platform == 'darwin' ) {
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
}
// createWindow();
// createJogWindow();
}
2018-06-25 17:25:19 +00:00
2018-08-23 20:09:27 +00:00
function createTrayIcon ( ) {
if ( process . platform !== 'darwin' ) {
appIcon = new Tray (
nativeImage . createFromPath ( iconPath )
)
const contextMenu = Menu . buildFromTemplate ( [ {
label : 'Quit Machine Driver (Disables all integration until started again)' ,
click ( ) {
appIcon . destroy ( ) ;
electronApp . exit ( 0 ) ;
}
} ] )
appIcon . on ( '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-08-16 12:50:11 +00:00
2018-08-23 20:09:27 +00:00
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
appIcon . setContextMenu ( contextMenu )
2018-08-06 17:19:25 +00:00
2018-08-23 20:09:27 +00:00
appIcon . displayBalloon ( {
icon : nativeImage . createFromPath ( iconPath ) ,
title : "Driver Started" ,
content : "OpenBuilds Machine Driver has started successfully: Active on " + ip . address ( ) + ":" + config . webPort
} )
} else {
const dockMenu = Menu . buildFromTemplate ( [ {
label : 'Quit Machine Driver (Disables all integration until started again)' ,
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 ( {
width : 660 ,
height : 730 ,
fullscreen : false ,
center : true ,
resizable : true ,
title : "OpenBuilds Machine Driver " ,
frame : false ,
autoHideMenuBar : true ,
icon : '/app/favicon.png'
} ) ;
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 ) {
event . preventDefault ( ) ;
jogWindow . hide ( ) ;
return false ;
} ) ;
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 ) ;
} )
// jogWindow.maximize()
// jogWindow.webContents.openDevTools()
2018-06-19 08:07:03 +00:00
2018-08-23 20:09:27 +00:00
}
2018-06-19 08:07:03 +00:00
2018-08-23 20:09:27 +00:00
function createWindow ( ) {
// Create the browser window.
mainWindow = new BrowserWindow ( {
width : 1200 ,
height : 900 ,
fullscreen : false ,
center : true ,
resizable : true ,
title : "OpenBuilds Machine Driver " ,
frame : true ,
autoHideMenuBar : true ,
icon : '/app/favicon.png'
} ) ;
// and load the index.html of the app.
// mainWindow.loadURL('file://' + __dirname + '/app/index.html');
// mainWindow.loadURL(`file://${__dirname}/app/index.html`)
var ipaddr = ip . address ( ) ;
// mainWindow.loadURL(`//` + ipaddr + `:3000/`)
mainWindow . loadURL ( "http://localhost:3000" ) ;
mainWindow . on ( 'close' , function ( event ) {
event . preventDefault ( ) ;
mainWindow . hide ( ) ;
return false ;
} ) ;
2018-06-19 20:25:40 +00:00
2018-08-23 20:09:27 +00:00
// Emitted when the window is closed.
mainWindow . 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.
mainWindow = null ;
} ) ;
mainWindow . once ( 'ready-to-show' , ( ) => {
mainWindow . show ( )
} )
mainWindow . maximize ( )
// mainWindow.webContents.openDevTools()
} ;
2018-06-19 08:07:03 +00:00
2018-08-23 20:09:27 +00:00
// electronApp.commandLine.appendSwitch("--ignore-gpu-blacklist");
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
2018-08-23 20:09:27 +00:00
electronApp . on ( 'will-quit' , function ( event ) {
event . preventDefault ( )
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if ( process . platform !== 'darwin' ) {
electronApp . quit ( ) ;
appIcon . destroy ( ) ;
}
2018-07-24 15:25:35 +00:00
electronApp . quit ( ) ;
appIcon . destroy ( ) ;
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
if ( process . platform !== 'darwin' ) {
electronApp . quit ( ) ;
appIcon . destroy ( ) ;
}
2018-06-19 08:07:03 +00:00
electronApp . quit ( ) ;
2018-06-19 20:25:40 +00:00
appIcon . destroy ( ) ;
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
electronApp . setLoginItemSettings ( {
openAtLogin : true ,
args : [ ]
} )
}
2018-06-29 13:01:16 +00:00
}
2018-07-24 15:25:35 +00:00
process . on ( 'exit' , ( ) => console . log ( 'exit' ) )