Trigger macro on stalled, paused or completed process

Is there a trigger to begin a macro when an app’s process is either stalled, paused, or complete?

Generally, no, since these aren't "events" in macOS terms -- the exception might be "complete" if that means the application quits.

You could, instead, perform regular state checks to see if any of those conditions are true. The checks would very much depend on the app/process -- do you something particular in mind?

Specifically, I'm looking to clear a screen from completed transcoded videos. I've got the actions with no issue, but am having trouble creating the trigger once one or a series of videos are transcoded.

By perform regular state checks, I assume you mean visually check myself, versus using an automated state check. If by automated, this would function just as well. Is there a trigger for beginning a macro on a change in state (or if a state has not changed in X time)? Thanks.

No -- because, again, these aren't "events". So you'll have to check using action(s) in your macro for whether something is, or isn't, happening.

Depending on the software/workflow you could wait until a progress bar is no longer on the screen, a menu item is or isn't available, a dialog appears, an entry appears in a log file... You could use file sizes -- when file x stops changing. File locks through the lsof shell command. You could even monitor the process's resource use -- "if below 5% CPU for >30s, job is finished".

And there are plenty of other methods -- which to use will depend on your software and workflow. Most will involve you running a KM macro either periodically -- every minute, say -- or "permanently" using an infinite loop that checks, pauses, loops back and checks, pauses...

Since Nige has responded, and his answers are usually twice as good as mine, you don't have to read my response. But I'm still responding anyway because it helps me "wake up."

As for the condition "stalled", there might be some specific cases where it's possible for that condition to be correctly tested, such as if this equivalent for a machine code instruction was ever executed:

Line 100: GOTO 100

But in general, this problem is called "The Halting Problem" which is mathematically proven to be impossible to detect for any computer program.

Despite that being true, it is sometimes possible, to detect if a program is "stalled," even by a KM macro. You said,

That sounds possible, because that's testing for "completion" not for "stalling." You or I just need to describe how you can tell if the app looks when it is "complete." And as my next paragraph explains, we can use this information to detect if some test hasn't returned a certain value in N seconds, so that's similar to testing for a "stall condition."

No, there's no "trigger", but I solve this all the time in my macros by "polling"! It's not hard. When I need a variable to record the last time my macro saw some condition in another app, I always create a variable named like this: "TimeLastX" (meaning "the time of the last X condition") . And I either assign that variable the value of "TIME()" or "SECONDS()". I have about 30 variables starting with the letters "TimeLast" like "TimeLastPrint". In this way I can write code that either takes action if some condition HAS or HASN'T occurred in the last N seconds. Here's an example of some code that I use to make sure I execute something only if it has been at least 15 seconds since the last time I detected a condition...

image

Thanks again. I like the approach to monitoring CPU usage for the specific app. I believe this would satisfy what I'm attempting. Can you point me in a direction for where to start regarding a trigger that would execute actions when CPU usage for X app falls below a certain percent?

Not answering the question in the the threads title here now, but it sounds to me like you could get something close to what you want monitoring the render files instead of the app itself. As a rendering video file usually have a continuously growing file size you could monitor for whenever the file size stops changing.

Just very quickly threw together this kind of messy test here now to demonstrate how I’m thinking. This test macro is triggered whenever a file is added to the Documents folder, (you’ll have to set the trigger to the path where your app outputs it’s renders). It is set to recheck every 10 second to see if the file size have changed, if not it will progress from the loop. I realize that the way it is set up now, with the Break from Loop within the Switch, the Until could be set up as an infinite loop instead, but this is anyways only a demonstration of a starting point, an idea you could maybe build on further if it seems to be able to give you what you need.

Moniotor file for completion.kmmacros (4.9 KB) (v11.0.3)

Macro image

Haven’t toyed with this yet, but conceptually it sounds exactly like what I’m trying to do. Thanks for the insight and suggestions.

1 Like

I had to solve this same thing when I wanted to watch for new apps added to the Applications folder—Keyboard Maestro's watched folder trigger would fire long before the app was finished copying, because the app bundle is created first, which Keyboard Maestro sees as "done," but all the parts of the bundle were still copying.

I went through a few iterations of solutions, but in the end, I wound up using a loop like this:

set new_size to 0
execute actions until conditions met:
  set old_size = new_size
  pause briefly (under a second, in my use case)
  get new_size
until: new_size = old_size

For the get new size step, though, I didn't use Keyboard Maestro's built-in function, as it wasn't clear if it updated rapidly enough. Instead, I used a shell command:

du -s /full/path/to/file.jpg | egrep -Eo '\d+\t'

This returns the size in bytes, and it's updated instantly each time you run it. This lets me make the pause very brief, so there's very little lag between the file copy being done and when the macro can proceed. Here's the final version as I used in my AppWatcher macro:

-rob.

If your process starts by writing a new file, I'd also go with @Alexander's approach. My generic template for this is similar:

File Write Monitor.kmmacros (6.4 KB)

Image

There's quite a pause because some of the files I monitor are written to in spurts -- there can be a few seconds between operations.

This is actually more difficult -- many apps will spawn multiple processes so you have to sum them, and you can't be sure which of the processes is the one you're concerned about. But here's an example of a "pause until sum of CPU use is less than...".

Wait Until Process < 10%.kmmacros (7.6 KB)

Image

It should really be re-written so all the shell stuff is done in a single action, for efficiency. I'm going to claim it's so you can more easily see what's going on, rather than it being laziness on my part :wink:

If your machine's CPU is peaking while transcoding and running at a much lower level at other times you might get away with simply checking total CPU usage:

Wait Until CPU < 20%.kmmacros (3.5 KB)

Image

And there are plenty of other options -- it really does depend on what will do the best job with your apps and workflow.