Home AMX User Forum NetLinx Studio

Conditional inclusion of modules?

Is it possible to conditionally use a module based on a variable, such as SYSTEM_NUMBER? I have two sets of conference rooms that are pretty much identical other than some having an LCD display, and some having a projector. I want to use the exact same code for both styles, and can easily handle everything else based on system number other than defining the modules for the displays. I know I can load the module through the web UI, but I also want RMS monitoring, and I don't believe I can do the same with the RMS module.

Comments

  • viningvining Posts: 4,368
    The best you could do is use #if_defined or #if_not_defined compiler directives. Variables have no value during the compiling.
  • ericmedleyericmedley Posts: 4,177
    I do this by having a set of constants like
    DEFINE_CONSTANT
    
    //Uses_Sanyo_Model_such_and_so=1
    Uses_Epson_Model_such_and_so=1
    //Uses_Jvc_Model_such_and_so=1
    etc...
    
    Then just un comment out the gear that is present.

    Then have an

    #IF_DEFINED Uses_Sanyo_Model_such_and_so
    // Code for module and so forth
    #END_IF
  • mstocummstocum Posts: 120
    ericmedley wrote: »
    I do this by having a set of constants like
    DEFINE_CONSTANT
    
    //Uses_Sanyo_Model_such_and_so=1
    Uses_Epson_Model_such_and_so=1
    //Uses_Jvc_Model_such_and_so=1
    etc...
    
    Then just un comment out the gear that is present.

    Then have an

    #IF_DEFINED Uses_Sanyo_Model_such_and_so
    // Code for module and so forth
    #END_IF

    I was really hoping to just have a single AXS that covers both situations without any changes (so I don't have several copies of the same file to make changes in). I think I'll just end up with an AXS for each room type, and move the main code to an include file. Not ideal, but it works. I was just curious if there was a better way.
  • ericmedleyericmedley Posts: 4,177
    You are making a great case for JAVA.
    :)
  • mstocummstocum Posts: 120
    ericmedley wrote: »
    You are making a great case for JAVA.
    :)

    Can you load new modules from within Duet? Is there some OSGI incantation you need to go through, or is it as simple as instantiating the right class? (insert comment about how swell it would be if AMX had better Duet documentation).
  • champchamp Posts: 261
    Dynamic Device Discovery was all about this but it never took off.
    I tried it when it first came out nearly 10 years ago but at the time there were only 3 products programmed and the one I tried didn't work so I shelved it.

    Maybe I should have another crack at it, I doubt it will work any more as AMX has removed all the NetLinx modules from the web site and somewhere along the line they had a brain fail and switched the standard parameter order from (dvDevice, vdvDevice) to (vdvDevice, dvDevice). Ironically the NetLinx modules worked more often than Duet ones and didn't tend to stop an entire processor when they didn't, the really old ones even had source code! I guess AMX just like to make sure programmers never have it easy.

    An idea I have been tossing up but haven't implemented or tested yet where I define multiple modules then combine devices to point virtual devices at the right module. I'm not sure if it will work, especially with duet modules but may be worth a try.
  • mstocummstocum Posts: 120
    champ wrote: »
    Dynamic Device Discovery was all about this but it never took off.

    I don't believe the RMS monitoring modules can be loaded this way, and since TVs and projectors have different modules, I'm back where I started. That of course brings up the question of why do we even have to load RMS modules for Duet modules, but that's probably a question for a different subforum...
  • AMXJeffAMXJeff Posts: 450
    champ wrote: »
    Dynamic Device Discovery was all about this but it never took off.

    Almost every system I program, I use Dynamic Device Discovery. Although I don't use AMX binding solution. I have created my own Web Servlet that allows me to link duet modules to virtual devices with out the need for all that binding crap. Just pick a module and a duet device and load it.

    Loading duet modules is actually quite easy in NetLinx. There is a load and a unload function that you can call, all you need to do is fill I'm the array of properties, and load.

    So the customer has been able to easily swap out displays when they get old. Upload module to master, use my Servlet to pick the module, and press load. Done.

    My Servlet reads the properties from the duet modules manifest and calls the duet load method, which is also available from duet.

    Works real sweet.

    Anyway, duet rocks! Only drag is support is non-existent.

    With RMS, you can actually use OSGI to send message to the client module, but you would need to create your own monitor modules for that, which is a lot of front work.
  • JeffJeff Posts: 374
    Obviously I'm late to the party here, but just for the record what you want is possible using combine devices.
    define_start
    switch(nProjSelected)
    {
    	case 1:combine_devices(vdvProj,vdvInFocus)
    	case 2:combine_devices(vdvProj,vdvSanyo)
    }
    
    define_module 'InFocus LP820 Comm' projmdl2(vdvInFocus,dvProj)
    define_module 'Sanyo XU48 Comm' projmdl1(vdvSanyo,dvProj)
    

    This is from a project when I was a VERY inexperienced codemonkey, but it worked so you can probably start from here and make it better. Essentially I had a variable that tracked which projector was in the room and on startup (or the button press that changed the variable) I would combine a virtual with the virtual that went with that module.

    At the time, my modules didn't do anything on their own, they only parsed stuff from the mainline and sent it out. If you were going to use modules that did their own polling (which I assume you would), I imagine something like this would work (but I haven't tested it)
    define_device
    dvProj				=	05001:1:0		//Actual Projector
    
    vdvProj				=	33001:1:0		//Virtual device that your mainline sends commands to
    vdvInFocusVirtual	=	33002:1:0		//Virtual Device for the InFocus Projector
    vdvInFocus			=	33003:1:0		//Actual Device for InFocus Projector
    vdvSanyoVirtual		=	33004:1:0		//Virtual Device for the Sanyo Projector
    vdvSanyo			=	33005:1:0		//Actual Device for Sanyo Projector
    
    
    define_start
    switch(nProjSelected)
    {
    	case 1:
    	{
    		combine_devices(vdvProj,vdvInFocusVirtual)
    		combine_devices(dvProj,vdvInFocus)
    	}
    	case 2:
    	{
    		combine_devices(vdvProj,vdvSanyoVirtual)
    		combine_devices(dvProj,vdvSanyo)
    	}
    }
    
    define_module 'InFocus LP820 Comm' projmdl2(vdvInFocusVirtual,vdvInFocus)
    define_module 'Sanyo XU48 Comm' projmdl1(vdvSanyoVirtual,vdvSanyo)
    

    In theory, this should result in whichever module you want to use sending it's commands to a virtual device which is combined with the actual device, and the module you DON"T want to use sending it's commands to a virtual device that goes nowhere.

    I think you could change that switch statement to switch on system_number as well if you wanted to do that.

    Disclaimer: Haven't tested the second bit of code, but I bet it'd work, and if it doesn't it's a good place to start.
  • GregGGregG Posts: 251
    You could also go with dead simple, and include a generic display control file with something like this in it:
    // Also does power ( 0 = off, anything else = on and input selected )
    Define_Function MonitorFunction(Integer nMonitor, Integer nInput)
    {
      Send_String 0,"'MonitorFunction( Monitor: ',Itoa(nMonitor),', Function: ',Itoa(nInput),' )'"
      Switch(uDisplays[nMonitor].ControlType)
      {
        Case MON_TYPE_NEC:			NECMetaFunction(nMonitor,nInput)
        Case MON_TYPE_PLANAR:		PlanarMetaFunction(nMonitor,nInput)
        Case MON_TYPE_PANASONIC:		PanasonicMetaFunction(nMonitor,nInput)
        Case MON_TYPE_VIEWSONIC:		ViewsonicMetaFunction(nMonitor,nInput)
        Case MON_TYPE_SHARP_SPACES_AFTER:
        Case MON_TYPE_SHARP_SPACES_BEFORE:  SharpMetaFunction(nMonitor,nInput,uDisplays[nMonitor].ControlType)
        Case MON_TYPE_SONY:			SonyMetaFunction(nMonitor,nInput)
      }
    }
    
    Then you could change the display type by altering the value of uDisplays[nMonitor].ControlType for any given nMonitor. (And/or load the data in from a file on boot)
  • mstocummstocum Posts: 120
    I ended up solving the problem by just moving all of the code to an include file, then having two different master AXS files set a couple defines and include the main code. Not elegant, but it did the job.
Sign In or Register to comment.