pythonfmu3 0.3.2__py3-none-any.whl → 0.3.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pythonfmu3/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.3.2"
1
+ __version__ = "0.3.4"
pythonfmu3/builder.py CHANGED
@@ -13,7 +13,7 @@ from typing import Iterable, Optional, Tuple, Union
13
13
  from xml.dom.minidom import parseString
14
14
  from xml.etree.ElementTree import Element, SubElement, tostring
15
15
  from .osutil import get_lib_extension, get_platform
16
- from .fmi3slave import FMI3_MODEL_OPTIONS, Fmi3Slave, Fmi3SlaveBase
16
+ from .fmi3slave import FMI3_MODEL_OPTIONS_COMMON, FMI3_MODEL_OPTIONS_COSIM, FMI3_MODEL_OPTIONS_MX, Fmi3Slave, Fmi3SlaveBase
17
17
 
18
18
  FilePath = Union[str, Path]
19
19
  HERE = Path(__file__).parent
@@ -137,16 +137,20 @@ class FmuBuilder:
137
137
  dest_file = dest / f"{model_identifier}.fmu"
138
138
 
139
139
  type_node = xml.find("CoSimulation")
140
- option_names = [opt.name for opt in FMI3_MODEL_OPTIONS]
141
- if type_node:
140
+ option_names = [opt.name for opt in FMI3_MODEL_OPTIONS_COMMON]
141
+ cosim_option_names = option_names.copy()
142
+ cosim_option_names.extend(opt.name for opt in FMI3_MODEL_OPTIONS_COSIM)
143
+ if type_node is not None:
142
144
  for option, value in options.items():
143
- if option in option_names:
145
+ if option in cosim_option_names:
144
146
  type_node.set(option, str(value).lower())
145
147
 
146
148
  type_node = xml.find("ModelExchange")
147
- if type_node:
149
+ mx_option_names = option_names.copy()
150
+ mx_option_names.extend(opt.name for opt in FMI3_MODEL_OPTIONS_MX)
151
+ if type_node is not None:
148
152
  for option, value in options.items():
149
- if option in option_names:
153
+ if option in mx_option_names:
150
154
  type_node.set(option, str(value).lower())
151
155
 
152
156
  with zipfile.ZipFile(dest_file, "w") as zip_fmu:
@@ -247,7 +251,25 @@ def create_command_parser(parser: argparse.ArgumentParser):
247
251
  default=None
248
252
  )
249
253
 
250
- for option in FMI3_MODEL_OPTIONS:
254
+ for option in FMI3_MODEL_OPTIONS_COMMON:
255
+ action = "store_false" if option.value else "store_true"
256
+ parser.add_argument(
257
+ f"--{option.cli}",
258
+ dest=option.name,
259
+ help=f"If given, {option.name}={action[6:]}",
260
+ action=action
261
+ )
262
+
263
+ for option in FMI3_MODEL_OPTIONS_COSIM:
264
+ action = "store_false" if option.value else "store_true"
265
+ parser.add_argument(
266
+ f"--{option.cli}",
267
+ dest=option.name,
268
+ help=f"If given, {option.name}={action[6:]}",
269
+ action=action
270
+ )
271
+
272
+ for option in FMI3_MODEL_OPTIONS_MX:
251
273
  action = "store_false" if option.value else "store_true"
252
274
  parser.add_argument(
253
275
  f"--{option.cli}",
pythonfmu3/fmi3slave.py CHANGED
@@ -21,14 +21,22 @@ from .unit import Unit
21
21
 
22
22
  ModelOptions = namedtuple("ModelOptions", ["name", "value", "cli"])
23
23
 
24
- FMI3_MODEL_OPTIONS: List[ModelOptions] = [
24
+ FMI3_MODEL_OPTIONS_COMMON: List[ModelOptions] = [
25
25
  ModelOptions("needsExecutionTool", True, "no-external-tool"),
26
- ModelOptions("canHandleVariableCommunicationStepSize", True, "no-variable-step"),
27
26
  ModelOptions("canBeInstantiatedOnlyOncePerProcess", False, "only-one-per-process"),
28
27
  ModelOptions("canGetAndSetFMUState", False, "handle-state"),
29
28
  ModelOptions("canSerializeFMUState", False, "serialize-state")
30
29
  ]
31
30
 
31
+ FMI3_MODEL_OPTIONS_COSIM: List[ModelOptions] = [
32
+ ModelOptions("canHandleVariableCommunicationStepSize", True, "no-variable-step"),
33
+ ]
34
+
35
+ FMI3_MODEL_OPTIONS_MX: List[ModelOptions] = [
36
+ ModelOptions("needsCompletedIntegratorStep", False, "needs-completed-step"),
37
+ ]
38
+
39
+
32
40
  class Fmi3StepResult(NamedTuple):
33
41
  status: Fmi3Status = Fmi3Status.ok
34
42
  eventHandlingNeeded: bool = False
@@ -103,23 +111,26 @@ class Fmi3SlaveBase(object):
103
111
  root = Element("fmiModelDescription", attrib)
104
112
 
105
113
  options = dict()
106
- for option in FMI3_MODEL_OPTIONS:
114
+ for option in FMI3_MODEL_OPTIONS_COMMON:
107
115
  value = model_options.get(option.name, option.value)
108
116
  options[option.name] = str(value).lower()
117
+
109
118
  options["modelIdentifier"] = self.modelName
110
- options["canNotUseMemoryManagementFunctions"] = "true"
119
+
120
+ options_cs = options.copy()
121
+ for option in FMI3_MODEL_OPTIONS_COSIM:
122
+ options_cs[option.name] = str(value).lower()
111
123
 
112
- options_me = dict()
113
- options_me["canGetAndSetFMUState"] = "true"
114
- options_me["modelIdentifier"] = self.modelName
115
- options_me["needsCompletedIntegratorStep"] = "false"
124
+ options_me = options.copy()
125
+ for option in FMI3_MODEL_OPTIONS_MX:
126
+ options_me[option.name] = str(value).lower()
116
127
 
117
128
  # check if we have cosim mixin or model exchange mixin
118
129
  if isinstance(self, ModelExchange):
119
130
  SubElement(root, "ModelExchange", attrib=options_me)
120
131
 
121
132
  if isinstance(self, CoSimulation):
122
- SubElement(root, "CoSimulation", attrib=options)
133
+ SubElement(root, "CoSimulation", attrib=options_cs)
123
134
 
124
135
  if self.units:
125
136
  unit_defs = SubElement(root, "UnitDefinitions")
@@ -172,8 +183,7 @@ class Fmi3SlaveBase(object):
172
183
  initial_unknown = list(
173
184
  filter(lambda v: (v.causality == Fmi3Causality.output and (v.initial in allowed_variability))
174
185
  or v.causality == Fmi3Causality.calculatedParameter
175
- or v in continuous_state_derivatives and v.initial in allowed_variability
176
- or v.variability == Fmi3Variability.continuous and v.initial in allowed_variability and v.causality != Fmi3Causality.independent, self.vars.values())
186
+ or v in continuous_state_derivatives and v.initial in allowed_variability, self.vars.values())
177
187
  )
178
188
 
179
189
  for v in outputs:
@@ -271,10 +281,13 @@ class Fmi3SlaveBase(object):
271
281
  for vr in vrs:
272
282
  var = self.vars[vr]
273
283
  if isinstance(var, Int32):
274
- refs.append(int(var.getter()))
284
+ if len(var.dimensions) == 0:
285
+ refs.append(int(var.getter()))
286
+ else:
287
+ refs.extend(map(int, var.getter()))
275
288
  else:
276
289
  raise TypeError(
277
- f"Variable with valueReference={vr} is not of type Integer!"
290
+ f"Variable with valueReference={vr} is not of type Int32!"
278
291
  )
279
292
  return refs
280
293
 
@@ -283,7 +296,10 @@ class Fmi3SlaveBase(object):
283
296
  for vr in vrs:
284
297
  var = self.vars[vr]
285
298
  if isinstance(var, (Enumeration, Int64)):
286
- refs.append(int(var.getter()))
299
+ if len(var.dimensions) == 0:
300
+ refs.append(int(var.getter()))
301
+ else:
302
+ refs.extend(map(int, var.getter()))
287
303
  else:
288
304
  raise TypeError(
289
305
  f"Variable with valueReference={vr} is not of type Int64!"
@@ -295,11 +311,14 @@ class Fmi3SlaveBase(object):
295
311
  for vr in vrs:
296
312
  var = self.vars[vr]
297
313
  if isinstance(var, UInt64):
298
- val = var.getter()
299
- refs.append(val if isinstance(val, ctypes.c_uint64) else ctypes.c_uint64(val))
314
+ if len(var.dimensions) == 0:
315
+ val = var.getter()
316
+ refs.append(ctypes.c_uint64(val) if not isinstance(val, ctypes.c_uint64) else val)
317
+ else:
318
+ refs.extend(map(ctypes.c_uint64, var.getter()))
300
319
  else:
301
320
  raise TypeError(
302
- f"Variable with valueReference={vr} is not of type UInt64!"
321
+ f"Variable with valueReference={vr} is not of type Uint64!"
303
322
  )
304
323
  return refs
305
324
 
@@ -314,7 +333,7 @@ class Fmi3SlaveBase(object):
314
333
  refs.extend(var.getter())
315
334
  else:
316
335
  raise TypeError(
317
- f"Variable with valueReference={vr} is not of type Real!"
336
+ f"Variable with valueReference={vr} is not of type Float64!"
318
337
  )
319
338
  return refs
320
339
 
@@ -323,7 +342,11 @@ class Fmi3SlaveBase(object):
323
342
  for vr in vrs:
324
343
  var = self.vars[vr]
325
344
  if isinstance(var, Boolean):
326
- refs.append(bool(var.getter()))
345
+ if len(var.dimensions) == 0:
346
+ refs.append(bool(var.getter()))
347
+ else:
348
+ refs.extend(var.getter())
349
+
327
350
  else:
328
351
  raise TypeError(
329
352
  f"Variable with valueReference={vr} is not of type Boolean!"
@@ -343,30 +366,48 @@ class Fmi3SlaveBase(object):
343
366
  return refs
344
367
 
345
368
  def set_int32(self, vrs: List[int], values: List[int]):
346
- for vr, value in zip(vrs, values):
369
+ offset = 0
370
+ for vr in vrs:
347
371
  var = self.vars[vr]
348
372
  if isinstance(var, Int32):
349
- var.setter(value)
373
+ size = var.size(self.vars)
374
+ if size > 1:
375
+ var.setter(values[offset:offset+size])
376
+ else:
377
+ var.setter(values[offset])
378
+ offset += size
350
379
  else:
351
380
  raise TypeError(
352
- f"Variable with valueReference={vr} is not of type Integer!"
381
+ f"Variable with valueReference={vr} is not of type Int32!"
353
382
  )
354
383
 
355
384
  def set_int64(self, vrs: List[int], values: List[int]):
356
- for vr, value in zip(vrs, values):
385
+ offset = 0
386
+ for vr in vrs:
357
387
  var = self.vars[vr]
358
388
  if isinstance(var, (Enumeration, Int64)):
359
- var.setter(value)
389
+ size = var.size(self.vars)
390
+ if size > 1:
391
+ var.setter(values[offset:offset+size])
392
+ else:
393
+ var.setter(values[offset])
394
+ offset += size
360
395
  else:
361
396
  raise TypeError(
362
- f"Variable with valueReference={vr} is not of type Integer!"
397
+ f"Variable with valueReference={vr} is not of type Int64!"
363
398
  )
364
399
 
365
400
  def set_uint64(self, vrs: List[int], values: List[int]):
366
- for vr, value in zip(vrs, values):
401
+ offset = 0
402
+ for vr in vrs:
367
403
  var = self.vars[vr]
368
404
  if isinstance(var, UInt64):
369
- var.setter(value)
405
+ size = var.size(self.vars)
406
+ if size > 1:
407
+ var.setter(values[offset:offset+size])
408
+ else:
409
+ var.setter(values[offset])
410
+ offset += size
370
411
  else:
371
412
  raise TypeError(
372
413
  f"Variable with valueReference={vr} is not of type UInt64!"
@@ -385,14 +426,20 @@ class Fmi3SlaveBase(object):
385
426
  offset += size
386
427
  else:
387
428
  raise TypeError(
388
- f"Variable with valueReference={vr} is not of type Real!"
429
+ f"Variable with valueReference={vr} is not of type Float64!"
389
430
  )
390
431
 
391
432
  def set_boolean(self, vrs: List[int], values: List[bool]):
392
- for vr, value in zip(vrs, values):
433
+ offset = 0
434
+ for vr in vrs:
393
435
  var = self.vars[vr]
394
436
  if isinstance(var, Boolean):
395
- var.setter(value)
437
+ size = var.size(self.vars)
438
+ if size > 1:
439
+ var.setter(values[offset:offset+size])
440
+ else:
441
+ var.setter(values[offset])
442
+ offset += size
396
443
  else:
397
444
  raise TypeError(
398
445
  f"Variable with valueReference={vr} is not of type Boolean!"
@@ -66,7 +66,8 @@ void SlaveInstance::SetFloat64(
66
66
  void SlaveInstance::SetInt32(
67
67
  const FMIValueReference /*vr*/[],
68
68
  std::size_t nvr,
69
- const FMIInt32 /*value*/[])
69
+ const FMIInt32 /*value*/[],
70
+ std::size_t nValues)
70
71
  {
71
72
  if (nvr != 0) {
72
73
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -76,7 +77,8 @@ void SlaveInstance::SetInt32(
76
77
  void SlaveInstance::SetInt64(
77
78
  const FMIValueReference /*vr*/[],
78
79
  std::size_t nvr,
79
- const FMIInt64 /*value*/[])
80
+ const FMIInt64 /*value*/[],
81
+ std::size_t nValues)
80
82
  {
81
83
  if (nvr != 0) {
82
84
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -86,7 +88,8 @@ void SlaveInstance::SetInt64(
86
88
  void SlaveInstance::SetUInt64(
87
89
  const FMIValueReference /*vr*/[],
88
90
  std::size_t nvr,
89
- const FMIUInt64 /*value*/[])
91
+ const FMIUInt64 /*value*/[],
92
+ std::size_t nValues)
90
93
  {
91
94
  if (nvr != 0) {
92
95
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -97,7 +100,8 @@ void SlaveInstance::SetUInt64(
97
100
  void SlaveInstance::SetBoolean(
98
101
  const FMIValueReference /*vr*/[],
99
102
  std::size_t nvr,
100
- const FMIBoolean /*value*/[])
103
+ const FMIBoolean /*value*/[],
104
+ std::size_t nValues)
101
105
  {
102
106
  if (nvr != 0) {
103
107
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -108,7 +112,8 @@ void SlaveInstance::SetBoolean(
108
112
  void SlaveInstance::SetString(
109
113
  const FMIValueReference /*vr*/[],
110
114
  std::size_t nvr,
111
- const FMIString /*value*/[])
115
+ const FMIString /*value*/[],
116
+ std::size_t nValues)
112
117
  {
113
118
  if (nvr != 0) {
114
119
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -131,7 +136,8 @@ void SlaveInstance::GetFloat64(
131
136
  void SlaveInstance::GetInt32(
132
137
  const FMIValueReference /*vr*/[],
133
138
  std::size_t nvr,
134
- FMIInt32 /*value*/[]) const
139
+ FMIInt32 /*value*/[],
140
+ std::size_t nValues) const
135
141
  {
136
142
  if (nvr != 0) {
137
143
  throw std::logic_error("Attempted to get nonexistent variable");
@@ -142,7 +148,8 @@ void SlaveInstance::GetInt32(
142
148
  void SlaveInstance::GetInt64(
143
149
  const FMIValueReference /*vr*/[],
144
150
  std::size_t nvr,
145
- FMIInt64 /*value*/[]) const
151
+ FMIInt64 /*value*/[],
152
+ std::size_t nValues) const
146
153
  {
147
154
  if (nvr != 0) {
148
155
  throw std::logic_error("Attempted to get nonexistent variable");
@@ -153,7 +160,8 @@ void SlaveInstance::GetInt64(
153
160
  void SlaveInstance::GetUInt64(
154
161
  const FMIValueReference /*vr*/[],
155
162
  std::size_t nvr,
156
- FMIUInt64 /*value*/[]) const
163
+ FMIUInt64 /*value*/[],
164
+ std::size_t nValues) const
157
165
  {
158
166
  if (nvr != 0) {
159
167
  throw std::logic_error("Attempted to get nonexistent variable");
@@ -164,7 +172,8 @@ void SlaveInstance::GetUInt64(
164
172
  void SlaveInstance::GetBoolean(
165
173
  const FMIValueReference /*vr*/[],
166
174
  std::size_t nvr,
167
- FMIBoolean /*value*/[]) const
175
+ FMIBoolean /*value*/[],
176
+ std::size_t nValues) const
168
177
  {
169
178
  if (nvr != 0) {
170
179
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -175,7 +184,8 @@ void SlaveInstance::GetBoolean(
175
184
  void SlaveInstance::GetString(
176
185
  const FMIValueReference /*vr*/[],
177
186
  std::size_t nvr,
178
- FMIString /*value*/[]) const
187
+ FMIString /*value*/[],
188
+ std::size_t nValues) const
179
189
  {
180
190
  if (nvr != 0) {
181
191
  throw std::logic_error("Attempted to set nonexistent variable");
@@ -76,23 +76,28 @@ public:
76
76
  virtual void SetInt32(
77
77
  const FMIValueReference vr[],
78
78
  std::size_t nvr,
79
- const FMIInt32 value[]);
79
+ const FMIInt32 value[],
80
+ std::size_t nValues);
80
81
  virtual void SetInt64(
81
82
  const FMIValueReference vr[],
82
83
  std::size_t nvr,
83
- const FMIInt64 value[]);
84
+ const FMIInt64 value[],
85
+ std::size_t nValues);
84
86
  virtual void SetUInt64(
85
87
  const FMIValueReference vr[],
86
88
  std::size_t nvr,
87
- const FMIUInt64 value[]);
89
+ const FMIUInt64 value[],
90
+ std::size_t nValues);
88
91
  virtual void SetBoolean(
89
92
  const FMIValueReference vr[],
90
93
  std::size_t nvr,
91
- const FMIBoolean value[]);
94
+ const FMIBoolean value[],
95
+ std::size_t nValues);
92
96
  virtual void SetString(
93
97
  const FMIValueReference vr[],
94
98
  std::size_t nvr,
95
- const FMIString value[]);
99
+ const FMIString value[],
100
+ std::size_t nValues);
96
101
 
97
102
  /* Called from fmi3GetXxx()/fmiGetXxx().
98
103
  * Throws std::logic_error by default.
@@ -105,23 +110,28 @@ public:
105
110
  virtual void GetInt32(
106
111
  const FMIValueReference vr[],
107
112
  std::size_t nvr,
108
- FMIInt32 value[]) const;
113
+ FMIInt32 value[],
114
+ std::size_t nValues) const;
109
115
  virtual void GetInt64(
110
116
  const FMIValueReference vr[],
111
117
  std::size_t nvr,
112
- FMIInt64 value[]) const;
118
+ FMIInt64 value[],
119
+ std::size_t nValues) const;
113
120
  virtual void GetUInt64(
114
121
  const FMIValueReference vr[],
115
122
  std::size_t nvr,
116
- FMIUInt64 value[]) const;
123
+ FMIUInt64 value[],
124
+ std::size_t nValues) const;
117
125
  virtual void GetBoolean(
118
126
  const FMIValueReference vr[],
119
127
  std::size_t nvr,
120
- FMIBoolean value[]) const;
128
+ FMIBoolean value[],
129
+ std::size_t nValues) const;
121
130
  virtual void GetString(
122
131
  const FMIValueReference vr[],
123
132
  std::size_t nvr,
124
- FMIString value[]) const;
133
+ FMIString value[],
134
+ std::size_t nValues) const;
125
135
 
126
136
  // Called from fmi3DoStep()/fmiDoStep(). Must be implemented in model code.
127
137
  virtual FMIStatus DoStep(
@@ -334,7 +334,7 @@ fmi3Status fmi3GetInt32(
334
334
  {
335
335
  const auto component = reinterpret_cast<Component*>(c);
336
336
  try {
337
- component->slave->GetInt32(vr, nvr, values);
337
+ component->slave->GetInt32(vr, nvr, values, nValues);
338
338
  return fmi3OK;
339
339
  } catch (const cppfmu::FatalError& e) {
340
340
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -354,7 +354,7 @@ fmi3Status fmi3GetInt64(
354
354
  {
355
355
  const auto component = reinterpret_cast<Component*>(c);
356
356
  try {
357
- component->slave->GetInt64(vr, nvr, values);
357
+ component->slave->GetInt64(vr, nvr, values, nValues);
358
358
  return fmi3OK;
359
359
  } catch (const cppfmu::FatalError& e) {
360
360
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -374,7 +374,7 @@ fmi3Status fmi3GetUInt64(
374
374
  {
375
375
  const auto component = reinterpret_cast<Component*>(c);
376
376
  try {
377
- component->slave->GetUInt64(vr, nvr, values);
377
+ component->slave->GetUInt64(vr, nvr, values, nValues);
378
378
  return fmi3OK;
379
379
  } catch (const cppfmu::FatalError& e) {
380
380
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -394,7 +394,7 @@ fmi3Status fmi3GetBoolean(
394
394
  {
395
395
  const auto component = reinterpret_cast<Component*>(c);
396
396
  try {
397
- component->slave->GetBoolean(vr, nvr, values);
397
+ component->slave->GetBoolean(vr, nvr, values, nValues);
398
398
  return fmi3OK;
399
399
  } catch (const cppfmu::FatalError& e) {
400
400
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -414,7 +414,7 @@ fmi3Status fmi3GetString(
414
414
  {
415
415
  const auto component = reinterpret_cast<Component*>(c);
416
416
  try {
417
- component->slave->GetString(vr, nvr, values);
417
+ component->slave->GetString(vr, nvr, values, nValues);
418
418
  return fmi3OK;
419
419
  } catch (const cppfmu::FatalError& e) {
420
420
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -455,7 +455,7 @@ fmi3Status fmi3SetInt32(
455
455
  {
456
456
  const auto component = reinterpret_cast<Component*>(c);
457
457
  try {
458
- component->slave->SetInt32(vr, nvr, values);
458
+ component->slave->SetInt32(vr, nvr, values, nValues);
459
459
  return fmi3OK;
460
460
  } catch (const cppfmu::FatalError& e) {
461
461
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -475,7 +475,7 @@ fmi3Status fmi3SetInt64(
475
475
  {
476
476
  const auto component = reinterpret_cast<Component*>(c);
477
477
  try {
478
- component->slave->SetInt64(vr, nvr, values);
478
+ component->slave->SetInt64(vr, nvr, values, nValues);
479
479
  return fmi3OK;
480
480
  } catch (const cppfmu::FatalError& e) {
481
481
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -495,7 +495,7 @@ fmi3Status fmi3SetUInt64(
495
495
  {
496
496
  const auto component = reinterpret_cast<Component*>(c);
497
497
  try {
498
- component->slave->SetUInt64(vr, nvr, values);
498
+ component->slave->SetUInt64(vr, nvr, values, nValues);
499
499
  return fmi3OK;
500
500
  } catch (const cppfmu::FatalError& e) {
501
501
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -515,7 +515,7 @@ fmi3Status fmi3SetBoolean(
515
515
  {
516
516
  const auto component = reinterpret_cast<Component*>(c);
517
517
  try {
518
- component->slave->SetBoolean(vr, nvr, values);
518
+ component->slave->SetBoolean(vr, nvr, values, nValues);
519
519
  return fmi3OK;
520
520
  } catch (const cppfmu::FatalError& e) {
521
521
  component->logger.Log(fmi3Fatal, "", e.what());
@@ -535,7 +535,7 @@ fmi3Status fmi3SetString(
535
535
  {
536
536
  const auto component = reinterpret_cast<Component*>(c);
537
537
  try {
538
- component->slave->SetString(vr, nvr, values);
538
+ component->slave->SetString(vr, nvr, values, nValues);
539
539
  return fmi3OK;
540
540
  } catch (const cppfmu::FatalError& e) {
541
541
  component->logger.Log(fmi3Fatal, "", e.what());