Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: use standard port and clarify several places

Learning Objective

After completing this lesson, you will be able to:

  • explain how a pico is a first-class Internet citizen
  • explain channels and use the "My Picos" page to manage them
  • send events and queries to a pico using a browser, the event console, and the "Testing" tab
  • use logs
  • use the klog() operator

Prerequisites

  • complete the Pico Engine Quickstart
  • have a ruleset registered , installed in the pico-engine, and added to a installed in a pico
  • have installed the event console in Google Chrome

Pico as an Internet citizen

A pico (quoting from Rebuilding KRL):

...

The pico has multiple URL's that can be used to query its state and send it events. HTTP is used as the transport protocol.

events

Here is a sample URL that sends an event to a pico like the one you created in the Pico Engine Quickstart:

Code Block
http://localhost:80848080/sky/event/citdel5gz00012aaoo5ucc613/5echo-hello/echo/hello

Breaking this URL into components:

  • "http://" identifies HTTP as the protocol
  • "localhost:80848080" is the domain name and port of the pico-engine which hosts the pico
  • "sky/event" identifies this as an event for the pico
  • "citdel5gz00012aaoo5ucc613" is the pico's event channel identifier (ECI) (yours will be different)
  • "5echo-hello" is an arbitrary string which serves as an event identifier (EID) (useful when looking at logs)
  • "echo" identifies the domain of the event
  • "hello" identifies the type of the event

queries

Here is a sample URL that sends a query to the Picoa pico:

Code Block
http://localhost:80848080/sky/cloud/citdel5gz00012aaoo5ucc613/hello_world/hello?obj=Bob

...

  • "sky/cloud" identifies this as a query for the pico
  • the event channel identifier or ECI
  • "hello_world" is the ruleset nameidentifier or RID
  • "hello" is the name of a shared function from that ruleset
  • "obj" is the name of the argument that the function expects
  • "Bob" is the value for that argument

Create a Channel

As you can see in the URL for events and queries, channels are the way in which a pico can be identified by the pico-engine.

Picos can have multiple channels. The best practice is to create a channel for each purpose or correspondent. Each channel has a This is because the main channel, created at the same time as the pico, should be kept secret because it cannot be replaced except by deleting the pico and re-creating a replacement pico. A channel that you create for a particular purpose can be revoked without affecting your pico.

Each channel has a name and a type.

To create a new channel, visit the "Channels" tab:

...

Info

Note that the channel identifiers you will see are assigned by your pico-engine, and will differ from the ones seen in the these screenshots.

Enter "lesson" in the box whose placeholder is "name" and "temporary" in the box whose placeholder is "type" and click the "add channel" button to create a new channel.

...

Congratulations! You have created your first channel.

Sending events through the channel

Since a pico is a first-class Internet citizen, there are many ways in which you can send it an event. We will look at three such ways here:

  1. Directly using a URL through a client (ex. a browser, or the `curl` command in a Bash shell)
  2. Using the event console or some other console for RESTful APIs
  3. Using the "Testing" tab of the UI

1. Directly using a URL

Construct a URL that identifies your Pico by the channel id that you created in the previous section. Remember to replace the channel identifier in the sample URL with the identifier of your "lesson" channel. Also, you may choose your own event identifier (rather than use "5")., as we did for this screenshot).

Code Block
http://localhost:8080/sky/event/citeh9si400022aao04assjxy/5/echo/hello

You can use the URL in any Internet client. For example, you could use it in the `curl` command in a Bash shell.

Here we will use a tab in the browser. Place the URL in the location area of your browser, and press the Enter key.

The result will look something like this:

Image Removed

Using the event console

There is a Google Chrome application that you can add to your browser to make it easy to send events. You can find it on github and install it into your browser following the instructions. You can then launch it and enter in the host:port of your pico engine, the channel identifier and the event domain and type.

Image Removed

Click the "Raise Event" button to send the event to your pico engine, and the Image Added

Congratulations! You just received your first directive from an event you raised.

Directives allow picos to direct endpoints to react a certain way to an event.  Our rule's directive just says hello, but it could be used to do more complex things. Directives allow the program's logic to be placed in the rules, not in the end points.  Placing logic in the rules provides loose coupling with easier scaling and maintenance.

2. Using the event console

The Kynetx event console is a Google Chrome application that you can add to your browser to make it easy to send events. You can find it on github and install it into your browser following the instructions. You can then launch it and enter in the host:port of your pico engine, the channel identifier and the event domain and type.

Image Added

Click the "Raise Event" button to send the event to your pico engine, and the app will scroll to the Results section, where you can see the directives generated by your event.

Notice that the event identifier was chosen by the event console.

3. Using the "Testing" tab

While developing When you develop a ruleset, you can may choose to use the "My Picos" Testing" tab of the "My Picos" page which can provide a simple UI for your event. To do so, you must modify the ruleset to define and share The "Testing" tab works by querying your ruleset to see if it shares the name __testing and bind it to a structure which represents the events and queries you wish to test.

Modify your ruleset to look like this:

...

if it does, it parses the structure so named and builds simple forms to test each of the queries and events which the structure defines.

The value bound to __testing is a structure that describes those portions of our ruleset that we wish to expose in the "Testing" tab. You do not need to expose every aspect of your ruleset, but only those that you wish to appear in the "Testing" tab.

Add this code into the global block of your ruleset:

Code Block
    __testing = { "queries": [ { "name": "hello", "args": [ "obj" ] },
                               { "name": "__testing" } ],
                  "events": [ { "domain": "echo", "type": "hello" } ]
                }
  }
 
  rule hello_world {
    select when echo hello

...

You have added a new name__testing (double underscore), which defines two queries and one event, to the "global" block of the ruleset.

This name must also be shared, so we you will need to add it to the "shares" entry in the "meta" block of the ruleset. The "shares" keyword is followed by a comma-separated list of names defined in the globals section which we wish to use outside of the ruleset. Those Any names not mentioned in "shares" are for the private use of the the ruleset and are not exposed outside the ruleset.

The value bound to __testing is a structure that describes those portions of our ruleset that we wish to expose in the "Testing" tab. You do not need to expose every aspect of your ruleset, but only those that you wish to appear in the "Testing" tab.

Be sure to use the "validate" button to make sure there are no syntax errors in your ruleset. Once you get the "ok" go ahead and register, enable, and install your modified ruleset. (Review the Pico Engine Quickstart page if necessary)

Refresh your "My Picos" page, and click on the "Testing" tab.

Image Removed

Notice the button "echo/hello", representing this event for your ruleset named "hello_world". Click on this button to send the event.

Image Removed

Using logs

Look at the console from which you started your pico-engine.

You should see entries like this one:

...

Edit the "meta" block of your ruleset to look like this:

Code Block
  meta {
    name "Hello World"
    description <<
A first ruleset for the Quickstart
>>
    author "Phil Windley"
    logging on
    shares hello, __testing
  }

Be sure to use the "validate" button to ensure that you have introduced no syntax errors into your ruleset. Once you get the "ok", go ahead and push your changes into Github and re-install the ruleset into your pico. (Review the Pico Engine Quickstart page if necessary)

Refresh your "My Picos" page, and click on the "Testing" tab. Notice under your ruleset identifier that there are three forms, one for each of the queries and the event that you described in your ruleset.

Image Added

Notice the button "echo/hello", representing this event for your ruleset named "hello_world". Click on this button to send the event.

Image Added

Notice in the directive returned by the event that the "Testing" tab uses the event identifier "__testing".

Using logs

Look at the console from which you started your pico-engine.

You should see entries like this one:

Code Block
[DEBUG] { rid: 'hello_world',
  event: 
   { eci: 'citeh9si400022aao04assjxy',
     eid: '5',
     domain: 'echo',
     type: 'hello' } } fired

You may find this information This console log may be useful in debugging events.

For example, try a typo in the URL for the event, say by spelling "echo" incorrectly as "ecco". In the console log, you will see that the event is recievedreceived, and the Pico selected (based on its ECI), but you will not see that the event has fired.

Send a query through your channel

Create a URL for your Pico which uses your "lesson" channel identifier. It will look something like

Code Block
http://localhost:80848080/sky/cloud/citeh9si400022aao04assjxy/hello_world/hello?obj=Bob

Places where yours your URL will differ from the one shown above:

  • you may be using a different port (other than "80848080")
  • you will be using a different channel identifier (your ECI will not be "citeh9si400022aao04assjxy")
  • you may be using a different value for the expected argument named "obj" (not "Bob")

You can also Enter your URL into the location line of your browser, or use it in a `curl` command in a Bash shell.

You can also enter the value for the argument in the "Testing" tab, in the box whose placeholder is "obj", and click on the link "hello".

...

Congratulations! You know how to send queries to a pico, either directly using a URL, or through the UI.

More about logs

KRL provides an operator, klog(), which allows us to print information into the log filelogs. It is an operator, rather than a statement, so it is applied to an expression. It prints into the log the message passed to it as an argument, followed by the value of the expression on which it operates. As an example, we will modify your "hello_world" rule to expect an attribute, named "name" and use it to customize the Finally, it returns the value of the expression on which it operates, unchanged. This makes it easy to add to or remove from your KRL code without changing its meaning.

As an example, modify your "hello_world" rule to expect an attribute, named "name" and use it to customize the message returned in the directive.

...

This is the first use in these lessons of a prelude block within a rule. This is where we bind values to names which can then be used within the rule. Here, we obtain the value of an the event attribute named "name" and bind that value to a name which is also named "name". We apply the "klog" operator to that value, which simply passes the value along, but as a side-effect logs its argument followed by the value.

...

Code Block
    __testing = { "queries": [ { "name": "hello", "args": [ "obj" ] },
                               { "name": "__testing" } ],
                  "events": [ { "domain": "echo", "type": "hello",
                                "attrs": [ "name" ] } ]
                }

After making these changes to your ruleset, be sure to validate it, then push your change to Github, and re-install into your pico.

With these changes, we refresh the "Testing" tab and you can now enter a value into the box whose placeholder is "name" before clicking on the "echo/hello" button to send the event.

The console of your web server should now show the expected message Examine the terminal or console from which you launched your engine. You will see the expected message from the klog operator, which will look like this (embedded in other logging messages, just before the rule fires):

Code Block
[DEBUG] { rid: undefined,
  event: 
   { eci: 'ciu4b6zui0001jfs0nmki6z1y',
     eid: '5',
     domain: 'echo',
     type: 'hello' } } rule selected: hello_world -> hello_world
[KLOG] our passed in name:  Bob
[DEBUG] { rid: 'hello_world',
  event: 
   { eci: 'citeh9si400022aao04assjxy',
     eid: '5',
     domain: 'echo',
     type: 'hello' } } fired

Using the "Logging" tab

Click on the "Logging" tab.

Image Removed

...

the "Logging" tab

Click on the "Logging" tab for your pico.

Image Added

Notice that logging is disabled. The ruleset required for logging is pre-registered in your pico engine. Click on the "Rulesets" tab, and notice that it appears in a dropdown list named "Available Rulesets".

Image Added

Click on the "install ruleset" button to install the "io.picolabs.logging" ruleset to in your pico.

Click again on the "Logging" tab.

...

Logging is now available for this pico, but is turned off. Click  the the "On" button, and refresh the "My Picos" page.

You should see the logs one episode, for the event that turned logging on. Now go to the testing tab and do a query and an event for your hello_world ruleset. Refresh the page, and you will see logging episodes matching that match your testing activity. Select a couple of these to see the detailed logging.

...

Here we see the logging for a query and an event.

Congratulations!

You now know how to send events to, and make queries of, a pico. You have also learned some debugging techniques.

...