Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

Access/execute codesys menu

etamgul
2015-07-16
2016-05-12
  • etamgul - 2015-07-16

    I've been trying to upload application and log into my device but it is running in "SIL2" mode which locks the memory access so
    before login/upload I have to set my "PLC" or device into "Debug mode" using the CODESYS granted GUI menu "SIL2/Enter Debug Mode..."

    So far there is no entry point or sub method to access/call that menu (from codesys ScriptEngine), but I found a way to read the GUID of those menus:

    \# cmds = IScriptCommands
    cmds = system.commands 
    \# cmd = IScriptCommand
    for cmd i cmds.GetEnumerator(): 
    Β  Β  print(cmd.name)
    Β  Β  print(cmd.guid)
    

    This gives me a GUID of the searched command, but is there a way to call/execute this menu using the GUID
    (like its done in codesys/Test Manager python scripts)?

    Thanks

     
  • Anonymous - 2015-07-16

    Originally created by: M.Schaber

    Hi, etamgul,

    The following should work (I did not test it myself, I don't have the SIL2 extension installed here):

    system.commands["sil2_commands", "enter_debug_mode"].execute("{device object guid"})
    

    or alternatively, using the command guid

    system.commands["{B4C6C2D3-CFDA-4A01-9065-E9AD98FADFA4}"].execute("{device object guid"})
    

    You need to pass the guid of the device in question.

    Remark:
    The execute() function of the commands is officially undocumented and unsupported (as we do not intend to document the command interface for end users), but it may be used as an "emergency exit" in cases like this. Usually, this indicates a missing "official" scripting API. I'll talk to the SIL2 guys whether they intend to add an official scripting API for SIL2.

     
  • etamgul - 2015-07-16

    Hi

    Thank you for the snippet, that was thing I was looking for!
    Its working but now i got a new problem: somehow I have to answer a pop-up windows that is asking me whether I really want to put my PLC into debug mode.

    I found the ISystem.prompt_answers Property but so far I had no luck using it,
    could you help me with this one also?

    Tried to print out the question list and place many answers everywhere but seems that the execute command is halting the execution of the script too.

    system.prompt_answers["sil2_commands"]= PromptResult.OK
    system.prompt_answers["enter_debug_mode"]= PromptResult.OK
    system.commands["sil2_commands", "enter_debug_mode"].execute(str(proj_device.guid))
    system.prompt_answers["sil2_commands"]= PromptResult.OK
    system.prompt_answers["enter_debug_mode"]= PromptResult.OK
    system.delay(1000)
    system.prompt_answers["sil2_commands"]= PromptResult.OK
    system.prompt_answers["enter_debug_mode"]= PromptResult.OK
    for i in system.prompt_answers:
    Β  Β  print str(i)
    

    And I'm sure that I'm not using the prompt_answer correctly.

     
  • Anonymous - 2015-07-16

    Originally created by: M.Schaber

    Hi,

    The key for the prompt_answers dictionary neds to be the message key of the dialog in question, not the command name.

    The message key for the prompt in question is "EnterDebugMode_Prompt".

    There's another dialog coming up later, which is a simple info dialog. You can either catch it using the message key "EnterDebugMode_Info_PlcEnteredDebugMode", or by unsetting the ForwardSimplePrompts flag - unsetting this flag simply suppresses all dialogs with only a single OK button and no choice to the user.

    In general, you can learn about unknown message keys by setting the "LogMessageKeys" flag at the beginning of your script:

    system.prompt_handling |= PromptHandling.LogMessageKeys
    

    This will log all message keys to the message view.

    In your case, there are two more message keys you could get: "EnterDebugMode_Error_PlcDeniesDebugMode" and "EnterDebugMode_Exception" - they can happen when something goes wrong.

    HTH,
    Markus

     
  • etamgul - 2015-07-17

    Thank you again, I think I've managed it. I had to experiment a bit but just for the others who would like to do the same:

    If I got it right

    system.prompt_handling |= PromptHandling.ProcessScriptPrompts # this forwards prompts to script
    system.prompt_handling &= ~PromptHandling.ForwardSimplePrompts # this silences other prompts
    system.prompt_answers["EnterDebugMode_Prompt"]=PromptResult.OK # you have to put it before the execute
    system.commands["sil2_commands", "enter_debug_mode"].execute(str(proj_device.guid))
    

    What I did not understand is why I had to pre-answer a prompt but its working so far so I dont mind

     
  • Anonymous - 2015-07-17

    Originally created by: M.Schaber

    Hi,

    The ProcessScriptPrompts is only about the prompts issued by the script itsself, via system.ui - it is disabled by default so a script which disables ForwardSimplePrompts can still show its own prompts.

    You need to "pre-answer" the prompts for the following reason: Command execution is synchroneous[1], like any other function or method call. Control only returns back to the script after the command is finished. So when the script lines after the command are executed, all prompts have already been shown. The only way to solve this is to preload the answers for the expected prompts[2].

    [1] Even if it was asynchroneous, there'd be a race condition.

    [2] Or to invent a time traveling device, of course...

    HTH,
    Markus

     

    Related

    Talk.ru: 1
    Talk.ru: 2

  • etamgul - 2015-08-13

    I was experimenting with this system.commands["", ""] interface and I'm trying to figure out
    where did you get those strings ("sil2_commands", "enter_debug_mode").

    When i list all the commands i get the same guid but with different name:
    b4c6c2d3-cfda-4a01-9065-e9ad98fadfa4 - "Enter debug mode..."

    Could you tell me how can I get a list of the available/searchable tokens that can be searched for
    using the IScriptCommands' [] get interface?

    To be more excact: I'm trying to figure out how could I set and enable a breakpoint using the script.
    I'm not sure if its managable at all (or available but just with limitation e.g. script executed under GUI).

    Thanks!

     
  • etamgul - 2015-08-13

    Never mind, i found it:

    for cmd in system.commands.GetEnumerator(): 
    Β  Β  print("{0} - {1} - {2}".format(cmd.guid, cmd.name, cmd.tokens));
    

    b4c6c2d3-cfda-4a01-9065-e9ad98fadfa4 - Enter debug mode... - Arraystr
    37fbe729-b4ba-41fe-9f74-4987df16c487 - Create coverage info - Arraystr

     
  • Anonymous - 2015-08-16

    Originally created by: M.Schaber

    Hi,

    Happy you found a solution - on the other hand, you can also use the guid as key in the [index] operator - a little bit more ugly, but it should work, too.

     
  • RTgiga - 2015-09-18
    system.prompt_handling |= PromptHandling.ProcessScriptPrompts # this forwards prompts to script
    system.prompt_handling &= ~PromptHandling.ForwardSimplePrompts # this silences other prompts
    system.prompt_answers["EnterDebugMode_Prompt"]=PromptResult.OK # you have to put it before the execute
    system.commands["sil2_commands", "enter_debug_mode"].execute(str(proj_device.guid))
    

    I had the same issue and this works fine for me but I'm still wondering, if there is an easy/easier way to find out the project device guid? I found the guid in an exported file (Project -> Export...) but i hope there is a more elegant solution (maybe another python script?).

     
  • Anonymous - 2015-09-18

    Originally created by: M.Schaber

    Hi,

    The objects in a project all have a "guid" property - so you could use projects.primary.find("DeviceName")[0].guid if the device is the only object with this name.

     
  • sg - 2016-05-11

    I am trying to execute the command : ('Update structured variables', <system.guid 0x00000000000000f9="" object="" at="" <span="">[714fa2c5-b677-45b2-85d8-3144aba5d531]>, Arraystr)
    This is a workaround for me because recipe management is not available through scripts</system.guid>

    I need to update the structured variables of all the recipes from the script. I thought the argument to the execute command would be the guid of the recipe. But I get the error : object reference not set to an instance of an object. Am I missing some argument?

    cmd = system.commands['{714fa2c5-b677-45b2-85d8-3144aba5d531}'] #get the update structured variables command
    cmd.execute('{f992dc78-635a-4094-bcb4-56c1e53ee1de}')#execute command using recipe guid
    
     
  • Anonymous - 2016-05-12

    Originally created by: M.Schaber

    Hi,

    Please note that using the undocumented command interface is not a supported usecase. We might use it for workaorunds sometimes.

    The command in question does not take any arguments. Instead, it works on the currently selected Recipe Definition Editor. If the active view is not a Recipe Definition Editor, it will throw a null reference exception.

    HTH,
    Markus

     

Log in to post a comment.