Check the last time a specific macro ran

It's that, but having extra files on my computer is not a good workflow for me and I would rather have the variables all in one place, related to KM. I don't need to have this info in other computers (as I only have 1 for now anyway) so a global variable seems to be the only option.

That's fine (but a KM variable is really just a text entry in a document, anyway).

1 Like

Yes, but it's all managed in the KM environment instead of having an extra text file somewhere. it's easier if all variables are in the variables pane inside KM. At least, for this particular case, of course

Going back to the original question...

Are you aware that KM keeps track of macro usage statistics in a file? So you can find out what you're looking for by querying that file.

Since the file is a plist, querying it is not quite as simple as searching a text file would be. To help you out I've created a KM subroutine macro that takes as input the UUID of the macro you're interested in and returns the UNIX time of that macro's last use. Here's the subroutine:

Download Macro(s): [SUB] Get Last Run Time of Macro.kmmacros (3.3 KB)

Macro-Image

Macro-Notes
  • Macros are always disabled when imported into the Keyboard Maestro Editor.
    • The user must ensure the macro is enabled.
    • The user must also ensure the macro's parent macro-group is enabled.
System Information
  • macOS 13.6.1
  • Keyboard Maestro v11.0.2

And to illustrate its usage, here's a simple macro that calls the subroutine and displays the time in a window:

Download Macro(s): Test [SUB] Get Last Run Time of Macro.kmmacros (3.0 KB)

Macro-Image

Macro-Notes
  • Macros are always disabled when imported into the Keyboard Maestro Editor.
    • The user must ensure the macro is enabled.
    • The user must also ensure the macro's parent macro-group is enabled.
System Information
  • macOS 13.6.1
  • Keyboard Maestro v11.0.2

To make full use of this you'll need to supply the UUID of the macro of interest. For simplicity, I use the UUID of this test macro as derived in the red action.

Hope this helps.

1 Like

Thanks for sharing.
I haven't used it yet, but looking at the plist file on my computer, I think I will run into the same issue:
If I run the main macro (not the sub routine) at 10:34am, and then at 11:56am won't the date that gets saved in the plist be 11:56am? If so, then this won't work, because the date I need is the 10:34.
If I need to run the macro to get the date, then KM will save that date before I even get to the action to get the date (the red action, I guess).

Does it make sense?

So technically, I don't need the "last" date, I need the date before that one.
I would need the last date, if I wasn't required to run the macro in order to get it.

Hope I'm making sense here... haha

That's why I thought of using the global variable at the end of the macro and save that as the date so even if I run the macro again in 2 hours, the global variable is holding the old date, which is what I need.

If you run my macro and its subroutine to check the last run time of your macro that isn't going to affect the last run time of your macro. So no, it doesn't make sense to me :person_shrugging:

Ok let's go by steps:
I ran the main macro you provided (Test [SUB] Get Last Run Time of Macro) and I got this:

2024-02-06 16:31:54 Action 15480837 failed: Execute a Shell Script failed with script error: Unknown format specifier: raw
plutil: [command_option] [other_options] file...
The file '-' means stdin
Command options are (-lint is the default):

and then a long list of instructions.

I think you mentioned that I needed to include the UUID in the red action so I did this, right?

image

I guess probably the issue is that we are both looking at the "run date" as 2 different things. You have the time it ran (meaning, when it started running, which to me is the real run date) and the time it finished running. Let's say the macro takes 1 minute to run and I start it at 1:00pm
So I have the time it started running (1:00pm) and the time it ended (1:01pm).
So if the plist saves the time it ended, then I get the date I need (even though it does't make sense to call it the date it ran). But if it saves the time it starts, then it won't, because it will automatically give me the date of when I started running it now. Because the moment I run the macro itself, it will save the new date.
Now if it records the date it ended, then it doesn't make much sense to call it "the last it ran". Let me give you a real life example, maybe that helps you understand my perspective:

If you wake up and go jogging at 6am and it take you 2 hours until you're back home and someone asks you: so when did you go on your daily jogging? You don't say "at 8am", right? So when someone asks you "when was the last time you ran?" you will say "today at 6am", not "today at 8am".

So I guess this all depends on when KM is saving that date.

I'd probably use two variables, LastRun and CurrentRun. At the end, set LastRun to NOW() if it doesn't exist (i.e. it's the first run) and just exit. If it exists, set CurrentRun to NOW(). Then calculate the time delta between CurrentRun and LastRun. Do your backup stuff, then copy CurrentRun to LastRun and exit.

That's grossly simplified, but hopefully conveys the idea.

-rob.

1 Like

Yes, that's what I ended up doing actually :slight_smile:
One global variable called trBackupUnixLastRun that runs at the end of the macro.
image

Then at the top of the macro I have this:
image

I was having an issue with the UNIX time not being accurate, but for this particular scenario that doesn't matter, because all I want is the number of minutes in between them

I didn't know this was the right term for this. Always learning. Thanks! :slight_smile: