Home AMX User Forum AMXForums Archive Threads Tips and Tricks

Change a TP4 button channel dynamically

Dear All,
is there any way and the possibility for a TP4 button channel to be dynamically reassigned through the code ? For example the port 1 channel 100 to be changed to port1 channel 200.

Thanks,
George

Comments

  • Joe HebertJoe Hebert Posts: 2,159
    Dear All,
    is there any way and the possibility for a TP4 button channel to be dynamically reassigned through the code ? For example the port 1 channel 100 to be changed to port1 channel 200.

    Nope. You can use REBUILD_EVENT to generate a new event table but you can't change the actual channel code of a button to the fly. What are you trying to accomplish?
  • I'm trying to make MIO-R4 hard buttons to send different channels when it is on different popup pages. For various reasons, I don't want to make it with "IF" statements
  • ericmedleyericmedley Posts: 4,177
    why do you need to change the button in the UI? Cannot this be done in code with a conditional? I essentially do this same function all the time where a given button does a multitude of things depending upon conditions.
  • MLaletasMLaletas Posts: 226
    I don't want to make it with "IF" statements

    May I ask why? Without the two letter word, well i dont know what I would do with my life.
  • [USER="48"]George Krietsepis[/USER] if it's [Pages] & not [Popup Pages] then you can:
    ? {{<Ctrl>B -or- <RtClick>Show External Controls}}
    ? Select all the buttons you want to customize (on a per-page scheme)
    ? Select the [General] Properties Tab
    ? Change [Override Global Settings] to [yes]
    ? Now each hard button can be selected per normal TP button & on the [Programming] Properties Tab you can change the [P:C] values

    I think this is definitely the more labor intensive way (not only with development, but especially with regards to maintenance/support...) and I agree with [USER="1623"]ericmedley[/USER] and I track a flag & use a conditional expression.
  • thank you all, but let me clear why I need to do with that way... I have some MSD-701 touch panels which implement very complicated actions. The code is also very complicated and now I need to add some MIO-R4's. The hard buttons should do different things on different pop up pages ( "GigaNexus" yes, I know the "override global settings" but this is for the main pages, not for the pop up ones ).
    I cannot explain in details, but if statements needed I should use hundreds of "if"...."if"...."if"...."if"...."if"...."if"...."if".... ones.
  • ericmedleyericmedley Posts: 4,177
    thank you all, but let me clear why I need to do with that way... I have some MSD-701 touch panels which implement very complicated actions. The code is also very complicated and now I need to add some MIO-R4's. The hard buttons should do different things on different pop up pages ( "GigaNexus" yes, I know the "override global settings" but this is for the main pages, not for the pop up ones ).
    I cannot explain in details, but if statements needed I should use hundreds of "if"...."if"...."if"...."if"...."if"...."if".. .."i f".... ones.

    I'm sorry but this still doesn't change the argument. And the fact that, in any case, you cannot do it, still points you in the same directino: doing it in code. The whole If If If If thing too is not necessary.

    Here's a smiple approach. make a variable that tracks the mode of the button. How many modes? Who cares - lets say the one button can do 100 different things. In code as you go along you're tracking what mode the system is in. Cable/Satellite/HVAC/Pop Up Toaster/Coffe Maker/World Wide ThermoNuclear War Engage/etc...

    You can even create constants that chagne the numbers into text.

    integer Mode_Cable=1;
    integer Mode_Satellite-2;
    integer Mode_ThermoNuclear_war=55;
    etc..

    Then in code you just track it
    define_function fn_set_North_Korea_status(integer nCrazy_Level)}
    if(nCrazy_Level>5){
    MyMode=Mode_ThermoNuclear_war;
    }// if
    }// define_function
    


    so what you end up with is a button event (or a button event that goes off to a function )
    Button_Event[MyR4s,The_Button]{
    push:{
    switch(MyMode){
    case Mode_Cable:{
    // do the cable thing
    }// case
    case Mode_Satellite:{
    .// do the satellite thing
    }// case
    case Mode_ThermoNuclear_war:{
    // do the thermonuclear war thing
    }
    }// switch
    }// push
    }// button_event
    
    

    I do this for a lot of both hard and soft buttons. I even deliberately change the button labels on the fly. And if there's hard buttons I even turn on/off little pointers in the UI layout to let the user know the hard button now does something else. this approach is entirely scaleable and allows for almost an endless variety of things a single button can do (or not do for that case) I use the same idea to disable a button if I don't want the user hitting it. I hope this helps.
  • a_riot42a_riot42 Posts: 1,624
    Dear All,
    is there any way and the possibility for a TP4 button channel to be dynamically reassigned through the code ? For example the port 1 channel 100 to be changed to port1 channel 200.

    Thanks,
    George

    No and thank goodness there isn't. It would be a mess. Each page on an R4 has a different set of buttons so you can just changes pages to use different channel numbers if need be. Alternatively you can keep the numbers as is, and depending on what's needed, run different code when its triggered. Changing channels dynamically will not make your life easier.
    Paul
  • viningvining Posts: 4,368
    If you want to keep button event for each device I would create a virtual UI device for each device instead of the tradional different UI port number. In the real button event I would just do a do_push_timed with the max time ever needed for any possible hold events and then a do_release in the release handler. In the real push just send the do_push_timed and release to a corresponding index of the virtual array for the active device. Then in the virtual button event your push, hold and release will work just as if it was being directly controlled by the UI. This allows you to keep a normal button event for each device instead of using arrays to map button pushes to actions for each device.
  • viningvining Posts: 4,368
    Here's a template I created to use UIs to control virtual UIs as opposed to using button array mapping for the different devices. This should work and allow each device to have it's own button events while the UI uses the same port to control all device. Just another way to skin a cat. I just wrote this so it isn't tested but I used to do similar to control instances of modules and never had a problem.
    PROGRAM_NAME='Do_Push_Template'
    (***********************************************************)
    (*  FILE CREATED ON: 01/28/2018  AT: 17:23:44              *)
    (***********************************************************)
    (*  FILE_LAST_MODIFIED_ON: 01/28/2018  AT: 18:29:04        *)
    (***********************************************************)
    
    DEFINE_CONSTANT //template constants
    
    DO_PUSH_TIMED_5S_MAX     = 50;
    DO_PUSH_TIMED_10S_MAX     = 100;
    DO_PUSH_TIMED_15S_MAX     = 150 ;
    DO_PUSH_TIMED_20S_MAX     = 200 ;
    DO_PUSH_TIMED_30S_MAX     = 300;
    DO_PUSH_TIMED_1M_MAX     = 600;
    DO_PUSH_TIMED_5M_MAX     = 3000;
    
    CHAR NUM_UIs_IN_SYSTEM    = 7;
    
    DEFINE_VARIABLE //real UI's
    
    VOLATILE DEV dvUI_Arry[NUM_UIs_IN_SYSTEM]   = //real UIs
    
                {
                 dvUI_1
                ,dvUI_2
                ,dvUI_3
                ,dvUI_4
                ,dvUI_5
                ,dvUI_6
                ,dvUI_7
                }
    
    DEFINE_VARIABLE //virtual device UI's
    
    VOLATILE DEV vUI_DevArry[NUM_DEVs_IN_SYSTEM] = //device virtual UIs
    
                {
                 vDev1_UI
                ,vDev2_UI
                ,vDev3_UI
                ,vDev4_UI
                }
    
    DEFINE_VARIABLE //geeneral var's
    
    PERSISTENT INTEGER nUI_Active_Dev[NUM_UIs_IN_SYSTEM];
    VOLATILE INTEGER nUI_PushedBtn[NUM_UIs_IN_SYSTEM];
    
    DEFINE_EVENT    //BUTTON_EVENT[dvUI_Arry,0]//the real UIs to interface with the devices virtual UI
    
    BUTTON_EVENT[dvUI_Arry,0]
    
         {
         PUSH :
          {
          STACK_VAR INTEGER nBtn;
          STACK_VAR INTEGER nUI_Indx;
    
          nBtn = BUTTON.INPUT.CHANNEL;
          nUI_Indx = GET_LAST(dvUI_Arry);
    
          if(nBtn <= NUM_DEVs_IN_SYSTEM)//let's say button 1-10 are for dev control selection
               {                
               nUI_Active_Dev[nUI_Indx] = nBtn;
               }
          if(nUI_Active_Dev[nUI_Indx])
               {
               nUI_PushedBtn[nUI_Indx] = nBtn;                       
               DO_PUSH_TIMED(vUI_DevArry[nUI_Active_Dev[nUI_Indx]],nBtn,DO_PUSH_TIMED_15S_MAX);
               }                    //longest possible hold ever needed for any device
          else
               {
               //send 0 error UI has no selected devices.......
               }
          }
         //
         //HOLD: occurs in the virtual button event not here, you're not running code here
         //
         RELEASE:
          {
          STACK_VAR INTEGER nBtn;
          STACK_VAR INTEGER nUI_Indx;
    
          nBtn = BUTTON.INPUT.CHANNEL;
          nUI_Indx = GET_LAST(dvUI_Arry);
    
          if(nUI_PushedBtn[nUI_Indx] == nBtn)//don't send a release if we didn't send a push first, not likely
               {
               DO_RELEASE(vUI_DevArry[nUI_Active_Dev[nUI_Indx]],nBtn);
               nUI_PushedBtn[nUI_Indx] = 0;
               }
          }
         }     
    
    DEFINE_EVENT    //BUTTON_EVENT[vDev1_UI,0]//device 1 virtual UI
    
    BUTTON_EVENT[vDev1_UI,0]
    
         {
         PUSH :
          {
          STACK_VAR INTEGER nBtn;
    
          nBtn = BUTTON.INPUT.CHANNEL;
          if(nBtn <= NUM_DEVs_IN_SYSTEM)//only the index button of this virtual will trigger this
               {
               //device selected start up code and send FB to populate UI values, etc
               }
          else
               {
               //do stuff
               }
          }
         HOLD[2,REPEAT]:
          {
          //holds will work up to 10 seconds max since the do_push is timed with a max time of 15 seconds
          }
         RELEASE:
          {
          //releases work just normally
          }
         }
    
    DEFINE_EVENT    //BUTTON_EVENT[vDev2_UI,0]//device 2 virtual UI
    
    BUTTON_EVENT[vDev2_UI,0]
    
         {
         PUSH :
          {
          STACK_VAR INTEGER nBtn;
    
          nBtn = BUTTON.INPUT.CHANNEL;
          if(nBtn <= NUM_DEVs_IN_SYSTEM)//only the index button of this virtual will trigger this
               {
               //device selected start up code and send FB to populate UI values, etc
               }
          else
               {
               //do stuff
               }
          }
         HOLD[2,REPEAT]:
          {
          //holds will work up to 10 seconds max since the do_push is timed with a max time of 15 seconds
          }
         RELEASE:
          {
          //releases work just normally
          }
         }
    
    DEFINE_EVENT    //BUTTON_EVENT[vDev3_UI,0]//device 3 virtual UI
    
    BUTTON_EVENT[vDev3_UI,0]
    
         {
         PUSH :
          {
          STACK_VAR INTEGER nBtn;
    
          nBtn = BUTTON.INPUT.CHANNEL;
          if(nBtn <= NUM_DEVs_IN_SYSTEM)//only the index button of this virtual will trigger this
               {
               //device selected start up code and send FB to populate UI values, etc
               }
          else
               {
               //do stuff
               }
          }
         HOLD[2,REPEAT]:
          {
          //holds will work up to 10 seconds max since the do_push is timed with a max time of 15 seconds
          }
         RELEASE:
          {
          //releases work just normally
          }
         }
    
    DEFINE_EVENT    //BUTTON_EVENT[vDev4_UI,0]//device 4 virtual UI
    
    BUTTON_EVENT[vDev4_UI,0]     
         {
         PUSH :
          {
          STACK_VAR INTEGER nBtn;
    
          nBtn = BUTTON.INPUT.CHANNEL;
          if(nBtn <= NUM_DEVs_IN_SYSTEM)//only the index button of this virtual will trigger this
               {
               //device selected start up code and send FB to populate UI values, etc
               }
          else
               {
               //do stuff
               }
          }
         HOLD[2,REPEAT]:
          {
          //holds will work up to 10 seconds max since the do_push is timed with a max time of 15 seconds
          }
         RELEASE:
          {
          //releases work just normally
          }
         }
    
  • John NagyJohn Nagy Posts: 1,734
    Sounds like what the OP needs is an architecture.
    Imagine if the core processes had a notion of what was going on, instead of slavishly passing buttons into actions.
    Like, if the system knew what source was selected in a particular room, giving context to any UI that was in charge of that room at the moment. So the UI would only every have to say "PLAY" and the system would apply that action to whatever the context demanded, instead of sorting through what page the ui was on and manhandling the hard button input to keep up.
    I bet that such an architecture would also be able to easily share what rooms were in use, with what sources, should that matter to a user. Maybe even avoid conflicts automatically. Among other things.
    Throw in a database of devices to define what "Play" means to each, and how to reach them (IR? SERIAL? IP? RELAY?) to say that... and gee, you could "reprogram" the system dynamically by just changing pointers to different sources (or system devices) in data. Maybe even without rebooting.
    Yeah. A big project. One that sounds familiar to some of us....
Sign In or Register to comment.