Hi,
I have a Gateway scheduled script that runs weekdays during working hours every hour at the 58th minute. If a criteria is met it sends an emaiI. I made a change to the script one day, and suddenly it started sending two emails, one with the changes I had just made, and one without those changes. I wasn't sure why that was, so I moved the script schedule to send at 56 minutes past the hour. I then got an email at 56 and 58 minutes past the hour.
I restarted the Ignition service thinking some rogue copy of the script was still active somehow. Same behavior.
I looked at the gateway scripts page, and it only showed the script that I had moved, there was no extra script that it would execute according to that page, but it is executing.
I exported the project, deleted the project, and reimported it. Same behavior.
I disabled the gate schedule script. I am now getting email only from the original copy of the script at 58 minutes. I don't ee anything else in the designer.
Anybody have any thoughts on this?
Thanks
Perhaps the original script was in an inherited project, and is still running via another project?
(If so, you should break the habit of defining any gateway event scripts in an inheritable project.)
Good point, but none of my projects are inheritable. There is another coy running on my test server, but it isn't generating this. I moved the test version to 57 past the hour and could see that one running on the test gateway page.
Is the actual code embedded in the event, or in a project library script called from the event? If the latter, you can search in the project tree on the gateway filesystem for some of the code or message text.
It's embedded in the event
I've tried anyway and haven't found anything.
I deleted the original project and the email still came out.
Pretty definitive evidence that another project or another gateway is involved. Consider shutting the gateway down just before the next scheduled time and see if the emails come out. 
1 Like
I looked at a gateway that had nothing to do with this project, and lo and behold, this project was active on that gateway. I deleted the project, and assume the extra email will stop. Now to find out how that happened....
Consider making it a policy that scripting the "from" email address to be of the form scriptname.projectName.gateway@yourcompany.com
. This may be helpful in quickly tracking down the source of stray emails - particularly if a script or alarm, etc., goes rogue. It may prevent your mail server getting blacklisted.
It's a while since I looked into this and I can't remember how much of it can be generated by system functions. If you figure it out then post it here!
Messing around for a few minutes gives me this which returns the project and gateway name (provided that it's a project script):
# !!! See improved version in post #12 !!!
fromAddr = (system.util.getProjectName()
+ "."
+ system.net.getHostName()
+ "@myCompany.com"
)
# e.g., myProject.myGateway@myCompany.com
Now can anyone suggest a method of returning the script path/name other than hard-coding it in the script?
Beware, system.net.getHostName()
is not the same as the gateway name (though still potentially useful diagnostic info). You can retrieve that the actual gateway name via system tag.
For script path/name you have to look at Jython's stack peeking machinery to get anything reliable, but even then a lot of the time we're just passing in something like <file>
, not a useful identifier. It's on my list of improvements to make - generally useful global implicit context.
wait, would __name__ not work?
I was assuming scripts got imported in the engine
(That won't give you the full path, but it will give you script names).
If you're using some sort of eval, it might be a different question
Thanks for that reminder, Paul.
@Leor_Fishman, that's a big help too.
Updated email from address:
tagPaths = ["[System]Gateway/SystemName"]
systemName = system.tag.readBlocking(tagPaths)[0].value
fromAddr = (__name__
+ "." + system.util.getProjectName()
+ "." + systemName
+ "@myCompany.com"
)
# e.g., projectLibraryName.myProject.myGateway@myCompany.com
1 Like
NP!
python dunders (the name for the underscored reserved words) have lots of useful "black magic" in them 
If you have my toolkit installed, use:
origin = system.util.getProjectName() + '.' + system.reflect.getModulePath()
Or:
tkCtx = system.util.toolkitContext()
systemName = tkCtx.systemPropertiesManager.systemName
origin = systemName + '.' + system.util.getProjectName() + '.' + system.reflect.getModulePath()
Perhaps with:
logger = system.util.getLogger(origin)
See:
https://www.automation-pros.com/toolkit/doc/reflection.html#getmodulepath
2 Likes
From memory, not consistently everywhere. There are lots of places where all you'll get from __name__
will be <file>
or <import>
or something similarly vague. The ticket I'm thinking of has, as a first pass measure, simply going through everywhere in Ignition we execute a script on your behalf and making sure we pass in a useful location/name.
This is internal ticket IGN-7976 if you want to bug your support rep about it.
Indeed. My .getModulePath()
function only works in Ignition project library modules. So too with the full path support in the .asThrowable()
function.
Another reason to put all possible code into project library functions.
1 Like
this is one of the most ominous things i've ever heard about a scripting engine lmfao
basically every way i can think of to write an engine would have this always work or never work
It is inevitable when you embed a scripting engine into another process. Jython is not in the driver's seat the way CPython is for any of its extensions.
Ignition's event scripts and extension methods are compiled and run in little tiny isolated worlds that have limited self-knowledge exposed to the script itself. That is one of the reasons I encourage Ignition developers to always use one-liners in events and extensions to delegate to the project library. Only in the project library can you expect jython infrastructure to be (mostly) consistent.
2 Likes
Agreed, plus you can search the project libraries, but the event scripts are in the data.bin file. I will start doing this, thanks
That's a great idea, thanks for mentioning it, I will implement this!