tflemer
Is there a way to execute an OS command in OpenPLC? I would like to run an ordered shutdown based on events in OpenPLC.  Something like this from Python:

def restart():

    command = "/usr/bin/sudo /sbin/shutdown -r now"

    import subprocess

    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)

    output = process.communicate()[0]

    print output

Quote 0 0
thiagoralves
Nope. That’s not possible with OpenPLC.
Quote 0 0
tflemer

Thiago,

Thanks for confirmation on no exec.  I looked everywhere/way possible, even IEC 61131-3.  Nothing.  Still, I though may be I missed it.

NodeRed has this exec capability.  My concern was that NodeRed would not work on the same RPi as OpenPLC.  So, far both seem to be working together.  OpenPLC uses version 4.3 of nodejs.  NodeREd upgraded nodejs to 8.3.  So far it appears that OpenPLC is OK with the newer version of nodejs.

Now, NodeRed has three general ways to access OpenPLC and the RPi.  GPIO as installed with NodeRed, Modbus node, and OpenPLC node, which is based on the Modbus node.  Currently, I am testing a GPIO interface with OpenPLC – it works.  Not sure it will work with the full range of Modbus Mapping in OpenPLC.  This may be a question more about NodeRed.  Is there any advantage of one node over the other, GPIO, Modbus, OpenPLC ?

Tom

Quote 0 0
thiagoralves
I don't have any experience at all with NodeRED. I could guess that GPIO would be the one to cause more issues, as both NodeRED and OpenPLC will be competing to access the GPIO hardware. Modbus should work just like any other Modbus interface, which means you can safely read/write the entire OpenPLC buffer. OpenPLC doesn't implement any special driver to talk to NodeRED applications, so I assume that this OpenPLC library available for NodeRED (it was not developed by me) must use some sort of Modbus to communicate with OpenPLC. Therefore, Modbus or OpenPLC should be the same thing in the end.
Quote 0 0
tflemer
Here is a belated follow on. Your guess is correct on GPIO. I tramped though some of the source code for OpenPLC. As I understand, the IO in the Raspberry Pi driver defines the pins as input or output at start up. Works fine. When the Node Red GPIO package reads an OpenPLC defined output pin, Node Red switches it to an input. So, the pin is no longer functional in OpenPLC. A reboot is required to reset the pin for OpenPLC. Not good. However, when I put OPenPLC and Node Red on separate SBCs, GPIO is simple to work with.

Node Red Modbus has a lot of features. OpenPLC defined output pins can be read with Node Red Modbus. The problem I encountered is that it reads a minimum of 8 bits to an array. I can Split the array in Node Red, but handling the single bit is not trivial. I think there must be something really simple that I a missing. At this point Node Red Modbus is a no go for me.

Node Red Open PLC has an interesting feature, where structured text can be loaded to the OpenPLC server via a node. It works. As long as Node Red OpenPLC nodes stay within the topology of Raspberry Pi and connections, one could programmatically change the OpenPLC runtime program. Not something I need currently.

There are three functions that I want, which OpenPLC cannot do simply.

Execute a Raspbian command. Node Red can trigger a command based on reading a pin state.

Simple Web Control Station – Node Red can do simple.

Monitor IO activity – Node Red can do this. However, my present set up requires two Raspberry Pis. One for OpenPLC and another for Node Red. So far, my test set up is doing what I told it to do, not necessarily what I need it to do. Using Node Red to monitor the activity is very helpful. There is a limitation, in that Node Red cannot monitor internal logic of a OpenPLC program. The project I am working on does not have a lot of depth. I can see where an increase in logic would require a more capable tool.

I have been running OpenPLC in a test bed for over a month now. I am really impressed on how well it runs.  Thanks
Quote 0 0
thiagoralves
Given that OpenPLC uses MatIEC to compile its programs, you could try to run a system exec using MatIEC pragmas. From MatIEC manual:
"The IEC standard allows compilers to accept extensions as long as they are within pragmas, which for the IEC 61131-3 is any text delimited by '{' and '}'. Our compiler also allows that C or C++ code be inserted inlined with ST or IL code. This is done by simply inserting any C or C++ code, within the two '{' and '}' delimiters, in ST or IL code. Note that this support is prelimenary and its syntax may change without notice (as everything else in this project, really...;-] )".

So you could try to do this by adding a Function in Structured Text to your program that checks whether the condition to execute the command is true, and in case it is, just insert a C++ system exec command within the '{' and '}' delimiters. Something like this (not tested):

FUNCTION Execute_Command : BOOL
  VAR_INPUT
    test_condition : BOOL;
  END_VAR
  VAR_OUTPUT
    command_executed : BOOL;
  END_VAR
  
  IF test_condition THEN
    command_executed := TRUE;
{system("put your command in here");}
  ELSE
    command_executed := FALSE;
  END_IF;
Quote 0 0
thiagoralves
I can confirm that this works. I created a small project (attached) that calls a system exec to rename a file. Before uploading the OpenPLC program, simply create a file on the OpenPLC_v2 folder called "file1". Then run the program. Whenever you press the button on %IX0.2 your file will be renamed to "file2". You can then manually rename it back to "file1" and press the button again. It worked for me every time I pressed the button.
Quote 1 0
tflemer
OK - this works well.  Many thanks.  Also, good to know for future reference,
Quote 0 0
ajhart
Work Perfectly! Thank you very much.....
Quote 0 0