Hello Everyone, I would like to use the onExecute function instead of the onComplete

Hello Everyone, I would like to use the onExecute function instead of the onComplete on the “Watch Gcode oncomplete and control Arduino to turn on and off” macros. Im currently using the following code but it isnt working (It doesnt even show the alerts). Any Ideas? Thanks in advance.

// Watch onComplete and Fire Laser
var myMacro = {
gcode: null, // holds our gcode
init: function() {
// Uninit previous runs to unsubscribe correctly, i.e.
// so we don’t subscribe 100’s of times each time we modify
// and run this macro
if (window[“myMacro”]) {
macro.status(“This macro was run before. Cleaning up…”);
window[“myMacro”].uninit();
}
macro.status(“Starting watch onComplete macro”);
// subscribe to onComplete
chilipeppr.subscribe("/com-chilipeppr-interface-cnccontroller/onExecute", this, this.onExecute);
// store macro in window object so we have it next time thru
window[“myMacro”] = this;
this.getGcode();
},
uninit: function() {
macro.status(“Uninitting macro.”);
chilipeppr.unsubscribe("/com-chilipeppr-interface-cnccontroller/onExecute", this.onExecute);
},
getGcode: function() {
chilipeppr.subscribe("/com-chilipeppr-widget-gcode/recvGcode", this, this.getGcodeCallback);
chilipeppr.publish("/com-chilipeppr-widget-gcode/requestGcode", “”);
chilipeppr.unsubscribe("/com-chilipeppr-widget-gcode/recvGcode", this.getGcodeCallback);
},
getGcodeCallback: function(data) {
this.gcode = data;
},
onExecute: function(data) {
// macro.status(“Got onCompleted. data:” + JSON.stringify(data));
// Id’s from the Gcode widget always start with g
// If you jog, use the serial port console, or do other stuff we’ll
// see callbacks too, but we only want real gcode data here
if (data.Id.match(/^g(\d+)/)) {
// $1 is populated with digits from the .match regex above
var index = parseInt(RegExp.$1);
// our id is always 1 ahead of the gcode.lines array index, i.e.
// line 1 in the widget is this.gcode.lines[0]
var gcodeline = this.gcode.lines[index - 1];

		// Try to match M3, M5, and M30 (program end)
		// The \b is a word boundary so looking for M3 doesn't also
		// hit on M30
		if (gcodeline.match(/\bM3\b/i)) {
			// turn laser off
			alert("Reached a M3");
		} else if (gcodeline.match(/\bM5\b/i)) {
			// turn laser on
			alert("Reached a M5");
		} else if (gcodeline.match(/\bM30\b/i)) {
			macro.status("Done running our gcode. Laser off.");
			chilipeppr.publish("/com-chilipeppr-widget-serialport/ws/send", "send " + this.arduinoSerialPort + " laser-off\n");
			this.uninit();
		}
		
	}
}

}
myMacro.init();

Yeah, onExecute only exists on TinyG, not on Grbl. You never stated what controller you were using, but I’m guessing here.

Sorry I did not state what controller I am using. However, i am using a TinyG as a controller so there should be no problem asking for the onExecute method. Am I using the function incorrectly?

Ahh. Ok, if you’re using TinyG you absolutely should get onExecute callbacks. I recall you MUST have line numbers in your Gcode to get TinyG to send {sr:} reports back, which are what generate the ability to do onExecute callbacks. Are you seeing those in your serial port console as your code runs? Turn off the funnel to see all raw info.

@jlauer I have the “Add line numbers” feature turned on on the G code widget, However i haven’t checked if the TinyG sends {sr:} reports back, will check tommorow and report back to you. Should the code I pasted in the opening post work if the {sr:} responses are working?

Yes, your code looks fine. I would turn back on that macro.status() line though in the 1st line of your onExecute callback to make sure you’re getting that call. You may be, and it may just be your first if statement that’s failing.

Hello again! I changed my code into this and now everything works, however the execute function skips the M commands, and random number lines is there any way to prevent this? I am guessing it skips the M commands because tinyG doesnt execute them and the macros.status prints, the M commands are ignored.

var myMacro = {
gcode: null, // holds our gcode
init: function() {
// Uninit previous runs to unsubscribe correctly, i.e.
// so we don’t subscribe 100’s of times each time we modify
// and run this macro
if (window[“myMacro”]) {
macro.status(“This macro was run before. Cleaning up…”);
window[“myMacro”].uninit();
}
macro.status(“Starting watch onComplete macro”);
// subscribe to onComplete
chilipeppr.subscribe("/com-chilipeppr-interface-cnccontroller/onExecute", this, this.onExecute);
// store macro in window object so we have it next time thru
window[“myMacro”] = this;
this.getGcode();
},
uninit: function() {
macro.status(“Uninitting macro.”);
chilipeppr.unsubscribe("/com-chilipeppr-interface-cnccontroller/onExecute", this.onExecute);
},
getGcode: function() {
chilipeppr.subscribe("/com-chilipeppr-widget-gcode/recvGcode", this, this.getGcodeCallback);
chilipeppr.publish("/com-chilipeppr-widget-gcode/requestGcode", “”);
chilipeppr.unsubscribe("/com-chilipeppr-widget-gcode/recvGcode", this.getGcodeCallback);
},
getGcodeCallback: function(data) {
this.gcode = data;
},
onExecute: function(data) {

// Id’s from the Gcode widget always start with g
// If you jog, use the serial port console, or do other stuff we’ll
// see callbacks too, but we only want real gcode data here

// $1 is populated with digits from the .match regex above
var index = parseInt(data.line);
// our id is always 1 ahead of the gcode.lines array index, i.e.
// line 1 in the widget is this.gcode.lines[0]
var gcodeline = this.gcode.lines[index-1];
macro.status(gcodeline);
// Try to match M3, M5, and M30 (program end)
// The \b is a word boundary so looking for M3 doesn’t also
// hit on M30
if (gcodeline.match(/\bM3\b/i)) {
// turn laser off
alert(“Reached a M3”);
} else if (gcodeline.match(/\bM5\b/i)) {
// turn laser on
alert(“Reached a M5”);
} else if (gcodeline.match(/\bM30\b/i)) {
macro.status(“Done running our gcode. Laser off.”);
chilipeppr.publish("/com-chilipeppr-widget-serialport/ws/send", “send " + this.arduinoSerialPort + " laser-off\n”);
this.uninit();
}

}
}
myMacro.init();

I do think TinyG sends an onExecute {sr:} update on M3 and M5. The first thing that jumps out at me is to not call window.alert() like you are because that hard pauses JavaScript execution and thus you could lose events off the stack (maybe, not sure). Instead just send your debug to the console or that macro.status() method to not pause your code.

When you say it skips other random number lines, did you verify you didn’t get an {sr:} in the serial port console for those?