Scheduling events

Picos are a good fit for applications that have a relatively small amount of state for each entity, and that perform relatively quick computations, relatively infrequently.

Web applications fit that profile. From time to time, someone requests information about the state of an entity. That state is expressed as a web page, and that doesn't take a lot of time to compute.

Every so often, an event occurs that is of interest to the entity, and the pico reacts to that event by changing its state, which also doesn't require a lot of compute time.

Sometimes, though, we'll want the entity's pico to spontaneously wake up and do something. This is where scheduled events come into play.

Motivation

On November 10, 2022, a group of PicoStack programmers wrote a web application during a Hack Day at work (see slide deck from a report given the next day).

When the web page is visited, the pico consults a web API, checks for Ribs being served that day, and produces a page showing the entire menu. The last slide of the deck shows the page for the day of the report.

That's fine, as far as it goes. But rather than a person having to take action to view the page each day, it would be more convenient if the pico could just wake up every morning, check for the desired food, and send an email message if it was being served.

Scheduling an event

The KRL language defines a number of "libraries" which provide some functionality, and any pico can use them. To the language, they appear to be modules, but using them doesn't require the use module notation in the meta block because they are built-in.

While libraries most frequently define functions to be used by KRL code, some of them also define actions. In addition, some, like the event library which we have already seen in a previous post, are known by the compiler.

The schedule library is also known to the compiler. It defines a function, an action, and also a couple of postlude statements that are known to the compiler.

Setting up a regular event

In the postlude of a rule, you can establish a regular event, to be raised within the pico at times you define.

For example, you might want some rules to select at 8 a.m. every day. To do this, you would have a rule that establishes the schedule, such as this one:

  rule dailyAtEight {
    select when calibrate_schedule_event eight_a_m
    fired {
      schedule org_picostack_get_me_ribs event "it_is_morning"
repeat << 0 8 * * * >> attributes { } setting(id) ent:id := id } }

Once this rule has selected, it fires and the pico will now wake up every morning at 8 a.m., as if an alarm had gone off, to the org_picostack_get_me_ribs:it_is_morning event.

This is like setting the alarm.

Responding to the scheduled event

It is a simple matter to define a rule in the same ruleset to react to the scheduled event.

  rule checkEveryMorning {
    select when org_picostack_get_me_ribs it_is_morning
    pre {
      menu = time:now().get_lunch_menu()
      found_fav_food = menu.has_fav_food()
    }
    if found_fav_food then noop()
    fired {
      raise byname_notification event "status" attributes {
        "application": meta:rid,
	"subject": "Cannon Has " + found_fav_food,
	"description": "Found " + found_fav_food.lc() + " on the menu today!"
      }
    }
  }

When the alarm goes off, this rule selects and gets the day's menu, and checks it for favorite foods. If one is found, it raises an event for the same pico. This is the byname_notification:status event, defined in another ruleset which uses the technique described in an earlier post, Sending email via a web API, to send the actual email message.

This is like reacting to your alarm clock going off.

No comments:

Post a Comment