(Classic) Lesson: Pico-Based Systems

Learning Objectives

After completing this lesson you will be able to do the following:

  • Explain picos and how children and parent picos work
  • Use the developer tools to manage and interact with child picos.
  • Use Wrangler to manage and interact with child picos programmatically.



Prerequisites

You should have completed the following lessons

You should read:

Pico Children

One of the important features of programming with picos is creating children. Solving programming problems with picos usually involves creating a system of picos that cooperate to solve the problem. This lesson introduces the concept of pico life-cycle management.

The pico that is created when you created your account is called a "primary" or "account" pico and is the primary pico. 

  • Every pico except primary picos have a parent. 
  • Only primary picos can register rulesets. 
  • You can create as many child picos as you like. 
  • Picos can be the children of other child picos. 

Creating Children Using Devtools

You can use Devtools to manage child picos. 

Start by clicking on "About this Pico" on the main page of Devtools and then clicking the "New Child" button:

You will be asked to provide a name for the child. 

You should see a page like the following:

 

You can delete a child pico, by clicking on the name to show the detail and clicking the delete button. You will be asked to confirm your choice. 

 

 

 

Deleting a pico is not reversible. Any channels, installed rulesets, data in persistent variables, etc. will be deleted with the child and cannot be recovered.

 

 

 

 

Try creating a second child pico and deleting it. 

Visiting a Child Pico

Click on the "Open This Pico" link in the child you created above. You should see a screen like this:

You have now navigated to the child pico and Devtools is pointed there. Any operations you take in Devtools will be taken in the child pico.

Notice that the title bar now says "Viewing: Assignment 1" telling you that you're operating on that pico. 

This screen shows you the primary and parent picos. In this case, they're the same because the parent is also the primary pico, but that needn't be the case. You can navigate back to the parent pico by clicking the "Open Parent" button. 

Creating Children Programmatically Using Wrangler

One of the hallmarks of picos is that they can create other picos programatically. In this section, we'll write rules that manage the pico lifecycle. 

Creating a Child with an Action

First, let's create a rule that creates a child using the Wrangler action createChild()

   rule createAChild {
    select when pico_systems child_requested
    pre{
      random_name = "Test_Child_" + math:random(999);
      name = event:attr("name").defaultsTo(random_name);
    }
    {
      wrangler:createChild(name);
    }
    always{
      log("create child names " + name);
    }
  }
This code isn't doing anything fancy, just making up a name if one isn't provided and adding the child. The action is taken with the name and a child is created. 

To use Wrangler functions or actions, we have to use the wrangler module in the meta block:

use module v1_wrangler alias wrangler

The name of the registered ruleset that implements wrangler is v1_wrangler. We alias it as wrangler for use in the code above. 

After executing this, you should see the new child in Devtools:

Listing the Children

We can use the Wrangler function children() to get a list of the children.  Here's a function that uses it within the test ruleset:

showChildren = function() {
  wrangler:children();
}

This is nothing but a wrapper. You don't need to wrap Wrangler functions to use them within the ruleset, but we do if we want to make them visible via the Sky Cloud API for the pico. We also have to turn sharing on and provide the function in the meta block:

 meta {
   
   //...
   sharing on
   provides showChildren
}

This allows the functions named in the provides pragma to be seen in the pico's query API.  Now we can call showChildren() using the 

Deleting a Child Pico with an Action

We delete picos using the Wrangler action deleteChild(). The action takes the name of the child to delete. Here's a rule that uses that action:

  rule deleteAChild {
    select when pico_systems child_deletion_requested
    pre {
      name = event:attr("name");
    }
    if(not name.isnull()) then {
      wrangler:deleteChild(name)
    }
    fired {
      log "Deleted child named " + name;
    } else {
      log "No child named " + name;
    }

  }

Again, this rule is quite simple, reading the name of the child to delete from the event attribute name and then taking the action deleteChild(). Note the use of the conditional action to only take action if the name isn't null. 

Installing Rulesets with an Action

While most rulesets get installed upon creation, we sometimes want to control rulesets programmatically. Wrangler provides functions for listing the rulesets (rulesets()) and actions for installing and uninstalling rulesets. 

The action for installing a ruleset is installRulesets(). It takes a parameter that can be either a string naming a single ruleset ID to install or an array of strings representing a list of rulesets to install. Note that ruleset installation is idempotent. There's no penalty for attempting to install a ruleset multiple times. It can only be installed once in any given pico. The action installRulesets() also takes two optional parameters:

  • eci - the ECI of the pico to install the ruleset in
  • name - the name of the pico to install the ruleset in

If both are missing, the ruleset is installed in the current pico. If both are given, the value in name is used preferentially. 

Here's a rule that installs a ruleset in a pico when the event ruleset_install_requested is raised. 

rule installRulesetInChild {
  select when pico_systems ruleset_install_requested
  pre {
    rid = event:attr("rid");
    pico_name = event:attr("name");
  }
  wrangler:installRulesets(rid) with
    name = pico_name
}

We can raise the event using the Kynetx Event Console with rid set to b16x30 (a simple event log testing ruleset):

Checking the installed rulesets for that pico in Devtools shows that it was indeed installed:

The uninstallRulesets() action has the exact same parameters (required and optional) as installRulesets()

Do This

Now that you know how to manage the pico lifecycle, try the following:

  1. Clean up your pico by deleting any test rulesets you creating following along with the examples above. You can do that using Devtools or using a rule. 
  2. Write a ruleset that includes a rule called CreateFurnaceSystem that creates three picos as children of the primary pico that are configured as follows:
    1. Furnace - name is Furnace and installed rulesets are the default
    2. TempSensor - name is TempSensor and installed rulesets are the default
    3. Thermostat - name is Thermostat and installed rulesets include b16x30. 
    Trigger your rule and use Devtools to ensure it works as intended. 

Questions:

  1. What did you name your event? Why?
  2. What would you do differently if you wanted these three picos to be children of a fourth pico named FurnaceSystem that is a child of the primary pico? 

 

Copyright Picolabs | Licensed under Creative Commons.