Skip to content

Commit 4d50af3

Browse files
author
Lars Ivar Hatledal
committed
Add FMPy state integration test #62
1 parent f343412 commit 4d50af3

File tree

1 file changed

+73
-18
lines changed

1 file changed

+73
-18
lines changed

pythonfmu/tests/test_integration.py

+73-18
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
"pyfmi", reason="pyfmi is required for testing the produced FMU"
1111
)
1212

13-
1413
DEMO = "pythonslave.py"
1514

1615

@@ -51,7 +50,7 @@ def test_integration_reset(tmp_path):
5150

5251

5352
@pytest.mark.integration
54-
def test_integration_state(tmp_path):
53+
def test_integration_get_state(tmp_path):
5554
script_file = Path(__file__).parent / DEMO
5655

5756
FmuBuilder.build_FMU(script_file, dest=tmp_path, needsExecutionTool="false", canGetAndSetFMUstate="true")
@@ -69,6 +68,7 @@ def step(model):
6968
t += dt
7069

7170
model = pyfmi.load_fmu(str(fmu))
71+
model.initialize()
7272
step(model)
7373
state = model.get_fmu_state()
7474
assert model.get_real([vr])[0] == pytest.approx(dt, rel=1e-7)
@@ -82,23 +82,79 @@ def step(model):
8282

8383

8484
@pytest.mark.integration
85-
def test_integration_get(tmp_path):
85+
def test_integration_get_serialize_state(tmp_path):
86+
fmpy = pytest.importorskip(
87+
"fmpy", reason="fmpy is not available for testing the produced FMU"
88+
)
89+
90+
script_file = Path(__file__).parent / DEMO
91+
92+
FmuBuilder.build_FMU(script_file, dest=tmp_path)
93+
94+
fmu = tmp_path / "PythonSlave.fmu"
95+
assert fmu.exists()
96+
97+
model_description = fmpy.read_model_description(fmu)
98+
99+
unzipdir = fmpy.extract(fmu)
100+
101+
model = fmpy.fmi2.FMU2Slave(
102+
guid=model_description.guid,
103+
unzipDirectory=unzipdir,
104+
modelIdentifier=model_description.coSimulation.modelIdentifier,
105+
instanceName='instance1')
106+
107+
vr = 5 # realOut
108+
t = 0.0
109+
dt = 0.1
86110

111+
def step(model):
112+
nonlocal t
113+
model.doStep(t, dt)
114+
t += dt
115+
116+
model.instantiate()
117+
model.setupExperiment()
118+
model.enterInitializationMode()
119+
model.exitInitializationMode()
120+
121+
step(model)
122+
state = model.getFMUstate()
123+
assert model.getReal([vr])[0] == pytest.approx(dt, rel=1e-7)
124+
step(model)
125+
assert model.getReal([vr])[0] == pytest.approx(dt * 2, rel=1e-7)
126+
model.setFMUstate(state)
127+
assert model.getReal([vr])[0] == pytest.approx(dt, rel=1e-7)
128+
step(model)
129+
assert model.getReal([vr])[0] == pytest.approx(dt * 3, rel=1e-7)
130+
131+
serialize_fm_ustate = model.serializeFMUstate(state)
132+
model.freeFMUstate(state)
133+
de_serialize_fm_ustate = model.deSerializeFMUstate(serialize_fm_ustate)
134+
model.setFMUstate(de_serialize_fm_ustate)
135+
assert model.getReal([vr])[0] == pytest.approx(dt, rel=1e-7)
136+
137+
model.freeFMUstate(de_serialize_fm_ustate)
138+
model.terminate()
139+
140+
141+
@pytest.mark.integration
142+
def test_integration_get(tmp_path):
87143
script_file = Path(__file__).parent / DEMO
88144

89145
FmuBuilder.build_FMU(script_file, dest=tmp_path, needsExecutionTool="false")
90146

91147
fmu = tmp_path / "PythonSlave.fmu"
92148
assert fmu.exists()
93149
model = pyfmi.load_fmu(str(fmu))
94-
150+
95151
to_test = {
96152
"intParam": 42,
97153
"intOut": 23,
98154
"realOut": 3.0,
99155
"booleanVariable": True,
100156
"stringVariable": "Hello World!",
101-
"realIn": 2./3.,
157+
"realIn": 2. / 3.,
102158
"booleanParameter": False,
103159
"stringParameter": "dog"
104160
}
@@ -107,33 +163,32 @@ def test_integration_get(tmp_path):
107163
for key, value in to_test.items():
108164
var = variables[key]
109165
if var.type == pyfmi.fmi.FMI2_INTEGER:
110-
model_value = model.get_integer([var.value_reference,])[0]
166+
model_value = model.get_integer([var.value_reference, ])[0]
111167
elif var.type == pyfmi.fmi.FMI2_REAL:
112-
model_value = model.get_real([var.value_reference,])[0]
168+
model_value = model.get_real([var.value_reference, ])[0]
113169
elif var.type == pyfmi.fmi.FMI2_BOOLEAN:
114-
model_value = model.get_boolean([var.value_reference,])[0]
170+
model_value = model.get_boolean([var.value_reference, ])[0]
115171
elif var.type == pyfmi.fmi.FMI2_STRING:
116-
model_value = model.get_string([var.value_reference,])[0]
172+
model_value = model.get_string([var.value_reference, ])[0]
117173
else:
118174
pytest.xfail("Unsupported type")
119-
175+
120176
assert model_value == value
121177

122178

123179
@pytest.mark.integration
124180
def test_integration_set(tmp_path):
125-
126181
script_file = Path(__file__).parent / DEMO
127182

128183
FmuBuilder.build_FMU(script_file, dest=tmp_path, needsExecutionTool="false")
129184

130185
fmu = tmp_path / "PythonSlave.fmu"
131186
assert fmu.exists()
132187
model = pyfmi.load_fmu(str(fmu))
133-
188+
134189
to_test = {
135190
"intParam": 20,
136-
"realIn": 1./3.,
191+
"realIn": 1. / 3.,
137192
"booleanParameter": True,
138193
"stringParameter": "cat"
139194
}
@@ -143,19 +198,19 @@ def test_integration_set(tmp_path):
143198
var = variables[key]
144199
if var.type == pyfmi.fmi.FMI2_INTEGER:
145200
model.set_integer([var.value_reference, ], [value, ])
146-
model_value = model.get_integer([var.value_reference,])[0]
201+
model_value = model.get_integer([var.value_reference, ])[0]
147202
elif var.type == pyfmi.fmi.FMI2_REAL:
148203
model.set_real([var.value_reference, ], [value, ])
149-
model_value = model.get_real([var.value_reference,])[0]
204+
model_value = model.get_real([var.value_reference, ])[0]
150205
elif var.type == pyfmi.fmi.FMI2_BOOLEAN:
151206
model.set_boolean([var.value_reference, ], [value, ])
152-
model_value = model.get_boolean([var.value_reference,])[0]
207+
model_value = model.get_boolean([var.value_reference, ])[0]
153208
elif var.type == pyfmi.fmi.FMI2_STRING:
154209
model.set_string([var.value_reference, ], [value, ])
155-
model_value = model.get_string([var.value_reference,])[0]
210+
model_value = model.get_string([var.value_reference, ])[0]
156211
else:
157212
pytest.xfail("Unsupported type")
158-
213+
159214
assert model_value == value
160215

161216

0 commit comments

Comments
 (0)