Home AMX User Forum NetLinx Studio

Shutdown/Startup Schedule

I am attempting to create my own schedule for system startup and shutdown. I would like to create my own module but have never done this. To get started, I need to allow the user to input a date and time in the touch panel.

questions:

How do I pull that info from the text input box in tp4? What I am going to do once I get the data from the input box i will use a compare_string with the time keyword.

Am I on the right track?

Comments

  • ericmedleyericmedley Posts: 4,177
    Look up the KEYB command in the manual of your touch panel. That will show you how to get user typed info back into your program. The panel sends back whatever they type in as a string on the data event.
  • I looked up the KEYB command and I may be going about this wrong. What I am looking to do is create a schedule that will allow the user to change the specific start and shutdown times of the system.

    What is the best way to go about this???
  • jjamesjjames Posts: 2,908
    As Eric suggested based on the information that you've provided, you would capture the data coming back from the touch panel by looking for the KEYB string in your string event.

    As far as how you go about doing it - I suggest you write it down & think of all of the steps necessary to trigger something. Think, for instance, on how you set your alarm to wake you up. You need to input the time. The clock needs to evaluate what time you've entered and compare it against the current time. If it's the same, do something - if not, don't. The logic is fairly simple, in my opinion.
  • The KEYB command is what you would use to trigger the code you need in the DATA_EVENT for the touch panel to enter and save the time you want to shut the system down.

    The process of actually shutting the system down can be as elaborate as you want to make it. When I have done it, I use two timelines. One is my feedback timeline that cycles at either 1/2 or 1 second to update specific feedback that would appear on almost all of the screens of a touch panel (such as mic mute status). That is where I check for the shutdown time. What I do is start a two-hour process to shut down the system. This is in case someone is actually using the system after hours. If I see a button press when the timer has started, I restart the timer to give them another two hours of use. I do this so that if someone is really using the system, I give them two hours to finish up. For example, if they are watching a DVD, there could be two hours from the time they start it until the movie is finished. I don't want to shut the system down while they are still using it, so I wait two hours from the last time they pressed a button.


    If I am withing the shutdown "window", and I haven't already started my countdown timer process, I start a timeline that has an array of 6 elements. The first is for 1 hour and 55 minutes, and the remainder are for one minute each. When a timeline.sequence is triggered, I pop up a warning message on the panel that says that the system will shutdown in 5, 4, 3, 2, <1 minutes. There is a button that they can press to restart the countdown back to two hours. That way, if they see the message and press the button, I don't bother them again for an hour and 55 minutes.

    The reason for the shutdown window, is to prevent the timer from running during the normal operating hours. For example, I will only have the countdown timer running between 7PM and 6AM for most systems. So timeline 2is only allowed to run between those hours. If 6AM comes along and the timeline is active, I kill it.

    There are probably a million ways to do this. Back several years ago I needed an auto-shutdown process and this is what I did. It may be completely different if I were to rewrite it today.
  • Thank you guys. I will expierment with this and let you know how I make out.
  • is it possible to not use the keyb- command? i am using an NXD 430 and am very limited. instead i wanted to use buttons i made with the numbers 0-9 and an enter button. I would have a start time and a shutdown time.

    How would I go about this?
  • danlee20 wrote: »
    is it possible to not use the keyb- command? i am using an NXD 430 and am very limited. instead i wanted to use buttons i made with the numbers 0-9 and an enter button. I would have a start time and a shutdown time.

    How would I go about this?

    First - Attend training. Read PI. Read the Netlinx Manual - pick the options that work for your situation.
    Second - Make the touch panel page. Decide if you want to use strings, commands, or channels on the buttons you created.
    Third - Write the associated code to handle your button presses.
    -- feel free to reverse two and three --
    Fourth - Test. Fix. Try Again. Possibly post the TP4 file and code on the forums for suggestions.
  • BUTTON_EVENT[dvTPSCHED,1]
    {
    PUSH:


    {
    SEND_COMMAND dvTPSCHED,"'^TXT-11,0 ',ITOA(nONE)"

    }

    }

    Can you not pass a command through a button event? I am still not getting any text input on the panel.
  • Should be SEND_COMMAND dvTPSCHED, "'^TXT-11,0,',ITOA(nONE)"

    Looks like you missed the comma after the 0.

    I can't see your TP4 file to tell if this is correct other than that.
  • Thank you!! thats exactly what it was. I need to be more careful that is the second time i forgot that comma!!
  • Ok, now im having an issue with every time I hit a number it overwrites my previous number. Do I need a set string length or an array? How do I go about implementing those?

    my code:

    BUTTON_EVENT[dvTPSCHED,0]
    {
    PUSH:
    {
    SWITCH(BUTTON.INPUT.CHANNEL)
    {
    CASE 1:
    {
    SEND_COMMAND dvTPSCHED,"'^TXT-11,0, ',ITOA(nONE)"
    }
    CASE 2:
    {
    SEND_COMMAND dvTPSCHED,"'^TXT-11,0, ',ITOA(nTWO)"
    }
    CASE 3:
    {
    SEND_COMMAND dvTPSCHED,"'^TXT-11,0, ',ITOA(nTHREE)"
    }
    }
    }
    }
  • jjamesjjames Posts: 2,908
    You're setting the text to be that, it doesn't append. You *can* use the ^BAT command, which should append the text.
  • thank you jjames. The only problem with using that is it keeps going. I need it to stop at 4 digits or overwrite after four digits have been entered. I haven't seen any commands on the ams pi which would allow me to do this, unless I'm missing something.
  • ericmedleyericmedley Posts: 4,177
    danlee20 wrote: »
    thank you jjames. The only problem with using that is it keeps going. I need it to stop at 4 digits or overwrite after four digits have been entered. I haven't seen any commands on the ams pi which would allow me to do this, unless I'm missing something.

    Those limitations are defined by you in how you go about programming it. For example you could limit the size of the array stroring the values. or you could follow the length of the pointer, or you could just ignor imputs past 4 values. It all depends upon how you program.
  • So I am making good progress now. I am stumped at how to store what im reading from the touch panel into a variable... im using the ?TXT- command to get the text information from the touch panel.
    My Code:
    BUTTON_EVENT[dvTPSCHED,12]
    {
    PUSH:
    {
    SEND_COMMAND dvTPSCHED,"'?TXT-11,0 '"
    }
    }


    This is what I see in notifications:

    Line 1 (12:50:45):: Input Status:Pushed [10001:3:1] - Channel 12
    Line 2 (12:50:45):: Command To [10001:3:1]-[?TXT-11,0 ]
    Line 3 (12:50:45):: Input Status:Released [10001:3:1] - Channel 12
  • ericmedleyericmedley Posts: 4,177
    It's coming back in a data_even from the touch panel as a string.

    You know they cover all this in programming classes. It'd really do you good to enroll. Your going to find this forum will turn on you pretty soon as you are asking questions that clearly indicate that you haven't been to classes.

    Hope that helps.
  • The "?TXT" command returns text to a custom_event, in a custom.text. Look for it in the help file.

    I don't think you need to go this deep, probably just store them in an char array when you get the TP input that you were appending with ^BAT.
  • ericmedleyericmedley Posts: 4,177
    mdonaldson wrote: »
    The "?TXT" command returns text to a custom_event, in a custom.text. Look for it in the help file.

    I don't think you need to go this deep, probably just store them in an char array when you get the TP input that you were appending with ^BAT.

    Ha! Shows how much I read in these posts.. :D
  • viningvining Posts: 4,368
    Here's a simple example of how to receive digits from a panel and display on the panel. The example uses digits 0-9 on channels 10-19 with an enter button on channel 20. Just push a button and store the digit in a string, send the string to the panel, append additional button pushes "digits" to the string and again send the entire string to the panel. For something so simple there's no need to append string on the panel, that's usually only used when you need a button to display strings greater than the single string limit of 180 or there abouts.

    You need to create a VT button and assign it to the constant. I called mine "MY_DIGITS_VT_CHNL".

    This code will only allow you to enter 4 digits if you enter a 5th it will clear the previous 4 and start over. It will also clear the digits collected if you take longer than 10 senconds between entries.

    FYI, this hasn't been tested but should work as described.
    BUTTON_EVENT[dvUIa,0]
         
         {
         PUSH:
    	  {
    	  STACK_VAR INTEGER nBtn;
    	  STACK_VAR INTEGER nUI_Indx;
    	  LOCAL_VAR CHAR cDigitStr[4];
    	  
    	  nBtn = BUTTON.INPUT.CHANNEL;
    	  nUI_Indx = GET_LAST(dvUIa) ;
    
    	  fnDIGITs_DeBug("'UI-[ ',fnDEV_TO_STRING(dvUIa[nUI_Indx]),' ], PUSH CHNL-[ ',itoa(nBtnIndx),' ] :DEBUG<',ITOA(__LINE__),'>'") ;
    	  
    	  SELECT
    	       {
    	       ACTIVE(nBtn >= 10 && nBtn <= 19)://digits 0-9 (channel 10-19)
    		    {
    		    CANCEL_WAIT 'DIGITS_CLEAR_STRING';
    		    WAIT 100 'DIGITS_CLEAR_STRING' //CLEAR AFTER 10 SECONDS 
    			 {
    			 cDigitStr = '';
    			 SEND_COMMAND dvUIa[nUI_Indx], "'^TXT-',itoa(MY_DIGITS_VT_CHNL),',0,',cDigitStr" ; 
    			 }			      
    		    if(LENGTH_STRING(cDigitStr) < MAX_LENGTH_STRING(cDigitStr))
    			 {//ADD TO EXISTING IF ANY
    			 cDigitStr = "cDigitStr,itoa(nBtn-10)";
    			 }
    		    else//IF WE ALREADY HAVE 4 DIGITS, CLEAR AND START OVER
    			 {
    			 cDigitStr = itoa(nBtn-10);
    			 }
    		    SEND_COMMAND dvUIa[nUI_Indx], "'^TXT-',itoa(MY_DIGITS_VT_CHNL),',0,',cDigitStr" ; 
    		    }
    	       ACTIVE(nBtn == 20)://ENTER / TAKE ENTRY
    		    {
    		    (* NEED CODE HERE *) //DO SOMETHING WITH cDigitStr
    		    CANCEL_WAIT 'DIGITS_CLEAR_STRING';
    		    cDigitStr = '';//NOW CLEAR AND UPDATE UI.  COULD WAIT 10 SECONDS AND IT WILL CLEAR AUTOMATICALLY
    		    SEND_COMMAND dvUIa[nUI_Indx], "'^TXT-',itoa(MY_DIGITS_VT_CHNL),',0,',cDigitStr" ; 
    		    }
    
  • Thanks for the help!!

    Eric- i have been to programmer 1, it is very basic in programmer one. The last few days they go very fast not allowing for any information to absorb. This is not the instructors fault, but rather the time they have to cram information into you. I certainly do not want to get on the forums bad side. Its just, since joining this forum I have learned a tremendous amount!!!
    I apologize for the amount of questions I ask, but I do really appreciate everyones help. I came to this forum to learn and be taught from guys like yourself that have been doing this for years. I hope to one day be at a level that you all are at.

    Thank you for all your help thus far :)
  • jjamesjjames Posts: 2,908
    I think a general rule when asking for help is that you've done some work first before asking. Showing the work you've done, and then asking why it doesn't work, or what you're doing wrong will definitely keep you off of the bad side forum. :)

    I agree that just simply storing the number in a char array would be the easiest & fastest way to do it. When you're done, I think I'll post a way I'd do it. It could turn out to be a fun little exercise. :)
  • vining wrote: »
    You need to create a VT button and assign it to the constant. I called mine "MY_DIGITS_VT_CHNL".

    Almost all of this makes sense. You just showed me a completely different way of thinking about doing this. The only thing I am having trouble understanding is quoted line above. Please forgive me, as im sure its something very simple.
  • viningvining Posts: 4,368
    danlee20 wrote: »
    Almost all of this makes sense. You just showed me a completely different way of thinking about doing this. The only thing I am having trouble understanding is quoted line above. Please forgive me, as im sure its something very simple.
    When you create on a button in TPD4 you can assign it channel port/code numbers, address port/code (used mostly for VT or variable text) numbers, level, command, etc.

    Button that just gets pushed to intiate a PUSH in a BUTTON_EVENT are normally just assigned a channel port & code. If you want to send the TP VT (variable text) you need to send it to a button that has the address port/code set. Usually these buttons don't need the channel port/code set.

    If your buttons for these digits are on channel port 2 (for example) and code numbers 10-19 (0-9), 20 (enter) then typically you would create a VT button that has the address port set to 2 and typically the address code of 1 if this is the first VT button you've created. Could be anything but usually you start with 1. For the sake of this code the address port needs to be the same and the channel ports but with slight modifications it could be anything you want but again normally they're the same.

    Then the part about the constant would be just creating a contstant with the value of the address code being used for your VT.

    DEFINE_CONSTANT

    MY_DIGITS_VT_CHNL = 1;// using address code number 1 for your VT

    You would mostly likely change that name to something more appropriate or just remove the MY_ portion.

    Now anytime you push a digit button you'll send or re-send the string holding your string to your VT text button. Keep in mind everything on the TP is button so when we call a VT field a button we don't typically intend it to be pushed but just used as a display. Later when you start doing music lists they'll become both buttons for pushing and displays for VT buts that's not until we get to chapter 6 in our text book. :)
  • question on the Time function

    I am still working on building my schedule and have figured quite a bit out. I was quite sick for about a week so I to take some time off.

    To use the TIME function in netlinx, is this a data event? Here is an example of what I have tried but gotten no results.

    DATA_EVENT[dvIO]
    {
    Push:
    {
    IF(TIME = 23:00)
    {
    on[dvIO,2]
    }
    }
    }

    That is an example I tried just to expieriement with the time call. It is almost exactly what is in th manual, so im curious as to why it is not doing anything. I also cannot find anywhere wher I can change the Netlinx time and date format. Is the possible?

    Thanks in advance
  • Try:

    IF(TIME = '23:00:00')....
  • jjamesjjames Posts: 2,908
    You *REALLY* need to use the NetLinx Keyword Help file and start reading up the functions you're using.

    In NetLinx Studio, press "Help" then click on "NetLinx Keyword Help." Or, highlight the word TIME and press F1.

    You said it was "almost exactly what is in the manual" - what manual?
  • the manual they give you at programmer one. I guess manual is misleading. But none the less.
  • viningvining Posts: 4,368
    danlee20 wrote: »
    the manual they give you at programmer one. I guess manual is misleading. But none the less.
    Could you post the exact code example from the P1 booklet cuz the code you posted has allot of issues.

    Your trying to process a push in a data event and IO's only have ONLINE: or OFFLINE: events possible in data_events. Typically you just set IO port parameters in the ONLINE handler of the IO's data_event like:
    DATA_EVENT   [dv_IO]                 /// I/O sensor input port 17 
         {
         ONLINE:
    	  {
    	  SEND_COMMAND dv_IO,'SET INPUT 1 LOW' ;//SNOW MELT POWER SENSE
    	  SEND_COMMAND dv_IO,'SET INPUT 2 HIGH' ;//WATER SENSOR (NC)
    	  SEND_COMMAND dv_IO,'SET INPUT 3 HIGH' ;
    	  SEND_COMMAND dv_IO,'SET INPUT 4 LOW' ;
    	  SEND_COMMAND dv_IO,'SET INPUT 5 LOW' ;
    	  SEND_COMMAND dv_IO,'SET INPUT 6 LOW' ;
    	  SEND_COMMAND dv_IO,'SET INPUT 7 LOW' ;
    	  SEND_COMMAND dv_IO,'SET INPUT 8 LOW' ;
    	  }                               
         }         
    
    Now for your PUSH you need to create a button_event so do some reading on them.
    BUTTON_EVENT[dv_IO,IO_SNOW_MELT]//  IO SNOW MELT
         
         {
         PUSH:
    	  {
    	  //SEND_STRING 0, "'IO PUSH, CHNL-[ ',ITOA(BUTTON.INPUT.CHANNEL),' ], SNOWMELT AC PWR ON <',ITOA(__LINE__),'>'" ;
    	  fnIO_Relay_DeBug("'IO ON, CHNL-[ ',ITOA(BUTTON.INPUT.CHANNEL),' ], SNOWMELT AC PWR ON :DEBUG<',ITOA(__LINE__),'>'") ;
    	  ON[dv_IO,BUTTON.INPUT.CHANNEL] ;
    	  nSnowMelt_On = 1 ;
    	  //[dvUI_Arry,BTN_SNOW_MELT] = nSnowMelt_On ;
    	  }
         RELEASE:
    	  {
    	  //SEND_STRING 0, "'IO RELEASE, CHNL-[ ',ITOA(BUTTON.INPUT.CHANNEL),' ], SNOWMELT AC PWR OFF <',ITOA(__LINE__),'>'" ;
    	  fnIO_Relay_DeBug("'IO OFF,CHNL-[ ',ITOA(BUTTON.INPUT.CHANNEL),' ], SNOWMELT AC PWR OFF :DEBUG<',ITOA(__LINE__),'>'") ;
    	  OFF[dv_IO,BUTTON.INPUT.CHANNEL] ;
    	  nSnowMelt_On = 0 ;
    	  //[dvUI_Arry,BTN_SNOW_MELT] = nSnowMelt_On ;
    	  }
         } 
    
    You could also do a channel_event instead with ON: & OFF: handlers.

    Then you have a logic issue with your code using the IF(TIME = 23:00) which should be IF(TIME = '23:00:00') as posted earlier but that will only ever work if your push event occurs at exactly 23:00:00 so you basically have a 1 second window each day when an IO push will fire off that code.

    What are you trying to achieve? If you're just trying to set the IO channel to to on at 23:00:00 then just drop
    IF(TIME = '23:00:00')
    {
    on[dvIO,2]
    }
    
    in define program or a timeline. For new programmers define program is the easiest to accomplish but put it after a wait 5 or something so it only runs and compare the time every 1/2 second rather that 6000 (?) times a second. Also keep in mind that the time 23:00:00 will be true for a full second and while that seems short to us the processor could run through that code thousands of times and each time executing your code. Not so bad if you're just turning on the IO but other code could cripple your processor so the wait 5 will only allow it to fire twice at most. If running other code, not just setting your IO you'd want to add a flag or a wait 10 so the code only fires once.
Sign In or Register to comment.