Is there a reliable way to determine if a print job is in progress?

I have a few shell scripts that i use to keep my various hosts configured as I expect.

I'd like to gate them with a simple is_printer_printing_right_now.sh or similar. My question is what - if any - way is there to tell that the printer is currently printing?

my initial thought was to check either via API call or if the UART seems to be connected/in use, but i figured i'd check here to see if there was something simpler and more reliable, first.

Thanks for any suggestions!

A REST api call would do the trick. Specifically looking into the state part returned.

http://docs.octoprint.org/en/master/api/printer.html#retrieve-the-current-printer-state

1 Like

And if you're comfortable with NodeJS you could use my octo-client module.

isPrinting.js:

var OctoPrint = require('octo-client');

OctoPrint.printerState(function(ptr){
  if (ptr.state.flags.operational) {
    var isPrinting = ptr.state.flags.printing;
    console.log(isPrinting);
  }
});

Thank you both for a quick reply!

I was hesitant to leave an API token on disk (one more $thing to update if/when the API token gets rotated and one more $thing to update if the API ever changes) but the API is simple enough that a bit of curl+jq magic should do exactly what I need.

Here's what I came up with:

Note:

I don't know if this is by design (and, if it is, please reconsider that choice!!!!!!!) but the API does not always return JSON. If the printer is not powered up or otherwise connected, no JSON just plain text.

If somebody can point me in the direction of the source, i'll be more than happy to submit a PR so that the API always returns parse-able JSON

Anyways.

Make sure that curl and jq are installed.
Feel free to submit feedback and improvements.
It took me 15 min to write and the "code" is 100% open, so the license is "use as you see fit, you're on your own"

You will need to make a file w/ your API key in it. Format is any format that will work with source.
Here's what mine looks like:

me@octoprint-host:~ $ cat api.key
##
# This is the API key for octoprint API
# Used by is_printer_in_use_now.sh for gating certain
# systemd processes. Keep confidential!
API_KEY=<api_key_here>

And here's the script:

#!/bin/bash
##
# A very simple script to determine if Octoprint is currently connected to a printer and
#   if that printer is currently in use.
#
# This script is intended to be used with ExecStartPre or similar systemd.service directives
#   so that services and operations can be defered/gated until there is no in-progress print.
#
# Note: This will *not* prevent octoprint from starting a print job *while* various sytem tasks
#   or services are running, however!
#
# v1.0.2
##
# OctoPrint API requires all requests to be authenitcated. Pass in an API token via header.
# This is the location of the file that has the API key. Must be a simple text file with format:
#
#    API_KEY=your_32_character_api_key_here
##
KEY_FILE='./api.key'

##
# The host string
OCTOPI_HOST_STRING='localhost'

##
# Additionally, the API does not *always* return JSON. Annoying, but there are far worse sins
#   to commit in API design. We'll check the payload for this string specifically to determine
#   if we need to parse the API payload as JSON or not.
##
STATUS_NOT_OPERATIONAL='Printer is not operational'

##
# If we do decide that the API payload is JSON, this is the path we'll want jq to pull out
##
JQ_STATUS_PATH='.state.flags.printing'


##
# With init variables out of the way, begin pre-flight checks...
##
# Is the key-file present?
if ! [ -f "$KEY_FILE" ]; then
    echo "[E]   Can't access \$KEY_FILE. Can't continue!"
    exit 1
fi

# Do we have the necessary programs?
if ! [ -x "$(command -v jq)" ]; then
    echo "[E]   the required program jq is not installed"
    exit 1
fi

if ! [ -x "$(command -v curl)" ]; then
    echo "[E]   the required program curl is not installed"
    exit 1
fi

##
# Ok, ready to go!
echo "[I]   pre-flight checks passed. Inquiring about printer status..."
# Load Key File
source $KEY_FILE

##
# We know that JQ is installed, so make the curl call and look @ the results
# Tell curl to follow any redirects, ignore any SSL errors and don't bother with any progress bars
CURL_OUT_RAW=$(curl --insecure -L --silent --header 'Content-Typplication/json' \
--header "X-Api-Key: $API_KEY" http://$OCTOPI_HOST_STRING/api/printer?exclude=temperature,sd)

# Dump to console
echo "[D]   \$CURL_OUT_RAW: $CURL_OUT_RAW"

##
# Now we need to check if the payload is JSON or not...
if [[ "$CURL_OUT_RAW" == "$STATUS_NOT_OPERATIONAL" ]]; then
    echo "[I]   It appears that the printer is not currently connected"
    # printer is not printing, so return no error
    return 0
else
    echo "[I]   It appears that the printer is connected... checking status"
    JQ_RESULT=$( echo $CURL_OUT_RAW | jq -r $JQ_STATUS_PATH)
fi

echo "[D]   \$JQ_RESULT: $JQ_RESULT"


if [[ "$JQ_RESULT" == "false" ]]; then
    echo "[I]   It appears that the printer is not currently printing"
    # printer is not printing, so return no error
    return 0
else
    echo "[I]   It appears that the printer is currently printing"
    return 1
fi

I am fairly certain it is, and that it is the proper design choice. The API doesn't just return text, it also returns an HTTP status code. The returned data is parsable json only if the status code doesn't indicate an error. It would be strange to wrap errors into json. Or would you expect eg a 404 error to also show json data?

Any client should first look at the HTTP status code before considering to parse the output as json.

Having said that, the source is here: https://github.com/foosel/octoprint

1 Like

In those instances, I think the response code returned is 409, so you could check against that.