Creating Custom Timers with Scripting

From time to time customers ask us about the possibility of using timers with their RedEye systems -- for example, to turn on a sprinkler system at a certain time of day, or to respond to certain events only after dark. While full support for timers is something that is on our roadmap, you can achieve some basic timer functionality today using RedEye scripts.

Adding a Sleep Button

Many television sets include a sleep button which will turn off the TV after 15, 30, or 60 minutes -- perfect if your routine is letting the soothing rhythms of late night talk shows sweep you into dreamland (thanks, Jimmy). Unfortunately, the TV sleep button doesn't shut down your system. What's that? You want a RedEye sleep button in your Watch TV activity? Well, you've come to the right place. Our first step is to add a new button to the activity itself. Because we are going to use scripting for this, let's edit the activity layout using the browser application. Once you have opened up the activity layout for editing, click on the "Add Control" button and choose "Button" for the control type. Here is how the screen looks after we have moved our new button into place: [caption id="attachment_1575" align="alignnone" width="300" caption="(click to enlarge)"][/caption]  

Activity Shutdown Script, Part One

Next we need to add some functionality to our button. We want it to wait for a bit, and then shutdown the currently running activity. We'll make this happen using a script. To do so, click on the "Choose Action" hyperlink. Then change the action type to "Script" and hit the "Edit" button. [caption id="attachment_1577" align="alignnone" width="300" caption="(click to enlarge)"][/caption]   When the script editor opens, we have a template for our action script. We can go ahead and delete the comment text -- it's just a placeholder. Next, head over to the "System Functions" menu and choose the Scripting.Wait function -- this allows us to put a delay into our script. [caption id="attachment_1579" align="alignnone" width="300" caption="(click to enlarge)"][/caption]   For now, let's put a relatively short delay in here -- we don't want to have to wait 15 or 30 minutes between tests. The wait function is looking for a time value in milliseconds, so let's put in the number 2000 -- a 2 second wait. Here's the script thus far:
require "systemScript"

Next up, let's head back to the System Functions menu and select the Scripting.LaunchActivity function, which we can use to shut everything down. Select the "roomId" text and then replace it by choosing your room out of the Rooms menu. Then for the activityId, enter -1 to shut everything down. [caption id="attachment_1578" align="alignnone" width="300" caption="(click to enlarge)"][/caption]   Here is the script I have -- yours will probably have a different room ID and name, but everything else should be the same.
require "systemScript"

Scripting.LaunchActivity(0--[[Room: Media Room]], -1)
To test our script, simply click on the "Test Script" button (you may want to launch an activity on your RedEye first if there isn't one running already so that you can confirm the shutdown part is working).

Launching a Background Task

We are almost finished, but we have one more thing to consider. When testing the script, you may have noticed that it ran for several seconds -- 2 seconds for our delay, and then however long it took to turn off the activity you were using. Here's something important to note: while the script was running, we could not send any other commands to the system -- our script was blocking everything else until it finished. With a 2 second delay, that's fine, but obviously it would not be acceptable for us to jam up the system for half an hour. After all, we might want to change the channel or adjust the volume after we hit the sleep button. We need some way of pushing the sleep command into the background while we do other things. Thankfully, RedEye offers a means to run scripts in the background using the Lua Task library. All we need to do is add a couple of lines to our existing script. First, we need to include the Lua Task library in our script. We do this by adding the following line to the top of the script:
require "task"
Next, we will take our current script and assign it to a local variable:
local scriptText = [[Scripting.Wait(2000)
                     Scripting.LaunchActivity(0--[[Room: Media Room]], -1)]]
Then we need to add an equal sign to the front of this variable -- that tells Lua Task that the text we are sending is a script rather than the location of a script file.
local scriptText = [[=Scripting.Wait(2000)
                      Scripting.LaunchActivity(0--[[Room: Media Room]], -1)]]
Finally, we call the task.create function.
task.create("WatchTV_Sleep", scriptText)
If you were to look at Lua Task's online documentation, you would notice that we added something extra to the front of this function. We have extended Lua Task a bit so that we can send messages between different tasks in a reliable way. For this type of usage, you do not need to worry too much about what happens here, but the value you send does need to be unique. I have chosen to use the name of the activity plus the button name; to avoid conflict with built-in RedEye task names, please avoid starting your task name with a number. The following screenshot shows how the script looks at this point. [caption id="attachment_1586" align="alignnone" width="300" caption="(click to enlarge)"][/caption] Once you have tested this version of the script to see that it works (notice how quickly it runs?), you can adjust the Scripting.Wait function to your desired length. Remember, we are dealing in milliseconds, so 15 minutes is 900,000 (please leave out the comma), 30 minutes is 1,800,000, and one hour is 3,600,000. Here is the final script for a 30 minute sleep button: [caption id="attachment_1587" align="alignnone" width="300" caption="(click to enlarge)"][/caption] That's it (easy, right?). Save your action script and your activity layout, and you are finished. Sweet dreams.