Configurations, Instances and Connectors

To build an executable ThingML program, you need to instantiate things and connect them together. A ThingML configuration defines a set of instances and connectors between their ports. A ThingML configuration is similar to, for example, a Java main operation.

This example reuses basic components provided by the ThingML framework to blink a LED:

/*
 * Step1: Import the ThingML application you want to run.
 * Applications are usually defined at a PIM level
 */
import "../blink.thingml"

/*
 * Step2: Import PSM things that would need to instantiate 
 * to properly run the application. 
 * Here: LED and Timer for the Arduino platform
 */
import "../../hardware/bricks/_arduino/led.thingml"
import "../../core/_arduino/timer.thingml"

/*
 * Step3: Define the configuration
 */
configuration BlinkArduino
{

        /*
         * Step3.1: Define instances
         * ThingML provides two instantiation policies:
         * - simple instanciation, for example timer. 
         *       This is rather similar to a new in Java
         * - group instanciation, for example led.
         *       This allow to instantiate a pre-defined
         *       configuration, with some instances and connectors
         *       already defined.  
         *  To access an instance in a group, 
         *  a sub-group in a group or a property of an instance,
         *  we use a classic dotted notation eg:
         *  groupName.subGroupName.instanceName.propertyName         
         */
        //Led group: defines a LED and connection to Arduino board
        //realized within the group. You just need to set the PIN
        //of the LED using the set primitive.
        group led : LedArduino
                set led.io.digital_output.pin = DigitalPin:PIN_13

        // The timer
        instance timer : TimerArduino

        // The blink application
        instance app : Blink


        /*
         * Step3.2: Define connectors between instances
         */
        connector app.HW => led.led.Led
        connector app.HW => timer.timer
}

Why the hell should we write led.led.Led?

The first "led", corresponds to

group led : LedArduino

You basically refer to the group you have just declared. So far, so good.

Now, let's dive into that LedArduino stuff:

configuration fragment LedArduino
{
    group io : DigitalOutputArduino

    instance led : LedUC         
    connector led.DigitalOutput => io.digital_output.DigitalOutput
} 

"led.led", thus refers to the led declaration inside LedArduino. So far, so good.

Now, let's dive into that LedUC stuff to find out where does the last "Led" comes from. Note that we are looking for a port (since this "led.led.Led" was defined in a connector:

thing LedUC includes Led, DigitalOutputMsgs
{...}

Nope. That's not here. Let's have a look at the includes, for example "includes Led":

thing fragment Led includes LedMsgs
{   
    provided port Led //the holy grail
    {
        receives led_on, led_off, led_toggle
    }
}

Hell yeah, there's a Led port.

That was... easy?