NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

How to specify a unique integer for each local variable defined in TestStand?

I have a .net application that reads all TestStand local variables, but for the .net application each local variable should have a unique integer number. Iterating through the locals and storing the index is not a good solution, because if a local variable is moved or deleted, the index will change.

 

Does anyone know how to do this in TestStand or having an idea how to this in my .net application?

 

Thanks.

0 Kudos
Message 1 of 11
(5,008 Views)

a few ideas come to mind:

 

1) If you are holding onto these variables as propertyobjects in .NET you can use the .NET ObjectIDGenerator class. If you aren't holding onto them in .NET this won't work though since you might get back a different .net propertyobject for the same COM propertyobject each time you get it.

2) Encode the unique id into the name of the variable and parse the name of the variable to get it when you need it.

3) create a container for each variable and store the value as one variable in the container and add a second variable to store your unique integer.

4) If you are using the latest version of TestStand (4.2) there is a feature where you can add attributes to a variable. Attributes are metadata that you can store for each variable. To add an attribute in the sequence editor, right-click on a variable, go to the advanced submenu and select Edit Attributes. You can then store your unique integer as an attribute on each variable.

 

Hope this helps,

-Doug

0 Kudos
Message 2 of 11
(4,986 Views)

Thanks Doug,

 

The best solution would be the best for me, because defining the number has be done automatically. But I don´t think this will work because the ID generated has to be the same for each variable each time the sequence is reloaded and started. This is because internal I need a unique number for each variable and this should be the same each time the sequence is reloaded. Please correct me if I am wrong. If solution 1 indeed does not support my need, then I would prefer the fourth solution, using a variable attribute to keep the unique number. However this unique number should be generated automatically while creating the variable. Is it possible to rise an event in C# when a TestStand variable is created, after this I will generate the number in C# and the attribute should be update automatically in TestStand  from C#? Looking forward for your response.

 

0 Kudos
Message 3 of 11
(4,975 Views)

There is no way (at least no straightforward, supported way) to get an event whenever a variable is created in the variables view. You could write a tool that modifies your sequence files by adding a numeric ID attribute to each variable when you run it. You could even run such a tool automatically when the sequence file is first run or loaded by calling the sequence from your code as the first step or using a sequence file load callback.

 

However, please note that what you are asking for is very unusual, if you provide more details about what you need this id for and what you are trying to accomplish, I might be able to suggest an alternative solution that does not require these ids.

 

I'd also like to suggest that rather than a number, you might consider using a GUID instead since it's easier to create a GUID that is guaranteed unique rather than a number (i.e. to create a unique number you'd have to make sure it's not being used by any variable yet, but GUIDs on the other hand are unique by definition whenever you create one).

 

Hope this helps,

-Doug

Message Edited by dug9000 on 06-23-2009 10:19 AM
0 Kudos
Message 4 of 11
(4,961 Views)
Thanks Doug for your reply. Using a GUID is not an option because this ID is too long. I will try to explain why I need this ID for. I have a lot of C# code that generates code to deal with a lot of instruments. For example to configure a device, user defined variables can be used to specify some settings or to store results. These variables are not stored in the generated code with a name but with an integer number. Now I want to try to be use all our existing device driver code with the TestStand sequencer. So, I need a translation between the name of a TestStand local variable and an integer number. After constructing the interface to my code I want to read all the variables from TestStand and now I need the integer ID to do the mapping to my variables. I know that I can use use your proposition 2 by encoding the unique ID into the name of the variable and parse the name of the variable to get it back, but this is not an automated way. This will be rather difficult if there are several hundreds of variables. For this reason I am looking for an alternative way. Looking forward for your response. Best regards 

 

0 Kudos
Message 5 of 11
(4,942 Views)

One thing I would like to point out is it would make things a whole lot simpler if you could store a string for the id instead of an integer. I know it would require changes to your existing code, but I think it would likely be worth it because if you could store a string you could actually just store the lookup string of the teststand variable (i.e. "Locals.myvariable") which would make the code a lot more straightforward, flexible, and more self-documenting. It would be more flexible because you could even specify "FileGlobals.MyVariable" or "Step.MyVariable" without further changes to your architecture.

 

If it's just not possible to change your existing code then the next best solution I'd recommend is a map or hashtable from this integer id to the lookup string that I mentioned above. Do you need to go from the integer id to the variable, or from the variable to the integer id or both? Where do you need to do this mapping? In your dotnet code or in the sequence? With more information I might be able to suggest a good way to implement this mapping. It really depends on where in your code or sequence you need to go from the integer id to the lookupstring or vice-versa.

 

Hope this helps,

-Doug

0 Kudos
Message 6 of 11
(4,932 Views)

In reading what you wrote more carefully, I think I understand where you need the mapping. You are doing this in dotnet code that wraps your existing generated code right? I think what might work best is when you generate the dotnet code that you are going to be calling, you can also generate the map from integer id to teststand lookupstring. Then your wrapper code can just use this generated map to get the TestStand lookupstring and then just use the lookup string along with the TestStand sequence context to get the variable. For example, if you have the sequence context and the lookupstring "Locals.myvariable" and Locals.myvariable is a numeric variable, you can get that value just by doing the following:

 

sequenceContext.AsPropertyObject().GetValNumber(mymap[integerId], 0);

 

Most of the PropertyObject API methods use lookup strings so there are many things you can do with the variable just by having the lookupstring. Let me know if I am misunderstanding your situation or if you need more details.

 

-Doug

0 Kudos
Message 7 of 11
(4,931 Views)

Hi Doug,

 

I do not understand it completely.

 

In test stand I want to use always variables with a name, because as you already mentioned it is more self-documenting.

 

But because I have a lot of .net code that is used al the time, I do not think that it is a good idea to change the code to use a name instead of a number.

 

In my .net code I have to do the conversion from an integer to a string and vice versa. I like the idea of using a hash table to store the number and the text for each variable, but then it should be possible to store this hashtable in the TestStand sequence, is this possible?

 

If I serialize this hashtable, is there a way to store it into the sequence?

 

Looking forward for your respons,

 

Best regards

 

0 Kudos
Message 8 of 11
(4,913 Views)

Hi,

 

You could store it as an attribute to relavant local variable in TestStand if you are using 4.2. Otherwise you would have to store it in an other Locals/FileGlobals.

 

Regards

Ray Farmer

Regards
Ray Farmer
0 Kudos
Message 9 of 11
(4,906 Views)

Certainly. You could either serialize it as a string (probably XML) and store it in a teststand string variable. Or you could serialize it as binary data and use the SetValBinary PropertyObject method to set a string variable to store binary data (the binary data will be encoded and compressed if you use the SetVal/GetValBinary) API.

 

If you want something that's actually usable as a map from the TestStand sequence side, you can create an array of containers. If you make the name of the containers in the array your hashkey and make a subproperty of the container store the value you can do map lookups as follows:

 

Locals.myArray["mykey"].value

 

You of course would have to write code to create this array programmatically if that's what you want. If you don't need the map/hashtable in the sequence then just serializing the hashtable to binary or xml via .net serializers and storing the result in a teststand string variable would be simpler.

 

-Doug

0 Kudos
Message 10 of 11
(4,898 Views)