LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Save Actor Hierarchy to Configuration File

Hello,

 

I've been working on a new project over the past few months using the LabView Actor Framework, which I have found to be extremely useful and will help simplify my code maintenance in the future.

 

One issue I am currently stuck on and trying to work through is the ability to save some sort of configuration file for the user containing all the relevant configuration settings and daata for each Actor in a single file.  I started out using the LabView config file VIs, which worked fairly well while my Actor's had fairly simple data.  I have one File Management Actor dedicated to saving all data and files to disk.  This actor maintained a .ini configuration file, and the other Actors would send it a message when its data changed and its section in the .ini file would be overwritten with the new settings.  

 

This was working great until the complexity of some of the Actor's data stared increasing, which includes signal processing algorithms and machine learning algorithms.  I tried just writing these new settings to binary strings in the .ini files, but when I load the config file using LabView's config file vi it can take over 10 minutes to read the file, which is incredibly slow and not acceptable for my application.

 

My goal is to save the important configuration data for the Actor hierarchy (which includes some dynamically launched nested Actors) to a single configuration file, which can then be loaded at a later time by the user so they don't need to reconfigure all their settings every time they use my program.  I don't want the user to have to worry about maintaining multiple configuration files.

 

My new idea is to use some type of tree traversal algorithm that moves through the Actor hierarchy, possibly using synchronous messaging to pass a LabView class that holds all the configuration settings and data, and once finished saving it to a binary file.

 

Before I commit to redoing my code, which will likely be painful to change since I had already based things around using LabView config file VIs and .ini files, I wanted to see if anyone else has come up with an elegant solution for accomplishing this goal.

0 Kudos
Message 1 of 7
(2,852 Views)

I use JSON for both the file format and the config info passed between application components.  Each level embeds the JSON of its subcomponents in its own JSON configuration string.  The standard LabVIEW JSON functions aren't usable for this but other JSON libraries are (such as JSONtext).

0 Kudos
Message 2 of 7
(2,836 Views)

Thank you for your reply.  Do you know if you can directly save and load LabView classes with JSONtext, and is it compatible with LabView 2019?

0 Kudos
Message 3 of 7
(2,814 Views)

Just FYI, I've been down the road of trying to just save the whole class to a file, then reloading it later. Unfortunately this *very* rapidly explodes the file size of the config VI and makes it non-human-readable.

 

The issue is that the classes maintain their version history and include GOBS of stuff about them that's not relevant to your user. Though it's painful, I'd highly recommend writing individual getters and setters for each class's relevant private data.

 

Are you storing the whole class as a binary blob in the ini file? If so that's probably the issue; you're not just storing your important data, but ALL of the info about the ENTIRE actor, its parents, all of its enqueuers and references, literally everything back up to and including the main Actor.vi.

 

BTW, as a side tip: one decent way to handle loading and saving private data is to just write a single "Load or Save [parameter]" VI. It will have your class as an input and output, a boolean "Load?" input, a file path input, and an input AND output for the parameter you're getting or setting. If the Load? flag is True, it sets the value from the input to the object. If it's False, it reads it from the object and saves it to the file.

 

Combine that with creating a malleable version of the "get value from config file" that will automatically set the "Type" (you might can do this with just the polymorphic Autoselect function- it's been a while and I can't remember the specific nuances... maybe the malleable version I made just integrated the Read vs Write into a single config file VI instead of choosing Read or Write in a case structure in the actual reader/writer file).

 

Anyway, what that gets you is a single place to define the Section and Tag of the item in the config file. It always bothered me that I had the same information duplicated in two spots (namely, the Section and Tag both had to exist in the Reader and Writer). If the layout changed any, you had to update it in both locations or you'd get an error that you wouldn't see until runtime.

0 Kudos
Message 4 of 7
(2,774 Views)

I am not saving the entire class to a binary blob, I am only saving the important configuration setting data.

 

I am not sure what you mean towards the end of your response.  Nothing is duplicated in the configuration file, each section and key show up only once.

0 Kudos
Message 5 of 7
(2,769 Views)

@dh10 wrote:

I am not saving the entire class to a binary blob, I am only saving the important configuration setting data.

 

I am not sure what you mean towards the end of your response.  Nothing is duplicated in the configuration file, each section and key show up only once.


The duplication is in the code, no the configuration file. If you have a "Load configuration" VI, you have to tell it the Section and Tag names (for example, "Scale factor") once in the Read and once in the Write. If, later on, you decide to change the name of that tag to "Scale factor (mm/v)", then you have to change it in both the Read VI and the Write VI, leading to potential errors errors with either typos or just plain forgetting to change it in both spots. If "Read" is looking for "Scale factor(mm/V)" and "Write" is looking for "Scale factor (mm/V)" then your code won't work when you try to load non-default values.

 

Oh, and one other thing- I'm not sure about JSONText, but at least some of the JSON VI's don't actually store default values in the file. For example, if Class.ScaleFactor has a default value of 16, that won't appear in the file. See this thread where I ran into this: https://forums.ni.com/t5/LabVIEW/Flatten-object-to-XML-doesn-t-work-with-default-values-in-class/td-...

0 Kudos
Message 6 of 7
(2,763 Views)

I usually have class methods called "Get Config as JSON" and "Set Config from JSON", or similar named messages for mesage-handling loops.  Sometimes I have a "Config" subcluster that just gets converted too/from JSON as a whole.  Then adding new state data that is saved just involves dropping things in the subcluster.  

0 Kudos
Message 7 of 7
(2,741 Views)