I’m looking to create a counter that, when executed, will increase the variable value by 1 for a certain time period, then reduce it once the time has expired (see image). My method seemed like the most simplistic way, but I’m concerned if running dozens (or hundreds if the pause was changed to 1 hour) of these simultaneously would harm system resources and potentially create opportunity for them all to stop and mess up if ever the “cancel all macros” was executed.
Can someone help me in figuring out a way to do a calculation version by how much time has passed each time the macro is executed? ie: it makes timestamps for when each one was run then removes those older than X time or something. I don’t need the Counter in real time after the time period expires, it would be okay if it updated only when executed.
It wouldn't be so much a resource problem -- they'd be paused most of the time! -- but there is a limit on the number of concurrent macros (by default, 50). I'd be more worried about having to keep track of dozens (or hundreds) of Global variables!
Perhaps start again and describe what you are doing and want to achieve -- the how may be completely different, for example a variable containing a list of execution instance UUIDs with their starting timestamps.
I am using a macro to send emails, but my mail server can only handle so many per hour, so I want to make it so I can track each time I use the macro to send an email so I don’t send too many in too short of time.
Like @Nige_S suggested, I'd also propose keeping a log of timestamps.
Here's a macro that appends a global variable with an Epoch timestamp, every time the macro is triggered by another trigger than a Periodic Trigger. Every time the macro runs, it deletes any timestamps older than one hour from the start of the comma-separated list (variable array), and updates the Stream Deck button title with the number of timestamp entries the global variable holds.
A periodic trigger runs the macro every minute to keep the button up to date. If the macro was triggered by the periodic trigger, the macro ends execution after setting the button to the count. In any other event, it will continue to execute any actions you place below the bottom switch.
What about this as an alternative solution. Assume your email server can handle N per minute (can be a fraction). And assume if you haven't sent any emails in a long time, then you are allowed to send M emails, and after than N per minute.
Ideally you'd upgrade to a plan (or change your mail provider) with a limit above what you're likely to need and so avoid the problem altogether! There are many reasons for that, including "so many per hour" often isn't the whole story -- 90% of the hourly limit for a few consecutive hours may also get you blocked, as might 75% for three days, and so on.
Most providers don't publish full details to prevent just this sort of "optimisation"
If you can't upgrade/change provider then I'd go for a Global counter like @peternlewis suggests, decrementing on each send and with time-based incrementing -- doing it that way let's you show "Can still send: n" on your button, reverse the logic if you'd prefer "Have already sent: n".
You'll still have to play around to optimise things -- is it a rolling count or reset on the hour, for example -- and I'd start with a limit of 50% of maximum to allow for the longer-period rate limits. Absent full disclosure from your provider you'll only be able to find things out by pushing the boundaries until you get blocked...
Don't forget that every address in the "To", "CC", and "BCC" fields will (almost certainly) count against your "quota"! So include extra counts for those if you use them.
In my experience, it is often good to limit the rate of emails sending regardless of the limit. I typically allow a couple seconds between sends (which does mean my mailouts take quite a long time - luckily I don't do them very often). That said, I'll likely need to come up with a new system given all the new email sending restrictions around these days (damn spam!).