LIBPF® Python Model User API manual
Introduction
Intended audience
Model Users who want to programmatically control their models via the Python scripting language.
System integrator and app developers who want to develop solutions based on the modeling of industrial continuous processes with the LIBPF® enabling technology, in particular solutions which interact with process models via scripts or automation.
Scope
This document is the manual for the Python incarnation of the LIBPF® high level Model User API, a simple, high-level API to manage and use process models who have been previously prepared and deployed by model developers.
The LIBPF® Python Model User API is a SWIG-wrapped version of the C++ Model User API.
Prerequisites
-
having received and installed a LIBPF® model
-
having installed a Python 3 interpreter
-
knowledge of the Python scripting language
-
acquaintance with the field of industrial continuous processes
-
the roles involved with the lifecycle of solutions developed using the LIBPF® enabling technology, see LIBPF® Technology Introduction
-
a general knowledge of the concepts of the LIBPF® high level Model User API, see LIBPF® Model User API documentation
-
to import successfully the LibpfUserPython module in python, the files LibpfUserPython.py and _LibpfUserPython.so should be present in the current directory
Python interface
Start your Python 3 interpreter and import the LibpfUserPython model:
import LibpfUserPython
Before performing any operation with the LibpfUserPython module, you should call the LibpfUserPython.initializeKernel() method.
Kernel API
The capabilities of the Kernel API can be queried with the command:
dir(LibpfUserPython)
apiVersion
Query the Model User API version
Parameters:
- (output) error: an intPointer object; on exit contains an error code; the code is 0 if the operation was successful; to obtain more descriptive error codes, use the LibpfUserPython.errorMessage function to convert the code in a human-readable description
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() error = LibpfUserPython.intPointer() error.assign(1) apiVersion = LibpfUserPython.apiVersion(error) print('error', error.value(), ' message', LibpfUserPython.errorMessage(error.value())) print('API version = ' + apiVersion)
createCase
Creates a new case instance.
Parameters:
-
(input) cdj: a string containing a UTF-8 encoded, JSON-serialized CaseDescriptor object; for more information see the Doxygen-generated reference documentation for the LIBPF® C++ Model User API section on the CaseDescriptor class.
-
(output) error: an intPointer object; on exit contains an error code; the code is 0 if the operation was successful; to obtain more descriptive error codes, use the LibpfUserPython.errorMessage function to convert the code in a human-readable description
Returns a valid, persistent Case handle on success, or an invalid Handle if there was an error.
A valid returned Handle can be used to access the case instance.
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() error = LibpfUserPython.intPointer() error.assign(1) ch = LibpfUserPython.createCase('{"type":"Pasteur"}', error) print('error', error.value(), ' message', LibpfUserPython.errorMessage(error.value())) print('ch = ', ch.toString())
in this example the JSON string is supplied directly, and contains the only really required field: the type.
The following, more elaborate example uses the Python built-in json module (JSON encoder and decoder) to create the JSON string from a dictionary.
import json, LibpfUserPython LibpfUserPython.initializeKernel() error = LibpfUserPython.intPointer() error.assign(1) so = { u'a': u'b', u'c':u'd', u'e':u'f' } io = { u'g': 1, u'h':2 } cd = { u'type': u'SaltPepper', u'tag': u'case123', u'description': u'case with 1 2 3 times', u'stringOptions': so, u'integerOptions': io } cdj = json.dumps(cd) ch = LibpfUserPython.createCase(cdj, error) print(error.value()) print('ch = ', ch.toString())
defaultType
Returns the default model type that createCase will instantiate if the JSON string supplied to LibpfUserPython.createCase is empty.
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() dt = LibpfUserPython.defaultType() print('default type = ', dt)
description
Returns the kernel description as an UTF-8 encoded string
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() d = LibpfUserPython.description() print('kernel description = ', d)
duplicate
Duplicate an existing case instance
Parameters:
-
(input) handle: the existing case handle
-
(input) tag: tag string for the new Case instance, UTF-8 encoded string
-
(input) description: description string for the new Case instance, UTF-8 encoded string
-
(output) error: an intPointer object; on exit contains an error code; the code is 0 if the operation was successful; to obtain more descriptive error codes, use the LibpfUserPython.errorMessage function to convert the code in a human-readable description
Returns the new case instance handle, or an invalid Handle in case of error
import LibpfUserPython LibpfUserPython.initializeKernel() h1 = LibpfUserPython.Handle('0') error = LibpfUserPython.intPointer() error.assign(1) h2 = duplicate(h1, 'new tag', 'new description', error) print(h2.toString())
errorMessage
Parameters:
- (input) error: one of the values of the ErrorCode enum
Returns the textual representation of the error
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() error = LibpfUserPython.intPointer() error.assign(1) enumerator = LibpfUserPython.jsonEnumerator('aaaaaaaaaaaaaaaaa', error) print('error', error.value(), ' message', LibpfUserPython.errorMessage(error.value()))
initializeKernel
This function initializes the library and the kernel, in detail:
-
sets verbosityGlobal to 2
-
initializes several internal LIBPF® global data structures
-
fills in the component list
-
registers the kernel as a product
-
registers the kernel-supplied enumerators and types
-
prints the startup banner
It should be called at least once before performing any operation with the library.
This function executes these initializations only once discarding subsequent calls.
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel()
intPointer
Creates an integer variable pointer, which can be supplied as a parameter to all the LIBPF® Python Model User API functions that take an error parameter rather than returning an integer.
After the function returns, the error code can be accessed via the value method.
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() error = LibpfUserPython.intPointer() error.assign(1) print(error.value())
jsonEnumerator
Parameters:
-
(input) name: the name of the enumerator
-
(output) error: an intPointer object; on exit contains an error code; the code is 0 if the operation was successful; to obtain more descriptive error codes, use the LibpfUserPython.errorMessage function to convert the code in a human-readable description
Returns a UTF-8 encoded string with the JSON-serialized Enumerator object, or an empty JSON object if there was a problem
Example usage:
import LibpfUserPython, json LibpfUserPython.initializeKernel() error = LibpfUserPython.intPointer() error.assign(1) je = LibpfUserPython.jsonEnumerator('feedType', error) if (error.value() == 0): e = json.loads(je) print('feedType = ', e)
Sample returned JSON:
{ "name": "feedType", "description": "Feed type selection - It selects the fluid composition to be pasteurization", "options": [ { "name": "milkWhole", "description": "Milk, whole, 3.25% milkfat, with added vitamin D" }, { "name": "chocolateIceCream", "description": "Ice cream, soft serve, chocolate" }, { "name": "eggWhole", "description": "Egg, whole, raw, fresh" }, { "name": "vanillaFatFreeIceCream", "description": "Ice creams, BREYERS, 98% Fat Free Vanilla" }, { "name": "user", "description": "(default) user specified defaults to pure water" } ] }
jsonListTypes
Queries the available types
Parameters:
- error: an intPointer object
Returns UTF-8 encoded string with the JSON-serialized list of TypeDescriptor objects, or an empty JSON object if there was a problem.
Example usage:
import LibpfUserPython, json LibpfUserPython.initializeKernel() error = LibpfUserPython.intPointer() error.assign(1) jlt = LibpfUserPython.jsonListTypes(error) if (error.value() == 0): lt = json.loads(jlt) print('listTypes = ', lt)
Sample returned JSON:
{ "types": [ { "name": "chiller", "description": "packaged chiller unit", "category": "flowsheet", "instantiable": true, "integerOptions": [ { "name": "stages", "value": 2, "min": 1, "max": 10 } ], "stringOptions": [ { "name": "type", "value": "scroll", "enumerator": "compressorType" } ] } ] }
jsonTypeDescriptor
Queries a specific type
Parameters:
-
name the name of the type to query
-
error: an intPointer object
Returns UTF-8 encoded string with the JSON-serialized TypeDescriptor object, or an empty JSON object if there was a problem
Example usage:
import LibpfUserPython, json LibpfUserPython.initializeKernel() error = LibpfUserPython.intPointer() error.assign(1) jtd = LibpfUserPython.jsonTypeDescriptor('Pasteur', error) if (error.value() == 0): td = json.loads(jtd) print('Paster = ', td)
Sample returned JSON:
{ "name": "chiller", "description": "packaged chiller unit", "category": "flowsheet", "instantiable": true, "integerOptions": [ { "name": "stages", "value": 2, "min": 1, "max": 10 } ], "stringOptions": [ { "name": "type", "value": "scroll", "enumerator": "compressorType" } ] }
license
Returns the kernel license as an UTF-8 encoded string
Example usage:
import LibpfUserPython, json print('license = ', LibpfUserPython.license())
listEnumerators
Queries the available enumerators
Parameters
- (output) error: an intPointer object; on exit contains an error code; the code is 0 if the operation was successful; to obtain more descriptive error codes, use the LibpfUserPython.errorMessage function to convert the code in a human-readable description
Returns a list of the available enumerators as strings.
Example usage:
import LibpfUserPython, json LibpfUserPython.initializeKernel() error = LibpfUserPython.intPointer() error.assign(1) le = LibpfUserPython.listEnumerators(error) if (error.value() == 0): for e in le: print(json = json + '"' + enumerator + '"')
name
Returns the kernel name as an UTF-8 encoded string
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() n = LibpfUserPython.name() print('kernel name = ', n)
purge
Remove all existing case instances
Returns the error code; the code is 0 if the operation was successful; to obtain more descriptive error codes, use the LibpfUserPython.errorMessage function to convert the code in a human-readable description
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() error = LibpfUserPython.purge()
remove
Remove an existing case instance
Parameters:
- handle: the existing case handle
Returns error code; the code is 0 if the operation was successful; to obtain more descriptive error codes, use the LibpfUserPython.errorMessage function to convert the code in a human-readable description
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') error = LibpfUserPython.remove(ch);
setVerbosityGlobal
Sets the global verbosity level:
-
0 for high-priority messages
-
1 for informational messages
-
2 for function and member function entry/exit
-
3 for detailed diagnostic
Parameters:
- verbosity: global verbosity level
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() LibpfUserPython.setVerbosityGlobal(3)
uninitializeKernel
Frees all resources acquired by initializeKernel.
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() LibpfUserPython.uninitializeKernel()
version
Returns the kernel version as an UTF-8 encoded string
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() v = LibpfUserPython.version() print('kernel version = ', v)
Case API
The capabilities of the Case API can be queried with the command:
dir(LibpfUserPython.Case)
constructor
Establishes a connection to the case
Parameters:
- handle: case handle
If the handle is invalid or there is an error, the Case is instantiated in the invalid state.
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch)
calculateSync
Synchronously calculate the case.
Returns the error code.
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) error = c.calculateSync()
errorMessage
Parameters:
- error: one of the values of the ErrorCode enum
Returns the textual representation of the error
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) error = c.calculateSync() print('error', error.value(), ' message', c.errorMessage(error.value()))
exportDataBase
Export database snapshot of all data related to the case instance in sqlite3 format
Parameters:
- sqliteFileName: full path to the sqlite database binary format file that should be written; if the file exists, it will be overwritten
Returns the error code.
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) error = c.exportDataBase('0.sqlite')
exportSvg
Export to SVG format, saving a file handle.svg
Parameters:
- tiny: if true, print the layout to SVG Tiny 1.1 format, else to Full SVG 1.1 format
Returns the error code.
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) error = c.exportSvg('0.svg')
exportTxt
Export text file report of all data related to the case instance
Parameters:
- txtFileName: full path to the text format file that should be written; if the file exists, it will be overwritten
Returns the error code.
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) error = c.exportTxt('0.txt')
exportXml
Export to XML: recursively print all Quantities, Strings and Integers to xml files in the directory dir
Parameters:
- dir: the directory to save files to
Returns the error code.
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) error = c.exportXml('0')
get
Query the value of a Quantity
Parameters:
-
path: the string full path to the variable, i.e. S01:Tphase.ndot
-
error: an intPointer object
Returns the current value in SI units
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) error = LibpfUserPython.intPointer() error.assign(1) value = c.get('S01:Tphase.ndot', error)
getInteger
Query the value of an Integer
Parameters:
-
path: the string full path to the variable, i.e. C101.nStage
-
error: an intPointer object
Returns the current value
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) error = LibpfUserPython.intPointer() error.assign(1) value = c.getInteger('C101.nStage', error)
getString
Query the value of a String
Parameters:
-
path: the string full path to the variable, i.e. S01.flashoption
-
error: an intPointer object
Returns the current value
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) error = LibpfUserPython.intPointer() error.assign(1) value = c.getString('S01.flashoption', error)
homotopySync
Synchronously perform a homotopy calculation of the case.
Parameters:
- homotopyInput: UTF-8 encoded, JSON-serialized HomotopyInput object with the information on the changes to be applied
Returns the error code.
Example usage:
import LibpfUserPython, json LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) cv = [ { u'variable': u'S01.T', u'start': 298.15, u'end': 300 }, { u'variable': u'RX:reactions[0].z', u'start': 0.9, u'end': 0.95 } ] hi = { u'type': u'SaltPepper', u'id': int(ch.toString()), u'points': 20, u'controlled': cv } jhi = json.dumps(hi) error = c.homotopySync(jhi)
isValid
Returns true if the Case is valid
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) print(c.isValid())
sensitivitySync
Synchronously perform a sensitivity calculation of the case.
Parameters:
- sensitivityInput: UTF-8 encoded, JSON-serialized SensitivityInput object with the information on the sensitivity to perform
Returns the error code.
Example usage:
import LibpfUserPython, json LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) cv = [ { u'variable': u'FILTER.outSplit[0][2]', u'label': u'Filter efficiency', u'unit': u'', u'start': 0.9, u'end': 0.99, u'points': 3 }, { u'variable': u'RX:reactions[0].z', u'label': u'Product conversion', u'unit': u'', u'start': 0.9, u'end': 0.95, u'points': 3 }, { u'variable': u'SPL.outSplit[0]', u'label': u'Purge fraction', u'unit': u'', u'start': 0.8, u'end': 0.98, u'points': 3 } ] mv = [ { u'variable': u'S01.T', u'label': u'temperature', u'unit': u'Ku' }, { u'variable': u'S01:Tphase.mdot', u'label': u'mass flow', u'unit': u'kg/h' } ] si = { u'type': u'SaltPepper', u'name': u'aaaaaaaaa', u'order': u'boustrophedon', u'startinground': 0, u'timeout': 0.0, u'controlled': cv, u'manipulated': mv } jsi = json.dumps(si) error = c.sensitivitySync(jsi)
set
Set one or more quantities
Parameters:
- homotopyInput: UTF-8 encoded, JSON-serialized HomotopyInput object with the information on the changes to be applied; not all fields must be filled in, basically what is required is the controlled array be non-empty and each element of the controlled array be a dictionary with at least two keys, value and end
Returns the error code.
Example usage:
import LibpfUserPython, json LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) cv = [ { u'variable': u'S01.T', u'end': 300 }, { u'variable': u'RX:reactions[0].z', u'end': 0.95 } ] hi = { u'controlled': cv } jhi = json.dumps(hi) error = c.set(jhi)
setDescription
Change the description of the instance
Parameters
- desc UTF-8 encoded string with the new description
Returns the error code.
Example usage:
import LibpfUserPython, json LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) error = c.setDescrition('test case')
setTag
Change the tag of the instance
Parameters
- tag: UTF-8 encoded string with the new tag
Returns the error code.
Example usage:
import LibpfUserPython, json LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') c = LibpfUserPython.Case(ch) error = c.setTag('test')
Handle API
The capabilities of the handle API can be queried with the command:
dir(LibpfUserPython.Handle)
constructor
Instantiates the Handle
Parameters:
- value: a string representation of the Handle
If the value is invalid the Handle is instantiated in the invalid state.
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0')
isValid
Returns true if the Handle is valid
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') print(ch.isValid())
toString
Returns a string representation of the Handle
Example usage:
import LibpfUserPython LibpfUserPython.initializeKernel() ch = LibpfUserPython.Handle('0') print(ch.toString())