Customizing Digital Thing Code

To customize and test the code generated by the IoTCatalyst Studio designer, it is mandatory to mount a Container in the targeted Hypervisor.
Once the Container is correctly mounted you can find the generated code in the following file:

<runtime_path>/containers/<id_container>/digitalthing/<digital_thing_name>/main.py

where:
 - runtime_path is the installation directory of the Hypervisor defined in the settings file.
 - id_container is the container id visible in the container details from the IoT Catalyst Studio.
 - digital_thing_name is the name of the Digital Thing.

In order to install third party libraries, the Hypervisor virtualenv must be previously activated, so if third party libraries are needed to run the customized code in main.py, they must be installed in the virtualenv of the Hypervisor whose location is defined in the python_path parameter of the Hypervisor settings file (see Hypervisor installation guide for further details).

Context

Every Digital Thing when containerized, can access to a collection of useful parameters grouped in the running "context". The context is dynamically set up at runtime by the IoT Catalyst Edge for each started container.

The context contains:

 - context["IoTCatalystAPIEndpoint"]: represents the IoT Catalyst Studio API endpoint.
 - context["idContainer"]: represents the Container ID.
 - context["nameContainer"]: represents the Container Name.
 - context["idHypervisor"]: represents the Hypervisor ID.
 - context["nameHypervisor"]: represents the Hypervisor Name.
 - context["idHypervisorHostType"]: represents the Hypervisor Host Type.
 - context["vendor"]: represents the Gateway vendor where the Hypervisor is installed.
 - context["model"]: represents the Gateway model where the Hypervisor is installed.
 - context["architecture"]: represents the architecture of the Hypervisor is installed.
 - context["lat"]: represents the latitude of the Location of the Hypervisor.
 - context["lon"]: represents the longitude of the Location of the Hypervisor.
 - context["bof"]: represents the bof json.
 - context["token"]: represents the token of the Passport file of the Hypervisor.
 - context["startTime"]: represents the timestamp of the Container start.

Settings

All the settings defined in the Design phase from the IoT Catalyst Studio Designers, are accessible inside the Digital Thing code, through the settings dictionary.

Features

Every feature Data, Event, Action, Function is represented inside the Digital Thing code by a decorated function.
The decorators must not be removed from the IoT Catalyst Studio generated code of the Digital Thing in order to benefit all the functionality of the underlying Hypervisor SDK.

Data

In the following code there is an example of a Data feature type:

copy
@register_notification(auto=True,pool='main',post_procs=[],polling=settings['POLLING_TIME_DATA'],updatable=False)
def dato1():
    _dato1=random.randint(1,10)
    # INSERT YOUR CODE HERE TO PRODUCE THE DATA
    # ...
    # ...
    # ...
    print('Producing data update for feature [dato1]', _dato1)
    #RETURN THE PRODUCED VALUE
    return _dato1

Events

Event features are similar to Data features, typically an event has the auto parameter set to False in the decorator and returns a Boolean data which value is True if the event occur.

copy
@register_notification(auto=True,pool='main',post_procs=[],polling=settings['POLLING_TIME_EVENT'],updatable=False)
def event1():
    _event1=False
    # INSERT YOUR CODE HERE TO PRODUCE THE EVENT DATA
    # THIS METHOD SHOULD RETURN A BOOLEAN
    # ...
    # ...
    # ...
    #RETURN THE PRODUCED VALUE
    print('Producing event update for feature [event1]',_event1)
    return _event1

Actions

Action features are particular procedures that can be triggered from the IoT Catalyst Studio (GUI and API). The Actions can take a maximum of 5 input parameters.

copy
@register_action
def action1(param1):
    # INSERT YOUR CODE HERE
    # ...
    # ...
    # ...
    if _dato1 == 15:
        updateContainerStatus("critical", "-1", "too much")
    else:
        event1()

Now call the plugin initializer function and add some custom options.

Functions

Function features are very similar to Action features, the only difference between Action and Functions is that Functions returns a value that can be visualized in IoT Catalyst Studio or used by the IoT Domain Navigator object.

copy
@register_function
def func1(param1, param2):
    # INSERT YOUR CUSTOM CODE HERE
    # ...
    # ...
    # ...
    return param2

Housekeeping Callback Functions

There are 3 reserved function features that are called automatically by the SDK (if defined inside the Digital Thing code).
These functions are the following:

copy
@register_function
def __OnStart():
    return True

@register_function
def __OnEnd():
    return True

@register_function
def __OnUnMount():
    return True

The __OnStart function is called on every START Container Command received by the Hypervisor.
The __OnEnd function is called on every STOP Container Command received by the Hypervisor.
The __OnUnMount function is called on every UNMOUNT Container Command received by the Hypervisor.

Container custom status

Each Container can assume a predefined status based on his life cycle.
There is also an embedded function inside the Hypervisor SDK that can be used to set a use defined status of the Container based on the custom business logic implemented.
This function called updateContainerStatus takes the following parameters:
 - status: a string representing the gravity of the reported event
 - status_code: a numeric code to represent the status
 - message: a string with a descriptive message

copy
updateContainerStatus("error", "-1", "Error Accessing Sensor")

IoT Catalyst Studio API

To call IoT Catalyst Studio API inside the Digital Thing code, in the Hypervisor SDK there are some utility functions useful for this task.
The functions are:
 - getTokenByPassport
 - callStudioAPI
The getTokenByPassport returns the API authorization token and function requires the following parameters:
 - IoT Catalyst Studio API endpoint.
 - The Hypervisor Passport token (found inside the IoTCPassport.xml file in the Hypervisor installation folder).
The callStudioAPI returns the API response json and requires the following parameters:
 - IoT Catalyst Studio API endpoint.
 - The IoT Catalyst Studio API authorization token.
 - The name of the API method.
 - The body of the API method request.

copy
from sdk.Common.IoTCUtils import getTokenByPassport, callStudioAPI
tok = getTokenByPassport(context["IoTCatalystAPIEndpoint"], context["token"])
res = callStudioAPI(context["IoTCatalystAPIEndpoint"], tok, "General.settings", {})

In the previous code snippet, there is an example to use the API utility functions.

Constants

The SDK injects some useful constants that can be used inside the Digital Thing Code:
 - CONTAINER_FOLDER: represents the full path folder of the Container where the Digital Thing Code is running.
 - RESOURCES_PATH: represents the full path of the resources folder, which can be useful to store or retrieve resources referenced in the Digital Thing Code, for example external scripts or executables. All the files inside the resources folder can be distributed to the Digital Thing Library.


Distribute Digital Thing to the Studio Library

Once the custom code is finally customized and is running correctly, you can distribute the Digital Thing package back to the IoT Catalyst Studio Library.
To distribute the customized Digital Thing on the IoT Catalyst Studio Library is necessary to run a shell script that creates a .zip package that can be uploaded to the Library.
The distribution script is the following:

<runtime_path>/containers/<id_container>/distribute.sh

(or .bat, depending on the machine architecture).

The script produces a .zip package in the following folder:

<runtime_path>/containers/dist/<digital_thing_name>.zip

Tipically on Linux machines the Hypervisor is started with elevated privileges, if so than also the distribution script must be launched with elevated privileges (sudo).
The produced zip package can be uploaded to the IoT Catalyst Studio Digital Thing Library.