Home AMX User Forum NetLinx Studio

Sleep Timers and Timelines...

I have been reviewing the Netlinx language reference guide as well as the Programmer 1 &2 manual, and they both show a section on Timelines. I still don't get it. The example refers to sending a command to a touchpanel, like so:

case 1: { SEND_COMMAND dvPanel,"'TEXT1-1 1'" }

isn't this just sending a text string to the panel? how would it know what button or field to send it to?

I added the TimeArray variable into the watch bar under debug mode, but when I press the button I assigned it to, the values don't change. I believe I entered this verbatim from the PDF file, as I wanted to see what it did.

<code>
DEFINE_CONSTANT
TL1=1 //timeline item #1
TL2=2 //timeline item #2
DEFINE_VARIABLE
LONG TimeArray[100] //Timeline item #3
DEFINE_EVENT
TIMELINE_EVENT[TL1] //timeline item #4, captures all events
{
switch(TIMELINE.SEQUENCE) //which time was it?
{
case 1: {SEND_COMMAND dvJVCLT37X898Tp,"'TEXT1-1 1'"}
case 2: {SEND_COMMAND dvJVCLT37X898Tp,"'TEXT1-1 2'"}
case 3: {SEND_COMMAND dvJVCLT37X898Tp,"'TEXT1-1 3'"}
case 4: {SEND_COMMAND dvJVCLT37X898Tp,"'TEXT1-1 4'"}
case 5: {SEND_COMMAND dvJVCLT37X898Tp,"'TEXT1-1 5'"}
}
}
TIMELINE_EVENT[TL2] //timeline item #5, captures all events
{
switch(TIMELINE.SEQUENCE) //which time was it?
{
case 1: {SEND_COMMAND dvJVCLT37X898Tp,"'TEXT2-2 1'"}
case 2: {SEND_COMMAND dvJVCLT37X898Tp,"'TEXT2-2 2'"}
case 3: {SEND_COMMAND dvJVCLT37X898Tp,"'TEXT2-2 3'"}
case 4: {SEND_COMMAND dvJVCLT37X898Tp,"'TEXT2-2 4'"}
case 5: {SEND_COMMAND dvJVCLT37X898Tp,"'TEXT2-2 5'"}
}
}
DEFINE_PROGRAM
PUSH[dvJVCLT37X898Tp,502]
{
TimeArray[1] = 1000
TimeArray[2] = 2000
TimeArray[3] = 3000
TimeArray[4] = 4000
TimeArray[5] = 5000
TIMELINE_CREATE(TL1, TimeArray, 5,TIMELINE_ABSOLUTE,TIMELINE_REPEAT)
}
PUSH[dvJVCLT37X898Tp,503]
{
TimeArray[1] = 1000
TimeArray[2] = 1000
TimeArray[3] = 1000
TimeArray[4] = 1000
TimeArray[5] = 1000
TIMELINE_CREATE(TL2, TimeArray, 5, TIMELINE_RELATIVE, TIMELINE_ONCE)
}
</code>

Comments

  • wrong code braces again....
  • travtrav Posts: 188
    Firstly, Timelines and the associated array of times, give you the ability to have an event fire based upon that array of times (millisecond accurate). So those times will not change in your debug window, but are actually a reference for the timeline to know when to trigger it's events.

    From the example you pasted in :
    TimeArray[1] = 1000
    TimeArray[2] = 2000
    TimeArray[3] = 3000
    TimeArray[4] = 4000
    TimeArray[5] = 5000
    TIMELINE_CREATE(TL1, TimeArray, 5,TIMELINE_ABSOLUTE,TIMELINE_REPEAT)
    

    When the timeline starts it starts at an arbitrary zero moment in 'time' and the elements of the array (in this case 5) correspond to the times at which it will fire an event. In the above example, at 1second every second through to 5 seconds.

    At each of these 'times' a timeline event is triggered in which you can do specific things dependant on which timeline.sequence number it was (ie which position in the array), or indeed do anything you want in this array at which ever time you want.

    A timeline can be repeating, in the above set of times, if the timeline was created as a repeating timeline then it would continue to fire a sequence of events 1 through to 5 once a second for ever.

    The following set of times:
    TimeArray[1] = 1000
    TimeArray[2] = 1000
    TimeArray[3] = 1000
    TimeArray[4] = 1000
    TimeArray[5] = 1000
    TIMELINE_CREATE(TL2, TimeArray, 5, TIMELINE_RELATIVE, TIMELINE_ONCE)
    

    Gives us a good example of the difference between an ABSOLUTE timeline, as in the previsous example where the times in the array triggered events at abosulte moments in time, and a RELATIVE timeline.

    A Relative timeline (TIMELINE_RELATIVE) fires events (in this case 5 of them again) relative to the previous time, so from our zero moment in time, the first event TimeArray[1] = 1000 will fire 1000msec after that zero moment, so an absolute 1 second from the start point of our timeline. The second event will fire 1000msec later relative to our 1st event, so an absolute 2sec after our zero moment.

    I hope that helps with timelines, as to the send command. AMX-PI provides you with a list of all commands and their syntax that you can send to a touchpanel.
    case 1: { SEND_COMMAND dvPanel,"'TEXT1-1 1'" }
    

    That specific command is a legacy command and its structure is as follows:

    "'TEXT<variable text address 1-255>-<new text to be put in button>'"

    I hope this helps!
  • You can use the ^TXT command to send Variable Text. I normally define my Variable Text boxes on the TP as constants in Netlinx to make the code more readable (example at bottom).

    From AMX-PI:
    AMX-PI wrote:
    "'^TXT-,,'"

    Assign a text string to those buttons with a defined address range.

    Sets non-unicode text.



    Syntax:

    SEND_COMMAND ,"'^TXT-,,'"



    Variables:

    variable text address range = 1 - 4000.

    button states range = 1 - 256 for multi-state buttons

    (0 = All states, for General buttons 1 = Off state and 2 = On state).

    new text = 1 - 50 ASCII characters.



    Example:

    SEND_COMMAND Panel,"'^TXT-500.504&510.515,1&2,Test Only'"

    Sets the On and Off state text for buttons with the variable

    text ranges of 500-504 & 510-515.

    Here's what I mean about naming the Variable Text addresses as constants:
    DEFINE_CONSTANT
    
    INTEGER nVT_CableBoxSelected = 1						//Variable Text Button for which cable box is selected
    
    BUTTON_EVENT[tpCableBoxArray,0]
    {
      PUSH:
      {
             IF(nLastButtonPressed>110 and nLastButtonPressed<151)			//Cable Box source selection
    		{
    		  nTPCableBoxTrackingArray[nPanelIndex]=nLastButtonPressed-110
    		  SEND_COMMAND dvLastPanel, "'^TXT-',ITOA(nVT_CableBoxSelected),',0,',cCableBoxNames[nTPCableBoxTrackingArray[nPanelIndex]]"
                    }
      }
    }
    

    LOL on your <\Code> craziness. How many variations are there :)

    --John
  • Ok, that is helpful.

    Anyways, my whole purpose here is to determine the best way to do a sleep timer in a master bedroom. I understand that I should use a Timeline, ok. I think I want to start out by saying set the TimeArray to 1 sec. so that it will repeat every second. At the end of the Timeline, I want to execute the function for Room Off, and kill the timeline. While the timeline is running, I want to have a countdown button showing the time remaining before the system will shut down. I want to allow the user to press the actual time remaining, and auto-increment both the time remaining as well as the actual timeline.
    DEFINE_CONSTANT    <-----Do I Even Need This in this instance?
    MBedSleep = 1
    
    DEFINE_VARIABLE
    LONG TimeArray[100]       <-------Is this just the maximum number of values the timeline variable will hold?
    INTEGER nSleep              <-------The variable I wish to decrement and increment with the timelines
    
    
    DEFINE_EVENT
    TIMELINE_EVENT[MBedSleep]  //sleep timer, captures all events
    {
    	If (nSleep>0)
    	{
    		nSleep--
    		SEND_COMMAND dvJVCLT37X898Tp,"'^TXT-10,0,',ITOA(nSleep)"
    	}
    	ELSE
    	{
    		SEND_COMMAND dvJVCLT37X898Tp,"'^TXT-10,0,'"
    		fcnROOMOFF()
    	}
    }
    
    DEFINE_PROGRAM
    
    PUSH[dvJVCLT37X898Tp,504]  <--The button to press to start the timeline/timer
    {
    	nSleep=60
            TimeArray[1] = 1000
    	
    	TIMELINE_CREATE(MBedSleep, TimeArray, 1,TIMELINE_ABSOLUTE,TIMELINE_REPEAT)
    }
    

    Its not working... :( Tips?
  • OK, well apparently this puts my processor into a loop where it is telling the tv to turn off every second. Guess I have to go back to square 1...
  • HedbergHedberg Posts: 671
    No, I don't think you have to go back to square one. You have started a timeline and you are decrementing a variable every time the timeline event occurs -- every one second in this case. When the variable hits zero you run your function to turn off the TV, but then you continue to run the time line without modifying the variable (it stays at zero) and you continue to test for zero and continue to call your function every second. There are couple different ways that you can modify the code.

    First, if you look at your timeline event carefully you will see that the count down actually taxes 61 seconds. This may be okay, but if you want to be more precise you could move your decrement un top of your test to see if the timer has expired. This may have odd consequences if you allow your timeline to run indefinitely Then, after the time has expired, you can kill the timeline to prevent it from running the tv turnoff function every second.
    might look like this
    TIMELINE_EVENT[MBedSleep]  //sleep timer, captures all events
    {
    	nSleep--
    	If (nSleep>0)
    	{
    
    		SEND_COMMAND dvJVCLT37X898Tp,"'^TXT-10,0,',ITOA(nSleep)"
    	}
    	ELSE
    	{
    		SEND_COMMAND dvJVCLT37X898Tp,"'^TXT-10,0,'"
    		fcnROOMOFF()
                    timeline_kill (MbedSleep)
    	}
    }
    
    

    you could also use timeline_pause and timeline_restart instead of timeline_kill and a subsequent timeline_create. I don't know enough to say what advantage in resources one method may have over another. Personally, sort of like pausing and restarting rather than killing and creating, but that may be just a fetish.
  • Other than seeing the code stop executing via netlinx notifications, is there a way to see if the timeline was ACTUALLY killed or paused?
  • Ok, well it seems that a reload of the project with timeline_kill fixed the issue. So I've got a timeline that works. cool. However, why is it important that the constant I create for the name of the Timeline be equal to 1? Also, is the TimeArray that I created necessary in an instance where I am only using a single timeline sequence? (If it's just because you can't have a timeline.sequence without an array, I'm ok with that answer.)
  • The Constant you created for the Timeline is the Timeline ID. You can have as many of these as you like, but they must start at 1 and go up from there. You can then call them whatever you like by defining a constant attributed to the number. It's so it knows which Timeline is being run.

    The Timeline works on an array of times because these times can differ. For example, you can have an array { 1000, 2000, 5000, 5500, 6000, 7000 } that will fire an event after one second, two seconds, then five seconds, then five and a half etc etc, depending on whether its absolute or relative. Much fun can be had!
  • viningvining Posts: 4,368
    vegastech wrote:
    wrong code braces again....
    You can always just go into "edit post" and correct this at any time. You can also preview post to check the layout prior to posting. Use square braces "[" "]" not "<" ">" w/o the double quotes.
  • So with regard to the array, in a setting where a single time is selected initially but then the user wants to change it to a different time (Besides sleep timers, think start times before a presentation starts), would a multi-number array still be used if a user were allowed to enter their own start time instead? Or would I just map the number they enter to an integer with a single number array counting down? Am I over-thinking the array here? I just wonder if perhaps the array is best used when firing events at different times, similar to a function call with waits?
  • With reference to the constants needing to start with 1, I was reviewing B Clements's volume hold repeats using timelines. His constants do not start with 1. This is confusing to me.
  • DHawthorneDHawthorne Posts: 4,584
    vegastech wrote: »
    With reference to the constants needing to start with 1, I was reviewing B Clements's volume hold repeats using timelines. His constants do not start with 1. This is confusing to me.

    I don't think it really matters, as long as they are unique. My understanding is that they are a handle to a pointer.
Sign In or Register to comment.