job.timesLeft.file returns null
-
Hello everyone,
for a specific project i need to print at controlled timing and speed so the print lasts for a specific amount of time, one year, whatever the job time is.
I recently got kicked out of several different prints when trying to reduce speed factor below 10% (on another print i remember trying 5% with no issues though).
; from eventlog.txt 2024-01-26 00:03:09 [warn] Error: in file macro line 12 column 45: meta command: expected numeric operands 2024-01-26 00:03:09 [warn] Cancelled printing file 0:/gcodes/test transparence cbmp.gcode, print time was 11h 10m
After investigation it was because I was using job.timesLeft.file in some operations while it returned null. Any idea how/why this might happen and how I could solve this ? Estimated print time too long ? Not enough file progress in between 2 checks ?
// in PrintMonitor.cpp fileProgressRate = 1000.0 * (currentFraction - lastSnapshotFileFraction)/printTimeSinceLastSnapshot; //(...) case fileBased: if (lastSnapshotTime != printStartTime && fileProgressRate > 0.0) { return (1.0 - FractionOfFilePrinted())/fileProgressRate; } break;
For the moment I added if statements in my macros to check whether it's null or not but then I have to put an arbitrary value which will skew the timing.
Thank you in advance
Best -
@modl If the estimated time is less than or equal to zero,
null
is returned. -
@chrishamm Thank you for your reply
That's what i am trying to understand, the print was not finished when i got returned null.
Basically my macro is called at every layer change and adjusts print speed and eventually issues a G4 S{var.calculatedvalue} .
Last time this happened i was already 90% into the print and last layers were showing around 15h print time left at 20% speed, based on job.timesLeft.file. Then i slowed down the print some more (M220 S10), and after a few layer changes, it returned null, while it should have been somewhere around 30h.
Can it be the other way around and fileProgressRate is so small that the returned value is overflowing ? -
Hi again,
here is what's happening, out of nowhere in between two random layers, job.timesLeft.file returns null,and I still don't understand the cause.
I hope someone can shed some light on thisThank you in advance
-
@modl are you running in standalone mode or with attached SBC ?
Is it possible that your print file was running a macro or changing tool when you had that "null" value? If so, could that macro or tool change have taken longer than 30 seconds to execute?
-
@dc42 Thank you for your reply
It is running in standalone mode.
The macro is called in between layer changes. There's an M116 in my tool change routine and I recently lowered the standby temperature so it indeed takes longer to heat back up. However I use prusa slicer, it groups layers so that it will print 2 layers with 1 tool then 2 with the other, etc... so layer change happens in between 2 tool changes. Hope that makes sense. Basically M116 is definitely executed when the macro is called.My print file gcode looks like this on layer changes
;LAYER_CHANGE ;Z:23.46 ;HEIGHT:0.119999 set global.layerNumber = 194 M98 P"0:/macros/storelayernumber.g" G1 Z23.46 F240 M98 P"0:/macros/pausetimer.g" G1 E-3 F3000 G1 X177.321 Y497.259 F7800 G1 X178.761 Y492.757 Z23.543 F7803.691 G1 Z23.46 F240 G1 E3 F3000 ;TYPE:Perimeter ;WIDTH:0.224999
job.timesLeft.file is echoed at the beginning of the test macro, so nothing is running before that
; pausetimer.g macro calculates how long a print needs to be paused between each layer for the print to take exactly one year to finish (or the amount of time decided in start.g) var pauseTimer = 0 var timeleft = global.endTime - state.time echo "Job time left (file, test)" , job.timesLeft.file if job.timesLeft.file != null var totalTimeLeft = var.timeleft - job.timesLeft.file else var totalTimeLeft = var.timeleft if job.timesLeft.file != null var secondsleft = mod(job.timesLeft.file, 60) var minutesleftinsec = mod(job.timesLeft.file - var.secondsleft, 3600) var hoursleftinsec = mod(job.timesLeft.file - var.minutesleftinsec - var.secondsleft, 86400) var daysleftinsec = job.timesLeft.file - var.hoursleftinsec - var.minutesleftinsec - var.secondsleft var minutesleft = var.minutesleftinsec / 60 var hoursleft = var.hoursleftinsec / 3600 var daysleft = var.daysleftinsec / 86400 echo "Global endtime: ", global.endTime, "; Current time: ", state.time, "; Job time left if no pauses " ^ floor(var.daysleft) ^ "d " ^ floor(var.hoursleft) ^ "h " ^ floor(var.minutesleft) ^ "m " ^ floor(var.secondsleft) ^ "s" else echo "Time left for a 1 year print: ", var.timeleft ,"and job.timesLeft.file is out of range: ", job.timesLeft.file var layersLeft = global.totalLayerCount - global.layerNumber ; how many layers are left as per the slicer which is more accuratethat the firmware in case of a shutdown echo "Current layer: " ^ global.layerNumber ^ "/" ^ global.totalLayerCount ^ " (" ^ var.layersLeft ^ " layers remaining)" if job.file.fileName == "0:/gcodes/xatardiascabra.gcode" ; for this macro to have an effect the file must be called this way, this is to prevent long print times for test files named differently (obviously if global.totalLayerCount > global.layerNumber && global.layerNumber > 1 && state.time < global.endTime set var.pauseTimer = var.totalTimeLeft / var.layersLeft echo "Print pausing for ",var.pauseTimer,"s" else set var.pauseTimer = 0 echo "1 year has already passed since the start of this print, not pausing" G4 S{var.pauseTimer} else echo "No pause between layer"
; storelayernumber.g stores the current layer number according to slicer, for restoring in case of power failure echo >"0:/macros/layernumberglobal.g" "set global.layerNumber =", global.layerNumber
-
@modl thanks. I've reviewed the code, and what I think is happening is that RRF made no progress through the file for 30 seconds. As it uses the rate of progress (which it calculates about every 30 seconds) and the remaining file size to estimate the time left, it can't calculate that estimate when no progress is being made; so it returns null.
-
@dc42 Thank you, it sounds plausible. I'll try to write some code for deamon.g to mitigate the null case (like store the last available correct value in a global and use that instead)