Time Until Trigger / Time elapsed after trigger variable
Is this a feature relevant to companion itself, and not a specific module?
- [x] I believe this to be a feature for companion, and is not specific to a module
Is there an existing issue for this?
- [x] I have searched for similiar existing issues
Describe the feature
Please add the ability to see how much time remaining before a trigger hits and how much time has elapsed since the trigger was last hit. We have several buttons that "arm" triggers, with the user being able to arm & disarm the trigger. First, if it's armed I would like to have a countdown showing in the button to when the events in the trigger will fire. Second, I want to be able to use logic and time math so, for instance, if the trigger is not armed and it's only 3 minutes until it's supposed to be triggered I can have a button start flashing with custom text warning the user that they haven't armed the button and the events won't be happening. I know I could probably manually do this by creating custom variables, but we sometimes change the date/times of certain triggers, which would mean having to change the variables as well - leading to the possibility of mistakes. Having this built-in to companion would prevent a mis-matched trigger and variable mistake. Thank you for your consideration!
Usecases
No response
What specific events are you wanting timers for? Simply saying you want a timer for when an event will fire isn't helpful when most events are not predictable.
The more predictable events, such as triggering on a certain time of day, if you know the time something is going to trigger you can already use Expressions to create a countdown to/from that time from which you can then do other things such as flashing buttons.
Hi Jeff... I'm really only looking to have a variable tell me how much time is left on a trigger that's set for, say, Sunday at 10:56:44. But I have to be able to calculate it from the trigger itself and not a custom variable as if the time of our service changes, I don't want to have to manage another custom variable. I hope that makes sense.
You mentioned I could already do that calculation and see how much time until a trigger fires. I see you said expressions. Would you mind giving me an example of how to do that? Thank you
What specific events are you wanting timers for? Simply saying you want a timer for when an event will fire isn't helpful when most events are not predictable.
The more predictable events, such as triggering on a certain time of day, if you know the time something is going to trigger you can already use Expressions to create a countdown to/from that time from which you can then do other things such as flashing buttons.
Jeff, if you have a moment, would you mind showing me the expression to write that can calculate the time remaining from the trigger time (which I guess I'd have to duplicate to a custom variable) to the current time?
$(internal:time_hms) is the current time
12:34:56 is whatever time you want something to trigger
timestampToSeconds('12:34:56') - timestampToSeconds($(internal:time_hms)) ) is the difference in time between the two.
secondsToTimestamp(timestampToSeconds('12:34:56') - timestampToSeconds($(internal:time_hms)))) is that previous value, converted back into a timestamp.
If your trigger is multiple days away, you can use $(internal:date_iso) to get the current date, and similarly use very basic math to calculate the number of days difference between now and when you want something to trigger, times that by 86400 (seconds in a day) then add that to the time difference between timestamps.
If you want to know how long as passed since the last trigger, in your trigger simply save $(internal:time_hms) to a variable, such as $(custom:last_trigger), and then same as previously compare that to the current time and it'll get you the time difference since the last trigger.
If you want to do things when there's X amount of time before the trigger, when you calculate the time difference in seconds if it's less than 180 you know it's within 3 minutes, so start flashing, or changing text, etc...
$(internal:time_hms)is the current time12:34:56is whatever time you want something to triggertimestampToSeconds('12:34:56') - timestampToSeconds($(internal:time_hms)) )is the difference in time between the two.secondsToTimestamp(timestampToSeconds('12:34:56') - timestampToSeconds($(internal:time_hms))))is that previous value, converted back into a timestamp.If your trigger is multiple days away, you can use
$(internal:date_iso)to get the current date, and similarly use very basic math to calculate the number of days difference between now and when you want something to trigger, times that by 86400 (seconds in a day) then add that to the time difference between timestamps.If you want to know how long as passed since the last trigger, in your trigger simply save
$(internal:time_hms)to a variable, such as$(custom:last_trigger), and then same as previously compare that to the current time and it'll get you the time difference since the last trigger.If you want to do things when there's X amount of time before the trigger, when you calculate the time difference in seconds if it's less than 180 you know it's within 3 minutes, so start flashing, or changing text, etc...
Thank you very much, Jeff.
$(internal:time_hms)is the current time12:34:56is whatever time you want something to triggertimestampToSeconds('12:34:56') - timestampToSeconds($(internal:time_hms)) )is the difference in time between the two.secondsToTimestamp(timestampToSeconds('12:34:56') - timestampToSeconds($(internal:time_hms))))is that previous value, converted back into a timestamp.If your trigger is multiple days away, you can use
$(internal:date_iso)to get the current date, and similarly use very basic math to calculate the number of days difference between now and when you want something to trigger, times that by 86400 (seconds in a day) then add that to the time difference between timestamps.If you want to know how long as passed since the last trigger, in your trigger simply save
$(internal:time_hms)to a variable, such as$(custom:last_trigger), and then same as previously compare that to the current time and it'll get you the time difference since the last trigger.If you want to do things when there's X amount of time before the trigger, when you calculate the time difference in seconds if it's less than 180 you know it's within 3 minutes, so start flashing, or changing text, etc...
Jeff this was great thank you! I'm looking through the documentation (before I asked you again!) and I'm trying to figure out how I can do an expression that says "how many seconds is it from RIGHT NOW until the upcoming Sunday at 10:56:42". I see how I can do that math for a specific date, but not 'this coming sunday"
As I said, it's all just math. Calculate time difference between times of day, calculate difference in days between now and the target day and multiply by seconds in a day, add those 2 things.
Example of time until 10:56:42 on Sunday.
target = timestampToSeconds('10:56:42')
now = timestampToSeconds($(internal:time_hms))
days = (7 - $(internal:date_dow)) * 86400
difference = target - now + days
secondsToTimestamp(difference)
If you wanted to make it more safe to things such as the day of week being less than the current dow (such as if you wanted a time until monday, which would be dow 1) you could do a check to see if it's less than the current dow and if so add 7 so it'll count to the next week.
Because secondsToTimestamp doesn't show days, for me at the time of writing this and in my time zone it shows 107:57:56, which is correct as it's almost 108 hours from now.
As I said, it's all just math. Calculate time difference between times of day, calculate difference in days between now and the target day and multiply by seconds in a day, add those 2 things.
Example of time until 10:56:42 on Sunday.
target = timestampToSeconds('10:56:42') now = timestampToSeconds($(internal:time_hms)) days = (7 - $(internal:date_dow)) * 86400 difference = target - now + days secondsToTimestamp(difference)If you wanted to make it more safe to things such as the day of week being less than the current dow (such as if you wanted a time until monday, which would be dow 1) you could do a check to see if it's less than the current dow and if so add 7 so it'll count to the next week.
Because
secondsToTimestampdoesn't show days, for me at the time of writing this and in my time zone it shows107:57:56, which is correct as it's almost 108 hours from now.
Thank you. I took your example and have run with it! I really am grateful for the help.
In the Triggers interface, it would be very useful to display when each trigger was last matched (conditions true) and last fired (actions executed). This would help operators and developers quickly see if a trigger is behaving correctly without having to check logs.
⸻
Problem / Why
Right now it’s hard to know if a trigger is: • Matching conditions at all • Matching but being held back by cooldown or disabled state • Actually firing actions
During a live show this makes troubleshooting slow and uncertain.
⸻
Proposed Solution
Add runtime info to each trigger in the UI: • Last matched: Timestamp + relative time (e.g., 2025-09-04 11:02:13 · 3m ago) • Last fired: Timestamp + relative time • Times fired: Counter since Companion start (optional reset button)
Placement: • New columns in the Triggers list • Read-only fields in the trigger detail panel
If never matched/fired, show “—”. Grey out when disabled.
⸻
Live Updates • Update fields live via existing WebSocket/event bus (no page refresh needed). • Emit event payload like:
{ "type": "triggerRuntimeUpdate", "triggerId": "abc123", "lastMatchedAt": "2025-09-04T10:02:13.456Z", "lastFiredAt": "2025-09-04T10:02:15.102Z", "timesFired": 9 }
⸻
Technical Sketch • Extend in-memory trigger runtime with:
interface TriggerRuntime { lastMatchedAt?: number lastFiredAt?: number timesFired: number }
• Update lastMatchedAt when conditions evaluate true.
• Update lastFiredAt and increment timesFired when actions run.
• Emit triggerRuntimeUpdate on each change.
• Keep runtime only (reset on restart).
⸻
Edge Cases • Disabled triggers → show “—”, don’t update. • Cooldown → lastMatchedAt may change without lastFiredAt. • Action error → still update lastFiredAt when firing attempted. • Cloned triggers → reset runtime values.
⸻
Acceptance Criteria • See “Last matched” and “Last fired” per trigger. • Values update within ~1s of a trigger event. • “Times fired” increments correctly. • Disabled triggers stay frozen. • Reset works if implemented.
⸻
Impact
Small, low-risk addition that gives operators immediate visibility into trigger behaviour. Makes debugging faster and boosts confidence during shows.
You could just use the already existing methods within Companion to achieve much of what you're interested in.
For example. create a variable $(custom:trigger_x_lastFired). or whatever you like. Set the first Action to save the current $(internal:time_hms) to that variable. Congrats you now have a time since it last fired!
Want to know how many times it fired? $(custom:trigger_x_timesFired), with an Action to increment it by 1. If you set that value to not persist and be 0 at startup it'll reset each time you start Companion.
Want to know how many times the Event triggered but the conditions were/weren't met? Move your conditions to Expressions within Actions and you can log the time/state of various conditional elements.
This all already allows you to debug and check how many times specific triggers are running (or all triggers if you wish), condition state, actions firing, etc...
I think in the long run a more verbose logging system could be beneficial but Companion isn't particularly well set up right now to handle verbose logging and would need more general changes to companion to support control of what is/isn't logged (due to the potential performance hit of verbose logging) and better ways to present logs to users.
hi! Put this on the back burner until this morning. I have one thing I can't figure out despite an hour of trying. So (thanks again for your help), I have the countdown working great. I even have multiple feedbacks so it starts warning you more and more intensely that it's not going to turn on the stream as the countdown gets closer to zero.
After it hits 00:00:00, the feedback then blinks the light fast and says "STREAM DISABLED : NOT STARTED". Basically if you ignore all the flashing lights, it'll keep flashing warning you that you never enabled the "auto Stream" and you're not streaming.
So far so good. I used your help to calculate the day differences so the number of days away is always counting correctly. Essentially it "resets" to a countdown after midnight the next day. Before that it will be a negative number. Makes sense I guess. But, the feedback warning the stream hasn't started.... I only want that to work for 45 minutes (the average time of a service). After that 45 minutes I want it to start counting down until the time for next week. Does that make sense? Normally easy.... I simply take the time that's the countdown in hh:mm:ss and do a timestampToSeconds and 2700 to it. But after the countdown time expires, it will generate a negative number until midnight the next day. timestampToSeconds only returns 0 if it's a negative number so I can't see a way to say "make this feedback happen until -45 minutes has past then ignore it.
Apologies for hopping onto this train here, but it is the only kind of related thread I could find.
I wanted to find out if there is a way to have a button display how much time has elapsed since it has been pressed?