Subprocess & system.util.execute

Hi
I have Ignition Version 8.1.3 running on Raspberry Pi under latest Linux
I have developed a Python script that runs on the Ignition Gateway machine. It has been tested and runs correctly from both the IDE and command line.
I now want run it from Ignition, eg a button press or tag event.

I have tried both system.util.execute and subprocess methods, in both Gateway Message events and tag change scripts, and cannot coax either of them to work.

  1. Using subprocess.Popen([ sys.executable, “home/pi/myDirectory/doIt.py” ])
    This throws a “No such file or directory” error

  2. Using system.util.execute([ ‘python /home/pi/Nest/.py’ ])
    This does not throw an error, but the Python script does not execute

Can someone help with:
a. Which method is preferable?
b. For the recommended method, what is the process command format?

Thanks in advance

Is the file executable for the user running the Ignition service? (Including readable folders in the hierarchy.)

1 Like

Using system.util.execute([ ‘python /home/pi/Nest/.py’ ]) - I don’t know if you just had a transcription error typing up the question. but shouldn’t this be the same diretory as before and pointing to dolt.py? So system.util.execute([ ‘python “home/pi/myDirectory/doIt.py”]) - you’re saying this sort of statement does not throw an error and it does not run the dolt.py?

Somewhat related - as I recall python3 is not automatically aliased to python on the raspberry pi. Make sure when you type python into terminal, you see the version that your file is written in. Otherwise you might mean to be using python3.

1 Like

pturmel
I changed permissions to -rwx for all users and it has made no difference

bkarabinchak.psi :
The code in tag change script is:

logger.info(“starting”)
system.util.execute([“python3”, “/home/pi/Nest/doIt.py” ])
logger.info(“completed”)

Both log messages appear in the system log, there are no error messages thrown to the log and the doIt.py script is not executed

What is the contents of dolt.py? What are you expecting to happen? I wouldn’t think you would get any errors to your log. What you’re doing is telling your raspberry pi to run dolt.py, in a separate process, outside of Ignition. So whether it works or not, Ignitiion I don’t believe would have any access to that information, unless you did it with subprocess.Popen, and had shell=True iirc - which would only feed you back the strings of the terminal as it executes, but again, you won’t be getting any errors here (except for an error in trying to run it at all, but once it goes, its it’s own process).

Now I will wait for @pturmel to correct me where I am wrong :joy:

Here is an example of subprocess that might help out

def cpuLoad():
	import subprocess
	proc = subprocess.Popen(['powershell.exe', "wmic /node:<ipaddr> cpu get loadpercentage"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
	output = proc.stdout.read()
	print output	
cpuLoad()

bkarabinchak.psi
Thank you for the feedback
The python script does some image processing and writes results to a database. It runs asynchronously and no results are required to be returned to Ignition.
It also displays some images and prints some debug info to the console.
I thought this may have been an issue so I have now added a “headless” mode with no print output or image display. This mode works fine from command line. I can run this headless script and it executes correctly and writes results to database (which can be seen in Ignition). However it still does not work when I run it from Ignition/subprocess()

So I remain confused.
I have a couple of questions:

  1. Where do I find any error messages thrown by my py script? I have checked logs in “/var/log” directory with no joy files
  2. The only other thing I can think of is that the sql writes are failing due to user permissions? What user does Ignition service run as? I connect from the python script using “pymysql.connect(host='localhost,user=“root”,password=“rootpassword”,database=”"mydb’)"
  1. For logging, that will go to stderr (standard error output to the console) if you haven’t routed it to a logging file. execute() won’t show that, and subprocess can, but you have to get the subprocess code right to get any stderr messages back from subprocess into variables in Python that you can print.
  2. If you list your processes (“ps” command with appropriate arguments) you’ll be able to see what user Ignition is running as.

However, before going any further you might try to provide the full path to the python executable. The OS doesn’t always set up environment variables for execute() that include python3 in the path.

system.util.execute([“/path/to/python3”, “/home/pi/Nest/doIt.py” ])

If you’re using subprocess, to get standard printed results (stdout, not stderr) one option is to do something more like:

import subprocess
result = subprocess.check_output(“/path/to/python3”, “/path/to/python/program.py”)

Also, you could instead wrap your Python program in a local web service using flask or bottle. Some folks go that direction for portability. (I’ve done it myself for home projects with image capture from a Pi camera.) More info can be found here: Python, Jython, CPython, Libraries, Pip, and Python 2.7 vs 3 - A quick primer

1 Like

What user is the Ignition process running as? Typically it is “ignition”, and that won’t be able to make file changes without write permissions.

Are you sure your handler is executing? Include logging in your handler before and after system.util.execute and check the gateway log for the output. (Use system.util.getLogger() instead of using print statements.)

@Jay_L - You really shouldn't be posting the same thing in multiple topics...

1 Like

Hello pturmel:

I also doubted that at the beginning,

while when I tried 'system.util.execute(["rm","rf","/home/file/os_.py"])', I actually deleted that py file from the folder, so I think the handler is executing.

Don’t cross-post the same thing in multiple topics.
FAQ - Inductive Automation Forum

For those trying to help you, it leads to more work for them since Person A may see this topic and Person B sees the other topic. They then add answers independently of each other, to the separate posts, not realizing that the other person may have already posted the exact same answer in the other topic. They may also miss the other persons posts and have no chance to build upon them with additional thoughts.

Long story short, wastes time (making people less likely to offer assistance in the future) and can reduce the quality of the answers you will get in the end. If you see a relevant topic that you would like to pull into the discussion, you can post in your original topic with a link to the relevant second topic.

1 Like

But you aren't pooling it. You are fragmenting it. As @WillMT10 says, please don't waste our volunteer time with repeat posts.

2 Likes

Thank you for your patient explanation, ans I feel so sorry to do that. That won’t happen again.

1 Like

I feel sorry about my behavior,

and I promise this is the last time such a stupid behavior happened.

This guy really knows how to apologize. Reminds me of the apology scene from “A Fish Called Wanda”.