RIAPS is a Resilient Middleware for Smart Grids. See riaps.isis.vanderbilt.edu for more information.
Two applications, Periodic and Sporadic, are located in the LearnTimer directory of riaps-tutorials. They demonstrate the below timer programming models.
Periodic software timers enable programmers to call functions at regular intervals. RIAPS supports this by allowing components to declare a timer port, as in the below model file snippet:
...
component Foo {
timer clock 1000 msec;
...
}
...
This port, named clock, will send the Foo component a message every 1000 milliseconds. Because an interval is specified, this will be a periodic timer. When the Foo thread receives that message, it will look for a function named on_clock in the Foo.py component code.
from riaps.run.comp import Component
class Foo(Component):
def __init__(self):
super(Foo, self).__init__()
def on_clock(self):
msg = self.clock.recv_pyobj() # Required to remove the timer message from the message queue
self.logger.info(f"Hello world!")
Running this component will cause Hello world! to be logged once every second. msg in this scope is a timestamp of when the clock timer fired; its value is a float instance, containing the number of seconds since the Unix epoch.
timer <PORT NAME> <INTERVAL> <UNITS>;
UNITS can be one of min, sec, msec.
Sporadic software timers allow code to declare that some action will happen once, after a specified delay. RIAPS supports this by allowing components to declare a timer port without a given interval, as in the below model file snippet:
...
component Bar {
timer clock;
...
}
...
To use this timer port, give it a delay interval using it’s setDelay(<some interval, float>) method, then launch the timer thread with its launch() method. The below implementation of Bar calls these functions on the timer port clock in the components handleActivate method.
from riaps.run.comp import Component
class Bar(Component):
def __init__(self):
super(Bar, self).__init__()
def handleActivate(self):
self.clock.setDelay(3.0) # Delay for 3s
self.clock.launch() # Start the timer
self.logger.info("I will say Hello world! in 3 seconds...")
def on_clock(self):
msg = self.clock.recv_pyobj() # Required to remove the timer message from the message queue
self.logger.info(f"Hello world!")
Running an application that uses this component will result in this sequence of events:
Bar initializes the component, then its ports.handleActivate() for each of its components, during which Bar sets its sporadic timer delay (setDelay(3.0)) and launches it (launch()).Sporadic timers support other methods for modifying the interval and cancelling an active timer. These are documented in the port’s API.