Buildings.Utilities.IO.Python36

Package to call Python functions

Information

This package contains blocks and functions that embed Python 3.6 in Modelica. Data can be sent to Python functions and received from Python functions. This allows for example data analysis in Python as part of a Modelica model, or data exchange as part of a hardware-in-the-loop simulation in which Python is used to communicate with hardware.

See Buildings.Utilities.IO.Python36.UsersGuide for instruction.

Extends from Modelica.Icons.VariantsPackage (Icon for package containing variants).

Package Content

Name Description
Buildings.Utilities.IO.Python36.UsersGuide UsersGuide User's Guide
Buildings.Utilities.IO.Python36.Real_Real Real_Real Block that exchanges a vector of real values with a Python function
Buildings.Utilities.IO.Python36.Functions Functions Package with functions that call Python
Buildings.Utilities.IO.Python36.Examples Examples Collection of models that illustrate model use and test models

Buildings.Utilities.IO.Python36.Real_Real Buildings.Utilities.IO.Python36.Real_Real

Block that exchanges a vector of real values with a Python function

Buildings.Utilities.IO.Python36.Real_Real

Information

Block that exchanges data with a Python function that does not need to pass an object from one call to the next.

For each element in the input vector uR[nDblWri], the value of the flag flaDblWri[nDblWri] determines whether the current value, the average over the sampling interval or the integral over the sampling interval is sent to Python. The following three options are allowed:


flaDblWri[i] Value sent to Python
0 Current value of uR[i]
1 Average value of uR[i] over the sampling interval
2 Integral of uR[i] over the sampling interval

If the function needs to pass an object from one invocation to the next, set passPythonObject = true. Otherwise, leave it at its default value passPythonObject = false.

Extends from Modelica.Blocks.Interfaces.DiscreteBlock (Base class of discrete control blocks).

Parameters

TypeNameDefaultDescription
TimesamplePeriod Sample period of component [s]
TimestartTime0First sample time instant [s]
StringmoduleName Name of the python module that contains the function
StringfunctionNamemoduleNameName of the python function
IntegernDblWrinDblWri(min=1)Number of double values to write to Python
IntegernDblReanDblRea(min=1)Number of double values to be read from the Python
Integerflag0Flag for double values (0: use current value, 1: use average over interval, 2: use integral over interval)
BooleanpassPythonObjectfalseSet to true if the Python function returns and receives an object, see User's Guide

Connectors

TypeNameDescription
input RealInputuR[nDblWri]Real inputs to be sent to Python
output RealOutputyR[nDblRea]Real outputs received from Python

Modelica definition

model Real_Real "Block that exchanges a vector of real values with a Python function" extends Modelica.Blocks.Interfaces.DiscreteBlock( startTime=0, firstTrigger(fixed=true, start=false)); parameter String moduleName "Name of the python module that contains the function"; parameter String functionName=moduleName "Name of the python function"; parameter Integer nDblWri(min=1) "Number of double values to write to Python"; parameter Integer nDblRea(min=1) "Number of double values to be read from the Python"; parameter Integer flag = 0 "Flag for double values (0: use current value, 1: use average over interval, 2: use integral over interval)"; final parameter Integer flaDblWri[nDblWri] = fill(flag, nDblWri) "Flag for double values (0: use current value, 1: use average over interval, 2: use integral over interval)"; parameter Boolean passPythonObject = false "Set to true if the Python function returns and receives an object, see User's Guide"; Modelica.Blocks.Interfaces.RealInput uR[nDblWri] "Real inputs to be sent to Python"; Modelica.Blocks.Interfaces.RealOutput yR[nDblRea] "Real outputs received from Python"; Real uRInt[nDblWri] "Value of integral"; Real uRIntPre[nDblWri] "Value of integral at previous sampling instance"; Real uRWri[nDblWri] "Value to be sent to Python"; Real uRWri_temp[nDblWri] "Internal value"; protected Buildings.Utilities.IO.Python36.Functions.BaseClasses.PythonObject pytObj= Buildings.Utilities.IO.Python36.Functions.BaseClasses.PythonObject() "Python object, used to avoid instantiating Python in each call, and to pass python object if passPythonObject=true"; initial equation uRWri = pre(uR); uRWri_temp = pre(uR); uRInt = zeros(nDblWri); uRIntPre = zeros(nDblWri); for i in 1:nDblWri loop assert(flaDblWri[i]>=0 and flaDblWri[i]<=2, "Parameter flaDblWri out of range for " + String(i) + "-th component."); end for; // The assignment of yR avoids the warning // "initial conditions for variables of type Real are not fully specified". // At startTime, the sampleTrigger is true and hence this value will // be overwritten. yR = zeros(nDblRea); equation for i in 1:nDblWri loop der(uRInt[i]) = if (flaDblWri[i] > 0) then uR[i] else 0; end for; when {sampleTrigger} then // Compute value that will be sent to Python for i in 1:nDblWri loop if (flaDblWri[i] == 0) then uRWri_temp[i] = pre(uR[i]); uRWri[i] = pre(uR[i]); // Send the current value. else if (time > 0) then uRWri_temp[i] = uRInt[i] - pre(uRIntPre[i]); // Integral over the sampling interval if (flaDblWri[i] == 2) then uRWri[i] = uRWri_temp[i]; else uRWri[i] = uRWri_temp[i]/samplePeriod; // Average value over the sampling interval end if; else uRWri[i] = pre(uR[i]); uRWri_temp[i] = pre(uR[i]); end if; end if; end for; // Exchange data yR = Buildings.Utilities.IO.Python36.Functions.exchange( moduleName=moduleName, functionName=functionName, dblWri=uRWri, intWri={0}, nDblWri=nDblWri, nDblRea=nDblRea, nIntWri=0, nIntRea=0, nStrWri=0, strWri={""}, pytObj=pytObj, passPythonObject = passPythonObject); // Store current value of integral uRIntPre= uRInt; end when; end Real_Real;