How can I set up a gateway script to run once at 4pm everyday? I want to write a value to a single tag at this time. thanks
While you could use a timer script, I prefer a tag change event.
trigger = '4:00:00 PM' timeValue = newValue.getValue() timeString = timeIn.toLocaleString()[11:].strip() if timeString == trigger: #do some stuff
I set it up like you have, but it doesn’t work. Any ideas? thanks
trigger = '10:40:00 AM' timeValue = newValue.getValue() timeString = timeIn.toLocaleString()[11:].strip() if timeString == trigger: system.tag.write('CNC_Global/2ndShiftStart',timeValue)
Just how precise do you need to be? And what do you need to do if you are excessively late due to a gateway problem?
FWIW, I would use a gateway timer event script that ran often enough for your precision requirements, and I would use a DateTime memory tag to hold the last execution timestamp. In each execution, compare the last timestamp against the current time and your desired trigger time. Then skip, execute, or perform some error correction accordingly.
The tag writing process doesn’t need to be that precise, I’d say anything within a 30 sec window would work just fine. I had this working from a propertychange event on a label with the expression now(). then I used the code below. It worked well, but if the client isn’t open it doesn’t execute. I’m know my solution, or code, is not ideal. I will look into the method you suggested.
datetime = event.source.text time = datetime.split(' ') suffix = datetime.split(' ') concat = time + suffix import datetime value = datetime.datetime.now() if concat == '4:00:00PM': system.tag.write("CNC_Global/2ndShiftStart", value)
Use another memory tag of type datetime to hold the trigger boundary if you need user access to tweak it. Try to do your math on dates and times without converting back and forth to strings. Use the system.date.addDays() function to advance your trigger target from one day to the next.
From a 1 second timer script.
from time import localtime, strftime
curTime = strftime("%H:%M:%S", localtime())
if curTime == ‘16:00:00’: #Time is military time, include leading zero in hour.
Bad. If the gateway experiences any heavy load at 4pm, this expression can miss the event. Especially if using fixed delay. If using fixed period, and the event that normally falls a 3:59:59 is slightly delayed, this can fire twice in a row. The chance is low, so you wouldn’t be likely to see either problem often, but it would happen.
I would use something like this in a project script module:
from java.util import Date lastTrigPath = '[default]some/path/to/datetime/tag' # Simple function to convert any timestamp to the trigger point on the same day def truncateToTrigger(ts): return Date(ts.year, ts.month, ts.date, 16, 0, 0) # Check if time to run the triggered event. Call from timer script def checkTrigger(): last = system.tag.read(lastTrigPath).value nextTrig = truncateToTrigger(last) if nextTrig.time < last.time: nextTrig = system.date.addDays(nextTrig, 1) now = Date() if nextTrig.time <= now.time: system.tag.write(lastTrigPath, now) # Do the trigger stuff here
project.something.checkTrigger() from a gateway timer script of the desired precision. It will not double fire, and will always fire if the event is late. Even if it’s late due to a gateway reboot.
I would use an expression tag with value change script. The expression should be “current hour >= 16”. The value change script would start with an if statement checking tag value = true. Let me know if you want more details, I can fire up a designer and give real expressions and scripting.
You can’t call project scripts from tag events. You have to use another tag anyways to avoid doubling on gateway restart or tag edit after 4pm. Works for quick and dirty problems. Not a good answer for anything important.
It is a gateway script, not a project script. It is easy enough to change the expression to meet the needs, current time >= “3:59:30 PM” and current time <= “4:00:30 PM” would meet the requirements. Taking advantage of the initial change property would prevent doubling up should the server restart in that minute.
This is ambigous. There are three scripting scopes in Ignition:
Client Scope. This applies to the designer, too, and both
project.*script modules are available. This is also the only scope that contains gui and nav and any related functions. Both client and designer have an Event Dispatch Thread in the foreground for all user interface operations.
Gateway Project Scope. Other than GUI functionality, this exposes the same script resources. This scope applies to gateway event scripts and scripts called from transaction group expressions. If something is configured via a node in the lower half of the designer’s Nav tree, it is almost certain to be this scope (if not client).
Gateway Global Scope. Sometimes called “shared” scope, as only the
shared.*script modules are available. Applies to tag events (define on the tag, not in the project) in particular, like the ValueChange event you are recommending. (I don’t.)
So, you’ve never had a server crash for more than a minute? Like, not restarting until IT intervenes, on a Sunday afternoon? Been there, done that, don’t like the T-shirt.
Since this basic and common need seems to not be as straight-forward and simple for new users as it probably should be I have added this idea to the feature request list.