06-20-2009 01:38 AM
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.
06-22-2009 12:50 PM
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
06-23-2009 02:51 AM
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.
06-23-2009 10:16 AM - edited 06-23-2009 10:19 AM
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
06-24-2009 04:09 AM
06-24-2009 10:26 AM
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
06-24-2009 10:33 AM
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
06-25-2009 02:33 AM
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
06-25-2009 04:10 AM
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
06-25-2009 11:50 AM
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