NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Create Testsequence by using the TestStand API with Python

Hello Folks,

Since a month I'm came in touch with TestStand and VeriStand.
My attempt is during my Mastersthesis to create an ideally Python Program that creates TestStand sequence files.
It seems, at least from my point of view, a complete rabbit hole with thousands of options, but I'm still struggling to find what feeds my needs.

If found the example files where you can create a sequence file by using a sequence.xml.
But unfortunately, at least to me, it seems to be a hassle to figure out which lookupstrings match to what.
Or where I find the needed ones to make my step functional.
Is there any page I maybe missed or a button I need to click to see how they translate?

Next trouble I ran into today, how to create a Locals variable.
I need to set one to pass the created asam xil framework command to the following step.
I only found a sequence file that uses the ActiveX/Com adapter to create one.
But I didn't found a way to put this in the sequence.xml file.

Just an hour ago, I found this:

Calling the TestStand API in Python - NI Community

It seems to still work even with python 3.10 but still it s a little stabbing in the dark to get it up and running a specially for the add local variable part.

Maybe I have some complete wrong approach on this hole thing but at the moment it drives me nuts.
It would be great if someone could give me some input.

Greats,
maxhuebn

0 Kudos
Message 1 of 8
(404 Views)

Hi,

 

not much of a Pythpn guy, but.... from what I understand, the TestStand API is exposed for Python just as for LabVIEW or .net.

 

So for me, this means that your pain basically lies in using the API, right?

 

Regards

Oli

0 Kudos
Message 2 of 8
(368 Views)

Hi Oli,


If it's true that the API is accessible by all languages similar, then yes, it lies in understanding it.

For my understanding now, there are different approaches.


One is to use the API as a dll like the NationalInstruments.TestStand.Interop.API bind in your program.

And for this to work you need to call the program inside from TestStand to get a running engine.

Another is to attach to a running TestStand engine instance using ActiveX/COM as far as I understood.

For the first approach, I'm using a xml file which gets translated to TestStand using a sequence.


<?xml version="1.0" encoding="utf-8"?>
<SequenceFile xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Sequence Name="MainSequence">
    <StepGroup Name="setup">
      <Step Name="Create Veristand Variable" Type="Action" Adapter="Automation Adapter">
        <!-- <Prop LookupString="TS.SData.Call.ServerName">NI TestStand 2022 Q4 API</Prop>
        <Prop LookupString="TS.SData.Call.MemberName">SetValInterface</Prop>
        <Prop LookupString="TS.SData.Call.Parameters.value.value.AutomationParameter.ArgVal">"veristand"</Prop>
        <Prop LookupString="TS.SData.Call.Parameters.value.value.AutomationParameter.Direction">1</Prop> -->
        <Prop LookupString="TS.SData.Call.ServerName">NI TestStand 2022 Q4 API</Prop>
        <Prop LookupString="TS.SData.Call.MemberName">SetValInterface</Prop>
        <Prop LookupString="lookupString">"veristand"</Prop>
        <Prop LookupString="options">1</Prop>
        <Prop LookupString="newValue">Nothing</Prop>
      </Step>
      <Step Name="About" Type="MessagePopup" Adapter="None Adapter">
        <Prop LookupString="MessageExpr">\"This Sequence was generated from an XML file using the
          TestStand API.\"</Prop>
      </Step>
      <Step Name="Open Veristand" Type="NI_OpenVeriStandProject" Adapter="None Adapter">
        <Prop LookupString="ProjectPath">C:\\Users\\Public\\Documents\\National Instruments\\NI VeriStand 2020\\Examples\\Stimulus Profile\\Engine Demo\\Engine Demo.nivsproj</Prop>
        <Prop LookupString="StepReferenceOutputExpression">Locals.veristand</Prop>
      </Step>
    </StepGroup>
    <StepGroup Name="main">
      <Step Name="Create Framework" Type="NI_FrameworkCreate" Adapter="None Adapter">
        <Prop LookupString="Source">From VeriStand Project</Prop>
        <!-- <Prop LookupString="SourceParameters.VeriStandProjectStepReferenceExpression">Locals.veristand</Prop> -->
      </Step>
      <Step Name="Get python signals" Type="NumericLimitTest" Adapter="Python Adapter">
        <Prop LookupString="TS.SData.PythonCall.ModulePath">C:\\Users\\451702\\OneDrive - Alstom\\03_gitlab_at\\fts_to_teststand\\BASTA-web.py</Prop>
        <Prop LookupString="TS.SData.PythonCall.FunctionOrAttributeName">return_10</Prop>
        <Prop LookupString="Limits.Low">-1</Prop>
        <Prop LookupString="Limits.High">1</Prop>
      </Step>
      <Step Name="wait a little" Type="NI_Wait" Adapter="None Adapter">
        <!-- <Prop LookupString="ModulePath">\"..\BASTA-web.py\"</Prop> -->
        <Prop LookupString="TimeExpr">2</Prop>
      </Step>
      <Step Name="Test 2" Type="StringValueTest" Adapter="None Adapter">
        <Prop LookupString="Limits.String">Comparison String</Prop>
        <Prop LookupString="Result.String">Comparison String</Prop>
      </Step>
      <Step Name="Call subSequence" Type="SequenceCall" Adapter="Sequence Adapter">
        <Prop LookupString="Module.AsSequenceCallModule.SequenceName">subSequence</Prop>
        <Prop LookupString="Module.UseCurFile">true</Prop>
      </Step>
    </StepGroup>
    <StepGroup Name="cleanup">
      <Step Name="Cleanup" Type="Action" Adapter="None Adapter" />
    </StepGroup>
  </Sequence>
  <Sequence Name="subSequence">
    <StepGroup Name="setup" />
    <StepGroup Name="main">
      <Step Name="subTest 1" Type="NumericLimitTest" Adapter="None Adapter">
        <Prop LookupString="Limits.Low">-2</Prop>
        <Prop LookupString="Limits.High">2</Prop>
      </Step>
    </StepGroup>
    <StepGroup Name="cleanup" />
  </Sequence>
</SequenceFile>​

The understanding of this approach was quite easy. But to make a step working, you need those prop information to be entered.
And I got shipwrecked on the more complicated ones, like the ones in the Automation Adapter.
In the GUI from TestStand those fields are rather easy to find and fill in but how is the LookupString in the xml structure.
In attachment is the original c# parser from the examples delivered with TestStand.

And there is this part in the code which has some pros and some cons:
//Evaluate an expression to set the property at the lookupString to the specified value.
//This method prevents the need to determine the data type of the property.

But how to distinguish the lookupString?

Greats,

Maximilian




0 Kudos
Message 3 of 8
(350 Views)

IMHO, you should use the API to build that test sequence. This is the most flexible way. Everything else is just a workaround

 

But to be successful you need to understand the TestStand Object Hierachy. It is always preferable to know what you are doing.

 

I do indeed reccommend the TestStand help, it describes the API quite good. Do you happen to have access to NI Training Ressources in the company where you are working (you usually do, if your company has an EA or VLA). If so you should look at the "Architecting TestSystems using TestStand" Course. Or a colleague might have the course manual for you to borrow.

 

Apart from that, I recommend reading through the examples that com along with TestStand. There are several on using the API. No matter if they are implemented in C# , LabVIEW or TestStand itself, they all use the same API and the same workflows.

 

Last not least: https://youtu.be/fPwgqkJ6wG0?feature=shared this is one of the go-to vids regarding using the TestStand object structure

 

Guess, you gotta go through all that stuff...

 

Have a great weekend! Nevertheless 😉

Oli

 

 

0 Kudos
Message 4 of 8
(321 Views)

Thanks for this video that really helped a lot.
But there is still something I can't get my head around.

So no matter with which language I call the API the best practice way to declare the needed information is to go with an lookupString.
For a MessagePopup that is really straight forward.
I look inside the Properties there is one and it is call MessageExpr and I directly set it with a value.

If for example I go with a Statement, there is the expression field. But under the Properties there is no property where I can parse a String.
What would be the natural approach to that?
There is a SubProperty inside this class Statement but nothing I would call easy.

Do you have any option for that as well?

0 Kudos
Message 5 of 8
(93 Views)

To find out about Step Properties, there's basically two ways:

 

https://www.ni.com/docs/de-DE/bundle/teststand-api-reference/page/teststand-api-ref/step.htm

 

which gives you the very generic Step properties.

 

Yet, you are usually working with StepTypes based on the Step class. You can find those descriptions in the Type Palettes.

(CTRL+T)

 

Oli_Wachno_0-1714452266570.png

 

 

With the statement step, you basically picked a definition where the edit panel kinda uses non-existing properties.

 

Things might get clear whith the next two screenshots 😉

 

Oli_Wachno_1-1714452430500.png

 

is in fact

 

Oli_Wachno_2-1714452466996.png

 

 

 

 

 

 

Message 6 of 8
(81 Views)

I saw this section but was disapointed maybe it lays in my version of TestStand as I assume now:
maxhuebn_0-1714460627766.png


I didn't choose TestStand 2022 as it was the newest working version with the deployed VeriStand version but didn't had in mind that the type tree changed.
Or did I miss something to tick in the overview.

Yes exactly that I figured out as well, but there is not only the statement which is uses something which is not handled as a property.
If I go with any Step in the python adapter.
There is no property for all the stuff like Module operation scop what so ever.

maxhuebn_1-1714461343381.png


They are all stored in the TS.Data substructure, which for mind definition at the moment is a subproperty.
The example for the API made for me the impression that most elements can be accessed using a lookupstring in the property section.
But as far as I can tell at the moment, those are just the really basic ones.

0 Kudos
Message 7 of 8
(72 Views)

Ok so now I have seen there is something really, and it is not me searching at the wrong place there is some light I can see 😄

 

Show Hidden properties did the trick!


Here are some pictures how to enable them to get an overview about the hidden properties which in fact can be accessed and needed to be accessed by the api.

maxhuebn_0-1714462767880.png

 

 

maxhuebn_1-1714462811349.png

 

PS: I got to excited too early.
The TS structure is still empty, and it is the only way to pass a python Pass/Fail Test the module to be parsed...
So seems to be still searching around in the sequence file as an XML to understand what belongs where.

 

0 Kudos
Message 8 of 8
(68 Views)