Home AMX User Forum NetLinx Studio

Virtual Devices - Why Bother?

I'm working on some code that I didn't write. It's a very simple setup that I could have programmed quickly - just a projector with three simple inputs through an A/V switcher and a touchpanel. It doesn't communicate with other rooms or do anything other turn the projector off/on and switch sources.

But the code is a forest of indirect programming spread out among 11 different include files and modules. And everything has a virtual device. When you turn on the system, a function is accessed which sends commands to the virtual projector which, in turn, activates the actual projector. (A simple send_string to the projector would suffice, in my opinion.) I've been called in because the "blank screen" button doesn't work, and I have to untangle his messy code and re-do it. It would be faster to start over, I think. But I digress.

In other places I've been, the previous programmer made a virtual touch panel and combined it with the realone, but I never saw any reason to include the virtual one in these programs.

What am I missing? Why all the virtual devices? Is it just a habit of certain programmers that I've never needed to use? Or am I missing something vital?

Comments

  • ericmedleyericmedley Posts: 4,177
    Obviously not seeing the code it's a bit hard to make comments...

    But my guess would be that you're seeing the product of someone who has designed a system that works for a variety of system sizes and scales and has just pared this one down to the size of the system in question.

    From my own experience you tend to get to this point after doing a whole bunch of large systems using a fairly 'one-off' design method. Sooner or later the scale becomes too difficult to manage.

    So for example, I eventually designed a system that could handle up to 100 TPs, 100 TVs in any configuration, 48 whole house audio zones, etc...... When I programmed a new system all I had to do was just fill in data for that system. I didn't really program anything.

    The design work was already finished. I just needed to input data for what room(s) a TP controlled, what TVs it controlled, what the names of audio zones were. Etc..

    I'd guess what you have might be something along these lines and it was just scaled down for your little system.

    But that's just a guess...
  • samossamos Posts: 106
    A few years ago the classes would teach that all touch panels should be combined with a virtual device. That is the way AMX would teach you to program all panels that you use. So my guess is that he was using a virtual device for all touch panels. As far as for devices most modules use some form of virtual devices to communicate with there devices. I am not saying this is the best way to do things but this is the way that AMX would teach at the classes.
  • Interesting. I've only been in this game for five years, and it's amazing how many practices there are that only exist out of habit. Not that I'm judging - I spent half of my time lining up the brackets in the code because they weren't organized like my brackets.
  • regallionregallion Posts: 95
    I'm guilty of adding various levels of abstraction myself.

    I've worked on so many large projects where equipment lists change at the list minute, kit is added or removed that the "normal" method of programming these systems would just be a nightmare.

    I actually spent a good few months developing an Excel spreadsheet that allowed me to define my device classes, quantities, locations and any other meta-data I wanted to track and then hit a button and generate pretty much all my core control code.

    Client swaps a projector model? No problem, change a cell value in the spreadsheet and hit the "Generate" button again.

    Biggest advantage of this is once the code has stabilised (ok - debugged!), every time I make a change to the sheet and hit the button I know the code is bug-free and going to work!

    I've attached a screenshot of an example project I worked on with this in action.

    Things like adhering to a methodology like SNAPI and constructing your drivers / modules in a consistent way help a lot.

    But to do this, you need to work in an abstract, virtual way!

    Urgh - hope the picture isn't too big!
  • tom goeztom goez Posts: 75
    Virtual Devices - Why Bother?

    I use them for every touch panel, wired or wireless.

    If a panel goes offline at a customer's premise, the virtual stays online (unless there's a massive failure of the master) and the system can be controlled via a M2M. Very useful for remote monitoring situations which we do a lot of.

    I have seen programmers use myriads of include files which makes following the code difficult. Sometimes I think it's to keep a competitor's programmer from easily mastering their code. I usually just do a rewrite. It can be quicker.
  • PhreaKPhreaK Posts: 966
    When done properly abstraction allows for flexibility and (should) increase readability. When its not quite all the way there it makes you want to track down the previous programmer and give them a solid slap with a wet wish. Virtual devices are one of the tools that assist with providing abstraction in NetLinx.

    For example, say you have a system where all devices are controlled via modules that conform to SNAPI and you've been called in because they are swapping out the projector with a different model. If the abstraction has been designed properly the core system logic does not care, or even know what type of projector its talking to. It doesn't even need to know its a projector. All that its concerned about is that there is a display attached somehow (again, this part of the system shouldn't care how).

    In this case you can build a module for the new device, run it up on your desk and test it to make sure that everything behaves as expected, or you may even have one from another job ready to go. Now when you head to site its just a matter of changing the define_module line that instantiates the module and your done. All the device interaction is done via a virtual device so there's nothing else to do - all the system logic remains unchanged and RMS monitors everything nicely without you needing to touch a thing. No trawling through mountains of unfamiliar code for individual string events to the device. No incredibly time intensive system interaction tests. And most importantly, a massively reduced risk of introducing new bugs.
  • ericmedleyericmedley Posts: 4,177
    I don't use the 'combine TPs with Virtual devices' method myself. I prefer to manage devices with dev arrays and then reference all channels, levels, buttons and commands to and from stiff with arrays.

    Combine device is left over from Axcess days. I really don't see any advantage to using it over dev arrays and don't like to deal with the disadvantages.

    But there are a lot of ways to skin a cat.
  • rfletcherrfletcher Posts: 217
    I'm working on some code that I didn't write. It's a very simple setup that I could have programmed quickly - just a projector with three simple inputs through an A/V switcher and a touchpanel. It doesn't communicate with other rooms or do anything other turn the projector off/on and switch sources.

    But the code is a forest of indirect programming spread out among 11 different include files and modules. And everything has a virtual device. When you turn on the system, a function is accessed which sends commands to the virtual projector which, in turn, activates the actual projector. (A simple send_string to the projector would suffice, in my opinion.) I've been called in because the "blank screen" button doesn't work, and I have to untangle his messy code and re-do it. It would be faster to start over, I think. But I digress.

    In other places I've been, the previous programmer made a virtual touch panel and combined it with the realone, but I never saw any reason to include the virtual one in these programs.

    What am I missing? Why all the virtual devices? Is it just a habit of certain programmers that I've never needed to use? Or am I missing something vital?

    The main thing I use virtual devices for (really the only thing) is to communicate with modules. There are imo two major reasons to use modules to interface with devices. Reason #1 is that they are much easier to reuse in new systems as opposed to copy & paste to the main file because they have their own namespace and therefor you don't have to worry about conflicting variable names. This makes programming new systems significantly faster, and cuts down on time spent debugging (since the device module is already debugged). Reason #2 is that if you program them with a common interface it makes replacing the device with a new one much easier down the road when the old device dies or when the device turns out to be back ordered until the end of time and you have to make a last minute substitution.

    For the first couple of years I did the whole combine a virtual device with every touch panel (since that's what they taught me to do in programmer 1&2), but I've since stopped that. I can't really see any reason to do it with modern touch panels. I now only combine virtual devices with touch panels (or anything else) when I've either got multiple panels controlling a single device or when I've got multiple rooms sharing a single device (like a video codec).

    I'm also guilty of having a large number of include files in my systems (at least for the last two years or so). My include files fall into two groups.

    Group one are the system-specific include files. I put all my system programming into include files because it makes it much easier to quickly flip between different locations in the code. I find multi-thousand line files to be really unweildly to work on and especially to debug. It's so much easier to double-click on a file in the workspace than to scroll up 2000 lines.

    Group two are a collection of include files that contain the API for my modules. I have all my send_commands for modules wrapped in functions so that they are available to the auto-complete feature of studio. This makes programming faster and more importantly, cuts down on debugging issues due to typos. Also, I have a bunch of constants defined for all the channel & level numbers necessary to interface with the module for the same reason, and because using the constants makes the code more readable. Additionally, these files help offset one of the possible drawbacks of modules, that they're undocumented black-boxes for a programmer who comes in after me. That's not much of a benefit for me personally, but it's good karma :)

    Of course all these features of the language (and really any feature of any language :p) can be abused in ways that make code confusing as hell too, negating their benefits.

    Apologies for the wall of text, this post got a little out of hand. (probably doesn't help that I'm a bit tired)

    -Ryan
  • Thanks for all the good replies - it's been very enlightening to see how some of you do things.

    I've been trying to tell myself to use more include files so I can avoid copy/paste operations, but I haven't done it, yet. I'm not sure I'll ever use modules heavily, but that's probably just a habit rather than a serious decision.
  • DHawthorneDHawthorne Posts: 4,584
    I don't use combines any more for any reason, but I use virtual devices all the time, in every device module I write. They make my modules interchangeable with very little work. If all my receiver modules use the form, SEND_COMMAND dvReceiver, "'SOURCE=BD'", I can change, upgrade, and update my receiver just by swapping in a new module ... but that command requires a virtual to interpret it and send it to the actual device. If it's a very simple device, and all I have to do is send a few functions, I won't bother, but most of the time, my home-grown API makes my life a lot easier. It's more work to make the module, for for most things I have a boilerplate and all I have to do is update the command strings and parsing.
  • trobertstroberts Posts: 228
    Great Topic!
    Is there any difference in horsepower from the processor whether you are sending feedback to a virtual TP as opposed to a physical TP?

    I am in the middle of taking over a large job with CONSTANT upgrades and changes. For HVAC in the current code (not written by me) there are 5 include files and 1 module. I normally start my programs with a template axs file, where I have structures to track all my TPs, selected zones, etc then I use include files for all my subsystems (HVAC, Lighting, etc) my include files are very modular, but I have never used virtual devices. I have also never needed to have real code in more than one master. On this job they seem to have installed masters for every subsystem, which means lots on M2M communication. I am starting to see the value in using virtual devices, but I am unsure of where to go from here.

    My include files rely on seeing variables in my structures that reside in the main axs, which in this jobs case would reside on the system 1, while the HVAC port and preferable my axi and processing for the HVAC would reside on system 2...here is an example of my own programming
    sHVAC_INFO.nCURR_TEMP[sTP_INFO[nPNL_IDX].nHVAC_ZONE
    here is the problem on this particular job
    sHVAC_INFO would need to reside on system 2
    sTP_INFO would need to reside on system 1
    I dont think there is a way to do this on two separate systems.
    I guess my questions are, would a virtual devices help me in keeping my method of programming with an axi. Do I need to change my way of thinking and start changing my axi into a module...somehow...???
    Also does anyone know of a tech note or any other thread or write up on virtual devices?
    Any input or thoughts would be appreciated.
  • champchamp Posts: 261
    Another use of a virtual deviceis to share variables across systems by using the levels and channels.

    I also like using modules to make it easier when multiple people are working on the same project. When you try to combine two programs that are written all in mainline you get conflicting variables and have to cut /paste/ modify all over the place, on the other hand just adding a module is neat. If nothing else modules remove the need to use unique timeline IDs.
    Modules don't have to be for controlling devices, they can just be chunks of code that do stuff with data.
Sign In or Register to comment.