Developers

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?
Tags (1)
0 Kudos
8 REPLIES 8
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
KiranPrasanna
Channel Surfer

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

Hello,

I have changed background image in .brs file in task node folder but it is not updated. 

I need to change the background image in .brs file in task node folder. Please provide me the information.

 

I have set the Background image like this

m.background = m.top.findNode("background")
m.background.uri = "pkg:/images/Envoi.jpg"
 
 
0 Kudos
KiranPrasanna
Channel Surfer

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

Hello,

API call triggered in the timer but not going to the next actions.

When I set the timer to m.top.deactivate = true then only the next actions are working.

I need to call the api in timer for every 5 sec.

Based on the API response I have to stop the timer and navigating to another screen.

Xml file:

<?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 :

function fetch1(url as string) as string
req = CreateObject("roUrlTransfer")
port = CreateObject("roMessagePort")
req.SetMessagePort(port)
req.setRequest("POST")
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)
json = ParseJson(msg)
print "json.result.devicestatus" json.statusCode
if json.statusCode = 200
m.global.userToken = json.result.token
print "userToken11111111" m.global.userToken
if m.global.userToken <> invalid
m.top.deactivate = true
end if
else if json.statusCode = 401
activation()
end if
if type(msg) = "roUrlEvent" then
code = msg.GetResponseCode()
if code = 200 then
return msg.GetString()
else
return ""
end if
else
result.AsyncCancel()
return ""
end if
end while
end if
return ""
end function

0 Kudos
Community is Being Upgraded!

We’re upgrading Roku Community to bring you a faster, more mobile-friendly experience. You may notice limited functionality or read-only access during this time. Read more here.

Planned Downtime:
Community will be unavailable for up to 24–48 hours during the upgrade window during the week of May 19th and you may notice reduced functionality. In the meantime, for additional assistance, visit our Support Site.

We're sorry for this disruption — we’re excited to share what’s next!