Skip to content

Create a Kelvin SmartApp™

You can build for both x86_64 and arm64 devices.

$ kelvin app create

[kelvin.sdk][2023-10-19 18:39:54][I] Refreshing metadata..
Please provide a name for the application: event-detection

After providing Kelvin SmartApps™ name (i.e.: event-detection):

[kelvin.sdk][2023-10-19 18:43:36][I] Creating new application "event-detection"
[kelvin.sdk][2023-10-19 18:43:36][I] Retrieving the latest schema version
[kelvin.sdk][2023-10-19 18:43:39][R] Successfully created new application: "event-detection".

This will automatically create a Kelvin SmartApp™ bootstrap within a directory named as event-detection. It contains 5 different files (app.yaml, main.py, requirements.txt, Dockerfile and .dockerignore) which are gonna be explained in the next section.

Folder Structure

You can now open the folder in your favorite IDE or editor and start to modify the files to create your Kelvin SmartApp™.

$ cd event-detection
$ ls -la
-rw-rw-r-- 1 ubuntu ubuntu  361 Oct  2 21:57 .dockerignore
-rw-rw-r-- 1 ubuntu ubuntu  133 Oct  2 21:57 Dockerfile
-rw-rw-r-- 1 ubuntu ubuntu  436 Oct  2 21:57 app.yaml
-rw-rw-r-- 1 ubuntu ubuntu  610 Oct  2 21:57 main.py
-rw-rw-r-- 1 ubuntu ubuntu   17 Oct  2 21:57 requirements.txt

Below is a brief description of each file.

The app.yaml is the main configuration file that holds both Kelvin SmartApps™ definition as well as the deployment/runtime configuration. It is composed by the following sections:

spec_version key

The spec_version key is automatically injected and specifies Kelvin SmartApps™ JSON Schema (latest) version which both defines and validates the app.yaml structure.

spec_version: 4.12.0

info section

The info section holds Kelvin SmartApps™ basic information required to make itself uploadable to Kelvin's App Registry.

info:
    name: event-detection
    title: Event Detection
    description: Monitors if a motor is overheating. If so, it will send a Control Change to reduce the Motor Speed.
    version: 1.0.0

The name is Kelvin SmartApps™ unique identifier. The title and description will appear on the Kelvin UI once Kelvin SmartApps™ is uploaded.

Info

The version should be bumped everytime Kelvin SmartApps™ gets an update, and before it gets uploaded to the App Registry.

app section

The app:kelvin can be considered the app.yaml "main" section. It defines what are Kelvin SmartApps™ inputs and outputs, as well as define Kelvin SmartApps™ "global" configuration(s) and its (asset) parameters definition. We'll go through each of these sections individually with a more detailed analysis later on this guide.

app:
    type: kelvin
    kelvin:
        inputs: []
        outputs: []
        configuration: {}
        parameters: []

Info

All of these are [optional], and can be left empty.

system section

The system section is [optional] and can be used to set different system requirements/constraints within Kelvin SmartApps™ running environment. i.e. Resources, Environment Variables, Volumes, Ports, etc:

system:
    resources: {}
    privileged: Boolean
    environment_vars: []
    ports: []
    volumes: []

resources section

The resources defines the reserved (requests) and limits the resources allocated to Kelvin SmartApps™:

system:
    resources:
        requests:   # Reserved
            cpu: 100m
            memory: 256Mi
        limits:     # Limits
            cpu: 200m
            memory: 512Mi

environment_vars section

The environment_vars is used to define Environment Variables available within Kelvin SmartApps™ container. i.e.:

system:
    environment_vars:
        - name: KELVIN_GW_MODE
            value: SOCKETS

Info

KELVIN_GW_MODE is an Environment Variable that is [required] by Kelvin's platform. Others can optionally be added.

volumes section

Mounted volumes are [optional] and their main purpose is to share and persist data generated by Kelvin SmartApps™ or used by it in a specific place. They act like a shared folder between Kelvin SmartApps™ and the host. Kelvin supports directory volumes, such as folders or serial ports, persistent, and file/test volumes:

system:
    volumes:
        # Folder Volume
        - name: serial-rs232
            target: /dev/rs232 # Container path
            type: host
            host:
            source: /dev/ttyS0 # Host path

        # Persistent Volume
        - name: extremedb
            target: /extremedb/data
            type: persistent

        # File/Text Volume
        - name: model-parameters
            target: /opt/kelvin/data/parameters.bin
            type: text # Renders data into a file
            text:
            base64: true
            encoding: utf-8
            data: |-
                SGVsbG8gUHJvZHVjdCBHdWlsZCwgZnJvbSB0aGUgRW5naW5lZXJpbmcgR3VpbGQhCg==

ports section

The ports is [optional] and used to define network port mappings. i.e.:

system:
    ports:
        - name: http
            type: host # Exposed on the host
            host:
            port: 80

        - name: opcua
            type: service # Exposed as a service for other containers
            service:
            port: 48010
            exposed_port: 30120
            exposed: true

privileged key

The privileged key is [optional] and used to grant extended privileges to Kelvin SmartApps™, allowing it to access any devices on the host, such as a Serial device:

system:
    privileged: true

The main.py is used as the entry point of Kelvin SmartApps™. When it runs, main.py is typically the first script that gets executed, and it usually contains the main logic or orchestrates the flow of Kelvin SmartApps™. However, naming a file "main.py" is just a convention, and it's not mandatory. The name helps developers quickly identify where the primary logic of Kelvin SmartApps™ begins.

The following code example will be generated upon kelvin app create:

import asyncio

from kelvin.application import KelvinApp # KelvinApp import


async def main() -> None:
    # Creating instance of Kelvin SmartApp™ Client
    app = KelvinApp()

    # Connect the App Client
    await app.connect()

    while True:
        # Custom Loop
        await asyncio.sleep(1)


if __name__ == "__main__":
    asyncio.run(main())

The requirements.txt file is used to list all the dependencies a Python Kelvin SmartApps™ needs. It can be used to easily install all the required packages, ensuring Kelvin SmartApps™ runs correctly.

The Dockerfile is a script used to define the instructions and configuration for building a Docker image. It specifies the base image, installation of software, file copying, and other setup tasks needed to create a reproducible and isolated environment for running Kelvin SmartApps™ in Docker containers.

FROM python:3.10-slim

ENV PYTHONUNBUFFERED=1
WORKDIR /opt/kelvin/app 
COPY . /opt/kelvin/app
RUN pip install -r requirements.txt

ENTRYPOINT python main.py

Info

If main.py is not the intended entry point, it also needs to be replaced on the Dockerfile.

Specifies which files and directories should be excluded when building Kelvin SmartApps™ Docker image. It helps reducing the build context, resulting in smaller, more efficient Docker image.