Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
vbacct
Visitor

Is there a way to execute a function every few secs

I am looking for a function that does something similar to JavaScript's SetInterval() method, basically execute a function every few seconds/millisecs. And keep executing the function until the time interval is cleared. Looks like the roTimeSpan can be used to execute a function after certain time interval but how to make it run continuously until the time interval is cleared?
0 Kudos
11 REPLIES 11
RokuJoel
Binge Watcher

Re: Is there a way to execute a function every few secs

roTimeSpan should work for what you are trying to do, you'll likely need several instances and use it in several ways, here's one way:

Example: exec a function for a specific duration:


timer=createobject("roTimeSpan")
timer.mark()
maxExecutionTime=50
while timer.totalseconds() < maxExecutionTime
myfunction()
end while


0 Kudos
RokuMarkn
Visitor

Re: Is there a way to execute a function every few secs

If you're looking for a way to essentially run a function "in the background" while other things are happening, you'll need to integrate it into whatever event loop is running at the time. Just make sure your wait has a timeout, and check your timer to see if it's time to run the function. Something like:


next_call_time = 0
while true
wait(100, msgport)
t = timer.TotalSeconds()
if t > next_call_time then
next_call_time = t + interval
call_my_function()
end if
... rest of event loop ....


--Mark
0 Kudos
vbacct
Visitor

Re: Is there a way to execute a function every few secs

Thanks RokuJoel and RokuMarkn.
0 Kudos
NicholasStokes
Binge Watcher

Re: Is there a way to execute a function every few secs

Hello,

I have triggered Api call every 5 sec using timer function

I am using this below function

m.testtimer = m.top.findNode("testTimer")
m.testtimer.control = "start"
m.testtimer.ObserveField("fire", "changetext")

xferActive1 = CreateObject("roURLTransfer")
xferActive1.SetCertificatesFile("common:/certs/ca-bundle.crt")
xferActive1.setRequest("POST")
url = xferActive1.SetURL("https://jonathanbduval.com/roku/feeds/roku-developers-feed-v1.json")


But I am getting the dot error in CreateObject line

0 Kudos
renojim
Community Streaming Expert

Re: Is there a way to execute a function every few secs

You can't use roUrlTransfer in the render thread.  You will have to use a task that gets run when the timer fires.

Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
0 Kudos
ssaguiar
Streaming Star

Re: Is there a way to execute a function every few secs

In your xml file, define a timer which will repeat every 4 seconds:

<Timer

    id = "SessionRegisterRetryTimer"
    repeat = "true"
    duration = "4"
/>
 
in your brs file:
 
m.sessionRegisterRetryTimer = m.top.findNode("SessionRegisterRetryTimer")
m.sessionRegisterRetryTimer.observeField("fire", "SessionRegisterRetry")
 
where you need to start the timer:
 
m.sessionRegisterRetryTimer.control = "start"
 
then, in the SessionRegisterRetry function, you do what you have to do. In this case it will be called every 4 seconds, after the first call.
 
function SessionRegisterRetry()
    print "called sSessionRegisterRetry function"
end function
 
 
0 Kudos
KiranPrasanna
Channel Surfer

Re: Is there a way to execute a function every few secs

I tried this way but still getting the same error in below line


xferActive1 = CreateObject("roURLTransfer")

I need to trigger Api call every 5 sec. Could you provide the information

0 Kudos
KiranPrasanna
Channel Surfer

Re: Is there a way to execute a function every few secs

In your xml file, define a timer which will repeat every 4 seconds:

<Timer

id = "SessionRegisterRetryTimer"
repeat = "true"
duration = "4"
/>

in your brs file:

m.sessionRegisterRetryTimer = m.top.findNode("SessionRegisterRetryTimer")
m.sessionRegisterRetryTimer.observeField("fire", "SessionRegisterRetry")

where you need to start the timer:

m.sessionRegisterRetryTimer.control = "start"

then, in the SessionRegisterRetry function, you do what you have to do. In this case it will be called every 4 seconds, after the first call.

function SessionRegisterRetry()
print "called sSessionRegisterRetry function"

xferActive1 = CreateObject("roURLTransfer")
xferActive1.SetCertificatesFile("common:/certs/ca-bundle.crt")
xferActive1.setRequest("POST")
url = xferActive1.SetURL("https://jonathanbduval.com/roku/feeds/roku-developers-feed-v1.json")

end function

But still getting the same error in below line

xferActive1 = CreateObject("roURLTransfer")

I need to trigger Api call for every 5 sec. Could you provide the information

 

 

 

0 Kudos
sanity-check
Roku Guru

Re: Is there a way to execute a function every few secs

I'd create a long running task that keeps requesting the data until I tell it to stop, and observe a field on it to get updates.

So..

PollUrlTask.xml:

 

<?xml version="1.0" encoding="UTF-8"?>

<component name="PollUrlTask" extends="Task">

  <interface>
    <field id="url" type="string" />
    <field id="intervalSecs" type="integer" value="5" />

    <field id="deactivate" type="boolean" />
    
    <!-- watch this -->
    <field id="result" type="string" />
  </interface>

  <script type="text/brightscript" uri="PollUrlTask.brs" />

</component>

 

 

PollUrlTask.brs:

 

sub init()
  m.top.functionName = "run"
end sub
 
sub run()
  url = m.top.url
  interval = m.top.intervalSecs * 1000

  if url = invalid or url = "" then return
  if interval < 1000 then interval = 1000
 
  while m.top.deactivate = false
    m.top.result = fetch(url)
    sleep(interval)
  end while
end sub

function fetch(url as String) as String
  req = CreateObject("roUrlTransfer")
  port = CreateObject("roMessagePort")
  req.SetMessagePort(port)
  req.SetUrl(url)
  if (left(url, 5) = "https") then req.SetCertificatesFile("common:/certs/ca-bundle.crt")
  result = req.AsyncGetToString()
  if result then
    while true
      msg = wait(0, port)
      if type(msg) = "roUrlEvent" then
        code = msg.GetResponseCode()
        if code = 200 then 
          return msg.GetString()
        else
          return ""
        end if
      else 
        request.AsyncCancel()
        return ""
      end if
    end while
  end if
  return ""
end function

 

 

Then in the UI thread:

 

  m.testTask = createObject("roSGNode", "PollUrlTask")
  m.testTask.observeFieldScoped("result", "onTestTaskResult")
  m.testTask.url = "https://jonathanbduval.com/roku/feeds/roku-developers-feed-v1.json"
  m.testTask.intervalSecs = 4
  m.testTask.control = "RUN"
sub onTestTaskResult(event as Object)
  print "onTestTaskResult", event.getData()
end sub

 

..note it's coming back as a string and "alwaysNotify" is not set to true so your observer will only fire if the response has actually changed. I tend to process my data in the UI thread because it's massively faster, but if it's really heavy you might want to do that in the task. The "return empty string" error handling is good enough for some use cases, but not all!

This stops it:

 

  m.testTask.unobserveFieldScoped("result")
  m.testTask.deactivate = true
  m.testTask = invalid

 

 

0 Kudos