How to run python script via plugin?

andipandi
2015-09-16
2015-09-30
  • andipandi - 2015-09-16

    Dear Forum!

    Following up on http://forum.codesys.com/viewtopic.php?f=18&t=6115 (which I hijacked, sorry), I am wondering:

    Is it possible to programmatically start a Python script via a plugin?

    I. e. can I write a plugin that has a method that makes Codesys execute a Python script, e. g. based on its path? (I would then create another interface to that plugin, like a web service, in order to execute different Python scripts when feasible.)

    Many thanks
    Andreas Reiff

     
  • etamgul - 2015-09-25

    I'm replying as a user so dont take my word as an answer.

    What you could use is 'execfile(path_to_your_script);' this is similar to C include (it will put the content of the script/file you pass
    to the line where it is executed.

    With FIFO management you can create a python script (executed by codesys) which accepts pathes on your interface
    and puts it in the FIFO, then an endless loop processes the the FIFO and calls the execfile with your scripts.

    This would maybe the simpliest, I dont know if it works I've never tried the execfile in a loop but im using this method
    to exec multiple python script to the codesys executed one.

     
  • etamgul - 2015-09-25

    Also you can experiment with system execute command as described here:
    l viewtopic.php?f=18&t=6306 l

    the GUID/names you need is:
    974e36d0-d2ed-4dcc-9505-2e4f2fb9c70d - Execute Script File... - Arraystr

    so:
    system.commands[GUID('974e36d0-d2ed-4dcc-9505-2e4f2fb9c70d')].execute(...)

    or identical:
    system.commands["script", "execute"].execute(...)

    I dont know:
    - if this can be execute without GUI (--noUI) execution
    - if execute() takes an argument
    - if it does not you have to use additional methods to pass the path of the script to codesys (maybe system.prompt_answers[...])

    Sorry I dont have the time to experiment with these. But thought it can help you.

     
  • Anonymous - 2015-09-25

    Originally created by: M.Schaber

    Hi, Andreas,

    andipandi hat geschrieben:
    Dear Forum!
    Following up on http://forum.codesys.com/viewtopic.php?f=18&t=6115 (which I hijacked, sorry), I am wondering:
    Is it possible to programmatically start a Python script via a plugin?
    I. e. can I write a plugin that has a method that makes Codesys execute a Python script, e. g. based on its path? (I would then create another interface to that plugin, like a web service, in order to execute different Python scripts when feasible.)

    With programmatically, I think you mean the Automation Platform.

    The ScriptEngine Plugin has an official Automation Platform API which allows to start your own scripts. (This is also what the Test Manager does within its "ExecuteScript" action.) This API provides more control than using the command execution.

    The apis are defined in the ScriptEngine interface DLL.

    There's also an article in the developer network

    HTH,
    Markus

     
  • andipandi - 2015-09-29

    @etamgul
    Many thanks, I probably was not clear enough in my description, I was wondering how to execute a script within Codesys - controlled from another program.

    @Markus
    Many thanks, that is what I am looking for.
    Since from my understanding, the plugin is passive, I would then have to create my own listener in that plugin in order to control it from outside the Codesys application.

    Your sample unfortunately is the other way round.. extending the script engine, but not controlling it.

    (Sorry, I have not developed with the Codesys plugin concept yet.)

     
  • andipandi - 2015-09-29

    Could that be

                var scriptEngine = (IScriptEngine)ComponentManager.Singleton.InstanceFactory.GetSystemInstance(typeof(IScriptEngine).FullName);
                if (scriptEngine == null)
                    throw new InvalidOperationException("No ScriptEngine accessible error.");
                scriptEngine.Execute("abc.py");
    

    ?

    Also, if I have this running in a plugin (that is the way to do it?) in a separate thread, can I just call the Execute method or is there some dependency on the main thread?

    Many thanks

     
  • Anonymous - 2015-09-30

    Originally created by: M.Schaber

    Hi,

    andipandi hat geschrieben:
    Could that be

                var scriptEngine = (IScriptEngine)ComponentManager.Singleton.InstanceFactory.GetSystemInstance(typeof(IScriptEngine).FullName);
                if (scriptEngine == null)
                    throw new InvalidOperationException("No ScriptEngine accessible error.");
                scriptEngine.Execute("abc.py");
    

    ?
    Also, if I have this running in a plugin (that is the way to do it?) in a separate thread, can I just call the Execute method or is there some dependency on the main thread?
    Many thanks

    Yes, that source looks like a valid, minimal script execution.

    For more control about the script, you can create an IScriptExecutor.

    IronPython by itself does not depend on the main thread, it is (or should be) as threading capable as other .NET languages like C#.

    However, the standard scripting API we provide to the scripts using the script drivers is inherently bound to the primary thread (UI thread), as it calls into Automation Platform APIs.

    If you do not want to use that API, just use an IScriptExecutor and don't call the "LoadScriptDrivers()" Method. Then your scripts can still use the whole .NET and IronPython standard library, as well as any APIs you provide or any Assemblies the script loads directly.

    HTH,
    Markus

     

Log in to post a comment.