Home AMX User Forum NetLinx Studio

Virtual Touchpanel

This may seem like a silly question and I am probably missing the big picture, but here goes. I am not understanding the best way to utilize a virtual TP.

If I declare my real TP's like:

DEFINE_DEVICE

dvTP = 10001:1:0
dvDVD_TP = 10001:2:0

then:
vdvDVD_TP = 33001:1:0

...

BUTTON_EVENT[dvDVD_TP,1]
{
PUSH:
{
PULSE[vdvDVD_TP,1]
}
}
CHANNEL_EVENT[vdvDVD_TP,1]
{
ON:
{
Do something
}
}


I know in a real world situation, the events would not be side by side like that. Usually in my main code I would have all of the main TP events. Includes would be used for other device controls, so all of the dvDVD_TP events would all be inside a DVD controls include. What then, is the proper way to utilize a virtual touchpanel?

Comments

  • jjamesjjames Posts: 2,908
    Seems like you'd be better off considering it as a module rather than a virtual panel, where you'd pulse the device you're controlling. Example:

    button_event[dvTp1,i_transportBtns]
    {
    push:{to[dv_dvd [i_dvdControlled], button.input.channel]}
    }

    channel_event[dv_dvd,i_transportBtns]
    {
    on:{ /* do something here*/ }
    }

    In the channel event, you'd do a get_last (since I'm considering dv_dvd as an array), and a switch-case on the channel.

    I don't get the concept of virtual panels either, but modules and pulsing channels makes sense.
  • jjames wrote: »
    Seems like you'd be better off considering it as a module rather than a virtual panel, where you'd pulse the device you're controlling. Example:

    button_event[dvTp1,i_transportBtns]
    {
    push:{to[dv_dvd [i_dvdControlled], button.input.channel]}
    }

    channel_event[dv_dvd,i_transportBtns]
    {
    on:{ /* do something here*/ }
    }

    In the channel event, you'd do a get_last (since I'm considering dv_dvd as an array), and a switch-case on the channel.

    I don't get the concept of virtual panels either, but modules and pulsing channels makes sense.

    Thank you sir. That's the way I have always understood it too. Most of my jobs have always been 1 TP to 1 Master. If that master were controlling several devices, I would create a diferent TP for each, like:

    dvTP = 10001:1:0
    dvDVD_TP = 10001:2:0
    dvCAM_TP =10001:3:0
    and so on

    I guess I had somehow got it in my head that using virtual TP's would somehow make all of that easier to track. The only example I can think of where virtual TP's would probably work, would be a situation with one master and multiple TP's in the same room or if one button push needed to control several things at once thereby having to utilize comm modules for multiple devices. But even then, if I were in a situation like that, I don't think virtual TP's would be the way I would go about it.
  • a_riot42a_riot42 Posts: 1,624
    I guess I had somehow got it in my head that using virtual TP's would somehow make all of that easier to track.

    You aren't using virtual touch panels. You are using different ports on a real touch panel. A virtual touch panel would be addressed like so:

    vdvTP = 33100:1:1

    But I don't find much reason to use such a thing when the real device suffices.
    Paul
  • Give me a little credit, lol. I know the difference between a real TP and a virtual one. I always declare new ports on the same real TP. I was thinking that a virtual TP could tie all of those ports together and make things neater. But as it turned out, they only made things more complicated.
  • jjamesjjames Posts: 2,908
    Using different ports to control different items explicitly is not unheard of and could be grounds for debate in code efficiency or style. I personally prefer to control multiple devices by using a simple variable. In a more or less object-orientated approach, I prefer to create structures for each device and of course each device as attributes. (Be prepared for a ramble!)

    Essentially - I define my cable box structures, and then have a simple variable called i_cableControl that is two-dimensional with the maximum length of the number of zones I have in the system. Each panel can realistically control one zone at a time. The argument that some zones can follow each other, so therefor you're controlling more than one will be left out for sake of simplicity. So, I set my i_cableControl[i_zone] to point to which cable box I want to control. This ultimately points back to the cable box structure's device attribute (i.e. Cable[1].device) and is used in a button_event like so:
    button_event[dv_tp,i_tpBtns_transport]
    {
      push:
      {
        // do stuff here that gets which zone we're via the touch panel structure, and determine what source we're controlling, etc. etc.
        switch(i_source)
        {
          case i_src_cab: { to[[color=red]Cable[[/color][color=green]i_cableControl[[/color][color=blue]Panel[i_panel].i_zone[/color][color=green]][/color][color=red]].device[/color], button.input.channel]};
        }
      }
    }
    

    This all points back to a specific device which was defined for the cable box's structure. By using variables for WHICH zone is being controlled by WHICH panel is being used that is ultimately pointing back to WHICH cable box is being utilized by it's pre-determined assignment or selected from the panel by the user. . . this can be expanded infinitely. You can use this structure of programming for an unlimited number of panels, zones and devices. I'm starting to do this now with all of my devices and it makes things super easy for the fact that it's between all devices.

    My point is, you don't need to use multiple ports for different types of devices. I don't see how it makes it any easier - in fact, I think it'd make things a bit more difficult (IMHO) - UNLESS your templates are set up so well that you don't ever need to make touch panel changes. By default, port one is used for a new button - I could see adding buttons and forgetting to set it to a specific port, but that's just me.

    To me, virtuals are used as translators or middle-men. You send them a command, or pulse a channel to create an action determined by the virtual's translation-dictionary.

    This is more than two-cents worth, but take it for what it's worth.
  • PhreaKPhreaK Posts: 966
    As the others have already suggested, if you're aiming to seperate areas of functionality in your UI using different ports of the physical TP works nicely.

    As to where virtual TP's are useful, the main scenario I've seen / implimented is if you have a TP that may not always be present (shared amoungst multiple facilities, or something like TPControl running on an iDevice) you can have your system update the virtual with channel and level info, then when the real device is present it is combined and will pick up system state without you having to re-send everything.
  • jjames wrote: »
    Using different ports to control different items explicitly is not unheard of and could be grounds for debate in code efficiency or style. I personally prefer to control multiple devices by using a simple variable. In a more or less object-orientated approach, I prefer to create structures for each device and of course each device as attributes. (Be prepared for a ramble!)

    Essentially - I define my cable box structures, and then have a simple variable called i_cableControl that is two-dimensional with the maximum length of the number of zones I have in the system. Each panel can realistically control one zone at a time. The argument that some zones can follow each other, so therefor you're controlling more than one will be left out for sake of simplicity. So, I set my i_cableControl[i_zone] to point to which cable box I want to control. This ultimately points back to the cable box structure's device attribute (i.e. Cable[1].device) and is used in a button_event like so:
    button_event[dv_tp,i_tpBtns_transport]
    {
      push:
      {
        // do stuff here that gets which zone we're via the touch panel structure, and determine what source we're controlling, etc. etc.
        switch(i_source)
        {
          case i_src_cab: { to[[color=red]Cable[[/color][color=green]i_cableControl[[/color][color=blue]Panel[i_panel].i_zone[/color][color=green]][/color][color=red]].device[/color], button.input.channel]};
        }
      }
    }
    

    This all points back to a specific device which was defined for the cable box's structure. By using variables for WHICH zone is being controlled by WHICH panel is being used that is ultimately pointing back to WHICH cable box is being utilized by it's pre-determined assignment or selected from the panel by the user. . . this can be expanded infinitely. You can use this structure of programming for an unlimited number of panels, zones and devices. I'm starting to do this now with all of my devices and it makes things super easy for the fact that it's between all devices.

    My point is, you don't need to use multiple ports for different types of devices. I don't see how it makes it any easier - in fact, I think it'd make things a bit more difficult (IMHO) - UNLESS your templates are set up so well that you don't ever need to make touch panel changes. By default, port one is used for a new button - I could see adding buttons and forgetting to set it to a specific port, but that's just me.

    To me, virtuals are used as translators or middle-men. You send them a command, or pulse a channel to create an action determined by the virtual's translation-dictionary.

    This is more than two-cents worth, but take it for what it's worth.

    That's a good idea. I am going to try something like that tomorrow. I had been declaring multiple TP's. Like a Vol_TP, DVD_TP, Tandberg_TP, etc. When everything is said and done, I usually end up with 7 or 8 declared TP's. I do it that way so I can add or subtract channels from a particular TP. I'll try it your way tomorrow to see what I can come up with. I'm always wanting to learn something new.
  • mushmush Posts: 287
    PhreaK wrote: »
    As to where virtual TP's are useful, the main scenario I've seen / implimented is if you have a TP that may not always be present (shared amoungst multiple facilities, or something like TPControl running on an iDevice) you can have your system update the virtual with channel and level info, then when the real device is present it is combined and will pick up system state without you having to re-send everything.

    .. and also when you have multiple panels displaying the same information. Combine them all with a virtual device and then you only have to send to that virtual for all devices to receive the same thing.

    eg,
    DEFINE_DEVICE
    vdvAlarm = $8000:1:0	// Virtual device for Security System
    
    DEFINE_COMBINE
    (vdvAlarm, 10001:39:1, 10001:39:2, 10001:39:3, 10001:39:4, 10001:39:5, 10001:39:6, 10001:39:7, 10001:39:8, 10001:39:9, 10001:39:10 )		// Combine the Real TP Port with the Virtual device
    
    DEFINE_MODULE 'Alarm'	mdlAlarm	(dvSERIAL1, vdvAlarm)
    

    Now all panels have access to the same module and receive feedback etc with only a few lines of code.
  • a_riot42a_riot42 Posts: 1,624
    mush wrote: »
    .. and also when you have multiple panels displaying the same information. Combine them all with a virtual device and then you only have to send to that virtual for all devices to receive the same thing.

    eg,
    DEFINE_DEVICE
    vdvAlarm = $8000:1:0	// Virtual device for Security System
    
    DEFINE_COMBINE
    (vdvAlarm, 10001:39:1, 10001:39:2, 10001:39:3, 10001:39:4, 10001:39:5, 10001:39:6, 10001:39:7, 10001:39:8, 10001:39:9, 10001:39:10 )		// Combine the Real TP Port with the Virtual device
    
    DEFINE_MODULE 'Alarm'	mdlAlarm	(dvSERIAL1, vdvAlarm)
    

    Now all panels have access to the same module and receive feedback etc with only a few lines of code.

    Is there an advantage to using a virtual rather than an array?

    DEFINE_VARIABLE
    dev dvAlarmTPs[] = {10001:39:1, 10001:39:2, 10001:39:3, 10001:39:4, 10001:39:5, 10001:39:6, 10001:39:7, 10001:39:8, 10001:39:9, 10001:39:10 }
    
    DEFINE_MODULE 'Alarm'	mdlAlarm	(dvSERIAL1, dvAlarmTPs)
    

    Paul
  • mushmush Posts: 287
    a_riot42 wrote: »
    Is there an advantage to using a virtual rather than an array?

    DEFINE_VARIABLE
    dev dvAlarmTPs[] = {10001:39:1, 10001:39:2, 10001:39:3, 10001:39:4, 10001:39:5, 10001:39:6, 10001:39:7, 10001:39:8, 10001:39:9, 10001:39:10 }
    
    DEFINE_MODULE 'Alarm'	mdlAlarm	(dvSERIAL1, dvAlarmTPs)
    

    Paul

    Only in that a virtual NEVER goes offline (except for when it does ;P) so when any panels drop off and then come back they are brought up to date with the virtual. There may be other reasons.
  • Spire_JeffSpire_Jeff Posts: 1,917
    mush wrote: »
    Only in that a virtual NEVER goes offline (except for when it does ;P) so when any panels drop off and then come back they are brought up to date with the virtual. There may be other reasons.

    Just for clarification, this only syncs channel and level states, correct? Variable text would still need to be sent as well as any ^BMF commands.

    Jeff
  • jjamesjjames Posts: 2,908
    The Debate

    I think the debate of using DEFINE_COMBINE with virtuals has been had many times. I believe many of us would agree that using an array of panels is much more manageable in the long run albeit at times a pain to perfect, especially with the feedback. However, with Netlinx being an event-driven system, this shouldn't be too difficult to deal with.
  • PhreaKPhreaK Posts: 966
    Spire_Jeff wrote: »
    Just for clarification, this only syncs channel and level states, correct? Variable text would still need to be sent as well as any ^BMF commands.
    Correct. You can keep the current state of all your variable text guff in an array (idx = button address) then iterate and shoot that through when a panel comes online.
  • mushmush Posts: 287
    jjames wrote: »
    I think the debate of using DEFINE_COMBINE with virtuals has been had many times. I believe many of us would agree that using an array of panels is much more manageable in the long run albeit at times a pain to perfect, especially with the feedback. However, with Netlinx being an event-driven system, this shouldn't be too difficult to deal with.

    G'day Grumpy!

    I have never used anything but define combine and, to my knowledge, have never had an issue with its use.
    Can you (or anyone else) please explain the argument (or point to a thread that discusses it) for using an array and why it is more manageable?

    Cheers

    Mush
  • jjames,

    Can you provide a little more explanation concerning your use of zones? I think I am missing something somewhere. Typically, all of my jobs involve one master, one room, and one TP. For each device, I would normally use a different port on the TP, like:

    dv_DVD_TP = 10001:2:0
    dv_CODEC_TP = 10001:3:0
    dv_VOL_TP = 10001:4:0

    Eventually, I usually end up declaring 7 or 8 TP's. For me, this makes channel assignments much easier. I can always start at channel 1 for each port. The obvious problem, this is not easily expandable. For example, if the customer decided to add another codec or more DVD players or tuners after the fact, this would require code changes. Structures and arrays would certainly make things more portable. When you create TP's, do you create everything on one port? What about large jobs that use 300 - 400 buttons?

    Another drawback that I have come across involves the use of IR devices. For a long time, we always spec'd the same model DVD player. I would upload the IR files to the master, number the buttons to match the proper IR function and do something like:
    BUTTON_EVENT[dv_DVD_TP,0]
    {
          PUSH:
          {
                SEND_COMMAND dvDVD,"'SP',BUTTON.INPUT.CHANNEL"
          }
    }
    

    This works well and good until the DVD player make and model is changed. Then I have to go back through the TP file and change the button numbers. Again, I am thinking your zone example would make things more portable. I have started implementing event tables, and I think tables are along the lines of your zoning.

    Maybe these are basic questions and I am overlooking something simple or not seeing the big picture. This is the byproduct of having cookie cutter jobs over and over...
Sign In or Register to comment.