Skip to content
This repository has been archived by the owner on Aug 13, 2020. It is now read-only.

Calvin GUI

Per Persson edited this page Oct 11, 2018 · 8 revisions

Building an application in the CalvinGUI

Before going ahead and ordering a bunch of sensors and devices capable of running Calvin (which of course we encourage you to do) you might want to try Calvin out in a sandboxed environment. This will also suit as an introduction to the Calvin GUI which is a great way to experiment with Calvin and to test different ways of putting together applications before deploying them.

Introduction to the GUI

In a web browser, goto Calvin Development GUI, you should see the following welcome screen:

intro_welcome

Start the Calvin GUI in a cloud sandbox (Not supported as of yet)

Running the Calvin GUI in a cloud sandbox is very straight forward. However, it will not provide the same flexibility and configuration possibilities as when running towards a local runtime.

  • Choose Try Calvin in cloud sandbox and press Start and the GUI will start.

Start the Calvin GUI with a local runtime

As of version 1.1.0, the GUI can be enabled in a runtime using the --gui flag. By default, the GUI is available on http://localhost:8000, but this can be changed using runtime flags --gui-if and --gui-port.

In prior versions, the following method can be used (and actually still works):

When trying out this for the first time, start Calvin from the directory calvin/examples/ui_in_gui/ inside the distribution. This we make Calvin read the configuration file below at boot. The purpose of this config file is to set up a number of virtual devices that you can manipulate without the need to connect real devices.

The config file calvin.conf contains the following information:

{
  "calvinsys": {
     "capabilities": {
         "sys.timer.once": {
             "module": "sys.timer.Timer",
             "attributes": {}
         },
         "sys.timer.repeating": {
             "module": "sys.timer.Timer",
             "attributes": {"repeats": true}
         },
         "io.light": {
           "module": "ui.Actuator",
           "attributes": {"ui_def": {"image":"KY-016", "control":{"sensor":false, "type":"boolean", "default":false}}}
         },
         "io.switch": {
           "module": "ui.Sensor",
           "attributes": {"ui_def": {"image":"KY-004", "control":{"sensor":true, "type":"boolean", "default":false}}}
         },
         "io.button": {
           "module": "ui.Sensor",
           "attributes": {"ui_def": {"image":"KY-004", "control":{"sensor":true, "type":"boolean", "default":0, "behaviour":"momentary"}}}
         },
         "io.tiltswitch": {
           "module": "ui.Sensor",
           "attributes": {"ui_def": {"image":"KY-020", "control":{"sensor":true, "type":"boolean", "default":false}}}
         },
         "io.lightbreaker": {
           "module": "ui.Sensor",
           "attributes": {"ui_def": {"image":"KY-010", "control":{"sensor":true, "type":"boolean", "default":false}}}
         },
         "io.buzzer": {
             "module": "ui.Actuator",
             "attributes": {"ui_def": {"image":"KY-006", "control":{"sensor":false, "type":"int", "default":false, "behaviour":"audio"}}}
         },
         "io.pwm": {
             "module": "ui.Actuator",
             "attributes": {"ui_def": {"image":"KY-Generic", "control":{"sensor":false, "type":"float", "default":0}}}
         },
         "io.temperature": {
           "module": "ui.TriggeredSensor",
           "attributes": {"ui_def": {"image":"KY-001", "control":{"sensor":true, "type":"float", "min":-20.0, "max":120.0, "default":20.0}}}
         },
         "io.humidity": {
           "module": "ui.TriggeredSensor",
           "attributes": {"ui_def": {"image":"KY-015", "control":{"sensor":true, "type":"float", "min":0.0, "max":100.0, "default":60.0}}}
         },
         "io.distance": {
           "module": "ui.TriggeredSensor",
           "attributes": {"ui_def": {"image":"Distance", "control":{"sensor":true, "type":"float", "min":0.0, "max":4.0, "default":2.0}}}
         },
         "io.stdout": {
           "module": "ui.StandardOut",
           "attributes": {"ui_def": {"control":{"type":"console"}}}
         }
      }
   }
}

This config file informs the runtime that specific UI components are available for a number of actors in the GUI. Without it the GUI wont be able to represent any hardware components. More information about calvin configurations here.

Start a local runtime:

  • In a terminal, cd to the directory calvin/examples/ui_in_gui/ and run the following commands:

      $csruntime --host 127.0.0.1 --port 5000 --controlport 5001 --name local_runtime
    

Note! Make sure to start the runtime from a directory containing the calvin.conf file above.

  • Back to the Welcome Screen in the web browser, Choose I have Calvin running on this machine and press Start and the GUI will start.

The GUI workspace

intro_workspace

  1. Actorstore: All available actors are listed under there respective categories. Click on a category to see its actors.

  2. Documentation: When selecting an item in the actor store the documentation for the currently selected item will be shown in this frame.

  3. Canvas: The canvas is the workspace, where dropped actors can be connected into applications. At the top of the canvas is a popup showing the current project. It is possible to have more than one project at the same time. Commands like “Run” and “Stop” from the project menu, and “Save” and “Open” from the file menu will operate on the currently active project.

  4. Inspector: When selecting an actor placed in the canvas area the inspector will be populated with relevant information about the actor, for a non running application, init parameters and name of the actor can be set. For a running application this is the place to migrate an actor to another runtime.

  5. Runtime overview: All available runtimes are presented here together with the capabilities of the runtime. This information is useful when migrating an actor to another runtime.

Example 1: Hello World

Lets start with a simple Hello World application with a small twist (migration)

A Constant

First, create a constant actor which will initiate a message.

  • Pick the actor Constant found in category std in the ActorStore, drag and drop it in the Canvas area. hello_constant

The red dot in the corner of the actor indicates that one or more arguments needs to be initiated for the actor.

When an actor is selected in the Canvas, information about ports and requirements will be shown in the Inspector, in addition, arguments for initiating the actor are visible.

  • Select the Constant actor by clicking on it.
  • In the inspector frame, initiate the data argument with "Hello World!" Note! String arguments must be quoted, i.e. enclosed in "".
  • It is good practice to name the actors in the application according to their purpose. Change the name of the actor to e.g. Greeter.

hello_inspect_constant

A Print

To print the constant to the console we need to add a Print actor. The Print actor can be found in the category io in the ActorStore.

  • Drag and drop a Print actor next to the Constant actor.

hello_greet_print

A Delay

The Constant actor will send tokens in a continues stream. To be able to distinguish each print a delay is needed.

  • From the category std, drag and drop a ClassicDelay or a Delay actor between the Print and Constant actors. hello_add_delay
  • Change the Value of the delay to 1 second by selecting the ClassicDelay actor and updating the Value in the Inspector to 1.
  • Also change the name of the actor as you see fit.

hello_inspect_delay

Connect the actors

The application is now almost ready, but for data to flow between the actors their ports need to be connected.

To connect an output port (on right hand side of actor) to an input port (left hand side of actor), simply click-and-hold a port, then drag to another port, and release. Now there should be a visible connection between the actors.

To remove a connection, drag from the input port and release anywhere on the canvas (not on another port).

  • Connect the actors.

hello_connection

Start the application

  • Start the application by clicking Run in the Project menu

hello_run

The application is now running and a new window containing a representation for the terminal will pop up, if it doesn't please refer to the Troubleshooting section section. hello_running

Migrating actors between runtimes

Migrating actors is one of the key features of Calvin. Migrating an actor between runtimes are very intuitive from the Calvin GUI.

Lets start with migrating the Print actor and verify that the prints currently residing in the GUI representation of a terminal moves to a local terminal instead.

Start a new runtime

Regardless whether the application is running in a sandboxed environment or on a local runtime, one more runtime is needed. This time the runtime shall use the default stdout_plugin and therefor no calvin.conf file is needed. Make sure the new runtime isn't started from a directory from which it can find the calvin.conf file. See how calvin configurations are found by the runtime in Configuration basics.

  • In a new terminal run the following command:

      $csruntime --host 127.0.0.1 --port 5002 --controlport 5003 --name another_runtime
    

Migrate the Print actor

  • Go back to the Calvin GUI and start the application if not already running.
  • Select the Print actor, in the Inspector a drop down meny is available.

hello_migrate

  • Select another_runtime from the meny.
  • The Print component will disappear from the Device Simulation window.

hello_migrated

  • The Print actor has migrated to the new terminal and the prints can now be seen there instead.

hello_migrate_terminal

Migrate back and forth

  • Test to migrate the Print actor back and forth between the runtimes.
  • The other actors can be migrated in the same manner.
  • Above the actors the runtime in which the actor currently resides is labeled, in addition migration status is stated during migration.

hello_runtime_label

Save an application

An application can be saved for future development or...

  • Stop the application if it is running.

general_stop

  • Save it.

general_save_as

  • Pick a name for the project.

general_save_popup

Now the application will be available for running or continues work in the future.

When creating large application, saving the project continuously is highly recommended.

Example 2: Button and Light

In the following example a simple application for controlling a light with a button is introduced. The application will comprise two actors, a Button actor and a Light actor.

  • Start with creating a new project.

general_new_project

The Actors

  • From the category io, drag and drop one Button actor and one Light actor to the Canvas area.
  • These actors have no arguments which needs to be initiated. However, the name of the actors can be changed in the same manner as for the actors in Example 1.
  • Connect the actor ports

light_connected

Start the application

  • Start the application as earlier described.

A new window containing a representation of both the Button and Light components will pop up. light_components

  • Try the application out by clicking the Button representation and see what happens with the Light representation.

Migrate the actors to a Raspberry Pi

The next step is to migrate the actors to a Raspberry Pi and try the application with real hardware. (To be continued...)

Troubleshooting

No device representation is seen in the GUI

If running Calvin on a local or remote machine as opposed to running in a sandboxed environment, make sure the runtime have access to a calvin.conf file which specifies capabilities such that the actors can be represented in the Calvin GUI. See calvin.conf in the ui_in_gui example in Calvin.

Strange output from application

Make sure no old application is running in the background by stopping all applications before trying to run the application again.

general_stop_all

All settings are correct but it still doesn't work

A simple way of debugging an application is to place an Identity actor between two actors in the application. The argument dump needs to be initiated to true. All tokens flowing trough the Identity actor will then be logged to the terminal window before continuing to the next actor. This approach might at least give a hint about where the problem occur.