Tutorial 3: Tutorial 3: Accessing and modifying model data

This tutorial demonstrates how to get and set values of objects based on their topological key (tk).

SIR 3S Installation

[1]:
SIR3S_SIRGRAF_DIR = r"C:\3S\SIR 3S Entwicklung\SirGraf-90-15-00-16_Quebec_x64" #change to local path

Imports

Note: The SIR 3S Toolkit requires the Sir3S_Toolkit.dll included in SIR 3S installations (version Quebec and higher).

[2]:
import sir3stoolkit

The core of sir3stoolkit is a Python wrapper around basic functionality of SIR 3S, offering a low-level access to the creation, modification and simulation of SIR 3S models. In the future pure python subpackages may be added.

[3]:
from sir3stoolkit.core import wrapper
[4]:
sir3stoolkit
[4]:
<module 'sir3stoolkit' from 'C:\\Users\\aUsername\\3S\\sir3stoolkit\\src\\sir3stoolkit\\__init__.py'>

The wrapper package has to be initialized with reference to a SIR 3S (SirGraf) installation.

[5]:
wrapper.Initialize_Toolkit(SIR3S_SIRGRAF_DIR)

Initialization

The SIR 3S Toolkit contains two classes: SIR3S_Model (model and data) and SIR3S_View (depiction in SIR Graf). All SIR 3S Toolkit functionality is accessed via the methods of these classes.

[6]:
s3s = wrapper.SIR3S_Model()
Initialization complete
[7]:
s3s_view = wrapper.SIR3S_View()
Initialization complete

Open Model

[8]:
dbFilePath=r"Tutorial3_Model.db3"
[9]:
s3s.OpenModel(dbName=dbFilePath,
              providerType=s3s.ProviderTypes.SQLite,
              Mid="M-1-0-1",
              saveCurrentlyOpenModel=False,
              namedInstance="",
              userID="",
              password="")
Model is open for further operation

This model has been prepared and contains two nodes connected by a pipe.

Get Values

Our goal is to find out what the type of the nodes is (PKON, QKON, etc.), and which length and roughness the pipe has.

The GetValue() function requires a tk to the object and the internal SIR 3S attribute name of the value we want to obtain. This guide will walk you through how to obtain those.

SIR 3S object types

First, we need to obtain the internal SIR 3S object types to later pass to our function for obtaining the attribute names.

You can use dir() to get an overview over the different object types existing in SIR 3S.

[10]:
object_types = [item for item in dir(s3s.ObjectTypes) if not (item.startswith('__') and item.endswith('__'))]
print(object_types)
['AGSN_HydraulicProfile', 'AirVessel', 'Arrow', 'Atmosphere', 'BlockConnectionNode', 'CalcPari', 'CharacteristicLossTable', 'CharacteristicLossTable_Row', 'Circle', 'Compressor', 'CompressorTable', 'CompressorTable_Row', 'ControlEngineeringNexus', 'ControlMode', 'ControlPointTable', 'ControlPointTable_Row', 'ControlValve', 'ControlVariableConverter', 'ControlVariableConverterRSTE', 'CrossSectionTable', 'CrossSectionTable_Row', 'DPGR_DPKT_DatapointDpgrConnection', 'DPGR_DataPointGroup', 'DPKT_Datapoint', 'DamageRatesTable', 'DamageRatesTable_Row', 'DeadTimeElement', 'Demand', 'DifferentialRegulator', 'DirectionalArrow', 'DistrictHeatingConsumer', 'DistrictHeatingFeeder', 'Divider', 'DriveEfficiencyTable', 'DriveEfficiencyTable_Row', 'DrivePowerTable', 'DrivePowerTable_Row', 'EBES_FeederGroups', 'EfficiencyConverterTable', 'EfficiencyConverterTable_Row', 'ElementQuery', 'EnergyRecoveryTable', 'EnergyRecoveryTable_Row', 'EnvironmentTemp', 'FWBZ_DistrictHeatingReferenceValues', 'FlapValve', 'FlowControlUnit', 'FluidQualityParamSet', 'FluidQualityParamSet_OS', 'FluidThermalPropertyGroup', 'FreeDuct', 'FunctionGenerator', 'FunctionTable', 'FunctionTable_Row', 'GasComponent', 'GasMixture', 'GeneralSection', 'Gravitation', 'HeatExchanger', 'HeatFeederConsumerStation', 'HeaterCooler', 'Histeresis', 'House', 'Hydrant', 'Integrator', 'LAYR_Layer', 'LoadFactorTable', 'LoadFactorTable_Row', 'LogicalComparison', 'LogicalStorage', 'MeasuredVariableTable', 'MeasuredVariableTable_Row', 'MinMaxSelection', 'Multiplier', 'NetValve', 'Node', 'NonReturnValvesTable', 'NonReturnValvesTable_Row', 'NumericalDisplay', 'ObjectContainerSymbol', 'OpenContainer', 'Oval', 'PARZ_TransientCalculationParameters', 'PhaseSeparation', 'PidController', 'Pipe', 'PipeGroup', 'PipeTable', 'PipeTable_Row', 'PipeVertex', 'Polygon', 'Polyline', 'PressureRegulator', 'PressureZone', 'Pt1Controller', 'Pump', 'PumpCharTable', 'PumpCharTable_Row', 'PumpGroup', 'PumpOfPumpGroup', 'PumpSpeedTable', 'PumpSpeedTable_Row', 'RART_ControlMode', 'REGP_ControlParameters', 'RMES_DPTS_RmesInternalDataPoint', 'Rectangle', 'RegulatorsTable', 'RegulatorsTable_Row', 'ReturnTemperaturTable', 'ReturnTemperaturTable_Row', 'RoundRectangle', 'SIRGRAF', 'SPLZ_TimeSeries', 'SafetyValve', 'SetpointDevice', 'SolarCollector', 'StandPipe', 'Street', 'SummingPoint', 'SwitchInBlock', 'TemperatureTable', 'TemperatureTable_Row', 'Text', 'ThermalOutputTable', 'ThermalOutputTable_Row', 'ThermophysPropTable', 'ThermophysPropTable_Row', 'TransitionSymbol', 'Transmitter', 'TransportVariable', 'USCH_UserDefinedProperties', 'Unknown', 'VARA_ColorScale', 'VARA_ROWS_WidthOrScale', 'VRCT_ViewRectangle', 'Valve', 'ValveLiftTable', 'ValveLiftTable_Row', 'VarFlowTable', 'VarFlowTable_Row', 'VarPressureTable', 'VarPressureTable_Row', 'VentOpenCloseTable', 'VentOpenCloseTable_Row', 'VentValve', 'VentilatedPressureAirVessel', 'WBLZ_ThermalBalance', 'WeatherDataTable', 'WeatherDataTable_Row']

In our simple example we are only interested in the object types of nodes and pipes.

[11]:
node_type=s3s.ObjectTypes.Node
[12]:
pipe_type=s3s.ObjectTypes.Pipe

GetTksofElementType()

Now, we obtain the tks of the nodes and pipes in this model.

We use GetTksofElementType() to create a list of all node tks in the model.

[13]:
nodes=s3s.GetTksofElementType(ElementType=node_type)
[14]:
print(nodes)
['4921762654790163024', '5483574590487309449']

If you don’t want to predefine your element type you can also just pass it like done below

[15]:
pipes=s3s.GetTksofElementType(ElementType=s3s.ObjectTypes.Pipe)
[16]:
print(pipes)
['4614473539164226343']

GetTkFromIDReference()

We can use the GetTkFromIDReference() function, in case we have an ID reference value of a certain element given and want to get its tk.

The nodes in our model have ID reference “A” and “B”.

[17]:
s3s.GetTkFromIDReference(IdRef="A", object_type=s3s.ObjectTypes.Node)
[17]:
'4921762654790163024'
[18]:
s3s.GetTkFromIDReference(IdRef="A", object_type=s3s.ObjectTypes.Node)
[18]:
'4921762654790163024'

We can see that they are the same tks we got from GetTksofElementType().

GetObjectTypeof_Key()

If we already have a tk/pk of an element we can use the GetObjectTypeof_Key() function to obtain its datatype.

[19]:
print(s3s.GetObjectTypeof_Key(Key=nodes[0]))
ObjectTypes.Node

GetPropertiesofElementType()

Now, we obtain the internal SIR 3S attribute names. These will be necessary for our value query.

We use GetPropertiesofElementType() to create a list of all properties of nodes and pipes.

[20]:
node_properties=s3s.GetPropertiesofElementType(ElementType=node_type)
[21]:
print(node_properties)
['Name', 'Ktyp', 'Zkor', 'QmEin', 'Lfakt', 'Fkpzon', 'Fkfstf', 'Fkutmp', 'Fkfqps', 'Fkcont', 'Fk2lknot', 'Beschreibung', 'Idreferenz', 'Iplanung', 'Kvr', 'Qakt', 'Xkor', 'Ykor', 'NodeNamePosition', 'ShowNodeName', 'KvrKlartext', 'NumberOfVERB', 'HasBlockConnection', 'Tk', 'Pk', 'IsMarked', 'InVariant', 'GeometriesDiffer', 'SymbolFactor', 'bz.Drakonz', 'bz.Fk', 'bz.Fkpvar', 'bz.Fkqvar', 'bz.Fklfkt', 'bz.PhEin', 'bz.Tm', 'bz.Te', 'bz.PhMin']
[22]:
pipe_properties=s3s.GetPropertiesofElementType(ElementType=pipe_type)
[23]:
print(pipe_properties)
['Name', 'FkdtroRowd', 'Fkltgr', 'Fkstrasse', 'L', 'Lzu', 'Rau', 'Jlambs', 'Lambda0', 'Zein', 'Zaus', 'Zuml', 'Asoll', 'Indschall', 'Baujahr', 'Hal', 'Fkcont', 'Fk2lrohr', 'Beschreibung', 'Idreferenz', 'Iplanung', 'Kvr', 'LineWidthMM', 'DottedLine', 'DN', 'Di', 'KvrKlartext', 'HasClosedNSCHs', 'Tk', 'Pk', 'IsMarked', 'InVariant', 'Xkor', 'Ykor', 'GeometriesDiffer', 'bz.Fk', 'bz.Qsvb', 'bz.Irtrenn', 'bz.Leckstatus', 'bz.Leckstart', 'bz.Leckend', 'bz.Leckort', 'bz.Leckmenge', 'bz.Imptnz', 'bz.Zvlimptnz', 'bz.Kantenzv', 'bz.ITrennWithNSCH']

GetValue()

Now, we can access values of indiviudal nodes with a corresponding tk.

We use GetValue for such individual value query.

Node 1

As tk we just use the first tk from our nodes list.

[24]:
node1_ktyp=s3s.GetValue(Tk=nodes[0], propertyName='Ktyp')
[25]:
print(node1_ktyp)
('PKON', 'string')

As you can see it returns a tuple value consisting of the actual value (here: ‘PKON’) of the attribute and the attribute data type.

You can access the indiviudal components as follows.

[26]:
actual_value=node1_ktyp[0]
[27]:
print(actual_value)
PKON
[28]:
data_type=node1_ktyp[1]
[29]:
print(data_type)
string

Node 2

Now we use the second tk from our nodes list.

[30]:
node2_ktyp_actual_value=s3s.GetValue(Tk=nodes[1], propertyName='Ktyp')[0]
[31]:
print(node2_ktyp_actual_value)
QKON

Pipe

For the pipe we will just ignore the datatypes of the attributes and just access the value.

[32]:
print(pipe_properties)
['Name', 'FkdtroRowd', 'Fkltgr', 'Fkstrasse', 'L', 'Lzu', 'Rau', 'Jlambs', 'Lambda0', 'Zein', 'Zaus', 'Zuml', 'Asoll', 'Indschall', 'Baujahr', 'Hal', 'Fkcont', 'Fk2lrohr', 'Beschreibung', 'Idreferenz', 'Iplanung', 'Kvr', 'LineWidthMM', 'DottedLine', 'DN', 'Di', 'KvrKlartext', 'HasClosedNSCHs', 'Tk', 'Pk', 'IsMarked', 'InVariant', 'Xkor', 'Ykor', 'GeometriesDiffer', 'bz.Fk', 'bz.Qsvb', 'bz.Irtrenn', 'bz.Leckstatus', 'bz.Leckstart', 'bz.Leckend', 'bz.Leckort', 'bz.Leckmenge', 'bz.Imptnz', 'bz.Zvlimptnz', 'bz.Kantenzv', 'bz.ITrennWithNSCH']
[33]:
pipe_length=s3s.GetValue(Tk=pipes[0], propertyName='L')[0]
[34]:
print(pipe_length)
141,4214
[35]:
pipe_roughness=s3s.GetValue(Tk=pipes[0], propertyName='RAU')[0]
[36]:
print(pipe_roughness)
0,25

GetGeometryInformation()

We can use the GetGeometryInformation() function to obtain the geometries of the objects based on their tk.

[37]:
for node in nodes:
    print(s3s.GetGeometryInformation(Tk=node))
POINT (0 0)
POINT (100 100)
[38]:
s3s.GetGeometryInformation(Tk=pipes[0])
[38]:
'LINESTRING (0 0, 100 100)'

Set Values

SetValues()

You can use the SetValue() function to change non-result non-geometry values of objects based on their tk.

Node

[39]:
print(s3s.GetValue(Tk=nodes[0], propertyName='Ktyp'))
('PKON', 'string')

Here we change a node from PKON to QKON

[40]:
s3s.SetValue(nodes[0], propertyName='Ktyp', Value='QKON')
Value is set
[41]:
print(s3s.GetValue(Tk=nodes[0], propertyName='Ktyp'))
('QKON', 'string')

Pipe

[42]:
print(s3s.GetValue(Tk=pipes[0], propertyName='RAU')[0])
0,25

Here we change the roughness of a pipe from value 3 to 6.

[43]:
s3s.SetValue(Tk=pipes[0], propertyName='RAU', Value='6')
Value is set
[44]:
print(s3s.GetValue(Tk=pipes[0], propertyName='RAU')[0])
6

SetGeometryInformation()

You can use the SetGeometryInformation() function to change non-result geometry values of objects based on their tk. The geometry has to be given in Wkt format.

Let’s move the simple network 100 into positive x-direction.

Node

[45]:
s3s.SetGeometryInformation(Tk=nodes[0], Wkt="POINT (100 0)")
Geometry Information is set correctly
[45]:
True
[46]:
s3s.SetGeometryInformation(Tk=nodes[1], Wkt="POINT (200 100)")
Geometry Information is set correctly
[46]:
True

Pipe

[47]:
s3s.SetGeometryInformation(Tk=pipes[0], Wkt="LINESTRING (100 0, 200 100)")
Geometry Information is set correctly
[47]:
True

Save Changes

If you want your changes made to the model to be saved use the SaveChanges() function.

[48]:
#s3s.SaveChanges()

Alternatively, the user can save the changes when closing the model using the CloseModel() function.

[49]:
#s3s.CloseModel(saveChangesBeforeClosing=True)

Now you are able to access values from SIR 3S objects based on their tk, but using the above methods only works for non-result values.

Next: Tutorial 4: Accessing simulation results