Jump to content

ak_nz

Members
  • Posts

    88
  • Joined

  • Last visited

  • Days Won

    7

Posts posted by ak_nz

  1. Thanks for the replies, guys. (Thanks also for the links, ak_nz). That (mostly) clarifies things for me. ak_nz, I won't have a problem with children restricting the parent functionality if I do override the method at some point - I guess you're talking about LSP, right?

     

    One final question on this: once I put code in my abstract parent method, is it technically no longer called "abstract"? I can see that it doesn't matter functionally, but I just want to get my terminology right at this early stage. 

     

    You can have an abstract class that implements some concrete logic. Since it is functionally irrelevant from a compiler perspective the important thing is to communicate the intent of the class to other developers. One technique I use in this scenario is to alter the class icon to a wire-frame cube (rather than a full cube) using GDS which indicates that the class is not intended to be instantiated but exists only to specify a common interface for concrete children and implement some common behavior. 

    • Like 1
  2. You aren't really "breaking" any good-practice rules in OOP design. There is nothing inherently wrong with have common functionality in an abstract parent - as long as you are comfortable that this will always reasonably be the case for all child implementations. If you come up against scenarios where children are over-riding methods just to inhibit parent behavior then you are definitely seeing a code smell - your hierarchy is making assumptions about behavior that are not true for all children.

     

    One of the most important guidelines for OOP design is to favor composition over inheritance for exactly this reason - inheritance enforces behavior that isn't always appropriate. The guideline encourages small, focused hierarchies of classes and then using composition where needed to add functionality without impacting the hierarchy.

     

    Unfortunately OOP development in LabVIEW is cumbersome compared to other languages, so we can all be forgiven for taking a short-cut where it is simply more expedient.

     

    EDIT: If you are new to OOP development, I encourage you to read through these if you haven't already:

    • Like 1
  3. All I can add to this is that QueueYueue's suggestion is exactly how I resolve similar issues in my frameworks without resorting to other class creation frameworks such as GOOP or G#. Let dynamic dispatch work it's magic on object terminals and let the root class be by-reference.

     

    The ESF has the same issue you are experiencing but it has that nifty class creation utility to hide the busy work.

  4. How did you go about writing to the output stream? I used the VI found here and it writes to the console, but it isn't captured by Bamboo (although my echod commands in my batch file are, so I know bamboo does get this stuff). I may just write to a file and have my batch script read from the file and echo its contents after the fact as James mentions but it would be nice if I could get it to update in real time and let the tool stick everything in its native log file. In the meantime, I will confirm Bamboo will get StdOut so I'm not chasing something that's impossible

     

    We pretty much use the VI from that thread. I've attached our copy (LV2012 onwards). I can't say much about Bamboo, but when we use TeamCity it is looking for tokens in the stream that indicate specific messages. That's how we transmit status messages (progress) as well as unit test results etc.

     

    I do recall having issues executing a batch file and then receiving messages though - currently we execute scripts manually in TeamCity (ie. it opens a command window and then feeds each line as StdIn). Perhaps this is related to your issue?

    Write to Console Standard Out.vi

  5. I thought about this route but if it fails I wanted to be able to add errors to the file. I suppose I could do if finished and file doesn't exist, success, if finished and file exists, failed.

     

    If you don't have the option of extracting information form the output stream with your Bamboo thingy-a-bob then this would be your best option.

    • Like 1
  6. What I am doing is launching LabVIEW from the command line, via a batch script that is called from bamboo. I have an input variable that is the path of the VI which does the build using the build API that ships with LabVIEW. Bamboo relies on the response from the application that was launched to determine a passed/failed build. I am now taking the approach my batch file waits for the call to LabVIEW to return, my build VI dumps a log file which holds success/failure inside, and my batch script looks at the file to determine a pass fail. Then, the batch script can return exit(0) or exit(1) itself, which bamboo captures. To get out of LabVIEW, I am fine with just putting an exit LabVIEW function in my VI that does the build, since this VM will be dedicated to builds. Whew.

     

    Edit: I did try launching LabVIEW directly from Bamboo. While this did launch LabVIEW, calling exit (0) or exit(1) from LabVIEW using the CLFN crashed LabVIEW. So, there was no way to tell Bamboo that the build failed or succeeded, and it would always fail.

     

    We do the same thing - since the command output stream is already hooked back to TeamCity we don't need any content in the result log file - it's presence (or not) indicates whether the LabVIEW process finished successfully or not.

  7. I do not know if you have seen https://decibel.ni.com/content/thread/8817  on the community web site, it is quite an interesting read plus http://blog.jki.net/news/niweek-2012-fire-and-forget-bulletproof-builds-using-continuous-integration-with-labview-video-slides-now-available/ JKI have a download with some example code for kicking off a build.

     

     

    Our main software dev teams C & C++ work on Jenkins for all our builds, but I have not done one for LabVIEW yet. 

     

    One problem I have with all this is LabVIEW software licenses. Jenkins here works on a Linux box, I would need to allocate a LabVIEW build PC  (windows)  and put a copy of LabVIEW on that PC for no other reason the the build and I have no spare licenses. I could see how it would work well with the floating license situation, but I am on fixed seats here.

     

    Before we had a dedicated build agent PC (well virtual machine, but you get the gist) I actually used my development machine as a build server and scheduled the hours the the agent was available for (typically break times, outside work hours, times I knew it didn't need LabVIEW etc.). Not quite as useful as a dedicated machine but it was able to take advantage of the same license. I could enable or disable the agent when I needed control of LabVIEW back to get some actual work done, and then relinquish it back to the build agent when I was done. Build agents are independent of the build server with TeamCity so if my development machine was unavailable the build server would try and locate another available agent.

     

    Thanks guy, good responses. This is the feedback I have been looking for. AK_NZ this is pretty much the route I have been beginning to take so that at least confirms I am on the right path. Danny, I don't have the same licensing issue luckily. But, I really appreciate those links. I hadn't come across them and they seem pretty valuable.

     

    The biggest issue we faced was the automation of the LabVIEW IDE. We went through several hoops to make sure that we could shut-down the IDE normally when a "build" was finished. If only LabVIEW, ironically, had a command-line version  :P

  8. Yes, the build can be finicky for sure. I'll see how this works out. Anyways, I am making some headway and when I have something that's at least somewhat substantial I'll post back with my findings.

     

    We built a basic utility we inventively called "GBuild" that is run via command-line when starting LabVIEW. GBuild parses LabVIEW command line arguments (ignoring itself) to determine what project to open, whether to mass compile or clear the compiled object cache, what number to version a build (e.g.with reference to source control version), what unit tests to run (by unit test framework provider, we occasionally use more than one), what VI Analyzer configuration file to use (if required) and then what build specification to execute. We use the command output stream to feed information back to the CI runner (progress, unit test results etc.), which in our case happens to be TeamCity.

     

    The actual TeamCity build agent in our case is a virtual machine with the development environment elsewhere on the network. As part of the pre-build process TeamCity automatically checks the source out of source control prior to starting GBuild.

     

    This works quite well, even in some scenarios where we "chain" builds (one build is dependent on the previous).

     

    The only issue we have had is where we use .NET assemblies as part of a project that is being built - if the .NET assembly version has changed then we have had to add a programmatic "Save All" to avoid LabVIEW hanging at exit with a prompt to save changes (since there is no actual user).

    • Like 1
  9. I'm looking at a spec for a future feature in LabVIEW today. The spec talks about top-level VIs and not-top-level VIs. The top-level VIs are the ones that are the top of your application or that are kicked off and run independently (through Asynch Call By Ref or the Run VI method). The not-top-level VIs are all the other VIs.

     

    Does anyone have a term better than "not-top-level VIs"? I'd like to call them "subVIs", but people both inside and outside NI abuse that term all the time to refer to all VIs since any given VI could become a subVI at any time. Using "subVIs" for a specific subset of VIs apparently creates confusion -- trying to do that appears to be what lead this spec document that I'm reading to use "not-top-level VIs".

     

    Does anyone have a good term expressly for "not-top-level VIs"? Or should I just tell people "use the term 'subVI' and we'll educate the confused."?

     

    Personally I have no problem with the term subVI. In our business we understand that the term refers to a caller-callee relationship - often we say "PleaseDoThis.vi calls DoThis.vi as a subVI" to indicate that more clearly.

  10. There is a threadconfig.vi in vi.lib\Utility\sysinfo.llb that will configure LabVIEW and write the necessary settings into the LabVIEW.ini file. You can then copy them into your application ini file.

     

     

    I typically have a post-build action that can update the ini file with the appropriate keys. Having written an application with over 20 asynchronous processes running long-time .NET calls it comes in handy. On occasion I have had to create a "wrapper" VI that launches the common SubVI(s) in a  specific execution system so that I can share the load appropriately. The SubVI(s) are obviously configured same as caller.

  11. The .NET GUID would work for sure, but here's my KISS solution.

     

    A private VI that is a functional global. I'll call it "generate GUID". All it does is store an internal counter that gets incremented every time you call it. First time you get to it you get a 0, 2nd time it's a 1, etc. Guaranteed to never give you the same value twice (until your program restarts or your counter rolls over). I find this works for 99% of my unique ID needs.

     

    Followup food for thought: if you use unique ID's you probably need to use a constructor type VI. There's no way to enforce this in LabVIEW, but it's something that you can document and check for at runtime. If you do things By reference you can enforce the constructor a little better, you get a built in Unique ID (the reference value), but now you have all the additional concerns of a by-ref architecture. Unique IDs are not enough of a reason for me to switch to By-ref, but they could be one check in the "pro" column that I would consider when designing the entire system.

     

     

    You could certainly use the basic incrementing number solution. Often I need to serialize my objects to disk and back so I tend to go straight to the less KISS approach so that each object really is unique.

  12. I'm looking for a way to programmatically generate a unique identifier for each instance of a object class.

    E.g. is there a function to get a refnum from an object?

     

    Ideally, someone can suggest a built-in unique identifier so I don't have to build into object data and check it myself.

     

    By-value objects are just data so there is no unique identifier for them that already exists - you will have to create one yourself. You could create a GUID as an object property. They are unique "enough" that they are used through-out the Windows infrastructure. The .NET static method Guid.NewGuid() will provide this for you as a string in a single call.

  13. ak_nz,

     

    Do you know if there would be any issues with having TFS and SVN on the same system while I am trying to evaluate SVN?

     

    Joe

     

    As long as they are different working copies there should be no conflicts at all. I personally have both those, Perforce (legacy systems) and Git source control providers installed.

  14. This is what I used to do (using SVN) as I was scared that moving files using the LV project would break my VCS. Actually it turned out to be a far bigger pain constantly re-finding VIs in the LV Project.

     

    Now I perform all file operations using the Project window and I just rely on the VCS tool (I use Hg now) to figure out what has gone wrong. Sure you may lose some of the file "history", but at least most of the time the LV Project does not get confused.

     

    For SVN - using the TSVN Toolkit (from Viewpoint USA - see VIPM) helps alleviate this issue (as well as file renames). It makes the changes both in Project Explorer and SVN using the "Rename" command. THis basically performs the SVN rename (even if you just moved the file) and performs all the caller linking as well, just like normal rename / move on disk functions. The main downside is that you have to perform it one file at a time rather than bulk as you can with move on disk. We moved to SVN (away from both TFS and Perforce) because of this toolkit  - and this is one of the key reasons.

     

    There is no such convenience for Perforce or TFS. Without the TSVN Toolkit this would be the same similar issue with SVN as well.

     

    As far as source control goes - I still think that storing relative paths in all project and library-type xml files is the best best (where projects are still absolute paths). At least then a convention of "folder -> project file -> sub folders with all the project content" would make re-linking easier if you wanting to move things around outside of LabVIEW.

  15. Hi there,

     

    It's a loaded question to be sure. But we have had to consider similar things in the past before as well. Here would be my feedback:

    • We use Intouch for production equipment HMIs. This is mainly due to the ease of rapid prototyping and the enhanced graphical capabilities that are needed. We find that LabVIEW is sorely lacking in this department - our HMIs are intended to be operated with minimal training and be accessible to the "swipe" generation.
    • For test equipment with specialist hardware we often have a TestStand or LabVIEW back-end that does a lot of the hardware interfacing. For other automation equipment we often revert back to cheap but effective PLCs.
    • The ability to do complex animation effects, window management and scripting is typically built-in and intuitive in most SCADA systems. It's what they are there for after all.
    • Most SCADA HMIs (Intouch included) support ModbusTCP. This is a very common communication protocol and is often "built-in"..
    • We have implemented much more complex systems than this in Intouch previously.
    • SCADA systems typically require purchasing a development license and then a run-time license on each machine running the deployed HMI. You should factor this cost into your solution chart when making the decision. You can always contact a local representative in your country to determine the expected costs.
    • Do not forget the cost of engineering time. This is difficult to gauge in your case but the fact that you are already familiar with LabVIEW is a strong tick in that column.

     

    SCADA systems are not as typically good at performing test sequencing (their primary function is data collection, display and logging hence the name). In your case the infrastructure needed is not great so it is quite possible to implement what you are proposing in such a system and we have done so many times before. However I suspect that familiarity will be the biggest deciding factor for you. I would encourage you to explore the SCADA option if only for future endeavors where your requirements are different.

     

    Hope that helps.

  16. how does a deployed labview application have it's thread configuration set?  Do the changes you make in the threadconfig.vi somehow get put into the application ini that the run-time engine reads?

     

    John

     

    The configuration is contained in the *.ini file for the built application along with other properties such as vi server configuration. Here's an example of the content that updates the Other1 and Other2 execution systems maximum thread count for each priority. You can generate this programmatically as part of the application build spec with a Post-Built Action :

     

    ESys.other1.Normal = 20
    ESys.other1.High = 20
    ESys.other1.VHigh = 20
    ESys.other1.TCritical = 20
    ESys.other2.Normal = 20
    ESys.other2.High = 20
    ESys.other2.VHigh = 20
    ESys.other2.TCritical = 20

     

    Note that you could also just use the same property settings in your LabVIEW.ini file for the same effect in the development environment. I believe this is all threadconfig.vi actually does however it doesn't touch any application build specs (not that sophisticated I'm afraid).

     

    Here is a quick post build vi I cobbled together to generate the entries on every application build:

    post-27534-0-01300200-1398971787_thumb.p

    • Like 1
  17. Thanks Omar. Further investigation seems to indicate that pulling network licenses is what is causing the issue. Oh well, running the agent as an application will work for now.

     

     

    I didn't use the VLA with my CI Servers so that could be the issue.  If any dialog was blocking the execution, then you're basically stuck if LabVIEW is running as a service with no UI.

     

     

     

    Re: VI Tester, check out the LabVIEW Tools Network - you might find a nice surprise ;)

     

    I see a fix there for template instantiation, nice! I'll check it out. I confess I had actually lost a little faith and ended up building my own unit test framework with some similarities to VI Tester (ie based on xUnit) solely so that we could run on 2012+ and get the benefits of a leaner framework for CI rather than NI's UTF. But I would always rather use a tried and tested tool. Just an FYI this is the sort of tool we would happily pay money for!

  18. Hi Omar. Thanks for your response - yes I read your presentation thoroughly!

     

    I have tried previously adjusting the service's rights to interact with the desktop but it was still no go. I can only think that some other policy is blocking my ability to do this. Given we have a VLA and are checking out development licenses from the server rather than a local license I had wondered whether it was this activity that was being blocked in this scenario.

     

    I have ended up running the TeamCity agent as an application rather than a service; things work fine this way. It's not ideal but would welcome any other ideas.

     

    PS. Any idea when VI Tester will be updated to LV2012++? Nudge, nudge!  :shifty: 

  19. Hello all,

     

    I am trying to integrate our LabVIEW build workflow into our CI Server. Currently we have several builds in LabVIEW projects that we can programmatically call in order to perform the build, conduct unit testing etc. using the IDE.

     

    I'm looking to integrate this into our build server using TeamCity. Every time we check in changes to one of the projects a build is triggered. Since building requires the IDE running, I am attempting to use the Command-line Runner in TeamCity to execute a batch file that launches the IDE with the builder VI as an argument. The build VI performs the builds, testing and then shuts-down LabVIEW.

     

    Running the batch file manually (as me) works a treat - LabVIEW starts up, the builds occur, unit test results are captured and then the IDE shuts-down. However I have run into a problem getting the batch file automatically called by TeamCity. The build agent runs as a windows service and it appears as if windows services do not have permissions ordinarily to start up GUI applications. I have tried several options such as configuring the log-on account for the service to run etc. Every time the build occurs, the log shows that the batch file has been run but LabVIEW does not start up.

     

    Unfortunately there is no command-line version of LabVIEW (pity) so it appears as if there is no obvious way to get this to work. Has any-one attempted this before? I know guys at JKI pull this off (using a different CI server) and I'm wondering whether this issue is familiar to anyone.

     

    Thanks for any and all help.

     

     

  20. The original post can clarify but I think the complaint is that when the VI from the tools menu is ran from the project explorer, the App.MenuLaunchApp doesn't return the application instance that the project is using.

     

    hoovahh is correct - I would like to ensure that I run a VI in the correct application context (in my case it will always be the singular My Computer) of the active project regardless of whether the menu was opened from Project Explorer or a VI opened from Project Explorer. I had hoped that MenuLaunchApp would provide this but Aristos' explanation proves otherwise.

     

     

    The MenuLaunchApp property only works the way you desire when the menu launch VI is launched from the menu of a VI. If you want to gain access to the project from which the menu launch VI was run, you'll need to use the Active Project property:

     

    attachicon.gifproj.png

     

    From here, you can parse the project and get the Application Instance (which will be different per target in the project) you want.

     

    This seems like the best idea. Since I want to the same behaviour regardless of whether the menu is called from project explorer or a VI in that project, this would appear to be the only way to ensure that. I am building a simple custom unit test framework so all my tests will be executed in the IDE in the My Computer app instance; I can hard-code the search for that.

     

    Thanks for your help guys.

  21. I had something similar happen.  Before today I have never ran a tools menu item from the project window not that I think it is a bad idea.  I have a tool that takes an array of string and makes an enum based on it.  It will make it in the application instance that the VI calling it is in.  When I run it from a VI it works as expected making it part of the project that VI is in.  But similar to your issue when I run it on the project window it makes the enum not putting it in the project instance.  Not sure if this is expected or not just wanted to let you know you aren't crazy.  By the way I see this in 2012 SP1.

     

    Thanks for checking it out (although I might still be a little crazy generally speaking!). I'm on 2012 SP1 as well.

     

    I did a little test using a basic VI that grabs the current context and the MenuLaunch context names under a number of conditions:

     

    1. Getting Started Window - ThisContext=NI.LV.Dialog, MenuLaunchContext=NI.LV.Editor, MenuLaunchVI=GSW.lvlibp:GettingStartedWindow.vi
    2. Project Explorer - ThisContext=NI.LV.Dialog, MenuLaunchContext=NI.LV.Dialog, MenuLaunchVI=_ProjectWindow2
    3. New VI in the Project - ThisContext=NI.LV.Dialog, MenuLaunchContext=My Computer, MenuLaunchVI=Untitled 1

    Surprisingly there is an actual Launch VI for running from the tools menu in Project Explorer, although I don't know whether the naming is anything specific or could just be random. In any event this doesn't get me the project application context that I was after unfortunately.

  22. Hello forum LAVA-ites,

     

    I am attempting to write a Tools Menu item to slot into the IDE. The intent of this "Tools" VI is that it determines the application instance that launched it and dynamically run a VI in that application instance so that the launched VI can access VIs in that instance. This is basically a custom Unit Testing tool that looks for particular VIs in the project that houses the application instance.

     

    I was attempting to use the App.MenuLaunchApp property in this "Tools" VI so that I could wire up an Open VI Reference node with the right application instance and the name of the VI to run dynamic VI to run. I added an extra indicator on the launched VI to show what application context it is running in.

     

    If I have a VI open from a Project and then launch the "Tools" VI from the Tools menu, then the dynamically run VI indicator shows "My Computer" (referring to the project housing the application instance). However - if I launch the "Tools" VI from the Tools Menu while Project Explorer is showing then the dynamic VI launches in the NI.LV.Dialog irrespectively (the indicator on the front panel of this VI shows this).

     

    Is this expected behaviour? Is there a way around this so that the dynamic VI gets loaded into the right application instance even if launched from Project Explorer?

     

    Thanks in advance.

    • Like 1
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.