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(' ')[3]
suffix = datetime.split(' ')[4]
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.
[code]import system
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.
system.tag.write(âtagâ,value)[/code]
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
Call 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
shared.*
andproject.*
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.