Migrating Python Apps from KICS 3.2 to KICS 3.5
Overview
Prerequisite for application Migration:
- KICS 3.5 package must be installed on User's machine (Windows, Linux or Mac).
- User must have access to a Platform instance running KICS 3.5.
The application's app.yaml update to the new schema is required to be compatible to the new KICS 3.5.
The python code doesn't need to be changed. It should work with the newest KICS version.
The migration can be done in two ways:
- Using Kelvin-sdk tool through
kelvin app migrate command
- Migrating manually using the steps described bellow starting in the Migration steps section
The highlighted app.yaml must be migrated in order the to work with the KICS 3.5
.
├── app.yaml
├── requirements.txt
├── datamodel
└── hello_model.yml
├── docs
└── hello_world
├── hello_world.py
└── ...
├── ...
├── ...
Automated Migration command
The kelvin app migrate command helps to migrate Kelvin apps from KICS 3.2 to KICS 3.5.
The command performs the app.yaml update to the new schema version.
Warning
- Backup your application's
app.yaml!
To execute the migrate command, navigate to the application root folder where the app.yaml is located and run:
-
Build and test the application to check for any migration problemns.
-
[Optional] Use kelvin studio for missing configurations during the migration process, see Configuring your App.
Manual Migration steps
app.yaml
The app.yaml for KICS 3.5 is a simplified version from the KICS 3.2 app.yaml.
The following sections show the required changes to migrate the yaml file.
Warning
First, backup your old app.yaml. Example app.yaml.bk
The highlighted lines are the sections that require to be changed.
| KICS 3.2 |
KICS 3.5 |
# app.yaml
info:
description: hello-world
name: hello-world
title: hello-world
version: 1.0.0
spec_version: 1.0.0
system:
resources:
memory: 256M
cpu: 400m
app:
kelvin:
core:
connections:
- name: myconnection
type: opcua
opcua:
endpoint: 'opc.tcp://data-source:48010'
registry_map:
inputs:
- access: RW
historize: false
name: temperature
node: ns=2;s=temperature
upload: false
- access: RW
historize: false
name: humidity
node: ns=2;s=humidity
upload: false
outputs: []
- name: myconnection2
type: opcua
opcua:
endpoint: 'opc.tcp://data-output:48010'
registry_map:
inputs: []
outputs:
- access: RW
historize: false
name: predictions
node: ns=2;s=predictions
upload: false
parameters: []
inputs:
- data_model: raw.float32
name: temperature
values: []
- data_model: raw.float32
name: humidity
values: []
outputs:
- data_model: hello.model
name: predictions
values: []
data_models:
- name: raw.float32 # raw datamodel
version: 2.0.0
- name: raw.int32 # raw datamodel
version: 2.0.0
- name: hello.model
version: 1.0.0
- name: local.model
version: 1.0.0
path: datamodel/local_model.yml
interface:
client:
args: [ ]
executable: run_app
period: 1.0
spawn: true
type: client
language:
python:
entry_point: hello_world.hello_world:App
requirements: requirements.txt
type: python
logging_level: INFO
runtime:
historize_inputs: false
historize_outputs: true
type: opcua
version: 4.0.0
images:
base: ''
builder: ''
system_packages:
- vim
- nano
configuration:
- name: initial_config
data_model: hello.model
values:
- name: value1
value: 1
- name: value2
value: 2
- name: initial_config2
data_model: raw.float32
values:
- name: value
value: 2
type: kelvin
|
# app.yaml
info:
description: hello-world
name: hello-world
title: hello-world
version: 1.0.0
spec_version: 2.0.0
system:
resources:
memory: 256M
cpu: 400m
app:
kelvin:
core:
inputs:
- name: temperature
data_type: raw.float32
sources:
- workload_names: [ workload-1 ]
asset_names: [ asset1 ]
- data_type: raw.float32
name: humidity
sources:
- workload_names: [ workload-2 ]
asset_names: [ asset2 ]
outputs:
- name: predictions
data_type: hello.model
targets:
- workload_names: [ workload-3 ]
asset_names: [ asset3 ]
data_types:
- name: hello.model
version: 1.0.0
- name: local.model
version: 1.0.0
path: datatype/local_model.yml
# optional, can be removed if this defaults are present
interface:
client:
args: [ ]
executable: run_app
period: 1.0
spawn: true
type: client
language:
python:
entry_point: hello_world.hello_world:App
requirements: requirements.txt
type: python
logging_level: INFO
system_packages:
- vim
- nano
configuration:
initial_config:
value1: 1
value2: 1
initial_config2: 2
type: kelvin
|
Datatypes
The main changes to the datatypes are:
- The
datamodel name was renamed to datatype.
- The
datamodel folder was renamed to datatype.
- The
raw datatypes are now built in with the application's base image and don't required to be declared in the
app.yaml datatypes section.
Apply the following changes if the application uses/contains any datatype.
1. Rename the section `data_models` to `data_types`.
2. Remove any entry with `raw` datatypes in the data types list.
4. Fix `path` property if exists in any of the element in the data types list by changing the folder from `datamodel` to `datatype`.
3. Rename apps folder `datamodel` to `datatype`
| KICS 3.2 |
KICS 3.5 |
# app.yaml
app:
kelvin:
core:
data_models:
- name: raw.float32 # raw datatype, can be removed
version: 2.0.0
- name: raw.int32 # raw datatype, can be removed
version: 2.0.0
- name: hello.model
version: 1.0.0
- name: local.model
version: 1.0.0
# local datatype, path field is added only when datatype
# was not uploaded and is present in the datatype folder
path: datatype/local_datatype.yml
|
# app.yaml
app:
kelvin:
core:
data_types:
- name: hello.model
version: 1.0.0
- name: local.model
version: 1.0.0
# local datatype, path field is added only when datatype
# was not uploaded and is present in the datatype folder
path: datatype/local_datatype.yml
|
With the new KICS version, the connections section was removed. This way, the connections are now defined inside the
inputs/outputs section.
Apply the following changes to the inputs/outputs and connections section:
-
Inputs
- remove the values field
- add the sources field and define the workload names and asset names, if applied, for the application
...
inputs:
- name: temperature
data_type: raw.float32
sources:
- workload_names: [ workload-1 ]
asset_names: [ asset1 ]
-
Outputs
- remove the values field
- add the targets field and define the workload names and asset names, if applied, for the application
...
outputs:
- name: predictions
data_type: hello.model
targets:
- workload_names: [ workload-2 ]
asset_names: [ asset2 ]
-
Remove the connections section
The following example shows the mapping between the old and new values.
| KICS 3.2 |
KICS 3.5 |
# environment.yaml
app:
kelvin:
core:
inputs:
- name: temperature
data_model: raw.float32
values: []
- name: humidity
data_model: raw.float32
values: []
outputs:
- name: predictions
data_model: hello.model
values: []
connections:
- name: myconnection
type: opcua
opcua:
endpoint: 'opc.tcp://workload-1.app:48010'
registry_map:
inputs:
- access: RW
historize: false
name: temperature
node: ns=2;s=temperature
upload: false
- access: RW
historize: false
name: humidity
node: ns=2;s=humidity
upload: false
outputs: []
- name: myconnection2
type: opcua
opcua:
endpoint: 'opc.tcp://workload-2.app:48010'
registry_map:
inputs: []
outputs:
- access: RW
historize: false
name: predictions
node: ns=2;s=predictions
upload: false
parameters: []
...
|
# app.yaml
app:
kelvin:
core:
inputs:
- name: temperature
data_type: raw.float32
sources:
- workload_names: [ workload-1 ]
asset_names: [ asset1 ]
- data_type: raw.float32
name: humidity
sources:
- workload_names: [ workload-1 ]
asset_names: [ asset1 ]
outputs:
- name: predictions
data_type: hello.model
targets:
- workload_names: [ workload-2 ]
asset_names: [ asset2 ]
...
|
Configuration
The new configuration field is defined by a dictionary and can take any values.
The following example shows the migration of two configurations.
The first config initial_config is a simple object with two float values. The second, initial_config2, is float value.
| KICS 2.0 |
KICS 3.0 |
# app.yaml
...
app:
kelvin:
core:
configuration:
- name: initial_config
data_model: local.model
values:
- name: value1
value: 1
- name: value2
value: 2
- name: initial_config2
data_model: raw.text
values:
- name: value
value: "sometest"
...
|
# app.yaml
...
app:
kelvin:
core:
configuration:
initial_config:
value1: 1
value2: 2
initial_config2: "sometest"
...
|
requirements.txt
KICS 3.5 uses the package kelvin-app>=6.0.0. Therefore, it is necessary to update it in requirements.txt.
.
├── app.yaml
├── requirements.txt
├── datatype
└── hello_model.yml
├── docs
└── hello_world
├── hello_world.py
└── ...
# requirements.txt
kelvin-app[data]>=6.0.0